Compare commits

...

6 Commits

Author SHA1 Message Date
6f0aee1cc5 version updates 2019-05-23 20:43:09 +08:00
3575e20137 update Writer feature of glog 2019-05-23 20:34:06 +08:00
f69f529258 Merge branch 'master' into develop 2019-05-23 19:14:19 +08:00
3e7416ca7d add Skip for glog 2019-05-23 19:14:16 +08:00
9da883a50c comment updates 2019-05-23 11:49:33 +08:00
ea3e03aaba example updates for glog 2019-05-23 09:26:37 +08:00
13 changed files with 141 additions and 58 deletions

View File

@ -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)
}

View File

@ -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 {

View File

@ -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 ""
}

View File

@ -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 {

View File

@ -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
}

View File

@ -11,7 +11,7 @@ func main() {
l := glog.New()
path := "/tmp/glog"
l.SetPath(path)
l.SetStdPrint(false)
l.SetStdoutPrint(false)
// 使用默认文件名称格式
l.Println("标准文件名称格式,使用当前时间时期")
// 通过SetFile设置文件名称格式

View File

@ -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")
}

View File

@ -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
View 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")
}

View File

@ -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"))
}

View 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")
//}

View 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")
}

View File

@ -1,4 +1,4 @@
package gf
const VERSION = "v1.6.14"
const VERSION = "v1.6.15"
const AUTHORS = "john<john@goframe.org>"