zoukankan      html  css  js  c++  java
  • 在 Go 语言中使用 Log 包--转自GCTT

    Linux 在许多方面相对于 Windows 来说都是独特的,在 Linux 中编写程序也不例外。标准输出,标准 err 和 null devices 的使用不仅是一个好主意,也是一个原则。如果您的程序将记录日志信息,则最好遵循目标约定。这样,您的程序将兼容所有 Mac/Linux 工具和托管环境。

    Go 在标准库中有一个 log 包和 logger 类型。使用 log 包将为您提供成为优秀公民 (译注:指 log 包兼容性非常好) 所需的一切。您将能够写入所有标准设备,自定义文件或支持 io.Writer 接口的任何目标。

    我提供了一个非常简单的示例,它将帮助您开始使用 logger :

     1 package main
     2 
     3 import (
     4     "io"
     5     "io/ioutil"
     6     "log"
     7     "os"
     8 )
     9 
    10 var (
    11     Trace   *log.Logger
    12     Info    *log.Logger
    13     Warning *log.Logger
    14     Error   *log.Logger
    15 )
    16 
    17 func Init(
    18     traceHandle io.Writer,
    19     infoHandle io.Writer,
    20     warningHandle io.Writer,
    21     errorHandle io.Writer) {
    22 
    23     Trace = log.New(traceHandle,
    24         "TRACE: ",
    25         log.Ldate|log.Ltime|log.Lshortfile)
    26 
    27     Info = log.New(infoHandle,
    28         "INFO: ",
    29         log.Ldate|log.Ltime|log.Lshortfile)
    30 
    31     Warning = log.New(warningHandle,
    32         "WARNING: ",
    33         log.Ldate|log.Ltime|log.Lshortfile)
    34 
    35     Error = log.New(errorHandle,
    36         "ERROR: ",
    37         log.Ldate|log.Ltime|log.Lshortfile)
    38 }
    39 
    40 func main() {
    41     Init(ioutil.Discard, os.Stdout, os.Stdout, os.Stderr)
    42 
    43     Trace.Println("I have something standard to say")
    44     Info.Println("Special Information")
    45     Warning.Println("There is something you need to know about")
    46     Error.Println("Something has failed")
    47 }

    运行此程序时,您将获得以下输出:

    1 INFO: 2013/11/05 18:11:01 main.go:44: Special Information
    2 WARNING: 2013/11/05 18:11:01 main.go:45: There is something you need to know about
    3 ERROR: 2013/11/05 18:11:01 main.go:46: Something has failed

    您会注意到没有显示 Trace logging (译注:跟踪记录器)。让我们看看代码,找出原因。

    查看 Trace logging 部分的代码:

    var Trace *log.Logger
    
    Trace = log.New(traceHandle,
        "TRACE: ",
        log.Ldate|log.Ltime|log.Lshortfile)
    
    Init(ioutil.Discard, os.Stdout, os.Stdout, os.Stderr)
    
    Trace.Println("I have something standard to say")

    该代码创建一个名为 Trace 的包级变量,它是一个指向 log.Logger 对象的指针。然后在 Init 函数内部创建一个新的 log.Logger 对象。log.New 函数的参数如下:

    func New(out io.Writer, prefix string, flag int) *Logger
    out:    The out variable sets the destination to which log data will be written. // 译注 out 变量设置将写入日志数据的目标
    prefix: The prefix appears at the beginning of each generated log line. // 译注 前缀出现在每个生成的日志行的开头。
    flags:  The flag argument defines the logging properties. // 译注 flag 参数定义日志记录属性
    Flags:
    
    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: message
        Ldate = 1 << iota // the date: 2009/01/23
        Ltime             // the time: 01:23:23
        Lmicroseconds     // microsecond resolution: 01:23:23.123123. assumes Ltime.
        Llongfile         // full file name and line number: /a/b/c/d.go:23
        Lshortfile        // final file name element and line number: d.go:23. overrides Llongfile
        LstdFlags = Ldate | Ltime // initial values for the standard logger
    )

    在此示例程序中,Trace 的目标是 ioutil.Discard 。这是一个 null device (译注:对应 /dev/null 相当于垃圾桶,消息直接丢弃),所有写入调用都可以成功而不做任何事情。因此,使用 Trace 写入时,终端窗口中不会显示任何内容。

    再来看看 Info 的代码:

    var Info *log.Logger
    
    Info = log.New(infoHandle,
        "INFO: ",
        log.Ldate|log.Ltime|log.Lshortfile)
    
    Init(ioutil.Discard, os.Stdout, os.Stdout, os.Stderr)
    
    Info.Println("Special Information")
    

      

    对于 Info (译注:消息记录器),os.Stdout 传入到 init 函数给了 infoHandle 。这意味着当您使用 Info 写消息时,消息将通过标准输出显示在终端窗口中。

    最后,看下 Error 的代码:

    var Error *log.Logger
    
    Error = log.New(errorHandle,
        "ERROR: ",  // 译注: 原文是 INFO 与原始定义不同,应该是笔误,故直接修改
        log.Ldate|log.Ltime|log.Lshortfile)
    
    Init(ioutil.Discard, os.Stdout, os.Stdout, os.Stderr)
    
    Error.Println("Something has failed") // 译注: 原文是 Special Information 与原始定义不同,应该是笔误,故直接修改

    这次 os.Stderr 传入到 Init 函数给了 errorHandle 。这意味着当您使用 Error 写消息时,该消息将通过标准错误显示在终端窗口中。但是,将这些消息传递给 os.Stderr 允许运行程序的其他应用程序知道发生了错误。

    由于支持 io.Writer 接口的任何目标都可以接受,因此您可以创建和使用文件:

    1 file, err := os.OpenFile("file.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
    2 if err != nil {
    3     log.Fatalln("Failed to open log file", output, ":", err)
    4 }
    5 
    6 MyFile = log.New(file,
    7     "PREFIX: ",
    8     log.Ldate|log.Ltime|log.Lshortfile)

    在示例代码中,打开一个文件,然后将其传递给 log.New 函数。现在,当您使用 MyFile 进行写入时,数据将写到 file.txt 里。

    您还可以让 logger (译注:记录器) 同时写入多个目标。

     1 file, err := os.OpenFile("file.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
     2 if err != nil {
     3     log.Fatalln("Failed to open log file", output, ":", err)
     4 }
     5 
     6 multi := io.MultiWriter(file, os.Stdout)
     7 
     8 MyFile := log.New(multi,
     9     "PREFIX: ",
    10     log.Ldate|log.Ltime|log.Lshortfile)

    这里数据将写入到文件和标准输出里。

    注意在处理 OpenFile 的任何错误时使用 log.Fatalln 方法。 log 包提供了一个可以配置的初始 logger。以下是使用具有标准配置的日志的示例程序:

    package main
    
    import (
        "log"
    )
    
    func main() {
        log.Println("Hello World")
    }

    以下是输出:

    2013/11/05 18:42:26 Hello World
    

    如果想要删除或更改输出格式,可以使用 log.SetFlags 方法:

    package main
    
    import (
        "log"
    )
    
    func main() {
        log.SetFlags(0)
        log.Println("Hello World")
    }

    以下是输出:

    Hello World
    

    现在所有格式都已删除。如果要将输出发送到其他目标,请使用 log.SetOutput :

    package main
    
    import (
        "io/ioutil"
        "log"
    )
    
    func main() {
        log.SetOutput(ioutil.Discard)
        log.Println("Hello World")
    }

    现在终端窗口上不会显示任何内容。您可以使用任何支持io.Writer 接口的目标。

    基于这个例子,我为我的所有程序编写了一个新的日志包:

    go get github.com/goinggo/tracelog

    我希望在开始编写Go程序时我就知道 log 和 loggers 。期待将来能够看到我写的更多日志包。


    via: https://www.ardanlabs.com/blog/2013/11/using-log-package-in-go.html

    作者:William Kennedy  译者:chaoshong  校对:polaris1119

    本文由 GCTT 原创编译,Go语言中文网 荣誉推出

  • 相关阅读:
    优先队列
    Problem W UVA 662 二十三 Fast Food
    UVA 607 二十二 Scheduling Lectures
    UVA 590 二十一 Always on the run
    UVA 442 二十 Matrix Chain Multiplication
    UVA 437 十九 The Tower of Babylon
    UVA 10254 十八 The Priest Mathematician
    UVA 10453 十七 Make Palindrome
    UVA 10163 十六 Storage Keepers
    UVA 1252 十五 Twenty Questions
  • 原文地址:https://www.cnblogs.com/tymagic/p/10669138.html
Copyright © 2011-2022 走看看