提供:ZStack云计算
系列教程
本教程为《生产环境构建指南:Web应用》系列六篇中的第六篇。
内容简介
在今天的教程中,我们将一同了解如何为生产环境设置集中式日志记录。集中式日志记录能够有效收集服务器日志并对其进行可视化处理。一般来讲,备份与监控工作在优先级上要高于设置这样一套复杂的日志记录机制,不过我们仍然能够借助后者确切把握应用程序中的问题或者趋势。
在本文中,我们将设置一套ELK堆栈(即Elasticsearch、Logstash以及Kibana),同时配置用于承载应用程序的服务器以将其相关日志发送至日志记录服务器。我们还将设置Logstash过滤器以对日志进行解析与整理,这将帮助我们更为轻松地对日志内容加以搜索与过滤,并将其直接引入Kibana可视化方案当中。
先决条件
如果大家希望通过域名访问自己的日志记录仪表板,则需要在当前域名下创建一条A记录,例如“logging.example.com”,并使其指向我们日志记录服务器的公共IP地址。另外,大家也可以直接通过该公共IP地址访问监控仪表板。这里建议大家将该日志记录Web服务器设置为使用HTTPS,同时将其部署在VPN之后以限制访问来源。
在日志记录服务器上安装ELK
要在日志记录服务器上安装ELK,请参阅教程:How To Install Elasticsearch, Logstash, and Kibana 4 on 如何在Ubuntu 14.04上安装Elasticsearch、Logstash与Kibana 4。
如果大家使用专有DNS以实现域名解析,请确保遵循生成SSL证书部分中的选项二。
参阅内容截止于“设置Logstash Forwarder”部分。
在客户端上设置Logstash Forwarder
要在客户端服务器上设置日志发布工具Logstash Forwarder,即db1、app1、app2以及lb1,请参阅ELK教程中的[设置Logstash Forwarder章节](https://www.digitalocean.com/community/tutorials/how-to-install-elasticsearch-logstash-and-kibana-4-on-ubuntu-14-04#set-up-logstash-forwarder-(add-client-servers)。
完成之后,大家应该已经可以通过日志记录服务器的公共网络地址登录至Kibana当中了,且可以查看每台服务器的系统日志。
确定需要收集的日志内容
根据具体应用与设置,我们可通过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
将以下内容添加至现有条目的“files”部分当中,从而将MySQL慢查询日志作为“mysql-slow”类别发送至Logstash服务器:
logstash-forwarder.conf — MySQL slow query
,
{
"paths": [
"/var/log/mysql/mysql-slow.log"
],
"fields": { "type": "mysql-slow" }
}
保存并退出。此配置将使得Logstash Forwarder发布MySQL慢查询日志并将其标志为“mysql-slow”类型日志,以备后续过滤使用。
重启Logstash Forwarder以应用这项日志发布功能:
- sudo service logstash-forwarder restart
多行输出Codec
MySQL慢查询日志为多行格式(即每个条目跨越多行),因此我们必须使用Logstash的多行codec以处理这类日志。
在ELK(即日志记录)服务器上打开此配置文件,并找到Lumberjack输入定义位置:
- sudo vi /etc/logstash/conf.d/01-lumberjack-input.conf
在lunberjack输入定义中添加以下命令行:
codec => multiline {
pattern => "^# User@Host:"
negate => true
what => previous
}
保存并退出。此配置使得Logstash能够使用多行日志处理机制以应对包含这一特定模式(即以”# User@Host:”开头)的日志。
接下来,我们需要设置Logstash过滤器以处理MySQL日志。
MySQL日志过滤器
在ELK(即日志记录)服务器上,打开一个新文件并添加用于Logstash的MySQL日志过滤器。我们将其命名为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在条件符合的情况下利用Grok模式对mysql-slow类日志进行过滤。符合默认Apache日志消息格式的apache-access类日志则由Logstash提供的Grok模式进行解析,而符合默认错误日志格式的apache-error类日志则由Grok过滤器进行解析。
为了让这些过滤器正常起效,我们需要重启Logstash:
- sudo service logstash restart
现在大家需要验证Logstash是否运行正常,任何配置错误都会导致其出现故障。
另外大家还需要确认Kibana能否正常显示过滤后的Apache日志。
Apache日志
Apache的日志通常位于/var/log/apache2,名称则为“access.log”或者“error.log”。收集这些日志将帮助我们了解谁的IP地址正在访问服务器,其发出了哪些请求,其正在使用哪种操作系统及网络浏览器,同时掌握Apache报告的全部错误信息。
发布Apache日志文件
我们必须配置Logstash Forwarder以将Apache访问与错误日志发布至我们的日志记录服务器。
在我们的应用程序服务器——app1与app2——上,打开Logstash Forwarder配置文件:
- sudo vi /etc/logstash-forwarder.conf
在现有条目中的“files”部分之内添加以下内容,从而将正确类型的Apache日志发送至Logstash服务器:
logstash-forwarder.conf — Apache access and error logs
,
{
"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反向代理是我们通过互联网实现应用程序服务器访问的惟一途径。要通过变更查看访问我们站点的实际用户的源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服务器上打开一个新文件,向其中添加用于Logstash的Apache日志过滤器。我们将其命名为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利用Grok模式对符合条件的apache-access与apache-error类日志进行过滤。符合默认Apache日志消息格式的apache-access类日志则由Logstash提供的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
在现有条目中的“files”部分内添加以下内容,保证HAProxy日志以“haproxy-log”类别发送至Logstash服务器:
logstash-forwarder.conf — HAProxy logs
,
{
"paths": [
"/var/log/haproxy.log"
],
"fields": { "type": "haproxy-log" }
}
保存并退出。此配置将使得Logstash Forwarder发布HAProxy日志并将其标记为haproxy-log,以备日后过滤之用。
重启Logstash Forwarder以启用日志发布功能:
sudo service logstash-forwarder restart
HAProxy日志过滤器
在ELK服务器上打开一个新文件,并将我们的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利用Grok模式对符合条件的haproxy-log类日志进行过滤。符合默认HAProxy日志消息格式的haproxy-log类日志将由Logstash提供的Grok模式进行解析。
重启Logstash以应用各过滤器:
- sudo service logstash restart
现在大家需要验证Logstash是否运行正常,任何配置错误都会导致其出现故障。
设置Kibana可视化工具
现在我们已经可以通过集中方式对日志进行收集了,接下来我们要利用Kibana对其进行可视化处理。具体方式请参阅如何使用Kibana仪表板与可视化工具一文。
在熟悉了Kibana之后,大家不妨参阅How To Map User Location with GeoIP and ELK如何利用GeoIP与ELK将用户位置汇总为地图一文以了解更多可视化选项。
总结
祝贺大家!各位已经完成了生产环境下的Web应用设置系列教程。如果大家认真阅读了全部内容,那么现在应该已经拥有了一套教程中使用的设置方案(包含专有DNS与远程备份机制)。
换言之,大家已经拥有了一款通常实际运行的应用,其中包含去耦组件,并由备份、监控以及集中式日志记录组件提供相关支持。当然,也请大家对这套应用加以测试,确保全部组件都如预期般正常起效。
本文来源自DigitalOcean Community。英文原文:Building for Production: Web Applications — Centralized Logging By Mitchell Anicas
翻译:diradw