go语言syslog日志接收

go语言syslog日志接收

  1. code
  2. 5 months ago
  3. 6 min read

Syslog是一种用于系统日志管理的标准协议,它能够帮助用户收集、存储和分析系统产生的日志信息。通过Syslog,用户可以将来自不同设备和应用程序的日志信息集中到一个地方,并进行统一管理和分析,有助于故障排查、安全监控和性能优化等工作, 本文将讲解基本的syslog使用,以及如何用go直接接收远端的syslog日志。

基本使用

配置syslog的服务端和客户端。在Linux系统中,常用的Syslog服务端包括rsyslog和syslog-ng。下面以rsyslog为例,介绍其配置方法。

配置Syslog服务端

Syslog服务端负责接收和存储来自各个设备和应用程序的日志信息。

  1. 安装rsyslog 编辑rsyslog配置文件/etc/rsyslog.conf,配置Syslog服务端接收和存储日志的规则。可以通过配置文件指定日志的存储路径、格式、过滤规则等内容。
# /etc/rsyslog.conf configuration file for rsyslog
#
# For more information install rsyslog-doc and see
# /usr/share/doc/rsyslog-doc/html/configuration/index.html
#
# Default logging rules can be found in /etc/rsyslog.d/50-default.conf


#################
#### MODULES ####
#################

module(load="imuxsock") # provides support for local system logging
#module(load="immark")  # provides --MARK-- message capability

# provides UDP syslog reception
module(load="imudp")
input(type="imudp" port="514")

# provides TCP syslog reception
#module(load="imtcp")
#input(type="imtcp" port="514")

# provides kernel logging support and enable non-kernel klog messages
module(load="imklog" permitnonkernelfacility="on")

###########################
#### GLOBAL DIRECTIVES ####

可以通过取消module的注释来开启UDP监听,如上。 重启生效

systemctl restart rsyslog

查看端口监听,发现新启了udp协议的514端口

➜  ~ netstat -ntlpu
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
udp        0      0 127.0.0.1:323           0.0.0.0:*                           2029178/chronyd
udp        0      0 0.0.0.0:514             0.0.0.0:*                           4062306/rsyslogd
udp6       0      0 ::1:323                 :::*                                2029178/chronyd
udp6       0      0 :::514                  :::*                                4062306/rsyslogd

配置Syslog客户端

编辑rsyslog配置文件/etc/rsyslog.conf,配置Syslog客户端发送日志的规则。可以通过配置文件指定要发送的日志信息、Syslog服务端的地址和端口等内容。

示例配置文件/etc/rsyslog.conf部分内容如下

# Send log messages to a remote syslog server *.* @192.168.1.100:514

重启rsyslog服务使配置生效:

sudo systemctl restart rsyslog

查看Syslog日志

Syslog服务端接收并存储日志信息后,用户可以通过命令行工具或日志管理工具查看日志内容。在Linux系统中,可以使用以下命令查看Syslog日志:

sudo tail -f /var/log/syslog

上述命令将实时显示/var/log/syslog文件的最新内容,其中包含了Syslog服务端接收的日志信息

分析Syslog日志

Syslog日志可能包含大量的信息,用户需要进行分析和筛选,以便找出关键信息。用户可以使用grep命令结合正则表达式来筛选和查找日志信息。

sudo grep "error" /var/log/syslog

上述命令将过滤出/var/log/syslog文件中包含”error”关键词的日志信息,帮助用户快速定位

配置Syslog日志旋转

Syslog日志文件可能会不断增长,占用大量磁盘空间。为了避免这种情况,用户可以配置Syslog日志的定时轮转,将旧的日志信息压缩或移动到其他位置,以释放磁盘空间。在Linux系统中,可以使用logrotate工具来实现Syslog日志的定时轮转。

编辑logrotate配置文件/etc/logrotate.d/rsyslog,配置Syslog日志的轮转规则。可以通过配置文件指定轮转的频率、保留的日志文件数量等内容。

示例配置文件/etc/logrotate.d/rsyslog部分内容如下:

/var/log/syslog

{

rotate 7

weekly

missingok

notifempty

compress

delaycompress

sharedscripts

postrotate

systemctl restart rsyslog

endscript

}

上述配置中,指定了每周轮转一次日志文件,保留7个旧的日志文件,并在轮转后重启rsyslog服务。

最后,使用logrotate命令手动轮转Syslog日志文件:

sudo logrotate /etc/logrotate.conf

golang接收syslog日志

根据如上的配置,我们发现还是比较麻烦的。特别是已经在使用golang程序接收各种日志的话。 我们使用了go-syslog这个库。

package sealsuite

import (
	"bytes"
	"encoding/json"
	"log"
	"net/http"

	"gopkg.in/mcuadros/go-syslog.v2"
)

func main() {
    //初始化了一个map[string]interface{} channel
	channel := make(syslog.LogPartsChannel)
	handler := syslog.NewChannelHandler(channel)

	server := syslog.NewServer()
	server.SetFormat(syslog.RFC5424)
	server.SetHandler(handler)
	server.ListenUDP("0.0.0.0:5144")

	server.Boot()

	go func(channel syslog.LogPartsChannel) {
		for logParts := range channel {
			//log.Println(logParts)

			// 解析syslog消息
			if logParts["message"] != nil {
				message := logParts["message"].(string)
				log.Println(message)
				json.Marshal(message)
				//http发送
				url := "http://127.0.0.1/xxx"
				req, err := http.NewRequest("POST", url, bytes.NewReader([]byte(message)))
				if err != nil {
					log.Println(err)
				}
				client := &http.Client{}
				resp, err := client.Do(req)
				if err != nil {
					log.Println("Error sending HTTP request:", err)
					return
				}
				defer resp.Body.Close()
			}

		}
	}(channel)

	server.Wait()
}
Code Golang