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

go語言日志實(shí)現(xiàn)詳解(打印日志、日志寫入文件和日志切割)

 更新時(shí)間:2022年10月29日 11:08:01   作者:ydl1128  
golang內(nèi)置了log包,實(shí)現(xiàn)簡(jiǎn)單的日志服務(wù),下面這篇文章主要給大家介紹了關(guān)于go語言日志實(shí)現(xiàn)(打印日志、日志寫入文件和日志切割)的相關(guān)資料,需要的朋友可以參考下

Go語言內(nèi)置的log包實(shí)現(xiàn)了簡(jiǎn)單的日志服務(wù)

log包定義了Logger類型,該類型提供了一些格式化輸出的方法。本包也提供了一個(gè)預(yù)定義的“標(biāo)準(zhǔn)”logger,可以通過調(diào)用函數(shù)Print系列(Print|Printf|Println)、Fatal系列(Fatal|Fatalf|Fatalln)、和Panic系列(Panic|Panicf|Panicln)來使用,比自行創(chuàng)建一個(gè)logger對(duì)象更容易使用。

Logger

package main

import (
	"log"
)

func main() {
	log.Println("這是一條測(cè)試的日志。")
	v := "很普通的"
	log.Printf("這是一條%s日志。\n", v)
	log.Fatalln("這是一條會(huì)觸發(fā)fatal的日志。")
	log.Panicln("這是一條會(huì)觸發(fā)panic的日志。")
}

標(biāo)準(zhǔn)logger的配置

SetFlags函數(shù)用來設(shè)置標(biāo)準(zhǔn)logger的輸出配置。

const (
    // 控制輸出日志信息的細(xì)節(jié),不能控制輸出的順序和格式。
    // 輸出的日志在每一項(xiàng)后會(huì)有一個(gè)冒號(hào)分隔:例如2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
    Ldate         = 1 << iota     // 日期:2009/01/23
    Ltime                         // 時(shí)間:01:23:23
    Lmicroseconds                 // 微秒級(jí)別的時(shí)間:01:23:23.123123(用于增強(qiáng)Ltime位)
    Llongfile                     // 文件全路徑名+行號(hào): /a/b/c/d.go:23
    Lshortfile                    // 文件名+行號(hào):d.go:23(會(huì)覆蓋掉Llongfile)
    LUTC                          // 使用UTC時(shí)間
    LstdFlags     = Ldate | Ltime // 標(biāo)準(zhǔn)logger的初始值
)
func main() {
	log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)
	log.Println("這是一條很普通的日志。")
}

配置日志前綴(SetPrefix)

func main() {
	log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)
	log.Println("這是一條很普通的日志。")
	log.SetPrefix("[哈哈哈]")
	log.Println("這是一條很普通的日志。")
}

配置日志輸出位置

SetOutput函數(shù)用來設(shè)置標(biāo)準(zhǔn)logger的輸出目的地,默認(rèn)是標(biāo)準(zhǔn)錯(cuò)誤輸出。

func init() {
	logFile, err := os.OpenFile("./xx.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
	if err != nil {
		fmt.Println("open log file failed, err:", err)
		return
	}
	log.SetOutput(logFile)
	log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)
}

創(chuàng)建新logger對(duì)象

log標(biāo)準(zhǔn)庫(kù)中還提供了一個(gè)創(chuàng)建新logger對(duì)象的構(gòu)造函數(shù)–New,支持我們創(chuàng)建自己的logger示例。New函數(shù)的簽名如下:

func New(out io.Writer, prefix string, flag int) *Logger

New創(chuàng)建一個(gè)Logger對(duì)象。其中,參數(shù)out設(shè)置日志信息寫入的目的地。參數(shù)prefix會(huì)添加到生成的每一條日志前面。參數(shù)flag定義日志的屬性(時(shí)間、文件等等)。

舉個(gè)例子:

func main() {
	logger := log.New(os.Stdout, "<New>", log.Lshortfile|log.Ldate|log.Ltime)
	logger.Println("這是自定義的logger記錄的日志。")
}
//<New>2017/06/19 14:06:51 main.go:34: 這是自定義的logger記錄的日志。

