自3月25至今,已经好久没有写学习日志了,今天在写日志抓取合并的小方法,发现抓取后的日志并米有依据系统执行的日志顺序排序。日志抓取排列逻辑如下:

  1. 通过日志标识,从各个日志文件(例如 use.log,error.log 等)中获取所需日志列表
  2. 合并日志列表
  3. 升序排序
  4. 输出日志报告

结果最后获取日志信息后,发现实际产出结果与预期结果不相符,如下所示:

 -- ::, - INFO  - [main] [cn.ffp.autotest.api.report.ReportHelper:] - [] 开始生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | -- :: | 是】概要报告 ...
-- ::, - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:] - [] 成功生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | -- :: | 是】概要报告 ...
-- ::, - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:] - [] 开始生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | -- :: | 是】断言报告 ...
-- ::, - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:] - [] 成功生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | -- :: | 是】断言报告 ...
-- ::, - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:] - [] 开始生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | -- :: | 是】请求响应报告 ...
-- ::, - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:] - [] 开始生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | -- :: | 是】请求报告 ...
-- ::, - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:] - [] 成功生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | -- :: | 是】请求报告 ...
-- ::, - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:] - [] 开始生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | -- :: | 是】请求参数报告 ...
-- ::, - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:] - [] 成功生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | -- :: | 是】请求参数报告 ...
-- ::, - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:] - [] 开始生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | -- :: | 是】请求主体报告 ...
-- ::, - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:] - [] 成功生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | -- :: | 是】请求主体报告 ...
-- ::, - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:] - [] 开始生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | -- :: | 是】日志报告 ...
-- ::, - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:] - [] 成功生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | -- :: | 是】请求响应报告 ...
-- ::, - INFO - [main] [cn.ffp.autotest.api.util.IpUtils:] - [] 成功获取主机IP地址...
-- ::, - INFO - [main] [cn.ffp.autotest.api.util.IpUtils:] - [] 成功获取主机IP地址...
-- ::, - INFO - [main] [cn.ffp.autotest.api.util.IpUtils:] - [] 开始通过主机域名【mb.ffp.com】获取对应的地址对象 ...
-- ::, - INFO - [main] [cn.ffp.autotest.api.util.IpUtils:] - [] 成功通过主机域名【mb.ffp.com】获取对应的地址对象 ...
-- ::, - INFO - [main] [cn.ffp.autotest.api.util.IpUtils:] - [] 开始获取主机IP地址...
-- ::, - INFO - [main] [cn.ffp.autotest.api.util.IpUtils:] - [] 开始获取主机IP地址...

通过日志可以发现,排序时起决定作用的日志时间影响较大,系统运算速度越快,产生相同时间开头的日志就越多,因而影响了最终的排序结果。

如何才能解决呢?我想出了如下的解决方案:

  1. 将所有的日志信息统一输出到一个文件中,只需要依次获取日志输出即可
  2. 创建自己的日志模块取代 log4j
  3. 日志排序打标,即:在每个日志字符串前添加一个唯一 ID,通过此 ID 进行排序
  4. 二次编译 log4j 的源码在 debug、info、warn、error、fatal 方法中添加延时

再三思索下,决定采用第四种解决方案。原因如下:

  1. 所有日志信息输出到同一文件,日志文件较大,且不符合日志分类习惯
  2. 耗时较长(主要是有很多开源的日志构件,自己再开发,觉得浪费时间,哈哈哈)
  3. 日志打标需要在每个日志输出的地方添加标识,因方法或语句块会被多次执行,此方案直接KO
  4. 省时省力,只是需要牺牲点时间(个人觉得此方案比其他方案会更优)

经过查询 log4j 的api 发现,上述日志方法在 org\apache\log4j\Category.java 文件中,具体延时时间依据实际需要自行酌情设置即可,添加或修改如下所示代码(info、warn、error、fatal 方法参考修改即可):

package org.apache.log4j;

import org.apache.log4j.spi.AppenderAttachable;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.HierarchyEventListener;
import org.apache.log4j.helpers.NullEnumeration;
import org.apache.log4j.helpers.AppenderAttachableImpl; import java.util.Enumeration;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Vector; public class Category implements AppenderAttachable { /**
* Aaron.ffp 2016-04-10 add log delay time 10ms
* reference:debug、info、warn、error、fatal
*/
protected long delay = 10; public void debug(Object message) {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
} if (repository.isDisabled(Level.DEBUG_INT))
return;
if (Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) {
forcedLog(FQCN, Level.DEBUG, message, null);
}
} public void debug(Object message, Throwable t) {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
} if (repository.isDisabled(Level.DEBUG_INT))
return;
if (Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel()))
forcedLog(FQCN, Level.DEBUG, message, t);
}
}

  下载 log4j-1.2.17.jar ,对其进行反编译(不会的请参阅我之前写的文章:Java学习-039-源码 jar 包的二次开发扩展实例(源码修改)),然后打包上传到私服,在 pom 文件中添加引用即可。

