gf/g/os/glog/glog_logger.go

393 lines
10 KiB
Go
Raw Normal View History

2018-04-19 16:24:48 +08:00
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
// @author john, zseeker
2018-04-19 16:24:48 +08:00
package glog
import (
"os"
"io"
"time"
"fmt"
"strings"
"runtime"
"strconv"
"gitee.com/johng/gf/g/os/gfile"
2018-07-11 17:06:47 +08:00
"gitee.com/johng/gf/g/util/gregex"
2018-08-24 23:41:58 +08:00
"gitee.com/johng/gf/g/container/gtype"
"gitee.com/johng/gf/g/os/gmlock"
2018-04-19 16:24:48 +08:00
)
const (
gDEFAULT_FILE_POOL_FLAGS = os.O_CREATE|os.O_WRONLY|os.O_APPEND
)
// 默认的日志换行符
2018-05-23 18:05:06 +08:00
var ln = "\n"
// 初始化日志换行符
func init() {
if runtime.GOOS == "windows" {
ln = "\r\n"
}
}
2018-08-28 17:06:49 +08:00
// 新建自定义的日志操作对象
func New() *Logger {
2018-08-24 23:41:58 +08:00
return &Logger {
io : nil,
path : gtype.NewString(),
level : gtype.NewInt(defaultLevel.Val()),
btSkip : gtype.NewInt(),
btEnabled : gtype.NewBool(true),
alsoStdPrint : gtype.NewBool(true),
2018-08-24 23:41:58 +08:00
}
}
2018-08-28 17:06:49 +08:00
// Logger深拷贝
func (l *Logger) Clone() *Logger {
return &Logger {
pr : l,
io : l.GetIO(),
path : l.path.Clone(),
2018-08-30 13:00:49 +08:00
level : l.level.Clone(),
btSkip : l.btSkip.Clone(),
btEnabled : l.btEnabled.Clone(),
alsoStdPrint : l.alsoStdPrint.Clone(),
2018-08-24 23:41:58 +08:00
}
}
2018-08-30 13:00:49 +08:00
// 设置日志记录等级
func (l *Logger) SetLevel(level int) {
l.level.Set(level)
}
// 获取日志记录等级
func (l *Logger) GetLevel() int {
return l.level.Val()
}
2018-08-30 13:00:49 +08:00
// 快捷方法打开或关闭DEBU日志信息
func (l *Logger) SetDebug(debug bool) {
l.level.Set(l.level.Val()|LEVEL_DEBU)
}
func (l *Logger) SetBacktrace(enabled bool) {
l.btEnabled.Set(enabled)
}
2018-04-20 17:53:34 +08:00
// 设置BacktraceSkip
func (l *Logger) SetBacktraceSkip(skip int) {
l.btSkip.Set(skip)
}
2018-08-24 23:41:58 +08:00
// 可自定义IO接口IO可以是文件输出、标准输出、网络输出
2018-04-19 16:24:48 +08:00
func (l *Logger) SetIO(w io.Writer) {
l.mu.Lock()
2018-04-19 16:24:48 +08:00
l.io = w
l.mu.Unlock()
2018-04-19 16:24:48 +08:00
}
2018-08-24 23:41:58 +08:00
// 返回自定义的IO默认为nil
2018-04-19 16:24:48 +08:00
func (l *Logger) GetIO() io.Writer {
l.mu.RLock()
r := l.io
l.mu.RUnlock()
return r
}
// 获取默认的文件IO
func (l *Logger) getFilePointer() *os.File {
2018-04-19 16:24:48 +08:00
if path := l.path.Val(); path != "" {
fpath := path + gfile.Separator + time.Now().Format("2006-01-02.log")
if fp, err := os.OpenFile(fpath, gDEFAULT_FILE_POOL_FLAGS, 0666); err == nil {
2018-04-19 16:24:48 +08:00
return fp
} else {
fmt.Fprintln(os.Stderr, err)
}
}
return nil
}
// 设置日志文件的存储目录路径
func (l *Logger) SetPath(path string) error {
//// 检测目录权限
//if !gfile.Exists(path) {
// if err := gfile.Mkdir(path); err != nil {
// fmt.Fprintln(os.Stderr, fmt.Sprintf(`glog mkdir "%s" failed: %s`, path, err.Error()))
// return err
// }
//}
//if !gfile.IsWritable(path) {
// errstr := path + " is no writable for current user"
// fmt.Fprintln(os.Stderr, errstr)
// return errors.New(errstr)
//}
2018-04-19 16:24:48 +08:00
l.path.Set(strings.TrimRight(path, gfile.Separator))
return nil
}
2018-05-24 12:37:55 +08:00
// 设置写日志时开启or关闭控制台打印默认是关闭的
2018-08-28 19:38:05 +08:00
func (l *Logger) SetStdPrint(enabled bool) {
l.alsoStdPrint.Set(enabled)
2018-05-24 12:37:55 +08:00
}
2018-04-19 16:24:48 +08:00
// 这里的写锁保证统一时刻只会写入一行日志,防止串日志的情况
func (l *Logger) print(std io.Writer, s string) {
2018-08-24 23:41:58 +08:00
// 优先使用自定义的IO输出
str := l.format(s)
writer := l.GetIO()
if writer == nil {
2018-08-24 23:41:58 +08:00
// 如果设置的IO为空那么其次判断是否有文件输出设置
// 内部使用了内存锁保证在glog中对同一个日志文件的并发写入不会串日志
if f := l.getFilePointer(); f != nil {
defer f.Close()
key := l.path.Val()
gmlock.Lock(key)
_, err := io.WriteString(f, str)
gmlock.Unlock(key)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
}
2018-04-19 16:24:48 +08:00
}
} else {
if _, err := io.WriteString(writer, str); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
}
}
if l.alsoStdPrint.Val() {
if _, err := io.WriteString(std, str); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
}
2018-04-19 16:24:48 +08:00
}
}
// 核心打印数据方法(标准输出)
func (l *Logger) stdPrint(s string) {
l.print(os.Stdout, s)
}
// 核心打印数据方法(标准错误)
func (l *Logger) errPrint(s string) {
// 记录调用回溯信息
2018-08-28 17:06:49 +08:00
if l.btEnabled.Val() {
2018-09-14 13:02:13 +08:00
backtrace := "Backtrace:" + ln + l.GetBacktrace(3)
2018-08-28 17:06:49 +08:00
if s[len(s) - 1] == byte('\n') {
s = s + backtrace + ln
} else {
s = s + ln + backtrace + ln
}
2018-04-19 16:24:48 +08:00
}
l.print(os.Stderr, s)
}
// 直接打印回溯信息参数skip表示调用端往上多少级开始回溯
func (l *Logger) PrintBacktrace(skip...int) {
customSkip := 1
if len(skip) > 0 {
customSkip += skip[0]
}
l.Println(l.GetBacktrace(customSkip))
}
// 获取文件调用回溯字符串参数skip表示调用端往上多少级开始回溯
func (l *Logger) GetBacktrace(skip...int) string {
customSkip := 0
if len(skip) > 0 {
customSkip += skip[0]
}
backtrace := ""
2018-04-20 17:53:34 +08:00
index := 1
2018-04-19 16:24:48 +08:00
for i := 1; i < 10000; i++ {
if _, cfile, cline, ok := runtime.Caller(customSkip + i + l.btSkip.Val()); ok {
2018-04-19 16:24:48 +08:00
// 不打印出go源码路径
2018-08-31 23:53:57 +08:00
if !gregex.IsMatchString("^" + gfile.GoRootOfBuild(), cfile) && !gregex.IsMatchString(`<autogenerated>`, cfile) {
backtrace += strconv.Itoa(index) + ".\t" + cfile + ":" + strconv.Itoa(cline) + ln
2018-04-20 17:53:34 +08:00
index++
2018-04-19 16:24:48 +08:00
}
} else {
break
}
}
return backtrace
}
func (l *Logger) format(s string) string {
return time.Now().Format("2006-01-02 15:04:05.000 ") + s
}
func (l *Logger) Print(v ...interface{}) {
l.stdPrint(fmt.Sprint(v...))
}
func (l *Logger) Printf(format string, v ...interface{}) {
l.stdPrint(fmt.Sprintf(format, v...))
}
func (l *Logger) Println(v ...interface{}) {
l.stdPrint(fmt.Sprint(v...) + ln)
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Printfln(format string, v ...interface{}) {
l.stdPrint(fmt.Sprintf(format + ln, v...))
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Fatal(v ...interface{}) {
l.errPrint(fmt.Sprint(v...))
os.Exit(1)
}
func (l *Logger) Fatalf(format string, v ...interface{}) {
l.errPrint(fmt.Sprintf(format, v...))
os.Exit(1)
}
func (l *Logger) Fatalln(v ...interface{}) {
l.errPrint(fmt.Sprint(v...) + ln)
2018-04-19 16:24:48 +08:00
os.Exit(1)
}
func (l *Logger) Fatalfln(format string, v ...interface{}) {
l.errPrint(fmt.Sprintf(format + ln, v...))
2018-04-19 16:24:48 +08:00
os.Exit(1)
}
func (l *Logger) Panic(v ...interface{}) {
s := fmt.Sprint(v...)
l.errPrint(s)
panic(s)
}
func (l *Logger) Panicf(format string, v ...interface{}) {
s := fmt.Sprintf(format, v...)
l.errPrint(s)
panic(s)
}
func (l *Logger) Panicln(v ...interface{}) {
s := fmt.Sprint(v...) + ln
2018-04-19 16:24:48 +08:00
l.errPrint(s)
panic(s)
}
func (l *Logger) Panicfln(format string, v ...interface{}) {
s := fmt.Sprintf(format + ln, v...)
2018-04-19 16:24:48 +08:00
l.errPrint(s)
panic(s)
}
func (l *Logger) Info(v ...interface{}) {
if l.checkLevel(LEVEL_INFO) {
2018-08-30 13:00:49 +08:00
l.stdPrint("[INFO] " + fmt.Sprint(v...) + ln)
}
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Infof(format string, v ...interface{}) {
if l.checkLevel(LEVEL_INFO) {
l.stdPrint("[INFO] " + fmt.Sprintf(format, v...))
2018-04-19 16:24:48 +08:00
}
}
func (l *Logger) Infofln(format string, v ...interface{}) {
if l.checkLevel(LEVEL_INFO) {
l.stdPrint("[INFO] " + fmt.Sprintf(format, v...) + ln)
2018-08-30 13:00:49 +08:00
}
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Debug(v ...interface{}) {
if l.checkLevel(LEVEL_DEBU) {
l.stdPrint("[DEBU] " + fmt.Sprint(v...) + ln)
2018-08-30 13:00:49 +08:00
}
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Debugf(format string, v ...interface{}) {
if l.checkLevel(LEVEL_DEBU) {
l.stdPrint("[DEBU] " + fmt.Sprintf(format, v...))
2018-08-30 13:00:49 +08:00
}
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Debugfln(format string, v ...interface{}) {
if l.checkLevel(LEVEL_DEBU) {
l.stdPrint("[DEBU] " + fmt.Sprintf(format, v...) + ln)
2018-08-30 13:00:49 +08:00
}
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Notice(v ...interface{}) {
if l.checkLevel(LEVEL_NOTI) {
l.errPrint("[NOTI] " + fmt.Sprint(v...) + ln)
2018-08-30 13:00:49 +08:00
}
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Noticef(format string, v ...interface{}) {
if l.checkLevel(LEVEL_NOTI) {
l.errPrint("[NOTI] " + fmt.Sprintf(format, v...))
2018-04-19 16:24:48 +08:00
}
}
func (l *Logger) Noticefln(format string, v ...interface{}) {
if l.checkLevel(LEVEL_NOTI) {
l.errPrint("[NOTI] " + fmt.Sprintf(format, v...) + ln)
2018-08-30 13:00:49 +08:00
}
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Warning(v ...interface{}) {
if l.checkLevel(LEVEL_WARN) {
l.errPrint("[WARN] " + fmt.Sprint(v...) + ln)
2018-08-30 13:00:49 +08:00
}
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Warningf(format string, v ...interface{}) {
if l.checkLevel(LEVEL_WARN) {
l.errPrint("[WARN] " + fmt.Sprintf(format, v...))
2018-08-30 13:00:49 +08:00
}
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Warningfln(format string, v ...interface{}) {
if l.checkLevel(LEVEL_WARN) {
l.errPrint("[WARN] " + fmt.Sprintf(format, v...) + ln)
2018-08-30 13:00:49 +08:00
}
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Error(v ...interface{}) {
if l.checkLevel(LEVEL_ERRO) {
l.errPrint("[ERRO] " + fmt.Sprint(v...) + ln)
2018-08-30 13:00:49 +08:00
}
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Errorf(format string, v ...interface{}) {
if l.checkLevel(LEVEL_ERRO) {
l.errPrint("[ERRO] " + fmt.Sprintf(format, v...))
2018-04-19 16:24:48 +08:00
}
}
func (l *Logger) Errorfln(format string, v ...interface{}) {
if l.checkLevel(LEVEL_ERRO) {
l.errPrint("[ERRO] " + fmt.Sprintf(format, v...) + ln)
2018-08-30 13:00:49 +08:00
}
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Critical(v ...interface{}) {
if l.checkLevel(LEVEL_CRIT) {
l.errPrint("[CRIT] " + fmt.Sprint(v...) + ln)
2018-08-30 13:00:49 +08:00
}
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Criticalf(format string, v ...interface{}) {
if l.checkLevel(LEVEL_CRIT) {
l.errPrint("[CRIT] " + fmt.Sprintf(format, v...))
2018-08-30 13:00:49 +08:00
}
2018-04-19 16:24:48 +08:00
}
func (l *Logger) Criticalfln(format string, v ...interface{}) {
if l.checkLevel(LEVEL_CRIT) {
2018-08-30 13:00:49 +08:00
l.errPrint("[CRIT] " + fmt.Sprintf(format, v...) + ln)
}
}
// 判断给定level是否满足
func (l *Logger) checkLevel(level int) bool {
return l.level.Val() & level > 0
2018-04-19 16:24:48 +08:00
}