醒来都是梦 發表於 2025-11-21 09:38:29

golang标准库log包的学习使用

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">一 log简介</a></li><li><a href="#_label1">二 log简单使用</a></li><ul class="second_class_ul"><li><a href="#_lab2_1_0">2.1 log.Print/Println/Printf函数</a></li><li><a href="#_lab2_1_1">2.2 log.Panic/Panicf/Panicln函数</a></li><li><a href="#_lab2_1_2">2.3 log.Fatal/Fatalf/Fatalln函数</a></li></ul><li><a href="#_label2">三 标准日志配置</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_3">3.1 flag参数</a></li><li><a href="#_lab2_2_4">3.2 标准日志配置示例</a></li></ul><li><a href="#_label3">四 日志前缀配置</a></li><ul class="second_class_ul"></ul><li><a href="#_label4">五 日志输出位置配置</a></li><ul class="second_class_ul"></ul><li><a href="#_label5">六 自定义logger</a></li><ul class="second_class_ul"></ul></ul></div><p class="maodian"><a name="_label0"></a></p><h2>一 log简介</h2>
<p>golang内置了log包,实现简单的日志服务。通过调用log包的函数,可以实现简单的日志打印功能。</p>
<p>log包定义了Logger类型,该类型提供了一些格式化输出的方法。本包也提供了一个预定义的&ldquo;标准&rdquo;logger,可以通过调用函数Print系列(Print|Printf|Println)、Fatal系列(Fatal|Fatalf|Fatalln)、和Panic系列(Panic|Panicf|Panicln)来使用,比自行创建一个logger对象更容易使用,它们会将日志信息打印到终端界面</p>
<p class="maodian"><a name="_label1"></a></p><h2>二 log简单使用</h2>
<p>log包中有3个系列的日志打印函数,分别print系列、panic系列、fatal系列.</p>
<table><thead><tr><th><strong>函数系列</strong></th><th>说明</th><th><strong>作用</strong></th></tr></thead><tbody><tr><td>Print</td><td>Print/Printf/Println</td><td>单纯打印日志</td></tr><tr><td>Panic</td><td>Panic/Panicf/Panicln</td><td>打印日志,抛出panic异常</td></tr><tr><td>Fatal</td><td>Fatal/Fatalf/Fatalln</td><td>打印日志,强制结束程序(os.Exit(1)),defer函数不会执行</td></tr></tbody></table>
<p>log包主要提供了3类接口,分别是print系列、panic系列、fatal系列,对每一类接口其提供了3种调用方式,分别是&ldquo;Xxxx、Xxxxln、Xxxxf&rdquo;,基本与<code>fmt</code>中的相关函数类似。</p>
<p class="maodian"><a name="_lab2_1_0"></a></p><h3>2.1 log.Print/Println/Printf函数</h3>
<p>log.Print/Println/Printf函数只是单纯打印日志</p>
<p>实例演示:</p>
<div class="jb51code"><pre class="brush:go;">package main

import "log"

func main() {
        log.Print("my log")
        log.Printf("my log %d", 100) // 格式化输出
        name := "tom"
        age := 20
        log.Println(name, " ", age)

}
</pre></div>
<p>运行结果:</p>
<blockquote><p> go run &quot;c:\Users\Mechrevo\Desktop\go_pro\test.go&quot;<br />2022/07/12 17:27:16 my log<br />2022/07/12 17:27:16 my log 100<br />2022/07/12 17:27:16 tom &nbsp; 20</p>
<p> exited with code=0 in 1.118 seconds</p></blockquote>
<p>基本使用与<code>fmt</code>中的函数类似</p>
<p class="maodian"><a name="_lab2_1_1"></a></p><h3>2.2 log.Panic/Panicf/Panicln函数</h3>
<p>log.Panic/Panicf/Panicln函数会打印出日志并且抛出panic异常,需要注意的是在panic之后声明的代码将不会执行。</p>
<p>实例演示:</p>
<div class="jb51code"><pre class="brush:go;">package main