重新执行测试用例,得到的日志数据如下所示(此时获取的日志结果为期望结果,同时从日志中也可看出我们的日志延时输出已经生效):

 2016-04-10 23:08:01,005 - INFO  - [main] [cn.ffp.autotest.api.report.ReportHelper:151] - [1460300877526] 开始生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | 2016-03-29 00:03:34 | 是】概要报告 ...
2016-04-10 23:08:01,015 - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:167] - [1460300877526] 成功生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | 2016-03-29 00:03:34 | 是】概要报告 ...
2016-04-10 23:08:01,025 - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:187] - [1460300877526] 开始生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | 2016-03-29 00:03:34 | 是】断言报告 ...
2016-04-10 23:08:01,035 - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:211] - [1460300877526] 成功生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | 2016-03-29 00:03:34 | 是】断言报告 ...
2016-04-10 23:08:01,045 - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:358] - [1460300877526] 开始生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | 2016-03-29 00:03:34 | 是】请求报告 ...
2016-04-10 23:08:01,055 - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:409] - [1460300877526] 开始生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | 2016-03-29 00:03:34 | 是】请求参数报告 ...
2016-04-10 23:08:01,065 - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:426] - [1460300877526] 成功生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | 2016-03-29 00:03:34 | 是】请求参数报告 ...
2016-04-10 23:08:01,075 - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:441] - [1460300877526] 开始生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | 2016-03-29 00:03:34 | 是】请求主体报告 ...
2016-04-10 23:08:01,085 - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:446] - [1460300877526] 成功生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | 2016-03-29 00:03:34 | 是】请求主体报告 ...
2016-04-10 23:08:01,095 - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:392] - [1460300877526] 成功生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | 2016-03-29 00:03:34 | 是】请求报告 ...
2016-04-10 23:08:01,105 - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:286] - [1460300877526] 开始生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | 2016-03-29 00:03:34 | 是】请求响应报告 ...
2016-04-10 23:08:01,205 - INFO - [main] [cn.ffp.autotest.api.util.IpUtils:98] - [1460300877526] 开始获取主机IP地址...
2016-04-10 23:08:01,215 - INFO - [main] [cn.ffp.autotest.api.util.IpUtils:108] - [1460300877526] 成功获取主机IP地址...
2016-04-10 23:08:01,225 - INFO - [main] [cn.ffp.autotest.api.util.IpUtils:192] - [1460300877526] 开始通过主机域名【mb.ffp.com】获取对应的地址对象 ...
2016-04-10 23:08:01,235 - INFO - [main] [cn.ffp.autotest.api.util.IpUtils:197] - [1460300877526] 成功通过主机域名【mb.ffp.com】获取对应的地址对象 ...
2016-04-10 23:08:01,245 - INFO - [main] [cn.ffp.autotest.api.util.IpUtils:98] - [1460300877526] 开始获取主机IP地址...
2016-04-10 23:08:01,255 - INFO - [main] [cn.ffp.autotest.api.util.IpUtils:108] - [1460300877526] 成功获取主机IP地址...
2016-04-10 23:08:01,265 - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:338] - [1460300877526] 成功生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | 2016-03-29 00:03:34 | 是】请求响应报告 ...
2016-04-10 23:08:01,275 - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:261] - [1460300877526] 开始生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | 2016-03-29 00:03:34 | 是】日志报告 ...
2016-04-10 23:08:01,305 - INFO - [main] [cn.ffp.autotest.api.report.ReportHelper:266] - [1460300877526] 成功生成【Test_001_001 | 首页接口-导航栏配置 | 范丰平 | 2016-03-29 00:03:34 | 是】日志报告 ...

至此, Java学习-046-测试日志抓取合并、排序问题解决方案之 --- log4j 二次定制,实现日志输出添加延时10ms 顺利完结,希望此文能够给初学 Java 的您一份参考。

最后,非常感谢亲的驻足,希望此文能对亲有所帮助。热烈欢迎亲一起探讨,共同进步。非常感谢! ^_^

