惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
Microsoft Azure Blog
Microsoft Azure Blog
MongoDB | Blog
MongoDB | Blog
小众软件
小众软件
Apple Machine Learning Research
Apple Machine Learning Research
O
OpenAI News
酷 壳 – CoolShell
酷 壳 – CoolShell
The GitHub Blog
The GitHub Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
博客园 - 聂微东
Engineering at Meta
Engineering at Meta
W
WeLiveSecurity
Hacker News: Ask HN
Hacker News: Ask HN
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
D
Docker
F
Full Disclosure
AI
AI
罗磊的独立博客
博客园 - 【当耐特】
U
Unit 42
S
SegmentFault 最新的问题
Stack Overflow Blog
Stack Overflow Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
P
Palo Alto Networks Blog
博客园_首页
H
Help Net Security
量子位
月光博客
月光博客
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 司徒正美
F
Fortinet All Blogs
D
DataBreaches.Net
B
Blog RSS Feed
Webroot Blog
Webroot Blog
TaoSecurity Blog
TaoSecurity Blog
S
Secure Thoughts
爱范儿
爱范儿
I
InfoQ
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Attack and Defense Labs
Attack and Defense Labs
Application and Cybersecurity Blog
Application and Cybersecurity Blog
C
CERT Recently Published Vulnerability Notes
Martin Fowler
Martin Fowler
Blog — PlanetScale
Blog — PlanetScale
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
Securelist

hanjm's blog

深入理解Prometheus(GO SDK及Grafana基本面板) 深入理解Prometheus(GO SDK及Grafana基本面板) 深入理解ActiveMQ消息队列协议STMOP AMQP MQTT Macos Docker container连接宿主机172.17.0.1的办法 Nginx With gRPC编译安装 Go sql.Driver的mysql Driver 中的一个有意思的行为 学习Influxdb GRPC文档阅读心得 Go如何优雅地错误处理(Error Handling and Go 1) Go如何优雅地错误处理(Error Handling and Go 1) 深入理解NATS & NATS Streaming (踩坑记) 深入理解GO时间处理(time.Time) 深入理解GO时间处理(time.Time) Go如何精确计算小数-Decimal研究-Tidb MyDecimal问题 DockerContainer下gdb无法正常工作的解决办法 Go sync.Pool Slice Benchmark Go最佳实践 Linux Cli下酷工具收集(持续) MacOS下酷工具收集(持续) Linux Cli下酷工具收集(持续) MacOS下酷工具收集(持续) 知名公司架构资料整理(持续) 知名公司架构资料整理(持续) Mysql 连接池问题 Go strings.TrimLeft() strings.TrimPrefix().md
GO Logger 日志实践
本文作者: hanjm · 2017-05-19 · via hanjm's blog
package zaplog

import (
"bytes"
"fmt"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"log"
"runtime"
"strings"
)

// CallerEncoder will add caller to log. format is "filename:lineNum:funcName", e.g:"zaplog/zaplog_test.go:15:zaplog.TestNewLogger"
func CallerEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(strings.Join([]string{caller.TrimmedPath(), runtime.FuncForPC(caller.PC).Name()}, ":"))
}

func newLoggerConfig(debugLevel bool) (loggerConfig zap.Config) {
loggerConfig = zap.NewProductionConfig()
loggerConfig.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
loggerConfig.EncoderConfig.EncodeCaller = CallerEncoder
if debugLevel {
loggerConfig.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
}
return
}

// NewCustomLoggers is a shortcut to get normal logger, noCallerLogger.
func NewCustomLoggers(debugLevel bool) (logger, noCallerLogger *zap.Logger) {
loggerConfig := newLoggerConfig(debugLevel)
logger, err := loggerConfig.Build()
if err != nil {
panic(err)
}
loggerConfig.DisableCaller = true
noCallerLogger, err = loggerConfig.Build()
if err != nil {
panic(err)
}
return
}

// NewLogger return a normal logger
func NewLogger(debugLevel bool) (logger *zap.Logger) {
loggerConfig := newLoggerConfig(debugLevel)
logger, err := loggerConfig.Build()
if err != nil {
panic(err)
}
return
}

// NewNoCallerLogger return a no caller key value, will be faster
func NewNoCallerLogger(debugLevel bool) (noCallerLogger *zap.Logger) {
loggerConfig := newLoggerConfig(debugLevel)
loggerConfig.DisableCaller = true
noCallerLogger, err := loggerConfig.Build()
if err != nil {
panic(err)
}
return
}

// CompatibleLogger is a logger which compatible to logrus/std log/prometheus.
// it implements Print() Println() Printf() Dbug() Debugln() Debugf() Info() Infoln() Infof() Warn() Warnln() Warnf()
// Error() Errorln() Errorf() Fatal() Fataln() Fatalf() Panic() Panicln() Panicf() With() WithField() WithFields()
type CompatibleLogger struct {
_log *zap.Logger
}

// NewCompatibleLogger return CompatibleLogger with caller field
func NewCompatibleLogger(debugLevel bool) *CompatibleLogger {
return &CompatibleLogger{NewLogger(debugLevel).WithOptions(zap.AddCallerSkip(1))}
}

// Print logs a message at level Info on the compatibleLogger.
func (l CompatibleLogger) Print(args ...interface{}) {
l._log.Info(fmt.Sprint(args...))
}

