mirror of
https://github.com/astaxie/beego.git
synced 2024-11-21 21:30:54 +00:00
Add custom logging format functionality and global formatter functionality
This commit is contained in:
parent
09afe0ae8e
commit
ed1d2c7f6e
@ -23,13 +23,15 @@ import (
|
|||||||
// connWriter implements LoggerInterface.
|
// connWriter implements LoggerInterface.
|
||||||
// Writes messages in keep-live tcp connection.
|
// Writes messages in keep-live tcp connection.
|
||||||
type connWriter struct {
|
type connWriter struct {
|
||||||
lg *logWriter
|
lg *logWriter
|
||||||
innerWriter io.WriteCloser
|
innerWriter io.WriteCloser
|
||||||
ReconnectOnMsg bool `json:"reconnectOnMsg"`
|
UseCustomFormatter bool
|
||||||
Reconnect bool `json:"reconnect"`
|
CustomFormatter func(*LogMsg) string
|
||||||
Net string `json:"net"`
|
ReconnectOnMsg bool `json:"reconnectOnMsg"`
|
||||||
Addr string `json:"addr"`
|
Reconnect bool `json:"reconnect"`
|
||||||
Level int `json:"level"`
|
Net string `json:"net"`
|
||||||
|
Addr string `json:"addr"`
|
||||||
|
Level int `json:"level"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConn creates new ConnWrite returning as LoggerInterface.
|
// NewConn creates new ConnWrite returning as LoggerInterface.
|
||||||
@ -45,7 +47,14 @@ func (c *connWriter) Format(lm *LogMsg) string {
|
|||||||
|
|
||||||
// Init initializes a connection writer with json config.
|
// Init initializes a connection writer with json config.
|
||||||
// json config only needs they "level" key
|
// json config only needs they "level" key
|
||||||
func (c *connWriter) Init(jsonConfig string) error {
|
func (c *connWriter) Init(jsonConfig string, LogFormatter ...func(*LogMsg) string) error {
|
||||||
|
for _, elem := range LogFormatter {
|
||||||
|
if elem != nil {
|
||||||
|
c.UseCustomFormatter = true
|
||||||
|
c.CustomFormatter = elem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return json.Unmarshal([]byte(jsonConfig), c)
|
return json.Unmarshal([]byte(jsonConfig), c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,9 +47,11 @@ var colors = []brush{
|
|||||||
|
|
||||||
// consoleWriter implements LoggerInterface and writes messages to terminal.
|
// consoleWriter implements LoggerInterface and writes messages to terminal.
|
||||||
type consoleWriter struct {
|
type consoleWriter struct {
|
||||||
lg *logWriter
|
lg *logWriter
|
||||||
Level int `json:"level"`
|
UseCustomFormatter bool
|
||||||
Colorful bool `json:"color"` //this filed is useful only when system's terminal supports color
|
CustomFormatter func(*LogMsg) string
|
||||||
|
Level int `json:"level"`
|
||||||
|
Colorful bool `json:"color"` //this filed is useful only when system's terminal supports color
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *consoleWriter) Format(lm *LogMsg) string {
|
func (c *consoleWriter) Format(lm *LogMsg) string {
|
||||||
@ -62,7 +64,7 @@ func (c *consoleWriter) Format(lm *LogMsg) string {
|
|||||||
h, _, _ := formatTimeHeader(lm.When)
|
h, _, _ := formatTimeHeader(lm.When)
|
||||||
bytes := append(append(h, msg...), '\n')
|
bytes := append(append(h, msg...), '\n')
|
||||||
|
|
||||||
return "eee" + string(bytes)
|
return string(bytes)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,10 +80,18 @@ func NewConsole() Logger {
|
|||||||
|
|
||||||
// Init initianlizes the console logger.
|
// Init initianlizes the console logger.
|
||||||
// jsonConfig must be in the format '{"level":LevelTrace}'
|
// jsonConfig must be in the format '{"level":LevelTrace}'
|
||||||
func (c *consoleWriter) Init(jsonConfig string) error {
|
func (c *consoleWriter) Init(jsonConfig string, LogFormatter ...func(*LogMsg) string) error {
|
||||||
|
for _, elem := range LogFormatter {
|
||||||
|
if elem != nil {
|
||||||
|
c.UseCustomFormatter = true
|
||||||
|
c.CustomFormatter = elem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(jsonConfig) == 0 {
|
if len(jsonConfig) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return json.Unmarshal([]byte(jsonConfig), c)
|
return json.Unmarshal([]byte(jsonConfig), c)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +104,15 @@ func (c *consoleWriter) WriteMsg(lm *LogMsg) error {
|
|||||||
if c.Colorful {
|
if c.Colorful {
|
||||||
lm.Msg = strings.Replace(lm.Msg, levelPrefix[lm.Level], colors[lm.Level](levelPrefix[lm.Level]), 1)
|
lm.Msg = strings.Replace(lm.Msg, levelPrefix[lm.Level], colors[lm.Level](levelPrefix[lm.Level]), 1)
|
||||||
}
|
}
|
||||||
msg := c.Format(lm)
|
|
||||||
|
msg := ""
|
||||||
|
|
||||||
|
if c.UseCustomFormatter {
|
||||||
|
msg = c.CustomFormatter(lm)
|
||||||
|
} else {
|
||||||
|
msg = c.Format(lm)
|
||||||
|
}
|
||||||
|
|
||||||
c.lg.writeln(msg)
|
c.lg.writeln(msg)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,9 @@ type fileLogWriter struct {
|
|||||||
hourlyOpenDate int
|
hourlyOpenDate int
|
||||||
hourlyOpenTime time.Time
|
hourlyOpenTime time.Time
|
||||||
|
|
||||||
|
UseCustomFormatter bool
|
||||||
|
CustomFormatter func(*LogMsg) string
|
||||||
|
|
||||||
Rotate bool `json:"rotate"`
|
Rotate bool `json:"rotate"`
|
||||||
|
|
||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
@ -104,7 +107,14 @@ func (w *fileLogWriter) Format(lm *LogMsg) string {
|
|||||||
// "rotate":true,
|
// "rotate":true,
|
||||||
// "perm":"0600"
|
// "perm":"0600"
|
||||||
// }
|
// }
|
||||||
func (w *fileLogWriter) Init(jsonConfig string) error {
|
func (w *fileLogWriter) Init(jsonConfig string, LogFormatter ...func(*LogMsg) string) error {
|
||||||
|
for _, elem := range LogFormatter {
|
||||||
|
if elem != nil {
|
||||||
|
w.UseCustomFormatter = true
|
||||||
|
w.CustomFormatter = elem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err := json.Unmarshal([]byte(jsonConfig), w)
|
err := json.Unmarshal([]byte(jsonConfig), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -153,7 +163,13 @@ func (w *fileLogWriter) WriteMsg(lm *LogMsg) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
hd, d, h := formatTimeHeader(lm.When)
|
hd, d, h := formatTimeHeader(lm.When)
|
||||||
msg := w.Format(lm)
|
msg := ""
|
||||||
|
if w.UseCustomFormatter {
|
||||||
|
msg = w.CustomFormatter(lm)
|
||||||
|
} else {
|
||||||
|
msg = w.Format(lm)
|
||||||
|
}
|
||||||
|
|
||||||
msg = fmt.Sprintf("%s %s\n", string(hd), msg)
|
msg = fmt.Sprintf("%s %s\n", string(hd), msg)
|
||||||
if w.Rotate {
|
if w.Rotate {
|
||||||
w.RLock()
|
w.RLock()
|
||||||
|
@ -9,12 +9,14 @@ import (
|
|||||||
|
|
||||||
// JLWriter implements beego LoggerInterface and is used to send jiaoliao webhook
|
// JLWriter implements beego LoggerInterface and is used to send jiaoliao webhook
|
||||||
type JLWriter struct {
|
type JLWriter struct {
|
||||||
AuthorName string `json:"authorname"`
|
AuthorName string `json:"authorname"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
WebhookURL string `json:"webhookurl"`
|
WebhookURL string `json:"webhookurl"`
|
||||||
RedirectURL string `json:"redirecturl,omitempty"`
|
RedirectURL string `json:"redirecturl,omitempty"`
|
||||||
ImageURL string `json:"imageurl,omitempty"`
|
ImageURL string `json:"imageurl,omitempty"`
|
||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
|
UseCustomFormatter bool
|
||||||
|
CustomFormatter func(*LogMsg) string
|
||||||
}
|
}
|
||||||
|
|
||||||
// newJLWriter creates jiaoliao writer.
|
// newJLWriter creates jiaoliao writer.
|
||||||
@ -23,7 +25,14 @@ func newJLWriter() Logger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Init JLWriter with json config string
|
// Init JLWriter with json config string
|
||||||
func (s *JLWriter) Init(jsonconfig string) error {
|
func (s *JLWriter) Init(jsonconfig string, LogFormatter ...func(*LogMsg) string) error {
|
||||||
|
for _, elem := range LogFormatter {
|
||||||
|
if elem != nil {
|
||||||
|
s.UseCustomFormatter = true
|
||||||
|
s.CustomFormatter = elem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return json.Unmarshal([]byte(jsonconfig), s)
|
return json.Unmarshal([]byte(jsonconfig), s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ type newLoggerFunc func() Logger
|
|||||||
|
|
||||||
// Logger defines the behavior of a log provider.
|
// Logger defines the behavior of a log provider.
|
||||||
type Logger interface {
|
type Logger interface {
|
||||||
Init(config string) error
|
Init(config string, LogFormatter ...func(*LogMsg) string) error
|
||||||
WriteMsg(lm *LogMsg) error
|
WriteMsg(lm *LogMsg) error
|
||||||
Format(lm *LogMsg) string
|
Format(lm *LogMsg) string
|
||||||
Destroy()
|
Destroy()
|
||||||
@ -115,6 +115,7 @@ type BeeLogger struct {
|
|||||||
init bool
|
init bool
|
||||||
enableFuncCallDepth bool
|
enableFuncCallDepth bool
|
||||||
loggerFuncCallDepth int
|
loggerFuncCallDepth int
|
||||||
|
globalFormatter func(*LogMsg) string
|
||||||
enableFullFilePath bool
|
enableFullFilePath bool
|
||||||
asynchronous bool
|
asynchronous bool
|
||||||
prefix string
|
prefix string
|
||||||
@ -129,8 +130,6 @@ const defaultAsyncMsgLen = 1e3
|
|||||||
|
|
||||||
type nameLogger struct {
|
type nameLogger struct {
|
||||||
Logger
|
Logger
|
||||||
// Formatter func(*LogMsg) string
|
|
||||||
LogFormatter
|
|
||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +205,16 @@ func (bl *BeeLogger) setLogger(adapterName string, configs ...string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lg := logAdapter()
|
lg := logAdapter()
|
||||||
err := lg.Init(config)
|
var err error
|
||||||
|
|
||||||
|
// Global formatter overrides the default set formatter
|
||||||
|
// but not adapter specific formatters set with logs.SetLoggerWithOpts()
|
||||||
|
if bl.globalFormatter != nil {
|
||||||
|
err = lg.Init(config, bl.globalFormatter)
|
||||||
|
} else {
|
||||||
|
err = lg.Init(config)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "logs.BeeLogger.SetLogger: "+err.Error())
|
fmt.Fprintln(os.Stderr, "logs.BeeLogger.SetLogger: "+err.Error())
|
||||||
return err
|
return err
|
||||||
@ -248,7 +256,6 @@ func (bl *BeeLogger) DelLogger(adapterName string) error {
|
|||||||
|
|
||||||
func (bl *BeeLogger) writeToLoggers(lm *LogMsg) {
|
func (bl *BeeLogger) writeToLoggers(lm *LogMsg) {
|
||||||
for _, l := range bl.outputs {
|
for _, l := range bl.outputs {
|
||||||
// fmt.Println("Formatted: ", l.Format(lm))
|
|
||||||
err := l.WriteMsg(lm)
|
err := l.WriteMsg(lm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "unable to WriteMsg to adapter:%v,error:%v\n", l.name, err)
|
fmt.Fprintf(os.Stderr, "unable to WriteMsg to adapter:%v,error:%v\n", l.name, err)
|
||||||
@ -394,6 +401,74 @@ func (bl *BeeLogger) startLogger() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetLoggerWithOpts sets a log adapter with a user defined logging format. Config must be valid JSON
|
||||||
|
// such as: {"interval":360}
|
||||||
|
func (bl *BeeLogger) setLoggerWithOpts(adapterName string, formatterFunc func(*LogMsg) string, configs ...string) error {
|
||||||
|
config := append(configs, "{}")[0]
|
||||||
|
for _, l := range bl.outputs {
|
||||||
|
if l.name == adapterName {
|
||||||
|
return fmt.Errorf("logs: duplicate adaptername %q (you have set this logger before)", adapterName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logAdapter, ok := adapters[adapterName]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("logs: unknown adaptername %q (forgotten Register?)", adapterName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if formatterFunc == nil {
|
||||||
|
return fmt.Errorf("No formatter set for %s log adapter", adapterName)
|
||||||
|
}
|
||||||
|
|
||||||
|
lg := logAdapter()
|
||||||
|
err := lg.Init(config, formatterFunc)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "logs.BeeLogger.SetLogger: "+err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
bl.outputs = append(bl.outputs, &nameLogger{
|
||||||
|
name: adapterName,
|
||||||
|
Logger: lg,
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLogger provides a given logger adapter into BeeLogger with config string.
|
||||||
|
func (bl *BeeLogger) SetLoggerWithOpts(adapterName string, formatterFunc func(*LogMsg) string, configs ...string) error {
|
||||||
|
bl.lock.Lock()
|
||||||
|
defer bl.lock.Unlock()
|
||||||
|
if !bl.init {
|
||||||
|
bl.outputs = []*nameLogger{}
|
||||||
|
bl.init = true
|
||||||
|
}
|
||||||
|
return bl.setLoggerWithOpts(adapterName, formatterFunc, configs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLoggerWIthOpts sets a given log adapter with a custom log adapter.
|
||||||
|
// Log Adapter must be given in the form common.SimpleKV{Key: "formatter": Value: struct.FormatFunc}
|
||||||
|
// where FormatFunc has the signature func(*LogMsg) string
|
||||||
|
func SetLoggerWithOpts(adapter string, config []string, formatterFunc func(*LogMsg) string) error {
|
||||||
|
err := beeLogger.SetLoggerWithOpts(adapter, formatterFunc, config...)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bl *BeeLogger) setGlobalFormatter(fmtter func(*LogMsg) string) error {
|
||||||
|
bl.globalFormatter = fmtter
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGlobalFormatter sets the global formatter for all log adapters
|
||||||
|
// This overrides and other individually set adapter
|
||||||
|
func SetGlobalFormatter(fmtter func(*LogMsg) string) error {
|
||||||
|
return beeLogger.setGlobalFormatter(fmtter)
|
||||||
|
}
|
||||||
|
|
||||||
// Emergency Log EMERGENCY level message.
|
// Emergency Log EMERGENCY level message.
|
||||||
func (bl *BeeLogger) Emergency(format string, v ...interface{}) {
|
func (bl *BeeLogger) Emergency(format string, v ...interface{}) {
|
||||||
if LevelEmergency > bl.level {
|
if LevelEmergency > bl.level {
|
||||||
|
@ -24,9 +24,11 @@ import (
|
|||||||
// and write the error-level logs to project.error.log and write the debug-level logs to project.debug.log
|
// and write the error-level logs to project.error.log and write the debug-level logs to project.debug.log
|
||||||
// the rotate attribute also acts like fileLogWriter
|
// the rotate attribute also acts like fileLogWriter
|
||||||
type multiFileLogWriter struct {
|
type multiFileLogWriter struct {
|
||||||
writers [LevelDebug + 1 + 1]*fileLogWriter // the last one for fullLogWriter
|
writers [LevelDebug + 1 + 1]*fileLogWriter // the last one for fullLogWriter
|
||||||
fullLogWriter *fileLogWriter
|
fullLogWriter *fileLogWriter
|
||||||
Separate []string `json:"separate"`
|
Separate []string `json:"separate"`
|
||||||
|
UseCustomFormatter bool
|
||||||
|
CustomFormatter func(*LogMsg) string
|
||||||
}
|
}
|
||||||
|
|
||||||
var levelNames = [...]string{"emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"}
|
var levelNames = [...]string{"emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"}
|
||||||
@ -44,7 +46,14 @@ var levelNames = [...]string{"emergency", "alert", "critical", "error", "warning
|
|||||||
// "separate":["emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"],
|
// "separate":["emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"],
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func (f *multiFileLogWriter) Init(config string) error {
|
func (f *multiFileLogWriter) Init(config string, LogFormatter ...func(*LogMsg) string) error {
|
||||||
|
for _, elem := range LogFormatter {
|
||||||
|
if elem != nil {
|
||||||
|
f.UseCustomFormatter = true
|
||||||
|
f.CustomFormatter = elem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
writer := newFileWriter().(*fileLogWriter)
|
writer := newFileWriter().(*fileLogWriter)
|
||||||
err := writer.Init(config)
|
err := writer.Init(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -74,7 +83,6 @@ func (f *multiFileLogWriter) Init(config string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,8 +9,10 @@ import (
|
|||||||
|
|
||||||
// SLACKWriter implements beego LoggerInterface and is used to send jiaoliao webhook
|
// SLACKWriter implements beego LoggerInterface and is used to send jiaoliao webhook
|
||||||
type SLACKWriter struct {
|
type SLACKWriter struct {
|
||||||
WebhookURL string `json:"webhookurl"`
|
WebhookURL string `json:"webhookurl"`
|
||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
|
UseCustomFormatter bool
|
||||||
|
CustomFormatter func(*LogMsg) string
|
||||||
}
|
}
|
||||||
|
|
||||||
// newSLACKWriter creates jiaoliao writer.
|
// newSLACKWriter creates jiaoliao writer.
|
||||||
@ -23,7 +25,14 @@ func (s *SLACKWriter) Format(lm *LogMsg) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Init SLACKWriter with json config string
|
// Init SLACKWriter with json config string
|
||||||
func (s *SLACKWriter) Init(jsonconfig string) error {
|
func (s *SLACKWriter) Init(jsonconfig string, LogFormatter ...func(*LogMsg) string) error {
|
||||||
|
for _, elem := range LogFormatter {
|
||||||
|
if elem != nil {
|
||||||
|
s.UseCustomFormatter = true
|
||||||
|
s.CustomFormatter = elem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return json.Unmarshal([]byte(jsonconfig), s)
|
return json.Unmarshal([]byte(jsonconfig), s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,8 @@ type SMTPWriter struct {
|
|||||||
FromAddress string `json:"fromAddress"`
|
FromAddress string `json:"fromAddress"`
|
||||||
RecipientAddresses []string `json:"sendTos"`
|
RecipientAddresses []string `json:"sendTos"`
|
||||||
Level int `json:"level"`
|
Level int `json:"level"`
|
||||||
|
UseCustomFormatter bool
|
||||||
|
CustomFormatter func(*LogMsg) string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSMTPWriter creates the smtp writer.
|
// NewSMTPWriter creates the smtp writer.
|
||||||
@ -50,7 +52,14 @@ func newSMTPWriter() Logger {
|
|||||||
// "sendTos":["email1","email2"],
|
// "sendTos":["email1","email2"],
|
||||||
// "level":LevelError
|
// "level":LevelError
|
||||||
// }
|
// }
|
||||||
func (s *SMTPWriter) Init(jsonconfig string) error {
|
func (s *SMTPWriter) Init(jsonconfig string, LogFormatter ...func(*LogMsg) string) error {
|
||||||
|
for _, elem := range LogFormatter {
|
||||||
|
if elem != nil {
|
||||||
|
s.UseCustomFormatter = true
|
||||||
|
s.CustomFormatter = elem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return json.Unmarshal([]byte(jsonconfig), s)
|
return json.Unmarshal([]byte(jsonconfig), s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user