Tomcat Access Log配置 - xiaobaoqiu Blog
1.配置的位置
项目conf目录下的server.xml文件,其中的AccessLogValve这个Valve的配置,比如下面这个配置:
2.参数详解
Tomcat AccessLogValve支持写列配置参数:
2.1 className
执行Access Log任务的类,默认是org.apache.catalina.valves.AccessLogValve;也可以使用org.apache.catalina.valves.FastCommonAccessLogValve,但这时候只支持common和combined patterns。
2.2 directory
AccessLogValve产生的Access Log文件存放目录的绝对路径或者相对路径。如果是相对路径,那么是相对$CATALINA_HOME的。如果没有指定这个参数,默认值是"logs"(相对$CATALINA_HOME)。
2.3 pattern
用于指定展示在Access Log中的各种request和response的信息字段的格式,也可以使用单词common或者combined来选择一种标准的日志形式。下一节会详细介绍。
注意优化的access只支持common和combined格式。
2.4 prefix
每个Access Log文件的文件名前缀,如果没有指定,默认是"access_log.“,如果想没有前缀,则指定一个空的字符串(zero-length string)。
2.5 resolveHosts
如果设置为true,则会通过DNS lookup将远程主机的IP地址转换成对应的主机。设置成false则跳过这个DNS lookup过程,然后在日志中直接展示IP地址。
2.6 suffix
每个Access Log文件的文件名后缀,如果没有指定,默认值是“”,如果想没有后缀,则指定一个空的字符串(zero-length string)。
2.7 rotatable
默认为true。这个参数决定是否需要切换切换日志文件,如果被设置为false,则日志文件不会切换,即所有文件打到同一个日志文件中,并且fileDateFormat参数也会被忽略。小心使用这个参数。
2.8 condition
设置是否打开条件日志,如果设置了这个参数,requests只有当ServletRequest.getAttribute()为null的时候才会被记录日志。比如这个值被设置成junk,然后当一个特定请求的ServletRequest.getAttribute(“junk”) == null的时候,这个request会被记录。使用Filters很容易在ServletRequest中设置或者不设置这个属性。
2.9 fileDateFormat
Tomcat允许指定Access Log文件名中日期格式。日期格式同时也决定了如何切换日志文件的策略,比如如果你想每小时生成一个日志文件,设置这个值为yyyy-MM-dd.HH。
3.pattern参数
pattern属性有一系列的字符串参数组成,每个参数都有前缀"%“,目前支持下面这些参数:
%a - 远程IP地址 %A - 本地IP地址 %b - 发送的字节数(Bytes sent), 不包括HTTP headers的字节,如果为0则展示'-' %B - 发送的字节数(Bytes sent), 不包括HTTP headers的字节 %h - 远程主机名称(如果resolveHosts为false则展示IP) %H - 请求协议 %l - 远程用户名,始终为'-'(Remote logical username from identd) %m - 请求的方法(GET, POST等) %p - 接受请求的本地端口 %q - 查询字符串,如果存在,有一个前置的'?' %r - 请求的第一行(包括请求方法和请求的URI) %s - response的HTTP状态码(200,404等) %S - 用户的session ID %t - 日期和时间,Common Log Format格式 %u - 被认证的远程用户, 不存在则展示'-' %U - 请求URL路径 %v - 本地服务名 %D - 处理请求的时间,单位为毫秒 %T - 处理请求的时间,单位为秒 %I - 当前请求的线程名(can compare later with stacktraces)
另外,Access Log中也支持cookie,请求header,响应headers,Session或者其他在ServletRequest中的对象的信息。格式遵循apache语法:
%{xxx}i 请求headers的信息 %{xxx}o 响应headers的信息 %{xxx}c 请求cookie的信息 %{xxx}r xxx是ServletRequest的一个属性 %{xxx}s xxx是HttpSession的一个属性
common模式的pattern(即默认pattern参数)的格式为'%h %l %u %t “%r” %s %b'。
combined模式的pattern可以增加Referer和User-Agent headers的参数形式,每个参数用双引号包起来,引号中的内容还是上面列举的参数。比如"%{User-Agent}i"使其为”%{User-Agent}i“,即请求的User-Agent(客户端,浏览器)。
了解CMS(Concurrent Mark-Sweep)垃圾回收器 - Java,JVM,CMS,垃圾回收,jc - Java - ITeye论坛
1.总体介绍:
CMS(Concurrent Mark-Sweep)是以牺牲吞吐量为代价来获得最短回收停顿时间的垃圾回收器。对于要求服务器响应速度的应用上,这种垃圾回收器非常适合。在启动JVM参数加上-XX:+UseConcMarkSweepGC ,这个参数表示对于老年代的回收采用CMS。CMS采用的基础算法是:标记—清除。
2.CMS过程:
- 初始标记(STW initial mark)
- 并发标记(Concurrent marking)
- 并发预清理(Concurrent precleaning)
- 重新标记(STW remark)
- 并发清理(Concurrent sweeping)
- 并发重置(Concurrent reset)
初始标记 :在这个阶段,需要虚拟机停顿正在执行的任务,官方的叫法STW(Stop The Word)。这个过程从垃圾回收的"根对象"开始,只扫描到能够和"根对象"直接关联的对象,并作标记。所以这个过程虽然暂停了整个JVM,但是很快就完成了。
并发标记 :这个阶段紧随初始标记阶段,在初始标记的基础上继续向下追溯标记。并发标记阶段,应用程序的线程和并发标记的线程并发执行,所以用户不会感受到停顿。
并发预清理 :并发预清理阶段仍然是并发的。在这个阶段,虚拟机查找在执行并发标记阶段新进入老年代的对象(可能会有一些对象从新生代晋升到老年代, 或者有一些对象被分配到老年代)。通过重新扫描,减少下一个阶段"重新标记"的工作,因为下一个阶段会Stop The World。
重新标记 :这个阶段会暂停虚拟机,收集器线程扫描在CMS堆中剩余的对象。扫描从"跟对象"开始向下追溯,并处理对象关联。
并发清理 :清理垃圾对象,这个阶段收集器线程和应用程序线程并发执行。
并发重置 :这个阶段,重置CMS收集器的数据结构,等待下一次垃圾回收。
CSM执行过程:
3.CMS缺点
- CMS回收器采用的基础算法是Mark-Sweep。所有CMS不会整理、压缩堆空间。这样就会有一个问题:经过CMS收集的堆会产生空间碎片。 CMS不对堆空间整理压缩节约了垃圾回收的停顿时间,但也带来的堆空间的浪费。为了解决堆空间浪费问题,CMS回收器不再采用简单的指针指向一块可用堆空 间来为下次对象分配使用。而是把一些未分配的空间汇总成一个列表,当JVM分配对象空间的时候,会搜索这个列表找到足够大的空间来hold住这个对象。
- 需要更多的CPU资源。从上面的图可以看到,为了让应用程序不停顿,CMS线程和应用程序线程并发执行,这样就需要有更多的CPU,单纯靠线程切 换是不靠谱的。并且,重新标记阶段,为空保证STW快速完成,也要用到更多的甚至所有的CPU资源。当然,多核多CPU也是未来的趋势!
- CMS的另一个缺点是它需要更大的堆空间。因为CMS标记阶段应用程序的线程还是在执行的,那么就会有堆空间继续分配的情况,为了保证在CMS回 收完堆之前还有空间分配给正在运行的应用程序,必须预留一部分空间。也就是说,CMS不会在老年代满的时候才开始收集。相反,它会尝试更早的开始收集,已 避免上面提到的情况:在回收完成之前,堆没有足够空间分配!默认当老年代使用68%的时候,CMS就开始行动了。 – XX:CMSInitiatingOccupancyFraction =n 来设置这个阀值。
总得来说,CMS回收器减少了回收的停顿时间,但是降低了堆空间的利用率。
参考:
remark如果耗时较长,通常原因是在cms gc已经结束了concurrent-mark步骤后,旧生代的引用关系仍然发生了很多的变化,旧生代的引用关系发生变化的原因主要是:
* 在这个间隔时间段内,新生代晋升到旧生代的对象比较多;
* 在这个间隔时间段内,新生代没怎么发生ygc,但创建出来的对象又比较多,这种通常就只能是新生代比较大的原因;
问题:有一个应用出现了cms gc remark通常要消耗4–5s的现象,由于remark是stw(stop-the-world)的,因此造成了应用暂停时间过长的现象。这个应用当时的启动参数的-Xmn为16g,但每次ygc后存活的其实不多,因此基本可以确定是由于新生代太大导致的,于是建议应用方将-Xmn降到了4g,remark时间很快就缩短到了几百ms,基本符合预期。
potential memory leak when using RAMDirectory ,CloseableThreadLocal and a thread pool .
Lucene的文档缓存数据会绑定线程,随着线程退出而清除。
On Thu, Jan 3, 2013 at 12:16 PM, Alon Muchnick <alon [at] datonics> wrote:
> hi Mike ,
>
> at the peak there are 500 live threads going through Lucune (not all of
> them at the same time , tomcat thread pool uses round robin ) ,regarding
> the Directory impl we are using RAMDirectory.
> the object that takes most of the heap is the "hardRefs" WeakHashMap class
> member in the CloseableThreadLocal class . the size of the map is 500 ,
> with one entry for each thread that went through Lucune.
Hmm ... I'm curious what's actually using up all the RAM here.
A buffered Directory impl (eg NIOFSDirectory) would have IndexInput
clones that have 1 KB buffers, but RAMDirectory doesn't do that.
> when in run the test with only one thread the initial RAM did not grow much
> beyond the initial 30MB .
OK that's good. So somehow each thread ties up ~ 1 MB RAM.
> when looking at the code i can see that the references to the hardRefs map
> will be cleared when :
>
> 1.a thread which searched Lucune is no longer alive , so its corresponding
> record in the map will be cleared either by the GC or by the purge() method
> .
>
> 2.the close() method is called which "should only be called when all
> threads are done using the instance" .
Right.
> what happens to threads that go through Lucune and stay alive for a very
> long times ?
> will they always be a reference key in the hardRefs map for them ?
Yes ... we never prune live threads.
> if so does the value for the corresponding record in the map will be
> overwritten each time this thread makes a new search ? or will it be some
> how accumulated ? :
Well, we set the value once when we first see the thread, and then use
that value from then on.
> value ---- org.apache.lucene.index.TermInfosReader$ThreadResources --->
>
> termInfoCache |org.apache.lucene.util.cache.SimpleLRUCache
> termEnum |org.apache.lucene.index.SegmentTermEnum
>
> i have reduced the size of the thread pool , and changed to a more
> aggressive thread closing policy ,threads are now reduced when they are not
> needed (before that the thread pool would reach its max size and stayed
> there),
> this should kick in the the purge method and reclaim memory from the closed
> threads .
>
> ill give the system a few hours to run and update on the results .
OK thanks.
Really anything more then 2 * number-of-cores threads coming through
Lucene is overkill ...