{"id":10068,"date":"2022-09-28T10:38:26","date_gmt":"2022-09-28T02:38:26","guid":{"rendered":"https:\/\/blog.ywdevops.cn\/?p=10068"},"modified":"2022-09-28T15:16:39","modified_gmt":"2022-09-28T07:16:39","slug":"zap","status":"publish","type":"post","link":"https:\/\/blog.ywdevops.cn\/index.php\/2022\/09\/28\/zap\/","title":{"rendered":"go\u8bed\u8a00\u4e4b\u65e5\u5fd7\u5e93zap"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><code>zap<\/code>\u662f<code>Uber<\/code>\u5f00\u53d1\u7684\u975e\u5e38\u5feb\u7684\u3001\u7ed3\u6784\u5316\u7684\uff0c\u5206\u65e5\u5fd7\u7ea7\u522b\u7684Go\u65e5\u5fd7\u5e93\u3002\u6839\u636eUber-go Zap\u7684\u6587\u6863\uff0c\u5b83\u7684\u6027\u80fd\u6bd4\u7c7b\u4f3c\u7684\u7ed3\u6784\u5316\u65e5\u5fd7\u5305\u66f4\u597d\uff0c\u4e5f\u6bd4\u6807\u51c6\u5e93\u66f4\u5feb<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u53ef\u5b9e\u73b0\u529f\u80fd\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>\u4e0d\u540c\u7ea7\u522b\u7684\u65e5\u5fd7\u8f93\u51fa\u5230\u4e0d\u540c\u6587\u4ef6\u4e2d<\/li><li>\u65e5\u5fd7\u6587\u4ef6\u6309\u7167\u6587\u4ef6\u5927\u5c0f\u6216\u65e5\u671f\u8fdb\u884c\u5207\u5272\u5b58\u50a8\uff0c\u4ee5\u907f\u514d\u5355\u4e00\u65e5\u5fd7\u6587\u4ef6\u8fc7\u5927<\/li><li>\u65e5\u5fd7\u4f7f\u7528\u7b80\u5355\u65b9\u4fbf\uff0c\u4e00\u6b21\u5b9a\u4e49\u5168\u5c40\u4f7f\u7528<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">github\u5730\u5740\uff1a<code>https:\/\/github.com\/uber-go\/zap<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u672c\u4f8b\u5b50\u9879\u76ee\u540d\u79f0\u4e3aoamp,\u6240\u7528\u914d\u7f6e\u6587\u4ef6\u5e93\u4e3agopkg.in\/ini.v1\uff0c\u5b98\u65b9\u5730\u5740\uff1a<strong>https:\/\/ini.unknwon.io\/<\/strong>,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1\u3001\u9996\u5148\u5728\u914d\u7f6e\u6587\u4ef6oamp\/conf\/app.ini\u4e2d\u7f16\u5199\u9700\u8981\u7684\u914d\u7f6e\uff0c\u5982\u4e0b\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;log]\n#\u5b9a\u4e49\u65e5\u5fd7\u7ea7\u522b,\u5206\u4e3adebug\u548cinfo\nLevel = info\r\n#\u5b9a\u4e49\u65e5\u5fd7\u683c\u5f0f\u5316\u7c7b\u578b\uff0c\u5206\u4e3ajson\u7c7b\u578b\u548c\u666e\u901a\u7c7b\u578bconsole\r\nFormat = json\n#\u5b9a\u4e49\u65e5\u5fd7\u6240\u5728\u7684\u6587\u4ef6\u5939,\u6b64\u6587\u4ef6\u5939\u4e3a\u76f8\u5bf9\u4e8e\u9879\u76ee\u6839\u76ee\u5f55\u7684\u6587\u4ef6\u5939\nDirectory = log\r\n#\u662f\u5426\u663e\u793a\u884c\u53f7\r\nShowLine = true\r\n#\u7f16\u7801\u7ea7\u522b,\u5305\u542b\u56db\u79cd:LowercaseLevelEncoder\u3001LowercaseColorLevelEncoder\u3001CapitalLevelEncoder\u3001CapitalColorLevelEncoder\r\nEncodeLevel = LowercaseLevelEncoder\r\n#\u662f\u5426\u8f93\u51fa\u5230\u63a7\u5236\u53f0\r\nLogToConsole = false\r\n#\u8fdb\u884c\u5207\u5272\u4e4b\u524d\u65e5\u5fd7\u6587\u4ef6\u6700\u5927\u5927\u5c0f(MB)\r\nMaxSize = 10\r\n#\u4fdd\u7559\u65e7\u6587\u4ef6\u7684\u6700\u5927\u4e2a\u6570\r\nMaxBackups = 5\r\n#\u4fdd\u7559\u65e7\u6587\u4ef6\u7684\u6700\u5927\u5929\u6570\r\nMaxAge = 10\r\n#\u662f\u5426\u538b\u7f29\r\nCompress = true\r\n#\u6808\u540d\r\nStacktraceKey = stacktrace<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">2\u3001\u5c06\u914d\u7f6e\u6587\u4ef6\u6620\u5c04\u5230\u7ed3\u6784\u4f53\u4e2d<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">(1)\u3001\u7f16\u5199\u6587\u4ef6oamp\/pkg\/setting\/setting.go\uff0c\u5148\u5b9a\u4e49\u7ed3\u6784\u4f53\uff0c\u5185\u5bb9\u5982\u4e0b\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u6ce8\u610f\uff1a\u7ed3\u6784\u4f53\u4e2d\u5b57\u6bb5\u8981\u4e0e\u914d\u7f6e\u6587\u4ef6\u4e2d\u5b57\u6bb5\u4e00\u6837\ntype log struct {\r\n    Level         string\r\n    Format        string\r\n    Directory     string\r\n    ShowLine      bool\r\n    StacktraceKey string\r\n    LogToConsole  bool\r\n    EncodeLevel   string\r\n    MaxSize       int\r\n    MaxBackups    int\r\n    MaxAge        int\r\n    Compress      bool\r\n}\r\nvar LogSetting = &amp;log{}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">(2)\u3001\u5c06\u914d\u7f6e\u6587\u4ef6\u5185\u5bb9\u6620\u5c04\u5230\u7ed3\u6784\u4f53\u4e2d\uff0c\u5982\u4e0b\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>func Setup() {\r\n\t\/\/\u8bfb\u53d6\u914d\u7f6e\u6587\u4ef6\r\n\tcfg, err := ini.Load(\"conf\/app.ini\")\r\n\tif err != nil {\r\n\t\tglobal.Log.Error(\"err\")\r\n\t}\r\n\t\/\/\u901a\u8fc7MapTo\u5c06\u914d\u7f6e\u6587\u4ef6log\u6620\u5c04\u5230\u7ed3\u6784\u4f53LogSetting\u4e2d\r\n\tif err := cfg.Section(\"log\").MapTo(LogSetting); err != nil {\r\n\t\tglobal.Log.Error(err.Error())\r\n\t}\r\n}<\/code><\/pre>\n\n\n\n<p class=\"has-luminous-vivid-amber-background-color has-background wp-block-paragraph\">\u6ce8\uff1a\u6620\u5c04\u540e\uff0c\u5176\u4f59\u6587\u4ef6\u901a\u8fc7setting.LogSetting.Level\u5c31\u53ef\u4ee5\u8bfb\u53d6\u54cd\u5e94\u914d\u7f6e\u4fe1\u606f<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">3\u3001\u5b9a\u4e49\u5168\u5c40\u53d8\u91cfLog\uff0c\u7f16\u8f91\u6587\u4ef6oamp\/global\/global.go\uff0c\u5185\u5bb9\u5982\u4e0b\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package global\r\n\r\nimport (\r\n\t\"go.uber.org\/zap\"\r\n)\r\n\r\/\/\u5916\u90e8\u8bbf\u95ee,\u56e0\u4e3aLog\u9700\u8981\u5927\u5199\nvar (\r\n\tLog *zap.Logger\r\n)\r<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">4\u3001\u7f16\u5199zap\u65e5\u5fd7\u5e93\u6587\u4ef6\uff0c\u7f16\u8f91oamp\/pkg\/logging\/zaplog.go\uff0c\u5185\u5bb9\u5982\u4e0b\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package logging\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"oamp\/global\"\r\n\t\"oamp\/pkg\/setting\"\r\n\t\"os\"\r\n\t\"time\"\r\n\r\n\t\"github.com\/natefinch\/lumberjack\"\r\n\t\"go.uber.org\/zap\"\r\n\t\"go.uber.org\/zap\/zapcore\"\r\n)\r\n\r\n\/\/\u521d\u59cb\u5316\u65e5\u5fd7,\u4f20\u9012\u65e5\u5fd7\u7ea7\u522b\u53c2\u6570\r\nfunc InitLog(level string) {\r\n\tvar (\r\n\t\tlogLevel = zap.InfoLevel \/\/\u5b9a\u4e49\u51fa\u521d\u59cb\u7684logLevel\u4e3ainfo\r\n\t)\r\n\t\/\/\u901a\u8fc7switch,\u6839\u636e\u4f20\u5165\u7684level\u4e0d\u540c,\u7ed9logLevel\u8d4b\u4e88\u4e0d\u540c\u7684\u503c\r\n\tswitch level {\r\n\tcase \"debug\":\r\n\t\tlogLevel = zap.DebugLevel \/\/debug\r\n\tcase \"info\":\r\n\t\tlogLevel = zap.InfoLevel \/\/info\r\n\tcase \"warn\":\r\n\t\tlogLevel = zap.WarnLevel \/\/warn\r\n\tcase \"error\":\r\n\t\tlogLevel = zap.ErrorLevel \/\/error\r\n\tcase \"panic\":\r\n\t\tlogLevel = zap.PanicLevel \/\/panic\r\n\tcase \"fatal\":\r\n\t\tlogLevel = zap.FatalLevel \/\/fatal\r\n\tdefault:\r\n\t\tlogLevel = zap.InfoLevel \/\/\u9ed8\u8ba4\u5c31\u662finfo\r\n\t}\r\n\t\/\/\u65e5\u5fd7\u7ea7\u522b,zap.LevelEnablerFunc(func(lev zapcore.Level) bool \u7528\u6765\u5212\u5206\u4e0d\u540c\u7ea7\u522b\u7684\u8f93\u51fa,zapcore.Level\u7c7b\u578b\u4e3aint8\r\n\tdebugPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { \/\/debug\u7ea7\u522b\r\n\t\treturn lev == zap.DebugLevel\r\n\t})\r\n\tinfoPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { \/\/info\u7ea7\u522b\r\n\t\treturn lev == zap.InfoLevel\r\n\t})\r\n\terrorPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { \/\/error\u7ea7\u522b\r\n\t\treturn lev == zap.ErrorLevel\r\n\t})\r\n\t\/\/\u5b9a\u4e49\u63a5\u53e3\u7c7b\u578b\u5207\u7247,zapcore.Core\u4e3a\u4e00\u4e2a\u63a5\u53e3\r\n\tvar cores &#91;]zapcore.Core\r\n\t\/\/\u5982\u679c\u65e5\u5fd7\u7ea7\u522b\u4e3adebug,\u90a3\u4e48\u5411\u5207\u7247\u4e2d\u6dfb\u52a0\u6570\u636e,\u6253\u5370debug\u65e5\u5fd7,\u5426\u5219\u6253\u5370info\u548cerror\r\n\tif logLevel == zap.DebugLevel {\r\n\t\tcores = append(cores, getEncoderCore(fmt.Sprintf(\".\/%s\/server_debug.log\", setting.LogSetting.Directory), debugPriority))\r\n\t} else if logLevel == zap.InfoLevel {\r\n\t\tcores = append(cores, getEncoderCore(fmt.Sprintf(\".\/%s\/server_info.log\", setting.LogSetting.Directory), infoPriority))\r\n\t\tcores = append(cores, getEncoderCore(fmt.Sprintf(\".\/%s\/server_error.log\", setting.LogSetting.Directory), errorPriority))\r\n\t}\r\n\t\/\/\u901a\u8fc7zap.New\u521b\u5efa\u4e00\u4e2alogger,NewTee\u521b\u5efa\u4e00\u4e2aCore\uff0c\u5c06\u65e5\u5fd7\u6761\u76ee\u590d\u5236\u5230\u4e24\u4e2a\u6216\u66f4\u591a\u7684\u5e95\u5c42Core\u4e2d,...\u8868\u793a\u89e3\u538b\u7f29\u5207\u7247\r\n\tlogger := zap.New(zapcore.NewTee(cores&#91;:]...))\r\n\t\/\/\u5224\u65ad\u662f\u5426\u663e\u793a\u884c\u53f7\r\n\tif setting.LogSetting.ShowLine {\r\n\t\tlogger = logger.WithOptions(zap.AddCaller())\r\n\t}\r\n\t\/\/\u5c06\u521b\u5efa\u540e\u7684logger\u8d4b\u503c\u7ed9\u5168\u5c40\u53d8\u91cfglobal.Log\r\n\tglobal.Log = logger\r\n}\r\n\r\n\/\/\u51fd\u6570\u53c2\u6570\u4e3a\u4e0a\u9762\u4f20\u9012\u8fc7\u6765\u7684\u6587\u4ef6\u540d\u548c\u7ea7\u522b,\u8fd4\u56de\u4e3a\u63a5\u53e3\u7c7b\u578b\r\nfunc getEncoderCore(fileName string, level zapcore.LevelEnabler) (core zapcore.Core) {\r\n\twriter := GetWriteSyncer(fileName) \/\/\u8c03\u7528\u51fd\u6570\u5bf9\u65e5\u5fd7\u8fdb\u884c\u5207\u5272,\u5e76\u8fd4\u56de\u5199\u5165\u4f4d\u7f6e\n        \/*\r\n             zapcore.NewCore\u65b9\u6cd5\u4e2d\u4e09\u4e2a\u53c2\u6570:\r\n             getEncoder(): \u4ee5\u4ec0\u4e48\u683c\u5f0f\u5199\u5165\u65e5\u5fd7\r\n             writer: \u65e5\u5fd7\u5199\u5230\u54ea\u91cc\r\n             level:   \u4ec0\u4e48\u7ea7\u522b\u7684\u65e5\u5fd7\u53ef\u4ee5\u88ab\u5199\u5165\r\n         *\/\r\n\treturn zapcore.NewCore(getEncoder(), writer, level)\r\n}\r\n\r\n\/\/\u5b9a\u4e49\u65e5\u5fd7\u8f93\u51fa\u683c\u5f0f\u4e3ajson\u8fd8\u662f\u666e\u901a\u683c\u5f0f\r\nfunc getEncoder() zapcore.Encoder {\r\n\t\/\/\u83b7\u53d6\u914d\u7f6e\u6587\u4ef6\u7684\u8f93\u51fa\u683c\u5f0f,json or console\r\n\tif setting.LogSetting.Format == \"json\" {\r\n\t\treturn zapcore.NewJSONEncoder(getEncoderConfig())\r\n\t}\r\n\treturn zapcore.NewConsoleEncoder(getEncoderConfig())\r\n}\r\n\r\n\/\/\u81ea\u5b9a\u4e49\u65e5\u5fd7\u683c\u5f0f,zapcore.EncoderConfig\u4e3a\u7ed3\u6784\u4f53\r\nfunc getEncoderConfig() (config zapcore.EncoderConfig) {\r\n\tconfig = zapcore.EncoderConfig{\r\n\t\tMessageKey:     \"message\",\r\n\t\tLevelKey:       \"level\",\r\n\t\tTimeKey:        \"time\",\r\n\t\tNameKey:        \"logger\",\r\n\t\tCallerKey:      \"caller\",                         \/\/\u65e5\u5fd7\u6587\u4ef6\u4f4d\u7f6e\r\n\t\tStacktraceKey:  setting.LogSetting.StacktraceKey, \/\/\u6808\u540d\r\n\t\tLineEnding:     zapcore.DefaultLineEnding,        \/\/\u9ed8\u8ba4\u7684\u7ed3\u5c3e\\n\r\n\t\tEncodeLevel:    zapcore.LowercaseLevelEncoder,    \/\/\u5c0f\u5199\u5b57\u6bcd\u8f93\u51fa\r\n\t\tEncodeTime:     CustomTimeEncoder,                \/\/\u81ea\u5b9a\u4e49\u65f6\u95f4\u683c\u5f0f\r\n\t\tEncodeDuration: zapcore.SecondsDurationEncoder,   \/\/\u7f16\u7801\u95f4\u9694\r\n\t\tEncodeCaller:   zapcore.FullCallerEncoder,        \/\/\u63a7\u5236\u6253\u5370\u7684\u6587\u4ef6\u4f4d\u7f6e\u662f\u7edd\u5bf9\u8def\u5f84,ShortCallerEncoder \u662f\u76f8\u5bf9\u8def\u5f84\r\n\t}\r\n\t\/\/\u6839\u636e\u914d\u7f6e\u6587\u4ef6\u91cd\u65b0\u914d\u7f6e\u7f16\u7801\u989c\u8272\u548c\u5b57\u4f53\r\n\tswitch {\r\n\tcase setting.LogSetting.EncodeLevel == \"LowercaseLevelEncoder\": \/\/ \u5c0f\u5199\u7f16\u7801\u5668(\u9ed8\u8ba4)\r\n\t\tconfig.EncodeLevel = zapcore.LowercaseLevelEncoder\r\n\tcase setting.LogSetting.EncodeLevel == \"LowercaseColorLevelEncoder\": \/\/ \u5c0f\u5199\u7f16\u7801\u5668\u5e26\u989c\u8272\r\n\t\tconfig.EncodeLevel = zapcore.LowercaseColorLevelEncoder\r\n\tcase setting.LogSetting.EncodeLevel == \"CapitalLevelEncoder\": \/\/ \u5927\u5199\u7f16\u7801\u5668\r\n\t\tconfig.EncodeLevel = zapcore.CapitalLevelEncoder\r\n\tcase setting.LogSetting.EncodeLevel == \"CapitalColorLevelEncoder\": \/\/ \u5927\u5199\u7f16\u7801\u5668\u5e26\u989c\u8272\r\n\t\tconfig.EncodeLevel = zapcore.CapitalColorLevelEncoder\r\n\tdefault:\r\n\t\tconfig.EncodeLevel = zapcore.LowercaseLevelEncoder\r\n\t}\r\n\treturn config\r\n}\r\n\r\n\/\/ \u81ea\u5b9a\u4e49\u65e5\u5fd7\u8f93\u51fa\u65f6\u95f4\u683c\u5f0f\r\nfunc CustomTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {\r\n\tenc.AppendString(t.Format(\"2006-01-02 15:04:05.000\"))\r\n}\r\n\r\n\/\/\u65e5\u5fd7\u5207\u5272,\u8fd4\u56de\u5199\u5165\u4f4d\u7f6e\r\nfunc GetWriteSyncer(file string) zapcore.WriteSyncer {\r\n\tlumberJackLogger := &amp;lumberjack.Logger{\r\n\t\tFilename:   file,                          \/\/ \u65e5\u5fd7\u6587\u4ef6\u7684\u4f4d\u7f6e\r\n\t\tMaxSize:    setting.LogSetting.MaxSize,    \/\/ \u5728\u8fdb\u884c\u5207\u5272\u4e4b\u524d\uff0c\u65e5\u5fd7\u6587\u4ef6\u7684\u6700\u5927\u5927\u5c0f\uff08\u4ee5MB\u4e3a\u5355\u4f4d\uff09\r\n\t\tMaxBackups: setting.LogSetting.MaxBackups, \/\/ \u4fdd\u7559\u65e7\u6587\u4ef6\u7684\u6700\u5927\u4e2a\u6570\r\n\t\tMaxAge:     setting.LogSetting.MaxAge,     \/\/ \u4fdd\u7559\u65e7\u6587\u4ef6\u7684\u6700\u5927\u5929\u6570\r\n\t\tCompress:   setting.LogSetting.Compress,   \/\/ \u662f\u5426\u538b\u7f29\/\u5f52\u6863\u65e7\u6587\u4ef6\r\n\t}\r\n\t\/\/\u5982\u679csetting.LogSetting.LogToConsole\u4e3atrue,\u90a3\u4e48\u65e5\u5fd7\u65e2\u8f93\u5165\u5230\u63a7\u5236\u53f0\u53c8\u8f93\u51fa\u5230\u6587\u4ef6\r\n\tif setting.LogSetting.LogToConsole {\r\n\t\treturn zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(lumberJackLogger))\r\n\t}\r\n\treturn zapcore.AddSync(lumberJackLogger)\r\n}\r<\/code><\/pre>\n\n\n\n<p class=\"has-luminous-vivid-amber-background-color has-background wp-block-paragraph\">\u6ce8\uff1a\u4e0a\u8ff0\u8bbe\u7f6e\u5982\u679c\u914d\u7f6e\u6587\u4ef6\u4e2dLevel\u4e3adebug\u7684\u65f6\u5019\uff0c\u53ea\u6253\u5370debug\u65e5\u5fd7\uff0c\u5426\u5219\u6253\u5370Info\u548cerror<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">5\u3001\u5728main.go\u6587\u4ef6\u4e2d\uff0c\u521d\u59cb\u5316setting.go\u6587\u4ef6\u548czao\u65e5\u5fd7\u5e93\u6587\u4ef6\uff0c\u5982\u4e0b\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"709\" height=\"203\" src=\"https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/18-2.png\" alt=\"\" class=\"wp-image-10082\" srcset=\"https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/18-2.png 709w, https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/18-2-300x86.png 300w, https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/18-2-600x172.png 600w\" sizes=\"auto, (max-width: 709px) 100vw, 709px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u521d\u59cb\u5316\u65e5\u5fd7\u5e93\u7684\u65f6\u5019\uff0c\u8981\u4f20\u9012\u65e5\u5fd7\u7ea7\u522b\uff0c\u5728\u6253\u5370\u65e5\u5fd7\u7684\u65f6\u5019\uff0c\u5728\u4efb\u610f\u4f4d\u7f6e\u901a\u8fc7global.Log.Info()\u5373\u53ef\u6253\u5370<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u542f\u52a8\u540e\u6253\u5370\u7684\u65e5\u5fd7\u5185\u5bb9\u5982\u4e0b\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;root@VM-16-6-centos oamp]# tail -n 100 log\/server_info.log \r\n{\"level\":\"info\",\"time\":\"2022-09-28 10:33:11.469\",\"caller\":\"\/data\/oamp\/main.go:22\",\"message\":\"Info........\"}\r\n{\"level\":\"info\",\"time\":\"2022-09-28 10:44:54.032\",\"caller\":\"\/data\/oamp\/main.go:22\",\"message\":\"Info........\"}\r\n{\"level\":\"info\",\"time\":\"2022-09-28 11:19:33.957\",\"caller\":\"\/data\/oamp\/main.go:22\",\"message\":\"Info........\"}\r<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;root@VM-16-6-centos oamp]# tail -n 100 log\/server_error.log\r\n{\"level\":\"error\",\"time\":\"2022-09-28 10:33:11.469\",\"caller\":\"\/data\/oamp\/main.go:23\",\"message\":\"Error........\"}\r\n{\"level\":\"error\",\"time\":\"2022-09-28 10:44:54.032\",\"caller\":\"\/data\/oamp\/main.go:23\",\"message\":\"Error........\"}\r\n{\"level\":\"error\",\"time\":\"2022-09-28 11:19:33.957\",\"caller\":\"\/data\/oamp\/main.go:23\",\"message\":\"Error........\"}\r<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>level\uff1a\u5f53\u524d\u65e5\u5fd7\u7ea7\u522b<\/li><li>time\uff1a\u5f53\u524d\u65f6\u95f4<\/li><li>caller\uff1a\u65e5\u5fd7\u5177\u4f53\u4f4d\u7f6e<\/li><li>message\uff1a\u5177\u4f53\u7684\u63cf\u8ff0\u4fe1\u606f<\/li><\/ul>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><strong>Gin\u4e2d\u4f7f\u7528zap\u65e5\u5fd7\u5e93<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u5728\u521d\u59cb\u5316gin\u5f15\u64ce\u7684\u65f6\u5019\uff0c\u6709\u4e24\u79cd\u65b9\u5f0fgin.Default()\u548cgin.New()\uff0c\u4e24\u8005\u7684\u533a\u522b\u662f\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>gin.Default()\u7528\u5230\u4e86gin\u6846\u67b6\u5185\u81ea\u5e26\u7684\u4e24\u4e2a\u9ed8\u8ba4\u4e2d\u95f4\u4ef7Logger()\u548cRecovery()\uff0cLogger()\u662f\u628agin\u6846\u67b6\u672c\u8eab\u7684\u65e5\u5fd7\u8f93\u51fa\u5230\u6807\u51c6\u8f93\u51fa\uff0c\u800cRecovery()\u662f\u5728\u7a0b\u5e8f\u51fa\u73b0panic\u7684\u65f6\u5019\u6062\u590d\u73b0\u573a\u5e76\u5199\u5165500\u54cd\u5e94\u7684<\/li><li>gin.New()\u6ca1\u6709\u7528\u81ea\u5e26\u7684\u4e2d\u95f4\u4ef6\uff0c\u56e0\u6b64\u5982\u679c\u901a\u8fc7gin.New()\u5b9e\u4f8b\u5f15\u64ce\uff0c\u63a7\u5236\u53f0\u770b\u4e0d\u5230\u8bf7\u6c42\u63a5\u53e3\u7684\u4efb\u4f55\u8f93\u51fa<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u5c06\u521d\u59cb\u5316\u5f15\u64ce\u6539\u4e3agin.New()\uff0c\u7136\u540e\u81ea\u5b9a\u4e49\u4e24\u4e2a\u4e2d\u95f4\u4ef6GinLogger()\u548cGinRecovery()\uff0c\u5b9e\u73b0\u5c06gin\u6846\u67b6\u4e2d\u7684\u65e5\u5fd7\u8f93\u51fa\u5230\u65e5\u5fd7\u5e93zap\u4e2d<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1\u3001\u4fee\u6539oamp\/router\/router.go\u6587\u4ef6\uff0c\u521d\u59cb\u5316\u5f15\u64ce\u6539\u4e3agin.New()\uff0c\u5982\u56fe\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"706\" height=\"201\" src=\"https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/19-2.png\" alt=\"\" class=\"wp-image-10096\" srcset=\"https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/19-2.png 706w, https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/19-2-300x85.png 300w, https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/19-2-600x171.png 600w\" sizes=\"auto, (max-width: 706px) 100vw, 706px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">2\u3001\u7f16\u8f91\u4e2d\u95f4\u4ef6\u6587\u4ef6, oamp\/middleware\/zaplog\/zaplog.go\uff0c\u5185\u5bb9\u5982\u4e0b\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package zaplog\r\n\r\nimport (\r\n\t\"net\"\r\n\t\"net\/http\"\r\n\t\"net\/http\/httputil\"\r\n\t\"oamp\/global\"\r\n\t\"os\"\r\n\t\"runtime\/debug\"\r\n\t\"strings\"\r\n\t\"time\"\r\n\r\n\t\"github.com\/gin-gonic\/gin\"\r\n\t\"go.uber.org\/zap\"\r\n)\r\n\r\n\/\/\u6b63\u5e38\u7684gin\u6846\u67b6\u65e5\u5fd7\u8f93\u51fa\r\nfunc GinLogger() gin.HandlerFunc {\r\n\treturn func(c *gin.Context) {\r\n\t\tstart := time.Now()\r\n\t\tpath := c.Request.URL.Path\r\n\t\tquery := c.Request.URL.RawQuery\r\n\t\tc.Next()\r\n\r\n\t\tcost := time.Since(start)\r\n\t\tglobal.Log.Info(path,\r\n\t\t\tzap.Int(\"status\", c.Writer.Status()),\r\n\t\t\tzap.String(\"method\", c.Request.Method),\r\n\t\t\tzap.String(\"path\", path),\r\n\t\t\tzap.String(\"query\", query),\r\n\t\t\tzap.String(\"ip\", c.ClientIP()),\r\n\t\t\tzap.String(\"user-agent\", c.Request.UserAgent()),\r\n\t\t\tzap.String(\"errors\", c.Errors.ByType(gin.ErrorTypePrivate).String()),\r\n\t\t\tzap.Duration(\"cost\", cost),\r\n\t\t)\r\n\t}\r\n}\r\n\r\n\/\/\u9879\u76ee\u53ef\u80fd\u51fa\u73b0\u7684panic\uff0c\u5e76\u4f7f\u7528zap\u8bb0\u5f55\u76f8\u5173\u65e5\u5fd7\r\nfunc GinRecovery(stack bool) gin.HandlerFunc {\r\n\treturn func(c *gin.Context) {\r\n\t\tdefer func() {\r\n\t\t\tif err := recover(); err != nil {\r\n\t\t\t\tvar brokenPipe bool\r\n\t\t\t\tif ne, ok := err.(*net.OpError); ok {\r\n\t\t\t\t\tif se, ok := ne.Err.(*os.SyscallError); ok {\r\n\t\t\t\t\t\tif strings.Contains(strings.ToLower(se.Error()), \"broken pipe\") || strings.Contains(strings.ToLower(se.Error()), \"connection reset by peer\") {\r\n\t\t\t\t\t\t\tbrokenPipe = true\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\thttpRequest, _ := httputil.DumpRequest(c.Request, false)\r\n\t\t\t\tif brokenPipe {\r\n\t\t\t\t\tglobal.Log.Error(c.Request.URL.Path,\r\n\t\t\t\t\t\tzap.Any(\"error\", err),\r\n\t\t\t\t\t\tzap.String(\"request\", string(httpRequest)),\r\n\t\t\t\t\t)\r\n\t\t\t\t\tc.Error(err.(error))\r\n\t\t\t\t\tc.Abort()\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif stack {\r\n\t\t\t\t\tglobal.Log.Error(\"&#91;Recovery from panic]\",\r\n\t\t\t\t\t\tzap.Any(\"error\", err),\r\n\t\t\t\t\t\tzap.String(\"request\", string(httpRequest)),\r\n\t\t\t\t\t\tzap.String(\"stack\", string(debug.Stack())),\r\n\t\t\t\t\t)\r\n\t\t\t\t} else {\r\n\t\t\t\t\tglobal.Log.Error(\"&#91;Recovery from panic]\",\r\n\t\t\t\t\t\tzap.Any(\"error\", err),\r\n\t\t\t\t\t\tzap.String(\"request\", string(httpRequest)),\r\n\t\t\t\t\t)\r\n\t\t\t\t}\r\n\t\t\t\tc.AbortWithStatus(http.StatusInternalServerError)\r\n\t\t\t}\r\n\t\t}()\r\n\t\tc.Next()\r\n\t}\r\n}\r<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">3\u3001\u5728\u8def\u7531\u7ec4\u4e2d\u6ce8\u518c\u4e2d\u95f4\u4ef6\uff0c\u5982\u56fe\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"709\" height=\"319\" src=\"https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/20-1.png\" alt=\"\" class=\"wp-image-10100\" srcset=\"https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/20-1.png 709w, https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/20-1-300x135.png 300w, https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/20-1-600x270.png 600w\" sizes=\"auto, (max-width: 709px) 100vw, 709px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">4\u3001\u8bf7\u6c42\u63a5\u53e3\u540e\uff0c\u53ef\u4ee5\u770b\u5230\u65e5\u5fd7\u5b9e\u65f6\u8f93\u51fa\uff0c\u5982\u56fe\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"710\" height=\"165\" src=\"https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/21.png\" alt=\"\" class=\"wp-image-10101\" srcset=\"https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/21.png 710w, https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/21-300x70.png 300w, https:\/\/blog.ywdevops.cn\/wp-content\/uploads\/2022\/09\/21-600x139.png 600w\" sizes=\"auto, (max-width: 710px) 100vw, 710px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>zap\u662fUber\u5f00\u53d1\u7684\u975e\u5e38\u5feb\u7684\u3001\u7ed3\u6784\u5316\u7684\uff0c\u5206\u65e5\u5fd7\u7ea7\u522b\u7684Go\u65e5\u5fd7\u5e93\u3002\u6839\u636eUber-go Zap\u7684\u6587\u6863\uff0c\u5b83\u7684\u6027\u80fd\u6bd4 [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":10070,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[111,23],"tags":[],"class_list":["post-10068","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-go","category-rong"],"blocksy_meta":{"styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":8}},"_links":{"self":[{"href":"https:\/\/blog.ywdevops.cn\/index.php\/wp-json\/wp\/v2\/posts\/10068","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ywdevops.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ywdevops.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ywdevops.cn\/index.php\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ywdevops.cn\/index.php\/wp-json\/wp\/v2\/comments?post=10068"}],"version-history":[{"count":28,"href":"https:\/\/blog.ywdevops.cn\/index.php\/wp-json\/wp\/v2\/posts\/10068\/revisions"}],"predecessor-version":[{"id":10102,"href":"https:\/\/blog.ywdevops.cn\/index.php\/wp-json\/wp\/v2\/posts\/10068\/revisions\/10102"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ywdevops.cn\/index.php\/wp-json\/wp\/v2\/media\/10070"}],"wp:attachment":[{"href":"https:\/\/blog.ywdevops.cn\/index.php\/wp-json\/wp\/v2\/media?parent=10068"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ywdevops.cn\/index.php\/wp-json\/wp\/v2\/categories?post=10068"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ywdevops.cn\/index.php\/wp-json\/wp\/v2\/tags?post=10068"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}