在CentOS服务器上做运维,最头疼的事情之一就是日志分散在几十台甚至上百台机器上,排查问题时要一台台SSH登录去翻/var/log目录。把rsyslog日志实时转发到Elasticsearch,是目前最主流、最成熟的集中式日志方案。核心思路就是:rsyslog通过omelasticsearch模块把日志以JSON格式推送到ES集群,再配合Kibana做可视化查询和告警。下面我直接把完整的配置流程、踩坑经验和优化建议一次性讲透。

一、整体架构和工作原理

整个日志链路非常清晰:CentOS服务器上的rsyslog守护进程读取本地日志文件(比如/var/log/messages、/var/log/secure、自定义应用日志等),经过规则过滤和格式化后,通过omelasticsearch输出模块以HTTP/HTTPS协议将日志批量发送到Elasticsearch节点。ES负责存储和索引,Kibana负责展示。如果日志量大,中间还可以加一层Logstash或Kafka做缓冲和预处理,但对于中小规模场景,rsyslog直连ES完全够用。

二、环境准备和前置条件

开始配置之前,你需要确认以下几点:

1. CentOS版本建议7.x或8.x,rsyslog版本至少8.x以上,因为omelasticsearch模块是从v8开始才内置的。可以用命令rsyslogd -v查看版本。

2. Elasticsearch集群已经部署完成并且正常运行,建议版本7.x或8.x。确认ES的HTTP端口(默认9200)可以从CentOS服务器访问。

3. 如果ES开启了X-Pack安全认证(生产环境强烈建议开启),你需要提前创建好有写入权限的用户,并记录用户名密码。

4. 网络层面确保CentOS服务器到ES节点的9200端口(或9200+SSL的9200)是通的,防火墙规则要放行。

三、安装rsyslog的Elasticsearch模块

CentOS 7上,rsyslog的omelasticsearch模块通常需要单独安装:

yum install -y rsyslog-elasticsearch

CentOS 8 / Rocky Linux / AlmaLinux上,模块可能已经包含在rsyslog包里,但为了保险也可以确认一下:

yum install -y rsyslog-elasticsearch

安装完成后,重启rsyslog服务:

systemctl restart rsyslog

验证模块是否加载成功:

rsyslogd -N 2 | grep elastic

如果输出类似module 'omelasticsearch' loaded就说明没问题。

四、配置rsyslog转发规则

新建一个独立的配置文件,不要直接改/etc/rsyslog.conf主文件,方便管理和维护:

vim /etc/rsyslog.d/50-elasticsearch.conf

写入以下内容(根据你的实际环境修改IP、端口、索引名等参数):

module(load="omelasticsearch"
       template="json"
       server="192.168.1.100"
       serverport="9200"
       searchIndex="rsyslog-%{+YYYY.MM.dd}"
       searchType="_doc"
       bulkMode="on"
       queue.type="linkedlist"
       queue.size="10000"
       queue.dequeuebatchsize="1000"
       action.resumeretrycount="-1"
       action.resumeinterval="30"
)

这里逐行解释关键参数:

template="json":使用JSON格式发送日志,这是ES最友好的格式,字段自动映射,不需要额外解析。

server和serverport:ES节点地址和端口,如果是集群可以写多个server行,rsyslog会自动做负载均衡和故障切换。

searchIndex="rsyslog-%{+YYYY.MM.dd}":按天创建索引,这是最佳实践。每天一个索引便于管理生命周期和清理过期数据。

bulkMode="on":开启批量发送模式,大幅提升吞吐量,减少网络开销。单条发送在高并发场景下会把ES打崩。

queue.type="linkedlist":使用内存队列,当ES暂时不可达时,日志会缓存在内存中,等恢复后自动重发。生产环境建议改成disk队列防止内存溢出:

queue.type="disk"
queue.filename="es_queue"
queue.maxdiskspace="2g"
queue.saveonshutdown="on"
queue.size="500000"

action.resumeretrycount="-1":无限重试,确保日志不丢失。

五、配置安全认证(X-Pack场景)

如果你的ES开启了安全认证,需要在模块配置中加入用户名密码:

module(load="omelasticsearch"
       template="json"
       server="192.168.1.100"
       serverport="9200"
       searchIndex="rsyslog-%{+YYYY.MM.dd}"
       searchType="_doc"
       bulkMode="on"
       action.resumeretrycount="-1"
       action.resumeinterval="30"
       username="rsyslog_writer"
       password="YourSecurePassword123"
)

