Nginx日志格式及配置
2019-03-02 20:58:00 阿炯

Nginx的日志分为access log 和 error log,其中access log 记录了哪些用户,哪些页面以及用户浏览器、ip和其他的访问信息;error log 则是记录服务器错误日志。Nginx服务器日志相关指令主要有两条:一条是log_format,用来设置日志格式;另外一条是access_log,用来指定日志文件的存放路径、格式和缓存大小,可以参加ngx_http_log_module。一般在nginx的配置文件中(/etc/nginx/conf/nginx.conf),如果不想启用日志则使用access_log off。


nginx 日志主要有两条指令:
log_format:用来设置日志格式;
access_log:用来指定日志文件的存放路径、格式(把定义的log_format 跟在后面)和缓存大小;如果不想启用日志则access_log off;

log_format 日志格式
log_format指令用来设置日志的记录格式,它的语法如下:
log_format name format {format ...}
log_format name(格式名字) 格式样式(即想要得到什么样的日志内容)

关于x_forwarded_for:通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_addr拿到的IP地址是反向代理服务器的IP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。

注:在server中设置x_forwarded_for
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


其中name表示定义的格式名称,format表示定义的格式样式。
 
log_format有一个默认的、无须设置的combined日志格式设置,相当于Apache的combined日志格式,其具体参数如下:
log_format combined '$remote_addr-$remote_user [$time_local]'
'"$request"$status $body_bytes_sent'
'"$http_referer" "$http_user_agent"'
 
也可以自定义一份日志的记录格式,不过要注意,log_format指令设置的名称在配置文件中是不能重复的。

假设将Nginx服务器作为Web服务器,位于负载均衡设备、Squid、Nginx反向代理之后,不能获取到客户端的真实IP地址了。原因是经过反向代理后,由于在客户端和Web服务器之间增加了中间层,因此Web服务器无法直接拿到客户端的IP。通过$remote_addr变量拿到的将是反向代理服务器的IP地址。

可在反向代理服务器在转发请求的HTTP头信息中,增加X-Forwarded-For信息,用以记录原有的客户端IP地址和原来客户端请求的服务器地址。此时要用log_format指令设置日志格式,让日志记录X-Forearded-For信息中的IP地址,即客户的真实IP。

例如,创建一个名为mylogformat的日志格式,再$http_x_forwarded_forlog_for变量记录用户的X_Forwarded-For IP 地址:
log_format mylogformat '$http_x_forwarded_for_$remote_user [$time_local]'
'"$request"$status $body_bytes_sent'
'"$http_referer" "$http_user_agent"'

在日志格式样式中,变量$remote_addr和$http_x_forwarded_for用于记录IP地址;
$remote_user用于记录远程客户端用户名称;
$time_local用于记录访问时间与时区;
$request用于记录请求URL与HTTP协议;
$status用于记录请求状态,例如成功时状态为200,页面找不到时状态为404;
$body_bytes_sent用于记录发送客户端的文件主体内容大小;
$http_referer用于记录是从哪个页面链接访问过来的;
$http_user_agent用于记录客户浏览器的相关信息。

一般来说:nginx的log_format有很多可选的参数用于指示服务器的活动状态,默认的是:
log_format  main  '$remote_addr - $remote_user [$time_iso8601] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

'$remote_addr - $request_time - $upstream_response_time - $remote_user [$time_iso8601] "$request" '
'$status $body_bytes_sent "$http_referer" '
'$http_user_agent $http_x_forwarded_for $upstream_addr $upstream_status'

想要记录更详细的信息需要自定义设置log_format,具体可设置的参数格式及说明如下:
参数                      说明                                         示例
$remote_addr             客户端地址                                    211.28.12.253
$remote_user             客户端用户名称                                --
$time_local              访问时间和时区                                18/Jul/2018:17:00:01 +0800
$request                 请求的URI和HTTP协议                           "GET /article-10000.html HTTP/1.1"
$http_host               请求地址,即浏览器中你输入的地址(IP或域名)     www.freeoa.net 192.168.100.100
$status                  HTTP请求状态                                  200
$upstream_status         upstream状态                                  200
$body_bytes_sent         发送给客户端文件内容大小                        1547
$http_referer            url跳转来源                                   https://www.baidu.com/
$http_user_agent         用户终端浏览器等信息                           "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SV1; GTB7.0; .NET4.0C;
$ssl_protocol            SSL协议版本                                   TLSv1
$ssl_cipher              交换数据中的算法                               RC4-SHA
$upstream_addr           后台upstream的地址,即真正提供服务的主机地址     10.10.10.10:80
$request_time            整个请求的总时间                               0.205
$upstream_response_time  请求过程中,upstream响应时间                    0.002


