Add structured logging to underlying http server
parent
c300578b71
commit
b60901e766
|
@ -2,6 +2,7 @@ package chronograf
|
|||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
|
@ -32,12 +33,13 @@ func (e Error) Error() string {
|
|||
type Logger interface {
|
||||
Debug(...interface{})
|
||||
Info(...interface{})
|
||||
Warn(...interface{})
|
||||
Error(...interface{})
|
||||
Fatal(...interface{})
|
||||
Panic(...interface{})
|
||||
|
||||
WithField(string, interface{}) Logger
|
||||
|
||||
// Logger can be transformed into an io.Writer.
|
||||
// That writer is the end of an io.Pipe and it is your responsibility to close it.
|
||||
Writer() *io.PipeWriter
|
||||
}
|
||||
|
||||
// Assets returns a handler to serve the website.
|
||||
|
|
|
@ -3,7 +3,6 @@ package kapacitor
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/chronograf"
|
||||
|
@ -25,7 +24,6 @@ func ValidateAlert(service string) error {
|
|||
func formatTick(tickscript string) (chronograf.TICKScript, error) {
|
||||
node, err := ast.Parse(tickscript)
|
||||
if err != nil {
|
||||
log.Fatalf("parse execution: %s", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
|
@ -81,6 +82,10 @@ func (ll *logrusLogger) WithField(key string, value interface{}) chronograf.Logg
|
|||
return &logrusLogger{ll.l.WithField(key, value)}
|
||||
}
|
||||
|
||||
func (ll *logrusLogger) Writer() *io.PipeWriter {
|
||||
return ll.l.Logger.WriterLevel(logrus.ErrorLevel)
|
||||
}
|
||||
|
||||
// New wraps a logrus Logger
|
||||
func New(l Level) chronograf.Logger {
|
||||
logger := &logrus.Logger{
|
||||
|
|
|
@ -2,9 +2,11 @@ package server
|
|||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"time"
|
||||
|
@ -57,7 +59,7 @@ type Server struct {
|
|||
HerokuOrganizations []string `long:"heroku-organization" description:"Heroku Organization Memberships a user is required to have for access to Chronograf (comma separated)" env:"HEROKU_ORGS" env-delim:","`
|
||||
|
||||
ReportingDisabled bool `short:"r" long:"reporting-disabled" description:"Disable reporting of usage stats (os,arch,version,cluster_id,uptime) once every 24hr" env:"REPORTING_DISABLED"`
|
||||
LogLevel string `short:"l" long:"log-level" value-name:"choice" choice:"debug" choice:"info" choice:"warn" choice:"error" choice:"fatal" choice:"panic" default:"info" description:"Set the logging level" env:"LOG_LEVEL"`
|
||||
LogLevel string `short:"l" long:"log-level" value-name:"choice" choice:"debug" choice:"info" choice:"error" default:"info" description:"Set the logging level" env:"LOG_LEVEL"`
|
||||
Basepath string `short:"p" long:"basepath" description:"A URL path prefix under which all chronograf routes will be mounted" env:"BASE_PATH"`
|
||||
ShowVersion bool `short:"v" long:"version" description:"Show Chronograf version info"`
|
||||
BuildInfo BuildInfo
|
||||
|
@ -211,10 +213,21 @@ func (s *Server) Serve() error {
|
|||
}
|
||||
s.Listener = listener
|
||||
|
||||
httpServer := &graceful.Server{Server: new(http.Server)}
|
||||
// Using a log writer for http server logging
|
||||
w := logger.Writer()
|
||||
defer w.Close()
|
||||
stdLog := log.New(w, "", 0)
|
||||
|
||||
// TODO: Remove graceful when changing to go 1.8
|
||||
httpServer := &graceful.Server{
|
||||
Server: &http.Server{
|
||||
ErrorLog: stdLog,
|
||||
Handler: s.handler,
|
||||
},
|
||||
Logger: stdLog,
|
||||
TCPKeepAlive: 5 * time.Second,
|
||||
}
|
||||
httpServer.SetKeepAlivesEnabled(true)
|
||||
httpServer.TCPKeepAlive = 5 * time.Second
|
||||
httpServer.Handler = s.handler
|
||||
|
||||
if !s.ReportingDisabled {
|
||||
go reportUsageStats(s.BuildInfo, logger)
|
||||
|
@ -247,7 +260,8 @@ func openService(boltPath, cannedPath string, logger chronograf.Logger, useAuth
|
|||
if err := db.Open(); err != nil {
|
||||
logger.
|
||||
WithField("component", "boltstore").
|
||||
Fatal("Unable to open boltdb; is there a chronograf already running? ", err)
|
||||
Error("Unable to open boltdb; is there a chronograf already running? ", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// These apps are those handled from a directory
|
||||
|
|
|
@ -80,9 +80,9 @@ func (up *URLPrefixer) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
|||
// extract the flusher for flushing chunks
|
||||
flusher, ok := rw.(http.Flusher)
|
||||
if !ok {
|
||||
up.Logger.
|
||||
WithField("component", "prefixer").
|
||||
Fatal("Expected http.ResponseWriter to be an http.Flusher, but wasn't")
|
||||
msg := "Expected http.ResponseWriter to be an http.Flusher, but wasn't"
|
||||
Error(rw, http.StatusInternalServerError, msg, up.Logger)
|
||||
return
|
||||
}
|
||||
|
||||
nextRead, nextWrite := io.Pipe()
|
||||
|
|
Loading…
Reference in New Issue