// Println logs a message at level Info on the compatibleLogger.
func (l CompatibleLogger) Println(args ...interface{}) {
l._log.Info(fmt.Sprint(args...))
}

// Printf logs a message at level Info on the compatibleLogger.
func (l CompatibleLogger) Printf(format string, args ...interface{}) {
l._log.Info(fmt.Sprintf(format, args...))
}

// Debug logs a message at level Debug on the compatibleLogger.
func (l CompatibleLogger) Debug(args ...interface{}) {
l._log.Debug(fmt.Sprint(args...))
}

// Debugln logs a message at level Debug on the compatibleLogger.
func (l CompatibleLogger) Debugln(args ...interface{}) {
l._log.Debug(fmt.Sprint(args...))
}

// Debugf logs a message at level Debug on the compatibleLogger.
func (l CompatibleLogger) Debugf(format string, args ...interface{}) {
l._log.Debug(fmt.Sprintf(format, args...))
}

// Info logs a message at level Info on the compatibleLogger.
func (l CompatibleLogger) Info(args ...interface{}) {
l._log.Info(fmt.Sprint(args...))
}

// Infoln logs a message at level Info on the compatibleLogger.
func (l CompatibleLogger) Infoln(args ...interface{}) {
l._log.Info(fmt.Sprint(args...))
}

// Infof logs a message at level Info on the compatibleLogger.
func (l CompatibleLogger) Infof(format string, args ...interface{}) {
l._log.Info(fmt.Sprintf(format, args...))
}

// Warn logs a message at level Warn on the compatibleLogger.
func (l CompatibleLogger) Warn(args ...interface{}) {
l._log.Warn(fmt.Sprint(args...))
}

// Warnln logs a message at level Warn on the compatibleLogger.
func (l CompatibleLogger) Warnln(args ...interface{}) {
l._log.Warn(fmt.Sprint(args...))
}

// Warnf logs a message at level Warn on the compatibleLogger.
func (l CompatibleLogger) Warnf(format string, args ...interface{}) {
l._log.Warn(fmt.Sprintf(format, args...))
}

// Error logs a message at level Error on the compatibleLogger.
func (l CompatibleLogger) Error(args ...interface{}) {
l._log.Error(fmt.Sprint(args...))
}

// Errorln logs a message at level Error on the compatibleLogger.
func (l CompatibleLogger) Errorln(args ...interface{}) {
l._log.Error(fmt.Sprint(args...))
}

// Errorf logs a message at level Error on the compatibleLogger.
func (l CompatibleLogger) Errorf(format string, args ...interface{}) {
l._log.Error(fmt.Sprintf(format, args...))
}

// Fatal logs a message at level Fatal on the compatibleLogger.
func (l CompatibleLogger) Fatal(args ...interface{}) {
l._log.Fatal(fmt.Sprint(args...))
}

// Fatalln logs a message at level Fatal on the compatibleLogger.
func (l CompatibleLogger) Fatalln(args ...interface{}) {
l._log.Fatal(fmt.Sprint(args...))
}

// Fatalf logs a message at level Fatal on the compatibleLogger.
func (l CompatibleLogger) Fatalf(format string, args ...interface{}) {
l._log.Fatal(fmt.Sprintf(format, args...))
}

// Panic logs a message at level Painc on the compatibleLogger.
func (l CompatibleLogger) Panic(args ...interface{}) {
l._log.Panic(fmt.Sprint(args...))
}

// Panicln logs a message at level Painc on the compatibleLogger.
func (l CompatibleLogger) Panicln(args ...interface{}) {
l._log.Panic(fmt.Sprint(args...))
}

// Panicf logs a message at level Painc on the compatibleLogger.
func (l CompatibleLogger) Panicf(format string, args ...interface{}) {
l._log.Panic(fmt.Sprintf(format, args...))
}

// With return a logger with an extra field.
func (l *CompatibleLogger) With(key string, value interface{}) *CompatibleLogger {
return &CompatibleLogger{l._log.With(zap.Any(key, value))}
}

// WithField return a logger with an extra field.
func (l *CompatibleLogger) WithField(key string, value interface{}) *CompatibleLogger {
return &CompatibleLogger{l._log.With(zap.Any(key, value))}
}

// WithFields return a logger with extra fields.
func (l *CompatibleLogger) WithFields(fields map[string]interface{}) *CompatibleLogger {
i := 0
var clog *CompatibleLogger
for k, v := range fields {
if i == 0 {
clog = l.WithField(k, v)
} else {
clog = clog.WithField(k, v)
}
i++
}
return clog
}

// FormatStdLog set the output of stand package log to zaplog
func FormatStdLog() {
log.SetFlags(log.Llongfile)
log.SetOutput(&logWriter{NewNoCallerLogger(false)})
}

type logWriter struct {
logger *zap.Logger
}

// Write implement io.Writer, as std log's output
func (w logWriter) Write(p []byte) (n int, err error) {
i := bytes.Index(p, []byte(":")) + 1
j := bytes.Index(p[i:], []byte(":")) + 1 + i
caller := bytes.TrimRight(p[:j], ":")
// find last index of /
i = bytes.LastIndex(caller, []byte("/"))
// find penultimate index of /
i = bytes.LastIndex(caller[:i], []byte("/"))
w.logger.Info("stdLog", zap.ByteString("caller", caller[i+1:]), zap.ByteString("log", bytes.TrimSpace(p[j:])))
return len(p), nil
}