(转)go语言web开发22 - beego框架之logs包使用

发布时间 2023-04-06 09:52:29作者: liujiacai

原文:https://www.cnblogs.com/hei-ma/articles/13791609.html

beego框架的logs包是一个用来处理日志的库,目前支持的引擎有 file(输出日志到文件)、console(终端输出)、net(输出到网络地址)、smtp(发送邮件)。

 

一、beego自带的日志功能(了解即可)

beego有自带的日志功能(了解即可,即将被弃用了,主要使用beego的logs包),看下面示例:

复制代码
func (c *InternelLogController) Get() {
    // 指定日志文件,指定日志文件后默认控制台和日志里都有日志输出
    beego.SetLogger("file", `{"filename":"logs/test-internel.log"}`)
    // 删除日志输出的引擎,在括号里指定要删除的日志输出的引擎,如果指定file就是不往日志里输出,如果指定console就是不往控制台输出
    beego.BeeLogger.DelLogger("console")
    // 设置日志输出的级别,日志里只记录设置的日志级别及以上。
    beego.SetLevel(beego.LevelError)


    // 日志级别与打印日志,beego自带的日志共有八个级别(数值级别是0-8)
    beego.Emergency("emergency log")    // 紧急的(数值级别:0)
    beego.Alert("alert log")            // 警告的(数值级别:1)
    beego.Critical("critical log")      // 关键的(数值级别:2)
    beego.Error("error log")            // 错误日志(数值级别:3)
    beego.Warn("warn log")              // 警告(数值级别:4)
    beego.Notice("notice log")          // 通知(数值级别:5)
    beego.Informational("informational log")             // 信息(数值级别:6)
    beego.Debug("debug log")             // debug日志(数值级别:7)

    c.TplName = "test_internel_log.html"
}
复制代码
设置日志级别:
  • beego.SetLevel(beego.LevelError)
  • 其他的日志级别:级别依次降低,数值的日志级别是从0开始的
    • 0:LevelEmergency

    • 1:LevelAlert

    • 2:LevelCritical

    • 3:LevelError

    • 4:LevelWarning

    • 5:LevelNotice

    • 6:LevelInformational

    • 7:LevelDebug

注意:

  • 设置了日志级别,输出的日志是当前的级别+比自身高的级别

  • 比如设置了LevelAlert级别,则会输出Alert和Emergency两个级别的日志

输出文件名和行号:

  • 日志默认输出调用的文件名和文件行号,如果不输出文件和文件行号,则:

    • beego.SetLogFuncCall(false)

 

二、logs包使用(后面主要使用这个包)

2.1、安装日志包

> set GOPROXY=https://goproxy.cn
> go get github.com/astaxie/beego/logs

 

2.2、日志级别

级别依次降低,数值的日志级别是从0开始的

  • 0:LevelEmergency
  • 1:LevelAlert
  • 2:LevelCritical
  • 3:LevelError
  • 4:LevelWarn = LevelWarning
  • 5:LevelNotice
  • 6:LevelInfo = LevelInformational
  • 7:LevelTrace = LevelDebug

 

2.3、日志引擎

日志引擎可以理解为日志输出的位置,logs包支持如下日志引擎:

  • console
    • 输出到命令行

    • logs.SetLogger(logs.AdapterConsole, `{"level":1,"color":true}`)

      • level 输出的日志级别

      • color 是否开启打印日志彩色打印(需环境支持彩色输出)

                          

  • file
    • 输出到文件

    • logs.SetLogger(logs.AdapterFile, `{"filename":"test.log"}`)

      • filename 保存的文件名

        maxlines 每个文件保存的最大行数,默认值 1000000

        maxsize 每个文件保存的最大尺寸,默认值是 1 << 28, //256 MB 2^28 1<< 3 2^3

        daily 是否按照每天 logrotate,默认是 true

        maxdays 文件最多保存多少天,默认保存 7 天

        rotate 是否开启 logrotate,默认是 true

        level 日志保存的时候的级别,默认是 Trace 级别

        perm 日志文件权限 4(读权限)2(写权限)1(执行权限)

  • multifile
    • 多文件日志写入,对号入座写入,比如test.error.log,err.debug.log

    • logs.SetLogger(logs.AdapterMultiFile, `{"filename":"test.log","separate":["emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"]}`)

      • 和file相比多了separate[`seprət`] 需要单独写入文件的日志级别,设置后命名类似 test.error.log

      • 注意:不要设置太多的级别,不然文件分类就太多了,不利于排查

  • smtp:日志告警
      • 邮件发送

      • logs.SetLogger(logs.AdapterMail,`{"username":"xxx@qq.com","password":"认证密码","host":"smtp.qq.com:587","fromAddress":"xxx@qq.com","sendTos":["xxx@qq.com"]}`)

        • username smtp 验证的用户地址

        • password smtp 验证密码

        • host SMTP服务器地址

          • QQ邮箱:SMTP服务器地址:smtp.qq.com(端口:587)

          • 雅虎邮箱: SMTP服务器地址:smtp.yahoo.com(端口:587)

          • 163邮箱:SMTP服务器地址:smtp.163.com(端口:25)

          • 126邮箱: SMTP服务器地址:smtp.126.com(端口:25)

          • 新浪邮箱: SMTP服务器地址:smtp.sina.com(端口:25)

        • fromAddress 发件人

          • 必须和前面认证的地址相同
        • sendTos 邮件需要发送的人,支持多个

        • subject 发送邮件的标题

        • level 日志发送的级别,默认是 Trace 级别

     

  • conn
    • 网络输出
      • logs.SetLogger(logs.AdapterConn, `{"net":"tcp","addr":":7020"}`)

        • reconnectOnMsg 是否每次链接都重新打开链接,默认是 false

          reconnect 是否自动重新链接地址,默认是 false

          net 发开网络链接的方式,可以使用 tcp、unix、udp 等

          addr 网络链接的地址

          level 日志保存的时候的级别,默认是 Trace 级别

 

  • ElasticSearch
    • 输出到 ElasticSearch

    • logs.SetLogger(logs.AdapterEs, {"dsn":"http://localhost:9200/","level":1})

  • 简聊
    • 输出到简聊

    • logs.SetLogger(logs.AdapterJianLiao, {"authorname":"xxx","title":"beego", "webhookurl":"https://jianliao.com/xxx", "redirecturl":"https://jianliao.com/xxx","imageurl":"https://jianliao.com/xxx","level":1})

  • slack
    • 输出到slack

    • logs.SetLogger(logs.AdapterSlack, {"webhookurl":"https://slack.com/xxx","level":1})

 

