jeanphorn / log4go Goto Github PK
View Code? Open in Web Editor NEWa logging package for golang similar to log4j or log4c++ supporting console, file and network.
a logging package for golang similar to log4j or log4c++ supporting console, file and network.
I'm using log4go in GCP environment with Stackdriver logging. Formatting a log message with pattern like:
"pattern": "{\"severity\": \"%L\", \"message\":\"(%S) %M\"}"
gives Stackdriver the possibility to recognize the loglevel and can so visualize the message in a proper way in the UI and gives the posibility to filter the messages by It's severity.
Unfortunately the Log4go levelstrings defined in
Line 83 in 617cc1d
Log4go | Stackdriver | Match |
---|---|---|
FNST | - | - |
FINE | - | - |
DEBG | DEBUG | NO |
TRAC | TRACE | NO |
INFO | INFO | YES |
WARN | WARN | YES |
EROR | ERROR | NO |
CRIT | CRITICAL | YES |
I'm looking for a possibility to overwrite the fixed levelstrings in log4go with my own levelstrings.
our service uses log4go,we found it will block our program when it got a error because writing file failed. For example, when disk was full, we got an error "FileLogWriter("../log/syncer.log"): write ../log/syncer.log: no space left on device" in stderr and our code was blocked when it try to log. the stack like this
1 runtime.gopark
runtime.goparkunlock
runtime.chansend
runtime.chansend1
github.com/jeanphorn/log4go.(*FileLogWriter).LogWrite
github.com/jeanphorn/log4go.Logger.intLogf
github.com/jeanphorn/log4go.Info
teledb/pkg/syncer.(*Controller).coordinator
teledb/pkg/syncer.(*Controller).Run
main.main.func2
maybe that is because the background goroutine will return when it meet a error
go func() {
defer func() {
if w.file != nil {
fmt.Fprint(w.file, FormatLogRecord(w.trailer, &LogRecord{Created: time.Now()}))
w.file.Close()
}
}()
for {
select {
case <-w.rot:
if err := w.intRotate(); err != nil {
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
return
}
case rec, ok := <-w.rec:
if !ok {
return
}
now := time.Now()
if (w.maxlines > 0 && w.maxlines_curlines >= w.maxlines) ||
(w.maxsize > 0 && w.maxsize_cursize >= w.maxsize) ||
(w.daily && now.Day() != w.daily_opendate) {
if err := w.intRotate(); err != nil {
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
return
}
}
// Sanitize newlines
if w.sanitize {
rec.Message = strings.Replace(rec.Message, "\n", "\\n", -1)
}
// Perform the write
n, err := fmt.Fprint(w.file, FormatLogRecord(w.format, rec))
if err != nil {
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
return
}
// Update the counts
w.maxlines_curlines++
w.maxsize_cursize += n
}
}
}()
and then the channel w.rec
will soon be full, and block the writer
// This is the FileLogWriter's output method
func (w *FileLogWriter) LogWrite(rec *LogRecord) {
w.rec <- rec
}
can we find a better way that will not make our service block ?
I think it would be a good idea if the Crash() function closes all loggers before panic, to output all messages in the queue.
Hi
I am facing couple of issues while implementing log rolling using this library:
If I need to use this library in multiple go files in a project, do i need to load the configuration in each go file? If not, I am trying to load it in single go file and exposing single variable for others to use in them.
While loading the configuration file using relative path (generated absolute path on the go using filesystem.AbsPath()), it gives error - config file .. is nonexistent
Any pointers what could be the issue and how to resolve it?
例如:现在输出 [2019/12/02 17:40:22 CST ] , 可以设置为[2019/12/02 17:40:22.123456789 CST] 这种么
With several of my apps I leave the log lines visible in a console window continuously. I'd like to be able to differentiate warnings, errors, and criticals from the other log lines at a glance by color coding the output based on the log level. This may not be of general interest, but someone else might find it useful.
I'm thinking of adding a new function, SetColors(), that takes an 8 item array where each item is a color to use for that log level. It would default to all NONE so the behavior would be as it is now. The writer would output the proper control string to set that color at the front of the log line and the control string to reset back to "none" at the end. A NONE value would not write anything extra. Overhead should be small, a couple of if statements, a control string lookup, and writing an extra 9 bytes. Obviously, I hope, this would only be for console logging.
I'll be prototyping this tomorrow (it's bedtime now). If this sounds like something that you would accept, I'll put in a pull request for you to look at. Your log4go repo seems to be the only fork that is being actively maintained so I'd rather add it to your's rather than fork it again.
I want to compress the output log, but I did not find how to support this function in this package. I want to ask, will this feature be supported in the future?
goroutine 17 [running]:
bytes.(*Buffer).WriteString(0xc0000fe310, 0x0, 0x7, 0x3, 0x3, 0x0)
C:/Go/src/bytes/buffer.go:188 +0xc7
github.com/jeanphorn/log4go.FormatLogRecord(0x731e02, 0x19, 0xc000050410, 0x1, 0x1)
C:/Users/Administrator/go/src/github.com/jeanphorn/log4go/pattlog.go:94 +0x44e
github.com/jeanphorn/log4go.(*ConsoleLogWriter).run(0xc000104220, 0x77c140, 0xc00000c018)
C:/Users/Administrator/go/src/github.com/jeanphorn/log4go/termlog.go:34 +0x70
created by github.com/jeanphorn/log4go.NewConsoleLogWriter
C:/Users/Administrator/go/src/github.com/jeanphorn/log4go/termlog.go:26 +0xba
I fixed this bug:
//please patch this file : pattlog.go
func FormatLogRecord(format string, rec *LogRecord) string {
//--------------------------------
//fix crash
defer func() {
if e := recover(); e != nil {
fmt.Printf("Panicing %s\n", e)
}
}()
//--------------------------------
....
func FormatLogRecord(format string, rec *LogRecord) string {
if rec == nil {
return "<nil>"
}
if len(format) == 0 {
return ""
}
out := bytes.NewBuffer(make([]byte, 0, 64))
secs := rec.Created.UnixNano() / 1e9
cache := *formatCache
if cache.LastUpdateSeconds != secs {
month, day, year := rec.Created.Month(), rec.Created.Day(), rec.Created.Year()
hour, minute, second := rec.Created.Hour(), rec.Created.Minute(), rec.Created.Second()
zone, _ := rec.Created.Zone()
updated := &formatCacheType{
LastUpdateSeconds: secs,
shortTime: fmt.Sprintf("%02d:%02d", hour, minute),
shortDate: fmt.Sprintf("%02d/%02d/%02d", day, month, year%100),
longTime: fmt.Sprintf("%02d:%02d:%02d %s", hour, minute, second, zone),
longDate: fmt.Sprintf("%04d/%02d/%02d", year, month, day),
}
cache = *updated
formatCache = updated
}
If i create a NewFileLogWriter and don't close the global default logger, I can easily create a race condition when FormatLogRecord modifies the formatCache. Multiple go routines invoke this function without any locking around this resource.
This is semi-related to this issue #13 which is also a data race condition created in this same function - since the LogRecord is being passed by reference in multiple go routines and rec.Created is modified.
Here is the output when using https://golang.org/doc/articles/race_detector.html
==================
WARNING: DATA RACE
Read at 0x00c0000fc148 by goroutine 8:
github.com/jeanphorn/log4go.FormatLogRecord()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/pattlog.go:46 +0xf9
github.com/jeanphorn/log4go.(*ConsoleLogWriter).run()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:34 +0xa3
Previous write at 0x00c0000fc148 by main goroutine:
my.company/my-service/logger.(*CustomLogWriter).LogWrite()
/Users/me/Development/my-service/logger/CustomLogWriter.go:22 +0x105
[22:36:34 UTC 2020/01/06] [DEFAULT] [INFO] (main.main:55) test
github.com/jeanphorn/log4go.(*Filter).intLogf()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/category.go:69 +0x37f
github.com/jeanphorn/log4go.(*Filter).Info()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/category.go:252 +0x1e3
main.main()
/Users/me/Development/my-service/main.go:55 +0x9ef
Goroutine 8 (running) created at:
github.com/jeanphorn/log4go.NewConsoleLogWriter()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:26 +0x11e
github.com/jeanphorn/log4go.init.0()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/log4go.go:160 +0x41
==================
==================
WARNING: DATA RACE
Read at 0x000001dda710 by goroutine 8:
github.com/jeanphorn/log4go.FormatLogRecord()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/pattlog.go:48 +0x182
github.com/jeanphorn/log4go.(*ConsoleLogWriter).run()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:34 +0xa3
Previous write at 0x000001dda710 by goroutine 11:
github.com/jeanphorn/log4go.FormatLogRecord()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/pattlog.go:61 +0x11cb
github.com/jeanphorn/log4go.NewFileLogWriter.func1()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/filelog.go:119 +0x2d8
Goroutine 8 (running) created at:
github.com/jeanphorn/log4go.NewConsoleLogWriter()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:26 +0x11e
github.com/jeanphorn/log4go.init.0()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/log4go.go:160 +0x41
Goroutine 11 (running) created at:
github.com/jeanphorn/log4go.NewFileLogWriter()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/filelog.go:83 +0x3ac
main.main()
/Users/me/Development/my-service/main.go:45 +0x747
==================
==================
WARNING: DATA RACE
Read at 0x00c000190050 by goroutine 8:
github.com/jeanphorn/log4go.FormatLogRecord()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/pattlog.go:48 +0x1a5
github.com/jeanphorn/log4go.(*ConsoleLogWriter).run()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:34 +0xa3
Previous write at 0x00c000190050 by goroutine 11:
github.com/jeanphorn/log4go.FormatLogRecord()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/pattlog.go:54 +0x104b
github.com/jeanphorn/log4go.NewFileLogWriter.func1()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/filelog.go:119 +0x2d8
Goroutine 8 (running) created at:
github.com/jeanphorn/log4go.NewConsoleLogWriter()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:26 +0x11e
github.com/jeanphorn/log4go.init.0()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/log4go.go:160 +0x41
Goroutine 11 (running) created at:
github.com/jeanphorn/log4go.NewFileLogWriter()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/filelog.go:83 +0x3ac
main.main()
/Users/me/Development/my-service/main.go:45 +0x747
==================
==================
WARNING: DATA RACE
Read at 0x00c000190058 by goroutine 8:
github.com/jeanphorn/log4go.FormatLogRecord()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/pattlog.go:48 +0x1a5
github.com/jeanphorn/log4go.(*ConsoleLogWriter).run()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:34 +0xa3
Previous write at 0x00c000190058 by goroutine 11:
github.com/jeanphorn/log4go.FormatLogRecord()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/pattlog.go:55 +0x1073
github.com/jeanphorn/log4go.NewFileLogWriter.func1()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/filelog.go:119 +0x2d8
Goroutine 8 (running) created at:
github.com/jeanphorn/log4go.NewConsoleLogWriter()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:26 +0x11e
github.com/jeanphorn/log4go.init.0()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/log4go.go:160 +0x41
Goroutine 11 (running) created at:
github.com/jeanphorn/log4go.NewFileLogWriter()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/filelog.go:83 +0x3ac
main.main()
/Users/me/Development/my-service/main.go:45 +0x747
==================
==================
WARNING: DATA RACE
Read at 0x00c000190068 by goroutine 8:
github.com/jeanphorn/log4go.FormatLogRecord()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/pattlog.go:48 +0x1a5
github.com/jeanphorn/log4go.(*ConsoleLogWriter).run()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:34 +0xa3
Previous write at 0x00c000190068 by goroutine 11:
github.com/jeanphorn/log4go.FormatLogRecord()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/pattlog.go:56 +0x10b5
github.com/jeanphorn/log4go.NewFileLogWriter.func1()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/filelog.go:119 +0x2d8
Goroutine 8 (running) created at:
github.com/jeanphorn/log4go.NewConsoleLogWriter()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:26 +0x11e
github.com/jeanphorn/log4go.init.0()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/log4go.go:160 +0x41
Goroutine 11 (running) created at:
github.com/jeanphorn/log4go.NewFileLogWriter()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/filelog.go:83 +0x3ac
main.main()
/Users/me/Development/my-service/main.go:45 +0x747
==================
==================
WARNING: DATA RACE
Read at 0x00c000190078 by goroutine 8:
github.com/jeanphorn/log4go.FormatLogRecord()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/pattlog.go:48 +0x1a5
github.com/jeanphorn/log4go.(*ConsoleLogWriter).run()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:34 +0xa3
Previous write at 0x00c000190078 by goroutine 11:
github.com/jeanphorn/log4go.FormatLogRecord()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/pattlog.go:57 +0x10f7
github.com/jeanphorn/log4go.NewFileLogWriter.func1()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/filelog.go:119 +0x2d8
Goroutine 8 (running) created at:
github.com/jeanphorn/log4go.NewConsoleLogWriter()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:26 +0x11e
github.com/jeanphorn/log4go.init.0()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/log4go.go:160 +0x41
Goroutine 11 (running) created at:
github.com/jeanphorn/log4go.NewFileLogWriter()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/filelog.go:83 +0x3ac
main.main()
/Users/me/Development/my-service/main.go:45 +0x747
==================
==================
WARNING: DATA RACE
Read at 0x00c000190088 by goroutine 8:
github.com/jeanphorn/log4go.FormatLogRecord()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/pattlog.go:48 +0x1a5
github.com/jeanphorn/log4go.(*ConsoleLogWriter).run()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:34 +0xa3
Previous write at 0x00c000190088 by goroutine 11:
github.com/jeanphorn/log4go.FormatLogRecord()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/pattlog.go:58 +0x1139
github.com/jeanphorn/log4go.NewFileLogWriter.func1()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/filelog.go:119 +0x2d8
Goroutine 8 (running) created at:
github.com/jeanphorn/log4go.NewConsoleLogWriter()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:26 +0x11e
github.com/jeanphorn/log4go.init.0()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/log4go.go:160 +0x41
Goroutine 11 (running) created at:
github.com/jeanphorn/log4go.NewFileLogWriter()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/filelog.go:83 +0x3ac
main.main()
/Users/me/Development/my-service/main.go:45 +0x747
==================
==================
WARNING: DATA RACE
Read at 0x00c0000fc170 by goroutine 8:
github.com/jeanphorn/log4go.FormatLogRecord()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/pattlog.go:89 +0x62d
github.com/jeanphorn/log4go.(*ConsoleLogWriter).run()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:34 +0xa3
Previous write at 0x00c0000fc170 by main goroutine:
my.company/my-service/logger.(*CustomLogWriter).LogWrite()
/Users/me/Development/my-service/logger/CustomLogWriter.go:23 +0x1dc
github.com/jeanphorn/log4go.(*Filter).intLogf()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/category.go:69 +0x37f
github.com/jeanphorn/log4go.(*Filter).Info()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/category.go:252 +0x1e3
main.main()
/Users/me/Development/my-service/main.go:55 +0x9ef
Goroutine 8 (running) created at:
github.com/jeanphorn/log4go.NewConsoleLogWriter()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/termlog.go:26 +0x11e
github.com/jeanphorn/log4go.init.0()
/Users/me/go/pkg/mod/github.com/jeanphorn/[email protected]/log4go.go:160 +0x41
==================
TRACE and DEBUG log levels are in wrong order: TRACE should be at higher level than DEBUG, i.e. setting config level to DEBUG should not log TRACEs
"console": {
"enable": true,
"level": "FINE"
},这个配置,若配置为enable:false,则直接崩溃。发现原因是category.go的第65行,
default_filter := Global["stdout"]
if lvl > default_filter.Level {}
这里的default_filter 为nil 。
解决办法是这里需要加个判断吧。
今天突然想关掉命令行日志,只保留文件日志发现的这个问题。
why i run "got get github.com/jeanphorn/log4go ",the console print this message:
github.com/jeanphorn/log4go
go/src/github.com/jeanphorn/log4go/jsonconfig.go:68:22: undefined: dst
go/src/github.com/jeanphorn/log4go/jsonconfig.go:71:18: undefined: file.ReadFile
go/src/github.com/jeanphorn/log4go/jsonconfig.go:77:20: undefined: dst
I tried this plugin, but nothing outputs.
package main
import (
"_self"
log "github.com/jeanphorn/log4go"
)
func main() {
log.LoadConfiguration("./log-cfg.json")
// original log4go test
log.Info("normal info test ...")
log.Debug("normal debug test ...")
_self.Say()
}
found that the log file can't roate to another file, ex: system.log, when maxsize will not to change to system.log.1.
code:
lvl := log4go.INFO
switch CFG.UString("log.level", "INFO") {
case "DEBUG":
lvl = log4go.DEBUG
case "INFO":
lvl = log4go.INFO
case "WARNING":
lvl = log4go.WARNING
case "ERROR":
lvl = log4go.ERROR
case "CRITICAL":
lvl = log4go.CRITICAL
default:
lvl = log4go.INFO
}
LOG.AddFilter("stdout", lvl, log4go.NewConsoleLogWriter())
logWriter := log4go.NewFileLogWriter("system.log", true, true)
logWriter.SetRotateSize(10)
logWriter.SetRotateLines(1000)
LOG.AddFilter("log", lvl, logWriter)
用着不错,可是为啥没有那么多星星那?
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x455c82]
goroutine 4 [running]:
bytes.(*Buffer).WriteString(0xc043212850, 0x0, 0x7, 0x3, 0x3, 0x0)
D:/Go/src/bytes/buffer.go:188 +0xb1
github.com/jeanphorn/log4go.FormatLogRecord(0x6e6a0f, 0x19, 0xc04339fc70, 0x1, 0x1)
D:/GOPATH/src/github.com/jeanphorn/log4go/pattlog.go:94 +0x3d6
github.com/jeanphorn/log4go.(*ConsoleLogWriter).run(0xc0420022e0, 0x716a80, 0xc042076008)
D:/GOPATH/src/github.com/jeanphorn/log4go/termlog.go:34 +0x77
created by github.com/jeanphorn/log4go.NewConsoleLogWriter
D:/GOPATH/src/github.com/jeanphorn/log4go/termlog.go:26 +0xc6
exit status 2
Please, add a function to load configuration from a string, not only from file
pattlog.go 第92行, 你这个rec是传给不止一个goroutine, 是指针传递, 所以在任何goroutine都不要无锁写入, 要不会导致崩溃。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.