Java打log日志
来源:互联网 发布:mac上画泳道图 编辑:程序博客网 时间:2024/05/18 00:49
最近写Java工程,需要在客户端打上log,以便进行出错追踪。刚开始试了一些log4j之类的包,想着功能强大点儿。但是由于配置、版本不兼容、傻叉Windows等一系列问题,最终放弃,干脆直接采用Java自带的log好了。
关于Java内置Logger的介绍,比较好的有这篇,可以学习一下其基本用法。
但是如果按照那篇博客的“(六)如何使用JDK内置logger ”写一个LogUtil的话,在我的需求下会出现问题。
由于我需要开启多线程,当一个线程出问题之后,另一个线程会出重新开一个log文件写日志,比如原来是xxx.log,会同时出现一个xxx.log.lck,如果那个线程出了问题,新的线程写日志就会写xxx.log.1,同时会出现xxx.log.1.lck,如果再出问题,会继续有xxx.log.2和xxx.log.2.lck以此类推。
从文件的名字来看,在写日志文件xxx.log的时候,xxx.log.lck应该是锁住了这个日志,只有当资源释放后其他的线程才能写这个日志,否则就只能新开日志,写到xxx.log.1中,依次类推。显然这不是我想要的,我想要所有的线程都写到一个log文件中去,不要分开。
功夫不负有心人,经过查找,Writing-logs-single-file-Multiple给出了答案:
Got the error with my code.
Was instantiating a new instance of fileHandler every time getLogger is called. This creates a new file since previous file is locked with other handler.
Changed initialization of Logger to a different method and implemented Singleton on the CustomLogger.
所以说是因为每次写log之前生成的logger创建了不同的fileHandler。只要都使用同一个handler就ok了。
解决了问题之后,感觉还有一些不太满意的地方,想调整一下日志的记录格式,自定义一发。然后在这里找到了答案。
下面是代码:
package com.allinone.client.util;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Date;import java.util.logging.Formatter;import java.util.logging.Handler;import java.util.logging.LogRecord;/** * 自定义日志格式 * * Created by pos on 2016/8/31. */class MyLogFormatter extends Formatter { // Create a DateFormat to format the logger timestamp. private static final DateFormat df = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss.SSS"); public String format(LogRecord record) { StringBuilder builder = new StringBuilder(1000); builder.append(df.format(new Date(record.getMillis()))).append(" - "); builder.append("[").append(record.getSourceClassName()).append("."); builder.append(record.getSourceMethodName()).append("] - \n"); builder.append("\t[").append(record.getLevel()).append("] - "); builder.append(formatMessage(record)); builder.append("\n\n"); return builder.toString(); } public String getHead(Handler h) { return super.getHead(h); } public String getTail(Handler h) { return super.getTail(h); }}
package com.allinone.client.util;import java.io.File;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import java.util.logging.*;/** * 默认将log文件输出到C:\Logs\AIOClient\xxxx年\x月\xxxx-xx-xx.log * 路径不存在的话会自动创建 * 可通过修改getLogFilePath修改生成的log路径 * * Created by pos on 2016/8/30. */public class LogUtil { private static Calendar now = Calendar.getInstance(); private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); private static final int year = now.get(Calendar.YEAR); private static final int month = now.get(Calendar.MONTH) + 1; private static final String LOG_FOLDER_NAME = "AIOClient"; private static final String LOG_FILE_SUFFIX = ".log"; private static Logger logger = Logger.getLogger("MyLogger"); //使用唯一的fileHandler,保证当天的所有日志写在同一个文件里 private static FileHandler fileHandler = getFileHandler(); private static MyLogFormatter myLogFormatter = new MyLogFormatter(); private synchronized static String getLogFilePath() { StringBuffer logFilePath = new StringBuffer();// logFilePath.append(System.getProperty("user.home")); logFilePath.append("C:\\Logs"); logFilePath.append(File.separatorChar); logFilePath.append(LOG_FOLDER_NAME); logFilePath.append(File.separatorChar); logFilePath.append(year); logFilePath.append(File.separatorChar); logFilePath.append(month); File dir = new File(logFilePath.toString()); if (!dir.exists()) { dir.mkdirs(); } logFilePath.append(File.separatorChar); logFilePath.append(sdf.format(new Date())); logFilePath.append(LOG_FILE_SUFFIX);// System.out.println(logFilePath.toString()); return logFilePath.toString(); } private static FileHandler getFileHandler() { FileHandler fileHandler = null; boolean APPEND_MODE = true; try { //文件日志内容标记为可追加 fileHandler = new FileHandler(getLogFilePath(), APPEND_MODE); return fileHandler; } catch (IOException e) { e.printStackTrace(); } return null; } public synchronized static Logger setLoggerHanlder() { return setLoggerHanlder(Level.ALL); } // SEVERE > WARNING > INFO > CONFIG > FINE > FINER > FINESET public synchronized static Logger setLoggerHanlder(Level level) { try { //以文本的形式输出// fileHandler.setFormatter(new SimpleFormatter()); fileHandler.setFormatter(myLogFormatter); logger.addHandler(fileHandler); logger.setLevel(level); } catch (SecurityException e) { logger.severe(populateExceptionStackTrace(e)); } return logger; } private synchronized static String populateExceptionStackTrace(Exception e) { StringBuilder sb = new StringBuilder(); sb.append(e.toString()).append("\n"); for (StackTraceElement elem : e.getStackTrace()) { sb.append("\tat ").append(elem).append("\n"); } return sb.toString(); } public static void main(String [] args) { Logger logger = LogUtil.setLoggerHanlder(Level.INFO); logger.info("Hello, world!"); logger.severe("What are you doing?"); logger.warning("Warning !");//// for(Handler h : logger.getHandlers()) {// h.close(); //must call h.close or a .LCK file will remain.// } }}
效果:
会在C盘下按照年月生成不同的文件夹。以日为单位,每天一个log文件。比如这次的运行结果是生成C:\Logs\AIOClient\2016\8\2016-08-31.log,内容如下:
2016/08/31 05:35:24.077 - [com.allinone.client.util.LogUtil.main] - [INFO] - Hello, world!2016/08/31 05:35:24.160 - [com.allinone.client.util.LogUtil.main] - [SEVERE] - What are you doing?2016/08/31 05:35:24.162 - [com.allinone.client.util.LogUtil.main] - [WARNING] - Warning !
- Java打log日志
- addLog(Log log) 打日志的方法
- java打log
- eclipse 集成tomcat的log打日志
- ios 打全局的Log日志
- java日志文件 log
- java log日志
- java Log日志规范
- java 操作日志 log
- Java log日志输出
- java中的日志log
- Java日志Log
- 在Java程序中打log
- 打log
- Java Log日志的使用
- android/java 自定义log日志
- Java日志log的使用
- java中关于log日志
- MySql(22)------mysql修改最大连接数常用方式
- 12. Integer to Roman
- c++ ActiveX基础1:使用VS2010创建MFC ActiveX工程项目
- 驰骋工作流引擎表单设计器-Pop返回值
- ObjectMapper 的使用和常用注解 过滤条件
- Java打log日志
- hashmap统计字符串中每个字符出现的次数
- beanshell
- linux黑科技---GREP:查找文件夹下特定字符串
- Linux设备驱动程序--学习笔记(2)
- springmvc注解方式
- Lucene简单使用
- 串的静态顺序存储基本操作
- Eclipse插件,只给你推荐这几个