网站搜索

如何在 Nginx 中配置自定义访问和错误日志格式


Nginx HTTP 服务器拥有出色的日志记录功能,并且高度可定制。在本文中,我们将解释如何在 Linux 中为 Nginx 配置自己的访问日志和错误日志格式。

本指南的目的是帮助您了解日志是如何生成的,以便配置自定义日志格式,以便调试、故障排除或分析 Web 服务器和 Web 应用程序中发生的情况(例如跟踪请求)。

另请阅读:4 个优秀的 Linux 开源日志监控和管理工具

本文由三个部分组成,将指导您配置访问/错误日志以及如何在 Nginx 中启用条件日志记录。

在 Nginx 中配置访问日志

Nginx下,所有客户端对服务器的请求都会使用ngx_http_log_module模块以指定的格式记录在访问日志中。

默认日志文件是 log/access.log (在 Linux 系统上通常是 /var/log/nginx/access_log),默认的日志记录格式通常是组合或主要格式(这可能因发行版而异)。

access_log指令(适用于http、服务器、位置,如果在位置和限制上下文除外)用于设置日志文件和log_format指令(适用于仅http上下文)用于设置日志格式。日志格式由公共变量和仅在写入日志时生成的变量来描述。

配置日志格式的语法为:

log_format format_name 'set_of_variables_to_define_format';

配置访问日志的语法为:

access_log /path/to/log_file format_name;		#simplest form 
OR
access_log /path/to/log_file [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];

以下是 CentOS 7 上默认 Nginx 配置文件 /etc/nginx/nginx.conf 的摘录。

http {
	#main log format 
	log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                               '$status $body_bytes_sent "$http_referer" '
                               '"$http_user_agent" "$http_x_forwarded_for"';

	access_log /var/log/nginx/access.log;
}

此日志格式会生成以下日志条目。

127.0.0.1 - dbmanager [20/Nov/2017:18:52:17 +0000] "GET / HTTP/1.1" 401 188 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0"

以下是另一种有用的日志记录格式,我们使用它使用一些默认变量来跟踪对 Web 应用程序的请求,最重要的是它具有请求 ID 并记录客户端位置详细信息(国家/地区、国家/地区代码、地区和城市)。

log_format  custom '$remote_addr - $remote_user [$time_local] '
                         	     '"$request" $status $body_bytes_sent '
                      		     '"$http_referer" "$http_user_agent" '
                     		     '"$http_x_forwarded_for" $request_id '
                   		     '$geoip_country_name $geoip_country_code '
                  		     '$geoip_region_name $geoip_city ';

你可以这样使用它:

access_log  /var/log/nginx/access.log custom;

这将产生一个如下所示的日志条目。

153.78.107.192 - - [21/Nov/2017:08:45:45 +0000] "POST /ngx_pagespeed_beacon?url=https%3A%2F%2Fwww.example.com%2Fads%2Ffresh-oranges-1509260795 HTTP/2.0" 204 0 "https://www.suasell.com/ads/fresh-oranges-1509260795" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0" "-" a02b2dea9cf06344a25611c1d7ad72db Uganda UG Kampala Kampala 

您可以使用同一级别的 access_log 指令指定多个日志,这里我们在 http 上下文中使用多个日志文件。

http{
	##default log format
	log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                                	      '$status $body_bytes_sent "$http_referer" '
                                         '"$http_user_agent" "$http_x_forwarded_for"';
      
	##request tracing using custom format
	log_format custom '$remote_addr - $remote_user [$time_local] '
                                           '"$request" $status $body_bytes_sent '
                                           '"$http_referer" "$http_user_agent" '
                                           '"$http_x_forwarded_for" $request_id '
                                           '$geoip_country_name $geoip_country_code '
                                          '$geoip_region_name $geoip_city ';

	##this uses the default log format
	access_log /var/log/nginx/access.log;

	##this uses the our custom log format
	access_log /var/log/nginx/custom_log custom;
}