2.4、输出文件名和行号:默认为true

  • logs.EnableFuncCallDepth(true)

 

2.5、异步输出日志

  • 为了提升性能, 可以设置异步输出

    • logs.Async()
  • 异步输出允许设置缓冲 chan 的大小

    • logs.Async(1e3)

 

2.6、解决日志里记录文件名及行号不正确问题

  • logs.SetLogFuncCallDepth(3) // 默认值是4,显示的文件和行号不对,改成3就好了
  • 如果你的应用自己封装了调用 log 包,那么需要设置 SetLogFuncCallDepth,默认是 2,也就是直接调用的层级,如果你封装了多层,那么需要根据自己的需求进行调整.

 

三、logs包实战

复制代码
func main() {
    // 修改配置,解决日志输出的信息里文件和行号不正确问题,在这里配置只在当前的controller生效,所以要在main函数里配置
    logs.SetLogFuncCallDepth(3)

    // Console引擎设置日志级别的两种方式,全局生效需要在main函数里配置
    //logs.SetLogger(logs.AdapterConsole, `{"level":"LevelCritical","color":true}`)      // 这个配置不好用,需要验证
    //logs.SetLevel(logs.LevelCritical)

    // file日志引擎设置
    // logs.SetLogger(logs.AdapterFile, `{"filename":"logs/test-log.log"}`)

    // 多文件日志写入,区分打印(error级别以上的输出到error.log的日志里,error级别以下的输出到info日志里)
    logs.SetLogger(logs.AdapterMultiFile, `{"filename":"logs/beego-project-multilog.log","separate":["error", "info"]}`)
    logs.Error("emergency log")    // 紧急的
    logs.Error("alert log")            // 警告的
    logs.Error("critical log")      // 关键的
    logs.Error("error log")            // 错误日志
    logs.Info("warn log")              // 警告
    logs.Info("notice log")          // 通知
    logs.Info("info log")            // 信息
    logs.Info("debug log")            // debug日志

    beego.Run()
}
复制代码

 

四、封装日志模板

这里封装一个过程进度的日志模板,日志里需要记录如下几条信息:

  • 开始时间
  • 当前第几个
  • 总数
  • 已耗时
  • 结束时间

 

4.1、封装日志模板函数

复制代码
package log_template

import "fmt"

func LogProcess(start_time string, cur int, count int, use_time string, end_time string) string {
    return fmt.Sprintf("starttime: %s, current/count:%d/%d, usetime: %s, endtime: %s", start_time, cur, count, use_time, end_time)
}
复制代码

 

4.2、程序使用日志模板

复制代码
func (c *LogTemplateController) Get() {

    count := 7
    for i:=1;i<count;i++  {
        // 获取程序开始执行时间
        start_time := time.Now()
        start_time_str := start_time.Format("2006-01-02 15:04:05")

        // 模拟程序执行耗时
        time.Sleep(time.Second * 3)

        // 获取程序执行结束时间
        end_time := time.Now()
        end_time_str := end_time.Format("2006-01-02 15:04:05")

        cur := i      // 当前执行的程序
        count := count-1       // 总数

        // 获取程序执行耗时
        use_time := end_time.Sub(start_time).String()

        // 使用日志模板将以上参数加工成规定得字符串
        ret := log_template.LogProcess(start_time_str,cur,count,use_time,end_time_str)
        fmt.Println(ret)

        // 打印info级别的日志
        logs.Info(ret)

    }


    c.TplName = "success.html"
}
复制代码

 

4.3、查看日志输出

复制代码
2020/10/09 17:02:45.699 [I] [log_template_controller.go:32]  starttime: 2020-10-09 17:02:42, current/count:1/6, usetime: 3.0001097s, endtime: 2020-10-09 17:02:45
2020/10/09 17:02:48.699 [I] [log_template_controller.go:32]  starttime: 2020-10-09 17:02:45, current/count:2/6, usetime: 3.0002995s, endtime: 2020-10-09 17:02:48
2020/10/09 17:02:51.700 [I] [log_template_controller.go:32]  starttime: 2020-10-09 17:02:48, current/count:3/6, usetime: 3.0003854s, endtime: 2020-10-09 17:02:51
2020/10/09 17:03:30.652 [I] [log_template_controller.go:32]  starttime: 2020-10-09 17:02:51, current/count:4/6, usetime: 3.0007772s, endtime: 2020-10-09 17:02:54
2020/10/09 17:03:33.656 [I] [log_template_controller.go:32]  starttime: 2020-10-09 17:03:30, current/count:5/6, usetime: 3.000565s, endtime: 2020-10-09 17:03:33
2020/10/09 17:03:36.658 [I] [log_template_controller.go:32]  starttime: 2020-10-09 17:03:33, current/count:6/6, usetime: 3.000843s, endtime: 2020-10-09 17:03:36
复制代码