OK,在开始研究Log4j的源码之前,我们先来自己模拟一个日志工具,名字就叫linkinlog4j好了。

在软件开发过程中,出现bug总是在所难免;事实上,以我个人经验,即使在实际开发阶段,fix bug时间要远超过写代码的时间。在开发阶段,比较有效的fix bug的方法当然是调试,然而如果代码比较复杂,而且开始对代码不是很熟悉,那么我们很容易在方法调用之间迷失方向;如果bug出现在多线程环境中,那么很多时候调试就无能为力了;另外当代码部署到服务器上运行时,不管是在UAT测试环境还是Production环境,此时要调试很多时候是不可能。相信有过几年工作经验的码农在和运维,测试交流的时候经常提及的日志级别了。



为了解决这些问题,我们可以在开发过程中事先在一些关键点上打印出一些日志信息(log),以利于在出问题后能知道当时运行的环境信息,特别是在production上,我们可以分析log以确定问题所在,当然前提log信息足够多。不过加入日志信息后,不难想象,它会对程序的运行性能产生一定的影响,而且如果log过多会导致有用的信息不容易找到,如果过少又不具备很大的参考价值,这样的日志除了降低程序的性能,貌似对其他方面没有帮助。



关于性能,Log4J号称在这面做了很多优化,但是据说logback做的更好(logback的源码还没来得及看,只是简单的用过,所以还不是很了解);而关于如何写log、在哪里写log、要把那些信息写入log中,个人感觉这是一门很大的学问,而且也是根据不同项目而不同,我以菜鸟身份在这里也就不多做赘述了。





OK,现在我们先来自己写一个测试类,然后通过System.out打印到控制台。代码如下:

package test.junit4test;

import org.junit.Test;

public class LinkinLogTest
{ @Test
public void testLog()
{
System.out.println("测试方法开始。。。");
try
{
throw new NullPointerException("这里人工抛出一个异常!");
}
catch (Exception e)
{
System.out.println("人工捕获一个异常" + e.getMessage());
e.printStackTrace(System.out);
}
System.out.println("测试方法结束。。。");
} }

运行下面的代码,控制台输出如下:

