麻豆黑色丝袜jk制服福利网站-麻豆精品传媒视频观看-麻豆精品传媒一二三区在线视频-麻豆精选传媒4区2021-在线视频99-在线视频a

千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

手機(jī)站
千鋒教育

千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

千鋒教育

掃一掃進(jìn)入千鋒手機(jī)站

領(lǐng)取全套視頻
千鋒教育

關(guān)注千鋒學(xué)習(xí)站小程序
隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

當(dāng)前位置:首頁(yè)  >  技術(shù)干貨  > 女性工程師分享Golang實(shí)現(xiàn)日志系統(tǒng)的經(jīng)驗(yàn)

女性工程師分享Golang實(shí)現(xiàn)日志系統(tǒng)的經(jīng)驗(yàn)

來源:千鋒教育
發(fā)布人:xqq
時(shí)間: 2023-12-21 13:15:49 1703135749

女性工程師分享:Golang實(shí)現(xiàn)日志系統(tǒng)的經(jīng)驗(yàn)

隨著軟件開發(fā)項(xiàng)目的逐漸復(fù)雜化,日志系統(tǒng)的作用也越發(fā)重要。日志系統(tǒng)不僅可以提供調(diào)試信息,還可以分析程序性能、監(jiān)控系統(tǒng)運(yùn)行狀況。本文將向大家分享如何使用 Golang 實(shí)現(xiàn)一個(gè)高效、可擴(kuò)展的日志系統(tǒng)。

1. 日志系統(tǒng)的需求分析

在實(shí)現(xiàn)日志系統(tǒng)之前,我們需要先明確日志系統(tǒng)的需求。

- 支持不同級(jí)別的日志記錄,如 Debug、Info、Warning、Error、Critical 等;

- 支持將日志輸出到控制臺(tái)或者文件;

- 支持按照時(shí)間或者文件大小進(jìn)行分割日志;

- 支持可配置化。

2. Golang 日志庫(kù)的選擇

在 Golang 中,有很多日志庫(kù)可以選擇。在本文中,我們選擇使用 Zap 作為日志庫(kù),原因如下:

- Zap 是 Uber 開源的一個(gè)高性能日志庫(kù),支持多種日志級(jí)別、輸出方式和分割策略等;

- Zap 采用了高效的無鎖機(jī)制,并且對(duì)內(nèi)存使用進(jìn)行了優(yōu)化,可以大大提高性能;

- Zap 支持多線程和多協(xié)程的并發(fā)輸出,可以滿足高并發(fā)場(chǎng)景的需求。

下面是使用 Zap 輸出日志的示例代碼:

package mainimport (    "go.uber.org/zap"    "go.uber.org/zap/zapcore")func main() {    logger, _ := zap.NewDevelopment(zap.AddStacktrace(zapcore.FatalLevel))    defer logger.Sync()    logger.Debug("Debug log")    logger.Info("Info log")    logger.Warn("Warn log")    logger.Error("Error log")    logger.Panic("Panic log")}

3. 日志系統(tǒng)的實(shí)現(xiàn)

在明確了需求并選擇了日志庫(kù)之后,我們就可以開始實(shí)現(xiàn)日志系統(tǒng)了。

3.1 日志級(jí)別

在日志系統(tǒng)中,不同級(jí)別的日志信息需要有不同的顏色或者標(biāo)識(shí)符。我們可以使用顏色庫(kù) color 來設(shè)置不同級(jí)別的日志顏色,示例代碼如下:

