将Apache日志发送到Graylog

时间:2020-03-21 11:47:00  来源:igfitidea点击:

我一直在寻找一种将Apache访问日志转发到Graylog的简便方法,并且遇到了GELF。

GELF

Syslog非常适合记录服务器的系统消息,而Graylog扩展日志格式(GELF)是从应用程序内部进行记录的理想选择。

GELF(1.1版)格式的消息是带有两个必填字段的JSON字符串:

  • 版本-必须由客户端库设置GELF规范版本“ 1.1”。
  • host-发送此消息的主机或者应用程序的名称,必须由客户端库设置。
  • short_message-简短的描述性消息,必须由客户端库设置。

应该设置一个时间戳字段,但不是必须的,因为如果不存在,服务器将其设置为NOW。
然后,我们发送的每个带有下划线(_)的字段都将被视为添加字段。

Apache配置

这是默认的CustomLog格式在Apache 2.4(CentOS 7)上的样子:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

我们将创建一个名为graylog_access的新CustomLog格式,以将访问日志格式化为GELF格式(JSON消息):

LogFormat "{ \"version\": \"1.1\", \"host\": \"%V\", \"short_message\": \"%r\", \"timestamp\": %{%s}t, \"level\": 6, \"_user_agent\": \"%{User-Agent}i\", \"_source_ip\": \"%{X-Forwarded-For}i\", \"_duration_usec\": %D, \"_duration_sec\": %T, \"_request_size_byte\": %O, \"_http_status_orig\": %s, \"_http_status\": %>s, \"_http_request_path\": \"%U\", \"_http_request\": \"%U%q\", \"_http_method\": \"%m\", \"_http_referer\": \"%{Referer}i\", \"_from_apache\": \"true\" }" graylog_access

我们的Apache位于代理之后,因此我们使用X-Forwarded-For。
请注意,我们需要启用mod_logio以使用%O。
检查此页面https://httpd.apache.org/docs/current/mod/mod_log_config.html以获取其他格式参数。

这是一种人类可读的格式:

{ 
 "version": "1.1",
 "host": "%V",
 "short_message": "%r",
 "timestamp": %{%s}t,
 "level": 6,
 "_user_agent": "%{User-Agent}i",
 "_source_ip": "%{X-Forwarded-For}i",
 "_duration_usec": %D,
 "_duration_sec": %T,
 "_request_size_byte": %O,
 "_http_status_orig": %s,
 "_http_status": %>s,
 "_http_request_path": "%U",
 "_http_request": "%U%q",
 "_http_method": "%m",
 "_http_referer": "%{Referer}i",
 "_from_apache": "true"
}

字段_http_status_orig包含到达我们的代理(并且已在内部重定向)的原始请求的状态。

默认情况下,%指令%s,%U,%T,%D和%r查看原始请求,而其他所有指令查看最终请求。

Apache能够写入错误并通过管道将日志文件访问另一个进程,而不是直接访问文件。
因此,我们可以通过nc(或者ncat)管道日志数据来将Apache日志发送到Graylog。
将以下内容放入Apache的主机配置中:

CustomLog "|/usr/bin/nc -u graylog.example.com 12201" graylog_access

上面假设graylog.example.com服务器在UDP端口12201上具有GELF输入侦听器。

服务器启动时,服务器将启动管道日志进程,如果在服务器运行时崩溃,则将重新启动管道日志进程。
引号用于包围将为管道调用的整个命令。