本身写的日志框架--linkinLog4j--日志框架的必要性


OK,在开始研究Log4j的源码以前,咱们先来本身模拟一个日志工具,名字就叫linkinlog4j好了。html

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


为了解决这些问题,咱们能够在开发过程当中事先在一些关键点上打印出一些日志信息(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,问题不少,那咱们来一步一步的解决吧。
相关文章
相关标签/搜索