import (
        "fmt"
        "log"
)

func main() {
        defer fmt.Println("发生了 panic错误!")
        log.Print("my log")
        log.Panic("my panic")
        fmt.Println("运行结束。。。")
}
</pre></div>
<p>运行结果:</p>
<blockquote><p> go run &quot;c:\Users\Mechrevo\Desktop\go_pro\test.go&quot;<br />2022/07/12 17:31:48 my log<br />2022/07/12 17:31:48 my panic<br />发生了 panic错误!<br />panic: my panic</p>
<p>goroutine 1 :<br />log.Panic({0xc00007ff30?, 0x60?, 0x6e7be0?})<br />&nbsp;&nbsp; &nbsp;c:/go/src/log/log.go:385 +0x65<br />main.main()<br />&nbsp;&nbsp; &nbsp;c:/Users/Mechrevo/Desktop/go_pro/test.go:11 +0xc5<br />exit status 2</p>
<p> exited with code=1 in 1.013 seconds</p></blockquote>
<p>可见输出了<code>log.Print</code>和<code>log.Panic</code>中的内容,然后再panic之前的defer函数被调用并输出,而<code>log.Panic</code>之后的<code>fmt.Println</code>并没有被调用输出,可见<code>log.Panic</code>抛出panic异常之后的代码是不会被调用的。</p>
<p>log.Panicf/Panicln用法与2.1中的Println/Printf函数类似,此处不再赘述。</p>
<p class="maodian"><a name="_lab2_1_2"></a></p><h3>2.3 log.Fatal/Fatalf/Fatalln函数</h3>
<p>对于<code>log.Fatal</code>接口,会将日志内容打印输出,接着调用系统的<code>os.Exit(1)</code>接口,强制退出程序并返回状态1,但是有一点需要注意的是,由于直接调用系统os接口退出,defer函数不会调用。</p>
<p>实例演示:</p>
<div class="jb51code"><pre class="brush:go;">package main

import (
        "fmt"
        "log"
)

func main() {
        defer fmt.Println("defer。。。")
        log.Print("my log")
        log.Fatal("my fatal")
        fmt.Println("运行结束。。。")
}
</pre></div>
<p>运行结果:</p>
<blockquote><p> go run &quot;c:\Users\Mechrevo\Desktop\go_pro\test.go&quot;<br />2022/07/12 17:40:04 my log<br />2022/07/12 17:40:04 my fatal<br />exit status 1</p>
<p> exited with code=1 in 0.975 seconds</p></blockquote>
<p>可见并没有调用defer函数。</p>
<p>log.Fatalf/Fatalln用法与2.1中的Println/Printf函数类似,此处不再赘述。</p>
<p class="maodian"><a name="_label2"></a></p><h2>三 标准日志配置</h2>
<p>默认情况下log只会打印出时间,但是实际情况下我们还需要获取文件名,行号等信息,log包提供给我们定制的接口。</p>
<p>log包提供两个标准log配置的相关方法:</p>
<table><thead><tr><th>方法</th><th>说明</th></tr></thead><tbody><tr><td>func Flags() int</td><td>返回标准log输出配置</td></tr><tr><td>func SetFlags(flag int)</td><td>设置标准log输出配置</td></tr></tbody></table>
<p class="maodian"><a name="_lab2_2_3"></a></p><h3>3.1 flag参数</h3>
<div class="jb51code"><pre class="brush:go;">const (
    // 控制输出日志信息的细节,不能控制输出的顺序和格式。
    // 输出的日志在每一项后会有一个冒号分隔,例如2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
    Ldate         = 1 &lt;&lt; iota   // 日期,2009/01/23
    Ltime                         // 时间,01:23:23
    Lmicroseconds               // 微秒级别的时间,01:23:23.123123(用于增强Ltime位)
    Llongfile                     // 文件全路径名+行号,/a/b/c/d.go:23
    Lshortfile                  // 文件名+行号,d.go:23(会覆盖掉Llongfile)
    LUTC                        // 使用UTC时间
    LstdFlags   = Ldate | Ltime // 标准logger的初始值
)
</pre></div>
<p class="maodian"><a name="_lab2_2_4"></a></p><h3>3.2 标准日志配置示例</h3>
<div class="jb51code"><pre class="brush:go;">package main

