为生产而构建:Web应用程序—集中式日志记录

来自菜鸟教程
跳转至:导航、​搜索

介绍

我们终于准备好为我们的生产应用程序设置设置集中式日志记录。 集中式日志记录是收集和可视化服务器日志的好方法。 通常,设置一个精心设计的日志系统不如设置可靠的备份和监控重要,但它在尝试识别应用程序的趋势或问题时非常有用。

在本教程中,我们将设置一个 ELK 堆栈(Elasticsearch、Logstash 和 Kibana),并配置构成我们应用程序的服务器以将其相关日志发送到日志服务器。 我们还将设置 Logstash 过滤器,它将解析和构建我们的日志,这将使我们能够轻松地搜索和过滤它们,并在 Kibana 可视化中使用它们。

先决条件

如果您想通过域名访问日志仪表板,请在您的域下创建一个 A 记录,例如“logging.example.com”,它指向您的 logging 服务器的公网 IP 地址。 或者,您可以通过公共 IP 地址访问监控仪表板。 建议您将日志记录 Web 服务器设置为使用 HTTPS,并通过将其置于 VPN 后面来限制对其的访问。

在日志服务器上安装 ELK

按照本教程在 logging 服务器上设置 ELK:如何在 Ubuntu 14.04 上安装 Elasticsearch、Logstash 和 Kibana 4。

如果您使用私有 DNS 进行名称解析,请务必遵循 生成 SSL 证书部分 中的 选项 2

当您到达 Set Up Logstash Forwarder 部分时停止。

在客户端上设置 Logstash 转发器

在您的客户端服务器上设置 Logstash Forwarder,一个日志传送器,即 db1、app1、app2 和 lb1,按照 ELK 教程的 设置 Logstash 转发器部分

完成后,您应该可以通过 logging 服务器的公网地址登录 Kibana,并查看每个服务器的 syslog。

确定要收集的日志

根据您的具体应用程序和设置,可以将不同的日志收集到您的 ELK 堆栈中。 在我们的例子中,我们将收集以下日志:

  • MySQL 慢查询日志 (db1)
  • Apache 访问和错误日志(app1 和 app2)
  • HAProxy 日志 (lb1)

我们选择这些日志是因为它们可以在故障排除或尝试识别趋势时提供一些有用的信息。 您的服务器可能有您想要收集的其他日志,但这将帮助您开始。

设置 MySQL 日志

MySQL 的慢查询日志通常位于 /var/log/mysql/mysql-slow。 它由运行时间足以被视为“慢查询”的日志组成,因此识别这些查询可以帮助您优化或排除应用程序故障。

开启 MySQL 慢查询日志

默认情况下不启用慢查询日志,所以让我们配置 MySQL 来记录这些类型的查询。

打开你的 MySQL 配置文件:

sudo vi /etc/mysql/my.cnf

找到注释过的“log_slow_queries”行,取消注释,如下所示:

/etc/mysql/my.cnf

log_slow_queries        = /var/log/mysql/mysql-slow.log

保存并退出。

我们需要重新启动 MySQL 以使更改生效:

sudo service mysql restart

现在 MySQL 会将其长时间运行的查询记录到配置中指定的日志文件中。

运送 MySQL 日志文件

我们必须配置 Logstash Forwarder 以将 MySQL 慢查询日志发送到我们的日志服务器。

在您的数据库服务器 db1 上,打开 Logstash Forwarder 配置文件:

sudo vi /etc/logstash-forwarder.conf

在现有条目下的“文件”部分添加以下内容,以将 MySQL 慢查询日志作为“mysql-slow”类型发送到您的 Logstash 服务器:

logstash-forwarder.conf — MySQL 慢查询

,
    {
      "paths": [
        "/var/log/mysql/mysql-slow.log"
       ],
      "fields": { "type": "mysql-slow" }
    }

保存并退出。 这将 Logstash Forwarder 配置为发送 MySQL 慢查询日志并将它们标记为“mysql-slow”类型的日志,稍后将用于过滤。

重新启动 Logstash Forwarder 以开始传送日志:

sudo service logstash-forwarder restart

多行输入编解码器

MySQL慢查询日志是多行格式(即 每个条目跨越多行),因此我们必须启用 Logstash 的多行编解码器才能处理这种类型的日志。

在 ELK 服务器 logging 上,打开定义了 Lumberjack 输入的配置文件:

sudo vi /etc/logstash/conf.d/01-lumberjack-input.conf

lumberjack 输入定义中,添加以下行:

    codec => multiline {
      pattern => "^# User@Host:"
      negate => true
      what => previous
    }

