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

golang中l(wèi)og包自定義輸出日志格式與寫入到文件

 更新時間:2023年06月30日 16:07:19   作者:Json_Marz  
這篇文章主要給大家介紹了關(guān)于golang中l(wèi)og包自定義輸出日志格式與寫入到文件的相關(guān)資料,日志輸出在任何項(xiàng)目中都極其重要,是有助于后續(xù)我們排查解決程序BUG,需要的朋友可以參考下

1.背景:

平時開發(fā)項(xiàng)目時打印日志用到logrus包,但是覺得logrus配置比較麻煩,于是想著直接使用go自帶的log包輸出日志,其提供了一些配置,比如SetPrefix(), 可以讓我們自己二次封裝,讓自己的日志內(nèi)容更鮮明些。

2.代碼:

package log
 
import (
    "fmt"
    "github.com/robfig/cron/v3"
    "io"
    "log"
    "os"
    "my_log/config"
    "runtime"
    "strconv"
    "strings"
    "sync"
    "time"
)
 
var (
    debug         *log.Logger
    info          *log.Logger
    warn          *log.Logger
    error         *log.Logger
    dayChangeLock sync.RWMutex
)
 
const (
    debugLevel = iota //iota=0
    infoLevel
    warnLevel
    errorLevel
)
 
func init() {
    dayChangeLock = sync.RWMutex{}
    createLogFile()
    go logJob()
}
 
func createLogFile() {
    dayChangeLock.Lock()
    defer dayChangeLock.Unlock()
    now := time.Now()
    postFix := now.Format("20060102")
    logFile := "plume_log_" + postFix + ".log"
    logOut, err := os.OpenFile(logFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, os.ModePerm)
    if err != nil {
        panic(err)
    } else {
        multiWriter := io.MultiWriter(os.Stdout, logOut)
        debug = log.New(multiWriter, "[DEBUG] ", log.Ldate|log.Ltime)
        info = log.New(multiWriter, "[INFO] ", log.Ldate|log.Ltime)
        warn = log.New(multiWriter, "[WARN] ", log.Ldate|log.Ltime)
        error = log.New(multiWriter, "[ERROR] ", log.Ldate|log.Ltime)
    }
}
 
func Debug(format string, v ...any) {
    if config.Conf.Level <= debugLevel {
        debug.Printf(getLineNo()+format, v...)
    }
}
 
func Info(format string, v ...any) {
    if config.Conf.Level <= infoLevel {
        info.Printf(getLineNo()+format, v...)
    }
}
 
func Warn(format string, v ...any) {
    if config.Conf.Level <= warnLevel {
        warn.Printf(getLineNo()+format, v...)
    }
}
 
func Error(format string, v ...any) {
    if config.Conf.Level <= errorLevel {
        error.Printf(getLineNo()+format, v...)
    }
}
 
func getLineNo() string {
    _, file, line, ok := runtime.Caller(2)
    if ok {
        split := strings.Split(file, "/")
        file = split[len(split)-1]
        fileLine := file + ":" + strconv.Itoa(line) + " "
        return fileLine
    }
    return ""
}
 
// logJob 定時操作日志
func logJob() {
    c := cron.New(cron.WithSeconds())
    c.AddFunc("@daily", func() {
    Info("執(zhí)行l(wèi)og定時任務(wù)。。。")
    now := time.Now()
    createLogFile()
    closeYesterdayLogFile := fmt.Sprintf("plume_log_%s.log", now.Add(-24*time.Hour).Format("20060102"))
        file, _ := os.Open(closeYesterdayLogFile)
        file.Sync()
        file.Close()
    // 刪除n天前的日志
    removeLogFile := fmt.Sprintf("plume_log_%s.log", time.Now().Add(time.Duration(config.Conf.Log.KeepDays)*-24*time.Hour).Format("20060102"))
    open, err := os.Open(removeLogFile)
    if err != nil {
        Error(err.Error())
        return
    }
    go func () {
        // 設(shè)置for select 的原因是文件雖然被關(guān)閉了,但文件所占的process還在進(jìn)行中,每10秒輪詢一次,執(zhí)行刪除操作,確保文件有被刪除
        loop:
            for {
                select {
                case <-time.After(10 * time.Second):
                    removeErr := os.Remove(removeLogFile)
                    if removeErr != nil {
                        Error(removeErr.Error())
                    } else {
                        Info("刪除日志成功:%s", removeLogFile)
                        break loop
                    }
                }
            }
        }()
    })
    c.Start()
}
 
