欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang結(jié)構(gòu)化日志log/slog包之LogValuer的用法簡(jiǎn)介

 更新時(shí)間:2023年10月18日 08:41:17   作者:路多辛  
這篇文章主要為大家詳細(xì)介紹了golang結(jié)構(gòu)化日志log/slog包中 LogValuer 和日志記錄函數(shù)的正確包裝方法,感興趣的小伙伴可以跟隨小編一起了解一下

上一篇文章講解了 log/slog 包中的分組、上下文和屬性值類型,本文講解下 LogValuer 和日志記錄函數(shù)的正確包裝方法。

slog.LogValuer

如果想改變或者自定義一個(gè)類型的日志記錄行為,可以通過(guò)實(shí)現(xiàn) slog.LogValuer 接口來(lái)實(shí)現(xiàn),slog.LogValuer 接口的定義如下:

type LogValuer interface {
    LogValue() Value
}

定義了一個(gè) LogValue 方法,返回一個(gè) Value 類型的對(duì)象。如果一個(gè)類型實(shí)現(xiàn)了 LogValuer 接口,那么從它的 LogValue 方法返回的 Value 將被用于日志記錄,可以用來(lái)控制該類型的值在日志中的顯示方式??磦€(gè)簡(jiǎn)單示例:

package main
 
import (
    "log/slog"
    "os"
)
 
type Token string
 
// 實(shí)現(xiàn) slog.LogValuer 接口
// 避免泄露 token
func (Token) LogValue() slog.Value {
    return slog.StringValue("******")
}
 
func main() {
    t := Token("shhhh!")
    logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
    logger.Info("生成 token", "用戶", "路多辛的博客", "token", t)
}

輸出內(nèi)容如下:

time=2023-10-15T15:06:58.253+08:00 level=INFO msg="生成 token" 用戶=路多辛的博客 token=******

從安全角度看,密碼或者token 等敏感信息是不能被記錄在日志里面的,可以使用自定義的并且實(shí)現(xiàn)了 LogValue 的類型來(lái)避免這種情況產(chǎn)生。在這個(gè)例子中,當(dāng)記錄 token 日志時(shí),token 會(huì)被轉(zhuǎn)換為“******”后記錄在日志里面。再看一個(gè)結(jié)合字段分組使用的示例:

package main
 
import (
    "log/slog"
)
 
type Name struct {
    First, Last string
}
 
func (n Name) LogValue() slog.Value {
    return slog.GroupValue(
        slog.String("first", n.First),
        slog.String("last", n.Last))
}
 
func main() {
    n := Name{"路多辛的博客", "路多辛的所思所想"}
    slog.Info("任務(wù)結(jié)束", "agent", n)
}

輸出內(nèi)容如下:

2023/10/15 15:06:09 INFO 任務(wù)結(jié)束 agent.first=路多辛的博客 agent.last=路多辛的所思所想

包裝輸出函數(shù)

日志記錄函數(shù)使用調(diào)用堆棧上的反射來(lái)查找應(yīng)用程序中日志記錄調(diào)用的文件名和行號(hào),這可能會(huì)導(dǎo)致包裝 slog 的函數(shù)記錄錯(cuò)誤的的源信息。舉個(gè)例子,如果在 mylog.go 中定義了一個(gè)日志記錄函數(shù) Infof,然后在 main.go 中調(diào)用了此函數(shù),這種情況下,日志會(huì)將把源文件記錄為 mylog.go 而不是 main.go。正確實(shí)現(xiàn) Infof 函數(shù)的方式是將獲取的源信息傳遞給 NewRecord 函數(shù),示例代碼如下:

package main
 
import (
	"context"
	"fmt"
	"log/slog"
	"os"
	"path/filepath"
	"runtime"
	"time"
)
 
func Infof(logger *slog.Logger, format string, args ...any) {
	if !logger.Enabled(context.Background(), slog.LevelInfo) {
		return
	}
	var pcs [1]uintptr
	runtime.Callers(2, pcs[:]) // skip [Callers, Infof]
	r := slog.NewRecord(time.Now(), slog.LevelInfo, fmt.Sprintf(format, args...), pcs[0])
	_ = logger.Handler().Handle(context.Background(), r)
}
 