保存并退出。 这会将 Logstash 配置为在遇到包含指定模式的日志时使用多行日志处理器(即 以“#User@Host:”开头)。

接下来,我们将为 MySQL 日志设置 Logstash 过滤器。

MySQL 日志过滤器

在 ELK 服务器 logging 上,打开一个新文件以将我们的 MySQL 日志过滤器添加到 Logstash。 我们将其命名为 11-mysql.conf,因此它将在 Logstash 输入配置之后读取(在 01-lumberjack-input.conf 文件中):

sudo vi /etc/logstash/conf.d/11-mysql.conf

添加以下过滤器定义:

11-mysql.conf

filter {
  # Capture user, optional host and optional ip fields
  # sample log file lines:
  if [type] == "mysql-slow" {
    grok {
      match => [ "message", "^# User@Host: %{USER:user}(?:\[[^\]]+\])?\s+@\s+%{HOST:host}?\s+\[%{IP:ip}?\]" ]
    }
    # Capture query time, lock time, rows returned and rows examined
    grok {
      match => [ "message", "^# Query_time: %{NUMBER:duration:float}\s+Lock_time: %{NUMBER:lock_wait:float} Rows_sent: %{NUMBER:results:int} \s*Rows_examined: %{NUMBER:scanned:int}"]
    }
    # Capture the time the query happened
    grok {
      match => [ "message", "^SET timestamp=%{NUMBER:timestamp};" ]
    }
    # Extract the time based on the time of the query and not the time the item got logged
    date {
      match => [ "timestamp", "UNIX" ]
    }
    # Drop the captured timestamp field since it has been moved to the time of the event
    mutate {
      remove_field => "timestamp"
    }
  }
}

保存并退出。 这将 Logstash 配置为使用 match 指令中指定的 Grok 模式过滤 mysql-slow 类型的日志。 apache-access 类型日志由 Logstash 提供的与默认 Apache 日志消息格式匹配的 Grok 模式解析,而 apache-error 类型日志由为匹配而编写的 Grok 过滤器解析默认错误日志格式。

为了让这些过滤器发挥作用,让我们重新启动 Logstash:

sudo service logstash restart

此时,您需要确保 Logstash 正常运行,因为配置错误会导致它失败。

您还需要确认 Kibana 能够查看过滤后的 Apache 日志。

阿帕奇日志

Apache 的日志通常位于 /var/log/apache2 中,名为“access.log”和“error.log”。 除了 Apache 报告的任何错误消息之外,收集这些日志将允许您查看谁在访问您的服务器的 IP 地址、他们的请求以及他们使用的操作系统和 Web 浏览器。

运送 Apache 日志文件

我们必须配置 Logstash Forwarder 以将 Apache 访问和错误日志发送到我们的日志服务器。

在您的应用服务器 app1 和 app2 上,打开 Logstash Forwarder 配置文件:

sudo vi /etc/logstash-forwarder.conf

在现有条目下的“文件”部分添加以下内容,以将 Apache 日志作为适当的类型发送到您的 Logstash 服务器:

logstash-forwarder.conf — Apache 访问和错误日志

,
    {
      "paths": [
        "/var/log/apache2/access.log"
       ],
      "fields": { "type": "apache-access" }
    },
    {
      "paths": [
        "/var/log/apache2/error.log"
       ],
      "fields": { "type": "apache-error" }
    }

保存并退出。 这会将 Logstash Forwarder 配置为发送 Apache 访问和错误日志,并将它们标记为各自的类型,用于过滤日志。

重新启动 Logstash Forwarder 以开始传送日志:

sudo service logstash-forwarder restart

现在,您的所有 Apache 日志都将具有与 HAProxy 服务器的私有 IP 地址匹配的客户端源 IP 地址,因为 HAProxy 反向代理是从 Internet 访问您的应用程序服务器的唯一方式。 要更改此设置以显示访问您站点的实际用户的源 IP,我们可以修改默认 Apache 日志格式以使用 HAProxy 发送的 X-Forwarded-For 标头。

打开您的 Apache 配置文件 (apache2.conf):

sudo vi /etc/apache2/apache2.conf

找到如下所示的行:

[Label apache2.conf — Original "combined" LogFormat]
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

%h 替换为 %{X-Forwarded-For}i,如下所示:

[Label apache2.conf — Updated "combined" LogFormat]
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

保存并退出。 这会将 Apache 访问日志配置为包含实际用户的源 IP 地址,而不是 HAProxy 服务器的私有 IP 地址。

重新启动 Apache 以使日志更改生效:

sudo service apache2 restart

现在我们准备好将 Apache 日志过滤器添加到 Logstash。

Apache 日志过滤器

在 ELK 服务器 logging 上,打开一个新文件以将我们的 Apache 日志过滤器添加到 Logstash。 我们将其命名为 12-apache.conf,因此它将在 Logstash 输入配置之后读取(在 01-lumberjack-input.conf 文件中):

sudo vi /etc/logstash/conf.d/12-apache.conf

添加以下过滤器定义:

12-apache.conf

filter {
  if [type] == "apache-access" {
    grok {
      match => { "message" => "%{COMBINEDAPACHELOG}" }
    }
  }
}
filter {
  if [type] == "apache-error" {
    grok {
      match => { "message" => "\[(?<timestamp>%{DAY:day} %{MONTH:month} %{MONTHDAY} %{TIME} %{YEAR})\] \[%{DATA:severity}\] \[pid %{NUMBER:pid}\] \[client %{IPORHOST:clientip}:%{POSINT:clientport}] %{GREEDYDATA:error_message}" }
    }
  }
}

保存并退出。 这将 Logstash 配置为使用各自 match 指令中指定的 Grok 模式过滤 apache-accessapache-error 类型的日志。 apache-access 类型日志由 Logstash 提供的与默认 Apache 日志消息格式匹配的 Grok 模式解析,而 apache-error 类型日志由为匹配而编写的 Grok 过滤器解析默认错误日志格式。

为了让这些过滤器发挥作用,让我们重新启动 Logstash:

sudo service logstash restart

此时,您需要确保 Logstash 正常运行,因为配置错误会导致它失败。 您还需要确认 Kibana 能够查看过滤后的 Apache 日志。

HAProxy 日志

HAProxy 的日志通常位于 /var/log/haproxy.log。 收集这些日志将允许您查看谁在访问您的负载均衡器的 IP 地址、他们正在请求什么、哪个应用程序服务器正在为他们的请求提供服务,以及有关连接的各种其他详细信息。

运送 HAProxy 日志文件

我们必须配置 Logstash Forwarder 来发送 HAProxy 日志。

在您的 HAProxy 服务器 lb1 上,打开 Logstash Forwarder 配置文件:

sudo vi /etc/logstash-forwarder.conf

在现有条目下的“文件”部分添加以下内容,以将 HAProxy 日志作为“haproxy-log”类型发送到您的 Logstash 服务器:

logstash-forwarder.conf — HAProxy 日志

,
    {
      "paths": [
        "/var/log/haproxy.log"
       ],
      "fields": { "type": "haproxy-log" }
    }

保存并退出。 这会将 Logstash Forwarder 配置为发送 HAProxy 日志并将它们标记为 haproxy-log,这将用于过滤日志。

重新启动 Logstash Forwarder 以开始传送日志:

sudo service logstash-forwarder restart

HAProxy 日志过滤器

在 ELK 服务器 logging 上,打开一个新文件以将我们的 HAProxy 日志过滤器添加到 Logstash。 我们将其命名为 13-haproxy.conf,因此它将在 Logstash 输入配置之后读取(在 01-lumberjack-input.conf 文件中):

sudo vi /etc/logstash/conf.d/13-haproxy.conf

添加以下过滤器定义:

filter {
  if [type] == "haproxy-log" {
    grok {
      match => { "message" => "%{SYSLOGTIMESTAMP:timestamp} %{HOSTNAME:hostname} %{SYSLOGPROG}: %{IPORHOST:clientip}:%{POSINT:clientport} \[%{MONTHDAY}[./-]%{MONTH}[./-]%{YEAR}:%{TIME}\] %{NOTSPACE:frontend_name} %{NOTSPACE:backend_name}/%{NOTSPACE:server_name} %{INT:time_request}/%{INT:time_queue}/%{INT:time_backend_connect}/%{INT:time_backend_response}/%{NOTSPACE:time_duration} %{INT:http_status_code} %{NOTSPACE:bytes_read} %{DATA:captured_request_cookie} %{DATA:captured_response_cookie} %{NOTSPACE:termination_state} %{INT:actconn}/%{INT:feconn}/%{INT:beconn}/%{INT:srvconn}/%{NOTSPACE:retries} %{INT:srv_queue}/%{INT:backend_queue} "(%{WORD:http_verb} %{URIPATHPARAM:http_request} HTTP/%{NUMBER:http_version})|<BADREQ>|(%{WORD:http_verb} (%{URIPROTO:http_proto}://))" }
    }
  }
}

保存并退出。 这将 Logstash 配置为使用相应 match 指令中指定的 Grok 模式过滤 haproxy-log 类型的日志。 haproxy-log 类型的日志由与默认 HAProxy 日志消息格式匹配的 Logstash 提供的 Grok 模式解析。

为了让这些过滤器发挥作用,让我们重新启动 Logstash:

sudo service logstash restart

此时,您需要确保 Logstash 正常运行,因为配置错误会导致它失败。

设置 Kibana 可视化

现在您正在一个中心位置收集日志,您可以开始使用 Kibana 来可视化它们。 本教程可以帮助您入门:如何使用 Kibana 仪表板和可视化

一旦您对 Kibana 有所了解,请尝试本教程以一种有趣的方式可视化您的用户:如何使用 GeoIP 和 ELK 映射用户位置。

结论

恭喜! 您已完成生产 Web 应用程序设置教程系列。 如果您按照所有教程进行操作,那么您应该有一个类似于我们在概述教程中描述的设置(使用私有 DNS 和远程备份):

也就是说,您应该有一个工作应用程序,具有分离的组件,由备份、监控和集中式日志记录组件支持。 请务必测试您的应用程序,并确保所有组件都按预期工作。