标签:
eslf4j的maven项目托管在https://github.com/xionghuiCoder/eslf4j,同时也可以在http://www.oschina.net/p/eslf4j上了解它的简单介绍。
eslf4j(expand slf4j)主要用于解决线上日志的bug定位问题。 对于大并发的网站,为了保证性能,往往设置日志级别为error,但是在这种情况下,如果线上出现了bug,往往只有一条错误日志,这对于定位问题几乎没有任何帮助,因为导致这个error往往是由于上下文的一个或几个错误数据或操作导致的,而上下文的info或debug日志并没有输出。
eslf4j可以缓存上下文日志,比如上面那种情况,一旦出现error,会打印出该error前的debug或info级别的日志。然而如果不出现error,则不会打印任何日志。这样既方便定位问题,也能防止输出大量日志而影响性能。
count=100 buffersize=10m minthreshold=debug filter=com.jd.o2o.filter.Null1Filter filter=com.jd.o2o.filter.Null2Filter memorymanager=com.jd.o2o.memory.NullMemoryManager
count为缓存的日志数量,必须配置(否则可能会造成内存泄露,这跟线程连接池和ThreadLocal的实现有关,就不详解了);比如这里配置为100,表示一旦打印一条日志,会同时打印出该条日志前的100条日志。
buffersize为eslf4j缓存的日志所占用的空间,必须配置,当缓存达到配置的大小时就会使用memorymanager来释放内存;这里配置的buffersize为10m,表示缓存最多会占用10m内存,另外支持单位b(bit),k(kb),g(gb)。
minthreshold为日志级别的最低闸值,必须配置,支持all,trace,debug,info,warn,error,fatal和off;比如这里配置为debug,只有级别大于或等于debug的日志才会被缓存并打印出来。
filter是日志过滤器,可以配置也可以不配置,当然也可以配置多个;filter需要实现com.jd.o2o.core.filter.Filter接口,而且需要一个无参构造器;filter会在日志被缓存前调用,可以自处理日志。
memorymanager用于管理内存,可以配置也可以不配置,memorymanager需要实现com.jd.o2o.core.memory.IMemoryManager接口,而且需要一个无参构造器,如果不配置会默认使用com.jd.o2o.core.memory.impl.DefaultMemoryManagerImpl来管理内存,memorymanager会在日志缓存达到buffersize时调用来释放内存。
1) filter是一个扩展点,需要实现com.jd.o2o.core.filter.Filter接口,Filter接口用于处理com.jd.o2o.core.bean.MessageBean,MessageBean包含日志message和throwable,filter可以修改日志或者修改异常,比如想要过滤掉带有"debug"字符串的message可以定义以下filter:
private static final String DEBUG_SIGN = "debug"; @Override public boolean doFilter(MessageBean messageBean) { String message = messageBean.getMessage(); if (message == null) { throw new Eslf4jException("message should not be null"); } if (message.contains(DEBUG_SIGN)) { // 返回false则不会缓存,也不会打印 return false; } return true; }
2) memorymanager是另外一个扩展点,默认会使用com.jd.o2o.core.memory.impl.DefaultMemoryManagerImpl来管理内存,当缓存的日志达到buffersize时,DefaultMemoryManagerImpl会清空部分线程的日志缓存,这样保证了空间的可用性,但是可能会丢失部分线程缓存的上下文日志,所以如果使用默认的DefaultMemoryManagerImpl最好配置好count和buffersize,可以通过以下公式来计算出合适的buffersize(单位为m):
buffersize = count*活动的线程数*平均每条日志的长度*2/1024
当然也可以自定义memorymanager,需要实现IMemoryManager接口,比如想要在清空缓存前输出上下文日志,可以定义以下memorymanager:
@Override public void manager(FixedQueue queue) { while (queue.size() > 0) { MessageBean bean = queue.remove(); // LOGGER为slf4j logger LOGGER.error(bean.getMessage(), bean.getThrowable()); } }
eslf4j是基于slf4j的扩展,选择slf4j是因为它很方便切换日志,比如切换log4j到logback只需修改架包和配置文件,完全不用修改代码。另外,使用eslf4j的api和slf4j十分相似,可以参考以下demo:
private static final Logger LOGGER = Eslf4jLoggerFactory.getLogger(clazz); ... LOGGER.info(msg); ...
标签:
原文地址:http://my.oschina.net/xionghui/blog/469171