補(bǔ)充:Go內(nèi)置的log庫(kù)功能有限,例如無法滿足記錄不同級(jí)別日志的情況,需要選擇使用第三方的日志庫(kù),如logrus、zap等。

日志庫(kù)級(jí)別

package log

import (
	"errors"
	"fmt"
	"strings"
	"time"
)

type LogLevel uint16

//日志常量
const (
	UNKNOW LogLevel = iota
	DEBUG 
	TRACE
	INFO
	WARNIG
	ERROR
	FATAL

)
//解析日志級(jí)別
func paraLogLevel(s string) (LogLevel,error) {
	s = strings.ToLower(s)
	switch s {

	case "debug":
		return DEBUG,nil

	case "tarce":
		return TRACE,nil
	case "info":
		return INFO,nil
	case "warnig":
		return WARNIG,nil
	case "error":
		return ERROR,nil
	case "fatal":
		return FATAL,nil
	default:
		err:= errors.New("無效的日志級(jí)別")
		return UNKNOW,err
	}
}
//定義日志級(jí)別機(jī)構(gòu)提
type Logger  struct{
	Level LogLevel
}
//構(gòu)造器
func NewLog(levelLog string) Logger  {
	level, err := paraLogLevel(levelLog)
	if err !=nil{
		panic(err)
	}
	return Logger{
		Level: level,
	}
}
//是否能夠打印某個(gè)級(jí)別的日志
func (l Logger)  enable(logLevel LogLevel) bool {
		return l.Level >logLevel
}

func (l Logger) Debug(msg string) {
	if l.enable(DEBUG){
		now := time.Now()
		fmt.Printf("[%s] [Debug] %s",now.Format("2006-01-02 15:04:05"),msg);
	}

}

func (l Logger) Info(msg string) {
	if l.enable(INFO){
		now := time.Now()
		fmt.Printf("[%s] [Info] %s",now.Format("2006-01-02 15:04:05"),msg);
	}

}

func (l Logger) Warning(msg string) {
	if l.enable(WARNIG){
		now := time.Now()
		fmt.Printf("[%s] [Warning] %s",now.Format("2006-01-02 15:04:05"),msg);
	}

}

func (l Logger) Error(msg string) {
	if l.enable(ERROR){
		now := time.Now()
		fmt.Printf("[%s] [Error] %s",now.Format("2006-01-02 15:04:05"),msg);
	}

}

func (l Logger) Fatal(msg string) {
	if l.enable(FATAL){
		now := time.Now()
		fmt.Printf("[%s] [Fatal] %s",now.Format("2006-01-02 15:04:05"),msg);
	}

}
import "gostudy/log"

func main()  {

	newLog := log.NewLog("warnig")
	newLog.Debug("這是debug日志")
	newLog.Info("這是info日志")
	newLog.Warning("這是Warning日志")
	newLog.Error("這是ERROR日志")
	newLog.Fatal("這是FATAL日志")
}

打印結(jié)果:[2022-08-04 10:41:56] [Debug] 這是debug日志[2022-08-04 10:41:56] [Info] 這是info日志

runtime.Caller

能夠拿到文件名函數(shù)名和行號(hào)

可變參數(shù)的日志

//......interface{}表示可變的任意參數(shù),可不傳也可傳任意長(zhǎng)度
func (l Logger) Debug(msg string, a ...interface{}) {
	msg = fmt.Sprint(msg,a)
	if l.enable(DEBUG){
		now := time.Now()
		fmt.Printf("[%s] [Debug] %s",now.Format("2006-01-02 15:04:05"),msg);
	}

}

實(shí)現(xiàn)往文件里面寫日志

1.新建fileloger.go文件,用來提供寫入日志的功能

package log

import (
	"errors"
	"fmt"
	"os"
	"path"
	"strings"
	"time"
)

type LogLevel uint16
//日志級(jí)別
const (
	UNKNOW LogLevel = iota
	DEBUG 
	TRACE
	INFO
	WARNIG
	ERROR
	FATAL

)
//解析日志
func paraLogLevel(s string) (LogLevel,error) {
	s = strings.ToLower(s)
	switch s {

	case "debug":
		return DEBUG,nil

	case "tarce":
		return TRACE,nil
	case "info":
		return INFO,nil
	case "warnig":
		return WARNIG,nil
	case "error":
		return ERROR,nil
	case "fatal":
		return FATAL,nil
	default:
		err:= errors.New("無效的日志級(jí)別")
		return UNKNOW,err
	}
}

