mirror of
https://gitee.com/johng/gf
synced 2026-06-07 02:12:11 +08:00
add default writer for glog to be integrated with other package; comments update for glog
This commit is contained in:
@ -15,60 +15,60 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Console values.
|
// Console values.
|
||||||
type gCmdValue struct {
|
type gCmdValue struct {
|
||||||
values []string
|
values []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Console options.
|
// Console options.
|
||||||
type gCmdOption struct {
|
type gCmdOption struct {
|
||||||
options map[string]string
|
options map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
var Value = &gCmdValue{} // Console values.
|
var Value = &gCmdValue{} // Console values.
|
||||||
var Option = &gCmdOption{} // Console options.
|
var Option = &gCmdOption{} // Console options.
|
||||||
var cmdFuncMap = make(map[string]func()) // Registered callback functions.
|
var cmdFuncMap = make(map[string]func()) // Registered callback functions.
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
reg := regexp.MustCompile(`\-\-{0,1}(.+?)=(.+)`)
|
reg := regexp.MustCompile(`\-\-{0,1}(.+?)=(.+)`)
|
||||||
Option.options = make(map[string]string)
|
Option.options = make(map[string]string)
|
||||||
for i := 0; i < len(os.Args); i++ {
|
for i := 0; i < len(os.Args); i++ {
|
||||||
result := reg.FindStringSubmatch(os.Args[i])
|
result := reg.FindStringSubmatch(os.Args[i])
|
||||||
if len(result) > 1 {
|
if len(result) > 1 {
|
||||||
Option.options[result[1]] = result[2]
|
Option.options[result[1]] = result[2]
|
||||||
} else {
|
} else {
|
||||||
Value.values = append(Value.values, os.Args[i])
|
Value.values = append(Value.values, os.Args[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BindHandle registers callback function <f> with <cmd>.
|
// BindHandle registers callback function <f> with <cmd>.
|
||||||
func BindHandle (cmd string, f func()) {
|
func BindHandle(cmd string, f func()) {
|
||||||
if _, ok := cmdFuncMap[cmd]; ok {
|
if _, ok := cmdFuncMap[cmd]; ok {
|
||||||
glog.Fatal("duplicated handle for command:" + cmd)
|
glog.Fatal("duplicated handle for command:" + cmd)
|
||||||
} else {
|
} else {
|
||||||
cmdFuncMap[cmd] = f
|
cmdFuncMap[cmd] = f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunHandle executes the callback function registered by <cmd>.
|
// RunHandle executes the callback function registered by <cmd>.
|
||||||
func RunHandle (cmd string) {
|
func RunHandle(cmd string) {
|
||||||
if handle, ok := cmdFuncMap[cmd]; ok {
|
if handle, ok := cmdFuncMap[cmd]; ok {
|
||||||
handle()
|
handle()
|
||||||
} else {
|
} else {
|
||||||
glog.Fatal("no handle found for command:" + cmd)
|
glog.Fatal("no handle found for command:" + cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AutoRun automatically recognizes and executes the callback function
|
// AutoRun automatically recognizes and executes the callback function
|
||||||
// by value of index 0 (the first console parameter).
|
// by value of index 0 (the first console parameter).
|
||||||
func AutoRun () {
|
func AutoRun() {
|
||||||
if cmd := Value.Get(1); cmd != "" {
|
if cmd := Value.Get(1); cmd != "" {
|
||||||
if handle, ok := cmdFuncMap[cmd]; ok {
|
if handle, ok := cmdFuncMap[cmd]; ok {
|
||||||
handle()
|
handle()
|
||||||
} else {
|
} else {
|
||||||
glog.Fatal("no handle found for command:" + cmd)
|
glog.Fatal("no handle found for command:" + cmd)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
glog.Fatal("no command found")
|
glog.Fatal("no command found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,18 +15,22 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 定时任务项
|
// Timed task entry.
|
||||||
type Entry struct {
|
type Entry struct {
|
||||||
cron *Cron // 所属定时任务
|
cron *Cron // Cron object belonged to.
|
||||||
entry *gtimer.Entry // 定时器任务对象
|
entry *gtimer.Entry // Associated gtimer.Entry.
|
||||||
schedule *cronSchedule // 定时任务配置对象
|
schedule *cronSchedule // Timed schedule object.
|
||||||
jobName string // 任务注册方法名称
|
jobName string // Callback function name(address info).
|
||||||
Name string // 定时任务名称
|
Name string // Entry name.
|
||||||
Job func() // 注册定时任务方法
|
Job func() `json:"-"` // Callback function.
|
||||||
Time time.Time // 注册时间
|
Time time.Time // Registered time.
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建定时任务
|
// addEntry creates and returns a new Entry object.
|
||||||
|
// Param <job> is the callback function for timed task execution.
|
||||||
|
// Param <singleton> specifies whether timed task executing in singleton mode.
|
||||||
|
// Param <times> limits the times for timed task executing.
|
||||||
|
// Param <name> names this entry for manual control.
|
||||||
func (c *Cron) addEntry(pattern string, job func(), singleton bool, times int, name ... string) (*Entry, error) {
|
func (c *Cron) addEntry(pattern string, job func(), singleton bool, times int, name ... string) (*Entry, error) {
|
||||||
schedule, err := newSchedule(pattern)
|
schedule, err := newSchedule(pattern)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -3,11 +3,10 @@
|
|||||||
// This Source Code Form is subject to the terms of the MIT License.
|
// 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,
|
// If a copy of the MIT was not distributed with this file,
|
||||||
// You can obtain one at https://github.com/gogf/gf.
|
// You can obtain one at https://github.com/gogf/gf.
|
||||||
|
//
|
||||||
// @author john, zseeker
|
// @author john, zseeker
|
||||||
|
|
||||||
// Package glog implements powerful and easy-to-use levelled logging functionality.
|
// Package glog implements powerful and easy-to-use levelled logging functionality.
|
||||||
//
|
|
||||||
// 日志模块, 直接文件/输出操作,没有异步逻辑,没有使用缓存或者通道
|
|
||||||
package glog
|
package glog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -29,10 +28,10 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// default level for log
|
// Default level for log
|
||||||
defaultLevel = gtype.NewInt(LEVEL_ALL)
|
defaultLevel = gtype.NewInt(LEVEL_ALL)
|
||||||
|
|
||||||
// default logger object, for package method usage
|
// Default logger object, for package method usage
|
||||||
logger = New()
|
logger = New()
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,8 +40,6 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetPath sets the directory path for file logging.
|
// SetPath sets the directory path for file logging.
|
||||||
//
|
|
||||||
// 日志日志目录绝对路径.
|
|
||||||
func SetPath(path string) {
|
func SetPath(path string) {
|
||||||
logger.SetPath(path)
|
logger.SetPath(path)
|
||||||
}
|
}
|
||||||
@ -50,151 +47,113 @@ func SetPath(path string) {
|
|||||||
// SetFile sets the file name <pattern> for file logging.
|
// SetFile sets the file name <pattern> for file logging.
|
||||||
// Datetime pattern can be used in <pattern>, eg: access-{Ymd}.log.
|
// Datetime pattern can be used in <pattern>, eg: access-{Ymd}.log.
|
||||||
// The default file name pattern is: Y-m-d.log, eg: 2018-01-01.log
|
// The default file name pattern is: Y-m-d.log, eg: 2018-01-01.log
|
||||||
//
|
|
||||||
// 日志文件名称.
|
|
||||||
func SetFile(pattern string) {
|
func SetFile(pattern string) {
|
||||||
logger.SetFile(pattern)
|
logger.SetFile(pattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLevel sets the default logging level.
|
// SetLevel sets the default logging level.
|
||||||
//
|
|
||||||
// 设置全局的日志记录等级.
|
|
||||||
func SetLevel(level int) {
|
func SetLevel(level int) {
|
||||||
logger.SetLevel(level)
|
logger.SetLevel(level)
|
||||||
defaultLevel.Set(level)
|
defaultLevel.Set(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetWriter sets the customed logging <writer> for logging.
|
// SetWriter sets the customized logging <writer> for logging.
|
||||||
// The <writer> object should implements the io.Writer interface.
|
// The <writer> object should implements the io.Writer interface.
|
||||||
// Developer can use customed logging <writer> to redirect logging output to another service,
|
// Developer can use customized logging <writer> to redirect logging output to another service,
|
||||||
// eg: kafka, mysql, mongodb, etc.
|
// eg: kafka, mysql, mongodb, etc.
|
||||||
//
|
|
||||||
// 可自定义IO接口,IO可以是文件输出、标准输出、网络输出.
|
|
||||||
func SetWriter(writer io.Writer) {
|
func SetWriter(writer io.Writer) {
|
||||||
logger.SetWriter(writer)
|
logger.SetWriter(writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWriter returns the customed writer object, which implements the io.Writer interface.
|
// GetWriter returns the customized writer object, which implements the io.Writer interface.
|
||||||
// It returns nil if no customed writer set.
|
// It returns nil if no customized writer set.
|
||||||
//
|
|
||||||
// 返回自定义的IO,默认为nil.
|
|
||||||
func GetWriter() io.Writer {
|
func GetWriter() io.Writer {
|
||||||
return logger.GetWriter()
|
return logger.GetWriter()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLevel returns the default logging level value.
|
// GetLevel returns the default logging level value.
|
||||||
//
|
|
||||||
// 获取全局的日志记录等级.
|
|
||||||
func GetLevel() int {
|
func GetLevel() int {
|
||||||
return defaultLevel.Val()
|
return defaultLevel.Val()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDebug enables/disables the debug level for default logger.
|
// SetDebug enables/disables the debug level for default logger.
|
||||||
// The debug level is enbaled in default.
|
// The debug level is enbaled in default.
|
||||||
//
|
|
||||||
// 设置是否允许输出DEBUG信息.
|
|
||||||
func SetDebug(debug bool) {
|
func SetDebug(debug bool) {
|
||||||
logger.SetDebug(debug)
|
logger.SetDebug(debug)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetStdPrint sets whether ouptput the logging contents to stdout, which is false indefault.
|
// SetStdPrint sets whether ouptput the logging contents to stdout, which is false in default.
|
||||||
//
|
|
||||||
// 设置写日志的同时开启or关闭控制台打印,默认是关闭的
|
|
||||||
func SetStdPrint(open bool) {
|
func SetStdPrint(open bool) {
|
||||||
logger.SetStdPrint(open)
|
logger.SetStdPrint(open)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPath returns the logging directory path for file logging.
|
// GetPath returns the logging directory path for file logging.
|
||||||
// It returns empty string if no directory path set.
|
// It returns empty string if no directory path set.
|
||||||
//
|
|
||||||
// 获取日志目录绝对路径
|
|
||||||
func GetPath() string {
|
func GetPath() string {
|
||||||
return logger.GetPath()
|
return logger.GetPath()
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrintBacktrace prints the caller backtrace,
|
// PrintBacktrace prints the caller backtrace,
|
||||||
// the optional parameter <skip> specify the skipped backtraces offset from the end point.
|
// the optional parameter <skip> specify the skipped backtrace offset from the end point.
|
||||||
//
|
|
||||||
// 打印文件调用回溯信息
|
|
||||||
func PrintBacktrace(skip...int) {
|
func PrintBacktrace(skip...int) {
|
||||||
logger.PrintBacktrace(skip...)
|
logger.PrintBacktrace(skip...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBacktrace returns the caller backtrace content,
|
// GetBacktrace returns the caller backtrace content,
|
||||||
// the optional parameter <skip> specify the skipped backtraces offset from the end point.
|
// the optional parameter <skip> specify the skipped backtrace offset from the end point.
|
||||||
//
|
|
||||||
// 获取文件调用回溯信息.
|
|
||||||
func GetBacktrace(skip...int) string {
|
func GetBacktrace(skip...int) string {
|
||||||
return logger.GetBacktrace(skip...)
|
return logger.GetBacktrace(skip...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBacktrace enables/disables the backtrace feature in failure logging outputs.
|
// SetBacktrace enables/disables the backtrace feature in failure logging outputs.
|
||||||
//
|
|
||||||
// 是否关闭全局的backtrace信息
|
|
||||||
func SetBacktrace(enabled bool) {
|
func SetBacktrace(enabled bool) {
|
||||||
logger.SetBacktrace(enabled)
|
logger.SetBacktrace(enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
// To is a chaining function,
|
// To is a chaining function,
|
||||||
// which redirects current logging content output to the sepecified <writer>.
|
// which redirects current logging content output to the sepecified <writer>.
|
||||||
//
|
|
||||||
// 链式操作,设置下一次写入日志内容的Writer
|
|
||||||
func To(writer io.Writer) *Logger {
|
func To(writer io.Writer) *Logger {
|
||||||
return logger.To(writer)
|
return logger.To(writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Path is a chaining function,
|
// Path is a chaining function,
|
||||||
// which sets the directory path to <path> for current logging content output.
|
// which sets the directory path to <path> for current logging content output.
|
||||||
//
|
|
||||||
// 链式操作,设置下一次输出的日志路径。
|
|
||||||
func Path(path string) *Logger {
|
func Path(path string) *Logger {
|
||||||
return logger.Path(path)
|
return logger.Path(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cat is a chaining function,
|
// Cat is a chaining function,
|
||||||
// which sets the category to <category> for current logging content output.
|
// which sets the category to <category> for current logging content output.
|
||||||
//
|
|
||||||
// 设置下一次输出的分类,支持多级分类设置.
|
|
||||||
func Cat(category string) *Logger {
|
func Cat(category string) *Logger {
|
||||||
return logger.Cat(category)
|
return logger.Cat(category)
|
||||||
}
|
}
|
||||||
|
|
||||||
// File is a chaining function,
|
// File is a chaining function,
|
||||||
// which sets file name <pattern> for the current logging content output.
|
// which sets file name <pattern> for the current logging content output.
|
||||||
//
|
|
||||||
// 设置日志输出文件名称格式
|
|
||||||
func File(pattern string) *Logger {
|
func File(pattern string) *Logger {
|
||||||
return logger.File(pattern)
|
return logger.File(pattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Level is a chaining function,
|
// Level is a chaining function,
|
||||||
// which sets logging level for the current logging content output.
|
// which sets logging level for the current logging content output.
|
||||||
//
|
|
||||||
// 设置日志打印等级.
|
|
||||||
func Level(level int) *Logger {
|
func Level(level int) *Logger {
|
||||||
return logger.Level(level)
|
return logger.Level(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backtrace is a chaining function,
|
// Backtrace is a chaining function,
|
||||||
// which sets backtrace options for the current logging content output .
|
// which sets backtrace options for the current logging content output .
|
||||||
//
|
|
||||||
// 设置文件调用回溯信息.
|
|
||||||
func Backtrace(enabled bool, skip...int) *Logger {
|
func Backtrace(enabled bool, skip...int) *Logger {
|
||||||
return logger.Backtrace(enabled, skip...)
|
return logger.Backtrace(enabled, skip...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StdPrint is a chaining function,
|
// StdPrint is a chaining function,
|
||||||
// which enables/disables stdout for the current logging content output.
|
// which enables/disables stdout for the current logging content output.
|
||||||
//
|
|
||||||
// 是否允许在设置输出文件时同时也输出到终端
|
|
||||||
func StdPrint(enabled bool) *Logger {
|
func StdPrint(enabled bool) *Logger {
|
||||||
return logger.StdPrint(enabled)
|
return logger.StdPrint(enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Header is a chaining function,
|
// Header is a chaining function,
|
||||||
// which enables/disables log header for the current logging content output.
|
// which enables/disables log header for the current logging content output.
|
||||||
//
|
|
||||||
// 是否打印每行日志头信息(默认开启)
|
|
||||||
func Header(enabled bool) *Logger {
|
func Header(enabled bool) *Logger {
|
||||||
return logger.Header(enabled)
|
return logger.Header(enabled)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
// This Source Code Form is subject to the terms of the MIT License.
|
// 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,
|
// If a copy of the MIT was not distributed with this file,
|
||||||
// You can obtain one at https://github.com/gogf/gf.
|
// You can obtain one at https://github.com/gogf/gf.
|
||||||
|
//
|
||||||
// @author john, zseeker
|
// @author john, zseeker
|
||||||
|
|
||||||
package glog
|
package glog
|
||||||
@ -26,15 +27,15 @@ import (
|
|||||||
|
|
||||||
type Logger struct {
|
type Logger struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
pr *Logger // 父级Logger
|
pr *Logger // Parent logger.
|
||||||
io io.Writer // 日志内容写入的IO接口
|
io io.Writer // Customized io.Writer.
|
||||||
path *gtype.String // 日志写入的目录路径
|
path *gtype.String // Logging directory path.
|
||||||
file *gtype.String // 日志文件名称格式
|
file *gtype.String // Format for logging file.
|
||||||
level *gtype.Int // 日志输出等级
|
level *gtype.Int // Output level.
|
||||||
btSkip *gtype.Int // 错误产生时的backtrace回调信息skip条数
|
btSkip *gtype.Int // Skip count for backtrace.
|
||||||
btStatus *gtype.Int // 是否当打印错误时同时开启backtrace打印(默认-1,表示默认打印逻辑 - 错误才打印)
|
btStatus *gtype.Int // Backtrace status(1: enabled - default; 0: disabled)
|
||||||
printHeader *gtype.Bool // 是否不打印前缀信息(时间,级别等)
|
printHeader *gtype.Bool // Print header or not(true in default).
|
||||||
alsoStdPrint *gtype.Bool // 控制台打印开关,当输出到文件/自定义输出时也同时打印到终端
|
alsoStdPrint *gtype.Bool // Output to stdout or not(true in default).
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -45,70 +46,66 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// 默认的日志换行符
|
// Default line break.
|
||||||
ln = "\n"
|
ln = "\n"
|
||||||
// 标准输出互斥锁,防止标准输出串日志
|
// Mutex to ensure log output sequence.
|
||||||
stdMu = sync.RWMutex{}
|
stdMu = sync.RWMutex{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// 初始化日志换行符
|
|
||||||
func init() {
|
func init() {
|
||||||
|
// Initialize log line breaks depending on underlying os.
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
ln = "\r\n"
|
ln = "\r\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a custom logger.
|
// New creates and returns a custom logger.
|
||||||
//
|
|
||||||
// 新建自定义的日志操作对象
|
|
||||||
func New() *Logger {
|
func New() *Logger {
|
||||||
return &Logger {
|
logger := &Logger {
|
||||||
io : nil,
|
|
||||||
path : gtype.NewString(),
|
path : gtype.NewString(),
|
||||||
file : gtype.NewString(gDEFAULT_FILE_FORMAT),
|
file : gtype.NewString(gDEFAULT_FILE_FORMAT),
|
||||||
level : gtype.NewInt(defaultLevel.Val()),
|
level : gtype.NewInt(defaultLevel.Val()),
|
||||||
btSkip : gtype.NewInt(),
|
btSkip : gtype.NewInt(),
|
||||||
btStatus : gtype.NewInt(-1),
|
btStatus : gtype.NewInt(1),
|
||||||
printHeader : gtype.NewBool(true),
|
printHeader : gtype.NewBool(true),
|
||||||
alsoStdPrint : gtype.NewBool(true),
|
alsoStdPrint : gtype.NewBool(true),
|
||||||
}
|
}
|
||||||
|
logger.io = &Writer {
|
||||||
|
logger : logger,
|
||||||
|
}
|
||||||
|
return logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clone returns a new logger, which is the clone the current logger.
|
// Clone returns a new logger, which is the clone the current logger.
|
||||||
//
|
|
||||||
// Logger拷贝.
|
|
||||||
func (l *Logger) Clone() *Logger {
|
func (l *Logger) Clone() *Logger {
|
||||||
return &Logger {
|
logger := &Logger {
|
||||||
pr : l,
|
pr : l,
|
||||||
io : l.GetWriter(),
|
|
||||||
path : l.path.Clone(),
|
path : l.path.Clone(),
|
||||||
file : l.file.Clone(),
|
file : l.file.Clone(),
|
||||||
level : l.level.Clone(),
|
level : l.level.Clone(),
|
||||||
btSkip : l.btSkip.Clone(),
|
btSkip : l.btSkip.Clone(),
|
||||||
btStatus : l.btStatus.Clone(),
|
btStatus : l.btStatus.Clone(),
|
||||||
printHeader : l.printHeader.Clone(),
|
printHeader : l.printHeader.Clone(),
|
||||||
alsoStdPrint : l.alsoStdPrint.Clone(),
|
alsoStdPrint : l.alsoStdPrint.Clone(),
|
||||||
}
|
}
|
||||||
|
logger.io = &Writer {
|
||||||
|
logger : logger,
|
||||||
|
}
|
||||||
|
return logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLevel sets the logging level.
|
// SetLevel sets the logging level.
|
||||||
//
|
|
||||||
// 设置日志记录等级
|
|
||||||
func (l *Logger) SetLevel(level int) {
|
func (l *Logger) SetLevel(level int) {
|
||||||
l.level.Set(level)
|
l.level.Set(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLevel returns the logging level value.
|
// GetLevel returns the logging level value.
|
||||||
//
|
|
||||||
// 获取日志记录等级
|
|
||||||
func (l *Logger) GetLevel() int {
|
func (l *Logger) GetLevel() int {
|
||||||
return l.level.Val()
|
return l.level.Val()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDebug enables/disables the debug level for logger.
|
// SetDebug enables/disables the debug level for logger.
|
||||||
// The debug level is enbaled in default.
|
// The debug level is enabled in default.
|
||||||
//
|
|
||||||
// 快捷方法,打开或关闭DEBU日志信息
|
|
||||||
func (l *Logger) SetDebug(debug bool) {
|
func (l *Logger) SetDebug(debug bool) {
|
||||||
if debug {
|
if debug {
|
||||||
l.level.Set(l.level.Val() | LEVEL_DEBU)
|
l.level.Set(l.level.Val() | LEVEL_DEBU)
|
||||||
@ -124,7 +121,6 @@ func (l *Logger) SetBacktrace(enabled bool) {
|
|||||||
} else {
|
} else {
|
||||||
l.btStatus.Set(0)
|
l.btStatus.Set(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBacktraceSkip sets the backtrace offset from the end point.
|
// SetBacktraceSkip sets the backtrace offset from the end point.
|
||||||
@ -132,22 +128,18 @@ func (l *Logger) SetBacktraceSkip(skip int) {
|
|||||||
l.btSkip.Set(skip)
|
l.btSkip.Set(skip)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetWriter sets the customed logging <writer> for logging.
|
// SetWriter sets the customized logging <writer> for logging.
|
||||||
// The <writer> object should implements the io.Writer interface.
|
// The <writer> object should implements the io.Writer interface.
|
||||||
// Developer can use customed logging <writer> to redirect logging output to another service,
|
// Developer can use customized logging <writer> to redirect logging output to another service,
|
||||||
// eg: kafka, mysql, mongodb, etc.
|
// eg: kafka, mysql, mongodb, etc.
|
||||||
//
|
|
||||||
// 可自定义IO接口,IO可以是文件输出、标准输出、网络输出
|
|
||||||
func (l *Logger) SetWriter(writer io.Writer) {
|
func (l *Logger) SetWriter(writer io.Writer) {
|
||||||
l.mu.Lock()
|
l.mu.Lock()
|
||||||
l.io = writer
|
l.io = writer
|
||||||
l.mu.Unlock()
|
l.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWriter returns the customed writer object, which implements the io.Writer interface.
|
// GetWriter returns the customized writer object, which implements the io.Writer interface.
|
||||||
// It returns nil if no customed writer set.
|
// It returns a default writer if no customized writer set.
|
||||||
//
|
|
||||||
// 返回自定义的IO,默认为nil
|
|
||||||
func (l *Logger) GetWriter() io.Writer {
|
func (l *Logger) GetWriter() io.Writer {
|
||||||
l.mu.RLock()
|
l.mu.RLock()
|
||||||
r := l.io
|
r := l.io
|
||||||
@ -156,23 +148,21 @@ func (l *Logger) GetWriter() io.Writer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getFilePointer returns the file pinter for file logging.
|
// getFilePointer returns the file pinter for file logging.
|
||||||
// It returns nil if file logging disabled, or file open fails.
|
// It returns nil if file logging is disabled, or file opening fails.
|
||||||
//
|
|
||||||
// 获取默认的文件IO.
|
|
||||||
func (l *Logger) getFilePointer() *gfpool.File {
|
func (l *Logger) getFilePointer() *gfpool.File {
|
||||||
if path := l.path.Val(); path != "" {
|
if path := l.path.Val(); path != "" {
|
||||||
// 文件名称中使用"{}"包含的内容使用gtime格式化
|
// Content containing "{}" in the file name is formatted using gtime
|
||||||
file, _ := gregex.ReplaceStringFunc(`{.+?}`, l.file.Val(), func(s string) string {
|
file, _ := gregex.ReplaceStringFunc(`{.+?}`, l.file.Val(), func(s string) string {
|
||||||
return gtime.Now().Format(strings.Trim(s, "{}"))
|
return gtime.Now().Format(strings.Trim(s, "{}"))
|
||||||
})
|
})
|
||||||
// 如果日志目录不存在则创建目录路径
|
// Create path if it does not exist。
|
||||||
if !gfile.Exists(path) {
|
if !gfile.Exists(path) {
|
||||||
if err := gfile.Mkdir(path); err != nil {
|
if err := gfile.Mkdir(path); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, fmt.Sprintf(`[glog] mkdir "%s" failed: %s`, path, err.Error()))
|
fmt.Fprintln(os.Stderr, fmt.Sprintf(`[glog] mkdir "%s" failed: %s`, path, err.Error()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fpath := path + gfile.Separator + file
|
fpath := path + gfile.Separator + file
|
||||||
if fp, err := gfpool.Open(fpath, gDEFAULT_FILE_POOL_FLAGS, gDEFAULT_FPOOL_PERM, gDEFAULT_FPOOL_EXPIRE); err == nil {
|
if fp, err := gfpool.Open(fpath, gDEFAULT_FILE_POOL_FLAGS, gDEFAULT_FPOOL_PERM, gDEFAULT_FPOOL_EXPIRE); err == nil {
|
||||||
return fp
|
return fp
|
||||||
} else {
|
} else {
|
||||||
@ -183,14 +173,10 @@ func (l *Logger) getFilePointer() *gfpool.File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetPath sets the directory path for file logging.
|
// SetPath sets the directory path for file logging.
|
||||||
//
|
|
||||||
// 设置日志文件的存储目录路径.
|
|
||||||
func (l *Logger) SetPath(path string) error {
|
func (l *Logger) SetPath(path string) error {
|
||||||
// path必须有值
|
|
||||||
if path == "" {
|
if path == "" {
|
||||||
return errors.New("path is empty")
|
return errors.New("path is empty")
|
||||||
}
|
}
|
||||||
// 如果目录不存在,则递归创建
|
|
||||||
if !gfile.Exists(path) {
|
if !gfile.Exists(path) {
|
||||||
if err := gfile.Mkdir(path); err != nil {
|
if err := gfile.Mkdir(path); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, fmt.Sprintf(`[glog] mkdir "%s" failed: %s`, path, err.Error()))
|
fmt.Fprintln(os.Stderr, fmt.Sprintf(`[glog] mkdir "%s" failed: %s`, path, err.Error()))
|
||||||
@ -203,8 +189,6 @@ func (l *Logger) SetPath(path string) error {
|
|||||||
|
|
||||||
// GetPath returns the logging directory path for file logging.
|
// GetPath returns the logging directory path for file logging.
|
||||||
// It returns empty string if no directory path set.
|
// It returns empty string if no directory path set.
|
||||||
//
|
|
||||||
// 获取设置的日志目录路径
|
|
||||||
func (l *Logger) GetPath() string {
|
func (l *Logger) GetPath() string {
|
||||||
return l.path.Val()
|
return l.path.Val()
|
||||||
}
|
}
|
||||||
@ -212,29 +196,24 @@ func (l *Logger) GetPath() string {
|
|||||||
// SetFile sets the file name <pattern> for file logging.
|
// SetFile sets the file name <pattern> for file logging.
|
||||||
// Datetime pattern can be used in <pattern>, eg: access-{Ymd}.log.
|
// Datetime pattern can be used in <pattern>, eg: access-{Ymd}.log.
|
||||||
// The default file name pattern is: Y-m-d.log, eg: 2018-01-01.log
|
// The default file name pattern is: Y-m-d.log, eg: 2018-01-01.log
|
||||||
//
|
|
||||||
// 设置日志文件名称格式.
|
|
||||||
func (l *Logger) SetFile(pattern string) {
|
func (l *Logger) SetFile(pattern string) {
|
||||||
l.file.Set(pattern)
|
l.file.Set(pattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetStdPrint sets whether ouptput the logging contents to stdout, which is false indefault.
|
// SetStdPrint sets whether output the logging contents to stdout, which is false in default.
|
||||||
//
|
|
||||||
// 设置写日志时开启or关闭控制台打印,默认是关闭的
|
|
||||||
func (l *Logger) SetStdPrint(enabled bool) {
|
func (l *Logger) SetStdPrint(enabled bool) {
|
||||||
l.alsoStdPrint.Set(enabled)
|
l.alsoStdPrint.Set(enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 这里的写锁保证统一时刻只会写入一行日志,防止串日志的情况
|
// 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) {
|
func (l *Logger) print(std io.Writer, s string) {
|
||||||
// 优先使用自定义的IO输出
|
// Customized writer has the most high priority.
|
||||||
if l.printHeader.Val() {
|
if l.printHeader.Val() {
|
||||||
s = l.format(s)
|
s = l.format(s)
|
||||||
}
|
}
|
||||||
writer := l.GetWriter()
|
writer := l.GetWriter()
|
||||||
if writer == nil {
|
if _, ok := writer.(*Writer); ok {
|
||||||
// 如果设置的writer为空,那么其次判断是否有文件输出设置
|
|
||||||
// 内部使用了内存锁,保证在glog中对同一个日志文件的并发写入不会串日志(并发安全)
|
|
||||||
if f := l.getFilePointer(); f != nil {
|
if f := l.getFilePointer(); f != nil {
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
key := l.path.Val()
|
key := l.path.Val()
|
||||||
@ -245,7 +224,7 @@ func (l *Logger) print(std io.Writer, s string) {
|
|||||||
fmt.Fprintln(os.Stderr, err.Error())
|
fmt.Fprintln(os.Stderr, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 当没有设置writer时,需要判断是否允许输出到标准输出
|
// Also output to stdout?
|
||||||
if l.alsoStdPrint.Val() {
|
if l.alsoStdPrint.Val() {
|
||||||
l.doStdLockPrint(std, s)
|
l.doStdLockPrint(std, s)
|
||||||
}
|
}
|
||||||
@ -254,7 +233,7 @@ func (l *Logger) print(std io.Writer, s string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 并发安全打印到标准输出
|
// doStdLockPrint prints <s> to <std> concurrent-safely.
|
||||||
func (l *Logger) doStdLockPrint(std io.Writer, s string) {
|
func (l *Logger) doStdLockPrint(std io.Writer, s string) {
|
||||||
stdMu.Lock()
|
stdMu.Lock()
|
||||||
if _, err := std.Write([]byte(s)); err != nil {
|
if _, err := std.Write([]byte(s)); err != nil {
|
||||||
@ -263,23 +242,21 @@ func (l *Logger) doStdLockPrint(std io.Writer, s string) {
|
|||||||
stdMu.Unlock()
|
stdMu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 核心打印数据方法(标准输出)
|
// stdPrint prints content <s> without backtrace.
|
||||||
func (l *Logger) stdPrint(s string) {
|
func (l *Logger) stdPrint(s string) {
|
||||||
l.print(os.Stdout, s)
|
l.print(os.Stdout, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 核心打印数据方法(标准错误)
|
// stdPrint prints content <s> with backtrace check.
|
||||||
func (l *Logger) errPrint(s string) {
|
func (l *Logger) errPrint(s string) {
|
||||||
// 记录调用回溯信息
|
if l.btStatus.Val() == 1 {
|
||||||
status := l.btStatus.Val()
|
|
||||||
if status == -1 || status == 1 {
|
|
||||||
s = l.appendBacktrace(s)
|
s = l.appendBacktrace(s)
|
||||||
}
|
}
|
||||||
// 防止串日志情况,这里不使用stderr,而是使用stdout
|
// In matter of sequence, do not use stderr here, but use the same stdout.
|
||||||
l.print(os.Stdout, s)
|
l.print(os.Stdout, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 输出内容中添加回溯信息
|
// appendBacktrace appends backtrace to the <s>.
|
||||||
func (l *Logger) appendBacktrace(s string, skip...int) string {
|
func (l *Logger) appendBacktrace(s string, skip...int) string {
|
||||||
trace := l.GetBacktrace(skip...)
|
trace := l.GetBacktrace(skip...)
|
||||||
if trace != "" {
|
if trace != "" {
|
||||||
@ -298,17 +275,13 @@ func (l *Logger) appendBacktrace(s string, skip...int) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PrintBacktrace prints the caller backtrace,
|
// PrintBacktrace prints the caller backtrace,
|
||||||
// the optional parameter <skip> specify the skipped backtraces offset from the end point.
|
// the optional parameter <skip> specify the skipped backtrace offset from the end point.
|
||||||
//
|
|
||||||
// 直接打印回溯信息,参数skip表示调用端往上多少级开始回溯
|
|
||||||
func (l *Logger) PrintBacktrace(skip...int) {
|
func (l *Logger) PrintBacktrace(skip...int) {
|
||||||
l.Println(l.appendBacktrace("", skip...))
|
l.Println(l.appendBacktrace("", skip...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBacktrace returns the caller backtrace content,
|
// GetBacktrace returns the caller backtrace content,
|
||||||
// the optional parameter <skip> specify the skipped backtraces offset from the end point.
|
// the optional parameter <skip> specify the skipped backtrace offset from the end point.
|
||||||
//
|
|
||||||
// 获取文件调用回溯字符串,参数skip表示调用端往上多少级开始回溯
|
|
||||||
func (l *Logger) GetBacktrace(skip...int) string {
|
func (l *Logger) GetBacktrace(skip...int) string {
|
||||||
customSkip := 0
|
customSkip := 0
|
||||||
if len(skip) > 0 {
|
if len(skip) > 0 {
|
||||||
@ -507,8 +480,6 @@ func (l *Logger) Criticalfln(format string, v ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// checkLevel checks whether the given <level> could be output.
|
// checkLevel checks whether the given <level> could be output.
|
||||||
//
|
|
||||||
// 判断给定level是否满足
|
|
||||||
func (l *Logger) checkLevel(level int) bool {
|
func (l *Logger) checkLevel(level int) bool {
|
||||||
return l.level.Val() & level > 0
|
return l.level.Val() & level > 0
|
||||||
}
|
}
|
||||||
@ -13,8 +13,6 @@ import (
|
|||||||
|
|
||||||
// To is a chaining function,
|
// To is a chaining function,
|
||||||
// which redirects current logging content output to the specified <writer>.
|
// which redirects current logging content output to the specified <writer>.
|
||||||
//
|
|
||||||
// 链式操作,设置下一次写入日志内容的Writer
|
|
||||||
func (l *Logger) To(writer io.Writer) *Logger {
|
func (l *Logger) To(writer io.Writer) *Logger {
|
||||||
logger := (*Logger)(nil)
|
logger := (*Logger)(nil)
|
||||||
if l.pr == nil {
|
if l.pr == nil {
|
||||||
@ -28,8 +26,6 @@ func (l *Logger) To(writer io.Writer) *Logger {
|
|||||||
|
|
||||||
// Path is a chaining function,
|
// Path is a chaining function,
|
||||||
// which sets the directory path to <path> for current logging content output.
|
// which sets the directory path to <path> for current logging content output.
|
||||||
//
|
|
||||||
// 链式操作,设置下一次输出的日志路径。
|
|
||||||
func (l *Logger) Path(path string) *Logger {
|
func (l *Logger) Path(path string) *Logger {
|
||||||
logger := (*Logger)(nil)
|
logger := (*Logger)(nil)
|
||||||
if l.pr == nil {
|
if l.pr == nil {
|
||||||
@ -45,9 +41,7 @@ func (l *Logger) Path(path string) *Logger {
|
|||||||
|
|
||||||
// Cat is a chaining function,
|
// Cat is a chaining function,
|
||||||
// which sets the category to <category> for current logging content output.
|
// which sets the category to <category> for current logging content output.
|
||||||
//
|
// Param <category> can be hierarchical, eg: module/user.
|
||||||
// 链式操作,设置下一次输出的日志分类(可以按照文件目录层级设置),在当前logpath或者当前工作目录下创建category目录,
|
|
||||||
// 这是一个链式操作,可以设置多个分类,将会创建层级的日志分类目录。
|
|
||||||
func (l *Logger) Cat(category string) *Logger {
|
func (l *Logger) Cat(category string) *Logger {
|
||||||
logger := (*Logger)(nil)
|
logger := (*Logger)(nil)
|
||||||
if l.pr == nil {
|
if l.pr == nil {
|
||||||
@ -64,8 +58,6 @@ func (l *Logger) Cat(category string) *Logger {
|
|||||||
|
|
||||||
// File is a chaining function,
|
// File is a chaining function,
|
||||||
// which sets file name <pattern> for the current logging content output.
|
// which sets file name <pattern> for the current logging content output.
|
||||||
//
|
|
||||||
// 日志文件格式
|
|
||||||
func (l *Logger) File(file string) *Logger {
|
func (l *Logger) File(file string) *Logger {
|
||||||
logger := (*Logger)(nil)
|
logger := (*Logger)(nil)
|
||||||
if l.pr == nil {
|
if l.pr == nil {
|
||||||
@ -79,8 +71,6 @@ func (l *Logger) File(file string) *Logger {
|
|||||||
|
|
||||||
// Level is a chaining function,
|
// Level is a chaining function,
|
||||||
// which sets logging level for the current logging content output.
|
// which sets logging level for the current logging content output.
|
||||||
//
|
|
||||||
// 设置日志打印等级
|
|
||||||
func (l *Logger) Level(level int) *Logger {
|
func (l *Logger) Level(level int) *Logger {
|
||||||
logger := (*Logger)(nil)
|
logger := (*Logger)(nil)
|
||||||
if l.pr == nil {
|
if l.pr == nil {
|
||||||
@ -94,8 +84,6 @@ func (l *Logger) Level(level int) *Logger {
|
|||||||
|
|
||||||
// Backtrace is a chaining function,
|
// Backtrace is a chaining function,
|
||||||
// which sets backtrace options for the current logging content output .
|
// which sets backtrace options for the current logging content output .
|
||||||
//
|
|
||||||
// 设置文件调用回溯信息
|
|
||||||
func (l *Logger) Backtrace(enabled bool, skip...int) *Logger {
|
func (l *Logger) Backtrace(enabled bool, skip...int) *Logger {
|
||||||
logger := (*Logger)(nil)
|
logger := (*Logger)(nil)
|
||||||
if l.pr == nil {
|
if l.pr == nil {
|
||||||
@ -112,8 +100,6 @@ func (l *Logger) Backtrace(enabled bool, skip...int) *Logger {
|
|||||||
|
|
||||||
// StdPrint is a chaining function,
|
// StdPrint is a chaining function,
|
||||||
// which enables/disables stdout for the current logging content output.
|
// which enables/disables stdout for the current logging content output.
|
||||||
//
|
|
||||||
// 是否允许在设置输出文件时同时也输出到终端
|
|
||||||
func (l *Logger) StdPrint(enabled bool) *Logger {
|
func (l *Logger) StdPrint(enabled bool) *Logger {
|
||||||
logger := (*Logger)(nil)
|
logger := (*Logger)(nil)
|
||||||
if l.pr == nil {
|
if l.pr == nil {
|
||||||
@ -127,8 +113,6 @@ func (l *Logger) StdPrint(enabled bool) *Logger {
|
|||||||
|
|
||||||
// Header is a chaining function,
|
// Header is a chaining function,
|
||||||
// which enables/disables log header for the current logging content output.
|
// which enables/disables log header for the current logging content output.
|
||||||
//
|
|
||||||
// 是否打印每行日志头信息(默认开启)
|
|
||||||
func (l *Logger) Header(enabled bool) *Logger {
|
func (l *Logger) Header(enabled bool) *Logger {
|
||||||
logger := (*Logger)(nil)
|
logger := (*Logger)(nil)
|
||||||
if l.pr == nil {
|
if l.pr == nil {
|
||||||
|
|||||||
19
g/os/glog/glog_writer.go
Normal file
19
g/os/glog/glog_writer.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright 2017 gf Author(https://github.com/gogf/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://github.com/gogf/gf.
|
||||||
|
|
||||||
|
|
||||||
|
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))
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
@ -39,7 +39,7 @@ func Export(i...interface{}) string {
|
|||||||
// 这里强制对所有map进行反射处理转换
|
// 这里强制对所有map进行反射处理转换
|
||||||
refValue := reflect.ValueOf(v)
|
refValue := reflect.ValueOf(v)
|
||||||
if refValue.Kind() == reflect.Map {
|
if refValue.Kind() == reflect.Map {
|
||||||
m := make(map[string]interface{})
|
m := make(map[string]interface{})
|
||||||
keys := refValue.MapKeys()
|
keys := refValue.MapKeys()
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
m[gconv.String(k.Interface())] = refValue.MapIndex(k).Interface()
|
m[gconv.String(k.Interface())] = refValue.MapIndex(k).Interface()
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"github.com/gogf/gf/g"
|
||||||
"github.com/gogf/gf/g/os/gcron"
|
"github.com/gogf/gf/g/os/gcron"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -12,7 +12,9 @@ func test() {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
_, err := gcron.Add("*/10 * * * * ?", test)
|
_, err := gcron.Add("*/10 * * * * ?", test)
|
||||||
fmt.Println(err)
|
if err != nil {
|
||||||
fmt.Println(gcron.Entries())
|
panic(err)
|
||||||
|
}
|
||||||
|
g.Dump(gcron.Entries())
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
}
|
}
|
||||||
|
|||||||
10
geg/os/glog/glog_writer.go
Normal file
10
geg/os/glog/glog_writer.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gogf/gf/g/os/glog"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
w := glog.GetWriter()
|
||||||
|
w.Write([]byte("hello"))
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user