這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
一、快速使用
Golang的log包短小精悍,可以非常輕鬆的實現日誌列印轉存功能。不用多說,log支援並行作業(即協程安全-相對於JAVA中的安全執行緒而言),其結構定義如下:
type Logger struct {mu sync.Mutex // ensures atomic writes; protects the following fieldsprefix string // prefix to write at beginning of each line // 日誌行首碼flag int // properties // 日誌列印格式標誌,用於指定每行日誌的列印格式out io.Writer // destination for output // 用於指定日誌輸出位置,理論上可以是任務地方,只要實現了io.Writer介面就行buf []byte // for accumulating text to write // 日誌內容}
log包定義了一些日誌格式標誌:
// These flags define which text to prefix to each log entry generated by the Logger.const (// Bits or'ed together to control what's printed. There is no control over the// order they appear (the order listed here) or the format they present (as// described in the comments). A colon appears after these items://2009/01/23 01:23:23.123123 /a/b/c/d.go:23: messageLdate = 1 << iota // the date: 2009/01/23Ltime // the time: 01:23:23Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime.Llongfile // full file name and line number: /a/b/c/d.go:23Lshortfile // final file name element and line number: d.go:23. overrides LlongfileLstdFlags = Ldate | Ltime // initial values for the standard logger)
上述這些標誌可以在建立Logger對象時指定(通過下面的New函數建立),也可以通過Logger.setFlat()方法動態指定。
Logger對象通過函數New建立
// New creates a new Logger. The out variable sets the// destination to which log data will be written.// The prefix appears at the beginning of each generated log line.// The flag argument defines the logging properties.func New(out io.Writer, prefix string, flag int) *Logger {return &Logger{out: out, prefix: prefix, flag: flag}}
log包已預設提供了一個日誌對象,並封裝了包層級的常用函數,該對象將日誌資訊輸出到標準輸出裝置中(開箱即用)。
var std = New(os.Stderr, "", LstdFlags) // 日誌中只使用的flag為LstdFlags,即只輸出日期
如果只是想輸出到終端而不儲存到檔案等其它地方時,可以直接通過log.Xxxx()方式直接調用,因為這些包層級的函數只是對std對象相關方法的簡單封裝,如println函數定義如下:
// Println calls Output to print to the standard logger.// Arguments are handled in the manner of fmt.Println.func Println(v ...interface{}) {std.Output(2, fmt.Sprintln(v...))}
二、Logger對象方法使用說明
Logger對象提供了如下幾個方法:
func (l *Logger) Output(calldepth int, s string) error ; // 真正負責日誌列印的方法,其它層級的列印方法都將會調用它// Println calls l.Output to print to the logger.// Arguments are handled in the manner of fmt.Println.func (l *Logger) Println(v ...interface{}) { // 一般資訊列印方法,相當於JAVA中log的info層級 l.Output(2, fmt.Sprintln(v...)) }// Panicln is equivalent to l.Println() followed by a call to panic(). func (l *Logger) Panicln(v ...interface{}) { // 業務異常時使用的方法,該方法會拋出異常,調用方可以用recover捕獲,相當於JAVA的ERROR層級(JAVA不會自動拋異常)s := fmt.Sprintln(v...)l.Output(2, s)panic(s) // 通過panic拋出異常,只有上層業務沒捕獲異常時,程式才會異常中止並退出,}// 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) // 調用該方法會中止應用程式並直接退出}
使用例子1
package mainimport ( "log" "os" "io/ioutil" "io")var ( Trace *log.Logger // 記錄所有日誌 Info *log.Logger // 重要的資訊 Warning *log.Logger // 需要注意的資訊 Error *log.Logger // 致命錯誤)func init() { file, err := os.OpenFile("file", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { log.Fatalln("Failed to open error log file:", err) } Trace = log.New(ioutil.Discard, "TRACE: ", log.Ltime|log.Lshortfile) Info = log.New(os.Stdout, "Info: ", log.Ltime|log.Lshortfile) Warning = log.New(os.Stdout, "Warning: ", log.Ltime|log.Lshortfile) Error = log.New(io.MultiWriter(file, os.Stderr), "Error", log.Ltime|log.Lshortfile)}func main() { Trace.Println("I have something standard to say") Info.Println("Special Information") Warning.Println("There is something you need to know about") Error.Println("Something has failed")}
使用例子2
package mainimport ( "bytes" "fmt""log""io""io/ioutil""os")type Logger struct {// contains filtered or unexported fields}var (Trace *log.LoggerInfo *log.LoggerWarning *log.LoggerError *log.Logger)func Init( traceHandle io.Writer, infoHandle io.Writer, warningHandle io.Writer, errorHandle io.Writer)(Trace,Info,Warning,Error *log.Logger) { Trace = log.New(traceHandle,"TRACE: ", log.Ldate|log.Ltime|log.Lshortfile) Info = log.New(infoHandle, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile) Warning = log.New(warningHandle, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile)Error = log.New(errorHandle, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile)// Trace.Println("XXXXXXXXXXXX")return //Trace,Info,Warning,Error}func test_log2(){Trace,Info,Warning,Error :=Init(ioutil.Discard, os.Stdout, os.Stdout, os.Stderr)Trace.Println("I have something standard to say")Info.Println("Special Information")Warning.Println("There is something you need to know about")Error.Println("Something has failed")}func test_log1(){var buf bytes.Bufferlogger := log.New(&buf, "logger: ", log.Lshortfile|log.Ldate) logger.Print("Hello, log file!") fmt.Print(&buf)}func main() {test_log1()test_log2()}
更多參考
https://blog.csdn.net/cza55007/article/details/46039279
http://xiaorui.cc/2016/03/15/%E4%BD%BF%E7%94%A8golang-log%E5%BA%93%E5%8C%85%E5%AE%9E%E7%8E%B0%E6%97%A5%E5%BF%97%E6%96%87%E4%BB%B6%E8%BE%93%E5%87%BA/
https://studygolang.com/articles/3326