go語言代碼log輸出,go log庫

Golang將日志同時輸出到控制臺和文件

日常開發(fā)當中需要將golang的log包打印的日志同時輸出到控制臺和文件,應該如何解決這個問題?

創(chuàng)新互聯長期為千余家客戶提供的網站建設服務,團隊從業(yè)經驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯網生態(tài)環(huán)境。為屯溪企業(yè)提供專業(yè)的成都網站建設、成都網站制作,屯溪網站改版等技術服務。擁有10年豐富建站經驗和眾多成功案例,為您定制開發(fā)。

log包可以通過SetOutput()方法指定日志輸出的方式(Writer),但是只能指定一個輸出的方式(Writer)。我們利用io.MultiWriter()將多個Writer拼成一個Writer使用的特性,把log.Println()輸出的內容分流到控制臺和文件當中。

原文地址

golang logger輸出格式怎么修改

1.Logger結構

首先來看下類型Logger的定義:

type Logger struct {

mu sync.Mutex // ensures atomic writes; protects the following fields

prefix string // prefix to write at beginning of each line

flag int // properties

out io.Writer // destination for output

buf []byte // for accumulating text to write

}

主要有5個成員,其中3個我們比較熟悉,分別是表示Log前綴的 "prefix",表示Log頭標簽的 "flag" ,以及Log的輸出目的地out。 buf是一個字節(jié)數組,主要用來存放即將刷入out的內容,相當于一個臨時緩存,在對輸出內容進行序列化時作為存儲目的地。 mu是一個mutex主要用來作線程安全的實習,當有多個goroutine同時往一個目的刷內容的時候,通過mutex保證每次寫入是一條完整的信息。

2.std及整體結構

在前一篇文章中我們提到了log模塊提供了一套包級別的簡單接口,使用該接口可以直接將日志內容打印到標準錯誤。那么該過程是怎么實現的呢?其實就是通過一個內置的Logger類型的變量 "std" 來實現的。該變量使用:

var std = New(os.Stderr, "", LstdFlags)

進行初始化,默認輸出到系統(tǒng)的標準輸出 "os.Stderr" ,前綴為空,使用日期加時間作為Log抬頭。

當我們調用 log.Print的時候是怎么執(zhí)行的呢?我們看其代碼:

func Print(v ...interface{}) {

std.Output(2, fmt.Sprint(v...))

}

這里實際就是調用了Logger對象的 Output方法,將日志內容按照fmt包中約定的格式轉義后傳給Output。Output定義如下 :

func (l *Logger) Output(calldepth int, s string) error

其中s為日志沒有加前綴和Log抬頭的具體內容,xxxxx 。該函數執(zhí)行具體的將日志刷入到對應的位置。

3.核心函數的實現

Logger.Output是執(zhí)行具體的將日志刷入到對應位置的方法。

該方法首先根據需要獲得當前時間和調用該方法的文件及行號信息。然后調用formatHeader方法將Log的前綴和Log抬頭先格式化好 放入Logger.buf中,然后再將Log的內容存入到Logger.buf中,最后調用Logger.out.Write方法將完整的日志寫入到輸出目的地中。

由于寫入文件以及拼接buf的過程是線程非安全的,因此使用mutex保證每次寫入的原子性。

l.mu.Lock()

defer l.mu.Unlock()

將buf的拼接和文件的寫入放入這個后面,使得在多個goroutine使用同一個Logger對象是,不會弄亂buf,也不會雜糅的寫入。

該方法的第一個參數最終會傳遞給runtime.Caller的skip,指的是跳過的棧的深度。這里我記住給2就可以了。這樣就會得到我們調用log 是所處的位置。

在golang的注釋中說鎖住 runtime.Caller的過程比較重,這點我還是不很了解,只是從代碼中看到其在這里把鎖打開了。

