使用 ELK 分析 CentOS 上的 JS 日志
一 架构与准备
- 组件与端口
- Elasticsearch:存储与检索,默认端口 9200
- Logstash:日志采集与解析,常用 5044(与 Filebeat 对接)
- Kibana:可视化与检索,默认端口 5601
- 环境与防火墙
- 安装 Java 8(ELK 7.x 常用),并放行端口:9200/9300/5601/5044
- 示例(CentOS 7+ firewalld):
- firewall-cmd --permanent --add-port={9200,9300,5601,5044}/tcp
- firewall-cmd --reload
- 日志形态建议
- Node.js 后端日志:输出到文件或 journald,推荐结构化(JSON)便于解析
- 前端浏览器日志:通过 WebSocket/HTTP 发送到日志网关或直接写入文件再由 Filebeat 采集
二 在 CentOS 部署 ELK
- 安装与启动(以 7.x 为例)
- 导入 GPG 并添加 YUM 源(Elasticsearch、Logstash、Kibana)
- 安装:yum install -y elasticsearch logstash kibana
- 启动与开机自启:
- systemctl enable --now elasticsearch
- systemctl enable --now logstash
- systemctl enable --now kibana
- 快速验证
- curl -X GET “http://localhost:9200/”
- 浏览器访问 http://<服务器IP>:5601 进入 Kibana 初始化
三 采集 Node.js 日志
- 方案 A Filebeat → Logstash → Elasticsearch(推荐)
- Filebeat 采集文件,Logstash 负责解析与丰富,再写入 ES
- Filebeat 配置(/etc/filebeat/filebeat.yml 片段)
- filebeat.inputs:
- type: log
paths:
- /var/log/nodejs/*.log
fields:
log_type: nodejs
- output.logstash:
- hosts: [“localhost:5044”]
- Logstash 配置(/etc/logstash/conf.d/nodejs.conf)
- input { beats { port => 5044 } }
- filter {
json {
source => “message”
target => “json”
remove_field => [“message”]
}
mutate {
rename => { “[json][level]” => “log_level” }
rename => { “[json][msg]” => “message” }
rename => { “[json][time]” => “timestamp” }
convert => { “response_time” => “float” }
}
date {
match => [ “timestamp”, “ISO8601”, “yyyy-MM-dd HH:mm:ss.SSS” ]
target => “@timestamp”
}
if [log_level] == “ERROR” {
mutate { add_tag => [“error”] }
}
}
- output {
elasticsearch {
hosts => [“http://localhost:9200”]
index => “nodejs-logs-%{+YYYY.MM.dd}”
}
stdout { codec => rubydebug }
}
- 方案 B 直接写入 journald(配合 systemd)
- 服务单元示例(/etc/systemd/system/nodeapp.service)
- [Service]
- ExecStart=/usr/bin/node /opt/app/index.js
- StandardOutput=journal
- StandardError=journal
- SyslogIdentifier=nodeapp
- Logstash 读取 journal(需配置 systemd 输入插件并授权访问 journal)
- 日志格式建议(Node.js,使用 winston 输出 JSON)
- const winston = require(‘winston’);
const logger = winston.createLogger({
level: ‘info’,
format: winston.format.json(),
transports: [new winston.transports.File({ filename: ‘/var/log/nodejs/app.log’ })]
});
logger.info({ msg: ‘User login’, userId: 123, ip: ‘10.0.0.1’ });
logger.error({ msg: ‘DB timeout’, err: ‘timeout’, duration_ms: 3200 });
- 前端浏览器日志(通过 WebSocket 实时上报到网关或直接落盘再由 Filebeat 采集)
四 在 Kibana 分析
- 索引与字段
- 进入 Stack Management → Index Patterns,创建索引模式:nodejs-logs-*
- 设置时间字段为 @timestamp,确认字段类型(如 log_level 为 keyword,response_time 为 number)
- 典型检索与可视化
- 错误率趋势:Kibana → Visualize → Line
- Metrics:Y 轴 Count;Buckets:X 轴 Date Histogram(@timestamp),Split Series 按 log_level
- 慢请求 TopN:
- Metrics:Y 轴 Average of response_time;Buckets:X 轴 Terms(如 url.path 或 route)
- 错误详情表格:
- Kibana → Discover,筛选 log_level: ERROR,展示 message、url、stack、userId、ip、@timestamp
- 告警示例(可选)
- 使用 Kibana Alerting 或 Elasticsearch Watcher 对“5xx 比例 > 1%”或“过去 5 分钟 ERROR > 10”触发通知(邮件/钉钉/企业微信)
五 运维与优化
- 日志轮转与保留
- 使用 logrotate 管理 Node.js 日志文件,示例(/etc/logrotate.d/nodejs):
- /var/log/nodejs/*.log {
- daily
- rotate 7
- compress
- delaycompress
- missingok
- notifempty
- create 0640 nodejs nodejs
- sharedscripts
- postrotate
- systemctl reload filebeat >/dev/null 2>&1 || true
- endscript
- }
- 性能与稳定性
- 为 Logstash 设置合适的 pipeline.workers 与 batch.size;ES 堆内存建议不超过物理内存的 50% 且留足 OS 缓存
- Filebeat 使用 harvester_limit 与 close_inactive 控制文件句柄占用
- 为高频字段(如 url、userId、traceId)设置 keyword 类型,避免聚合/排序时开销过大
- 建议将索引按天滚动(如 nodejs-logs-YYYY.MM.dd),并配置 ILM(Rollover + Delete)自动管理生命周期