以下是更高级的日志记录配置示例,对于包含压缩相关变量的日志格式以及创建压缩日志文件非常有用:

access_log /var/log/nginx/custom_log custom buffer 32k;
access_log /path/to/log.gz compression  gzip  flush=5m;

在 Nginx 中配置错误日志

如果 Nginx 遇到任何故障,它会在错误日志中记录相关信息。这些问题属于不同的严重级别:调试信息通知警告错误(这是默认级别,全局有效)、critalertemerg

默认日志文件是 log/error.log,但在 Linux 发行版上它通常位于 /var/log/nginx/ 中。 error_log 指令用于指定日志文件,它可以在 main、http、mail、stream、server、location 上下文中使用(按顺序)。

您还应该注意:

  • 主上下文中的配置始终由较低级别按上述顺序继承。
  • 较低级别的配置会覆盖从较高级别继承的配置。

您可以使用以下语法配置错误日志记录:

error_log /path/to/log_file log_level;

例如:

error_log /var/log/nginx/error_log warn; 

这将指示 Nginx 记录所有类型为 warn 的消息以及更严重的日志级别 critalertemerg消息。

在下一个示例中,将记录 critalertemerg 级别的消息。

error_log /var/www/example1.com/log/error_log crit;

考虑下面的配置,在这里,我们定义了不同级别的错误日志记录(在 http 和服务器上下文中)。如果出现错误,消息将仅写入一个错误日志,即最接近出现错误的级别的错误日志。

http {
	log_format compression '$remote_addr - $remote_user [$time_local] '
                           '"$request" $status $body_bytes_sent '
                           '"$http_referer" "$http_user_agent" "$gzip_ratio"';
	
	error_log  /var/log/nginx/error_log  crit;

    	server {
		listen 80;
		server_name example1.com;

		#this logs errors messages for example1.com only
      		error_log  /var/log/nginx/example1.error_log  warn;
            	…...
	}

     	server {
		listen 80;
		server_name  example2.com;

		#this logs errors messages for example2.com only
        		error_log  /var/log/nginx/example1.error_log;
        		…….
    	}
}

如果您使用多个 error_log 指令(如下面的配置(同一级别)),则消息将写入所有指定的日志。

server {
		listen 80;
		server_name example1.com;

      		error_log  /var/www/example1.com/log/error_log  warn;
		error_log  /var/log/nginx/example1.error_log  crit;
            	…...
	}

在 Nginx 中配置条件日志记录

在某些情况下,我们可能希望 Nginx 执行消息的条件日志记录。并非每条消息都必须由 Nginx 记录,因此我们可以忽略特定实例的访问日志中不重要或不太重要的日志条目。

我们可以使用 ngx_http_map_module 模块来创建变量,这些变量的值取决于其他变量的值。映射块内的参数(应仅存在于 http 内容中)指定源值和结果值之间的映射。

对于这种设置,如果条件计算结果为“0”或空字符串,则不会记录请求。此示例排除带有 HTTP 状态代码 2xx3xx 的请求。

http{
	map $status $condition {
		~^[23] 0;
    		default 1;
	}
	server{
		access_log  /path/to/access.log  custom if=$condition;
	}
}

这是在开发阶段调试 Web 应用程序的另一个有用示例。这将忽略所有消息并仅记录调试信息。

 
http{
	map $info  $debuggable { 
    		default     0; 
    		debug       1; 
	} 
	server{
		……..
		access_log /var/log/nginx/testapp_debug_access_log  debug if=$debuggable; 
		#logs other requests 
		access_log  /var/log/nginx/testapp_access.log  main; 
		…….
	}
}

您可以在此处找到更多信息,包括记录到系统日志。

目前为止就这样了!在本指南中,我们解释了如何在 Nginx 中配置访问和错误日志的自定义日志记录格式。使用下面的反馈表提出问题或分享您对本文的看法。