ELK 实战之三:Kibana 使用与 Tomcat、Nginx 日志格式处理
在前两篇文章中,我们分别介绍了 Elasticsearch 的核心概念与集群部署,以及 Logstash 的强大数据采集与处理能力。现在,我们将目光投向 ELK 技术栈的“脸面”—— Kibana。Kibana 是一个开源的数据分析和可视化平台,它让我们能够通过精美的图表和仪表盘与 Elasticsearch 中存储的数据进行交互。
本文将分为两大部分:
- Kibana 核心功能详解:带你快速上手 Kibana 的操作界面,掌握数据探索、可视化和仪表盘构建的核心技能。
- 日志格式处理实战:深入探讨如何为两种最常见的 Web 服务器日志(Nginx 和 Tomcat)配置合适的 Logstash 解析规则(Grok),确保数据能被正确地结构化,为后续的高效分析打下坚实基础。
无论你是运维工程师、开发人员还是数据分析师,掌握 Kibana 和日志解析都是释放日志数据价值的关键一步。
目录#
一、 Kibana 核心功能详解#
成功登录 Kibana(通常通过 http://<your-kibana-server>:5601)后,让我们来熟悉其核心功能模块。
1.1 初始设置:索引模式#
在开始使用 Kibana 之前,你必须先告诉它要去 Elasticsearch 中的哪个索引(或哪组索引)里查找数据。这个步骤就是创建 索引模式。
步骤:
- 进入 Management -> Stack Management。
- 在左侧导航栏选择 Kibana -> 索引模式。
- 点击 创建索引模式。
- 输入索引名称模式,例如:
logstash-nginx-*:匹配所有以logstash-nginx-开头的索引。logstash-*:匹配所有以logstash-开头的索引(更通用)。
- 点击 下一步。
- 选择用于时间过滤的字段(如
@timestamp)。这对于按时间序列分析日志至关重要。如果日志中没有时间字段,可以选择 我不想使用时间过滤器。 - 点击 创建索引模式。
最佳实践:
- 命名约定:建议在 Logstash 输出到 Elasticsearch 时使用带有日期戳的索引,如
logstash-nginx-2023.10.27,这样可以使用logstash-nginx-*这种模式轻松匹配所有相关索引。 - 时间字段:始终配置
@timestamp字段,它是 ELK 栈中事件时间戳的标准字段。
1.2 数据探索:Discover 功能#
Discover 是 Kibana 的数据探索中心,你可以在这里进行交互式查询和搜索。
核心操作:
- 选择索引模式:在左上角选择你想要探索的索引模式。
- 时间范围筛选:在右上角设置一个时间范围(如“最近 15 分钟”),Kibana 只会显示该时间段内的文档。
- 查询栏:使用 Kibana 查询语法(KQL) 或 Lucene 查询语法 进行搜索。
- KQL 示例:
response: 200:查找response字段值为 200 的日志。response: (400 OR 404 OR 500):查找状态码为 400、404 或 500 的错误日志。message: "Connection refused":在message字段中搜索包含该短语的日志。clientip: "192.168.1.*":使用通配符搜索特定 IP 段的日志。
- KQL 示例:
- 字段过滤:左侧栏列出了索引模式中的所有字段。你可以点击任意字段,查看其 Top N 值,并选择将其添加为过滤器(正面或反面过滤)。
1.3 可视化:Visualize 功能#
Visualize 模块允许你将数据转换为各种图表,从而更容易发现趋势、模式和异常。
常用图表类型:
- 柱状图:比较不同类别的数值,如“不同 HTTP 状态码的请求数量”。
- 折线图/面积图:展示数据随时间的变化趋势,如“每秒请求数(RPS)”。
- 饼图:显示组成部分的比例,如“不同浏览器类型的占比”。
- 数据表:列出详细的聚合数据,如“访问量最高的前 10 个 URL”。
- 指标:显示单个关键指标,如“当前在线用户数”、“平均响应时间”。
创建流程(以柱状图为例):
- 进入 Visualize -> 创建新的可视化。
- 选择 柱状图。
- 选择数据源(如之前创建的
logstash-nginx-*索引模式)。 - 在 buckets 区域配置 X 轴:
- 聚合:选择 Terms(用于分类统计)。
- 字段:选择
response.keyword(注意:对文本字段进行聚合时必须使用.keyword子字段)。 - 排序:按 计数 降序。
- 大小:显示前 10 个状态码。
- 点击右上角 更新 即可生成图表。
1.4 一站式视图:Dashboard 功能#
Dashboard 是将多个保存的可视化图表组合在一起形成的综合视图。它为你提供了一个监控系统健康状况和性能的一站式平台。
创建流程:
- 进入 Dashboard -> 创建新的仪表板。
- 点击 添加,选择之前创建好的各个可视化图表(如:RPS 折线图、状态码分布柱状图、Top URLs 数据表等)。
- 通过拖拽调整图表的位置和大小。
- 可以利用 Dashboard 顶部的时间选择器 同时控制所有图表的时间范围。
- 保存仪表板,便于日后快速访问。
二、 日志格式处理实战#
Kibana 的强大建立在数据被正确解析的基础上。原始日志通常是非结构化的文本,我们需要使用 Logstash 的 Grok 过滤器将其拆分成有意义的字段。
2.1 通用基础:日志结构化的重要性#
将一行日志从:
192.168.1.100 - - [27/Oct/2023:14:30:01 +0800] "GET /api/user HTTP/1.1" 200 1234
解析成如下 JSON 结构:
{
"clientip": "192.168.1.100",
"timestamp": "2023-10-27T06:30:01.000Z",
"verb": "GET",
"request": "/api/user",
"httpversion": "1.1",
"response": "200",
"bytes": "1234"
}这样做的好处是巨大的:你可以按 IP 地址、状态码、请求路径等任何字段进行筛选、聚合和可视化,而不再是简单的全文搜索。
2.2 Nginx 日志处理#
2.2.1 Nginx 日志格式解析#
默认的 Nginx 访问日志使用 NCSA 扩展日志格式,通常可以在 nginx.conf 中找到类似如下定义:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';对应的日志行示例:
192.168.1.100 - - [27/Oct/2023:14:30:01 +0800] "GET /index.html HTTP/1.1" 200 612 "http://example.com/referer" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36..."
2.2.2 Logstash Grok 配置实战#
以下是一个针对上述格式的 Logstash 配置片段 (nginx.conf):
input {
file {
path => "/var/log/nginx/access.log"
start_position => "beginning"
sincedb_path => "/dev/null" # 仅用于测试,生产环境请移除
codec => "plain"
type => "nginx-access"
}
}
filter {
# 使用 Grok 解析 NGINX 访问日志
grok {
match => { "message" => "%{IPORHOST:clientip} - %{DATA:remote_user} \[%{HTTPDATE:timestamp}\] \"%{WORD:verb} %{DATA:request} HTTP/%{NUMBER:httpversion}\" %{NUMBER:response} (?:%{NUMBER:bytes}|-) \"%{DATA:referrer}\" \"%{DATA:agent}\"" }
}
# 解析时间戳
date {
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
target => "@timestamp" # 将解析后的时间设置为 @timestamp 字段
remove_field => [ "timestamp" ] # 删除原始的 timestamp 字段
}
# 将字节数和状态码转换为数字类型
mutate {
convert => {
"response" => "integer"
"bytes" => "integer"
}
}
# 解析 User-Agent 字符串,获取浏览器、OS等信息
useragent {
source => "agent"
target => "user_agent"
}
}
output {
elasticsearch {
hosts => ["your-elasticsearch-host:9200"]
index => "logstash-nginx-%{+YYYY.MM.dd}"
}
stdout { codec => rubydebug } # 用于调试,输出到控制台
}Grok 模式说明:
%{IPORHOST:clientip}:匹配 IP 或主机名,并存入clientip字段。%{DATA:remote_user}:匹配-,存入remote_user字段。%{HTTPDATE:timestamp}:匹配[27/Oct/2023:14:30:01 +0800],存入timestamp字段。\"%{WORD:verb} %{DATA:request} HTTP/%{NUMBER:httpversion}\":匹配"GET /index.html HTTP/1.1",并分别解析出方法、请求路径和 HTTP 版本。
2.2.3 最佳实践与优化#
- Grok Debugger:强烈建议使用 Kibana 自带的 Grok Debugger(在 Management -> Dev Tools 中)来测试和调试你的 Grok 模式。
- 自定义模式:如果默认模式不能满足需求,可以创建自定义模式文件。
- 性能:Grok 消耗 CPU。如果日志格式固定且简单,考虑使用
dissect过滤器,它比 Grok 更高效。
2.3 Tomcat 日志处理#
2.3.1 Tomcat 日志格式解析#
Tomcat 的访问日志(localhost_access_log)格式可在 server.xml 中配置。默认格式类似:
%h %l %u %t "%r" %s %b
对应的日志行示例:
192.168.1.100 - - [27/Oct/2023:14:30:02 +0800] "GET /myapp/ HTTP/1.1" 200 12345
你会发现,这个格式与 Nginx 的非常相似,因此 Grok 模式也基本通用。
2.3.2 Logstash Grok 配置实战#
Logstash 配置与 Nginx 的非常类似:
input {
file {
path => "/path/to/tomcat/logs/localhost_access_log.*.txt"
start_position => "beginning"
codec => "plain"
type => "tomcat-access"
}
}
filter {
grok {
match => { "message" => "%{IPORHOST:clientip} %{DATA:ident} %{DATA:auth} \[%{HTTPDATE:timestamp}\] \"%{WORD:verb} %{DATA:request} HTTP/%{NUMBER:httpversion}\" %{NUMBER:response} %{NUMBER:bytes}" }
}
date {
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
target => "@timestamp"
remove_field => [ "timestamp" ]
}
mutate {
convert => {
"response" => "integer"
"bytes" => "integer"
}
}
}
output {
elasticsearch {
hosts => ["your-elasticsearch-host:9200"]
index => "logstash-tomcat-%{+YYYY.MM.dd}"
}
}2.3.3 处理多行日志(堆栈跟踪)#
Tomcat 的 catalina.out 或应用日志通常包含 Java 异常堆栈跟踪,这些是多行日志。直接采集会拆分成多个事件,导致信息混乱。必须使用 multiline Codec 来处理。
示例:处理 Java 异常日志
input {
file {
path => "/path/to/tomcat/logs/catalina.out"
start_position => "beginning"
codec => multiline {
# 模式:如果新行不是以空格或制表符开头(即不是堆栈跟踪的行),则它是一个新事件的开始。
pattern => "^\s"
# 如果新行不匹配上述模式(即不是以空白开头),则它属于上一个事件?不,这里应该是 negate 和 what 的组合。
# 更正:更常见的配置是匹配日志开头(如日期),然后将不匹配的行合并到上一个事件。
pattern => "^%{TIMESTAMP_ISO8601} "
negate => true
what => "previous"
}
type => "tomcat-catalina"
}
}
filter {
# 首先尝试匹配标准日志格式(包含时间戳、级别、类名等信息)
grok {
match => { "message" => "^%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:loglevel} \[%{DATA:thread}\] %{DATA:class} - %{GREEDYDATA:message}" }
overwrite => [ "message" ]
}
# 如果上一步匹配成功,则解析时间戳
if [timestamp] {
date {
match => [ "timestamp", "yyyy-MM-dd HH:mm:ss,SSS" ]
target => "@timestamp"
remove_field => [ "timestamp" ]
}
}
}multiline Codec 关键参数:
pattern:用于判断行是否属于同一事件的正则表达式。negate:true 或 false。如果为 true,表示当行不匹配 pattern 时,执行what的操作。what:previous或next。previous表示将当前行合并到前一行;next表示将当前行合并到后一行。
三、总结#
通过本文,我们系统地学习了 Kibana 的核心功能,并从实战角度深入剖析了如何解析 Nginx 和 Tomcat 这两种最常见的日志格式。
- Kibana 作为 ELK 栈的展示层,其强大的探索、可视化和仪表盘功能,使得海量日志数据变得直观、可操作。
- 日志解析 是 ELK 栈中至关重要且需要精细处理的一环。正确使用 Grok 和 多行编码器 将非结构化的原始日志转化为结构化的数据,是后续一切高效分析和监控的前提。
最佳实践链条:
- 规划日志格式:在应用和服务器层面定义清晰、一致的日志格式。
- 精心设计 Logstash 配置:使用 Grok Debugger 确保解析规则 100% 准确,并处理好多行事件。
- 定义清晰的 Kibana 索引模式:便于数据管理。
- 构建有意义的可视化图表和仪表盘:围绕业务和运维需求(如错误率、响应时间、流量趋势)来设计。
掌握这些技能,你将能真正驾驭 ELK 栈,将其转化为强大的运维和业务洞察工具。
四、参考资料#
- Kibana 官方文档 - 最权威和最新的功能说明。
- Grok Filter 插件文档 - 详细的 Grok 语法和内置模式列表。
- Grok Debugger - 在线调试 Grok 模式的利器(需在 Kibana Dev Tools 中访问)。
- Logstash 配置最佳实践 - Elastic 官方提供的性能优化建议。
- Dissect Filter 插件文档 - 对于分隔符固定的简单日志,Dissect 是比 Grok 更高效的选择。