package loggerimport (    "fmt"    "log"    "os"    "github.com/fatih/color"    "go.uber.org/zap"    "go.uber.org/zap/zapcore")var (    logger *zap.Logger)// LogLevel 日志級(jí)別type LogLevel uint8const (    // DebugLevel 調(diào)試級(jí)別    DebugLevel LogLevel = iota    // InfoLevel 普通信息級(jí)別    InfoLevel    // WarnLevel 警告級(jí)別    WarnLevel    // ErrorLevel 錯(cuò)誤級(jí)別    ErrorLevel    // PanicLevel 嚴(yán)重錯(cuò)誤級(jí)別    PanicLevel)var levelColors = func(...interface{}) string{    color.New(color.FgHiCyan).SprintFunc(),    color.New(color.FgHiGreen).SprintFunc(),    color.New(color.FgHiYellow).SprintFunc(),    color.New(color.FgHiRed).SprintFunc(),    color.New(color.FgHiRed, color.Bold).SprintFunc(),}func levelColor(l LogLevel) func(...interface{}) string {    if l >= DebugLevel && l <= PanicLevel {        return levelColors    }    return color.New(color.Faint).SprintFunc()}func init() {    encoderConfig := zap.NewDevelopmentEncoderConfig()    encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder    logger = zap.New(zapcore.NewCore(        zapcore.NewConsoleEncoder(encoderConfig),        zapcore.Lock(os.Stdout),        zap.NewAtomicLevelAt(zapcore.InfoLevel),    ))}// Debug debug級(jí)別日志func Debug(msg string, fields ...zap.Field) {    logger.Debug(msg, fields...)}// Info info級(jí)別日志func Info(msg string, fields ...zap.Field) {    logger.Info(msg, fields...)}// Warn warn級(jí)別日志func Warn(msg string, fields ...zap.Field) {    logger.Warn(msg, fields...)}// Error error級(jí)別日志func Error(msg string, fields ...zap.Field) {    logger.Error(msg, fields...)}// Panic panic級(jí)別日志func Panic(msg string, fields ...zap.Field) {    logger.Panic(msg, fields...)}// Println 輸出日志func Println(l LogLevel, format string, v ...interface{}) {    fmtMsg := fmt.Sprintf(format, v...)    lColor := levelColor(l)    lName := logLevelName(l)    msg := fmt.Sprintf(" %s", lColor(lName), fmtMsg)    log.Println(msg)}// logLevelName 獲取日志級(jí)別名稱func logLevelName(l LogLevel) string {    switch l {    case DebugLevel:        return "DEBUG"    case InfoLevel:        return "INFO"    case WarnLevel:        return "WARN"    case ErrorLevel:        return "ERROR"    default:        return "PANIC"    }}

在上面的代碼中,我們使用 LogLevel 枚舉類型來表示不同級(jí)別的日志信息,使用 levelColors 數(shù)組來存儲(chǔ)不同級(jí)別的日志顏色,通過 levelColor 函數(shù)來根據(jù)級(jí)別獲取對(duì)應(yīng)的顏色函數(shù)。在輸出日志時(shí),我們先使用 Zap 來輸出級(jí)別符號(hào)和日志信息,然后使用 log.Println 函數(shù)將日志信息輸出到控制臺(tái)。

3.2 日志輸出方式

我們通過 zapcore 包中的 WriteSyncer 接口來實(shí)現(xiàn)不同的日志輸出方式,示例代碼如下:

