前言

日志服务是应用程序里不可缺少的一个模块, 在golang里也有不少比较优秀的日志服务框架,比如很多项目都是用的Zap,就是比较常用的golang的日志框架,不过深深的java的使用经历,所以在使用其zap起来,总是觉得不是那么的舒服, 所以在自己的项目里都是使用那个自己封装的log4go的日志包, 注意这里并没有从框架的模式上去进行实现, 所以我这里也称之为一个简洁的golang的日志包。

说他简洁,功能并不简单

简洁,核心代码只有10K左右,但是功能并不简单。

配置文件

配置文件log4o.xml, 也支持json格式的配置文件, 通过配置log4go.xml文件即可定义需要使用的日志服务内容。

一起看看配置文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appender enabled="true" name="console">
    <type>console</type>
    <pattern>[%D %T %m] [%L][%l] (%S) %M</pattern>
    <!-- level is (:?FINEST|FINE|DEBUG|TRACE|INFO|WARNING|ERROR) -->
  </appender>
  <appender enabled="true" name="file">
    <type>file</type>
    <pattern>[%D %T %m] [%L][%l] (%S) %M</pattern>
    <property name="filename">test.log</property>
    <!--
       %T - Time (15:04:05 MST)
       %t - Time (15:04)
       %D - Date (2006/01/02)
       %d - Date (01/02/06)
       %L - Level (FNST, FINE, DEBG, TRAC, WARN, EROR, CRIT)
       %S - Source
       %M - Message
       It ignores unknown format strings (and removes them)
       Recommended: "[%D %T] [%L] (%S) %M"
    -->
    <property name="rotate">false</property> <!-- true enables log rotation, otherwise append -->
    <property name="maxsize">0M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 -->
    <property name="maxlines">0K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands -->
    <property name="daily">true</property> <!-- Automatically rotates when a log message is written after midnight -->
  </appender>
  <appender enabled="true" name="testfile">
    <type>file</type>
    <pattern>[%D %T %m] [%L][%l] (%S) %M</pattern>
    <property name="filename">trace.xml</property>
    <property name="rotate">false</property> <!-- true enables log rotation, otherwise append -->
    <property name="maxsize">100M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 -->
    <property name="maxlines">6K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands -->
    <property name="daily">false</property> <!-- Automatically rotates when a log message is written after midnight -->
  </appender>
  <appender enabled="true" name="logstash"><!-- enabled=false means this logger won't actually be created -->
    <type>socket</type>
    <pattern>[%D %T %m] [%L][%l] (%S) %M</pattern>
    <property name="endpoint">192.168.56.1:12124</property> <!-- recommend UDP broadcast -->
    <property name="protocol">tcp</property> <!-- tcp or udp -->
    <property name="retry">-1</property> <!-- 断线重连,设置为负数,反复重连,设置为正数,重连测试后失败 -->
    <property name="interval">30</property> <!-- 失败重连的间隔时间,默认30秒 -->
    <property name="check">false</property> <!-- 启动日志是否检查连接成功,如果检查,不成功会失败 -->
  </appender>
  <!-- 这个就是自定义的一个logger -->
  <!-- 输出级别是info级别及以上的日志,不要怕,StreamOperateFile已经过滤,只输出info级别的日志 -->
  <!-- additivity 这个默认是true,即继承父类 root logger -->
  <!-- 也就是说,你的这个日志也会在root的logger里面输出的,我这里配置false,就是不继承,各走各的。 -->
  <!-- appender-ref 也就是说这个logger的输出目的地是哪里,ref就是关联到上面声明的一个file,一个console -->
  <logger name="Sample">
    <level>info</level>
    <appender-ref ref="file" />
    <appender-ref ref="console" />
  </logger>

  <logger name="Demo">
    <level>info</level>
    <appender-ref ref="console" />
    <appender-ref ref="file" />
  </logger>

  <!-- 输出级别是info级别及以上的日志,下面的ref关联的两个appender没有filter设置,所以,info及以上的日志都是会输出到这2个appender的 -->
  <root>
    <level>info</level>
    <appender-ref ref="console" />
    <appender-ref ref="logstash" />
  </root>

</configuration>

配置文件是不是很熟悉,做过java的开发人员对个日志的配置文件就会相当的熟悉了, 这里基本上和java里的log4j和logback的配置项非常的相近了, 

appender对应着一种logAppend的实现, 目前log4go里,支持Console,Fille,Channel,TCP,UCP这样几种方式。  其中的TCP,UDP,Channel的Append主要是考虑日志对外Logstach, Kafka, Zipkin的需要的相关扩展。

使用简单

使用非常简单, 在配置文件里,配置好Append,配置好需要日志的级别,日志的TAG, 通过几行代码就可以实现日志的使用

## 引入包

import
(	"github.com/gohutool/log4go"
	"testing"
	"time"
)

# 定义日志对象
var logger = log4go.LoggerManager.GetLogger("com.hello")

#使用日志
log4go.LoggerManager.InitWithXML("./example.xml")
logger.Info("hello")
logger.Info("hello")
time.Sleep(1 * time.Second)
logger.Error("hello")

不同的logger实例对象,可以有各自不同的日志级别, log4go的日志是异步协程进行实现的,所以在使用Log4go进行日志处理时,对主业务的性能并行完成,不影响主业务处理的处理时间。

l

=== RUN   TestLoggerExample
[2022/06/17 11:17:59 CST 299] [INFO][com.hello] (github.com/gohutool/log4go/examples.TestLoggerExample:73) hello
[2022/06/17 11:17:59 CST 299] [INFO][com.hello] (github.com/gohutool/log4go/examples.TestLoggerExample:72) hello
[2022/06/17 11:18:00 CST 299] [EROR][com.hello] (github.com/gohutool/log4go/examples.TestLoggerExample:75) hello
--- PASS: TestLoggerExample (4.00s)
PASS

Debugger finished with the exit code 0

UDP相关配置

<appender enabled="true" name="logstash"><!-- enabled=false means this logger won't actually be created -->
  <type>socket</type>
  <pattern>[%D %T %m] [%L][%l] (%S) %M</pattern>
  <property name="endpoint">192.168.56.1:12124</property> <!-- recommend UDP broadcast -->
  <property name="protocol">udp</property> <!-- tcp or udp -->
</appender>

 

TCP相关配置

<appender enabled="true" name="logstash"><!-- enabled=false means this logger won't actually be created -->
  <type>socket</type>
  <pattern>[%D %T %m] [%L][%l] (%S) %M</pattern>
  <property name="endpoint">192.168.56.1:12124</property> <!-- recommend UDP broadcast -->
  <property name="protocol">tcp</property> <!-- tcp or udp -->
  <property name="retry">-1</property> <!-- 断线重连,设置为负数,反复重连,设置为正数,重连测试后失败 -->
  <property name="interval">30</property> <!-- 失败重连的间隔时间,默认30秒 -->
  <property name="check">false</property> <!-- 启动日志是否检查连接成功,如果检查,不成功会失败 -->
</appender>
结语

如标题所说, Log4go的实现并不是以框架的方式实现,所以功能上更多的偏向于如何去处理各种日志需要的实现上,同时基于微服务里的日志集中处理的实际场景,实现了channel,TCP,UDP方式的日志处理模式, 是一个专门的日志包工具。 可以在github里搜索gohutool/log4go,