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

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

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

1.背景:

平時開發(fā)項目時打印日志用到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定時任務。。。")
    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 () {
        // 設置for select 的原因是文件雖然被關閉了,但文件所占的process還在進行中,每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 // 藍色
//    green        int // 綠色
//    cyan         int // 青色
//    red          int // 紅色
//    purple       int // 紫色
//    yellow       int // 黃色
//    light_gray   int // 淡灰色(系統(tǒng)默認值)
//    gray         int // 灰色
//    light_blue   int // 亮藍色
//    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") // 配置文件名字,注意沒有擴展名
    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)
// 因為程序還在運行中,該日志文件所占的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
                }
            }
        }

總結

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

相關文章

  • 使用go語言實現(xiàn)cors中間件

    使用go語言實現(xiàn)cors中間件

    CORS是一種瀏覽器安全機制,用于控制在Web應用程序中不同源(Origin)之間的資源共享,本文將給大家介紹如何使用go語言實現(xiàn)cors中間件,文中有詳細的代碼示例供大家參考,需要的朋友可以參考下
    2023-09-09
  • Go語言HTTP服務實現(xiàn)GET和POST請求的同時支持

    Go語言HTTP服務實現(xiàn)GET和POST請求的同時支持

    做第三方接口有時需要用Get或者Post請求訪問,本文主要介紹了Golang發(fā)送Get和Post請求的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-05-05
  • golang 之 wire 庫的使用小結

    golang 之 wire 庫的使用小結

    Wire是一個用于Go語言的編譯時依賴注入庫,通過代碼生成提高性能和可維護性,它支持編譯時依賴注入、類型安全、簡單易用等功能,文章通過代碼示例展示了如何使用Wire進行依賴注入,并探討了其優(yōu)點如解耦、可測試和維護性,感興趣的朋友跟隨小編一起看看吧
    2025-03-03
  • 總結Golang四種不同的參數(shù)配置方式

    總結Golang四種不同的參數(shù)配置方式

    這篇文章主要介紹了總結Golang四種不同的參數(shù)配置方式,文章圍繞主題展開詳細的內(nèi)容戒殺,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • Go高級特性之并發(fā)處理http詳解

    Go高級特性之并發(fā)處理http詳解

    Golang?作為一種高效的編程語言,提供了多種方法來實現(xiàn)并發(fā)發(fā)送?HTTP?請求,本文將深入探討?Golang?中并發(fā)發(fā)送?HTTP?請求的最佳技術和實踐,希望對大家有所幫助
    2024-02-02
  • golang類型斷言的實現(xiàn)示例

    golang類型斷言的實現(xiàn)示例

    在Go語言中,類型斷言用于從接口類型獲取其具體類型的值,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-10-10
  • Go語言中gPRC的使用

    Go語言中gPRC的使用

    本文主要介紹了Go語言中gPRC的使用,包括Protobuf定義服務接口、HTTP/2協(xié)議與性能優(yōu)勢,以及流模式和發(fā)布-訂閱系統(tǒng)的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2025-07-07
  • Go泛型應用工廠方法及泛型使用

    Go泛型應用工廠方法及泛型使用

    這篇文章主要介紹了Go泛型應用工廠方法及泛型使用,結合工廠方法+泛型方法來看一下泛型到底是如何在業(yè)務場景中使用的,需要的小伙伴可以參考一下
    2022-07-07
  • Golang 1.18新特性模糊測試用法詳解

    Golang 1.18新特性模糊測試用法詳解

    模糊測試是一種軟件測試技術。其核心思想是將自動或半自動生成的隨機數(shù)據(jù)輸入到一個程序中,并監(jiān)視程序異常,如崩潰,斷言失敗,以發(fā)現(xiàn)可能的程序錯誤,比如內(nèi)存泄漏,本文給大家介紹了Golang 1.18 新特性模糊測試,感興趣的同學可以參考閱讀下
    2023-05-05
  • Go語言leetcode題解953驗證外星語詞典示例詳解

    Go語言leetcode題解953驗證外星語詞典示例詳解

    這篇文章主要為大家介紹了Go語言leetcode題解953驗證外星語詞典示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12

最新評論

屯门区| 沙坪坝区| 商城县| 霸州市| 怀化市| 乐至县| 牙克石市| 南充市| 醴陵市| 嫩江县| 凤山县| 菏泽市| 济源市| 渭源县| 南丰县| 南宁市| 陵水| 宁波市| 全椒县| 扎囊县| 乌海市| 伊通| 邵武市| 防城港市| 钦州市| 浦县| 霍城县| 永川市| 开封县| 广宁县| 霍邱县| 铅山县| 乐平市| 禄丰县| 中超| 渝中区| 浦北县| 江川县| 新邵县| 延吉市| 绥芬河市|