Java学习-046-日志抓取合并后排序问题解决方案之 --- log4j 二次定制,实现日志输出添加延时10ms的更多相关文章

  1. java学习-GET方式抓取网页(UrlConnection和HttpClient)

    抓取网页其实就是模拟客户端(PC端,手机端...)发送请求,获得响应数据documentation,解析对应数据的过程.---自己理解,错误请告知 一般常用请求方式有GET,POST,HEAD三种 G ...

  2. Android全局异常处理 实现自己定义做强制退出和carsh日志抓取

    在做android项目开发时,大家都知道都会遇到程序报错或者Anr异常,会弹出来一个强制退出的弹出框,对于开发人员是好事,但是对于用户体验和 UI实在毫无违和感,别说用户接受不了,就连我们自己本身可能 ...

  3. adb命令 logcat日志抓取

    一.logcat抓log方法:adb logcat命令,可以加条件过滤 1.安装SDK(参考android sdk环境安装) 2.使用数据线链接手机,在手机助手的sdcard中建立一个1.log的文件 ...

  4. adb logcat日志抓取

    adb命令 logcat日志抓取 一.logcat抓log方法:adb logcat命令,可以加条件过滤 1.安装SDK(参考android sdk环境安装) 2.使用数据线链接手机,在手机助手的sd ...

  5. 用libvlc 抓取解码后的帧数据

    vlc是一套优秀的开源媒体库,其特点是提供了完整的流媒体框架, 用它可以非常方便的实现抓取解码帧的功能. 与此功能有关的关键API为 libvlc_video_set_callbacks /*设置回调 ...

  6. c#抓取网页内容乱码的解决方案

    写过爬虫的同学都知道,这是个很常见的问题了,一般处理思路是: 使用HttpWebRequest发送请求,HttpWebResponse来接收,判断HttpWebResponse中”Content-Ty ...

  7. JAVA使用Gecco爬虫 抓取网页内容(附Demo)

    JAVA 爬虫工具有挺多的,但是Gecco是一个挺轻量方便的工具. 先上项目结构图. 这是一个 JAVASE的 MAVEN 项目,要添加包依赖,其他就四个文件.log4j.properties 加上三 ...

  8. java网络爬虫----------简单抓取慕课网首页数据

    © 版权声明:本文为博主原创文章,转载请注明出处 一.分析 1.目标:抓取慕课网首页推荐课程的名称和描述信息 2.分析:浏览器F12分析得到,推荐课程的名称都放在class="course- ...

  9. Java广度优先爬虫示例(抓取复旦新闻信息)

    一.使用的技术 这个爬虫是近半个月前学习爬虫技术的一个小例子,比较简单,怕时间久了会忘,这里简单总结一下.主要用到的外部Jar包有HttpClient4.3.4,HtmlParser2.1,使用的开发 ...

随机推荐

  1. H

    很爽的一局,打了70分钟,还刷新了我的最高击杀记录.打完出来一看居然是H局,第一次在H局里打出不错的表现诶.好像找人说一说,可惜并没有谁听,以前的朋友也不在了,还是算了,自己心里慢慢发霉去吧. 这局末 ...

  2. Webpack打包进阶

    说在前面 由于使用了React直出,页面各项性能指标使人悦目.本篇将深入探讨目前PC部落所采用webpack打包优化策略,以及探讨PC部落并未使用的 webpack Code Splitting 代码 ...

  3. Android 应用内存优化 之 onLowMemory & onTrimMemory

    OnLowMemory: 是Android提供的API,在系统内存不足,所有后台程序(优先级为background的进程,不是指后台运行的进程)都被杀死时,系统会调用OnLowMemory.OnTri ...

  4. Codeforces Round #252 (Div. 2) A - Valera and Antique Items

    水题 #include <iostream> #include <set> #include <vector> #include <algorithm> ...

  5. IOS UI segmentedControl UISegmentedControl 常见属性和用法

    UISegmentedControl中一些常见的属性和用法 //设置以图案作为分段的显示,仅需要图案的轮廓,这样颜色为分段的背景颜色 //    NSArray *items = @[[UIImage ...

  6. ACM: Ubiquitous Religions-并查集-解题报告

    Ubiquitous Religions Time Limit:5000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu Descript ...

  7. 4分钟apache自带ab压力测试工具使用: 2015.10.4

    2015.10.44分钟apache自带ab压力测试工具使用:win8.1 wampserver2.5 -Apache-2.4.9-Mysql-5.6.17-php5.5.12-64b 可以参考一下部 ...

  8. BZOJ4513: [Sdoi2016]储能表

    Description 有一个 n 行 m 列的表格,行从 0 到 n−1 编号,列从 0 到 m−1 编号.每个格子都储存着能量.最初,第 i 行第 j 列的格子储存着 (i xor j) 点能量. ...

  9. Poj 3250 单调栈

    1.Poj 3250  Bad Hair Day 2.链接:http://poj.org/problem?id=3250 3.总结:单调栈 题意:n头牛,当i>j,j在i的右边并且i与j之间的所 ...

  10. GO语言练习:构建json 和 解析JSON 实例

    本文介绍如何使用Go语言自带的库把对象转换为JSON格式,并在channel中进行传输后,并把JSON格式的信息转换回对象. 1.Go语言的JSON 库 Go语言自带的JSON转换库为 encodin ...