mirror of
https://github.com/kevin-DL/revel-cmd.git
synced 2026-01-22 15:05:26 +00:00
Lint fixes
This commit is contained in:
@@ -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),
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user