参考:Docker 日志整合 syslog - 简书 (jianshu.com)
创建rsyslog容器
配置文件 rsyslog.conf
# /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
#若启用UDP进行传输,则取消下面两行的注释
#module(load="imudp")
#input(type="imudp" port="514")
# provides TCP syslog reception
#若启用TCP进行传输,则取消下面两行的注释
#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 ####
###########################
#
# Use traditional timestamp format.
# To enable high precision timestamps, comment out the following line.
#
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
# Filter duplicated messages
$RepeatedMsgReduction on
#
# Set the default permissions for all log files.
#
$FileOwner syslog
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022
$PrivDropToUser syslog
$PrivDropToGroup syslog
#
# Where to place spool and state files
#
$WorkDirectory /var/spool/rsyslog
#
# Include all config files in /etc/rsyslog.d/
#
$IncludeConfig /etc/rsyslog.d/*.conf
Dockerfile
FROM ubuntu:20.04
# 设置环境变量
ENV DEBIAN_FRONTEND=noninteractive
# 更新包列表并安装 rsyslog
RUN apt-get update && \
apt-get install -y rsyslog && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 启动 rsyslog 服务
CMD ["rsyslogd", "-n"]
docker-compose.yml
version: '3.8'
services:
rsyslog:
build: .
container_name: my-rsyslog-container
ports:
- "514:514/udp"
- "514:514/tcp" # 根据配置文件开放的端口和协议
volumes:
- ./path/to/your/log-dir:/var/log #挂载接收到的数据
- ./rsyslog.conf:/etc/rsyslog.conf # 挂载宿主机的 rsyslog.conf 根据配置位置修改
restart: unless-stopped
docker-compose启动
sudo docker-compose up --build -d
测试rsyslog服务器启动
#打开终端并运行以下命令:
sudo docker inspect my-rsyslog-container|grep "IP" #查看容器IP
#发送 UDP 日志 这里IP修改成容器IP
logger -n 172.17.0.6 -P 514 "This is a test log message over UDP"
#发送 TCP 日志
logger -n 172.17.0.6 -P 514 -T "This is a test log message over TCP"
#进入容器并查看日志文件来验证是否成功接收到日志。
sudo docker exec -it my-rsyslog-container sh
#cat /var/log/syslog
#检查 /var/log/syslog 文件中是否包含您发送的日志消息。如果一切正常,您应该能看到类似于以下内容的输出:
This is a test log message over UDP
日志转发到rsyslog服务器
参考:Docker 日志整合 syslog - 简书 (jianshu.com)
方法一:利用Docker容器日志连接
下面启动容器,指定使用 syslog:
# 先删除之前的容器
$ docker stop nginx
$ docker rm nginx
# 启动
$ docker run \
-d \
-p 80:80 \
--name nginx \
--log-driver syslog \
--log-opt syslog-address=tcp://localhost:514 \
nginx
#进入容器并查看日志文件来验证是否成功接收到日志。
sudo docker exec -it my-rsyslog-container sh
$cat /var/log/all.log 或
$ tail -f /var/log/syslog
如果系统中启动了多个容器,每个容器的日志都输出到 syslog,就比较混乱了,这时我们可以在日志中指定容器tag,从而方便识别出相应的日志。
$ docker run \
-d \
-p 80:80 \
--name nginx \
--log-driver syslog \
--log-opt syslog-address=tcp://localhost:514 \
--log-opt tag="nginx" \
nginx
tag还可以更精确一点,因为docker提供了丰富的模板标签:
{{.ID}}:容器ID的前12个字符
{{.FullID}}:容器ID的完整名称
{{.Name}}:容器名称
{{.ImageID}}:容器镜像ID的前12个字符
{{.ImageFullID}}:容器镜像ID的完整名称
{{.ImageName}}:容器镜像名称
{{.DaemonName}}:Docker守护进程名称(名为docker)
示例:
$ docker run \
-d \
-p 80:80 \
--name nginx \
--log-driver syslog \
--log-opt syslog-address=tcp://localhost:514 \
--log-opt tag="{{.ImageName}}/{{.Name}}/{{.ID}}" \
nginx
方法二:修改Nginx配置文件实现转发
添加配置内容到 nginx.conf
error_log syslog:server=localhost:514,facility=local7,tag=nginx_error,severity=error;
access_log syslog:server=localhost:514,facility=local7,tag=nginx_access,severity=info;
nginx.conf
# cat /etc/nginx/nginx.conf
#添加 error_log syslog:server=localhost:514,facility=local7,tag=nginx_error,severity=error;
# access_log syslog:server=localhost:514,facility=local7,tag=nginx_access,severity=info;
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
error_log syslog:server=localhost:514,facility=local7,tag=nginx_error,severity=error;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
access_log syslog:server=localhost:514,facility=local7,tag=nginx_access,severity=info;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
结果如图

方法三:golang程序监听文件实现转发
1.首先在本地尝试发送数据给rsyslog容器

main.go
package main
import (
"fmt"
"log"
"log/syslog"
)
func main() {
// 连接到本地的 syslog 服务器,使用 TCP 协议
sysLog, err := syslog.Dial("tcp", "localhost:514", syslog.LOG_INFO, "myApp")
if err != nil {
log.Fatal(err)
}
defer sysLog.Close()
// 发送一条紧急级别的日志消息
sysLog.Emerg("An emergency message via TCP")
// 发送一条信息级别的日志消息
sysLog.Info("This is an informational message via TCP")
msg := fmt.Sprintf("A formatted message with number %d", 42)
sysLog.Info(msg)
}
2.读取本地文件到rsyslog容器
package main
import (
"bufio"
"log"
"log/syslog"
"os"
)
func main() {
// 连接到本地的 syslog 服务器,使用 TCP 协议
sysLog, err := syslog.Dial("tcp", "localhost:514", syslog.LOG_INFO, "nginx")
if err != nil {
log.Fatal(err)
}
defer sysLog.Close()
// 打开本地日志文件
logFile, err := os.Open("./access.log")
if err != nil {
log.Fatal(err)
}
defer logFile.Close()
// 创建一个新的 bufio 读取器来读取日志文件
reader := bufio.NewReader(logFile)
// 逐行读取日志文件并发送到 rsyslog 服务器
for {
line, err := reader.ReadString('\n')
if err != nil {
// 如果读取到文件末尾或发生错误,则退出循环
log.Printf("读取到文件末尾或读取日志时出错: %v", err)
break
}
// 发送日志行到 rsyslog 服务器
if err := sysLog.Info(line); err != nil {
log.Printf("发送日志时出错: %v", err)
break
}
}
}
3.golang程序监听文件实现转发
main.go
package main
import (
"bufio"
"errors"
"io"
"log"
"log/syslog"
"os"
"time"
)
func main() {
// 这里连接到本地的syslog服务器,实际根据配置文件开放的协议端口修改,localhost改成rsyslog服务器地址,syslog.LOG_INFO改成实际对应的日志级别, 修改tag成实际日志来源名称
sysLog, err := syslog.Dial("tcp", "localhost:514", syslog.LOG_INFO, "nginx_test")
#转发前"GET /group1/M00 HTTP/1.11estretestgtsttttt1" 400 173 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0"
#syslog接收后" Oct 11 18:56:19 VM-4-7-ubuntu nginx_test[986243]: 11.42.240.165 - - [14/May/2024:23:13:27 +0800] "GET /group1/M00 HTTP/1.11estretestgtsttttt1" 400 173 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125."0""
if err != nil {
log.Fatalf("无法连接到 syslog 服务器: %v", err)
}
defer sysLog.Close()
// 打开本地日志文件 视情况填写成需要的日志地址
logFile, err := os.Open("./access.log")
if err != nil {
log.Fatalf("无法打开日志文件: %v", err)
}
defer logFile.Close()
reader := bufio.NewReader(logFile)
for {
// 读取日志文件的一行
line, err := reader.ReadString('\n')
// 处理读取错误
if err != nil {
if errors.Is(err, io.EOF) {
log.Println("已到达文件末尾 (EOF)")
} else {
log.Printf("读取日志时出错: %v", err)
}
time.Sleep(5 * time.Second)
continue
}
// 发送日志行到 rsyslog 服务器
if err := sendLog(sysLog, line); err != nil {
log.Printf("发送日志时出错: %v", err)
sysLog, err = reconnectSyslog()
if err != nil {
log.Fatalf("重新连接到 syslog 服务器失败: %v", err)
}
}
}
}
// 发送日志到 syslog
func sendLog(sysLog *syslog.Writer, line string) error {
return sysLog.Info(line)
}
// 重新连接到 syslog 服务器
func reconnectSyslog() (*syslog.Writer, error) {
return syslog.Dial("tcp", "localhost:514", syslog.LOG_INFO, "nginx_test")
}
#运行main .go
go run main.go
#进入容器并查看日志文件来验证是否成功接收到日志。
sudo docker exec -it my-rsyslog-container sh
#cat /var/log/syslog

1537

被折叠的 条评论
为什么被折叠?



