目标是实现在kylin-server-10-sp2操作系统实现udp514的syslog接收以及将syslog写入mysql数据库,具体安装配置及优化过程如下:

准备好安装介质Kylin-Server-10-SP2-x86-Release-Build09-20210524.iso,安装Kylin-server-10-sp2操作系统。
[root@localhost ~]# nkvers
############## Kylin Linux Version #################
Release:
Kylin Linux Advanced Server release V10 (Sword)
Kernel:
4.19.90-24.4.v2101.ky10.x86_64
Build:
Kylin Linux Advanced Server
release V10 (SP2) /(Sword)-x86_64-Build09/20210524
#################################################
[root@localhost ]# rpm -qa | grep -E 'mariadb|mysql'
mariadb-common-10.3.9-9.p02.ky10.x86_64
pcp-pmda-mysql-4.1.3-12.ky10.x86_64
mariadb-devel-10.3.39-1.p01.01.ky10.x86_64
mariadb-10.3.9-9.p02.ky10.x86_64
python2-mysqlclient-1.3.12-8.ky10.x86_64
qt5-qtbase-mysql-5.11.1-11.p01.ky10.x86_64
mariadb-connector-c-devel-3.0.6-7.ky10.x86_64
mariadb-errmessage-10.3.9-9.p02.ky10.x86_64
mariadb-server-10.3.9-9.p02.ky10.x86_64
# 启动 MariaDB
systemctl start mariadb
# 设置开机自启
systemctl enable mariadb
# 检查状态
systemctl status mariadb
第一次登录可能无需密码:
sudo mysql
然后在 MariaDB 里:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'root1234';
FLUSH PRIVILEGES;
EXIT;
这样就设置了 root 密码。
– 登录
mysql -u root -p
-- 创建数据库
CREATE DATABASE syslogdb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- 创建用户
CREATE USER 'syslog'@'localhost' IDENTIFIED BY 'syslog';
-- 授权
GRANT ALL PRIVILEGES ON syslogdb.* TO 'syslog'@'localhost';
FLUSH PRIVILEGES;
-- 允许所有登录
UPDATE mysql.user SET Host='%' WHERE User='syslog' AND Host='localhost';
FLUSH PRIVILEGES;
GRANT ALL PRIVILEGES ON syslogdb.* TO 'syslog'@'%';
FLUSH PRIVILEGES;
EXIT;
现在 syslog-ng 就可以用 syslog 用户连接 syslogdb 来写入日志。
mysql -u syslog -p syslogdb
如果能进入数据库,就可以开始创建表或者让 syslog-ng 自动写入了。
ALTER USER 'root'@'localhost' IDENTIFIED BY 'root1234';
UPDATE mysql.user SET Host='%' WHERE User='root' AND Host='localhost';
FLUSH PRIVILEGES;
CREATE USER 'root'@'%' IDENTIFIED BY 'YourStrongPassword';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
这里 % 表示任意主机。
检查防火墙(Kylin V10 用 firewalld 或 iptables)允许 3306 端口访问:
firewall-cmd --permanent --add-port=3306/tcp
firewall-cmd --reload
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
service iptables save
[mysqld]
bind-address=0.0.0.0
然后重启 MariaDB:
systemctl restart mariadb
现在你就可以从远程主机用 root@ 登录 MariaDB 了:
mysql -h 192.168.183.137 -u root -p
-- 1. 使用数据库
USE syslogdb;
-- 2. 创建日志表
CREATE TABLE IF NOT EXISTS system_logs (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
received_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
hostname VARCHAR(255) DEFAULT NULL,
program VARCHAR(255) DEFAULT NULL,
pid INT DEFAULT NULL,
message TEXT,
facility INT DEFAULT NULL,
severity INT DEFAULT NULL,
syslog_pri INT DEFAULT NULL,
version INT DEFAULT NULL,
structured_data TEXT DEFAULT NULL,
warn_sended_flag TINYINT DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPRESSED;
-- 3. 可选索引,便于按时间、主机、程序查询
CREATE INDEX idx_received_at ON system_logs(received_at);
CREATE INDEX idx_hostname ON system_logs(hostname);
CREATE INDEX idx_program ON system_logs(program);
CREATE INDEX idx_severity ON system_logs(severity);
CREATE INDEX idx_flag ON system_logs(warn_sended_flag);
--按天分区
ALTER TABLE system_logs DROP PRIMARY KEY, ADD PRIMARY KEY (id, received_at);
ALTER TABLE system_logs
PARTITION BY RANGE (TO_DAYS(received_at)) (
PARTITION p20251130 VALUES LESS THAN (TO_DAYS('2025-12-01')),
PARTITION p20251201 VALUES LESS THAN (TO_DAYS('2025-12-02')),
PARTITION pmax VALUES LESS THAN MAXVALUE
);
--删除旧日志非常快:
ALTER TABLE system_logs DROP PARTITION p20251130;
最近 10000 条
SELECT * FROM system_logs
ORDER BY id DESC
LIMIT 10000;
✔ 走主键(非常快)
✔ 不需要按时间排序(时间索引不如 ID 快)
SELECT *
FROM system_logs
WHERE message LIKE '%Failed password%'
AND message LIKE '%192.168.1.10%'
AND warn_sended_flag = 0
ORDER BY id DESC
LIMIT 3;
日志来源主要是:
Linux 系统日志(systemd-journald → syslog-ng)
sshd 登录
su / sudo
各类 service
应用打印的 syslog
这些 都不是 RFC5424,所以:
✔ version → 是 NULL
✔ structured_data → 是 NULL
yum install -y
gcc gcc-c++ make autoconf automake libtool
pkgconfig
glib2 glib2-devel
openssl openssl-devel
libevent libevent-devel
json-c json-c-devel
flex bison
pcre pcre-devel
wget tar
cd /usr/local/src
wget https://github.com/syslog-ng/syslog-ng/releases/download/syslog-ng-4.7.1/syslog-ng-4.7.1.tar.gz -O syslog-ng.tar.gz
tar -xf syslog-ng.tar.gz
cd syslog-ng-4.7.1
# MySQL 相关依赖
yum install -y mariadb-devel || yum install -y mysql-devel
yum install -y libcurl-devel
yum install -y python3
yum install -y python3-devel
# 用以上可以测试venv是否安装成功
# python3 -m venv test_venv
########################################
# syslog-ng 4.7 优化版:internal 完全隔离
########################################
@version: 4.7
@include "scl.conf"
@module timestamp
@module afsql
@module affile
@module afsocket
###############################
# 全局选项
###############################
options {
chain_hostnames(no);
use_dns(no);
use_fqdn(no);
time_reopen(10);
log_fifo_size(10000);
keep_hostname(yes);
log_msg_size(65536);
stats(freq(3600));
};
# error 级别
filter f_error { level(err..emerg); };
# info 级别
filter f_info { level(info..notice); };
###############################
# 来源
###############################
source s_system { system(); };
source s_internal { internal(); };
source s_udp { udp(port(514)); };
source s_tcp { tcp(port(514)); };
###############################
# 写入 MySQL(带磁盘缓冲)
###############################
destination d_mysql {
sql(
type(mysql)
host("localhost")
username("syslog")
password("syslog")
database("syslogdb")
table("system_logs")
columns(
"received_at", "hostname", "program", "pid",
"message", "facility", "severity", "syslog_pri"
)
values(
"$R_YEAR-$R_MONTH-$R_DAY $R_HOUR:$R_MIN:$R_SEC",
"$HOST",
"$PROGRAM",
"$PID",
"$MSGONLY",
"$FACILITY_NUM",
"$LEVEL_NUM",
"$PRI"
)
batch-lines(100)
template_escape(no)
disk-buffer(
dir("/var/lib/syslog-ng/disk-buffer")
disk-buf-size(50M)
reliable(yes)
)
);
};
# 文件 destination
destination d_info_file {
file("/var/log/syslog-ng/info.log"
create_dirs(yes)
owner("root") group("root") perm(0644));
};
# error 日志写 MySQL
log {
source(s_udp);
filter(f_error);
destination(d_mysql);
};
# info 日志写文件
log {
source(s_udp);
filter(f_info);
destination(d_info_file);
};
###############################
# internal 日志写文件(不进入 MySQL)
###############################
destination d_internal_log {
file("/var/log/syslog-ng/internal.log"
create-dirs(yes)
owner("root") group("root") perm(0644)
);
};
log {
source(s_internal);
destination(d_internal_log);
flags(final);
};
###############################
# 错误日志备份(仅 err,不含 internal)
###############################
destination d_backup {
file("/var/log/syslog-ng/backup.log"
create-dirs(yes)
owner("root") group("root") perm(0644)
);
};
log {
source(s_system);
source(s_udp);
source(s_tcp);
filter { level(err); };
destination(d_backup);
};
###############################
# syslog-ng 统计日志
###############################
destination d_syslog_ng_stats {
file("/var/log/syslog-ng/stats.log"
owner("root") group("root") perm(0644)
create_dirs(yes)
);
};
log {
source(s_internal);
destination(d_syslog_ng_stats);
flags(final);
};
cd /usr/local/src
wget http://deb.debian.org/debian/pool/main/libd/libdbi/libdbi_0.9.0.orig.tar.gz
tar xf libdbi_0.9.0.orig.tar.gz
cd libdbi-0.9.0
./configure
make -j4
make install
ln -s /usr/local/include/dbi/dbi.h /usr/include/dbi.h
cd /usr/local/src
wget http://deb.debian.org/debian/pool/main/libd/libdbi-drivers/libdbi-drivers_0.9.0.orig.tar.gz
tar xf libdbi-drivers_0.9.0.orig.tar.gz
cd libdbi-drivers-0.9.0
./configure --with-mysql --disable-static
make -j4
make install
cp /usr/local/lib/dbd/libdbdmysql.so /usr/local/lib/syslog-ng/
export LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib/dbd:$LD_LIBRARY_PATH
echo "/usr/local/lib" > /etc/ld.so.conf.d/local.conf
ldconfig
echo "/usr/local/lib/syslog-ng" > /etc/ld.so.conf.d/syslog-ng.conf
ldconfig
cd /usr/local/src/syslog-ng-4.7.1
CPPFLAGS="-I/usr/local/include/dbi" LDFLAGS="-L/usr/local/lib" ./configure PYTHON=/usr/bin/python3 --enable-dbi --with-mysql
make -j4
make install
# /usr/local/sbin/syslog-ng -F -f /usr/local/etc/syslog-ng.conf -dv
syslog-ng: The -d/--debug option no longer implies -e/--stderr, if you want to redirect internal() source to stderr please also include -e/--stderr option
# 更详细
# /usr/local/sbin/syslog-ng -F -f /usr/local/etc/syslog-ng.conf -dve
/usr/local/sbin/syslog-ng -F -f /usr/local/etc/syslog-ng.conf
-F :前台运行(方便调试)
-f :指定配置文件路径
你可以后台运行:
nohup /usr/local/sbin/syslog-ng -F -f /usr/local/etc/syslog-ng.conf &
/usr/local/sbin/syslog-ng -F
tail -f /var/log/syslog-ng/internal.log
tail -f /var/log/syslog-ng/backup.log
[root@localhost ~]# syslog-ng --version
syslog-ng 4 (4.7.1)
Config version: 4.2
Installer-Version: 4.7.1
Revision:
Compile-Date: Nov 30 2025 21:44:02
Module-Directory: /usr/local/lib/syslog-ng
Module-Path: /usr/local/lib/syslog-ng
Include-Path: /usr/local/share/syslog-ng/include
Available-Modules: csvparser,timestamp,correlation,disk-buffer,examples,tfgetent,graphite,hook-commands,http,json-plugin,kvformat,linux-kmsg-format,map-value-pairs,pseudofile,mod-python,secure-logging,stardate,syslogformat,sdjournal,system-source,tags-parser,xml,regexp-parser,rate-limit-filter,metrics-probe,cloud_auth,basicfuncs,cryptofuncs,afstomp,appmodel,azure-auth-header,add-contextual-data,affile,afprog,afsocket,afsql,cef,afuser,confgen
Enable-Debug: off
Enable-GProf: off
Enable-Memtrace: off
Enable-IPv6: on
Enable-Spoof-Source: off
Enable-TCP-Wrapper: off
Enable-Linux-Caps: off
Enable-Systemd: on
[root@localhost ~]# logger -n 127.0.0.1 -P 514 "Hello SyslogNG Test"
syslog-ng控制台有以下日志
[2025-11-30T22:16:24.340855] Running SQL query; query=‘INSERT INTO system_logs (received_at, hostname, program, pid, message, facility, severity, syslog_pri) VALUES (‘2025-11-30 22:16:24’, ‘127.0.0.1’, ‘1’, NULL, ‘2025-11-30T22:16:24.340250+08:00 localhost.localdomain root - - [timeQuality tzKnown=“1” isSynced=“1” syncAccuracy=“228050”] Hello SyslogNG Test’, 1, 5, ‘13’)’
查mysql数据库有

logger -n 127.0.0.1 -P 514 "Hello SyslogNG Test"
默认发送的是 info 级别,而你配置的 MySQL 写入是 error…emerg 级别,所以不会写入数据库。
发送 error 或更高等级日志
使用 -p 选项指定 facility 和 severity,例如:
logger -n 127.0.0.1 -P 514 -p user.err "Hello SyslogNG Test - error level"
user 是 facility,可随意选一个(通常选 user 或 local0…local7)
err 是 severity(优先级),可用值:
关键字 描述 数字
emerg 系统不可用 0
alert 必须立即处理 1
crit 严重 2
err 错误 3
warning 警告 4
notice 注意 5
info 信息 6
debug 调试 7
所以只要 severity >= err 就会进入 MySQL。
logger -n 127.0.0.1 -P 514 -p user.err "This is an error log - should go to MySQL"
logger -n 127.0.0.1 -P 514 -p user.crit "This is a critical log"
logger -n 127.0.0.1 -P 514 -p user.info "Just info - won't go to MySQL"
import re
import time
import subprocess
LOG_FILE = "/var/log/syslog-ng/info.log"
# 正则提取登录失败的 IP
FAIL_PATTERN = re.compile(
r"Failed password for .* from (d+.d+.d+.d+)"
)
# 计数池
fail_count = {}
# 告警发送函数
def send_alert(ip, count):
print(f"[ALERT] {ip} 登录失败 {count} 次!")
# TODO: 可以在这里调用你的邮件/微信通知函数
# send_mail(...)
# send_wechat(...)
# send_qq(...)
def follow(log_file):
""" 类似 tail -F 行为 """
process = subprocess.Popen(
["tail", "-F", log_file],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
while True:
line = process.stdout.readline()
if not line:
time.sleep(0.1)
continue
yield line
if __name__ == "__main__":
print(f"监控文件:{LOG_FILE}")
for line in follow(LOG_FILE):
match = FAIL_PATTERN.search(line)
if match:
ip = match.group(1)
fail_count[ip] = fail_count.get(ip, 0) + 1
print(f"[INFO] {ip} 第 {fail_count[ip]} 次失败")
if fail_count[ip] == 3:
send_alert(ip, fail_count[ip])
logger -n 127.0.0.1 -P 514 “Failed password for root from 127.0.0.1”
logger -n 127.0.0.1 -P 514 “Failed password for root from 127.0.0.1”
logger -n 127.0.0.1 -P 514 “Failed password for root from 127.0.0.1”
[root@localhost ~]# python3 login_fail_monitor.py
监控文件:/var/log/syslog-ng/info.log
[INFO] 127.0.0.1 第 1 次失败
[INFO] 127.0.0.1 第 2 次失败
[INFO] 127.0.0.1 第 3 次失败
[ALERT] 127.0.0.1 登录失败 3 次!
创建:
/etc/systemd/system/login_fail_monitor.service
内容:
[Unit]
Description=Login Failure Monitor (Syslog-ng file-based)
After=network.target
[Service]
ExecStart=/usr/bin/python3 /opt/login_fail_monitor.py
Restart=always
User=root
[Install]
WantedBy=multi-user.target
安装并启动:
sudo systemctl daemon-reload
sudo systemctl enable login_fail_monitor
sudo systemctl start login_fail_monitor
查看状态:
sudo systemctl status login_fail_monitor
1️⃣ Facility(设施/来源)
作用:标记日志是从哪个系统组件/服务来的。
类型:整数(通常 0–23),有标准含义。
Facility 值 名称 说明
0 kern 内核消息
1 user 普通用户级消息
2 mail 邮件系统
3 daemon 系统后台守护进程
4 auth 安全/授权子系统
5 syslog syslog 守护进程本身
6 lpr 打印系统
7 news 网络新闻子系统
8 uucp UUCP 子系统
9 clock 时钟守护进程
10 authpriv 安全/授权子系统(私有)
11 ftp FTP 守护进程
12–15 local0–local7 本地使用(自定义程序日志)
在 syslog-ng 中,$FACILITY_NUM 就是日志的 facility 数字。
2️⃣ Severity(严重性/等级)
作用:标记日志的重要程度/紧急性。
类型:整数(0–7),数字越小越严重。
Severity 值 名称 说明
0 emerg 紧急:系统不可用
1 alert 警报:需要立即处理
2 crit 严重:严重错误
3 err 错误:普通错误
4 warning 警告:可能问题
5 notice 注意:正常但重要
6 info 信息:常规消息
7 debug 调试:详细调试信息
$LEVEL_NUM 就是日志的 severity 数字。
3️⃣ PRI(优先级)和 facility/severity 关系
syslog 消息的开头通常是 ,例如:
<11>1 2025-11-30T23:28:44.752202+08:00 …
计算方法:
PRI = facility * 8 + severity
例子:
<11>:
facility = 1 → user
severity = 3 → err
因为 1*8 + 3 = 11 ✅
<14>:
14 / 8 = 1,余 6 → facility=1 (user),severity=6 (info)
🔹 小结
facility:日志来源(哪个服务/系统组件)
severity:日志等级(紧急/错误/信息/调试)
MySQL 或告警系统可以根据 severity 过滤,只写 err、alert 等高等级日志。