测试方法开始。。。
人工捕获一个异常这里人工抛出一个异常!
java.lang.NullPointerException: 这里人工抛出一个异常!
at test.junit4test.LinkinTest.testLog(LinkinTest.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
测试方法结束。。。

OK,没有问题。但是这段代码有这很明显的缺陷:

1,我们这些日志只能打印在控制台。那么如果我们发布了我们的项目到我们的服务器,我们需要查看的是日志文件而不是控制台了。

2,这里我们自己写的这个日志类没有提现等级,如果我想控制不同的级别来控制某些的内容的输出和不输出,即使我们这里加了一个flag旗标,也没有从根本上解决问题。

3,现在我们的日志的内容都是比较简单,如果我们想要在控制台显示我们的日志的类名,方法运行的时间,所在的线程等等这些内容时,就要不停的重复的写一堆代码。

4,很多的时候我们希望我们的日志按照某种约定来生成,比如说按照日期,按照文件的大小存档,这个时候我们上面的那段代码根本实现不了。





OK,问题很多,那我们来一步一步的解决吧。

自己写的日志框架--linkinLog4j--日志框架的必要性的更多相关文章

  1. 如何在 ETL 项目中统一管理上百个 SSIS 包的日志和包配置框架

    一直准备写这么一篇有关 SSIS 日志系统的文章,但是发现很难一次写的很完整.因为这篇文章的内容可扩展的性太强,每多扩展一部分就意味着需要更多代码,示例和理论支撑.因此,我选择我觉得比较通用的 LOG ...

  2. JAVAEE——SpringBoot日志篇:日志框架SLF4j、日志配置、日志使用、切换日志框架

    Spring Boot 日志篇 1.日志框架(故事引入) 小张:开发一个大型系统: ​ 1.System.out.println(""):将关键数据打印在控制台:去掉?写在一个文件 ...

  3. 【开源】OSharp3.0框架解说系列(6.2):操作日志与数据日志

    OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...

  4. java日志框架与日志系统

    日志框架:提供日志调用的接口,实际的日志输出委托给日志系统实现. JCL(Jakarta Commons Logging):比较流行的日志框架,很多框架都依赖JCL,例如Spring等. SLF4j: ...

  5. logback框架之——日志分割所带来的潜在问题

    源码: logback-test.xml文件如下,有2个需要我们重点关注的参数: fileNamePattern:这里的日志文件名变动的部分是年月日时,外加1个文件分割自增变量,警告,年月日时的数值依 ...

  6. scrapy框架的日志等级和请求传参, 优化效率

    目录 scrapy框架的日志等级和请求传参, 优化效率 Scrapy的日志等级 请求传参 如何提高scripy的爬取效率 scrapy框架的日志等级和请求传参, 优化效率 Scrapy的日志等级 在使 ...

  7. 使用zap接收gin框架默认的日志并配置日志归档

    目录 使用zap接收gin框架默认的日志并配置日志归档 gin默认的中间件 基于zap的中间件 在gin项目中使用zap 使用zap接收gin框架默认的日志并配置日志归档 本文介绍了在基于gin框架开 ...

  8. BitAdminCore框架更新日志20180531

    索引 NET Core应用框架之BitAdminCore框架应用篇系列 框架演示:http://bit.bitdao.cn 框架源码:https://github.com/chenyinxin/coo ...

  9. BitAdminCore框架更新日志20180529

    索引 NET Core应用框架之BitAdminCore框架应用篇系列 框架演示:http://bit.bitdao.cn 框架源码:https://github.com/chenyinxin/coo ...

  10. 为了支持AOP的编程模式,我为.NET Core写了一个轻量级的Interception框架[开源]

    ASP.NET Core具有一个以ServiceCollection和ServiceProvider为核心的依赖注入框架,虽然这只是一个很轻量级的框架,但是在大部分情况下能够满足我们的需要.不过我觉得 ...

随机推荐

  1. RLP

    ** 原创勿转 ** 这是在看devp2p时看到的,英文原文地址:https://github.com/ethereum/wiki/wiki/RLP RLP:  Recursive Length Pr ...

  2. 微信小程序实现简易留言板

    微信小程序现在很火,于是也就玩玩,做了一个简易的留言板,让大家看看,你们会说no picture you say a j8 a,好吧先上图. 样子就是的,功能一目了然,下面我们就贴实现的代码,首先是H ...

  3. Python模块学习------ 多线程threading(1)

    # Method 1: 创建一个Thread实例,传给它一个函数:import threading from time import sleep, ctime loops = [4,2] def lo ...

  4. 【转载】linux挂载mount参数优化

    一. 1) 蓝色:表示经过优化的xfs mount时的参数defaults,noatime,nodiratime,nobarrier,discard,allocsize=256m,logbufs=8, ...

  5. 【读书笔记】【深入理解ES6】#9-JavaScript中的类

    大多数面向对象的编程语言都支持类和类继承的特性,而JavaScript却不支持这些特性,只能通过其他方法定义并关联多个相似的对象.这个状态一直从ECMAScript 1持续到ECMAScript 5. ...

  6. hibernate使用setResultTransformer()将SQL查询结果放入集合中

    在平时开发中Hibernate提供的hql基本能够满足我们的日常需求.但是在有些特殊的情况下,还是需要使用原生的sql,并且希望sql查询出来的结果能够绑定到pojo上.hibernate API中的 ...

  7. windows第七层负载均衡--基于IIS的ARR负载均衡

    载均衡有很多种方法,有硬件负载均衡,软件负载均衡,还可以从域名解析下手. 不过,今天只讲软件负载均衡 软件负载均衡一般分两种,从网络协议来讲(tcp/ip),主要集中在第四层和第七层进行负载均衡. 第 ...

  8. sublime text3安装、注册及常用插件

    由于换电脑,重装系统等问题,总要重装sublime.每次都要查来查去,不如自己记下来,以后再装也方便. 一.下载 官网下载安装包(http://www.sublimetext.com/) :然后直接点 ...

  9. JavaScript基础知识(对象、函数与对象)

    17.对象 属性:描述对象的信息  方法:描述对象的行为  封装:只关心输入和输出(不管过程如何实现) ü 对象的分类: 内置对象(原生对象): 就是JavaScript语言预定义的对象(如Strin ...

  10. JavaScript 数组对象的去重

    JavaScript数组去重 1.原型去重法.通过prototype找到数组的源性对象Array,在数组的原型上添加unique()方法.需要使用的时候使用 点 " . " 进行连 ...