package loggerimport (    "io/ioutil"    "log"    "os"    "time"    "go.uber.org/zap"    "go.uber.org/zap/zapcore")const (    maxLogSize  = 100 // 每個(gè)日志文件的最大大小,單位 MB    maxAge      = 30  // 日志文件的最長(zhǎng)保留時(shí)間,單位天    timeFormat  = "2006-01-02 15:04:05.000"    rotateEvery = 24 * time.Hour)var (    fileLogger *zap.Logger)func init() {    encoderConfig := zap.NewProductionEncoderConfig()    encoderConfig.EncodeTime = zapcore.TimeEncoderOfLayout(timeFormat)    encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder    encoderConfig.EncodeCaller = zapcore.ShortCallerEncoder    logger := zap.New(zapcore.NewCore(        zapcore.NewConsoleEncoder(encoderConfig),        zapcore.Lock(os.Stdout),        zap.NewAtomicLevelAt(zapcore.InfoLevel),    ))    fileLogger = zap.New(zapcore.NewCore(        zapcore.NewConsoleEncoder(encoderConfig),        zapcore.AddSync(newRotateFileWriter("logs", "app")),        zap.NewAtomicLevelAt(zapcore.InfoLevel),    ))    logger = logger.WithOptions(zap.AddCallerSkip(1))    fileLogger = fileLogger.WithOptions(zap.AddCallerSkip(1))}// SetLogFile 設(shè)置日志文件名func SetLogFile(name string) {    fileLogger.WithOptions(zap.AddCallerSkip(1))}// newRotateFileWriter 返回一個(gè)支持按文件大小和時(shí)間分割的 io.Writerfunc newRotateFileWriter(dir, prefix string) zapcore.WriteSyncer {    return zapcore.AddSync(&zapcore.RotateFile{        Filename:   prefix + ".log",        MaxSize:    maxLogSize,        MaxAge:     maxAge,        LocalTime:  true,        Compress:   true,        Interval:   rotateEvery,        Permissions: 0644,        Lumberjack: &lumberjack.Logger{            Filename:   filepath.Join(dir, prefix+".log"),            MaxSize:    maxLogSize,            MaxAge:     maxAge,            LocalTime:  true,            Compress:   true,            Permissions: 0644,        },    })}

在上面的代碼中,我們定義了一個(gè) newRotateFileWriter 函數(shù)來返回一個(gè)支持按文件大小和時(shí)間進(jìn)行分割的 io.Writer,其中使用了 github.com/natefinch/lumberjack 包來實(shí)現(xiàn)文件的日志輪轉(zhuǎn)。我們還定義了一個(gè) SetLogFile 函數(shù),用于設(shè)置日志文件的名稱。

3.3 日志可配置化

最后,我們需要將日志系統(tǒng)可配置化。我們可以通過讀取配置文件來設(shè)置日志級(jí)別、輸出方式等參數(shù),示例代碼如下:

package loggerimport (    "os"    "github.com/spf13/viper"    "go.uber.org/zap")// Config 日志配置type Config struct {    Level        string // 日志級(jí)別    Output       string // 日志輸出方式    RotateByHour bool   // 是否按小時(shí)進(jìn)行日志分割}var (    conf Config)// Init 初始化日志配置func Init() {    viper.SetConfigName("config") // 配置文件名稱    viper.AddConfigPath(".")      // 配置文件路徑    viper.SetConfigType("yml")    // 配置文件類型    if err := viper.ReadInConfig(); err != nil {        panic(err)    }    if err := viper.Unmarshal(&conf); err != nil {        panic(err)    }    level := zap.NewAtomicLevel()    if err := level.UnmarshalText(byte(conf.Level)); err != nil {        panic(err)    }    fileLogger = fileLogger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {        return zapcore.NewLevelEnabler(core.Enabled(level))    }))    if conf.Output == "file" {        SetLogFile("app")    }}

在上面的代碼中,我們使用 github.com/spf13/viper 包來讀取配置文件,將配置項(xiàng)映射到 Config 結(jié)構(gòu)體中,并根據(jù)配置項(xiàng)來設(shè)置日志級(jí)別和輸出方式。

4. 結(jié)論

通過本文的介紹,我們可以知道如何使用 Golang 實(shí)現(xiàn)一個(gè)高效、可擴(kuò)展的日志系統(tǒng)。在實(shí)現(xiàn)過程中,我們需要注意性能、安全和可維護(hù)性等方面,同時(shí)也需要考慮擴(kuò)展性和可配置化。最后,希望本文能對(duì)您有所幫助。

以上就是IT培訓(xùn)機(jī)構(gòu)千鋒教育提供的相關(guān)內(nèi)容,如果您有web前端培訓(xùn)鴻蒙開發(fā)培訓(xùn)python培訓(xùn)linux培訓(xùn),java培訓(xùn),UI設(shè)計(jì)培訓(xùn)等需求,歡迎隨時(shí)聯(lián)系千鋒教育。

tags:
聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
請(qǐng)您保持通訊暢通,專屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
免費(fèi)領(lǐng)取
今日已有369人領(lǐng)取成功
劉同學(xué) 138****2860 剛剛成功領(lǐng)取
王同學(xué) 131****2015 剛剛成功領(lǐng)取
張同學(xué) 133****4652 剛剛成功領(lǐng)取
李同學(xué) 135****8607 剛剛成功領(lǐng)取
楊同學(xué) 132****5667 剛剛成功領(lǐng)取
岳同學(xué) 134****6652 剛剛成功領(lǐng)取
梁同學(xué) 157****2950 剛剛成功領(lǐng)取
劉同學(xué) 189****1015 剛剛成功領(lǐng)取
張同學(xué) 155****4678 剛剛成功領(lǐng)取
鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
董同學(xué) 138****2867 剛剛成功領(lǐng)取
周同學(xué) 136****3602 剛剛成功領(lǐng)取
相關(guān)推薦HOT
實(shí)戰(zhàn)經(jīng)驗(yàn)Go語(yǔ)言在云原生應(yīng)用開發(fā)中的實(shí)踐總結(jié)

實(shí)戰(zhàn)經(jīng)驗(yàn):Go語(yǔ)言在云原生應(yīng)用開發(fā)中的實(shí)踐總結(jié)隨著云計(jì)算和容器化技術(shù)的發(fā)展,云原生應(yīng)用的興起越來越成為了技術(shù)圈的一個(gè)熱門話題。而作為一門...詳情>>

2023-12-21 14:40:17
深度剖析Go語(yǔ)言中的內(nèi)存泄漏問題及解決方案!

深度剖析Go語(yǔ)言中的內(nèi)存泄漏問題及解決方案!在Go語(yǔ)言中,內(nèi)存管理是由自帶的垃圾回收器來完成的,因此,大多數(shù)情況下我們不需要關(guān)心內(nèi)存管理問...詳情>>

2023-12-21 14:35:00
Golang中的協(xié)程池優(yōu)化高并發(fā)場(chǎng)景下的性能

在現(xiàn)代互聯(lián)網(wǎng)應(yīng)用中,高并發(fā)和性能優(yōu)化一直是開發(fā)人員所關(guān)注的重點(diǎn)。針對(duì)高并發(fā)場(chǎng)景下的性能問題,Golang官方提供了一種處理方案:協(xié)程池。本文...詳情>>

2023-12-21 14:12:08
使用Golang構(gòu)建高并發(fā)服務(wù)器實(shí)戰(zhàn)經(jīng)驗(yàn)分享

使用Golang構(gòu)建高并發(fā)服務(wù)器:實(shí)戰(zhàn)經(jīng)驗(yàn)分享在現(xiàn)代互聯(lián)網(wǎng)時(shí)代,高并發(fā)服務(wù)器已成為了互聯(lián)網(wǎng)應(yīng)用的必備技術(shù)之一。而Golang作為一門高效、易用、內(nèi)...詳情>>

2023-12-21 14:08:36
在Go語(yǔ)言中構(gòu)建高效的消息隊(duì)列系統(tǒng)的最佳實(shí)踐

在Go語(yǔ)言中構(gòu)建高效的消息隊(duì)列系統(tǒng)的最佳實(shí)踐消息隊(duì)列是一個(gè)非常常見的組件,用于處理異步數(shù)據(jù)傳輸和解耦。隨著數(shù)據(jù)量和并發(fā)性要求的增加,構(gòu)建...詳情>>

2023-12-21 13:51:01
快速通道
主站蜘蛛池模板: 台湾swag在线观看| 伊人久久大香线蕉综合电影| 一区二区3区免费视频| 无翼乌邪恶工番口番邪恶| 欧美最猛性xxxxx69交| 黑人一级黄色片| 色列有妖气acg全彩本子| 国产一区二区精品| 亚洲视频免费看| 日本高清二三四本2021第九页| 国产精品国产三级国产在线观看| 羞羞歪歪| 日本电车强视频在线播放| 19岁rapper潮水第一集| 亚洲a∨精品一区二区三区下载| 欧美在线播放| 人人爽天天碰天天躁夜夜躁| 无套影院| 久久电影网午夜鲁丝片免费| 久久99精品久久久久久| 日韩欧美亚洲国产精品字幕久久久| 久久天天躁日日躁狠狠躁| 两个体校校草被c出水| 韩国一级在线观看| 亲密爱人免费完整在线观看| 国产人妖网站| 渣男渣女抹胸渣男渣女| 精品国产柚木在线观看| 色播在线电影| 欧美成人免费观看| chinese乱子伦xxxx视频播放| 国产成人欧美一区二区三区vr | 噜噜噜在线视频免费观看| 日韩一级在线播放免费观看| 亚洲一区二区影院| 福利视频亚洲| 中国大陆国产高清aⅴ毛片| 美国十次导航| 成年女人免费播放影院| 啪啪电影院| 国产无套粉嫩白浆在线观看|