import (
        "fmt"
        "log"
)

func main() {
        i := log.Flags()
        fmt.Printf("i: %v\n", i)
        log.SetFlags(log.Ldate | log.Ltime | log.Llongfile)
        log.Print("my log")
}
</pre></div>
<p>运行结果:</p>
<blockquote><p> go run &quot;c:\Users\Mechrevo\Desktop\go_pro\test.go&quot;<br />i: 3<br />2022/07/12 17:59:29 c:/Users/Mechrevo/Desktop/go_pro/test.go:12: my log</p>
<p> exited with code=0 in 1.102 seconds</p></blockquote>
<p class="maodian"><a name="_label3"></a></p><h2>四 日志前缀配置</h2>
<p>log包提供两个日志前缀配置的相关函数:</p>
<table><thead><tr><th>方法</th><th>说明</th></tr></thead><tbody><tr><td>func Prefix() string</td><td>返回日志的前缀配置</td></tr><tr><td>func SetPrefix(prefix string)</td><td>设置日志前缀</td></tr></tbody></table>
<p>实例演示:</p>
<div class="jb51code"><pre class="brush:go;">package main

import (
        "fmt"
        "log"
)

func main() {
        s := log.Prefix()
        fmt.Printf("s: %v\n", s)
        log.SetPrefix(" ")
        s = log.Prefix()
        fmt.Printf("s: %v\n", s)
        log.Print("my log...")
}
</pre></div>
<p>运行结果:</p>
<blockquote><p> go run &quot;c:\Users\Mechrevo\Desktop\go_pro\test.go&quot;<br />s:&nbsp;<br />s: &nbsp;<br /> 2022/07/12 18:00:55 my log...</p>
<p> exited with code=0 in 0.977 seconds</p></blockquote>
<p class="maodian"><a name="_label4"></a></p><h2>五 日志输出位置配置</h2>
<p>前面介绍的都是将日志输出到控制台上,golang的log包还支持将日志输出到文件中,log包提供了<code>func SetOutput(w io.Writer)</code>函数,将日志输出到文件中。</p>
<p>实例演示:</p>
<div class="jb51code"><pre class="brush:go;">package main

import (
        "log"
        "os"
)

func main() {
        f, err := os.OpenFile("a.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
        if err != nil {
                log.Panic("打开日志文件异常")
        }
        log.SetOutput(f)
        log.Print("my log...")
}
</pre></div>
<p>运行结果:</p>
<p>日志输出到当前目录下 a.log文件中</p>
<blockquote><p>2022/07/12 18:02:20 my log...</p></blockquote>
<p class="maodian"><a name="_label5"></a></p><h2>六 自定义logger</h2>
<p>log包中提供了<code>func New(out io.Writer, prefix string, flag int) *Logger</code>函数来实现自定义logger。从效果上来看,就是标准日志配置、日志前缀配置、日志输出位置配置整合到一个函数中,使日志配置不在那么繁琐。</p>
<p>实例演示:</p>
<div class="jb51code"><pre class="brush:go;">package main

import (
        "log"
        "os"
)

var logger *log.Logger

func init() {
        logFile, err := os.OpenFile("a.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
        if err != nil {
                log.Panic("打开日志文件异常")
        }
        logger = log.New(logFile, "", log.Ldate|log.Ltime|log.Lshortfile)
}

func main() {
        logger.Println("自定义logger")
}
</pre></div>
<p>运行结果:</p>
<p>日志输出到当前目录下 a.log文件中</p>
<blockquote><p>2022/07/12 18:06:21 test.go:19: 自定义logge</p></blockquote>
頁: [1]
查看完整版本: golang标准库log包的学习使用