Skip to content

Commit

Permalink
agent: route http logs through hclog
Browse files Browse the repository at this point in the history
Pipe http server log to hclog, so that it uses the same logging format
as rest of nomad logs.  Also, supports emitting them as json logs, when
json formatting is set.

The http server logs are emitted as Trace level, as they are typically
repsent HTTP client errors (e.g. failed tls handshakes, invalid headers,
etc).

Though, Panic logs represent server errors and are relayed as Error
level.
  • Loading branch information
Mahmood Ali committed Apr 20, 2020
1 parent 68d0a9e commit 360e0a1
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 0 deletions.
1 change: 1 addition & 0 deletions command/agent/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ func NewHTTPServer(agent *Agent, config *Config) (*HTTPServer, error) {
Addr: srv.Addr,
Handler: gzip(mux),
ConnState: makeConnState(config.TLSConfig.EnableHTTP, handshakeTimeout, maxConns),
ErrorLog: newHTTPServerLogger(srv.logger),
}

go func() {
Expand Down
33 changes: 33 additions & 0 deletions command/agent/http_stdlog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package agent

import (
"bytes"
"log"

hclog "github.com/hashicorp/go-hclog"
)

func newHTTPServerLogger(logger hclog.Logger) *log.Logger {
return log.New(&httpServerLoggerAdapter{logger}, "", 0)
}

// a logger adapter that forwards http server logs as a Trace level
// hclog log entries. Logs related to panics are forwarded with Error level.
//
// HTTP server logs are typically spurious as they represent HTTP
// client errors (e.g. TLS handshake failures).
type httpServerLoggerAdapter struct {
logger hclog.Logger
}

func (l *httpServerLoggerAdapter) Write(data []byte) (int, error) {
if bytes.Contains(data, []byte("panic")) {
str := string(bytes.TrimRight(data, " \t\n"))
l.logger.Error(str)
} else if l.logger.IsTrace() {
str := string(bytes.TrimRight(data, " \t\n"))
l.logger.Trace(str)
}

return len(data), nil
}
48 changes: 48 additions & 0 deletions command/agent/http_stdlog_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package agent

import (
"bytes"
"testing"

"github.com/hashicorp/go-hclog"
"github.com/stretchr/testify/require"
)

func TestHttpServerLoggerFilters_Level_Info(t *testing.T) {
var buf bytes.Buffer
hclogger := hclog.New(&hclog.LoggerOptions{
Name: "testlog",
Output: &buf,
Level: hclog.Info,
})

stdlogger := newHTTPServerLogger(hclogger)

// spurious logging would be filtered out
stdlogger.Printf("spurious logging: %v", "arg")
require.Empty(t, buf.String())

// panics are included
stdlogger.Printf("panic while processing: %v", "endpoint")
require.Contains(t, buf.String(), "[ERROR] testlog: panic while processing: endpoint")

}

func TestHttpServerLoggerFilters_Level_Trace(t *testing.T) {
var buf bytes.Buffer
hclogger := hclog.New(&hclog.LoggerOptions{
Name: "testlog",
Output: &buf,
Level: hclog.Trace,
})

stdlogger := newHTTPServerLogger(hclogger)

// spurious logging will be included as Trace level
stdlogger.Printf("spurious logging: %v", "arg")
require.Contains(t, buf.String(), "[TRACE] testlog: spurious logging: arg")

stdlogger.Printf("panic while processing: %v", "endpoint")
require.Contains(t, buf.String(), "[ERROR] testlog: panic while processing: endpoint")

}

0 comments on commit 360e0a1

Please sign in to comment.