ELK 实战之三:Kibana 使用与 Tomcat、Nginx 日志格式处理

在前两篇文章中,我们分别介绍了 Elasticsearch 的核心概念与集群部署,以及 Logstash 的强大数据采集与处理能力。现在,我们将目光投向 ELK 技术栈的“脸面”—— Kibana。Kibana 是一个开源的数据分析和可视化平台,它让我们能够通过精美的图表和仪表盘与 Elasticsearch 中存储的数据进行交互。

本文将分为两大部分:

  1. Kibana 核心功能详解:带你快速上手 Kibana 的操作界面,掌握数据探索、可视化和仪表盘构建的核心技能。
  2. 日志格式处理实战:深入探讨如何为两种最常见的 Web 服务器日志(Nginx 和 Tomcat)配置合适的 Logstash 解析规则(Grok),确保数据能被正确地结构化,为后续的高效分析打下坚实基础。

无论你是运维工程师、开发人员还是数据分析师,掌握 Kibana 和日志解析都是释放日志数据价值的关键一步。

目录#

  1. Kibana 核心功能详解
    1. 初始设置:索引模式
    2. 数据探索:Discover 功能
    3. 可视化:Visualize 功能
    4. 一站式视图:Dashboard 功能
  2. 日志格式处理实战
    1. 通用基础:日志结构化的重要性
    2. Nginx 日志处理
      1. Nginx 日志格式解析
      2. Logstash Grok 配置实战
      3. 最佳实践与优化
    3. Tomcat 日志处理
      1. Tomcat 日志格式解析
      2. Logstash Grok 配置实战
      3. 处理多行日志(堆栈跟踪)
  3. 总结
  4. 参考资料

一、 Kibana 核心功能详解#

成功登录 Kibana(通常通过 http://<your-kibana-server>:5601)后,让我们来熟悉其核心功能模块。

1.1 初始设置:索引模式#

在开始使用 Kibana 之前,你必须先告诉它要去 Elasticsearch 中的哪个索引(或哪组索引)里查找数据。这个步骤就是创建 索引模式

步骤:

  1. 进入 Management -> Stack Management
  2. 在左侧导航栏选择 Kibana -> 索引模式
  3. 点击 创建索引模式
  4. 输入索引名称模式,例如:
    • logstash-nginx-*:匹配所有以 logstash-nginx- 开头的索引。
    • logstash-*:匹配所有以 logstash- 开头的索引(更通用)。
  5. 点击 下一步
  6. 选择用于时间过滤的字段(如 @timestamp)。这对于按时间序列分析日志至关重要。如果日志中没有时间字段,可以选择 我不想使用时间过滤器
  7. 点击 创建索引模式

最佳实践:

  • 命名约定:建议在 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 段的日志。
  • 字段过滤:左侧栏列出了索引模式中的所有字段。你可以点击任意字段,查看其 Top N 值,并选择将其添加为过滤器(正面或反面过滤)。

1.3 可视化:Visualize 功能#

Visualize 模块允许你将数据转换为各种图表,从而更容易发现趋势、模式和异常。

常用图表类型:

  • 柱状图:比较不同类别的数值,如“不同 HTTP 状态码的请求数量”。
  • 折线图/面积图:展示数据随时间的变化趋势,如“每秒请求数(RPS)”。
  • 饼图:显示组成部分的比例,如“不同浏览器类型的占比”。
  • 数据表:列出详细的聚合数据,如“访问量最高的前 10 个 URL”。
  • 指标:显示单个关键指标,如“当前在线用户数”、“平均响应时间”。

创建流程(以柱状图为例):

  1. 进入 Visualize -> 创建新的可视化
  2. 选择 柱状图
  3. 选择数据源(如之前创建的 logstash-nginx-* 索引模式)。
  4. buckets 区域配置 X 轴
    • 聚合:选择 Terms(用于分类统计)。
    • 字段:选择 response.keyword(注意:对文本字段进行聚合时必须使用 .keyword 子字段)。
    • 排序:按 计数 降序。
    • 大小:显示前 10 个状态码。
  5. 点击右上角 更新 即可生成图表。

1.4 一站式视图:Dashboard 功能#

Dashboard 是将多个保存的可视化图表组合在一起形成的综合视图。它为你提供了一个监控系统健康状况和性能的一站式平台。

创建流程:

  1. 进入 Dashboard -> 创建新的仪表板
  2. 点击 添加,选择之前创建好的各个可视化图表(如:RPS 折线图、状态码分布柱状图、Top URLs 数据表等)。
  3. 通过拖拽调整图表的位置和大小。
  4. 可以利用 Dashboard 顶部的时间选择器 同时控制所有图表的时间范围。
  5. 保存仪表板,便于日后快速访问。

二、 日志格式处理实战#

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 的操作。
  • whatpreviousnextprevious 表示将当前行合并到前一行;next 表示将当前行合并到后一行。

三、总结#

通过本文,我们系统地学习了 Kibana 的核心功能,并从实战角度深入剖析了如何解析 Nginx 和 Tomcat 这两种最常见的日志格式。

  • Kibana 作为 ELK 栈的展示层,其强大的探索、可视化和仪表盘功能,使得海量日志数据变得直观、可操作。
  • 日志解析 是 ELK 栈中至关重要且需要精细处理的一环。正确使用 Grok多行编码器 将非结构化的原始日志转化为结构化的数据,是后续一切高效分析和监控的前提。

最佳实践链条:

  1. 规划日志格式:在应用和服务器层面定义清晰、一致的日志格式。
  2. 精心设计 Logstash 配置:使用 Grok Debugger 确保解析规则 100% 准确,并处理好多行事件。
  3. 定义清晰的 Kibana 索引模式:便于数据管理。
  4. 构建有意义的可视化图表和仪表盘:围绕业务和运维需求(如错误率、响应时间、流量趋势)来设计。

掌握这些技能,你将能真正驾驭 ELK 栈,将其转化为强大的运维和业务洞察工具。


四、参考资料#

  1. Kibana 官方文档 - 最权威和最新的功能说明。
  2. Grok Filter 插件文档 - 详细的 Grok 语法和内置模式列表。
  3. Grok Debugger - 在线调试 Grok 模式的利器(需在 Kibana Dev Tools 中访问)。
  4. Logstash 配置最佳实践 - Elastic 官方提供的性能优化建议。
  5. Dissect Filter 插件文档 - 对于分隔符固定的简单日志,Dissect 是比 Grok 更高效的选择。