在实际使用中,使用F5或LVS为tomcat做负载均衡时,由于做了反向代理,tomcat记录的Aceess Log中,会将客户端ip记录为F5或lvs的ip,导致无法正常记录访问者的真实ip信息.
Tomcat配置中,可以通过修改AceessLogValve/ExtendedAceessLogValve的设置,解决这个问题.
Tomcat Log 如何记录Access Log
tomcat记录access log, 由conf目录下的server.xml配置.一个典型的配置如下:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
AccessLogValve中的pattern属性决定了log中需要记录哪些信息, 相应的pattern规范可以参考tomcat 的官方文档,有比较详细的说明.
pattern说明
下面介绍下如果在反向代理情况下记录用户真实的ip信息.
AceessLogValve
使用默认的AceessLogValve记录日志时,pattern 属性中可以使用%{xxx}i的格式获取请求的header信息. 故使用%{X-Forwarded-For}i即可获取请求中的X-Forwarded-For信息,即经过反向代理后的客户端真实ip.
配置文件的写法类似如下:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%{X-Forwarded-For}i %h %l %u %t "%r" %s %b" />
</Host>
ExtendedAceessLogValve
我们在项目中使用ExtendedAceessLogValve进行日志记录,主要是为了使日志遵守W3C标准, 使用ExtendedAceessLogValve时,可以在pattern 属性中使用cs(X-Forwarded-For)获取客户端真实ip,原理和AceessLogValve一致,只是写法不一样.
配置文件的写法类似如下:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.ExtendedAccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="cs(X-Forwarded-For) c-ip s-ip date time cs-method cs-uri sc-status bytes time-taken" />
</Host>