//獲取日志的字符串格式
func getLogStr (level LogLevel) string {

	switch level {

	case DEBUG:
		return "debug"

	case TRACE:
		return "tarce"
	case INFO:
		return "info"
	case WARNIG:
		return "warnig"
	case ERROR:
		return "error"
	case FATAL:
		return "fatal"
	default:
		return "unknow"
	}
}

//定義日志的結(jié)構(gòu)體
type FileLogger  struct{
	Level LogLevel
	filePath string
	fileName string
	//要打開和寫入的文件,一個(gè)日志文件一個(gè)錯(cuò)誤日志文件
	fileObj *os.File
	errfileObj *os.File
	maxFileSize int64
}

//構(gòu)造函數(shù)
func NewFlieLogger(LeveStr ,fp,fn string,size int64)  *FileLogger{

	level, err := paraLogLevel(LeveStr)
	if err != nil {
		panic(err)
	}
	f1 := &FileLogger{
		Level: level,
		filePath: fp,
		fileName: fn,
		maxFileSize: size,
	}
	err= f1.initFile()
	if err != nil {
		panic(err)
	}
	return f1
}

//初始化要打開和寫入的日志文件的操作
func (f *FileLogger) initFile() (error) {
	join := path.Join(f.filePath, f.fileName)
	fileObj, err := os.OpenFile(join, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		fmt.Printf("open log fail ,err: %v\n",err)
		return err
	}

	errFileObj, err := os.OpenFile(join+".err", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		fmt.Printf("open log fail ,err: %v\n",err)
		return err
	}
	//日志文件都打開
	f.fileObj = fileObj;
	f.errfileObj = errFileObj;
	return  nil

}
//判斷級(jí)別
func (l FileLogger)  enable(logLevel LogLevel) bool {
		return l.Level >logLevel
}
//打印日志操作
func (f *FileLogger) Log(leve LogLevel,msg string)  {
	now := time.Now()
	if f.enable(leve){

		fmt.Fprintf(f.fileObj,"[%s] [%s] %s",now.Format("2006-01-02 15:04:05"),getLogStr(leve),msg);
	}

	if leve >ERROR{

		fmt.Fprintf(f.errfileObj,"[%s] [%s] %s",now.Format("2006-01-02 15:04:05"),getLogStr(leve),msg);
	}
}

func (l FileLogger) Debug(msg string, a ...interface{}) {
	msg = fmt.Sprint(msg,a)
	if l.enable(DEBUG){
		l.Log(DEBUG,msg)
	}

}

func (l FileLogger) Info(msg string, a ...interface{}) {
	msg = fmt.Sprint(msg,a)
	if l.enable(WARNIG){
		l.Log(WARNIG,msg)
	}

}


func (l FileLogger) Warning(msg string, a ...interface{}) {
	msg = fmt.Sprint(msg,a)
	if l.enable(WARNIG){
		l.Log(WARNIG,msg)
	}

}

func (l FileLogger) Error(msg string, a ...interface{}) {
	msg = fmt.Sprint(msg,a)
	if l.enable(ERROR){
		l.Log(ERROR,msg)
	}

}

func (l FileLogger) Fatal(msg string, a ...interface{}) {
	msg = fmt.Sprint(msg,a)
	if l.enable(FATAL){
		l.Log(FATAL,msg)
	}

}

func (f *FileLogger) Colse()  {
	f.fileObj.Close()
	f.errfileObj.Close()
}

2.測(cè)試:

func main()  {

	newLog := log.NewFlieLogger("warnig","./","now.log",100*1024*1024)
	newLog.Debug("這是debug日志")
	newLog.Info("這是info日志")
	newLog.Warning("這是Warning日志")
	newLog.Error("這是ERROR日志")
	newLog.Fatal("這是FATAL日志")
	newLog.Colse()

}

//運(yùn)行兩次后,打印結(jié)果:

日志切割(按文件大小切割、按日期切割)

其實(shí)就是每次記錄文件的大小,超過了就重新寫一個(gè)文件。

