`
QING____
  • 浏览: 2249821 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

nginx/tomcat日志格式规范

 
阅读更多

    最近准备设计和开发一套日志收集平台,进而后续进行实时的日志分析、业务监控和预警等。在此之前,需要制定日志的格式规范,当然还有其他的约束性规范,才能良好的实现日志搜集、数据分拣、数据分析等特性。

 

    制定日志格式规范的方式与目的:

    1)所有项目,日志格式统一,可以极大的简化日志收集和分析的复杂度。

    2)nginx、tomcat等日志格式,需要合理,让日志查看和问题排查更加便捷,排除不用的字段信息,增加更多的有效字段。

    3)考虑到日志格式将来总会要变化,但是日志数据会被运维、开发、大数据平台、BI、安全等团队共同使用,为了避免日志格式的变化给所有相关团队带来干扰,降低改动的影响面,我们将日志中的字段进行分“域”;每个域包括多个字段,不同的团队关注不同的域,某个域中的字段列表改动时,不影响其他团队对数据的使用。我们解析日志数据时,首先将日志按照域分隔符分成多个"域",然后根据字段在域中的相对位置来获取字段值,而不是使用字段在整条日志的位置。我们使用“^_^”符号作为域分隔符。

    4)为了便于数据分拣、日志收集,我们约定所有的日志文件名必须遵循统一规则,这对Flume进行数据搜集非常有利。比如nginx日志、tomcat access log、业务日志等,日志的文件名遵循:<project-name>.<tag>.log.<yyyy-MM-dd>.<index>;例如:order-center.error.log.2017-10-11.0,其中<index>为rolling时生成的索引号。统一日志名称的原因是:易于通过文件名了解日志的来源和核心特性,此外对于Flume而言可以从文件名中得知项目的名称、日志等重要信息,既可以在收集时对日志进行按项目、日志进行分类存储。

    5)严格控制日志文件的大小,适时对日志文件进行rolling,我们约定任何日志文件的大小不得超过256M,超过此值时应该对日志进行rolling。原因非常简单,较大的日志文件既不便于收集、传输,也不便于进行查看,此外较大的日志还会降低文件IO的效率。在此基础上,我们要求在打印日志时需要对日志信息进行合理规划,尽可能精简日志信息,冗杂而庞大的日志信息不仅价值较低,而且消耗存储,此外较大的日志内容输出还会增加宿主机器的IO负载,毕竟我们的普通的application机器的IOPS通常不高。

    6)为了便于日志分拣、日志内容的可读性、本地性,我们在nginx、tomcat等所有日志内容中,都打印“当前机器的IP”、“日志产生的时间戳”等标记信息。

 

1、nginx日志格式:

log_format  main  '$time_local|$hostname|$remote_addr|$upstream_addr|$request_time|$upstream_response_time|$upstream_connect_time|'

'$status|$upstream_status|-|$bytes_sent|-|-|$remote_user|$request|$http_user_agent|$http_referer|^_^|'

'$scheme|$request_method|$request_trace_id|$request_trace_seq|^_^|'

'$http_x_forwarded_for|$http_Authorization|$cookie_uid';

 

    其中有几个“-”占位符,本人使用nginx 1.10版本,但是有几个非常重要的字段需要等到1.11版本发布后才能使用,所以此处先用“-”占位。

    nginx日志格式,本人参考了AWS ELB,我觉得ELB的日志格式还是比较规范,具有较高的参考价值。此处的nginx格式,与ELB日志格式在字段含以上一一对应,对于nginx缺失的字段,先用“-”占位。

   我们将nginx日志分为四个域,第一个域包含一些最常用、最重要的字段,通常与性能评估、数据分拣有关系;第二个域表示此次请求的一些状态信息,排查问题时可以关注此域;第三个域,是关于请求追踪的,我们为每个请求设定request_id等(其中$request_trace_id,$request_trace_seq是自定义的变量),此后在业务监控时可以将异常请求的全追踪链整理出来;第四个域,面向开发,通常用于打印一些HTTP参数等。

    $request_trace_id和$request_trace_seq是自定义的变量,分别表示“请求的追踪ID”和“请求追踪的序列数字”:

    一个新的请求都会有一个唯一的trace_id,此trace_id通常有最顶层proxy负责生成,生成后将会把trace_id添加到header中并传递给upstream层(tomcat等),upstream应用中如果有请求扇出,则继续将此trace_id下发,最终实现请求的链路追踪,我们将链路的追踪信息收集并整理,后期用于评估接口性能、业务监控、流量异常发现、容量规划等。

    如果proxy层发现请求的header中已经包含trace_id,那么我们认为此请求是“链路的一个环节”而不是一个新的请求,此时保留trace_id,并添加到header中继续转发。request_trace_seq默认为0,有upstream负责进行维护seq的值,比如每次下发对其值进行自增,nginx不负责此值的自增的原因是希望有应用程序自己决定seq的顺序。

##trace.setting
set	$request_trace_id $http_x_request_id;
set $request_trace_seq $http_x_request_req;

if ( $request_trace_id = '' ) {
	set	$request_trace_id $pid-$connection-$bytes_sent-$msec;
}
if ( $request_trace_seq = '' ) {
   set	$request_trace_seq 0;
}

 

....
server {
    listen       80;
    server_name  demo.com;
    include trace.setting;
    access_log  /var/log/nginx/demo.log  main;
    proxy_send_timeout      1800s;
    proxy_read_timeout      1800s;    

    location / {
            proxy_pass         http://10.0.0.1:8080;
            proxy_set_header   Host             $host;
            proxy_set_header   X-Request-ID $request_trace_id;
            proxy_set_header   X-Request-Seq $request_trace_seq;
    }
}
....

 

    字段含义(逐一对应):

字段名                          解释
time_local                   日志时间
hostname                 当前机器的hostname(非IP)
remote_addr                  客户端地址
upstream_addr               后端Server的地址
request_time            nginx处理请求的时长,从获取Client请求的首个字节开始到响应数据发送完毕,单位为“秒 + 毫秒”
upstream_response_time      从nginx与upstream建立连接开始到response数据接收完毕。
upstream_connect_time     与upstream建立连接的时间。
status                  nginx响应状态码
upstream_status        upstream返回给nginx的状态码(tomcat或者后继nginx)
bytes_received         nginx接收到Client的请求数据大小,1.11版本才能支持,此处用“-”占位符替代
bytes_sent               nginx返回给Client的数据大小
upstream_bytes_sent      nginx发送给upstream的字节数,1.11版本才支持,此处使用“-”占位符替代
upstream_bytes_received   nginx接收到upstream响应的字节数,1.11版本才支持,此处使用“-”占位符替代
remote_user            基本认证中的user信息
request                   HTTP请求行—首行
http_user_agent         标头中“User-Agent”值
http_referer              标头中“Referer”值
scheme                  请求的Scheme,HTTP或者HTTPS
request_method            HTTP(S)请求的方法名:GET,POST等
request_trace_id        获取标头中“X-Request-ID”值,如果不包含此header,则创建新的Trace_id。
request_trace_seq       获取标头中“X-Request-Seq”值,如果存在,表明此请求是trace link下发的请求。此值用于追踪请求链的层级或者顺序
http_{key}           获取HEADER中指定key的值。
cookie_{key}          获取COOKIE中指定key的值。

 

 2、Tomcat Access log格式规范

    对于JAVA WEB项目,tomcat提供了内置的access日志机制,有点类似于nginx的access日志;在开启时,tomcat会把接收到的请求信息打印在日志中,这对我们分析数据、排查问题、性能检测等有很大帮助。只需要修改server.xml文件即可:

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"

               prefix="access.log" suffix="" renameOnRotate="true"

pattern="%{yyyy-MM-dd HH:mm:ss}t|%A|%a|%p|%m|%s|%D|

%b|%{begin:msec}t|%{end:msec}t|^_^|

%{X-Request-ID}i|%{X-Request-Seq}i|^_^|

%S|%r|%{Referer}i|%{User-Agent}i" />

 

    基本原则跟nginx一样,分域,第一个域仍然是关于数据分拣、性能检测相关;第二个域是关于请求追踪的,将来对接追踪链系统;第三个域,是开发关注的,通常是打印一些HTTP 参数等。不过比较遗憾的是,tomcat access日志所能提供的字段信息比较少,没有nginx那么丰富。

    此外,为了让access log的文件名称遵循规范要求,我们在prefix和suffix的配置上做了调整。

    为了达成请求追踪的目的,我们在tomcat access log中也打印了request_trace_id和seq的相关信息。

 

3、业务日志格式

    我们的java程序内部也会打印一些日志,这些日志对问题排查、业务监控、数据统计非常重要,但是这些数据的使用者通常是大数据团队、BI部分、架构团队等,因此规范这些日志的格式至关重要;此外格式统一,对于开发工程师跨团队协作也非常有益。

    原则不变:便于数据分拣、分域;不过为了更好的执行,在此之前,我们需要约定日志组件为logback + sl4j;因为我们会使用logback中的MDC机制,来打印更多的运行时信息。

<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <pattern>%d{yyyy-MM-dd/HH:mm:ss.SSS}|%X{localIp}|%X{requestId}|%X{requestSeq}|^_^|uid:%X{uid}|^_^|[%t]|%-5level|%logger{50} %line - %m%n</pattern>
</encoder>

 

    整个过程中,我们将request_id从nginx传递到tomcat,在传递到java应用内部,主要是为后期的请求追踪平台做铺垫,同时我们排查问题也将更加容易。需要注意,%X{requestId}和%X{requestSeq}都是经过MDC Filter进行分装后的。

    在第二个域中,允许每个项目自定义各自的日志字段,为K-V模式,比如“uid:10010|orderId:10000”,K-V之间通过“:”分割,此后我们日志分析组件可以将它们解析成map并保存,比如保存在ES中。之所以这么做的原因是,每个业务系统需要打印的自定义字段各有不同,这对后续的数据分析和统计组件有较大的挑战,为了简化后续操作,我们将用户自定义字段部分结构松耦合。

 

    在上文中,我们还提到业务日志的大小问题,这就需要采用一定的rolling策略,我们约定所有项目的logback组件的版本不低于1.1.7,并统一rolling策略:

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_HOME}/order-center.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <fileNamePattern>${LOG_HOME}/order-center.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
        <maxFileSize>256MB</maxFileSize>
        <maxHistory>15</maxHistory>
        <totalSizeCap>32GB</totalSizeCap>
    </rollingPolicy>
….
</appender>

 

4、基础数据平台规划

    1)基于Flume组件,对全网项目的日志文件进行收集,包括历史文件(每天rotate生成的、rolling生成的文件)和实时日志信息(tail);将日志文件统一保存在一个或者多个堡垒机(group server)上,并将日志按照项目、时间进行归类。

    2)业务系统通常是分布式部署,一个project部署在多个机器上,每个机器都会产生新的日志信息,如果遇到线上问题,排查期间需要访问多个机器,为了解决这个问题,我们将每个项目实时产生的日志信息,统一汇总在堡垒机上一个文件中,比如:堡垒机上的/order-center/2017-10-11/access.log.tail,此文件保存了order-center项目中2017-10-11,多个tomcat实时的日志,它们混合在一起。

    3)Flume将实时日志转发到kafka中,其他数据统计、分析系统通过kafka消费数据。此外我们的Flume将采用“多层”架构设计,每个application宿主机器上部署一个Flume agent,同一个项目的agent将数据发给一个Flume collector(也是一个Flume agent),并统一由collector对日志信息进行分类、本地存储、Filter、以及转发给kafka等。

    4)基于storm + kafka对实时日志信息进行分析,并根据规则匹配日志内容,当遇到“业务异常”、“流量异常”等情况是,触发报警,并将相应的信息进行整理,形成traceing link并展示给相关人员。

分享到:
评论
2 楼 QING____ 2017-01-21  
hao_foo 写道
日志收集、分析、监控? 好像跟ELK 功能很相似。期待...
是的,前期将全链路的日志进行规范和统一,然后使用ELK、KAFKA、flume、storm/Spark进行分析或者展示,最终解决业务监控、数据分析、日志收集等特性。
1 楼 hao_foo 2017-01-16  
日志收集、分析、监控? 好像跟ELK 功能很相似。期待...

相关推荐

    Nginx+Tomcat负载均衡

    最近学习Nginx+tomcat实现 负载均衡。 首先大家注意: 本文章中没有session共享,关于session共享我会在下一篇中讲解,先实现Nginx+tomcat负载均衡再实现session共享。 从网上查了好多资料,多走了很多弯路,现在把...

    Nginx+Tomcat9搭建负载均衡实例,解压即可运行

    Tomcat9是Apache软件基金会的Jakarta项目中的一个核心项目,是一个开源的Servlet容器,主要实现了Java Servlet和JavaServer Pages(JSP)规范。Tomcat9支持最新的Java EE 8标准。 3. **负载均衡概念** 负载均衡是...

    基于CentOS 7.6 配置Nginx + Tomcat

    ### Nginx与Tomcat的集成 在本篇文章中,作者介绍了如何在CentOS 7.6上配置Nginx和Tomcat,使得Nginx可以作为反向代理服务器将不同路径的HTTP请求转发给不同的Tomcat实例。这种方式可以用来部署多个Web应用,同时还...

    Nginx+KeepAlived+Tomcat负载架构

    - **简介**:Apache Tomcat是一个开源的Servlet容器,它是实现SUN Microsystems公司制定的Servlet规范和JSP规范的一个免费的实现。 - **作用**:作为Web应用程序服务器,用于运行Java Web应用程序。 #### 三、架构...

    nginx和tomcat整合.pdf

    - **Tomcat**:Apache软件基金会的一个开源项目,用来实现Java Servlet规范以及JavaServer Pages(JSP)技术。 #### 二、准备工作 1. **下载并安装Nginx** - 下载地址:[http://nginx.org/download/]...

    Tomcat安全管理规范-线上运行配置规范

    ##### 3.10 访问日志格式规范(推荐) 统一访问日志格式,便于后续的日志分析和监控。 #### 四、总结 综上所述,为了确保Tomcat在线上的稳定运行和安全性,需要严格按照上述规范来进行安装、配置和安全管理。通过...

    三件套:tomcat8、Nginx1.2、jdk1.8

    Tomcat 8支持Java Servlet 3.1和JavaServer Pages (JSP) 2.3规范,提供了高效的性能和稳定性。开发者可以将自己编写的Web应用打包成WAR文件,然后将其放在Tomcat的webapps目录下,Tomcat会自动解压并启动应用。...

    nginx0.8+tomcat6

    在IT行业中,构建高效、可扩展的Web服务是至关重要的,而`nginx0.8`与`tomcat6`的组合就是一种常见的解决方案。`nginx`作为一款高性能的反向代理服务器,通常用于处理静态资源和实现负载均衡,而`tomcat`则是流行的...

    nginx+tomcat7+memcached所需jar

    "nginx+tomcat7+memcached"的组合就是一种常见的优化方案,它结合了Nginx的高性能反向代理能力,Tomcat7作为Java应用服务器,以及Memcached作为分布式缓存系统。下面我们将详细探讨这些技术以及它们集成所需的jar包...

    tomcat7 For Linux

    - 使用Nginx、HAProxy等工具实现Tomcat集群的负载均衡,提高系统的可用性和扩展性。 - 配置会话共享策略,确保用户请求的一致性。 ### 安全性 - **禁用不必要的服务**:如关闭默认的管理界面(除非进行了足够的...

    Nginx+Tomact集群部署

    - **Apache Tomcat**:简称Tomcat,是Apache软件基金会的一个开源项目,它实现了Servlet和JavaServer Pages等技术规范,能够作为Web服务器来处理各种数据。Tomcat通常用于部署Java Web应用程序。 #### 二、Nginx...

    apache-tomcat-8.5.51.tar.gz

    1. **Catalina**:这是Tomcat的核心组件,负责实现Servlet和JavaServer Pages (JSP) 规范。Catalina处理HTTP请求,并将它们分发到相应的Web应用程序。 2. **Jasper**:Jasper是Tomcat中的JSP编译器,它将JSP文件...

    apache-tomcat-7.0.73.tar.gz

    Tomcat是Apache软件基金会Jakarta项目的一部分,它实现了Java EE的Web组件规范,尤其是Servlet和JSP规范。这个版本7.0.73是针对7.x系列的一个稳定版本,包含了错误修复和性能优化。 在Linux环境下部署Apache Tomcat...

    apche_tomcat1.14.2-and-nginx8.5.65.zip

    Apache Tomcat 是一个开源的Java Servlet容器,它实现了Java EE的Web部分,包括Servlet、JavaServer Pages(JSP)和Java EE的WebSocket规范。Tomcat 8.5.65 版本是一个稳定的版本,支持最新的Java技术,并提供了性能...

    apache-tomcat-7.0.54+memcached+nginx

    Apache Tomcat 7.0.54 是一个广泛使用的开源Java Servlet容器,它实现了Java EE Web应用程序规范。在这个场景中,我们关注的是如何在Tomcat 7集群中配置和使用memcached以及配合Nginx进行负载均衡。Memcached是一种...

    tomcat+redis+nginx集群搭建所需jar包

    - **tomcat-juli-7.0.61.jar**:Tomcat的日志系统,提供自定义的日志记录功能。 - **tomcat-util-7.0.61.jar**:Tomcat的一些实用工具类,如线程池和字符串处理等。 - **tomcat-redis-session-manager-master-...

    同时部署多个Tomcat

    在IT行业中,Tomcat是一个广泛使用的Java Servlet容器,它实现了Java EE的Web应用程序规范。当需要在同一台服务器上运行多个不同的Web应用或者为了负载均衡、故障恢复等原因,我们需要部署多个Tomcat实例。以下是对...

Global site tag (gtag.js) - Google Analytics