最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

golang zap日志庫的具體使用

 更新時間:2025年11月16日 15:10:55   作者:困到碗里去  
本文主要介紹了golang zap日志庫的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、日志是什么

首先需要明確什么是日志

在程序運行的過程中,我們不可能總是能在控制臺看到全部信息

因為

  • 程序是黑盒運行的

    一旦程序啟動,內(nèi)部狀態(tài)、變量值、執(zhí)行路徑都是“看不到的”,除非你在特定位置打日志或調(diào)試

  • 生產(chǎn)環(huán)境不能用調(diào)試器(debug)

    在開發(fā)環(huán)境你可以斷點調(diào)試,但上線后的服務不能暫停調(diào)試,只能通過日志了解程序的行為

  • 問題多是間歇性或難復現(xiàn)的

    比如用戶在某個特定時間點請求超時,過一會又正常,這類問題無法穩(wěn)定復現(xiàn),只有日志能還原問題。

  • 多人協(xié)作/遠程運維需要可追溯

    如果有運維、測試、后端、前端一起協(xié)作,只靠“肉眼”觀察或靠猜是遠遠不夠的

這時我們要想知道程序運行過程中更多的信息,就需要用到日志,給出日志的概念

Go語言中的日志(logging),是指在程序運行過程中記錄信息的機制,通常用于追蹤程序執(zhí)行流程、調(diào)試問題、記錄錯誤、監(jiān)控運行狀態(tài)等