func main() {
	replace := func(groups []string, a slog.Attr) slog.Attr {
		// Remove time.
		if a.Key == slog.TimeKey && len(groups) == 0 {
			return slog.Attr{}
		}
		// Remove the directory from the source's filename.
		if a.Key == slog.SourceKey {
			source := a.Value.Any().(*slog.Source)
			source.File = filepath.Base(source.File)
		}
		return a
	}
	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{AddSource: true, ReplaceAttr: replace}))
	Infof(logger, "message, %s", "formatted")
}

到此這篇關(guān)于golang結(jié)構(gòu)化日志log/slog包之LogValuer的用法簡(jiǎn)介的文章就介紹到這了,更多相關(guān)go slog內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go中的Context實(shí)現(xiàn)原理以及正確使用方式

    Go中的Context實(shí)現(xiàn)原理以及正確使用方式

    在 Go 語(yǔ)言中,Context 包是一種非常常用的工具,它被用來(lái)管理 goroutine 之間的通信和取消,本文將深入探討Context 包的基本原理,包括使用場(chǎng)景、原理和一些最佳實(shí)踐,感興趣的小伙伴跟著小編一起來(lái)看看吧
    2024-11-11
  • Go?并發(fā)編程協(xié)程及調(diào)度機(jī)制詳情

    Go?并發(fā)編程協(xié)程及調(diào)度機(jī)制詳情

    這篇文章主要介紹了Go并發(fā)編程協(xié)程及調(diào)度機(jī)制詳情,協(xié)程是Go語(yǔ)言最大的特色之一,goroutine的實(shí)現(xiàn)其實(shí)是通過(guò)協(xié)程,更多相關(guān)內(nèi)容需要的朋友可以參考一下
    2022-09-09
  • Go http client 連接池不復(fù)用的問(wèn)題

    Go http client 連接池不復(fù)用的問(wèn)題

    這篇文章主要介紹了Go http client 連接池不復(fù)用的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • goLand Delve版本太老的問(wèn)題及解決

    goLand Delve版本太老的問(wèn)題及解決

    這篇文章主要介紹了goLand Delve版本太老的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • linux中用shell快速安裝配置Go語(yǔ)言的開(kāi)發(fā)環(huán)境

    linux中用shell快速安裝配置Go語(yǔ)言的開(kāi)發(fā)環(huán)境

    相信每位開(kāi)發(fā)者都知道選擇一門(mén)開(kāi)發(fā)語(yǔ)言,免不了需要安裝配置開(kāi)發(fā)環(huán)境,所以這篇文章給大家分享了linux下使用shell一鍵安裝配置GO語(yǔ)言開(kāi)發(fā)環(huán)境的方法,有需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。
    2016-10-10
  • Go語(yǔ)言狀態(tài)機(jī)的實(shí)現(xiàn)

    Go語(yǔ)言狀態(tài)機(jī)的實(shí)現(xiàn)

    本文主要介紹了Go語(yǔ)言狀態(tài)機(jī)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • golang MarshalJson的實(shí)現(xiàn)

    golang MarshalJson的實(shí)現(xiàn)

    本文主要介紹了golang MarshalJson的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03
  • 淺析Go中函數(shù)的健壯性,panic異常處理和defer機(jī)制

    淺析Go中函數(shù)的健壯性,panic異常處理和defer機(jī)制

    這篇文章主要為大家詳細(xì)介紹了Go中函數(shù)的健壯性,panic異常處理和defer機(jī)制的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-10-10
  • Go語(yǔ)言基礎(chǔ)知識(shí)點(diǎn)介紹

    Go語(yǔ)言基礎(chǔ)知識(shí)點(diǎn)介紹

    在本篇文章里小編給大家整理的是一篇關(guān)于Go語(yǔ)言基礎(chǔ)知識(shí)點(diǎn)介紹內(nèi)容,有興趣的朋友們可以跟著學(xué)習(xí)參考下。
    2021-07-07
  • golang實(shí)現(xiàn)并發(fā)數(shù)控制的方法

    golang實(shí)現(xiàn)并發(fā)數(shù)控制的方法

    下面小編就為大家分享一篇golang實(shí)現(xiàn)并發(fā)數(shù)控制的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12

最新評(píng)論