注意:密码明文写在配置文件里有安全风险。更安全的做法是使用rsyslog的密码文件机制:

vim /etc/rsyslog.d/elasticsearch_password
# 文件内容格式:
# user:password
rsyslog_writer:YourSecurePassword123

然后在模块配置中引用:

passwordfile="/etc/rsyslog.d/elasticsearch_password"

同时设置文件权限:

chmod 600 /etc/rsyslog.d/elasticsearch_password
chown root:root /etc/rsyslog.d/elasticsearch_password

六、配置日志过滤和自定义字段

默认情况下,rsyslog会把所有日志都转发到ES,这在生产环境中往往不合适。你需要根据实际需求做过滤。比如只转发messages和secure日志:

if $programname == 'messages' or $programname == 'secure' then {
    action(type="omelasticsearch"
           template="json"
           server="192.168.1.100"
           serverport="9200"
           searchIndex="rsyslog-%{+YYYY.MM.dd}"
           searchType="_doc"
           bulkMode="on"
           queue.type="disk"
           queue.filename="es_queue"
           queue.maxdiskspace="2g"
           queue.saveonshutdown="on")
}

如果你想给日志加上自定义标签(比如服务器名、环境标识),可以在模板中使用property replacer:

template(name="json_with_host" type="list") {
    constant(value="{")
    constant(value="\"@timestamp\":\"")     property(name="timereported" dateFormat="rfc3339")
    constant(value="\",\"host\":\"")        property(name="hostname")
    constant(value="\",\"severity\":\"")    property(name="syslogseverity-text")
    constant(value="\",\"facility\":\"")    property(name="syslogfacility-text")
    constant(value="\",\"program\":\"")     property(name="programname")
    constant(value="\",\"message\":\"")     property(name="msg" format="json")
    constant(value="\",\"env\":\"production\"")
    constant(value="}")
}

然后在模块中引用这个模板:template="json_with_host"

七、Elasticsearch端的索引模板配置

ES端需要提前创建索引模板,确保字段类型正确,尤其是时间字段。在Kibana的Dev Tools中执行:

PUT _index_template/rsyslog-template
{
  "index_patterns": ["rsyslog-*"],
  "template": {
    "settings": {
      "number_of_shards": 1,
      "number_of_replicas": 1,
      "index.lifecycle.name": "rsyslog-ilm-policy"
    },
    "mappings": {
      "properties": {
        "@timestamp": {
          "type": "date"
        },
        "host": {
          "type": "keyword"
        },
        "severity": {
          "type": "keyword"
        },
        "program": {
          "type": "keyword"
        },
        "message": {
          "type": "text"
        }
      }
    }
  }
}

同时建议配置ILM(Index Lifecycle Management)策略,自动管理索引的热、温、冷、删除阶段,避免磁盘被日志撑爆。

八、常见问题和排错技巧

1. 日志发不出去:先用curl测试ES连通性,curl -u user:pass http://192.168.1.100:9200。然后查看rsyslog日志/var/log/messages,搜索elasticsearch关键字看报错信息。

2. ES报413错误:说明单次批量数据太大,调小queue.dequeuebatchsize到500或更小。

3. 索引创建失败:检查ES是否允许自动创建索引,action.auto_create_index默认是true,如果被禁用了需要手动创建或开启。

4. 时间字段不对:rsyslog默认用timereported字段,如果你的应用日志时间戳在msg里面,需要用property replacer提取并设置为@timestamp。

5. 内存队列爆了:高并发场景务必用disk队列,并且设置合理的maxdiskspace,同时监控磁盘使用率。

九、性能优化建议

对于日志量超过每秒几千条的场景,我的建议是:

第一,批量大小控制在1000-2000条,不要贪大。第二,ES集群至少3个节点,分片数根据数据量合理规划,一般每天一个索引、每个索引1-3个分片就够了。第三,如果单台rsyslog转发压力大,可以在前面加一台Logstash做聚合和缓冲,Logstash的elasticsearch output插件性能更强、功能更丰富。第四,定期清理过期索引,用ILM自动执行,别让旧日志占着磁盘。

十、总结

rsyslog转发日志到Elasticsearch这套方案,部署简单、维护成本低、兼容性好,是CentOS运维场景下做日志集中管理的首选方案。核心就是装好omelasticsearch模块、写好配置文件、做好ES端索引模板和安全认证,再根据实际业务做好过滤和性能调优。把这几步做扎实,你的日志系统就能稳定运行,出了问题几分钟内就能定位到根因。