if l.flag(Lshortfile|Llongfile) != 0 {

// release lock while getting caller info - it‘s expensive.

l.mu.Unlock()

var ok bool

_, file, line, ok = runtime.Caller(calldepth)

if !ok {

file = "???"

line = 0

}

l.mu.Lock()

}

在formatHeader里面首先將前綴直接復制到Logger.buf中,然后根據flag選擇Log抬頭的內容,這里用到了一個log模塊實現的 itoa的方法,作用類似c的itoa,將一個整數轉換成一個字符串。只是其轉換后將結果直接追加到了buf的尾部。

縱觀整個實現,最值得學習的就是線程安全的部分。在什么位置合適做怎樣的同步操作。

4.對外接口的實現

在了解了核心格式化和輸出結構后,在看其封裝就非常簡單了,幾乎都是首先用Output進行日志的記錄,然后在必要的時候 做os.exit或者panic的操作,這里看下Fatal的實現。

func (l *Logger) Fatal(v ...interface{}) {

l.Output(2, fmt.Sprint(v...))

os.Exit(1)

}

// Fatalf is equivalent to l.Printf() followed by a call to os.Exit(1).

func (l *Logger) Fatalf(format string, v ...interface{}) {

l.Output(2, fmt.Sprintf(format, v...))

os.Exit(1)

}

// Fatalln is equivalent to l.Println() followed by a call to os.Exit(1).

func (l *Logger) Fatalln(v ...interface{}) {

l.Output(2, fmt.Sprintln(v...))

os.Exit(1)

}

這里也驗證了我們之前做的Panic的結果,先做輸出日志操作。再進行panic。

Go語言基礎語法(一)

本文介紹一些Go語言的基礎語法。

先來看一個簡單的go語言代碼:

go語言的注釋方法:

代碼執(zhí)行結果:

下面來進一步介紹go的基礎語法。

go語言中格式化輸出可以使用 fmt 和 log 這兩個標準庫,

常用方法:

示例代碼:

執(zhí)行結果:

更多格式化方法可以訪問中的fmt包。

log包實現了簡單的日志服務,也提供了一些格式化輸出的方法。

執(zhí)行結果:

下面來介紹一下go的數據類型

下表列出了go語言的數據類型:

int、float、bool、string、數組和struct屬于值類型,這些類型的變量直接指向存在內存中的值;slice、map、chan、pointer等是引用類型,存儲的是一個地址,這個地址存儲最終的值。

常量是在程序編譯時就確定下來的值,程序運行時無法改變。

執(zhí)行結果:

執(zhí)行結果:

Go 語言的運算符主要包括算術運算符、關系運算符、邏輯運算符、位運算符、賦值運算符以及指針相關運算符。

算術運算符:

關系運算符:

邏輯運算符:

位運算符:

賦值運算符:

指針相關運算符:

下面介紹一下go語言中的if語句和switch語句。另外還有一種控制語句叫select語句,通常與通道聯用,這里不做介紹。

if語法格式如下:

if ... else :

else if:

示例代碼:

語法格式:

另外,添加 fallthrough 會強制執(zhí)行后面的 case 語句,不管下一條case語句是否為true。

示例代碼:

執(zhí)行結果:

下面介紹幾種循環(huán)語句:

執(zhí)行結果:

執(zhí)行結果:

也可以通過標記退出循環(huán):

--THE END--

Go語言之log(如何將日志寫到指定文件里面)

對于Go語言的日志來說,如何將log寫到指定的文件里面,下面是一個例子。

output:

output:

golang怎么將控制臺的錯誤輸出寫入文件

你可以記錄下錯誤,然后寫入文件?;蛘咴趩觛o程序的時候,把輸出寫入文件。

像這樣: ./main a.log

網站標題:go語言代碼log輸出,go log庫
文章分享:http://muchs.cn/article44/hcgdee.html

成都網站建設公司_創(chuàng)新互聯,為您提供動態(tài)網站、ChatGPT網站設計公司、靜態(tài)網站網站排名、外貿建站

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯

網站建設網站維護公司