Go服务常规日志、监控日志分离

80 阅读1分钟

一个服务通常会有两类日志,对应两个日志全局实例:

  • 1、常规日志
    无规律,一般用于定位问题
  • 2、监控日志
    可以上报大数据平台进行清洗,结合监控指标进行数据分析

封装一下,易于日志框架依赖替换:

1. log.go

package log

import (
   "github.com/sirupsen/logrus"
   "gopkg.in/natefinch/lumberjack.v2"
)

var log *logrus.Logger

func Init(logLevel string) {

   log = logrus.New()
   level := logrus.InfoLevel
   switch {
   case logLevel == "debug":
      level = logrus.DebugLevel
   case logLevel == "info":
      level = logrus.InfoLevel
   case logLevel == "error":
      level = logrus.ErrorLevel
   default:
      level = logrus.InfoLevel
   }
   log.SetLevel(level)
   log.SetReportCaller(true)
   log.SetFormatter(&logrus.TextFormatter{
      ForceQuote:      true,
      TimestampFormat: "2006-01-02 15:04:05",
      FullTimestamp:   true,
   })
   log.SetOutput(&lumberjack.Logger{
      Filename:   "gateway.log",
      MaxSize:    100,
      MaxBackups: 100,
      MaxAge:     3,
      Compress:   true,
   })
}

func Println(v ...interface{}) {
   log.Info(v)
}

func Debug(v ...interface{}) {
   log.Debug(v)
}

func Info(v ...interface{}) {
   log.Info(v)
}

func Pair(key string, value interface{}) *logrus.Entry {
   return log.WithField(key, value)
}

func Pairs(fields logrus.Fields) *logrus.Entry {
   return log.WithFields(fields)
}

func WithError(err error) *logrus.Entry {
   return log.WithError(err)
}

func Warn(v ...interface{}) {
   log.Warn(v)
}

func Error(v ...interface{}) {
   log.Error(v)
}

func Fatal(v ...interface{}) {
   log.Fatal(v)
}

2. Event.go

// Event monitor information
type Event struct {
   // what business, mandatory
   Metric string
   // what scenario, secondary category under Metric, allow null
   MetricType string
   // what time, mandatory
   Time string
   // happening key info
   Key string
   // happening detail info
   Content interface{}
}

3. monitor.go

package monitor

import (
   "github.com/sirupsen/logrus"
   "gopkg.in/natefinch/lumberjack.v2"
)

var log *logrus.Logger

func Init() {
   log = logrus.New()
   log.SetFormatter(&logrus.JSONFormatter{
      DisableTimestamp: true,
   })
   log.SetOutput(&lumberjack.Logger{
      Filename:   "monitor.log",
      MaxSize:    100,
      MaxBackups: 100,
      MaxAge:     3,
      Compress:   true,
   })
}

func Report(event Event) {
   log.Info(event)
}

4. 使用

上报日志

monitor.Report(monitor.Event{
   Metric:     monitor.MetricApi,
   MetricType: monitor.MetricApiAccLog,
   Time:       now.Format(common.DateFormatMs),
   Key:        requestId,
   Content: monitor.ApiTransportMetric{
      Url:        r.URL.Path,
      Method:     r.Method,
      ReqHeader:  r.Header,
      ReqBody:    string(requestBody),
      Status:     status,
      RespHeader: w.Header(),
      RespBody:   body,
      StartTime:  requestStartTime,
      EndTime:    common.UnixMilliseconds(now),
      Cost:       common.UnixMilliseconds(now) - requestStartTime,
   },
})

常规日志

log.Pair("name", "wuxins").Info()
log.Info("hello world!")
log.Error("error occurs!")
log.Fatal("exit with code 1")