//var (
//    kernel32    = syscall.NewLazyDLL(`kernel32.dll`)
//    proc        = kernel32.NewProc(`SetConsoleTextAttribute`)
//    CloseHandle = kernel32.NewProc(`CloseHandle`)
//    // 給字體顏色對象賦值
//    FontColor = Color{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
//)
 
//type Color struct {
//    black        int // 黑色
//    blue         int // 藍(lán)色
//    green        int // 綠色
//    cyan         int // 青色
//    red          int // 紅色
//    purple       int // 紫色
//    yellow       int // 黃色
//    light_gray   int // 淡灰色(系統(tǒng)默認(rèn)值)
//    gray         int // 灰色
//    light_blue   int // 亮藍(lán)色
//    light_green  int // 亮綠色
//    light_cyan   int // 亮青色
//    light_red    int // 亮紅色
//    light_purple int // 亮紫色
//    light_yellow int // 亮黃色
//    white        int // 白色
//}
 
// 輸出有顏色的字體
//func ColorPrint4Window(s, t string) {
//    switch t {
//    case "DEBUG":
//        proc.Call(uintptr(syscall.Stdout), uintptr(FontColor.light_cyan))
//        Debug(s)
//    case "INFO":
//        proc.Call(uintptr(syscall.Stdout), uintptr(FontColor.green))
//        Info(s)
//    case "WARN":
//        proc.Call(uintptr(syscall.Stdout), uintptr(FontColor.light_yellow))
//        Warn(s)
//    case "ERROR":
//        proc.Call(uintptr(syscall.Stdout), uintptr(FontColor.red))
//        Error(s)
//    default:
//        proc.Call(uintptr(syscall.Stdout), uintptr(FontColor.black))
//        Info(s)
//    }
//}

使用viper讀取配置:

package config
 
import (
    "github.com/spf13/viper"
    "os"
)
 
var Conf *Config
 
type Config struct {
    Log
}
 
type Log struct {
    Level    int
    KeepDays int
    Prefix   string
}
 
func init() {
    Conf = &Config{}
    config := viper.New()
    path, _ := os.Getwd()
    config.SetConfigName("config") // 配置文件名字,注意沒有擴(kuò)展名
    config.SetConfigType("toml")
    config.AddConfigPath(path)
    if err := config.ReadInConfig(); err != nil {
        panic(err)
    }
    Conf.Level = config.GetInt("log.level")
    Conf.Log.KeepDays = config.GetInt("log.keep-days")
    Conf.Log.Prefix = config.GetString("log.prefix")
}
package main
 
import (
    "my_log/log"
)
 
func main() {
    log.Debug("我是debug日志")
    log.Info("我是info日志")
    log.Warn("我是warn日志")
    log.Error("我是error日志")
}

日志配置文件(config.toml):

[log]
level = 0
keep-days = 7
prefix = "test_"

控制臺輸出:

生成的日志文件內(nèi)容:

碰到的問題:

The process cannot access the file because it is being used by another process.

// 問題的產(chǎn)生:
file := "test_log.log"
os.Open(file)
file.Close()
os.Remove(file)
// 因?yàn)槌绦蜻€在運(yùn)行中,該日志文件所占的process還未停止
// 解決辦法:
// 延遲刪除文件,比如time.Sleep()
// 推薦使用:label:for + select 輪詢刪除,刪除完畢 break:label
// 示例代碼:
    loop:
        for {
            select {
            case <-time.After(10 * time.Second):
                removeErr := os.Remove(file)
                if removeErr != nil {
                    Error(removeErr.Error())
                } else {
                    Info("刪除日志成功:%s", file)
                    break loop
                }
            }
        }

