首頁  >  文章  >  後端開發  >  如何使用設定檔優雅地設定 Logger,同時支援日誌輪轉

如何使用設定檔優雅地設定 Logger,同時支援日誌輪轉

王林
王林轉載
2024-02-10 20:50:08920瀏覽

如何使用配置文件优雅地配置 Logger,同时支持日志轮转

php小編子墨將為大家分享如何使用設定檔來優雅地設定Logger,並實作日誌輪轉的方法。 Logger是一個常用的日誌記錄工具,它可以幫助我們記錄應用程式的運作狀態,以便於排查問題和追蹤日誌。使用Logger時,透過設定檔可以靈活地定義日誌的格式、輸出目標和日誌等級等,同時還可以設定日誌輪替的規則,實現日誌的自動管理和保存。透過合理的配置,我們可以實現更靈活和高效的日誌記錄和管理。在本文中,我們將詳細介紹如何使用設定檔來優雅地設定Logger,同時支援日誌輪轉的方法。

問題內容

問題描述

  • 功能:test1()是官方文件推薦的日誌輪替和切割庫ngopkg.in/natefinch/lumberjack.v2
  • 功能:test2()是一個logger,根據官方文件中的基本配置,使用yaml讀取配置。

執行完main函數後,

在控制台輸出:

2023-05-15t08:49:16.555 0800 |資訊|記錄器建置成功:來自 yaml 的設定 | {「app」:「jpz」}

#在日誌檔案foo.log中輸出:

{"level":"info","ts":1684111756.5545945,"msg":"記錄器建置成功:lumberjack.logger"}

這兩個日誌肯定是不同的。

我目前的要求:

  1. 兩者都支援使用設定檔config_log_zap.yaml讓所有設定生效,並讓lumberjack完成日誌輪調和分割工作。

  2. 控制台和日誌檔案的輸出應該是相同的,這樣我就可以透過設定檔快速套用所需的內容。之所以需要控制台和日誌文件,是因為我在開發過程中需要關注並記錄過去的輸出訊息。

    在控制台輸出:

    2023-05-15t08:49:16.555 0800 |資訊|記錄器建置成功:來自 yaml 的設定 | {「app」:「jpz」}

    #在日誌檔案foo.log中輸出:

    2023-05-15t08:49:16.555 0800 |資訊|記錄器建置成功:來自 yaml 的設定 | {「app」:「jpz」}

  3. #如何將 test1()test2() 合併為一個函數 test0() 以滿足上述兩個要求?

請給我一些幫助,我已經研究了很久了。

main.go

package main

import (
    "gopkg.in/yaml.v3"
    "os"

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

func test1() {
    // lumberjack.logger is already safe for concurrent use, so we don't need to
    // lock it.
    w := zapcore.addsync(&lumberjack.logger{
        filename:   "./foo.log",
        maxsize:    500, // megabytes
        maxbackups: 3,
        maxage:     28, // days
    })
    core := zapcore.newcore(
        zapcore.newjsonencoder(zap.newproductionencoderconfig()),
        w,
        zap.infolevel,
    )
    logger := zap.new(core)
    logger.info("logger construction succeeded:lumberjack.logger")
}

func test2() {
    var cfg zap.config
    yamlfile, _ := os.readfile("./config_log_zap.yaml")
    if err := yaml.unmarshal(yamlfile, &cfg); err != nil {
        panic(err)
    }

    logger := zap.must(cfg.build())
    defer logger.sync()

    logger.info("logger construction succeeded:config from yaml")
}

func main() {
    test1()
    test2()
}

config_log_zap.yaml

#
# For the full description for the configuration, see
# https://github.com/uber-go/zap/blob/382e2511e51cda8afde24f9e6e741f934308edfa/config.go#L58-L94
level: 'debug'
development: true
disableCaller: true
disableStacktrace: false
sampling:
  initial: 100
  thereafter: 100
encoding: 'console'
encoderConfig:
  messageKey: 'msg'
  levelKey: 'level'
  timeKey: 'ts'
  nameKey: 'logger'
  callerKey: 'caller'
  functionKey: 'function'
  stacktraceKey: 'stacktrace'
  skipLineEnding: false
  lineEnding: "\n"
  levelEncoder: 'capital'
  timeEncoder: 'iso8601'
  durationEncoder: 'string'
  callerEncoder: 'full'
  nameEncoder: 'full'
  consoleSeparator: ' | '
outputPaths:
  - 'stdout'
  - './foo.log'
errorOutputPaths:
  - 'stderr'
  - './error_logs'
initialFields:
  app: 'jpz'

解決方法

使用 zap.registersinklumberjack 記錄器註冊為新水槽:

package main

import (
    "net/url"
    "os"
    "strconv"
    "strings"

    "gopkg.in/yaml.v3"

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

type lumberjacksink struct {
    lumberjack.logger
}

func (l *lumberjacksink) sync() error {
    return nil
}

func parsenumber(s string, fallback int) int {
    v, err := strconv.atoi(s)
    if err == nil {
        return v
    }
    return fallback
}

func test0() {
    if err := zap.registersink("lumberjack", func(u *url.url) (zap.sink, error) {
        // read parameters from url:
        // lumberjack://localhost/foo.log?maxsize=500&maxbackups=3&maxage=28
        filename := strings.trimleft(u.path, "/")
        if filename == "" {
            filename = "foo.log"
        }
        q := u.query()
        l := &lumberjacksink{
            logger: lumberjack.logger{
                filename:   filename,
                maxsize:    parsenumber(q.get("maxsize"), 500),
                maxbackups: parsenumber(q.get("maxbackups"), 3),
                maxage:     parsenumber(q.get("maxage"), 28),
            },
        }
        return l, nil
    }); err != nil {
        panic(err)
    }

    var cfg zap.config
    yamlfile, _ := os.readfile("./config_log_zap.yaml")
    if err := yaml.unmarshal(yamlfile, &cfg); err != nil {
        panic(err)
    }

    logger := zap.must(cfg.build())
    defer logger.sync()

    logger.info("logger construction succeeded:config from yaml")
}

func main() {
    test0()
}

並修改設定檔以設定 outputpaths 如下:

outputPaths:
  - stdout
  - lumberjack://localhost/foo.log?maxSize=500&maxBackups=3&maxAge=28

以上是如何使用設定檔優雅地設定 Logger,同時支援日誌輪轉的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除