說白了,日志就是記錄把程序運行時關鍵的信息記錄下來(作用是 調(diào)試程序、監(jiān)控服務、追溯時間、異常報警

舉個例子,下面是一條比較完整的日志信息

2025/07/30 10:25:00 [ERROR] [user_handler.go:45] 登錄失敗:用戶名不存在,
userID=1234, IP=192.168.1.10

這條日志告訴我們:

  • 時間:2025/07/30 10:25:00
  • 級別:ERROR(表示錯誤)
  • 文件位置:user_handler.go 的第 45 行
  • 內(nèi)容:用戶登錄失敗
  • 附加信息:userID=1234,IP=192.168.1.10

所以總的來說,日志是你程序“說話”的方式,它盡可能多地還原程序在某一刻的狀態(tài)、操作內(nèi)容、上下文,幫助開發(fā)者和運維人員快速定位問題

已經(jīng)知道了日志是什么,接下來就該了解如何使用日志了

二、 Sugared Logger vs Logger

zap提供了兩種日志類型:Sugared Logger 和 Logger

  • 在性能很好但不是很關鍵的上下文中,使用 SugaredLogger 。它比其他結(jié)構(gòu)化日志記錄包快4-10倍,并且支持結(jié)構(gòu)化和printf風格的日志記錄。
  • 在每一微秒和每一次內(nèi)存分配都很重要的上下文中,使用 Logger 。它甚至比 SugaredLogger 更快,內(nèi)存分配次數(shù)也更少,但它只支持強類型的結(jié)構(gòu)化日志記錄。

這樣說還是太吃理解了,能不能說人話!

舉個例子,想象你在寫日志,其實就是“說一句話”告訴別人發(fā)生了什么:

Logger 就像一個非常講究的人,說話必須格式規(guī)范、用詞準確。

SugaredLogger 就像你平時聊天,語法寬松,說什么都行,只要別人聽懂。

  1. zap.Logger(原生 logger)
    ?? 特點:強類型、高性能、格式固定

    你必須這么說:

    logger.Info("用戶登錄", zap.String("用戶名", "alice"), zap.Int("ID", 1001))
    

    就像你必須填一張表格,每一欄都得按格式來寫,不允許亂來

    優(yōu)點:格式清晰、適合機器分析、性能高
    缺點:寫起來略麻煩,不像日常說話

  2. *zap.SugaredLogger(帶糖 logger)
    ?? 特點:語法更輕松,像聊天一樣記錄日志

    你可以這樣說:

    sugar.Infof("用戶 %s 登錄成功,ID=%d", "alice", 1001)
    sugar.Infow("用戶登錄成功", "用戶名", "alice", "ID", 1001)
    

    就像你發(fā)微信說話,不拘小節(jié),怎么說都行。

    優(yōu)點:寫起來簡單、省事
    缺點:性能略低一點(但對大多數(shù)業(yè)務沒影響)

開發(fā)階段我們常用 SugaredLogger,
高性能系統(tǒng)或日志采集模塊則更推薦用 Logger

如果你現(xiàn)在用的是 zap.NewProduction() 創(chuàng)建的 logger,只要加一行就可以用帶糖版本:

sugar := logger.Sugar()

反過來,如果你用了 SugaredLogger,也可以通過 sugar.Desugar() 還原成 Logger

三、 zap的基本配置

前面提到了日志包含的幾部分內(nèi)容,這些內(nèi)容是需要配置的
zap給我們提供了兩個預設工廠函數(shù)zap.NewProduction()zap.NewDevelopment() ,可以快速創(chuàng)建一個配置好的logger,當然了,如果不想用這兩個函數(shù),也可以自己配置一個logger,這里我們稍后再說

默認情況下,zap.NewProduction() 和 zap.NewDevelopment() 創(chuàng)建的 logger 都會把日志打印到終端(標準輸出,也就是 os.Stdout)。具體表現(xiàn)如下:

  • zap.NewProduction()
    輸出格式是 JSON,適合生產(chǎn)環(huán)境日志采集和分析
    默認日志級別是 Info 及以上
    日志內(nèi)容會打印到終端(控制臺)

  • zap.NewDevelopment()
    輸出格式是易讀的控制臺文本格式,適合開發(fā)調(diào)試
    默認日志級別是 Debug,能打印更多詳細信息
    日志內(nèi)容也打印到終端,方便開發(fā)時即時查看

它們的作用總結(jié)如下:

函數(shù)名適用場景日志格式默認日志級別額外特性
zap.NewProduction()生產(chǎn)環(huán)境JSON 格式Info自動添加 caller 信息、stacktrace
zap.NewDevelopment()開發(fā)調(diào)試人類可讀文本Debug更詳細、更寬松、更適合調(diào)試

zap配置包含哪幾方面

zap的基本配置,可以理解為一個日志要包含哪些方面的內(nèi)容:

  1. 輸出位置(Output Paths)

    決定日志打印到哪:

    • 終端(console)
    • 文件(如 logs/app.log)
    • 同時打印多個位置
  2. 日志級別(Level)
    你可以控制哪些日志會被打印:

  • debug:調(diào)試用,最詳細
  • info:普通日志(業(yè)務日志)
  • warn:警告,不影響業(yè)務但需要注意
  • error:錯誤日志(業(yè)務或系統(tǒng)異常)
  • fatal:致命錯誤,程序會崩潰

你可以通過配置或代碼動態(tài)設置級別,過濾不需要的日志。

  1. 編碼方式(Encoding)
    決定日志內(nèi)容的格式:

    • json:結(jié)構(gòu)化,適合線上,便于日志系統(tǒng)解析
    • console:可讀性強,適合本地開發(fā)調(diào)試
  2. 字段格式(EncoderConfig)
    控制時間戳、日志級別、調(diào)用位置的格式,示例:

    zapcore.EncoderConfig{
        TimeKey:        "time",
        LevelKey:       "level",
        NameKey:        "logger",
        CallerKey:      "caller",
        MessageKey:     "msg",
        StacktraceKey:  "stacktrace",
        EncodeLevel:    zapcore.CapitalColorLevelEncoder,
        EncodeTime:     zapcore.ISO8601TimeEncoder,
        EncodeCaller:   zapcore.ShortCallerEncoder,
    }
    

    這個是非常重要的配置,決定你打印出來的日志長什么樣。

  3. 是否打印調(diào)用位置(Caller)
    打印日志時是否帶上調(diào)用該日志的文件和行號:

    logger = logger.WithOptions(zap.AddCaller())
    
  4. 開發(fā)/生產(chǎn)環(huán)境區(qū)別

    • zap.NewDevelopment():
      默認日志級別是 debug
      編碼是 console
      更適合本地調(diào)試

    • zap.NewProduction():
      默認日志級別是 info
      編碼是 json
      默認輸出文件和標準輸出

四、 自定義logger

想自定義一個logger,需要用到函數(shù)zap.New()

zap.New() 是 zap 庫中最底層、最核心的函數(shù)之一,用于創(chuàng)建一個 Logger 實例。你可以把它理解為 “構(gòu)建一個完整日志器的工廠函數(shù)”。它的作用是把你配置好的日志核心(Core)和可選的日志選項(Options)組合在一起,生成一個真正能用的 Logger

函數(shù)簽名

func New(core zapcore.Core, options ...Option) *Logger

參數(shù)解釋:

參數(shù)作用
core必須;日志的核心組件,定義“日志要寫到哪、寫什么、寫多少級別”。必須使用 zapcore.NewCore() 來創(chuàng)建。
options…可選;附加功能,用于增強 logger,比如是否記錄調(diào)用行號、是否打印堆棧、默認字段等。

core

我們先看第一個參數(shù)core

core的類型是 zapcore.Core, 我們找到Core的源碼,可以知道core是一個接口類型

zapCore.Core:

type Core interface {
	LevelEnabler
	With([]Field) Core
	Check(Entry, *CheckedEntry) *CheckedEntry
	Write(Entry, []Field) error
	Sync() error
}

core必須使用zapcore.NewCore() 來創(chuàng)建

func NewCore(enc Encoder, ws WriteSyncer, enab LevelEnabler) Core {
	return &ioCore{
		LevelEnabler: enab,
		enc:          enc,
		out:          ws,
	}
}

可以看到返回一個 *ioCore 類型的結(jié)構(gòu)體
那么再看一下 ioCore 的源碼

type ioCore struct {
	LevelEnabler
	enc Encoder
	out WriteSyncer
}

可以看到這個結(jié)構(gòu)體由三部分組成,

encoder:日志內(nèi)容格式化方式
決定了日志內(nèi)容以什么格式輸出
常用的 encoder 有:

  • zapcore.NewConsoleEncoder(cfg):適合開發(fā)環(huán)境,輸出人類能看懂的日志(例如 key=value 的形式)
  • zapcore.NewJSONEncoder(cfg):適合生產(chǎn)環(huán)境,輸出 JSON 格式的結(jié)構(gòu)化日志,方便 ELK 等系統(tǒng)采集

writeSyncer:寫日志的地方
告訴 zap:日志要寫到哪去,可以是:

  • os.Stdout:控制臺
  • 文件:通過 lumberjack 實現(xiàn)日志切割
  • 組合:zapcore.NewMultiWriteSyncer() 支持同時寫多個地方

logLevel:最低日志級別
只有大于等于這個級別的日志才會被記錄,比如:

go語言中關于日志級別的定義:

const (
DebugLevel Level = iota - 1
InfoLevel
WarnLevel
ErrorLevel
DPanicLevel
PanicLevel
FatalLevel

_minLevel = DebugLevel
_maxLevel = FatalLevel

InvalidLevel = _maxLevel + 1

options

后面的參數(shù)是可選的,它們是一些 功能性增強選項,比如:

可選參數(shù)含義
zap.AddCaller()日志中加入調(diào)用的源碼文件名和行號
zap.AddCallerSkip(n)調(diào)整調(diào)用棧深度(比如封裝日志函數(shù)時常用)
zap.AddStacktrace(lv)在某個級別及以上打印調(diào)用堆棧
zap.Fields(…)給 logger 添加默認的字段信息(結(jié)構(gòu)化日志)
zap.Development()啟用開發(fā)模式(比如日志校驗更嚴格)

五、 使用Lumberjack進行日志切割歸檔

當服務產(chǎn)生日志很多,且希望控制文件大小/數(shù)量/時長時,就該用 Lumberjack 來切割歸檔日志

Lumberjack 是 Go 中一個輕量級的日志滾動庫,常和 zap 搭配使用,用于日志切割與歸檔。這在生產(chǎn)環(huán)境中非常實用,能避免日志無限增長導致磁盤爆滿

什么是 Lumberjack?
Lumberjack 是一個實現(xiàn)了 io.Writer 接口的日志文件滾動庫
用一句話說:它可以根據(jù)文件大小、備份數(shù)量、保留天數(shù)等規(guī)則自動切割日志文件。

常用配置項
使用 *lumberjack.Logger 配置日志行為:

&lumberjack.Logger{
    Filename:   "./logs/server.log", // 日志文件路徑
    MaxSize:    100,                 // 每個日志文件最大尺寸(MB)
    MaxBackups: 5,                   // 最多保留的舊日志文件數(shù)量
    MaxAge:     30,                  // 最長保留時間(天)
    Compress:   true,                // 是否壓縮歸檔舊日志
}

和 zap 結(jié)合使用
因為 zapcore.AddSync(io.Writer) 接收的是 io.Writer,而 lumberjack.Logger 實現(xiàn)了這個接口,所以可以無縫對接。

完整示例:

import (
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"
    "gopkg.in/natefinch/lumberjack.v2"
)

func main() {
    // 1. 創(chuàng)建 lumberjack logger
    writeSyncer := zapcore.AddSync(&lumberjack.Logger{
        Filename:   "./logs/server.log",
        MaxSize:    10,  // 10 MB
        MaxBackups: 3,   // 最多3個備份
        MaxAge:     7,   // 保留7天
        Compress:   true,
    })

    // 2. 設置編碼器
    encoder := zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())

    // 3. 創(chuàng)建 core
    core := zapcore.NewCore(encoder, writeSyncer, zapcore.InfoLevel)

    // 4. 創(chuàng)建 logger
    logger := zap.New(core)
    defer logger.Sync()

    // 5. 打印日志
    logger.Info("這是一個日志條目", zap.String("user", "tinG"))
}

Lumberjack 的優(yōu)勢

優(yōu)點說明
自動切割避免單個日志文件過大
自動清理根據(jù)時間或數(shù)量清理舊日志
自動壓縮節(jié)省磁盤空間
與 zap 無縫配合不需要額外適配代碼

補充:zap 自帶不支持切割 zap 默認是將日志打印到文件或終端,但不自帶日志切割能力

到此這篇關于golang zap日志庫的具體使用的文章就介紹到這了,更多相關golang zap日志庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 再次探討go實現(xiàn)無限 buffer 的 channel方法

    再次探討go實現(xiàn)無限 buffer 的 channel方法

    我們知道go語言內(nèi)置的channel緩沖大小是有上限的,那么我們自己如何實現(xiàn)一個無限 buffer 的 channel呢?今天通過本文給大家分享go實現(xiàn)無限 buffer 的 channel方法,感興趣的朋友一起看看吧
    2021-06-06
  • Go微服務鏈路追蹤OpenTelemetry實戰(zhàn)

    Go微服務鏈路追蹤OpenTelemetry實戰(zhàn)

    本文介紹了OpenTelemetry作為微服務鏈路追蹤的主流解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2026-04-04
  • Go語言指針使用分析與講解

    Go語言指針使用分析與講解

    這篇文章主要介紹了Go語言指針使用分析與講解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • GO語言make和new關鍵字的區(qū)別

    GO語言make和new關鍵字的區(qū)別

    本篇文章來介紹一道非常常見的面試題,到底有多常見呢?可能很多面試的開場白就是由此開始的。那就是?new?和?make?這兩個內(nèi)置函數(shù)的區(qū)別,希望對大家有所幫助
    2023-04-04
  • 深入了解Golang中的Slice底層實現(xiàn)

    深入了解Golang中的Slice底層實現(xiàn)

    本文主要為大家詳細介紹了Golang中slice的底層實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2023-02-02
  • Go語言題解LeetCode561數(shù)組拆分

    Go語言題解LeetCode561數(shù)組拆分

    這篇文章主要為大家介紹了Go語言題解LeetCode561數(shù)組拆分示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • Go語言LeetCode題解706設計哈希映射

    Go語言LeetCode題解706設計哈希映射

    這篇文章主要為大家介紹了Go語言LeetCode題解706設計哈希映射示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • GO項目部署Linux服務器的實現(xiàn)示例

    GO項目部署Linux服務器的實現(xiàn)示例

    本文主要介紹了GO項目部署Linux服務器的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-06-06
  • Golang HTML 模板使用指南示例詳解

    Golang HTML 模板使用指南示例詳解

    本文詳細介紹了Golang HTML模板的使用方法,包括基礎模板、高級模板、完整應用示例、CSS樣式、JavaScript交互等,文章強調(diào)了模板組織、代碼復用、語義化HTML、響應式設計、性能優(yōu)化等最佳實踐,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • Go語言string,int,int64 ,float之間類型轉(zhuǎn)換方法

    Go語言string,int,int64 ,float之間類型轉(zhuǎn)換方法

    Go語言中int類型和string類型都是屬于基本數(shù)據(jù)類型,兩種類型的轉(zhuǎn)化都非常簡單。下面通過本文給大家分享Go語言string,int,int64 ,float之間類型轉(zhuǎn)換方法,感興趣的朋友一起看看吧
    2017-07-07

最新評論

荣昌县| 临颍县| 梅州市| 衡阳市| 攀枝花市| 蒙阴县| 原平市| 柳江县| 杭州市| 安岳县| 托里县| 保康县| 林芝县| 普兰店市| 班戈县| 峨边| 泌阳县| 武定县| 塔城市| 榆社县| 阿尔山市| 滕州市| 万山特区| 富宁县| 汾阳市| 合作市| 贡嘎县| 澜沧| 东源县| 沅陵县| 景谷| 湘潭市| 澄城县| 奉化市| 桂东县| 贵州省| 怀宁县| 西藏| 连城县| 威信县| 筠连县|