通過Stat()函數(shù)拿到文件的一些信息

	open, _:= os.Open("文件名")
	stat, _, := open.Stat()
	stat.Size()//拿到文件大小

日期切割:

拿到文件的名稱或者檢查下有沒有當(dāng)天的日志文件,沒有就創(chuàng)建新增。

總結(jié)

到此這篇關(guān)于go語言日志實(shí)現(xiàn)(打印日志、日志寫入文件和日志切割)的文章就介紹到這了,更多相關(guān)go語言打印日志和日志切割內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go結(jié)合Redis用最簡(jiǎn)單的方式實(shí)現(xiàn)分布式鎖

    Go結(jié)合Redis用最簡(jiǎn)單的方式實(shí)現(xiàn)分布式鎖

    本文主要介紹了Go結(jié)合Redis用最簡(jiǎn)單的方式實(shí)現(xiàn)分布式鎖示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Go語言實(shí)現(xiàn)分布式鎖

    Go語言實(shí)現(xiàn)分布式鎖

    分布式鎖是控制分布式系統(tǒng)之間同步訪問共享資源的一種方式。如果不同的系統(tǒng)或是同一個(gè)系統(tǒng)的不同主機(jī)之間共享了一個(gè)或一組資源,那么訪問這些資源時(shí),需要通過一些互斥手段來防止彼此之間的干擾以保證一致性,在這種情況下,就需要使用分布式鎖了
    2023-01-01
  • 使用Lumberjack+zap進(jìn)行日志切割歸檔操作

    使用Lumberjack+zap進(jìn)行日志切割歸檔操作

    這篇文章主要介紹了使用Lumberjack+zap進(jìn)行日志切割歸檔操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • goland 實(shí)現(xiàn)websocket server的示例代碼

    goland 實(shí)現(xiàn)websocket server的示例代碼

    本文主要介紹了goland 實(shí)現(xiàn)websocket server的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • 使用Viper處理Go應(yīng)用程序的配置方法

    使用Viper處理Go應(yīng)用程序的配置方法

    Viper是一個(gè)應(yīng)用程序配置解決方案,用于Go應(yīng)用程序,它支持JSON、TOML、YAML、HCL、envfile和Java properties配置文件格式,這篇文章主要介紹了使用Viper處理Go應(yīng)用程序的配置,需要的朋友可以參考下
    2023-09-09
  • 詳解golang開發(fā)中http請(qǐng)求redirect的問題

    詳解golang開發(fā)中http請(qǐng)求redirect的問題

    這篇文章主要介紹了詳解golang開發(fā)中http請(qǐng)求redirect的問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Go 自定義package包設(shè)置與導(dǎo)入操作

    Go 自定義package包設(shè)置與導(dǎo)入操作

    這篇文章主要介紹了Go 自定義package包設(shè)置與導(dǎo)入操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • 線上問題排查之golang使用json進(jìn)行對(duì)象copy

    線上問題排查之golang使用json進(jìn)行對(duì)象copy

    這篇文章主要介紹了線上問題排查之golang使用json進(jìn)行對(duì)象copy,文章圍繞golang使用json進(jìn)行對(duì)象copy的內(nèi)存溢出問題排查展開詳細(xì)內(nèi)容需要的小伙伴可以參考一下
    2022-06-06
  • golang?墻上時(shí)鐘與單調(diào)時(shí)鐘的實(shí)現(xiàn)

    golang?墻上時(shí)鐘與單調(diào)時(shí)鐘的實(shí)現(xiàn)

    本文主要介紹了golang?墻上時(shí)鐘與單調(diào)時(shí)鐘的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Golang實(shí)現(xiàn)組合模式和裝飾模式實(shí)例詳解

    Golang實(shí)現(xiàn)組合模式和裝飾模式實(shí)例詳解

    這篇文章主要介紹了Golang實(shí)現(xiàn)組合模式和裝飾模式,本文介紹組合模式和裝飾模式,golang實(shí)現(xiàn)兩種模式有共同之處,但在具體應(yīng)用場(chǎng)景有差異。通過對(duì)比兩個(gè)模式,可以加深理解,需要的朋友可以參考下
    2022-11-11

最新評(píng)論