在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
参考:https://godoc.org/github.com/cihub/seelog 导入方式: import "github.com/cihub/seelog" 包seelog通过灵活的调度、过滤和格式化实现日志功能。
1.创建 使用下面的构造函数来创建一个日志记录器: func LoggerFromConfigAsBytes
func LoggerFromConfigAsFile
func LoggerFromConfigAsString
func LoggerFromWriterWithMinLevel
func LoggerFromWriterWithMinLevelAndFormat
func LoggerFromCustomReceiver(check https://github.com/cihub/seelog/wiki/Custom-receivers)
举例: 配置文件seelog.xml为,参考https://blog.csdn.net/luckytanggu/article/details/80345134: <seelog type="asynctimer" asyncinterval="1000000" minlevel="debug" maxlevel="error">
<outputs formatid="main">
<!-- 仅实现将日志内容输出到终端 -->
<console/>
</outputs>
<formats>
<!-- 设置格式,输出UTC日期 UTC时间 - 缩写版大写日志级别 - 相对于应用程序运行目录的调用者路径 - 日志记录器被调用时的行号 - 消息文本(最后换行) -->
<format id="main" format="%UTCDate %UTCTime - [%LEV] - %RelFile - l%Line - %Msg%n"/>
</formats>
</seelog>
然后应用为: package main
import (
log "github.com/cihub/seelog"
"fmt"
)
func main() {
logger, err := log.LoggerFromConfigAsFile("seelog.xml")
if err != nil {
fmt.Println("parse seelog.xml error")
}
log.ReplaceLogger(logger)
defer log.Flush()
log.Info("Hello from Seelog!")
}
输出为: userdeMBP:go-learning user$ go run test.go
2019-03-04 09:19:11 - [INF] - test.go - l20 - Hello from Seelog!
“defer”行语句很重要,因为如果使用异步日志行为,在关闭应用程序时,如果没有这行,可能会丢失一些消息,因为它们是在另一个非阻塞goroutine中处理的。为了避免这种情况,在关闭之前显式地延迟刷新所有消息。
2.使用 可以通过调用主日志函数其中之一的函数来直接使用上面的任一个LoggerFrom*函数来创建日志记录器 import log "github.com/cihub/seelog" func main() { logger, err := log.LoggerFromConfigAsFile("seelog.xml") if err != nil { panic(err) } defer logger.Flush() logger.Trace("test") logger.Debugf("var = %s", "abc") } 如果你正在使用内部日志记录编写自己的包,或者你有几个具有不同选项的日志记录程序,那么使用日志记录程序作为变量是非常方便的。但是对于大多数独立的应用程序来说,使用包级函数和变量会更方便。有一个包级别的变量'Current'就是为它而建的(即上面的logger等价于log.Current)。你也可以使用“ReplaceLogger”将其替换为另一个日志记录器,然后使用包级别函数: import log "github.com/cihub/seelog" func main() { logger, err := log.LoggerFromConfigAsFile("seelog.xml") if err != nil { panic(err) } log.ReplaceLogger(logger) defer log.Flush() log.Trace("test") log.Debugf("var = %s", "abc") } 两面的最后两行等价于: log.Current.Trace("test") log.Current.Debugf("var = %s", "abc") 在本例中,'Current'日志记录器被替换为使用'ReplaceLogger'调用,并成为由config创建的'logger'变量。通过这种方式,你可以使用包级别函数,而不是传递logger变量。
3.配置: 1)可见go第三方日志系统-seelog-Basic sections 2)使用代码进行配置: 虽然不建议使用代码进行配置,但有时需要使用代码,可以使用seelog进行配置。基本上,开始时你需要做的是创建约束、例外和分配器树(与配置相同)。这个包中的大多数New*类函数都用于提供此类功能。 package main import log "github.com/cihub/seelog" func main() { defer log.Flush() log.Info("Hello from Seelog!") //这个使用的是默认的日志记录器 consoleWriter, _ := log.NewConsoleWriter() //创建一个新的控制台写入器 formatter, _ := log.NewFormatter("%Level %Msg %File%n") //等价于配置中的<format>声明格式 root, _ := log.NewSplitDispatcher(formatter, []interface{}{consoleWriter}) //即等价于配置中的<output>,formatter是该分配器指定的格式,接收到的日志信息指定接收器为标准输出 constraints, _ := log.NewMinMaxConstraints(log.TraceLvl, log.CriticalLvl) //使用指定的最小和最大级别创建一个新的minMaxConstraints对象结构,即specificConstraints,指明一个范围内的级别 specificConstraints, _ := log.NewListConstraints([]log.LogLevel{log.InfoLvl, log.ErrorLvl})//一个个指明可用的级别,这里即只能使用info和error这两个级别 ex, _ := log.NewLogLevelException("*", "*main.go", specificConstraints) exceptions := []*log.LogLevelException{ex} //生成一个*log.LogLevelException对象列表 logger := log.NewAsyncLoopLogger(log.NewLoggerConfig(constraints, exceptions, root))//使用了这个函数就能够生成一个完整的seelog配置了 log.ReplaceLogger(logger) //下面的内容使用的就是我们上面自定义的日志生成器了 log.Trace("This should not be seen") log.Debug("This should not be seen") log.Info("Test") log.Error("Test2") } 返回: userdeMBP:go-learning user$ go run test.go 1551754090234813000 [Info] Hello from Seelog! Trace This should not be seen test.go Debug This should not be seen test.go Info Test test.go Error Test2 test.go 相关使用的函数: NewConsoleWriterfunc NewConsoleWriter() (writer *consoleWriter, err error) 创建一个新的控制台写入器。如果无法创建控制台写入器,则返回错误。 NewFormatterfunc NewFormatter(formatString string) (*formatter, error)
NewFormatter使用格式字符串创建新的格式化程序,即等价于配置中的<format>声明格式 NewSplitDispatcherfunc NewSplitDispatcher(formatter *formatter, receivers []interface{}) (*splitDispatcher, error)
声明一个Dispatcher分配器,即等价于配置中的<Splitter>。第一个参数即指定该分配器消息输出使用的格式,第二个参数指定的是日志的接收器,即是输出到标准输出,还是文件等 NewMinMaxConstraintsfunc NewMinMaxConstraints(min LogLevel, max LogLevel) (*minMaxConstraints, error) NewMinMaxConstraints使用指定的最小和最大级别创建一个新的minMaxConstraints结构。指明配置中的某个分配器中能够输出的日志级别的最大最小限制,这是指定一个范围 NewListConstraintsfunc NewListConstraints(allowList []LogLevel) (*listConstraints, error) NewListConstraints使用指定的允许级别创建一个新的listConstraints结构。这是一个个指明能够使用的级别类型 LogLevelExceptiontype LogLevelException struct { // contains filtered or unexported fields } LogLevelException表示当你需要一些特定的文件或函数来覆盖常规约束并使用它们自己的约束时使用的例外情况。即配置中的<exception> NewLogLevelExceptionfunc NewLogLevelException(funcPattern string, filePattern string, constraints logLevelConstraints) (*LogLevelException, error) NewLogLevelException创建一个新的例外.第一个参数指明该例外用于的函数需要满足的模式,第二个参数指明该例外用于的文件需要满足的模式,第三个例外则是指明该例外的日志级别限制,可使用NewMinMaxConstraints函数和NewListConstraints函数的返回值 NewAsyncLoopLoggerfunc NewAsyncLoopLogger(config *logConfig) *asyncLoopLogger NewAsyncLoopLogger创建一个新的异步循环记录器,声明该seelog使用的是异步循环,即等价于配置中的<seelog type="asyncloop">。使用了这个函数就能够生成一个完整的seelog配置了 NewLoggerConfigfunc NewLoggerConfig(c logLevelConstraints, e []*LogLevelException, d dispatcherInterface) *logConfig 生成一个日志记录器的配置信息,用来作为NewAsyncLoopLogger函数的输入。第一个参数是该日志记录器的日志级别限制,可以使用NewMinMaxConstraints函数和NewListConstraints函数的返回值;第二个参数是使用的例外的例外对象列表;第三个参数是指定了格式format和输出方式的分配器,即NewSplitDispatcher函数的返回值
4.其他函数: 1)New* 类型函数 1》指明所用的type类型,如上面的NewAsyncLoopLogger函数作用: NewSyncLoggerfunc NewSyncLogger(config *logConfig) *syncLogger NewSyncLogger创建一个同步的日志记录器,相当于配置中的<seelog type="sync">。第一个参数使用的是NewLoggerConfig函数的返回值,指明日志级别限制、例外和指定了格式format和输出方式的分配器 NewAsyncAdaptiveLoggerfunc NewAsyncAdaptiveLogger( config *logConfig, minInterval time.Duration, maxInterval time.Duration, criticalMsgCount uint32) (*asyncAdaptiveLogger, error) NewAsyncLoopLogger创建一个异步适应性生成器,相当于配置中的<seelog type="adaptive" mininterval="200000000" maxinterval="1000000000" critmsgcount="5">,第一个参数使用的是NewLoggerConfig函数的返回值,指明日志级别限制、例外和指定了格式format和输出方式的分配器;第二个和第三个参数指定计时器最小和最大时间间隔;第四个参数为关键消息计数 NewAsyncTimerLoggerfunc NewAsyncTimerLogger(config *logConfig, interval time.Duration) (*asyncTimerLogger, error) NewAsyncLoopLogger创建一个异步循环日志记录器,即相当于配置中的<seelog type="asynctimer" asyncinterval="5000">,第一个参数使用的是NewLoggerConfig函数的返回值,指明日志级别限制、例外和指定了格式format和输出方式的分配器;第二个参数指明的是计数器的时间间隔,即asyncinterval
2》接收器,即指定日志输出的形式,如上面的NewConsoleWriter
NewBufferedWriter
func NewBufferedWriter(innerWriter io.Writer, bufferSize int, flushPeriod time.Duration) (*bufferedWriter, error)
NewBufferedWriter创建一个新的缓冲写入器结构,即配置中的<buffered size="10000" flushperiod="1000">。第一个参数指定在写入内存同时写入的文件对象;第二个参数bufferSize以字节为单位的内存缓冲区的大小,0 则表示关闭此功能;第三个参数即指定的缓冲区刷新之间的间隔
NewConnWriter
func NewConnWriter(netName string, addr string, reconnectOnMsg bool) *connWriter
在网络netName上创建地址addr的写入器,相当于配置的<conn formatid="syslog" net="tcp4" addr="server.address:5514" tls="true" insecureskipverify="true" />。第一个参数指定使用的网络类型,即对应的net;第二个参数指定网络地址;第三个参数如果reconnectOnMsg = true,将在每次写入时打开连接 NewFileWriterfunc NewFileWriter(fileName string) (writer *fileWriter, err error)
创建一个新文件和相应的写入器。如果无法创建文件就会返回错误。相当于配置中的<file path="log.log"/>,第一个参数用于指明日志文件的名字 NewFormattedWriterfunc NewFormattedWriter(writer io.Writer, formatter *formatter) (*formattedWriter, error) NewRollingFileWriterSizefunc NewRollingFileWriterSize(fpath string, atype rollingArchiveType, apath string, maxSize int64, maxRolls int, namemode rollingNameMode, archiveExploded bool) (*rollingFileWriterSize, error) 相当于配置中<rollingfile type="size" filename="logs/roll.log" maxsize="1000" maxrolls="5" />,type为size。第一个参数指定回滚文件的路径;第二个参数指定存储旧卷而不是删除旧卷的存档的类型,相当于archivetype;第三个参数即指定存储旧卷的存档的路径,相当于archivepath;第四个参数为指定文件最大字节数;第五个参数为滚动文件的命名模式,相当于配置的namemode;第六个参数用于用于指定日志是应该被分解还是分组到同一个归档文件中 NewRollingFileWriterTimefunc NewRollingFileWriterTime(fpath string, atype rollingArchiveType, apath string, maxr int, timePattern string, namemode rollingNameMode, archiveExploded bool, fullName bool) (*rollingFileWriterTime, error) 相当于配置中的<rollingfile type="date" filename="logs/roll.log" datepattern="02.01.2006" maxrolls="7" />,type为date。第四个参数为指定文件中的最大行数;第五个参数指定输出在文件中时间的格式 NewSMTPWriterfunc NewSMTPWriter(sa, sn string, ras []string, hn, hp, un, pwd string, cacdps []string, subj string, headers []string) *smtpWriter NewSMTPWriter 返回一个新的SMTP写入器,相当于配置中的<smtp senderaddress="[email protected]" sendername="Automatic notification service" hostname="mail.none.org" hostport="587" username="nns" password="123">。sa,sn对应的就是senderaddress,sendername;ras即配置中子元素recipient的address可以有多个所以为列表,如: <recipient address="[email protected]"/> <recipient address="[email protected]"/> hn, hp, un, pwd对应的是hostname,hostport,username,password;cacdps即子元素cacertdirpath中的path值,如<cacertdirpath path="cacdp1"/>;subj即subject-电子邮件的主题;headers即该邮件的头消息,可以有多个值,所以为列表,如: <header name="Priority" value="Urgent" /> <header name="Importance" value="high" />
3》分配器,如上面的NewSplitDispatcher函数 NewFilterDispatcherfunc NewFilterDispatcher(formatter *formatter, receivers []interface{}, allowList ...LogLevel) (*filterDispatcher, error)
NewFilterDispatcher使用允许的级别列表创建一个新的filterDispatcher,相当于配置中的<filter levels="trace,debug">。
下面是自定义的分配器 NewCustomReceiverDispatcherfunc NewCustomReceiverDispatcher(formatter *formatter, customReceiverName string, cArgs CustomReceiverInitArgs) (*customReceiverDispatcher, error)
NewCustomReceiverDispatcher创建一个customReceiverDispatcher,它将数据分派到配置文件中使用<custom>标记创建的特定接收器。 NewCustomReceiverDispatcherByValuefunc NewCustomReceiverDispatcherByValue(formatter *formatter, customReceiver CustomReceiver, name string, cArgs CustomReceiverInitArgs) (*customReceiverDispatcher, error)
NewCustomReceiverDispatcherByValue基本上与NewCustomReceiverDispatcher相同,但是使用特定的CustomReceiver值而不是按类型实例化一个新值
4》格式化,如上面的NewFormatter函数
5》限制,如上面的NewListConstraints和NewMinMaxConstraints NewOffConstraintsfunc NewOffConstraints() (*offConstraints, error) “off”日志级别 “off”是一个特殊的日志级别,它意味着禁用日志记录。它可以在minlevel和level约束中使用,因此你可以在全局约束或例外约束中写入'minlevel= “off”'和'levels= “off”'来禁用日志。
2)常量 1》日志级别 const ( TraceLvl = iota //0 DebugLvl //1 InfoLvl WarnLvl ErrorLvl CriticalLvl Off //6 ) 2》日志级别字符串表示(使用在配置文件中) const ( TraceStr = "trace" DebugStr = "debug" InfoStr = "info" WarnStr = "warn" ErrorStr = "error" CriticalStr = "critical" OffStr = "off" ) 3》使用 %Date和%Time别名表示的日期和时间的格式化 const ( DateDefaultFormat = "2006-01-02" TimeFormat = "15:04:05" ) 4》FormatterSymbol是配置文件中用于标记特殊格式别名的特殊符号。 const ( FormatterSymbol = '%' ) 5》MaxQueueSize是队列中导致立即刷新的消息的关键数量。 const ( MaxQueueSize = 10000 ) 6》发送SMTP时的默认subject const ( // Default subject phrase for sending emails. DefaultSubjectPhrase = "Diagnostic message from server: " )
3)变量 var ( DefaultFormatter *formatter ) var DefaultMsgFormat = "%Ns [%Level] %Msg%n" 默认使用的日志消息的输出格式 ,即时间 [日志级别] 日志消息 换行符
4)输出日志函数 Criticalfunc Critical(v ...interface{}) error
Critical使用其操作数的默认格式来格式消息,并写入日志级别= Critical的默认日志记录器 Criticalffunc Criticalf(format string, params ...interface{}) error Criticalf根据格式说明符format格式化消息,并使用日志级别 = Critical写入默认日志记录器 Debugfunc Debug(v ...interface{})
Debug使用其操作数的默认格式来格式化消息,并使用日志级别= Debug将消息写入默认日志记录器 Debugffunc Debugf(format string, params ...interface{}) Debugf根据格式说明符格式化消息,并使用日志级别 = Debug写入默认日志记录器。 Errorfunc Error(v ...interface{}) error
Error使用其操作数的默认格式来格式化消息,并使用日志级别= Error写入默认日志记录器 Errorffunc Errorf(format string, params ...interface{}) error Errorf根据格式说明符format来格式化消息,并使用日志级别= Error写入默认日志记录器 Infofunc Info(v ...interface{})
Info 信息使用其操作数的默认格式来格式化消息,并使用日志级别 = Info写入默认日志记录器 Infoffunc Infof(format string, params ...interface{}) Infof根据格式说明符来格式化消息,并使用日志级别= Info写入默认日志记录器。 Tracefunc Trace(v ...interface{})
Trace使用其操作数的默认格式来格式化消息,并使用日志级别= Trace写入默认日志记录器 Traceffunc Tracef(format string, params ...interface{}) Tracef根据格式说明符来格式化消息,并使用日志级别= Trace写入默认日志记录器。 Warnfunc Warn(v ...interface{}) error
Warn使用其操作数的默认格式来格式化消息,并使用日志级别= Warn写入默认日志记录器 Warnffunc Warnf(format string, params ...interface{}) error Warnf根据格式说明符来格式化消息,并使用日志级别 = Warn写入默认日志记录器 举例: package main import log "github.com/cihub/seelog" func main() { testConfig := ` <seelog type="sync" minlevel="trace"> <outputs><console/></outputs> </seelog>` logger, _ := log.LoggerFromConfigAsBytes([]byte(testConfig)) log.ReplaceLogger(logger) defer log.Flush() 返回: userdeMBP:go-learning user$ go run test.go 1551777220280758000 [Trace] NOT Printed 1551777220280819000 [Trace] Returning NOT Printed 1551777220280842000 [Debug] NOT Printed 1551777220280848000 [Debug] Returning NOT Printed 1551777220280853000 [Info] Printed 1551777220280858000 [Info] Returning Printed 1551777220280863000 [Warn] Printed 1551777220280871000 [Warn] Returning Printed 1551777220280876000 [Error] Printed 1551777220280885000 [Error] Returning Printed 1551777220280891000 [Critical] Printed 1551777220280896000 [Critical] Returning Printed
5) Flushfunc Flush() Flush立即处理所有当前排队的消息和所有当前缓冲的消息。它是一个阻塞调用,仅在队列为空且所有缓冲区为空时才返回。
UseLoggerfunc UseLogger(logger LoggerInterface) error UseLogger将 'Current'包级别的日志记录器变量设置为指定值。此变量用于所有Trace/Debug/... 包级功能。 ⚠️:UseLogger不关闭前一个日志记录器(只刷新它)。因此,如果你经常使用它来替换日志记录程序,而不是在其他代码中关闭它们,那么最终将导致内存泄漏。 如果你调用了: seelog.UseLogger(somelogger) 之后你再调用: seelog.Debug("abc") 它其实久等价于: somelogger.Debug("abc")
ReplaceLoggerfunc ReplaceLogger(logger LoggerInterface) error ReplaceLogger充当UseLogger,但是以前使用的日志记录器会被销毁(默认和禁用的日志记录器除外)。 举例: package main import log "github.com/cihub/seelog" func main() { log.Info("Replace before Printed") //使用的是默认的格式 testConfig := ` <seelog type="sync" minlevel="info"> <outputs formatid="main"><console/></outputs> <formats> <format id="main" format="%UTCDate %UTCTime - [%LEV] - %RelFile - l%Line - %Msg%n"></format> </formats> </seelog>` logger, _ := log.LoggerFromConfigAsBytes([]byte(testConfig)) log.ReplaceLogger(logger) //替换后使用的就是上面新定义的格式了 defer log.Flush() log.Info("Replace after Printed") } 返回: userdeMBP:go-learning user$ go run test.go 1551777876234048000 [Info] Replace before Printed 2019-03-05 09:24:36 - [INF] - test.go - l20 - Replace after Printed
6)日志级别 LogLeveltype LogLevel uint8 日志级别类型 LogLevelFromStringfunc LogLevelFromString(levelStr string) (level LogLevel, found bool) LogLevelFromString解析字符串,如果成功就返回字符串相应的日志级别。Stringfunc (level LogLevel) String() string
LogLevelToString返回指定级别的seelog字符串表示形式。返回“”用于无效的日志级别。
7)日志级别例外 之前上面也讲到了,即 LogLevelExceptiontype LogLevelException struct {
// contains filtered or unexported fields
}
LogLevelException表示当你需要一些特定的文件或函数来覆盖常规约束并使用它们自己的约束时使用的例外情况。即配置中的<exception> NewLogLevelExceptionfunc NewLogLevelException(funcPattern string, filePattern string, constraints logLevelConstraints) (*LogLevelException, error)
NewLogLevelException创建一个新的例外.第一个参数指明该例外用于的函数需要满足的模式,第二个参数指明该例外用于的文件需要满足的模式,第三个例外则是指明该例外的日志级别限制,可使用NewMinMaxConstraints函数和NewListConstraints函数的返回值 然后下面是一些读取定义的例外中的一些值的方法: FilePatternfunc (logLevelEx *LogLevelException) FilePattern() string
FilePattern返回例外的文件模式 对应配置中的: <exceptions> <exception filepattern="test*" minlevel="error"/> </exceptions> FuncPatternfunc (logLevelEx *LogLevelException) FuncPattern() string
FuncPattern返回例外的函数模式 对应配置中的: <exceptions> <exception funcpattern="main.testFunc" minlevel="warn"/> </exceptions> IsAllowedfunc (logLevelEx *LogLevelException) IsAllowed(level LogLevel) bool
如果此LogLevelException的约束是允许指定的level日志级别的,那么IsAllowed将返回true MatchesContextfunc (logLevelEx *LogLevelException) MatchesContext(context LogContextInterface) bool
如果上下文context匹配此LogLevelException的模式,则MatchesContext返回true Stringfunc (logLevelEx *LogLevelException) String() string
8)LoggerInterface日志记录器接口 LoggerInterfacetype LoggerInterface interface { // Tracef formats message according to format specifier // and writes to log with level = Trace. Tracef(format string, params ...interface{}) // Debugf formats message according to format specifier // and writes to log with level = Debug. Debugf(format string, params ...interface{}) // Infof formats message according to format specifier // and writes to log with level = Info. Infof(format string, params ...interface{}) // Warnf formats message according to format specifier // and writes to log with level = Warn. Warnf(format string, params ...interface{}) error // Errorf formats message according to format specifier // and writes to log with level = Error. Errorf(format string, params ...interface{}) error // Criticalf fo |
请发表评论