ELK-生产案例项目分析及实战
1. 需求分析
确认需要收集的日志类型及使用的相关插件
- 系统日志: /var/log/* (可以使用 input 的 syslog 插件)
- 访问日志: Apache/Nginx/Tomcat 等的访问日志( 使用 input 的 file/json 等插件,filter 的 grok 插件)
- 错误日志: error log、Java 日志 (使用访问日志类似的插件,Java 的日志需要使用 codec 多行插件)
- 运行日志: 程序自己生成的 (使用 input 的 file/json 等插件)
- 网络日志: 防火墙、交换机、路由器等的日志 (可以使用 input 的 syslog 插件)
2. 日志标准化
2.1 日志放置目录及命名规范
规范日志放置目录和命名 ,以下是一个示例参考:
[root@linux-node1 logs]# tree /data/logs
/data/logs
├── access-log # 访问日志目录
├── error-log # 错误日志目录
└── runtime-log # 运行日志目录
2.2 日志切割
对于不同程序,有的程序可以自定义日志切割,有的可能需要自己编写脚本来进行日志切割。
日志文件切割时间可以按天、按小时等,这个需要根据实际业务的日志情况来确定。
2.3 日志接入格式标准
我们可以规定,如果要接入 ELK 日志系统,程序日志格式应该是 JSON 格式,方便日志的统一接收。
这个和研发去协商,为了实现 DevOps,研发和运维应该相互配合,如果日志格式不是 JSON,我们可以不接收。
2.4 原始日志文件删除和归档策略
比如可以将本地原始日志文件 rsync 到一个共享存储文件系统后,然后删除本地最近 7 天前的日志文件。
这个也是根据具体业务的日志情况来制定。
如果业务一天能产生海量日志,那么可能就要删除最近一天前的日志。
3. 工具化
如何使用 Logstash 等 Agent 工具进行日志收集。 需要规划好方案和画好架构图。
参考官网架构图
4. 实施
实施是基于我们在前面一系列文章的配置。
按照架构图安装 ELK 相关组件。
# 在 192.168.56.11 上的 Logstash 配置文件 shipper.conf,内容如下:
[root@linux-node1 conf.d]# cat shipper.conf
input {
file {
path => "/var/log/httpd/access_log"
start_position => "beginning"
type => "apache-access-log"
}
file {
path => "/var/log/elasticsearch/myes.log"
type => "es-log"
start_position => "beginning"
codec => multiline{
pattern => "^\["
negate => true
what => "previous"
}
}
}
output {
if [type] == "apache-access-log" {
redis {
host => "192.168.56.12"
port => 6379
db => 6
data_type => "list"
key => "apache-access-log"
}
}
if [type] == "es-log" {
redis {
host => "192.168.56.12"
port => 6379
db => 7
data_type => "list"
key => "es-log"
}
}
}
# 在 192.168.56.12 上的 Logstash 配置文件 indexer.conf,内容如下:
[root@linux-node2 conf.d]# cat indexer.conf
input {
syslog {
type => "system-syslog"
port => 514
}
redis {
type => "apache-access-log"
host => "192.168.56.12"
port => 6379
db => 6
data_type => "list"
key => "apache-access-log"
}
redis {
type => "es-log"
host => "192.168.56.12"
port => 6379
db => 7
data_type => "list"
key => "es-log"
}
}
filter {
if [type] == "apache-access-log" {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
}
}
output {
if [type] == "apache-access-log" {
elasticsearch {
hosts => ["192.168.56.11:9200"]
index => "apache-access-log-%{+YYYY.MM.dd}"
}
}
if [type] == "es-log" {
elasticsearch {
hosts => ["192.168.56.11:9200"]
index => "es-log-%{+YYYY.MM}"
}
}
if [type] == "system-syslog" {
elasticsearch {
hosts => ["192.168.56.11:9200"]
index => "system-syslog-%{+YYYY.MM}"
}
}
}
注意:
- type 是关键字,日志文件中不能使用 type;
- type 最好和 key 一样,这样不容易出错。
5. 监控
- 对 ES 以及 Kibana 进行监控。如果服务 DOWN 了要及时处理。
- 可以使用 Redis 的 list 作为 ELK 的消息队列。
- 对 Redis 的 List Key 长度进行监控(llen key_name)。例如: 超过”10 万”即报警(根据实际情况以及业务情况)
6. 扩展
- 开源日志分析平台:ELK、EFK、EHK
- 数据收集处理:Flume、Heka
- 消息队列: Redis、RabbitMQ、Kafka、Hadoop、WebHDFS
遇到的问题
1.192.168.56.11 上的 Apache 日志不能写入 Redis ,原因是 logstash init 脚本运行用户和组是 logstash ,但 httpd 目录权限如下:
[root@linux-node1 conf.d]# ll /var/log/httpd/ -d
drwx------ 2 root root 4096 Oct 9 12:18 /var/log/httpd/
logstash 用户进程没权限读取 access_log,当然就无法写入 Redis。
解决办法:
可以修改 logstash init 脚本运行用户和组为 root。因为 logstash 并不监听端口,所以可以换成 root 用户。
但推荐将修改 /var/log/httpd/
权限为 755。
2.Logstash 运行时报错
报错这里暂时不贴出来了。(因为里面含有的特殊符号标签会被 GitHub Pages 解析不出来)
初步判断 /etc/logstash/conf.d/
目录下只能有 Logstash 的 YAML 格式的配置文件,不能有其他格式的文件。
我将一个日志文件放在这里了,移走后就可以正常运行。