mirror of
https://gitee.com/johng/gf
synced 2026-06-10 19:31:44 +08:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6f0aee1cc5 | |||
| 3575e20137 | |||
| f69f529258 | |||
| 3e7416ca7d | |||
| 9da883a50c | |||
| ea3e03aaba |
@ -83,7 +83,7 @@ func SetDebug(debug bool) {
|
||||
logger.SetDebug(debug)
|
||||
}
|
||||
|
||||
// SetStdPrint sets whether ouptput the logging contents to stdout, which is false in default.
|
||||
// SetStdoutPrint sets whether ouptput the logging contents to stdout, which is false in default.
|
||||
func SetStdoutPrint(enabled bool) {
|
||||
logger.SetStdoutPrint(enabled)
|
||||
}
|
||||
|
||||
@ -40,6 +40,13 @@ func Level(level int) *Logger {
|
||||
return logger.Level(level)
|
||||
}
|
||||
|
||||
// Skip is a chaining function,
|
||||
// which sets backtrace skip for the current logging content output.
|
||||
// It also affects the caller file path checks when line number printing enabled.
|
||||
func Skip(skip int) *Logger {
|
||||
return logger.Skip(skip)
|
||||
}
|
||||
|
||||
// Backtrace is a chaining function,
|
||||
// which sets backtrace options for the current logging content output .
|
||||
func Backtrace(enabled bool, skip...int) *Logger {
|
||||
|
||||
@ -75,10 +75,6 @@ func New() *Logger {
|
||||
headerPrint : true,
|
||||
stdoutPrint : true,
|
||||
}
|
||||
// Default writer
|
||||
logger.writer = &Writer {
|
||||
logger : logger,
|
||||
}
|
||||
return logger
|
||||
}
|
||||
|
||||
@ -96,10 +92,6 @@ func (l *Logger) Clone() *Logger {
|
||||
headerPrint : l.headerPrint,
|
||||
stdoutPrint : l.stdoutPrint,
|
||||
}
|
||||
// Default writer
|
||||
logger.writer = &Writer {
|
||||
logger : logger,
|
||||
}
|
||||
return logger
|
||||
}
|
||||
|
||||
@ -156,7 +148,7 @@ func (l *Logger) SetWriter(writer io.Writer) {
|
||||
}
|
||||
|
||||
// GetWriter returns the customized writer object, which implements the io.Writer interface.
|
||||
// It returns a default writer if no customized writer set.
|
||||
// It returns nil if no writer previously set.
|
||||
func (l *Logger) GetWriter() io.Writer {
|
||||
return l.writer
|
||||
}
|
||||
@ -217,7 +209,7 @@ func (l *Logger) SetFile(pattern string) {
|
||||
l.file = pattern
|
||||
}
|
||||
|
||||
// SetStdPrint sets whether output the logging contents to stdout, which is true in default.
|
||||
// SetStdoutPrint sets whether output the logging contents to stdout, which is true in default.
|
||||
func (l *Logger) SetStdoutPrint(enabled bool) {
|
||||
l.stdoutPrint = enabled
|
||||
}
|
||||
@ -234,14 +226,12 @@ func (l *Logger) SetPrefix(prefix string) {
|
||||
}
|
||||
|
||||
// print prints <s> to defined writer, logging file or passed <std>.
|
||||
// It internally uses memory lock for file logging to ensure logging sequence.
|
||||
func (l *Logger) print(std io.Writer, s string) {
|
||||
// Customized writer has the most high priority.
|
||||
// Custom writer has the most high priority.
|
||||
if l.headerPrint {
|
||||
s = l.format(s)
|
||||
}
|
||||
writer := l.GetWriter()
|
||||
if _, ok := writer.(*Writer); ok {
|
||||
if l.writer == nil {
|
||||
if f := l.getFilePointer(); f != nil {
|
||||
defer f.Close()
|
||||
if _, err := io.WriteString(f, s); err != nil {
|
||||
@ -255,7 +245,7 @@ func (l *Logger) print(std io.Writer, s string) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if _, err := std.Write([]byte(s)); err != nil {
|
||||
if _, err := l.writer.Write([]byte(s)); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
}
|
||||
}
|
||||
@ -307,10 +297,9 @@ func (l *Logger) GetBacktrace(skip...int) string {
|
||||
customSkip = skip[0]
|
||||
}
|
||||
backtrace := ""
|
||||
index := 1
|
||||
from := 0
|
||||
// 首先定位业务文件开始位置
|
||||
for i := 0; i < 10; i++ {
|
||||
// Find the caller position exclusive of the glog file.
|
||||
for i := 0; i < 100; i++ {
|
||||
if _, file, _, ok := runtime.Caller(i); ok {
|
||||
if !gregex.IsMatchString("/g/os/glog/glog.+$", file) {
|
||||
from = i
|
||||
@ -318,11 +307,11 @@ func (l *Logger) GetBacktrace(skip...int) string {
|
||||
}
|
||||
}
|
||||
}
|
||||
// 从业务文件开始位置根据自定义的skip开始backtrace
|
||||
// Find the true caller file path using custom skip.
|
||||
index := 1
|
||||
goRoot := runtime.GOROOT()
|
||||
for i := from + customSkip + l.btSkip; i < 10000; i++ {
|
||||
if _, file, cline, ok := runtime.Caller(i); ok && file != "" {
|
||||
// 不打印出go源码路径及glog包文件路径,日志打印必须从业务源码文件开始,且从glog包文件开始检索
|
||||
if (goRoot == "" || !gregex.IsMatchString("^" + goRoot, file)) && !gregex.IsMatchString(`<autogenerated>`, file) {
|
||||
backtrace += fmt.Sprintf(`%d. %s:%d%s`, index, file, cline, ln)
|
||||
index++
|
||||
@ -334,6 +323,34 @@ func (l *Logger) GetBacktrace(skip...int) string {
|
||||
return backtrace
|
||||
}
|
||||
|
||||
// getLongFile returns the absolute file path along with its line number of the caller.
|
||||
func (l *Logger) getLongFile() string {
|
||||
from := 0
|
||||
// Find the caller position exclusive of the glog file.
|
||||
for i := 0; i < 100; i++ {
|
||||
if _, file, line, ok := runtime.Caller(i); ok {
|
||||
if !gregex.IsMatchString("/g/os/glog/glog.+$", file) {
|
||||
from = i
|
||||
break
|
||||
return fmt.Sprintf(`%s:%d`, file, line)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Find the true caller file path using custom skip.
|
||||
goRoot := runtime.GOROOT()
|
||||
for i := from + l.btSkip; i < 10000; i++ {
|
||||
if _, file, line, ok := runtime.Caller(i); ok && file != "" {
|
||||
if (goRoot == "" || !gregex.IsMatchString("^" + goRoot, file)) && !gregex.IsMatchString(`<autogenerated>`, file) {
|
||||
return fmt.Sprintf(`%s:%d`, file, line)
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
// format formats the content according the flags.
|
||||
func (l *Logger) format(content string) string {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
@ -371,14 +388,3 @@ func (l *Logger) format(content string) string {
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// getLongFile returns the absolute file path along with its line number of the caller.
|
||||
func (l *Logger) getLongFile() string {
|
||||
for i := 0; i < 100; i++ {
|
||||
if _, file, line, ok := runtime.Caller(i); ok {
|
||||
if !gregex.IsMatchString("/g/os/glog/glog.+$", file) {
|
||||
return fmt.Sprintf(`%s:%d`, file, line)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
@ -81,6 +81,20 @@ func (l *Logger) Level(level int) *Logger {
|
||||
return logger
|
||||
}
|
||||
|
||||
// Skip is a chaining function,
|
||||
// which sets backtrace skip for the current logging content output.
|
||||
// It also affects the caller file path checks when line number printing enabled.
|
||||
func (l *Logger) Skip(skip int) *Logger {
|
||||
logger := (*Logger)(nil)
|
||||
if l.parent == nil {
|
||||
logger = l.Clone()
|
||||
} else {
|
||||
logger = l
|
||||
}
|
||||
logger.SetBacktraceSkip(skip)
|
||||
return logger
|
||||
}
|
||||
|
||||
// Backtrace is a chaining function,
|
||||
// which sets backtrace options for the current logging content output .
|
||||
func (l *Logger) Backtrace(enabled bool, skip...int) *Logger {
|
||||
|
||||
@ -6,13 +6,9 @@
|
||||
|
||||
package glog
|
||||
|
||||
type Writer struct {
|
||||
logger *Logger
|
||||
}
|
||||
|
||||
// Write implements the io.Writer interface.
|
||||
// It just prints the content with header or level.
|
||||
func (w *Writer) Write(p []byte) (n int, err error) {
|
||||
w.logger.Header(false).Print(string(p))
|
||||
// It just prints the content using Print.
|
||||
func (l *Logger) Write(p []byte) (n int, err error) {
|
||||
l.Header(false).Print(string(p))
|
||||
return len(p), nil
|
||||
}
|
||||
@ -11,7 +11,7 @@ func main() {
|
||||
l := glog.New()
|
||||
path := "/tmp/glog"
|
||||
l.SetPath(path)
|
||||
l.SetStdPrint(false)
|
||||
l.SetStdoutPrint(false)
|
||||
// 使用默认文件名称格式
|
||||
l.Println("标准文件名称格式,使用当前时间时期")
|
||||
// 通过SetFile设置文件名称格式
|
||||
|
||||
@ -7,9 +7,9 @@ import (
|
||||
func main() {
|
||||
l := glog.New()
|
||||
l.SetFlags(glog.F_TIME_TIME|glog.F_FILE_SHORT)
|
||||
l.Println("123")
|
||||
l.Println("time and short line number")
|
||||
l.SetFlags(glog.F_TIME_MILLI|glog.F_FILE_LONG)
|
||||
l.Println("123")
|
||||
l.Println("time with millisecond and long line number")
|
||||
l.SetFlags(glog.F_TIME_STD|glog.F_FILE_LONG)
|
||||
l.Println("123")
|
||||
l.Println("standard time format and long line number")
|
||||
}
|
||||
|
||||
@ -5,6 +5,6 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
glog.Line().Println("123")
|
||||
glog.Line(true).Println("123")
|
||||
glog.Line().Println("this is the short file name with its line number")
|
||||
glog.Line(true).Println("lone file name with line number")
|
||||
}
|
||||
|
||||
14
geg/os/glog/glog_line2.go
Normal file
14
geg/os/glog/glog_line2.go
Normal file
@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/g/os/glog"
|
||||
)
|
||||
|
||||
func PrintLog(content string) {
|
||||
glog.Skip(1).Line().Println("line number with skip:", content)
|
||||
glog.Line().Println("line number without skip:", content)
|
||||
}
|
||||
|
||||
func main() {
|
||||
PrintLog("just test")
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/g/os/glog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
w := glog.GetWriter()
|
||||
w.Write([]byte("hello"))
|
||||
|
||||
glog.Path("/tmp/glog/test").GetWriter().Write([]byte("hello"))
|
||||
}
|
||||
30
geg/os/glog/glog_writer_greylog.go
Normal file
30
geg/os/glog/glog_writer_greylog.go
Normal file
@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
//import (
|
||||
// "github.com/gogf/gf/g/os/glog"
|
||||
// "github.com/robertkowalski/graylog-golang"
|
||||
//)
|
||||
//
|
||||
//type MyGrayLogWriter struct {
|
||||
// gelf *gelf.Gelf
|
||||
// logger *glog.Logger
|
||||
//}
|
||||
//
|
||||
//func (w *MyGrayLogWriter) Write(p []byte) (n int, err error) {
|
||||
// w.gelf.Send(p)
|
||||
// return w.logger.Write(p)
|
||||
//}
|
||||
//
|
||||
//func main() {
|
||||
// glog.SetWriter(&MyGrayLogWriter{
|
||||
// logger : glog.New(),
|
||||
// gelf : gelf.New(gelf.Config{
|
||||
// GraylogPort : 80,
|
||||
// GraylogHostname : "graylog-host.com",
|
||||
// Connection : "wan",
|
||||
// MaxChunkSizeWan : 42,
|
||||
// MaxChunkSizeLan : 1337,
|
||||
// }),
|
||||
// })
|
||||
// glog.Println("test log")
|
||||
//}
|
||||
28
geg/os/glog/glog_writer_hook.go
Normal file
28
geg/os/glog/glog_writer_hook.go
Normal file
@ -0,0 +1,28 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/g/net/ghttp"
|
||||
"github.com/gogf/gf/g/os/glog"
|
||||
"github.com/gogf/gf/g/text/gregex"
|
||||
)
|
||||
|
||||
type MyWriter struct {
|
||||
logger *glog.Logger
|
||||
}
|
||||
|
||||
func (w *MyWriter) Write(p []byte) (n int, err error) {
|
||||
s := string(p)
|
||||
if gregex.IsMatchString(`\[(PANI|FATA)\]`, s) {
|
||||
fmt.Println("SERIOUS ISSUE OCCURRED!! I'd better tell monitor in first time!")
|
||||
ghttp.PostContent("http://monitor.mydomain.com", s)
|
||||
}
|
||||
return w.logger.Write(p)
|
||||
}
|
||||
|
||||
func main() {
|
||||
glog.SetWriter(&MyWriter{
|
||||
logger : glog.New(),
|
||||
})
|
||||
glog.Fatal("FATAL ERROR")
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package gf
|
||||
|
||||
const VERSION = "v1.6.14"
|
||||
const VERSION = "v1.6.15"
|
||||
const AUTHORS = "john<john@goframe.org>"
|
||||
|
||||
Reference in New Issue
Block a user