如下是在nginx的LB代理层使用过的一个配置(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 $request_time $upstream_response_time $upstream_addr $upstream_status';

然后在nginx.conf文件或vhosts/*.conf文件中的access_log日志中指定级别为main。如下:
access_log  logs/freeoa_access.log main;
error_log logs/freeoa_error.log;

重启nginx服务后生效。日志截取如下(可以从日志中看到代理到后端哪台机器上的哪个端口上,负载访问的状态值等都能看到):
117.136.62.86 - 0.017 - 0.017 - - [26/Feb/2019:23:59:10 +0800] "GET /admin/appImg/CivilianService/ystb/z2212x.png HTTP/1.1" 200 3129 - No/1000 CFNetwork/976 Darwin/18.2.0 - 172.18.195.56:8002 200

可以看出几部分信息:
10.10.10.10 - - [22/Aug/2018:16:48:14 +0800] "POST /ajax/MbpRequest.do HTTP/1.1" 200 367 "-" "Dalvik/1.6.0 (Linux; U; Android 4.1.1; ARMM7K Build/JRO03H)" "119.189.56.255" 127.0.0.1:8090 0.022 0.022

1.客户端(用户)IP地址。如:10.10.10.10 (内网负载均衡地址)
2.访问时间。如:[22/Aug/2018:16:48:19 +0800]
3.访问端口。如:127.0.0.1:8080
4.响应时间。如:0.022
5.请求时间。如:0.022
6.用户地理位置代码(国家代码)。
7.请求的url地址(目标url地址)的host。如: /….
8.请求方式(GET或者POST等)。如:GET
9.请求url地址(去除host部分)。如:/html/test.html
10.请求状态(状态码,200表示成功,404表示页面不存在,301表示永久重定向等,具体状态码可以在网上找相关文章,不再赘述)。如:“200”
11.请求页面大小,默认为B(byte)。如:2426
12.来源页面,即从哪个页面转到本页,专业名称叫做“referer”。如:“http://freeoa.net”
13.用户浏览器语言。如: “es-ES,es;q=0.8”
14. 用户浏览器其他信息,浏览器版本、浏览器类型等。如: “Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11”


access_log

用了log_format 指令设置了日志格式之后,需要用access_log指令指定日志文件的存放路径;


注:一般log_format在全局设置,可以设置多个。access_log 可以在全局设置,但往往是定义在虚拟主机(server)中的location中:
http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        '"$status" $body_bytes_sent "$http_referer" '
        '"$http_user_agent" "$http_x_forwarded_for" '
        '"$gzip_ratio" $request_time $bytes_sent $request_length';

    log_format srcache_log '$remote_addr - $remote_user [$time_local] "$request" '
        '"$status" $body_bytes_sent $request_time $bytes_sent $request_length '
        '[$upstream_response_time] [$srcache_fetch_status] [$srcache_store_status] [$srcache_expire]';

    log_format freeoafmt1 '$remote_addr - $http_x_forwarded_for - $request_time - $upstream_cache_status - $remote_user - [$time_iso8601] - "$request" - $status - $body_bytes_sent - "$http_user_agent" - $http_referer - $upstream_addr - $upstream_response_time - $upstream_status';

    log_format freeoafmt2 '$remote_addr $remote_port - $http_x_forwarded_for - $request_time - $upstream_cache_status - $remote_user - [$time_iso8601] - "$request" - $status - $body_bytes_sent - "$http_user_agent" - $http_referer - $upstream_addr - $upstream_response_time - $upstream_status';

open_log_file_cache max=1000 inactive=60s;
 
server {
    server_name ~^(www\.)?(.+)$;
    access_log logs/$2-access.log main;
    error_log logs/$2-error.log;
    location /freeoacache {
        access_log logs/access-freeoacache.log freeoacache_log;
    }
}
}


Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;
Default:
access_log logs/access.log combined;
Context:    http, server, location, if in location, limit_except


http {
    log_format compression '$remote_addr - $remote_user [$time_local] '
                           '"$request" $status $body_bytes_sent '
                           '"$http_referer" "$http_user_agent" "$gzip_ratio"';
    server {
        gzip on;
        access_log /freeoa/logs/access.log compression;
        ...
    }
}

提高IO效率,启用缓冲
access_log /path/to/log/location [ format_of_log buffer_size ];

在缓冲区写满后才写到日志文件中。


提高存储效率,对日志文件启用自压缩功能
access_log /path/to/log/location [ format_of_log gzip ];


索性关掉日志记录
access_log off;


一些配置参考

不对状态码为200的访问进行日志记录

map $status $log_not_for_200_status {
    ~^200  0;
    default 1;
}

server {
    # Other directives here...
    access_log /freeoa/logs/access.log combined if=$log_not_for_200_status;
}

排除一些内网IP的访问记录

map $remote_addr $log_not_for_internal_ip {
    "192.168.1.168" 0;
    "192.168.2.169" 0;
    "192.168.3.170" 0;
    default 1;
}

server {
    access_log /freeoa/logs/access.log combined if=$log_not_for_internal_ip;
}


将日志打到系统的Syslog中(支持IP+端口、Socket等方式)

error_log  syslog:server=unix:/var/log/nginx.sock debug;
access_log syslog:server=[2001:db8::1]:1234,facility=local7,tag=nginx,severity=info;


access.log日志文件是可以按日期进行分割的,方便查看及处理。


相关说明解释:

1.$remote_addr 与$http_x_forwarded_for 用以记录客户端的ip地址;
2.$remote_user:用来记录客户端用户名称;
3.$time_local:用来记录访问时间与时区;
4.$request:用来记录请求的url与http协议;
5.$status:用来记录请求状态;成功是200,
6.$body_bytes_sent:记录发送给客户端文件主体内容大小;
7.$http_referer:用来记录从那个页面链接访问过来的;
8.$http_user_agent:记录客户端浏览器的相关信息;

有一点还要说明的是:如果所定义的log变量在这次访问时没有,则会以'-'替代之。


日志的存放路径

用了log_format 指令设置了日志格式之后,需要用access_log指令指定日志文件的存放路径。

1、语法:
access_log path(存放路径) format (自定义日志名称)

示例:access_log logs/access.log main;

2、设置刷盘策略:
access_log logs/freeoa_access.log buffer=32k flush=5s;

buffer 满 32k 才刷盘;假如 buffer 不满 5s 钟强制刷盘。

注:一般log_format在全局设置,可以设置多个。access_log 可以在全局设置,但往往是定义在虚拟主机(server)中的location中。

3、其它:
1)error_log:配置错误日志,例如上例。

2)open_log_file_cache:对于每一条日志记录,都将是先打开文件,再写入日志,然后关闭。可以使用open_log_file_cache来设置日志文件缓存(默认是off)。
语法:open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];

参数注释如下:
max:设置缓存中的最大文件描述符数量,如果缓存被占满,采用LRU算法将描述符关闭。
inactive:设置存活时间,默认是10s
min_uses:设置在inactive时间段内,日志文件最少使用多少次后,该日志文件描述符记入缓存中,默认是1次
valid:设置检查频率,默认60s

示例:open_log_file_cache max=1000 inactive=30s valid=1m min_uses=2;


日志分析

通过对日志格式的定义,就可以使用常见的 Linux 命令行工具进行分析了,下面提供一些参考示例。

查找访问频率最高的 URL 和次数:
cat access.log | awk -F '^A' '{print $10}' | sort | uniq -c

查找当前日志文件 500 错误的访问:
cat access.log | awk -F '^A' '{if($5 == 500) print $0}'

查找当前日志文件 500 错误的数量:
cat access.log | awk -F '^A' '{if($5 == 500) print $0}' | wc -l

查找某一分钟内 500 错误访问的数量:
cat access.log | awk -F '^A' '{if($5 == 500) print $0}' | grep '09:00' | wc-l

查找耗时超过 1s 的慢请求:
tail -f access.log | awk -F '^A' '{if($6>1) print $0}'

假如只想查看某些位:
tail -f access.log | awk -F '^A' '{if($6>1) print $3″|”$4}'

查找 502 错误最多的 URL:
cat access.log | awk -F '^A' '{if($5==502) print $11}' | sort | uniq -c

查找 200 空白页
cat access.log | awk -F '^A' '{if($5==200 && $8 < 100) print $3″|”$4″|”$11″|”$6}'

日志切割1

Nginx 的日志都是写在一个文件当中的,不会自动地进行切割,如果访问量很大的话,将导致日志文件容量非常大,不便于管理和造成Nginx 日志写入效率低下等问题。所以往往需要要对access_log、error_log日志进行切割,一般建议是天来切。

切割日志一般利用USR1信号让nginx产生新的日志:
#!/bin/bash
logdir="/apps/nginx/logs/"
pid=`cat $logdir/nginx.pid`
DATE=`date -d "1 hours ago" +%Y%m%d%H`
DATE_OLD=`date -d "7 days ago" +%Y%m%d`
for i in `ls $logdir/*access.log`; do
    mv $i $i.$DATE
done
for i in `ls $logdir/*error.log`; do
    mv $i $i.$DATE
done
kill -s USR1 $pid
rm -v $logdir"/access.log."$DATE_OLD*
rm -v $logdir"/error.log."$DATE_OLD*

1、分析:
将上面的脚本放到crontab中,每小时执行一次(0 ),这样每小时会把当前日志重命名成一个新文件;然后发送USR1这个信号让Nginx 重新生成一个新的日志(相当于备份日志),将前7天的日志删除;

2、说明:
在没有执行kill -USR1 $pid之前,即便已经对文件执行了mv命令而改变了文件名称,nginx还是会向新命名的文件"*access.log.2016072623"照常写入日志数据的。原因在于linux系统中,内核是根据文件描述符来找文件的。

3、logrotates:
使用系统自带的logrotates,也可以实现nginx的日志分割,查看其bash源码,发现也是发送USR1这个信号。


日志切割2

Nginx 的日志都是写在一个文件当中的,不会自动地进行切割,如果访问量很大的话,将导致日志文件容量非常大,不便于管理和造成Nginx 日志写入效率低下等问题。所以往往需要要对access_log、error_log日志进行切割。切割日志一般利用USR1信号让nginx产生新的日志。

nginx按日期分割存储日志,需要写shell脚本
#!/bin/bash  
#Auto cut nginx log script.  
LOGS_PATH= /var/log/nginx #你的日志目录  
TODAY=$(date -d 'yesterday' +%Y-%m-%d)  
#TODAY=history   
# 移动日志并改名  
mv -fv ${LOGS_PATH}/error.log ${LOGS_PATH}/error-back/error_${TODAY}.log #设置将生成的日志放到新的位置  
mv -fv ${LOGS_PATH}/access.log ${LOGS_PATH}/access-back/access_${TODAY}.log  

# 向nginx主进程发送重新打开日志文件的信号  
kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid)  #你的nginx.pid所在位置 找不到的话可以看一下nginx的conf文件   

然后写一个crontab,注意:kill这个命令需要执行权限,所以crontab最好写在root下。
0 0 * * * /bin/bash your_path/autocronlog.sh


在没有执行kill -USR1 $pid之前,即便已经对文件执行了mv命令或改变了文件名称,nginx还是会向新命名的文件写日志数据的。原因在于:linux系统中,内核是根据文件描述符来找文件的。

logrotates:使用系统自带的logrotates,也可以实现nginx的日志分割,通过查看其shell源码,发现也是发送USR1这个信号。


正确设置nginx中remote_addr和x_forwarded_for参数

网站经常会用到remote_addr和x_forwarded_for这两个头信息来获取客户端的IP,然而当有反向代理或者CDN的情况下,这两个值就不够准确了,需要调整一些配置。

什么是remote_addr

remote_addr代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(Nginx,Apache等)就会把remote_addr设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样web服务器就会把remote_addr设为这台代理机器的IP。

什么是x_forwarded_for

正如上面所述,当你使用了代理时,web服务器就不知道你的真实IP了,为了避免这个情况,代理服务器通常会增加一个叫做x_forwarded_for的头信息,把连接它的客户端IP(即你的上网机器IP)加到这个头信息里,这样就能保证网站的web服务器能获取到真实IP。

使用HAProxy做反向代理

通常网站为了支撑更大的访问量,会增加很多web服务器,并在这些服务器前面增加一个反向代理(如HAProxy),它可以把负载均匀的分布到这些机器上。你的浏览器访问的首先是这台反向代理,它再把你的请求转发到后面的web服务器,这就使得web服务器会把remote_addr设为这台反向代理的IP,为了能让你的程序获取到真实的客户端IP,你需要给HAProxy增加以下配置
option forwardfor

它的作用就像上面说的,增加一个x_forwarded_for的头信息,把你上网机器的ip添加进去。

使用Nginx的realip模块

当Nginx处在HAProxy后面时,就会把remote_addr设为HAProxy的IP,这个值其实是毫无意义的,你可以通过nginx的realip模块,让它使用x_forwarded_for里的值。使用这个模块需要重新编译Nginx,增加--with-http_realip_module参数
set_real_ip_from   10.1.10.0/24;
real_ip_header     X-Forwarded-For;

上面的配置就是把从10.1.10这一网段过来的请求全部使用X-Forwarded-For里的头信息作为remote_addr。

将Nginx架在HAProxy前面做HTTPS代理

网站为了安全考虑通常会使用https连接来传输敏感信息,https使用了ssl加密,HAProxy没法直接解析,所以要在HAProxy前面先架台Nginx解密,再转发到HAProxy做负载均衡。这样在Web服务器前面就存在了两个代理,为了能让它获取到真实的客户端IP,需要做以下配置。

首先要在Nginx的代理规则里设定
proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

这样会让Nginx的https代理增加x_forwarded_for头信息,保存客户的真实IP。

其次修改HAProxy的配置
option forwardfor except 10.1.10.0/24

这个配置和之前设定的差不多,只是多了个内网的IP段,表示如果HAProxy收到的请求是由内网传过来的话(https代理机器),就不会设定x_forwarded_for的值,保证后面的web服务器拿到的就是前面https代理传过来的。

为什么PHP里的HTTP_X_FORWARDED_FOR和Nginx的不一样

当你的网站使用了CDN后,用户会先访问CDN,如果CDN没有缓存,则回源站(即你的反向代理)取数据。CDN在回源站时,会先添加x_forwarded_for头信息,保存用户的真实IP,而你的反向代理也会设定这个值,不过它不会覆盖,而是把CDN服务器的IP(即当前remote_addr)添加到x_forwarded_for的后面,这样x_forwarded_for里就会存在两个值。Nginx会使用这些值里的第一个,即客户的真实IP,而PHP则会使用第二个,即CDN的地址。为了能让PHP也使用第一个值,你需要添加以下fastcgi的配置。

fastcgi_param HTTP_X_FORWARDED_FOR $http_x_forwarded_for;

它会把nginx使用的值(即第一个IP)传给PHP,这样PHP拿到的x_forwarded_for里其实就只有一个值了,也就不会用第二个CDN的IP了。

忽略x_forwarded_for

其实,当你使用了Nginx的realip模块后,就已经保证了remote_addr里设定的就是客户端的真实IP,再看下这个配置
set_real_ip_from   10.1.10.0/24;
real_ip_header     X-Forwarded-For;

它就是把x_forwarded_for设为remote_addr,而nginx里的x_forwarded_for取的就是其中第一个IP。使用这些设置就能保证你的remote_addr里设定的一直都是客户端的真实IP,而x_forwarded_for则可以忽略了。

使用"HTTP_X_FORWARDED_FOR"获取到的IP地址,有以下几种情况。

1)、没有使用代理服务器:
REMOTE_ADDR = 您的 IP
HTTP_VIA = 没数值或不显示
HTTP_X_FORWARDED_FOR = 无数值或不显示

2)、使用透明代理服务器(Transparent Proxies):
REMOTE_ADDR = 最后一个代理服务器 IP
HTTP_VIA = 代理服务器 IP
HTTP_X_FORWARDED_FOR = 您的真实 IP ,经过多个代理服务器时,这个值类似如下:118.168.8.66, 119.188.68.169, 119.188.68.231

此类代理服务器仍然将您的信息转发给您的访问对象,无法达到隐藏真实身份的目的。

3)、使用普通匿名代理服务器(Anonymous Proxies):
REMOTE_ADDR = 最后一个代理服务器 IP
HTTP_VIA = 代理服务器 IP
HTTP_X_FORWARDED_FOR = 代理服务器 IP ,经过多个代理服务器时,这个值类似如下:119.188.68.169, 119.188.68.231

此类代理服务器隐藏了您的真实IP,但是向访问对象透露了您是使用代理服务器访问他们的。

4)、使用欺骗性代理服务器(Distorting Proxies):
REMOTE_ADDR = 代理服务器 IP
HTTP_VIA = 代理服务器 IP
HTTP_X_FORWARDED_FOR = 随机的 IP ,经过多个代理服务器时,这个值类似如下:3.6.9.12, 119.188.68.169, 119.188.68.231

此类代理服务器告诉了访问对象您使用了代理服务器,却编造了一个虚假的随机IP代替您的真实IP欺骗它。

5)、使用高匿名代理服务器(High Anonymity Proxies (Elite proxies)):
REMOTE_ADDR = 代理服务器 IP
HTTP_VIA = 没数值或不显示
HTTP_X_FORWARDED_FOR = 没数值或不显示 ,经过多个代理服务器时,这个值类似如下:119.188.68.169, 119.188.68.231

此类代理服务器完全用代理服务器的信息替代了您的所有信息,就象您就是完全使用那台代理服务器直接访问对象一样。最后一次代理服务器的地址并没有记录在代理链中,因此只记录 X-Forwarded-For 字段是不够的。完整起见,Web服务器应该记录请求来源的IP地址以及X-Forwarded-For 字段信息。

error_log

The syntax of the error_log directive is
error_log /path/to/log_file log_level;
error_log log_file [ log_level ]

Example
error_log /var/log/nginx/error_log warn;


错误日志类型

类型1: upstream timed out
类型2: connect() failed
类型3: no live upstreams
类型4: upstream prematurely closed connection
类型5: 104: Connection reset by peer
类型6: client intended to send too large body
类型7: upstream sent no valid HTTP/1.0 header

详细说明

类型

错误日志

原因

解决办法

类型

错误日志

原因

解决办法

1upstream timed out (110: Connection timed out) while connecting to upstreamnginx与upstream建立tcp连接超时,nginx默认连接建立超时为200ms排查upstream是否能正常建立tcp连接
1upstream timed out (110: Connection timed out) while reading response header from upstreamnginx从upstream读取响应时超时,nginx默认的读超时为20s,读超时不是整体读的时间超时,而是指两次读操作之间的超时,整体读耗时有可能超过20s排查upstream响应请求为什么过于缓慢
2connect() failed (104: Connection reset by peer) while connecting to upstreamnginx与upstream建立tcp连接时被reset排查upstream是否能正常建立tcp连接
2connect() failed (111: Connection refused) while connecting to upstreamnginx与upstream建立tcp连接时被拒排查upstream是否能正常建立tcp连接
3no live upstreams while connecting to upstreamnginx向upstream转发请求时发现upstream状态全都为down排查nginx的upstream的健康检查为什么失败
4upstream prematurely closed connectionnginx在与upstream建立完tcp连接之后,试图发送请求或者读取响应时,连接被upstream强制关闭排查upstream程序是否异常,是否能正常处理http请求
5recv() failed (104: Connection reset by peer) while reading response header from upstreamnginx从upstream读取响应时连接被对方reset排查upstream应用已经tcp连接状态是否异常
6client intended to send too large body客户端试图发送过大的请求body,nginx默认最大允许的大小为1m,超过此大小,客户端会受到http 413错误码
  1. 调整请求客户端的请求body大小;
  2. 调大相关域名的nginx配置:client_max_body_size;
7upstream sent no valid HTTP/1.0 headernginx不能正常解析从upstream返回来的请求行排查upstream http响应异常


日志级别(Logging Levels)

The error_log directive can be configured to log more or less information as required. The level of logging can be any one of the following:
emerg: Emergency situations where the system is in an unusable state.
alert: Severe situation where action is needed promptly.
crit: Important problems that need to be addressed.
error: An Error has occurred. Something was unsuccessful.
warn: Something out of the ordinary happened, but not a cause for concern.
notice: Something normal, but worth noting has happened.
info: An informational message that might be nice to know.
debug: Debugging information that can be useful to pinpoint where a problem is occurring.



参考来源:

HTTP_X_FORWARDED_FOR获取到的IP地址

如何正确设置nginx中remote_addr和x_forwarded_for参数