<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      封裝zap log打印日志

      封裝 go.uber.org/zap log打印日志:

      支持輸出到標準輸出、文件;

      輸出到文件支持按時間或者大小切分文件;

      支持多個日志輸出級別;

      package main
      
      import (
          "context"
          "github.com/opentracing/opentracing-go"
          "github.com/uber/jaeger-client-go"
          "go.uber.org/zap/zapcore"
          "go.uber.org/zap"
          rotatelogs "github.com/lestrrat-go/file-rotatelogs"
          "io"
          "os"
          "time"
      )
      
      type LogIface interface {
          // 包含鏈路跟蹤信息的日志方法
          InfoWithCtx(ctx context.Context, format string, v ...interface{})
          ErrorWithCtx(ctx context.Context, format string, v ...interface{})
          // DebugWithCtx、WarnWithCtx、Info...
      }
      
      var sugarLogger *zap.SugaredLogger
      
      /**
       * 日志配置
       */
      type Config struct {
          Path        string //日志打印路徑
          Level       string //需要打印日志的最低級別日志級別有debug,info,warn,error,panic,fatal
          OutputMode  int    // 0:file 1:stdout 2:file+stdout
          ArchiveTime int    //存檔時間(單位天,默認20天)
          AddCaller   bool   //是否打印文件名行號,默認不打印debug會打印
      }
      var (
          OutputFile          int = 0 //file
          OutputStdout        int = 1 //stdout
          OutputFileAndStdout int = 2 //file+stdout
      )
      
      /**
       * 日志級別
       */
      var (
          DebugLevel = "debug" //日志級別
          InfoLevel  = "info"
          WarnLevel  = "warn"
          ErrorLevel = "error"
          PanicLevel = "panic"
          FatalLevel = "fatal"
      )
      
      var levelMap = map[string]zapcore.Level{
          DebugLevel: zapcore.DebugLevel,
          InfoLevel:  zapcore.InfoLevel,
          WarnLevel:  zapcore.WarnLevel,
          ErrorLevel: zapcore.ErrorLevel,
          PanicLevel: zapcore.PanicLevel,
          FatalLevel: zapcore.FatalLevel,
      }
      
      func getLoggerLevel(lvl string) zapcore.Level {
          if level, ok := levelMap[lvl]; ok {
              return level
          }
          return zapcore.InfoLevel
      }
      
      /**
       * 打印日志方法
       */
      func InfoWithCtx(ctx context.Context, format string, v ...interface{}) {
          traceID := TraceID(ctx)
          if traceID == "" {
              sugarLogger.Infof(format, v...)
              return
          }
          sugarLogger.With("trace_id", traceID).Infof(format, v...)
      }
      
      func ErrorWithCtx(ctx context.Context, format string, v ...interface{}) {
          traceID := TraceID(ctx)
          if traceID == "" {
              sugarLogger.Errorf(format, v...)
              return
          }
          sugarLogger.With("trace_id", traceID).Errorf(format, v...)
      }
      
      func TraceID(ctx context.Context) string {
          sp := opentracing.SpanFromContext(ctx)
          if sp == nil {
              return ""
          }
          sctx, ok := sp.Context().(jaeger.SpanContext)
          if !ok {
              return ""
          }
          return sctx.TraceID().String()
      }
      
      func getWriter(filename string, archiveTime int) io.Writer {
          if archiveTime < 5 { //日志存檔時間小于5天時,默認更新為30天
              archiveTime = 30
          }
          var withMaxAge = time.Duration(archiveTime) * 24 * time.Hour
          hook, err := rotatelogs.New(
              filename+".%Y-%m-%d", //info.log.2021-10-22
              //rotatelogs.WithLinkName(filename),         //為最新的日志建立軟連接
              rotatelogs.WithMaxAge(withMaxAge),         //默認保存30天
              rotatelogs.WithRotationTime(time.Hour*24), //切割頻率 24小時
          )
          if err != nil {
              panic(err)
          }
          return hook
      }
      
      /**
       * conf.Path: 日志目錄
       * conf.Level: 日志級別
       * serviceName: 服務名
       * addCaller: 是否開啟打印文件名以及行號信息
       * outputModel: 日志打印方式 0:file 1:stdout 2:file+stdout
       * archiveTime: 存檔時間(單位天,默認20天)
       */
      func LoadConfig(conf *Config, serviceName string) *zap.Logger {
          // 1.設置級別
          logLevel := getLoggerLevel(conf.Level)
          infoLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
              return lvl >= logLevel
          })
      
          // 2.設置文件存儲路徑
          logPath := conf.Path
          if logPath == "" {
              logPath = "./log/info.log"
          }
          infoWriter := getWriter(logPath, conf.ArchiveTime)
      
          // 3.設置config
          config := zapcore.EncoderConfig{
              MessageKey:    "message",
              LevelKey:      "level",
              TimeKey:       "time",
              CallerKey:     "caller",
              StacktraceKey: "stack",
              EncodeLevel:   zapcore.CapitalLevelEncoder,
              EncodeCaller:  zapcore.ShortCallerEncoder,
              EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
                  enc.AppendString(t.Format("2006-01-02T15:04:05-07:00"))
              },
              EncodeDuration: func(d time.Duration, enc zapcore.PrimitiveArrayEncoder) {
                  enc.AppendInt64(int64(d) / 1000000)
              },
          }
          encoder := zapcore.NewJSONEncoder(config)
      
          // 4.初始化日志操作句柄
          var core zapcore.Core
          if conf.OutputMode == OutputFileAndStdout {
              core = zapcore.NewTee(
                  zapcore.NewCore(encoder, zapcore.AddSync(infoWriter), infoLevel),
                  zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout)), logLevel),
              )
          } else if conf.OutputMode == OutputStdout {
              core = zapcore.NewTee(
                  zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), logLevel),
              )
          } else {
              core = zapcore.NewTee(
                  zapcore.NewCore(encoder, zapcore.AddSync(infoWriter), infoLevel),
              )
          }
          var option []zap.Option
          option = []zap.Option{zap.AddStacktrace(zap.ErrorLevel), zap.Fields(zap.String("service", serviceName))} //error級別會打印棧
          if conf.AddCaller {
              option = append(option, zap.AddCaller(), zap.AddCallerSkip(1))
          }
          return zap.New(core, option...)
      }
      
      //釋放資源
      func DeferLog() {
          _ = sugarLogger.Sync()
      }
      
      func main() {
          conf := &Config{
              Path:        "",
              Level:       InfoLevel,
              OutputMode:  2,
              ArchiveTime: 30,
              AddCaller:   false,
          }
          sugarLogger = LoadConfig(conf, "test-srv").Sugar()
          InfoWithCtx(context.Background(), "current time: %v", time.Now().Unix())
      }

       

      posted @ 2025-08-07 20:12  劃水的貓  閱讀(17)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 人妻中文字幕亚洲精品| 国产91色在线精品三级| 中文字幕结果国产精品| 正在播放酒店约少妇高潮| 久久精品道一区二区三区| 日韩精品无码一区二区视频| 激情影院内射美女| 色综合激情丁香七月色综合| 日韩中文字幕人妻一区| 大地资源网中文第五页| 伊人色综合九久久天天蜜桃| 双乳奶水饱满少妇呻吟免费看 | 卢湾区| 日韩精品视频一二三四区| 国产精品自拍实拍在线看| 欧美日韩国产亚洲沙发| 国产精品福利自产拍在线观看| 国产精品老年自拍视频| 婷婷色综合成人成人网小说| 国产成人一卡2卡3卡四卡视频| 国产+亚洲+制服| 中文字幕av国产精品| 四房播色综合久久婷婷| 精品无人区卡一卡二卡三乱码| 強壮公弄得我次次高潮A片| 最新av中文字幕无码专区| 中文字幕日韩视频欧美一区| 色成人亚洲| 亚洲精品国产中文字幕| 日本又色又爽又黄的a片吻戏| 美女一区二区三区亚洲麻豆| 午夜福利片1000无码免费| 三河市| 日本一区二区a√成人片| 久久96热在精品国产高清 | 亚洲AⅤ天堂AV天堂无码| 国产一区二区三区麻豆视频| 国产成人片无码视频在线观看| 亚洲一区二区中文av| 国产第一页浮力影院入口| 亚洲av无码精品色午夜蛋壳|