mirror of
https://github.com/kevin-DL/revel-cmd.git
synced 2026-01-11 10:44:28 +00:00
191 lines
6.3 KiB
Go
191 lines
6.3 KiB
Go
package logger
|
|
|
|
// Get all handlers based on the Config (if available).
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/revel/config"
|
|
)
|
|
|
|
func InitializeFromConfig(basePath string, config *config.Context) (c *CompositeMultiHandler) {
|
|
// If running in test mode suppress anything that is not an error
|
|
if config != nil && config.BoolDefault(TestModeFlag, false) {
|
|
// Preconfigure all the options
|
|
config.SetOption("log.info.output", "none")
|
|
config.SetOption("log.debug.output", "none")
|
|
config.SetOption("log.warn.output", "none")
|
|
config.SetOption("log.error.output", "stderr")
|
|
config.SetOption("log.crit.output", "stderr")
|
|
}
|
|
|
|
// If the configuration has an all option we can skip some
|
|
c, _ = NewCompositeMultiHandler()
|
|
|
|
// Filters are assigned first, non filtered items override filters
|
|
if config != nil && !config.BoolDefault(TestModeFlag, false) {
|
|
initAllLog(c, basePath, config)
|
|
}
|
|
initLogLevels(c, basePath, config)
|
|
if c.CriticalHandler == nil && c.ErrorHandler != nil {
|
|
c.CriticalHandler = c.ErrorHandler
|
|
}
|
|
if config != nil && !config.BoolDefault(TestModeFlag, false) {
|
|
initFilterLog(c, basePath, config)
|
|
if c.CriticalHandler == nil && c.ErrorHandler != nil {
|
|
c.CriticalHandler = c.ErrorHandler
|
|
}
|
|
initRequestLog(c, basePath, config)
|
|
}
|
|
|
|
return c
|
|
}
|
|
|
|
// Init the log.all configuration options.
|
|
func initAllLog(c *CompositeMultiHandler, basePath string, config *config.Context) {
|
|
if config != nil {
|
|
extraLogFlag := config.BoolDefault(SpecialUseFlag, false)
|
|
if output, found := config.String("log.all.output"); found {
|
|
// Set all output for the specified handler
|
|
if extraLogFlag {
|
|
log.Printf("Adding standard handler for levels to >%s< ", output)
|
|
}
|
|
initHandlerFor(c, output, basePath, NewLogOptions(config, true, nil, LvlAllList...))
|
|
}
|
|
}
|
|
}
|
|
|
|
// Init the filter options
|
|
// log.all.filter ....
|
|
// log.error.filter ....
|
|
func initFilterLog(c *CompositeMultiHandler, basePath string, config *config.Context) {
|
|
if config != nil {
|
|
extraLogFlag := config.BoolDefault(SpecialUseFlag, false)
|
|
|
|
for _, logFilter := range logFilterList {
|
|
// Init for all filters
|
|
for _, name := range []string{
|
|
"all", "debug", "info", "warn", "error", "crit",
|
|
"trace", // TODO trace is deprecated
|
|
} {
|
|
optionList := config.Options(logFilter.LogPrefix + name + logFilter.LogSuffix)
|
|
for _, option := range optionList {
|
|
splitOptions := strings.Split(option, ".")
|
|
keyMap := map[string]interface{}{}
|
|
for x := 3; x < len(splitOptions); x += 2 {
|
|
keyMap[splitOptions[x]] = splitOptions[x+1]
|
|
}
|
|
phandler := logFilter.parentHandler(keyMap)
|
|
if extraLogFlag {
|
|
log.Printf("Adding key map handler %s %s output %s", option, name, config.StringDefault(option, ""))
|
|
fmt.Printf("Adding key map handler %s %s output %s matching %#v\n", option, name, config.StringDefault(option, ""), keyMap)
|
|
}
|
|
|
|
if name == "all" {
|
|
initHandlerFor(c, config.StringDefault(option, ""), basePath, NewLogOptions(config, false, phandler))
|
|
} else {
|
|
initHandlerFor(c, config.StringDefault(option, ""), basePath, NewLogOptions(config, false, phandler, toLevel[name]))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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",
|
|
"trace", // TODO trace is deprecated
|
|
} {
|
|
if config != nil {
|
|
extraLogFlag := config.BoolDefault(SpecialUseFlag, false)
|
|
output, found := config.String("log." + name + ".output")
|
|
if found {
|
|
if extraLogFlag {
|
|
log.Printf("Adding standard handler %s output %s", name, output)
|
|
}
|
|
initHandlerFor(c, output, basePath, NewLogOptions(config, true, nil, toLevel[name]))
|
|
}
|
|
// Gets the list of options with said prefix
|
|
} else {
|
|
initHandlerFor(c, "stderr", basePath, NewLogOptions(config, true, nil, toLevel[name]))
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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
|
|
// context with the word "section=requestlog" to that handler.
|
|
// Note if request logging is not enabled the MatchAbHandler will not be added and the
|
|
// request log messages will be sent out the INFO handler
|
|
outputRequest := "stdout"
|
|
if config != nil {
|
|
outputRequest = config.StringDefault("log.request.output", "")
|
|
}
|
|
oldInfo := c.InfoHandler
|
|
c.InfoHandler = nil
|
|
if outputRequest != "" {
|
|
initHandlerFor(c, outputRequest, basePath, NewLogOptions(config, false, nil, LvlInfo))
|
|
}
|
|
if c.InfoHandler != nil || oldInfo != nil {
|
|
if c.InfoHandler == nil {
|
|
c.InfoHandler = oldInfo
|
|
} else {
|
|
c.InfoHandler = MatchAbHandler("section", "requestlog", c.InfoHandler, oldInfo)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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`.
|
|
func initHandlerFor(c *CompositeMultiHandler, output, basePath string, options *LogOptions) {
|
|
if options.Ctx != nil {
|
|
options.SetExtendedOptions(
|
|
"noColor", !options.Ctx.BoolDefault("log.colorize", true),
|
|
"smallDate", options.Ctx.BoolDefault("log.smallDate", true),
|
|
"maxSize", options.Ctx.IntDefault("log.maxsize", 1024*10),
|
|
"maxAge", options.Ctx.IntDefault("log.maxage", 14),
|
|
"maxBackups", options.Ctx.IntDefault("log.maxbackups", 14),
|
|
"compressBackups", !options.Ctx.BoolDefault("log.compressBackups", true),
|
|
)
|
|
}
|
|
|
|
output = strings.TrimSpace(output)
|
|
if funcHandler, found := LogFunctionMap[output]; found {
|
|
funcHandler(c, options)
|
|
} else {
|
|
switch output {
|
|
case "":
|
|
fallthrough
|
|
case "off":
|
|
// No handler, discard data
|
|
default:
|
|
// Write to file specified
|
|
if !filepath.IsAbs(output) {
|
|
output = filepath.Join(basePath, output)
|
|
}
|
|
|
|
if err := os.MkdirAll(filepath.Dir(output), 0755); err != nil {
|
|
log.Panic(err)
|
|
}
|
|
|
|
if strings.HasSuffix(output, "json") {
|
|
c.SetJSONFile(output, options)
|
|
} else {
|
|
// Override defaults for a terminal file
|
|
options.SetExtendedOptions("noColor", true)
|
|
options.SetExtendedOptions("smallDate", false)
|
|
c.SetTerminalFile(output, options)
|
|
}
|
|
}
|
|
}
|
|
}
|