Lint fixes

This commit is contained in:
Paul Tötterman
2020-10-19 13:40:52 +03:00
parent 3cec19ee62
commit 3d924a016b
65 changed files with 884 additions and 1083 deletions

View File

@@ -1,10 +1,11 @@
package logger
import (
"github.com/mattn/go-colorable"
"gopkg.in/natefinch/lumberjack.v2"
"io"
"os"
"github.com/mattn/go-colorable"
"gopkg.in/natefinch/lumberjack.v2"
)
type CompositeMultiHandler struct {
@@ -19,8 +20,8 @@ func NewCompositeMultiHandler() (*CompositeMultiHandler, LogHandler) {
cw := &CompositeMultiHandler{}
return cw, cw
}
func (h *CompositeMultiHandler) Log(r *Record) (err error) {
func (h *CompositeMultiHandler) Log(r *Record) (err error) {
var handler LogHandler
switch r.Level {
@@ -78,7 +79,7 @@ func (h *CompositeMultiHandler) SetHandler(handler LogHandler, replace bool, lev
}
}
// For the multi handler set the handler, using the LogOptions defined
// For the multi handler set the handler, using the LogOptions defined.
func (h *CompositeMultiHandler) SetHandlers(handler LogHandler, options *LogOptions) {
if len(options.Levels) == 0 {
options.Levels = LvlAllList
@@ -88,8 +89,8 @@ func (h *CompositeMultiHandler) SetHandlers(handler LogHandler, options *LogOpti
for _, lvl := range options.Levels {
h.SetHandler(handler, options.ReplaceExistingHandler, lvl)
}
}
func (h *CompositeMultiHandler) SetJson(writer io.Writer, options *LogOptions) {
handler := CallerFileHandler(StreamHandler(writer, JsonFormatEx(
options.GetBoolDefault("pretty", false),
@@ -101,12 +102,12 @@ func (h *CompositeMultiHandler) SetJson(writer io.Writer, options *LogOptions) {
h.SetHandlers(handler, options)
}
// Use built in rolling function
// Use built in rolling function.
func (h *CompositeMultiHandler) SetJsonFile(filePath string, options *LogOptions) {
writer := &lumberjack.Logger{
Filename: filePath,
MaxSize: options.GetIntDefault("maxSizeMB", 1024), // megabytes
MaxAge: options.GetIntDefault("maxAgeDays", 7), //days
MaxAge: options.GetIntDefault("maxAgeDays", 7), // days
MaxBackups: options.GetIntDefault("maxBackups", 7),
Compress: options.GetBoolDefault("compress", true),
}
@@ -141,12 +142,12 @@ func (h *CompositeMultiHandler) SetTerminal(writer io.Writer, options *LogOption
h.SetHandlers(handler, options)
}
// Use built in rolling function
// Use built in rolling function.
func (h *CompositeMultiHandler) SetTerminalFile(filePath string, options *LogOptions) {
writer := &lumberjack.Logger{
Filename: filePath,
MaxSize: options.GetIntDefault("maxSizeMB", 1024), // megabytes
MaxAge: options.GetIntDefault("maxAgeDays", 7), //days
MaxAge: options.GetIntDefault("maxAgeDays", 7), // days
MaxBackups: options.GetIntDefault("maxBackups", 7),
Compress: options.GetBoolDefault("compress", true),
}

View File

@@ -1,15 +1,12 @@
/*
Package logger contains filters and handles for the logging utilities in Revel.
These facilities all currently use the logging library called log15 at
https://github.com/inconshreveable/log15
Package logger contains filters and handles for the logging utilities in Revel.
These facilities all currently use the logging library called log15 at
https://github.com/inconshreveable/log15
Defining handlers happens as follows
1) ALL handlers (log.all.output) replace any existing handlers
2) Output handlers (log.error.output) replace any existing handlers
3) Filter handlers (log.xxx.filter, log.xxx.nfilter) append to existing handlers,
note log.all.filter is treated as a filter handler, so it will NOT replace existing ones
*/
package logger

View File

@@ -11,12 +11,12 @@ type LevelFilterHandler struct {
}
// Filters out records which do not match the level
// Uses the `log15.FilterHandler` to perform this task
// Uses the `log15.FilterHandler` to perform this task.
func LevelHandler(lvl LogLevel, h LogHandler) LogHandler {
return &LevelFilterHandler{lvl, h}
}
// The implementation of the Log
// The implementation of the Log.
func (h LevelFilterHandler) Log(r *Record) error {
if r.Level == h.Level {
return h.h.Log(r)
@@ -25,7 +25,7 @@ func (h LevelFilterHandler) Log(r *Record) error {
}
// Filters out records which do not match the level
// Uses the `log15.FilterHandler` to perform this task
// Uses the `log15.FilterHandler` to perform this task.
func MinLevelHandler(lvl LogLevel, h LogHandler) LogHandler {
return FilterHandler(func(r *Record) (pass bool) {
return r.Level <= lvl
@@ -33,7 +33,7 @@ func MinLevelHandler(lvl LogLevel, h LogHandler) LogHandler {
}
// Filters out records which match the level
// Uses the `log15.FilterHandler` to perform this task
// Uses the `log15.FilterHandler` to perform this task.
func NotLevelHandler(lvl LogLevel, h LogHandler) LogHandler {
return FilterHandler(func(r *Record) (pass bool) {
return r.Level != lvl
@@ -48,13 +48,13 @@ func CallerFileHandler(h LogHandler) LogHandler {
}
// Adds in a context called `caller` to the record (contains file name and line number like `foo.go:12`)
// Uses the `log15.CallerFuncHandler` to perform this task
// Uses the `log15.CallerFuncHandler` to perform this task.
func CallerFuncHandler(h LogHandler) LogHandler {
return CallerFuncHandler(h)
}
// Filters out records which match the key value pair
// Uses the `log15.MatchFilterHandler` to perform this task
// Uses the `log15.MatchFilterHandler` to perform this task.
func MatchHandler(key string, value interface{}, h LogHandler) LogHandler {
return MatchFilterHandler(key, value, h)
}
@@ -72,7 +72,7 @@ func MatchFilterHandler(key string, value interface{}, h LogHandler) LogHandler
}, h)
}
// If match then A handler is called otherwise B handler is called
// If match then A handler is called otherwise B handler is called.
func MatchAbHandler(key string, value interface{}, a, b LogHandler) LogHandler {
return FuncHandler(func(r *Record) error {
if r.Context[key] == value {
@@ -85,24 +85,24 @@ func MatchAbHandler(key string, value interface{}, a, b LogHandler) LogHandler {
})
}
// The nil handler is used if logging for a specific request needs to be turned off
// The nil handler is used if logging for a specific request needs to be turned off.
func NilHandler() LogHandler {
return FuncHandler(func(r *Record) error {
return nil
})
}
// Match all values in map to log
// Match all values in map to log.
func MatchMapHandler(matchMap map[string]interface{}, a LogHandler) LogHandler {
return matchMapHandler(matchMap, false, a)
}
// Match !(Match all values in map to log) The inverse of MatchMapHandler
// Match !(Match all values in map to log) The inverse of MatchMapHandler.
func NotMatchMapHandler(matchMap map[string]interface{}, a LogHandler) LogHandler {
return matchMapHandler(matchMap, true, a)
}
// Rather then chaining multiple filter handlers, process all here
// Rather then chaining multiple filter handlers, process all here.
func matchMapHandler(matchMap map[string]interface{}, inverse bool, a LogHandler) LogHandler {
return FuncHandler(func(r *Record) error {
matchCount := 0
@@ -114,10 +114,11 @@ func matchMapHandler(matchMap map[string]interface{}, inverse bool, a LogHandler
// Test for two failure cases
if value == v && inverse || value != v && !inverse {
return nil
} else {
matchCount++
}
matchCount++
}
if matchCount != len(matchMap) {
return nil
}
@@ -126,7 +127,7 @@ func matchMapHandler(matchMap map[string]interface{}, inverse bool, a LogHandler
}
// Filters out records which do not match the key value pair
// Uses the `log15.FilterHandler` to perform this task
// Uses the `log15.FilterHandler` to perform this task.
func NotMatchHandler(key string, value interface{}, h LogHandler) LogHandler {
return FilterHandler(func(r *Record) (pass bool) {
return r.Context[key] != value
@@ -158,7 +159,7 @@ func StreamHandler(wr io.Writer, fmtr LogFormat) LogHandler {
return LazyHandler(SyncHandler(h))
}
// Filter handler
// Filter handler.
func FilterHandler(fn func(r *Record) bool, h LogHandler) LogHandler {
return FuncHandler(func(r *Record) error {
if fn(r) {
@@ -168,18 +169,18 @@ func FilterHandler(fn func(r *Record) bool, h LogHandler) LogHandler {
})
}
// List log handler handles a list of LogHandlers
// List log handler handles a list of LogHandlers.
type ListLogHandler struct {
handlers []LogHandler
}
// Create a new list of log handlers
// Create a new list of log handlers.
func NewListLogHandler(h1, h2 LogHandler) *ListLogHandler {
ll := &ListLogHandler{handlers: []LogHandler{h1, h2}}
return ll
}
// Log the record
// Log the record.
func (ll *ListLogHandler) Log(r *Record) (err error) {
for _, handler := range ll.handlers {
if err == nil {
@@ -191,14 +192,14 @@ func (ll *ListLogHandler) Log(r *Record) (err error) {
return
}
// Add another log handler
// Add another log handler.
func (ll *ListLogHandler) Add(h LogHandler) {
if h != nil {
ll.handlers = append(ll.handlers, h)
}
}
// Remove a log handler
// Remove a log handler.
func (ll *ListLogHandler) Del(h LogHandler) {
if h != nil {
for i, handler := range ll.handlers {

View File

@@ -1,13 +1,14 @@
package logger
// Get all handlers based on the Config (if available)
// Get all handlers based on the Config (if available).
import (
"fmt"
"github.com/revel/config"
"log"
"os"
"path/filepath"
"strings"
"github.com/revel/config"
)
func InitializeFromConfig(basePath string, config *config.Context) (c *CompositeMultiHandler) {
@@ -43,7 +44,7 @@ func InitializeFromConfig(basePath string, config *config.Context) (c *Composite
return c
}
// Init the log.all configuration options
// Init the log.all configuration options.
func initAllLog(c *CompositeMultiHandler, basePath string, config *config.Context) {
if config != nil {
extraLogFlag := config.BoolDefault(SPECIAL_USE_FLAG, false)
@@ -61,13 +62,13 @@ func initAllLog(c *CompositeMultiHandler, basePath string, config *config.Contex
// log.all.filter ....
// log.error.filter ....
func initFilterLog(c *CompositeMultiHandler, basePath string, config *config.Context) {
if config != nil {
extraLogFlag := config.BoolDefault(SPECIAL_USE_FLAG, false)
for _, logFilter := range logFilterList {
// Init for all filters
for _, name := range []string{"all", "debug", "info", "warn", "error", "crit",
for _, name := range []string{
"all", "debug", "info", "warn", "error", "crit",
"trace", // TODO trace is deprecated
} {
optionList := config.Options(logFilter.LogPrefix + name + logFilter.LogSuffix)
@@ -94,9 +95,10 @@ func initFilterLog(c *CompositeMultiHandler, basePath string, config *config.Con
}
}
// Init the log.error, log.warn etc configuration options
// Init the log.error, log.warn etc configuration options.
func initLogLevels(c *CompositeMultiHandler, basePath string, config *config.Context) {
for _, name := range []string{"debug", "info", "warn", "error", "crit",
for _, name := range []string{
"debug", "info", "warn", "error", "crit",
"trace", // TODO trace is deprecated
} {
if config != nil {
@@ -115,7 +117,7 @@ func initLogLevels(c *CompositeMultiHandler, basePath string, config *config.Con
}
}
// Init the request log options
// Init the request log options.
func initRequestLog(c *CompositeMultiHandler, basePath string, config *config.Context) {
// Request logging to a separate output handler
// This takes the InfoHandlers and adds a MatchAbHandler handler to it to direct
@@ -143,7 +145,7 @@ func initRequestLog(c *CompositeMultiHandler, basePath string, config *config.Co
// Returns a handler for the level using the output string
// Accept formats for output string are
// LogFunctionMap[value] callback function
// `stdout` `stderr` `full/file/path/to/location/app.log` `full/file/path/to/location/app.json`
// `stdout` `stderr` `full/file/path/to/location/app.log` `full/file/path/to/location/app.json`.
func initHandlerFor(c *CompositeMultiHandler, output, basePath string, options *LogOptions) {
if options.Ctx != nil {
options.SetExtendedOptions(
@@ -185,5 +187,4 @@ func initHandlerFor(c *CompositeMultiHandler, output, basePath string, options *
}
}
}
return
}

View File

@@ -5,46 +5,57 @@
package logger_test
import (
"github.com/revel/config"
"github.com/revel/revel/logger"
"github.com/stretchr/testify/assert"
"os"
"strings"
"testing"
"github.com/revel/cmd/logger"
"github.com/revel/config"
"github.com/stretchr/testify/assert"
)
type (
// A counter for the tester
// A counter for the tester.
testCounter struct {
debug, info, warn, error, critical int
}
// The data to tes
// The data to tes.
testData struct {
config []string
result testResult
tc *testCounter
}
// The test result
// The test result.
testResult struct {
debug, info, warn, error, critical int
}
)
// Single test cases
// Single test cases.
var singleCases = []testData{
{config: []string{"log.crit.output"},
result: testResult{0, 0, 0, 0, 1}},
{config: []string{"log.error.output"},
result: testResult{0, 0, 0, 1, 1}},
{config: []string{"log.warn.output"},
result: testResult{0, 0, 1, 0, 0}},
{config: []string{"log.info.output"},
result: testResult{0, 1, 0, 0, 0}},
{config: []string{"log.debug.output"},
result: testResult{1, 0, 0, 0, 0}},
{
config: []string{"log.crit.output"},
result: testResult{0, 0, 0, 0, 1},
},
{
config: []string{"log.error.output"},
result: testResult{0, 0, 0, 1, 1},
},
{
config: []string{"log.warn.output"},
result: testResult{0, 0, 1, 0, 0},
},
{
config: []string{"log.info.output"},
result: testResult{0, 1, 0, 0, 0},
},
{
config: []string{"log.debug.output"},
result: testResult{1, 0, 0, 0, 0},
},
}
// Test singles
// Test singles.
func TestSingleCases(t *testing.T) {
rootLog := logger.New()
for _, testCase := range singleCases {
@@ -53,31 +64,51 @@ func TestSingleCases(t *testing.T) {
}
}
// Filter test cases
// Filter test cases.
var filterCases = []testData{
{config: []string{"log.crit.filter.module.app"},
result: testResult{0, 0, 0, 0, 1}},
{config: []string{"log.crit.filter.module.appa"},
result: testResult{0, 0, 0, 0, 0}},
{config: []string{"log.error.filter.module.app"},
result: testResult{0, 0, 0, 1, 1}},
{config: []string{"log.error.filter.module.appa"},
result: testResult{0, 0, 0, 0, 0}},
{config: []string{"log.warn.filter.module.app"},
result: testResult{0, 0, 1, 0, 0}},
{config: []string{"log.warn.filter.module.appa"},
result: testResult{0, 0, 0, 0, 0}},
{config: []string{"log.info.filter.module.app"},
result: testResult{0, 1, 0, 0, 0}},
{config: []string{"log.info.filter.module.appa"},
result: testResult{0, 0, 0, 0, 0}},
{config: []string{"log.debug.filter.module.app"},
result: testResult{1, 0, 0, 0, 0}},
{config: []string{"log.debug.filter.module.appa"},
result: testResult{0, 0, 0, 0, 0}},
{
config: []string{"log.crit.filter.module.app"},
result: testResult{0, 0, 0, 0, 1},
},
{
config: []string{"log.crit.filter.module.appa"},
result: testResult{0, 0, 0, 0, 0},
},
{
config: []string{"log.error.filter.module.app"},
result: testResult{0, 0, 0, 1, 1},
},
{
config: []string{"log.error.filter.module.appa"},
result: testResult{0, 0, 0, 0, 0},
},
{
config: []string{"log.warn.filter.module.app"},
result: testResult{0, 0, 1, 0, 0},
},
{
config: []string{"log.warn.filter.module.appa"},
result: testResult{0, 0, 0, 0, 0},
},
{
config: []string{"log.info.filter.module.app"},
result: testResult{0, 1, 0, 0, 0},
},
{
config: []string{"log.info.filter.module.appa"},
result: testResult{0, 0, 0, 0, 0},
},
{
config: []string{"log.debug.filter.module.app"},
result: testResult{1, 0, 0, 0, 0},
},
{
config: []string{"log.debug.filter.module.appa"},
result: testResult{0, 0, 0, 0, 0},
},
}
// Filter test
// Filter test.
func TestFilterCases(t *testing.T) {
rootLog := logger.New("module", "app")
for _, testCase := range filterCases {
@@ -86,33 +117,55 @@ func TestFilterCases(t *testing.T) {
}
}
// Inverse test cases
// Inverse test cases.
var nfilterCases = []testData{
{config: []string{"log.crit.nfilter.module.appa"},
result: testResult{0, 0, 0, 0, 1}},
{config: []string{"log.crit.nfilter.modules.appa"},
result: testResult{0, 0, 0, 0, 0}},
{config: []string{"log.crit.nfilter.module.app"},
result: testResult{0, 0, 0, 0, 0}},
{config: []string{"log.error.nfilter.module.appa"}, // Special case, when error is not nill critical inherits from error
result: testResult{0, 0, 0, 1, 1}},
{config: []string{"log.error.nfilter.module.app"},
result: testResult{0, 0, 0, 0, 0}},
{config: []string{"log.warn.nfilter.module.appa"},
result: testResult{0, 0, 1, 0, 0}},
{config: []string{"log.warn.nfilter.module.app"},
result: testResult{0, 0, 0, 0, 0}},
{config: []string{"log.info.nfilter.module.appa"},
result: testResult{0, 1, 0, 0, 0}},
{config: []string{"log.info.nfilter.module.app"},
result: testResult{0, 0, 0, 0, 0}},
{config: []string{"log.debug.nfilter.module.appa"},
result: testResult{1, 0, 0, 0, 0}},
{config: []string{"log.debug.nfilter.module.app"},
result: testResult{0, 0, 0, 0, 0}},
{
config: []string{"log.crit.nfilter.module.appa"},
result: testResult{0, 0, 0, 0, 1},
},
{
config: []string{"log.crit.nfilter.modules.appa"},
result: testResult{0, 0, 0, 0, 0},
},
{
config: []string{"log.crit.nfilter.module.app"},
result: testResult{0, 0, 0, 0, 0},
},
{
config: []string{"log.error.nfilter.module.appa"}, // Special case, when error is not nill critical inherits from error
result: testResult{0, 0, 0, 1, 1},
},
{
config: []string{"log.error.nfilter.module.app"},
result: testResult{0, 0, 0, 0, 0},
},
{
config: []string{"log.warn.nfilter.module.appa"},
result: testResult{0, 0, 1, 0, 0},
},
{
config: []string{"log.warn.nfilter.module.app"},
result: testResult{0, 0, 0, 0, 0},
},
{
config: []string{"log.info.nfilter.module.appa"},
result: testResult{0, 1, 0, 0, 0},
},
{
config: []string{"log.info.nfilter.module.app"},
result: testResult{0, 0, 0, 0, 0},
},
{
config: []string{"log.debug.nfilter.module.appa"},
result: testResult{1, 0, 0, 0, 0},
},
{
config: []string{"log.debug.nfilter.module.app"},
result: testResult{0, 0, 0, 0, 0},
},
}
// Inverse test
// Inverse test.
func TestNotFilterCases(t *testing.T) {
rootLog := logger.New("module", "app")
for _, testCase := range nfilterCases {
@@ -121,13 +174,15 @@ func TestNotFilterCases(t *testing.T) {
}
}
// off test cases
// off test cases.
var offCases = []testData{
{config: []string{"log.all.output", "log.error.output=off"},
result: testResult{1, 1, 1, 0, 1}},
{
config: []string{"log.all.output", "log.error.output=off"},
result: testResult{1, 1, 1, 0, 1},
},
}
// Off test
// Off test.
func TestOffCases(t *testing.T) {
rootLog := logger.New("module", "app")
for _, testCase := range offCases {
@@ -136,13 +191,15 @@ func TestOffCases(t *testing.T) {
}
}
// Duplicate test cases
// Duplicate test cases.
var duplicateCases = []testData{
{config: []string{"log.all.output", "log.error.output", "log.error.filter.module.app"},
result: testResult{1, 1, 1, 2, 1}},
{
config: []string{"log.all.output", "log.error.output", "log.error.filter.module.app"},
result: testResult{1, 1, 1, 2, 1},
},
}
// test duplicate cases
// test duplicate cases.
func TestDuplicateCases(t *testing.T) {
rootLog := logger.New("module", "app")
for _, testCase := range duplicateCases {
@@ -151,19 +208,27 @@ func TestDuplicateCases(t *testing.T) {
}
}
// Contradicting cases
// Contradicting cases.
var contradictCases = []testData{
{config: []string{"log.all.output", "log.error.output=off", "log.all.output"},
result: testResult{1, 1, 1, 0, 1}},
{config: []string{"log.all.output", "log.error.output=off", "log.debug.filter.module.app"},
result: testResult{2, 1, 1, 0, 1}},
{config: []string{"log.all.filter.module.app", "log.info.output=off", "log.info.filter.module.app"},
result: testResult{1, 2, 1, 1, 1}},
{config: []string{"log.all.output", "log.info.output=off", "log.info.filter.module.app"},
result: testResult{1, 1, 1, 1, 1}},
{
config: []string{"log.all.output", "log.error.output=off", "log.all.output"},
result: testResult{1, 1, 1, 0, 1},
},
{
config: []string{"log.all.output", "log.error.output=off", "log.debug.filter.module.app"},
result: testResult{2, 1, 1, 0, 1},
},
{
config: []string{"log.all.filter.module.app", "log.info.output=off", "log.info.filter.module.app"},
result: testResult{1, 2, 1, 1, 1},
},
{
config: []string{"log.all.output", "log.info.output=off", "log.info.filter.module.app"},
result: testResult{1, 1, 1, 1, 1},
},
}
// Contradiction test
// Contradiction test.
func TestContradictCases(t *testing.T) {
rootLog := logger.New("module", "app")
for _, testCase := range contradictCases {
@@ -172,15 +237,19 @@ func TestContradictCases(t *testing.T) {
}
}
// All test cases
// All test cases.
var allCases = []testData{
{config: []string{"log.all.filter.module.app"},
result: testResult{1, 1, 1, 1, 1}},
{config: []string{"log.all.output"},
result: testResult{2, 2, 2, 2, 2}},
{
config: []string{"log.all.filter.module.app"},
result: testResult{1, 1, 1, 1, 1},
},
{
config: []string{"log.all.output"},
result: testResult{2, 2, 2, 2, 2},
},
}
// All tests
// All tests.
func TestAllCases(t *testing.T) {
rootLog := logger.New("module", "app")
for i, testCase := range allCases {
@@ -195,7 +264,6 @@ func TestAllCases(t *testing.T) {
for _, testCase := range allCases {
testCase.validate(t)
}
}
func (c *testCounter) Log(r *logger.Record) error {
@@ -215,6 +283,7 @@ func (c *testCounter) Log(r *logger.Record) error {
}
return nil
}
func (td *testData) logTest(rootLog logger.MultiLogger, t *testing.T) {
if td.tc == nil {
td.tc = &testCounter{}
@@ -256,7 +325,7 @@ func (td *testData) validate(t *testing.T) {
assert.Equal(t, td.result.critical, td.tc.critical, "Critical failed "+strings.Join(td.config, " "))
}
// Add test to the function map
// Add test to the function map.
func counterInit(tc *testCounter) {
logger.LogFunctionMap["test"] = func(c *logger.CompositeMultiHandler, logOptions *logger.LogOptions) {
// Output to the test log and the stdout

View File

@@ -4,8 +4,8 @@ import (
"os"
)
// The log function map can be added to, so that you can specify your own logging mechanism
// it has defaults for off, stdout, stderr
// LogFunctionMap can be added to, so that you can specify your own logging mechanism
// it has defaults for off, stdout, stderr.
var LogFunctionMap = map[string]func(*CompositeMultiHandler, *LogOptions){
// Do nothing - set the logger off
"off": func(c *CompositeMultiHandler, logOptions *LogOptions) {

View File

@@ -2,14 +2,15 @@ package logger
import (
"fmt"
"github.com/revel/config"
"time"
"github.com/revel/config"
)
// The LogHandler defines the interface to handle the log records
// The LogHandler defines the interface to handle the log records.
type (
// The Multilogger reduces the number of exposed defined logging variables,
// and allows the output to be easily refined
// and allows the output to be easily refined.
MultiLogger interface {
// New returns a new Logger that has this logger's context plus the given context
New(ctx ...interface{}) MultiLogger
@@ -63,32 +64,32 @@ type (
Panicf(msg string, params ...interface{})
}
// The log handler interface
// The log handler interface.
LogHandler interface {
Log(*Record) error
//log15.Handler
// log15.Handler
}
// The log stack handler interface
// The log stack handler interface.
LogStackHandler interface {
LogHandler
GetStack() int
}
// The log handler interface which has child logs
// The log handler interface which has child logs.
ParentLogHandler interface {
SetChild(handler LogHandler) LogHandler
}
// The log format interface
// The log format interface.
LogFormat interface {
Format(r *Record) []byte
}
// The log level type
// The log level type.
LogLevel int
// Used for the callback to LogFunctionMap
// Used for the callback to LogFunctionMap.
LogOptions struct {
Ctx *config.Context
ReplaceExistingHandler bool
@@ -97,22 +98,22 @@ type (
ExtendedOptions map[string]interface{}
}
// The log record
// The log record.
Record struct {
Message string // The message
Time time.Time // The time
Level LogLevel //The level
Level LogLevel // The level
Call CallStack // The call stack if built
Context ContextMap // The context
}
// The lazy structure to implement a function to be invoked only if needed
// The lazy structure to implement a function to be invoked only if needed.
Lazy struct {
Fn interface{} // the function
}
// Currently the only requirement for the callstack is to support the Formatter method
// which stack.Call does so we use that
// which stack.Call does so we use that.
CallStack interface {
fmt.Formatter // Requirement
}
@@ -129,6 +130,7 @@ type formatFunc func(*Record) []byte
func (f formatFunc) Format(r *Record) []byte {
return f(r)
}
func NewRecord(message string, level LogLevel) *Record {
return &Record{Message: message, Context: ContextMap{}, Level: level}
}
@@ -141,28 +143,28 @@ const (
LvlDebug // Debug
)
// A list of all the log levels
// LvlAllList is a list of all the log levels.
var LvlAllList = []LogLevel{LvlDebug, LvlInfo, LvlWarn, LvlError, LvlCrit}
// Implements the ParentLogHandler
// Implements the ParentLogHandler.
type parentLogHandler struct {
setChild func(handler LogHandler) LogHandler
}
// Create a new parent log handler
// Create a new parent log handler.
func NewParentLogHandler(callBack func(child LogHandler) LogHandler) ParentLogHandler {
return &parentLogHandler{callBack}
}
// Sets the child of the log handler
// Sets the child of the log handler.
func (p *parentLogHandler) SetChild(child LogHandler) LogHandler {
return p.setChild(child)
}
// Create a new log options
// Create a new log options.
func NewLogOptions(cfg *config.Context, replaceHandler bool, phandler ParentLogHandler, lvl ...LogLevel) (logOptions *LogOptions) {
logOptions = &LogOptions{
Ctx: cfg,
Ctx: cfg,
ReplaceExistingHandler: replaceHandler,
HandlerWrap: phandler,
Levels: lvl,
@@ -171,14 +173,14 @@ func NewLogOptions(cfg *config.Context, replaceHandler bool, phandler ParentLogH
return
}
// Assumes options will be an even number and have a string, value syntax
// Assumes options will be an even number and have a string, value syntax.
func (l *LogOptions) SetExtendedOptions(options ...interface{}) {
for x := 0; x < len(options); x += 2 {
l.ExtendedOptions[options[x].(string)] = options[x+1]
}
}
// Gets a string option with default
// Gets a string option with default.
func (l *LogOptions) GetStringDefault(option, value string) string {
if v, found := l.ExtendedOptions[option]; found {
return v.(string)
@@ -186,7 +188,7 @@ func (l *LogOptions) GetStringDefault(option, value string) string {
return value
}
// Gets an int option with default
// Gets an int option with default.
func (l *LogOptions) GetIntDefault(option string, value int) int {
if v, found := l.ExtendedOptions[option]; found {
return v.(int)
@@ -194,7 +196,7 @@ func (l *LogOptions) GetIntDefault(option string, value int) int {
return value
}
// Gets a boolean option with default
// Gets a boolean option with default.
func (l *LogOptions) GetBoolDefault(option string, value bool) bool {
if v, found := l.ExtendedOptions[option]; found {
return v.(bool)

View File

@@ -2,18 +2,19 @@ package logger
import (
"fmt"
"github.com/revel/log15"
"log"
"os"
"github.com/revel/log15"
)
// This type implements the MultiLogger
// This type implements the MultiLogger.
type RevelLogger struct {
log15.Logger
}
// Set the systems default logger
// Default logs will be captured and handled by revel at level info
// Default logs will be captured and handled by revel at level info.
func SetDefaultLog(fromLog MultiLogger) {
log.SetOutput(loggerRewrite{Logger: fromLog, Level: log15.LvlInfo, hideDeprecated: true})
// No need to show date and time, that will be logged with revel
@@ -24,73 +25,73 @@ func (rl *RevelLogger) Debugf(msg string, param ...interface{}) {
rl.Debug(fmt.Sprintf(msg, param...))
}
// Print a formatted info message
// Print a formatted info message.
func (rl *RevelLogger) Infof(msg string, param ...interface{}) {
rl.Info(fmt.Sprintf(msg, param...))
}
// Print a formatted warn message
// Print a formatted warn message.
func (rl *RevelLogger) Warnf(msg string, param ...interface{}) {
rl.Warn(fmt.Sprintf(msg, param...))
}
// Print a formatted error message
// Print a formatted error message.
func (rl *RevelLogger) Errorf(msg string, param ...interface{}) {
rl.Error(fmt.Sprintf(msg, param...))
}
// Print a formatted critical message
// Print a formatted critical message.
func (rl *RevelLogger) Critf(msg string, param ...interface{}) {
rl.Crit(fmt.Sprintf(msg, param...))
}
// Print a formatted fatal message
// Print a formatted fatal message.
func (rl *RevelLogger) Fatalf(msg string, param ...interface{}) {
rl.Fatal(fmt.Sprintf(msg, param...))
}
// Print a formatted panic message
// Print a formatted panic message.
func (rl *RevelLogger) Panicf(msg string, param ...interface{}) {
rl.Panic(fmt.Sprintf(msg, param...))
}
// Print a critical message and call os.Exit(1)
// Print a critical message and call os.Exit(1).
func (rl *RevelLogger) Fatal(msg string, ctx ...interface{}) {
rl.Crit(msg, ctx...)
os.Exit(1)
}
// Print a critical message and panic
// Print a critical message and panic.
func (rl *RevelLogger) Panic(msg string, ctx ...interface{}) {
rl.Crit(msg, ctx...)
panic(msg)
}
// Override log15 method
// Override log15 method.
func (rl *RevelLogger) New(ctx ...interface{}) MultiLogger {
old := &RevelLogger{Logger: rl.Logger.New(ctx...)}
return old
}
// Set the stack level to check for the caller
// Set the stack level to check for the caller.
func (rl *RevelLogger) SetStackDepth(amount int) MultiLogger {
rl.Logger.SetStackDepth(amount) // Ignore the logger returned
return rl
}
// Create a new logger
// Create a new logger.
func New(ctx ...interface{}) MultiLogger {
r := &RevelLogger{Logger: log15.New(ctx...)}
r.SetStackDepth(0)
return r
}
// Set the handler in the Logger
// Set the handler in the Logger.
func (rl *RevelLogger) SetHandler(h LogHandler) {
rl.Logger.SetHandler(callHandler(h.Log))
}
// The function wrapper to implement the callback
// The function wrapper to implement the callback.
type callHandler func(r *Record) error
// Log implementation, reads the record and extracts the details from the log record
@@ -99,7 +100,7 @@ func (c callHandler) Log(log *log15.Record) error {
ctx := log.Ctx
var ctxMap ContextMap
if len(ctx) > 0 {
ctxMap = make(ContextMap, len(ctx) / 2)
ctxMap = make(ContextMap, len(ctx)/2)
for i := 0; i < len(ctx); i += 2 {
v := ctx[i]
@@ -108,24 +109,24 @@ func (c callHandler) Log(log *log15.Record) error {
key = fmt.Sprintf("LOGGER_INVALID_KEY %v", v)
}
var value interface{}
if len(ctx) > i + 1 {
value = ctx[i + 1]
if len(ctx) > i+1 {
value = ctx[i+1]
} else {
value = "LOGGER_VALUE_MISSING"
}
ctxMap[key] = value
}
} else {
ctxMap = make(ContextMap, 0)
ctxMap = make(ContextMap)
}
r := &Record{Message: log.Msg, Context: ctxMap, Time: log.Time, Level: LogLevel(log.Lvl), Call: CallStack(log.Call)}
return c(r)
}
// Internally used contextMap, allows conversion of map to map[string]string
// Internally used contextMap, allows conversion of map to map[string]string.
type ContextMap map[string]interface{}
// Convert the context map to be string only values, any non string values are ignored
// Convert the context map to be string only values, any non string values are ignored.
func (m ContextMap) StringMap() (newMap map[string]string) {
if m != nil {
newMap = map[string]string{}
@@ -137,6 +138,7 @@ func (m ContextMap) StringMap() (newMap map[string]string) {
}
return
}
func (m ContextMap) Add(key string, value interface{}) {
m[key] = value
}

View File

@@ -18,13 +18,13 @@ const (
errorKey = "REVEL_ERROR"
)
var (
levelString = map[LogLevel]string{LvlDebug: "DEBUG",
LvlInfo: "INFO", LvlWarn: "WARN", LvlError: "ERROR", LvlCrit: "CRIT"}
)
var levelString = map[LogLevel]string{
LvlDebug: "DEBUG",
LvlInfo: "INFO", LvlWarn: "WARN", LvlError: "ERROR", LvlCrit: "CRIT",
}
// Outputs to the terminal in a format like below
// INFO 09:11:32 server-engine.go:169: Request Stats
// INFO 09:11:32 server-engine.go:169: Request Stats.
func TerminalFormatHandler(noColor bool, smallDate bool) LogFormat {
dateFormat := termTimeFormat
if smallDate {
@@ -32,7 +32,7 @@ func TerminalFormatHandler(noColor bool, smallDate bool) LogFormat {
}
return FormatFunc(func(r *Record) []byte {
// Bash coloring http://misc.flogisoft.com/bash/tip_colors_and_formatting
var color = 0
color := 0
switch r.Level {
case LvlCrit:
// Magenta
@@ -54,7 +54,7 @@ func TerminalFormatHandler(noColor bool, smallDate bool) LogFormat {
b := &bytes.Buffer{}
caller, _ := r.Context["caller"].(string)
module, _ := r.Context["module"].(string)
if noColor == false && color > 0 {
if !noColor && color > 0 {
if len(module) > 0 {
fmt.Fprintf(b, "\x1b[%dm%-5s\x1b[0m %s %6s %13s: %-40s ", color, levelString[r.Level], r.Time.Format(dateFormat), module, caller, r.Message)
} else {
@@ -77,7 +77,7 @@ func TerminalFormatHandler(noColor bool, smallDate bool) LogFormat {
v := formatLogfmtValue(v)
// TODO: we should probably check that all of your key bytes aren't invalid
if noColor == false && color > 0 {
if !noColor && color > 0 {
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m=%s", color, k, v)
} else {
b.WriteString(k)
@@ -92,7 +92,7 @@ func TerminalFormatHandler(noColor bool, smallDate bool) LogFormat {
})
}
// formatValue formats a value for serialization
// formatValue formats a value for serialization.
func formatLogfmtValue(value interface{}) string {
if value == nil {
return "nil"
@@ -121,7 +121,7 @@ func formatLogfmtValue(value interface{}) string {
}
}
// Format the value in json format
// Format the value in json format.
func formatShared(value interface{}) (result interface{}) {
defer func() {
if err := recover(); err != nil {
@@ -148,12 +148,12 @@ func formatShared(value interface{}) (result interface{}) {
}
}
// A reusuable buffer for outputting data
// A reusuable buffer for outputting data.
var stringBufPool = sync.Pool{
New: func() interface{} { return new(bytes.Buffer) },
}
// Escape the string when needed
// Escape the string when needed.
func escapeString(s string) string {
needsQuotes := false
needsEscape := false
@@ -165,7 +165,7 @@ func escapeString(s string) string {
needsEscape = true
}
}
if needsEscape == false && needsQuotes == false {
if !needsEscape && !needsQuotes {
return s
}
e := stringBufPool.Get().(*bytes.Buffer)
@@ -215,7 +215,7 @@ func JsonFormatEx(pretty, lineSeparated bool) LogFormat {
props["lvl"] = levelString[r.Level]
props["msg"] = r.Message
for k, v := range r.Context {
props[k] = formatJsonValue(v)
props[k] = formatJSONValue(v)
}
b, err := jsonMarshal(props)
@@ -234,7 +234,7 @@ func JsonFormatEx(pretty, lineSeparated bool) LogFormat {
})
}
func formatJsonValue(value interface{}) interface{} {
func formatJSONValue(value interface{}) interface{} {
value = formatShared(value)
switch value.(type) {
case int, int8, int16, int32, int64, float32, float64, uint, uint8, uint16, uint32, uint64, string:

View File

@@ -1,29 +1,31 @@
package logger
import (
"log"
"github.com/revel/log15"
"gopkg.in/stack.v0"
"log"
)
// Utility package to make existing logging backwards compatible
// Utility package to make existing logging backwards compatible.
var (
// Convert the string to LogLevel
toLevel = map[string]LogLevel{"debug": LogLevel(log15.LvlDebug),
"info": LogLevel(log15.LvlInfo), "request": LogLevel(log15.LvlInfo), "warn": LogLevel(log15.LvlWarn),
// Convert the string to LogLevel.
toLevel = map[string]LogLevel{
"debug": LogLevel(log15.LvlDebug),
"info": LogLevel(log15.LvlInfo), "request": LogLevel(log15.LvlInfo), "warn": LogLevel(log15.LvlWarn),
"error": LogLevel(log15.LvlError), "crit": LogLevel(log15.LvlCrit),
"trace": LogLevel(log15.LvlDebug), // TODO trace is deprecated, replaced by debug
}
)
const (
// The test mode flag overrides the default log level and shows only errors
// The test mode flag overrides the default log level and shows only errors.
TEST_MODE_FLAG = "testModeFlag"
// The special use flag enables showing messages when the logger is setup
// The special use flag enables showing messages when the logger is setup.
SPECIAL_USE_FLAG = "specialUseFlag"
)
// Returns the logger for the name
// Returns the logger for the name.
func GetLogger(name string, logger MultiLogger) (l *log.Logger) {
switch name {
case "trace": // TODO trace is deprecated, replaced by debug
@@ -41,10 +43,9 @@ func GetLogger(name string, logger MultiLogger) (l *log.Logger) {
}
return l
}
// Used by the initFilterLog to handle the filters
// Used by the initFilterLog to handle the filters.
var logFilterList = []struct {
LogPrefix, LogSuffix string
parentHandler func(map[string]interface{}) ParentLogHandler
@@ -54,7 +55,6 @@ var logFilterList = []struct {
return NewParentLogHandler(func(child LogHandler) LogHandler {
return MatchMapHandler(keyMap, child)
})
},
}, {
"log.", ".nfilter",
@@ -65,20 +65,20 @@ var logFilterList = []struct {
},
}}
// This structure and method will handle the old output format and log it to the new format
// This structure and method will handle the old output format and log it to the new format.
type loggerRewrite struct {
Logger MultiLogger
Level log15.Lvl
hideDeprecated bool
}
// The message indicating that a logger is using a deprecated log mechanism
var log_deprecated = []byte("* LOG DEPRECATED * ")
// The message indicating that a logger is using a deprecated log mechanism.
var logDeprecated = []byte("* LOG DEPRECATED * ")
// Implements the Write of the logger
// Implements the Write of the logger.
func (lr loggerRewrite) Write(p []byte) (n int, err error) {
if !lr.hideDeprecated {
p = append(log_deprecated, p...)
p = append(logDeprecated, p...)
}
n = len(p)
if len(p) > 0 && p[n-1] == '\n' {
@@ -104,7 +104,7 @@ func (lr loggerRewrite) Write(p []byte) (n int, err error) {
// For logging purposes the call stack can be used to record the stack trace of a bad error
// simply pass it as a context field in your log statement like
// `controller.Log.Crit("This should not occur","stack",revel.NewCallStack())`
// `controller.Log.Crit("This should not occur","stack",revel.NewCallStack())`.
func NewCallStack() interface{} {
return stack.Trace()
}

View File

@@ -9,29 +9,29 @@ import (
"time"
)
// Function handler wraps the declared function and returns the handler for it
// Function handler wraps the declared function and returns the handler for it.
func FuncHandler(fn func(r *Record) error) LogHandler {
return funcHandler(fn)
}
// The type decleration for the function
// The type declaration for the function.
type funcHandler func(r *Record) error
// The implementation of the Log
// The implementation of the Log.
func (h funcHandler) Log(r *Record) error {
return h(r)
}
// This function allows you to do a full declaration for the log,
// it is recommended you use FuncHandler instead
// it is recommended you use FuncHandler instead.
func HandlerFunc(log func(message string, time time.Time, level LogLevel, call CallStack, context ContextMap) error) LogHandler {
return remoteHandler(log)
}
// The type used for the HandlerFunc
// The type used for the HandlerFunc.
type remoteHandler func(message string, time time.Time, level LogLevel, call CallStack, context ContextMap) error
// The Log implementation
// The Log implementation.
func (c remoteHandler) Log(record *Record) error {
return c(record.Message, record.Time, record.Level, record.Call, record.Context)
}
@@ -56,11 +56,9 @@ func LazyHandler(h LogHandler) LogHandler {
return FuncHandler(func(r *Record) error {
for k, v := range r.Context {
if lz, ok := v.(Lazy); ok {
value, err := evaluateLazy(lz)
_, err := evaluateLazy(lz)
if err != nil {
r.Context[errorKey] = "bad lazy " + k
} else {
v = value
}
}
}
@@ -88,11 +86,12 @@ func evaluateLazy(lz Lazy) (interface{}, error) {
results := value.Call([]reflect.Value{})
if len(results) == 1 {
return results[0].Interface(), nil
} else {
values := make([]interface{}, len(results))
for i, v := range results {
values[i] = v.Interface()
}
return values, nil
}
values := make([]interface{}, len(results))
for i, v := range results {
values[i] = v.Interface()
}
return values, nil
}