Play的日志
由于当前使用play1.25,虽然play提供了Logger进行日志功能,
但是没有找到其保存日志的文件,只是在控制台显示一些INFO级别的信息,感觉很无助
难道play1.25就提供打印日志的功能,不能将打印信息保存到一个文件中吗?
application.conf文件中有关于Log的配置
# Log level # ~~~~~ # Specify log level for your application. # If you want a very customized log, create a log4j.properties file in the conf directory #application.log=INFO # # More logging configuration #application.log.path=/log4j.properties #application.log.system.out=on
什么都不动,启动应用,IDE的控制台将按INFO级别输出日志
打开注释:
application.log=INFO ,也是输出按最低级别为INFO进行输出
将其改为 application.log=DEBUG,效果与INFO一样,难到play的日志输出默认最低为INFO
application.log=WARN 将输出WARN以上的信息
application.log=ERROR 将输出ERROR以上的信息
Play中使用Log4j配置
play如果检测到类路径下有log4j.properties文件,会自动加载该配置
然后使用log4j的配置进行日志管理
但是,打印出来的日志信息有点问题,不能输出详细的异常链
log4j.properties配置
#使用play做日志,这里的异常级别只对控制台输出有效,对于写文件仍然按DEBUG为最低级别进行! log4j.rootLogger=ERROR, Rolling, Console #this config for what ? #log4j.logger.play=INFO #Console log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n # Rolling files log4j.appender.Rolling=org.apache.log4j.RollingFileAppender log4j.appender.Rolling.File=application.log #日志记录最低级别为ERROR log4j.appender.Rolling.Threshold=ERROR log4j.appender.Rolling.MaxFileSize=1MB log4j.appender.Rolling.MaxBackupIndex=100 log4j.appender.Rolling.layout=org.apache.log4j.PatternLayout log4j.appender.Rolling.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n
模拟一个异常
public static void index(){ String username = Security.connected(); //Post对象的author属性为User类型 List<Post> posts = Post.find("author.username", username).<Post>fetch(); try { int i = 1/0; } catch(Exception e) { Logger.error(e.getMessage(), e); } render(posts); }
虽然指定了级别为ERROR以上,但是控制台仍会输出INFO级别
而且,记录日志的文件中也没有具体的异常链信息
只是记录了异常消息
2013-09-08 14:25:21,023 [play-thread-1] [play] [ERROR] - / by zero
而想要的是这样的异常记录
2013-09-08 14:20:34,407 [play-thread-1] [controllers.Admin] [ERROR] - / by zero java.lang.ArithmeticException: / by zero at controllers.Admin.index(Admin.java:41) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:557) at play.mvc.ActionInvoker.invoke(ActionInvoker.java:508) at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:484) at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:479) at play.mvc.ActionInvoker.invoke(ActionInvoker.java:161) at play.server.PlayHandler$NettyInvocation.execute(PlayHandler.java:251) at play.Invoker$Invocation.run(Invoker.java:278) at play.server.PlayHandler$NettyInvocation.run(PlayHandler.java:229) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:207) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619)
记录日志正确的做法
仍然增加一个log4j的配置
出现异常的地方,不使用Logger.error()记录日志,而是将异常包装为RuntimeException向上抛
抛到play中,由play来处理这个异常!
play接收到异常后,会将异常按log4j的配置进行保存,这样就得到了想要的日志了!!!
public static void index(){ String username = Security.connected(); //Post对象的author属性为User类型 List<Post> posts = Post.find("author.username", username).<Post>fetch(); try { int i = 1/0; } catch(Exception e) { //Logger.errro(e.getMessage,e);//无法得到具体的异常信息 throw new RuntimeException(e); } render(posts); }
重新打开application.log,此时记录的异常就详细多了
2013-09-08 15:15:29 ERROR @6fgka5n30 Internal Server Error (500) for request GET /admin/index Execution exception (In /app/controllers/Admin.java around line 43) RuntimeException occured : java.lang.ArithmeticException: / by zero play.exceptions.JavaExecutionException: java.lang.ArithmeticException: / by zero at play.mvc.ActionInvoker.invoke(ActionInvoker.java:237) at Invocation.HTTP Request(Play!) Caused by: java.lang.RuntimeException: java.lang.ArithmeticException: / by zero at controllers.Admin.index(Admin.java:43) at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:557) at play.mvc.ActionInvoker.invoke(ActionInvoker.java:508) at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:484) at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:479) at play.mvc.ActionInvoker.invoke(ActionInvoker.java:161) ... 1 more Caused by: java.lang.ArithmeticException: / by zero at controllers.Admin.index(Admin.java:41) ... 6 more
小结
play中做日志:
application.conf 不修改任何有关log的配置
增加log4j.properties文件,写两个Appender,一个往控制台打印,一个记录到文件
程序中catch到Exception时,直接使用RuntimeException包装后,往上抛即可
最后,在log4j配置指定的文件中即可找到记录的异常日志信息!