總結(jié)

到此這篇關(guān)于golang中l(wèi)og包自定義輸出日志格式與寫入到文件的文章就介紹到這了,更多相關(guān)go log包自定義輸出日志格式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解如何利用Golang泛型提高編碼效率

    詳解如何利用Golang泛型提高編碼效率

    Golang的泛型已經(jīng)出來有一段時間了,大家應(yīng)該或多或少對它有所了解。雖然Golang的泛型在功能上確實(shí)比較簡單,而且確實(shí)可能會增加代碼的復(fù)雜度,過度使用可能還會降低代碼可讀性。本文就來介紹一下Golang泛型的相關(guān)知識吧
    2023-04-04
  • Golang http請求封裝的代碼示例

    Golang http請求封裝的代碼示例

    http請求封裝在項(xiàng)目中非常普遍,下面筆者封裝了http post請求傳json、form 和get請求,以備將來使用,文中代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • 一文帶你了解Golang中的緩沖區(qū)Buffer

    一文帶你了解Golang中的緩沖區(qū)Buffer

    作為一種常見的數(shù)據(jù)結(jié)構(gòu),緩沖區(qū)(Buffer)在計(jì)算機(jī)科學(xué)中有著廣泛的應(yīng)用。這篇文章將詳細(xì)介紹?Go?中?Buffer?的用法,從多個方面介紹其特性和應(yīng)用場景,需要的可以參考一下
    2023-05-05
  • go語言csrf庫使用實(shí)現(xiàn)原理示例解析

    go語言csrf庫使用實(shí)現(xiàn)原理示例解析

    這篇文章主要為大家介紹了go語言csrf庫使用實(shí)現(xiàn)原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • Go內(nèi)置零值標(biāo)識符zero

    Go內(nèi)置零值標(biāo)識符zero

    大家學(xué)習(xí)和使用?Go?語言時,有一個神奇的概念:零值(zero-values),所以本文想給大家分享一個關(guān)于零值的新提案,目測已經(jīng)八九不離十了
    2023-08-08
  • GoLang職責(zé)鏈模式代碼實(shí)現(xiàn)介紹

    GoLang職責(zé)鏈模式代碼實(shí)現(xiàn)介紹

    這篇文章主要介紹了GoLang職責(zé)鏈模式代碼實(shí)現(xiàn),職責(zé)鏈模式是一種常用的設(shè)計(jì)模式,可以提高代碼的靈活性與可維護(hù)性,職責(zé)鏈模式將請求和處理分離,可以讓請求在處理鏈中依次經(jīng)過多個處理者,直到找到能夠處理請求的處理者為止
    2023-05-05
  • 使用golang寫一個redis-cli的方法示例

    使用golang寫一個redis-cli的方法示例

    這篇文章主要介紹了使用golang寫一個redis-cli的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-10-10
  • Go語言在Linux環(huán)境下輸出彩色字符的方法

    Go語言在Linux環(huán)境下輸出彩色字符的方法

    這篇文章主要介紹了Go語言在Linux環(huán)境下輸出彩色字符的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-04-04
  • Go語言bufio庫的全面指南與實(shí)戰(zhàn)技巧詳解

    Go語言bufio庫的全面指南與實(shí)戰(zhàn)技巧詳解

    這篇文章主要為大家全面介紹一下?bufio?庫的核心組件與功能,包括?Reader、Writer?和?Scanner?等并深入探討它們在實(shí)際編程中的運(yùn)用場景和技巧,感興趣的可以了解下
    2024-01-01
  • 詳談Golang uint類型溢出問題

    詳談Golang uint類型溢出問題

    在Go語言中,uint類型的無符號整數(shù)在達(dá)到其最大值時會發(fā)生回繞,為了避免溢出,應(yīng)確保不超出最大值,使用條件語句檢查接近溢出點(diǎn),選擇合適的數(shù)據(jù)類型,進(jìn)行適當(dāng)?shù)腻e誤處理,或者使用數(shù)學(xué)庫處理大整數(shù)
    2024-12-12

最新評論