锁定老帖子 主题:根据Session区分的日志系统.
精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-06-21
最后修改:2010-06-21
具体需求: 1,按这个分公司编号创建文件夹 2,按部门号+日期创建LOG文件 3,当日志文件大于指定SIZE时拷贝文件 各位多提一提意见,,, 本人技术有限, 有些地方的可能存在错误,我想不到的! 请各位指正啊!! Log.java package org.dhcc.fm.log; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.http.HttpSession; /** * 日志类 * @author lishengxi * */ public class Log { private LogFile tf = null; public Log(HttpSession session){ tf = new LogFile(session); } public String logForMat(){ SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日-HH点mm分ss秒"); String newDate = format.format(new Date()); return newDate+",发生错误:"; } public void error(String mss){ try { tf.write(logForMat()+mss); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void error(String mss,Exception et){ try { tf.write(logForMat()+mss,et); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } LogFactory.java package org.dhcc.fm.log; import javax.servlet.http.HttpSession; /** * 日志工厂类 * @author lishengxi * */ public class LogFactory { public static Log createLog(HttpSession session){ Log log = new Log(session); return log; } } LogFile.java package org.dhcc.fm.log; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.http.HttpSession; /** * 日志文件操作类 * @author lishengxi */ public class LogFile { private static String logpath = LogProperties.LOG_FM_FILE_PATH; private static String fileH = LogProperties.LOG_FM_FILE_TYPE; private static long length = LogProperties.LOG_FM_FILE_SIZE; private static String department = LogProperties.LOG_FM_SESSION_DEPARTMENT; private static String upbrno = LogProperties.LOG_FM_SESSION_UPBRNO; private static String encoding = LogProperties.LOG_FM_FILE_ENCODING; private String _fileName; private String up_br_no; private long count; public String getUp_br_no() { return up_br_no; } public void setUp_br_no(String upBrNo) { up_br_no = upBrNo; } public LogFile(HttpSession session){ String temp = session.getAttribute(department).toString(); if(temp!=null&&!temp.equals("")){ _fileName = temp; up_br_no = session.getAttribute(upbrno).toString(); } newFolder(); newFile(); } public void newFolder(){ try { String filePath = logpath+"\\"+getUp_br_no(); filePath = filePath.toString(); File myFilePath = new File(filePath); if(!myFilePath.exists()){ myFilePath.mkdir(); } } catch(Exception e) { e.printStackTrace(); } } public void newFile(){ try{ String filePath = logpath+"\\"+getUp_br_no()+"\\"+getLogFile(_fileName)+fileH; File myFilePath = new File(filePath); if (!myFilePath.exists()){ myFilePath.createNewFile(); } } catch (Exception e){ e.printStackTrace(); } } public void rollOver() { File myFilePath = new File(logpath+"\\"+getUp_br_no()+"\\"+getLogFile(_fileName)+fileH); File target = new File(logpath+"\\"+getUp_br_no()+"\\"+getTLogFile(_fileName)+fileH); if(myFilePath.length()>length){ myFilePath.renameTo(target); } } public void write(String str,Exception e) throws Exception{ this.rollOver(); File myFilePath = new File(logpath+"\\"+getUp_br_no()+"\\"+getLogFile(_fileName)+fileH); FileOutputStream fos = new FileOutputStream(myFilePath,true); OutputStreamWriter osw = new OutputStreamWriter(fos,encoding); PrintWriter myFile = new PrintWriter(osw); myFile.println(str); e.printStackTrace(myFile); myFile.close(); osw.close(); fos.close(); } public void write(String str) throws Exception{ this.rollOver(); File myFilePath = new File(logpath+"\\"+getUp_br_no()+"\\"+getLogFile(_fileName)+fileH); FileOutputStream fos = new FileOutputStream(myFilePath,true); OutputStreamWriter osw = new OutputStreamWriter(fos,encoding); PrintWriter myFile = new PrintWriter(osw); myFile.println(str); myFile.close(); osw.close(); fos.close(); } private String getLogFile(String fileName){ SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日"); return fileName+"_"+format.format(new Date()); } private String getTLogFile(String fileName){ SimpleDateFormat format = new SimpleDateFormat("HH点mm分ss秒"); return getLogFile(fileName)+"_"+format.format(new Date()); } } LogProperties.java package org.dhcc.fm.log; import java.io.IOException; import java.io.InputStream; import java.util.Properties; /** * 日志属性类 * @author lishengxi * */ public class LogProperties { private static final String LOGFILE = "LOG.properties"; //默认日志配置文件 public static String LOG_FM_FILE_PATH = "";//日志保存路径 public static String LOG_FM_FILE_TYPE = "";//日志文件类型 public static String LOG_FM_FILE_ENCODING = "";//日志文件编码 public static long LOG_FM_FILE_SIZE = 0;//日志文件大小 public static String LOG_FM_SESSION_DEPARTMENT = "";//部门 public static String LOG_FM_SESSION_UPBRNO = "";//机构 static{ //获取ClassPath下的日志配置文件 InputStream is1 = Thread.currentThread().getContextClassLoader().getResourceAsStream(LOGFILE); Properties p = new Properties(); try { p.load(is1); LOG_FM_FILE_PATH = p.getProperty("log.fm.file.path"); LOG_FM_FILE_TYPE = p.getProperty("log.fm.file.type"); LOG_FM_FILE_SIZE = LogUtil.toFileSize(p.getProperty("log.fm.file.size"),1024); LOG_FM_FILE_ENCODING = p.getProperty("log.fm.file.type.encoding"); LOG_FM_SESSION_DEPARTMENT = p.getProperty("log.fm.session.department"); LOG_FM_SESSION_UPBRNO = p.getProperty("log.fm.session.upbrno"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } LogUtil.java package org.dhcc.fm.log; /** * 日志工具类 * @author lishengxi * */ public class LogUtil { /** * 转换文件大小 2MB = 1024*1024*2 * @param value * @param dEfault * @return */ public static long toFileSize(String value, long dEfault) { if(value == null) return dEfault; String s = value.trim().toUpperCase(); long multiplier = 1; int index; if((index = s.indexOf("KB")) != -1) { multiplier = 1024; s = s.substring(0, index); } else if((index = s.indexOf("MB")) != -1) { multiplier = 1024*1024; s = s.substring(0, index); } else if((index = s.indexOf("GB")) != -1) { multiplier = 1024*1024*1024; s = s.substring(0, index); } if(s != null) { try { return Long.valueOf(s).longValue() * multiplier; } catch (NumberFormatException e) { e.printStackTrace(); } } return dEfault; } } 测试一下啊...!!!!!!!! package org.dhcc.fm.log; import java.util.Enumeration; import java.util.HashMap; import javax.servlet.ServletContext; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionContext; import org.dhcc.fm.log.*; public class Test extends Thread { private String TName = ""; public Test(String N){ TName = N; } @Override public void run() { // TODO Auto-generated method stub HttpSession session = new HttpSession() { HashMap sessionSop = new HashMap(); public void setMaxInactiveInterval(int arg0) { // TODO Auto-generated method stub } public void setAttribute(String arg0, Object arg1) { // TODO Auto-generated method stub sessionSop.put(arg0, arg1); } public void removeValue(String arg0) { // TODO Auto-generated method stub } public void removeAttribute(String arg0) { // TODO Auto-generated method stub } public void putValue(String arg0, Object arg1) { // TODO Auto-generated method stub } public boolean isNew() { // TODO Auto-generated method stub return false; } public void invalidate() { // TODO Auto-generated method stub } public String[] getValueNames() { // TODO Auto-generated method stub return null; } public Object getValue(String arg0) { // TODO Auto-generated method stub return null; } public HttpSessionContext getSessionContext() { // TODO Auto-generated method stub return null; } public ServletContext getServletContext() { // TODO Auto-generated method stub return null; } public int getMaxInactiveInterval() { // TODO Auto-generated method stub return 0; } public long getLastAccessedTime() { // TODO Auto-generated method stub return 0; } public String getId() { // TODO Auto-generated method stub return null; } public long getCreationTime() { // TODO Auto-generated method stub return 0; } public Enumeration getAttributeNames() { // TODO Auto-generated method stub return null; } public Object getAttribute(String arg0) { // TODO Auto-generated method stub return sessionSop.get(arg0); } }; session.setAttribute("department_name", "三星企划事业部"); session.setAttribute("up_br_no", "010002"); Log log = LogFactory.createLog(session); for(int i = 0 ; i < 10000 ; i ++){ try { thorwsOut(); } catch (Exception e) { // TODO Auto-generated catch block log.error("数据库连接错误!",e); e.printStackTrace(); } } } public void thorwsOut() throws Exception{ throw new Exception("数据连接格式不正确!.."); } public static void main(String agrs[]){ new Test("线程1").start(); System.out.println("1--------"); new Test("线程2").start(); System.out.println("2--------"); new Test("线程3").start(); System.out.println("3--------"); } } 忘了,要加入LOG.properties log.fm.file.path = c:\\fm_log\\ log.fm.file.type = .log log.fm.file.size = 1MB log.fm.file.type.encoding = UTF-8 log.fm.session.department = department_name log.fm.session.upbrno = up_br_no 效果就是 完!!!! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-06-21
我觉得你扩展一个log4j的Appender就可以了,曾经有个类似的需求,每个手机号生成不同的log文件到每个手机号自己的目录
|
|
返回顶楼 | |
发表时间:2010-06-21
climber2002 写道 我觉得你扩展一个log4j的Appender就可以了,曾经有个类似的需求,每个手机号生成不同的log文件到每个手机号自己的目录
恩 ,我尝试过... 重新实现一个Appender ,,关键是 如何把session 给传进去呢? |
|
返回顶楼 | |
发表时间:2010-06-21
贴一下我以前的代码吧,我自己创建了一个DeviceLogger扩展了log4j的logger, 然后写了一个DeviceFileAppender。 DeviceFileAppender里面维护了一个Map,用来完成手机号跟相应的FileAppender之间的映射。 不过你的实现要考虑session失效的时候把相应的FileAppender从Map删掉,要不最终会OutOfMemory。
public class DeviceLogger extends Logger { /** The fully qualified name of the Logger class. See also the getFQCN method. */ private static final String FQCN = DeviceLogger.class.getName() + "."; /** * In log4j.properties, this logger should be configured to an appender <code>DeviceFileAppender</code> */ public static final String PARENT_LOGGER_NAME = "com.smartomcx.logging.device."; private static DeviceLoggerFactory factory = new DeviceLoggerFactory(); private String imei; protected DeviceLogger(String name) { super(name); this.imei = name.substring(PARENT_LOGGER_NAME.length()); } public String getImei() { return imei; } public static DeviceLogger getDeviceLogger(String imei) { return (DeviceLogger)Logger.getLogger(PARENT_LOGGER_NAME + imei, factory); } } public class DeviceLoggerFactory implements LoggerFactory { public Logger makeNewLoggerInstance(String imei) { return new DeviceLogger(imei); } } /** * This appender appends the log of <code>DeviceLogger</code> to a separate file for each IMEI. * Under parent folder, each imei will have a subfolder, and the log for each IMEI will be output * to device.log under each specific folder * * @author * */ public class DeviceFileAppender extends AppenderSkeleton { private ConcurrentMap<String, FileAppender> appenders = new ConcurrentHashMap<String, FileAppender>(); /** Controls file truncatation. The default value for this variable * is <code>true</code>, meaning that by default a * <code>FileAppender</code> will append to an existing file and not * truncate it. * * <p>This option is meaningful only if the FileAppender opens the * file. */ protected boolean fileAppend = true; /** The name of the parent folder. */ protected String parentFolder = null; /** Do we do bufferedIO? */ protected boolean bufferedIO = false; /** * Determines the size of IO buffer be. Default is 8K. */ protected int bufferSize = 8*1024; public DeviceFileAppender() { } public boolean isFileAppend() { return fileAppend; } public void setFileAppend(boolean fileAppend) { this.fileAppend = fileAppend; } public String getParentFolder() { return parentFolder; } /** * This is the parent folder for all devices * @param parentFolder */ public void setParentFolder(String parentFolder) { this.parentFolder = parentFolder.trim(); if(this.parentFolder.endsWith(System.getProperty("file.separator") )) { //the folder name should not contain '/' at end this.parentFolder = this.parentFolder.substring(0, this.parentFolder.length() - 1); } } public boolean isBufferedIO() { return bufferedIO; } public void setBufferedIO(boolean bufferedIO) { this.bufferedIO = bufferedIO; } public int getBufferSize() { return bufferSize; } public void setBufferSize(int bufferSize) { this.bufferSize = bufferSize; } /* (non-Javadoc) * @see org.apache.log4j.AppenderSkeleton#append(org.apache.log4j.spi.LoggingEvent) */ @Override protected void append(LoggingEvent event) { Category category = event.getLogger(); if(!(category instanceof DeviceLogger)) { //only append DeviceLogger return; } DeviceLogger logger = (DeviceLogger)category; FileAppender appender = null; try { appender = getFileAppender(logger.getImei()); } catch (IOException e) { e.printStackTrace(); return; } appender.append(event); } /** * Get the FileAppender based on the imei * @param imei * @return * @throws IOException */ protected synchronized FileAppender getFileAppender(String imei) throws IOException { FileAppender appender = this.appenders.get(imei); if(appender != null) { return appender; } String imeiFolderPath = getImeiFolderPath(imei); File imeiFolder = new File(imeiFolderPath); deleteImeiFolderIfNotDirectory(imeiFolder); createImeiFolderIfNotExist(imeiFolder); String logFilePath = getLogFilePath(imeiFolderPath); appender = new FileAppender(getLayout(), logFilePath, this.isFileAppend(), this.isBufferedIO(), this.getBufferSize()); this.appenders.put(imei, appender); return appender; } /** * Get the log file path under the IMEI folder * @param imeiFolderPath * @return */ protected String getLogFilePath(String imeiFolderPath) { String logFilePath = imeiFolderPath + System.getProperty("file.separator") + "device.log"; return logFilePath; } /** * Get the IMEI folder path for a imei * @param imei * @return */ protected String getImeiFolderPath(String imei) { String imeiFolderPath = this.parentFolder + System.getProperty("file.separator") + imei; return imeiFolderPath; } protected void deleteImeiFolderIfNotDirectory(File imeiFolder) { if(imeiFolder.exists() && !imeiFolder.isDirectory()) { imeiFolder.delete(); } } private void createImeiFolderIfNotExist(File imeiFolder) { if(! imeiFolder.exists()) { imeiFolder.mkdir(); } } /* (non-Javadoc) * @see org.apache.log4j.Appender#close() */ public void close() { closeAllAppenders(); reset(); } private void closeAllAppenders() { Set<Entry<String, FileAppender>> entries = this.appenders.entrySet(); for(Entry<String, FileAppender> entry : entries) { entry.getValue().close(); } } private void reset() { this.appenders.clear(); } /* (non-Javadoc) * @see org.apache.log4j.Appender#requiresLayout() */ public boolean requiresLayout() { return true; } } |
|
返回顶楼 | |
发表时间:2010-06-21
log4j中的appender部分的配置
#define the appender named DEVICEFILE log4j.appender.DEVICEFILE=com.smartomcx.logging.DeviceFileAppender log4j.appender.DEVICEFILE.ParentFolder=../../../devices log4j.appender.DEVICEFILE.layout = org.apache.log4j.SimpleLayout log4j.logger.com.smartomcx.logging.device=DEBUG,DEVICEFILE 测试代码 public class DeviceLoggerTest { @Test public void testDeviceLogger() throws Exception { DeviceLogger logger = DeviceLogger.getDeviceLogger("1234567"); logger.info("test for device " + logger.getImei()); DeviceLogger logger2 = DeviceLogger.getDeviceLogger("1234568"); logger2.info("test for device " + logger.getImei()); DeviceLogger logger3 = DeviceLogger.getDeviceLogger("1234567"); logger3.info("another logger " + logger.getImei()); } } |
|
返回顶楼 | |
发表时间:2010-06-21
climber2002 写道 贴一下我以前的代码吧,我自己创建了一个DeviceLogger扩展了log4j的logger, 然后写了一个DeviceFileAppender。 DeviceFileAppender里面维护了一个Map,用来完成手机号跟相应的FileAppender之间的映射。 不过你的实现要考虑session失效的时候把相应的FileAppender从Map删掉,要不最终会OutOfMemory。
public class DeviceLogger extends Logger { /** The fully qualified name of the Logger class. See also the getFQCN method. */ private static final String FQCN = DeviceLogger.class.getName() + "."; /** * In log4j.properties, this logger should be configured to an appender <code>DeviceFileAppender</code> */ public static final String PARENT_LOGGER_NAME = "com.smartomcx.logging.device."; private static DeviceLoggerFactory factory = new DeviceLoggerFactory(); private String imei; protected DeviceLogger(String name) { super(name); this.imei = name.substring(PARENT_LOGGER_NAME.length()); } public String getImei() { return imei; } public static DeviceLogger getDeviceLogger(String imei) { return (DeviceLogger)Logger.getLogger(PARENT_LOGGER_NAME + imei, factory); } } public class DeviceLoggerFactory implements LoggerFactory { public Logger makeNewLoggerInstance(String imei) { return new DeviceLogger(imei); } } /** * This appender appends the log of <code>DeviceLogger</code> to a separate file for each IMEI. * Under parent folder, each imei will have a subfolder, and the log for each IMEI will be output * to device.log under each specific folder * * @author * */ public class DeviceFileAppender extends AppenderSkeleton { private ConcurrentMap<String, FileAppender> appenders = new ConcurrentHashMap<String, FileAppender>(); /** Controls file truncatation. The default value for this variable * is <code>true</code>, meaning that by default a * <code>FileAppender</code> will append to an existing file and not * truncate it. * * <p>This option is meaningful only if the FileAppender opens the * file. */ protected boolean fileAppend = true; /** The name of the parent folder. */ protected String parentFolder = null; /** Do we do bufferedIO? */ protected boolean bufferedIO = false; /** * Determines the size of IO buffer be. Default is 8K. */ protected int bufferSize = 8*1024; public DeviceFileAppender() { } public boolean isFileAppend() { return fileAppend; } public void setFileAppend(boolean fileAppend) { this.fileAppend = fileAppend; } public String getParentFolder() { return parentFolder; } /** * This is the parent folder for all devices * @param parentFolder */ public void setParentFolder(String parentFolder) { this.parentFolder = parentFolder.trim(); if(this.parentFolder.endsWith(System.getProperty("file.separator") )) { //the folder name should not contain '/' at end this.parentFolder = this.parentFolder.substring(0, this.parentFolder.length() - 1); } } public boolean isBufferedIO() { return bufferedIO; } public void setBufferedIO(boolean bufferedIO) { this.bufferedIO = bufferedIO; } public int getBufferSize() { return bufferSize; } public void setBufferSize(int bufferSize) { this.bufferSize = bufferSize; } /* (non-Javadoc) * @see org.apache.log4j.AppenderSkeleton#append(org.apache.log4j.spi.LoggingEvent) */ @Override protected void append(LoggingEvent event) { Category category = event.getLogger(); if(!(category instanceof DeviceLogger)) { //only append DeviceLogger return; } DeviceLogger logger = (DeviceLogger)category; FileAppender appender = null; try { appender = getFileAppender(logger.getImei()); } catch (IOException e) { e.printStackTrace(); return; } appender.append(event); } /** * Get the FileAppender based on the imei * @param imei * @return * @throws IOException */ protected synchronized FileAppender getFileAppender(String imei) throws IOException { FileAppender appender = this.appenders.get(imei); if(appender != null) { return appender; } String imeiFolderPath = getImeiFolderPath(imei); File imeiFolder = new File(imeiFolderPath); deleteImeiFolderIfNotDirectory(imeiFolder); createImeiFolderIfNotExist(imeiFolder); String logFilePath = getLogFilePath(imeiFolderPath); appender = new FileAppender(getLayout(), logFilePath, this.isFileAppend(), this.isBufferedIO(), this.getBufferSize()); this.appenders.put(imei, appender); return appender; } /** * Get the log file path under the IMEI folder * @param imeiFolderPath * @return */ protected String getLogFilePath(String imeiFolderPath) { String logFilePath = imeiFolderPath + System.getProperty("file.separator") + "device.log"; return logFilePath; } /** * Get the IMEI folder path for a imei * @param imei * @return */ protected String getImeiFolderPath(String imei) { String imeiFolderPath = this.parentFolder + System.getProperty("file.separator") + imei; return imeiFolderPath; } protected void deleteImeiFolderIfNotDirectory(File imeiFolder) { if(imeiFolder.exists() && !imeiFolder.isDirectory()) { imeiFolder.delete(); } } private void createImeiFolderIfNotExist(File imeiFolder) { if(! imeiFolder.exists()) { imeiFolder.mkdir(); } } /* (non-Javadoc) * @see org.apache.log4j.Appender#close() */ public void close() { closeAllAppenders(); reset(); } private void closeAllAppenders() { Set<Entry<String, FileAppender>> entries = this.appenders.entrySet(); for(Entry<String, FileAppender> entry : entries) { entry.getValue().close(); } } private void reset() { this.appenders.clear(); } /* (non-Javadoc) * @see org.apache.log4j.Appender#requiresLayout() */ public boolean requiresLayout() { return true; } } 对啊,, 难道销毁 要写成 监听 然后 把 那个MAP 改成static?? |
|
返回顶楼 | |
发表时间:2010-06-21
最后修改:2010-06-21
|
|
返回顶楼 | |
发表时间:2010-06-21
建立一个HttpSessionAttributeListener,当属性被添加时,根据一定的模式添加Appender,就OK啦。
|
|
返回顶楼 | |
发表时间:2010-06-22
mercyblitz 写道 建立一个HttpSessionAttributeListener,当属性被添加时,根据一定的模式添加Appender,就OK啦。
3Q,有一点点思路了!!! 本来以为LOG4J 实现不了.. |
|
返回顶楼 | |
发表时间:2010-06-22
lishengxi 写道 mercyblitz 写道 建立一个HttpSessionAttributeListener,当属性被添加时,根据一定的模式添加Appender,就OK啦。
3Q,有一点点思路了!!! 本来以为LOG4J 实现不了.. 再自己扩展一下log4j的file appender应该就可以了,需求的3,log4j已经实现了,只需要自己做1,2就可以了。 |
|
返回顶楼 | |