- 浏览: 37583 次
- 性别:
- 来自: 沈阳
最新评论
-
亮亮婷婷:
奥奥,我也是这样做的咧。我用的版本是CXF2.1.3(CXF2 ...
CXF STP不能生成WSDL文件 -
harbey:
genius0182 写道请问DisplayTag控件中文翻页 ...
请问DisplayTag控件中文翻页的问题 -
stckiss:
cxf2.1.3行不?搞了两小时还没搞定
CXF STP不能生成WSDL文件 -
genius0182:
问题解决了,反CXF换成2.1就好用了.
CXF STP不能生成WSDL文件 -
genius0182:
如果我把Spring的配置文件中的hibernate缓存设成f ...
getHibernateTemplate().find()和executeFind()的问题
最近因为需要写了一个日志模块,主要功能是实现日志文件滚动(不限日志文件个数的滚动),还有就是记录日志信息。因为我功能有限,所以我没有选择log4j这样的日志扩展,而选择了jdk log扩展。
开发环境是netbean 6.8
下面是扩展JDK LOG的Handler的类 直接上代码了。
import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.security.AccessController; import java.security.PrivilegedAction; import java.text.SimpleDateFormat; import java.util.Date; import java.util.logging.ErrorManager; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.LogRecord; import java.util.logging.SimpleFormatter; public class RollingFileHandler extends Handler { private MeteredStream meter; private boolean append; private int limit; // zero => no limit. private int count; private String pattern; private LogManager manager = LogManager.getLogManager(); private boolean doneHeader; private Writer writerHandler; private OutputStream output; ErrorManager error; private static int index = 1; @Override public synchronized void flush() { if (writerHandler != null) { try { writerHandler.flush(); } catch (Exception ex) { // We don't want to throw an exception here, but we // report the exception to any registered ErrorManager. reportError(null, ex, ErrorManager.FLUSH_FAILURE); } } } private synchronized void flushAndClose() throws SecurityException { manager.checkAccess(); if (writerHandler != null) { try { if (!doneHeader) { writerHandler.write(getFormatter().getHead(this)); doneHeader = true; } writerHandler.write(getFormatter().getTail(this)); writerHandler.flush(); writerHandler.close(); } catch (Exception ex) { // We don't want to throw an exception here, but we // report the exception to any registered ErrorManager. reportError(null, ex, ErrorManager.CLOSE_FAILURE); } writerHandler = null; output = null; } } /** * Change the output stream. * <P> * If there is a current output stream then the <tt>Formatter</tt>'s * tail string is written and the stream is flushed and closed. * Then the output stream is replaced with the new output stream. * * @param out New output stream. May not be null. * @exception SecurityException if a security manager exists and if * the caller does not have <tt>LoggingPermission("control")</tt>. */ protected synchronized void setOutputStream(OutputStream out) throws SecurityException { if (out == null) { throw new NullPointerException(); } flushAndClose(); output = out; doneHeader = false; String encoding = getEncoding(); if (encoding == null) { writerHandler = new OutputStreamWriter(out); } else { try { writerHandler = new OutputStreamWriter(out, encoding); } catch (UnsupportedEncodingException ex) { // This shouldn't happen. The setEncoding method // should have validated that the encoding is OK. throw new Error("Unexpected exception " + ex); } } } /** * Set (or change) the character encoding used by this <tt>Handler</tt>. * <p> * The encoding should be set before any <tt>LogRecords</tt> are written * to the <tt>Handler</tt>. * * @param encoding The name of a supported character encoding. * May be null, to indicate the default platform encoding. * @exception SecurityException if a security manager exists and if * the caller does not have <tt>LoggingPermission("control")</tt>. * @exception UnsupportedEncodingException if the named encoding is * not supported. */ public void setEncoding(String encoding) throws SecurityException, java.io.UnsupportedEncodingException { super.setEncoding(encoding); if (output == null) { return; } // Replace the current writer with a writer for the new encoding. flush(); if (encoding == null) { writerHandler = new OutputStreamWriter(output); } else { writerHandler = new OutputStreamWriter(output, encoding); } } // A metered stream is a subclass of OutputStream that // (a) forwards all its output to a target stream // (b) keeps track of how many bytes have been written private class MeteredStream extends OutputStream { OutputStream out; int written; boolean doneHeader; Writer writer; MeteredStream(OutputStream out, int written) { this.out = out; this.written = written; } public void write(int b) throws IOException { out.write(b); written++; } public void write(byte buff[]) throws IOException { out.write(buff); written += buff.length; } public void write(byte buff[], int off, int len) throws IOException { out.write(buff, off, len); written += len; } public void flush() throws IOException { out.flush(); } public void close() throws IOException { out.close(); } } private void open(File fname, boolean append) throws IOException { int len = 0; if (append) { len = (int) fname.length(); } FileOutputStream fout = new FileOutputStream(fname.toString(), append); BufferedOutputStream bout = new BufferedOutputStream(fout); meter = new MeteredStream(bout, len); setOutputStream(meter); } // Private method to configure a FileHandler from LogManager // properties and/or default values as specified in the class // javadoc. private void configure() { LogManager manager = LogManager.getLogManager(); String cname = getClass().getName(); pattern = "%h/java%u.log"; limit = 0; if (limit < 0) { limit = 0; } append = false; setLevel(Level.ALL); setFilter(null); setFormatter(new SimpleFormatter()); try { setEncoding(null); } catch (Exception ex) { try { setEncoding(null); } catch (Exception ex2) { // doing a setEncoding with null should always work. // assert false; } } } /** * Construct a default <tt>FileHandler</tt>. This will be configured * entirely from <tt>LogManager</tt> properties (or their default values). * <p> * @exception IOException if there are IO problems opening the files. * @exception SecurityException if a security manager exists and if * the caller does not have <tt>LoggingPermission("control"))</tt>. * @exception NullPointerException if pattern property is an empty String. */ public RollingFileHandler() throws IOException, SecurityException { manager.checkAccess(); configure(); openFiles(); } /** * Initialize a <tt>FileHandler</tt> to write to the given filename. * <p> * The <tt>FileHandler</tt> is configured based on <tt>LogManager</tt> * properties (or their default values) except that the given pattern * argument is used as the filename pattern, the file limit is * set to no limit, and the file count is set to one. * <p> * There is no limit on the amount of data that may be written, * so use this with care. * * @param pattern the name of the output file * @exception IOException if there are IO problems opening the files. * @exception SecurityException if a security manager exists and if * the caller does not have <tt>LoggingPermission("control")</tt>. * @exception IllegalArgumentException if pattern is an empty string */ public RollingFileHandler(String pattern) throws IOException, SecurityException { if (pattern.length() < 1) { throw new IllegalArgumentException(); } manager.checkAccess(); configure(); this.pattern = pattern; this.limit = 0; this.count = 1; openFiles(); } /** * Initialize a <tt>FileHandler</tt> to write to the given filename, * with optional append. * <p> * The <tt>FileHandler</tt> is configured based on <tt>LogManager</tt> * properties (or their default values) except that the given pattern * argument is used as the filename pattern, the file limit is * set to no limit, the file count is set to one, and the append * mode is set to the given <tt>append</tt> argument. * <p> * There is no limit on the amount of data that may be written, * so use this with care. * * @param pattern the name of the output file * @param append specifies append mode * @exception IOException if there are IO problems opening the files. * @exception SecurityException if a security manager exists and if * the caller does not have <tt>LoggingPermission("control")</tt>. * @exception IllegalArgumentException if pattern is an empty string */ public RollingFileHandler(String pattern, boolean append) throws IOException, SecurityException { if (pattern.length() < 1) { throw new IllegalArgumentException(); } manager.checkAccess(); configure(); this.pattern = pattern; this.limit = 0; this.count = 1; this.append = append; openFiles(); } /** * Initialize a <tt>FileHandler</tt> to write to a set of files. When * (approximately) the given limit has been written to one file, * another file will be opened. The output will cycle through a set * of count files. * <p> * The <tt>FileHandler</tt> is configured based on <tt>LogManager</tt> * properties (or their default values) except that the given pattern * argument is used as the filename pattern, the file limit is * set to the limit argument, and the file count is set to the * given count argument. * <p> * The count must be at least 1. * * @param pattern the pattern for naming the output file * @param limit the maximum number of bytes to write to any one file * @param count the number of files to use * @exception IOException if there are IO problems opening the files. * @exception SecurityException if a security manager exists and if * the caller does not have <tt>LoggingPermission("control")</tt>. * @exception IllegalArgumentException if limit < 0, or count < 1. * @exception IllegalArgumentException if pattern is an empty string */ public RollingFileHandler(String pattern, int limit, int count) throws IOException, SecurityException { if (limit < 0 || count < 1 || pattern.length() < 1) { throw new IllegalArgumentException(); } manager.checkAccess(); configure(); this.pattern = pattern; this.limit = limit; this.count = count; openFiles(); } /** * Initialize a <tt>FileHandler</tt> to write to a set of files * with optional append. When (approximately) the given limit has * been written to one file, another file will be opened. The * output will cycle through a set of count files. * <p> * The <tt>FileHandler</tt> is configured based on <tt>LogManager</tt> * properties (or their default values) except that the given pattern * argument is used as the filename pattern, the file limit is * set to the limit argument, and the file count is set to the * given count argument, and the append mode is set to the given * <tt>append</tt> argument. * <p> * The count must be at least 1. * * @param pattern the pattern for naming the output file * @param limit the maximum number of bytes to write to any one file * @param count the number of files to use * @param append specifies append mode * @exception IOException if there are IO problems opening the files. * @exception SecurityException if a security manager exists and if * the caller does not have <tt>LoggingPermission("control")</tt>. * @exception IllegalArgumentException if limit < 0, or count < 1. * @exception IllegalArgumentException if pattern is an empty string * */ public RollingFileHandler(String pattern, int limit, int count, boolean append) throws IOException, SecurityException { if (limit < 0 || pattern.length() < 1) { throw new IllegalArgumentException(); } manager.checkAccess(); configure(); this.pattern = pattern; this.limit = limit; this.count = count; this.append = append; openFiles(); } // Private method to open the set of output files, based on the // configured instance variables. private void openFiles() throws IOException { if (append) { File f = new File(pattern); try { open(f, true); } catch (IOException ex) { reportError(null, ex, ErrorManager.OPEN_FAILURE); } } else { rotate(); } } // Rotate the set of output files private synchronized void rotate() { File target; File file; Level oldLevel = getLevel(); setLevel(Level.OFF); close(); Date date = new Date(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss"); String dateFormat = format.format(date); boolean renameSucceeded = true; if (count > 0) { file = new File(pattern + '_' + dateFormat + '.' + count); if (file.exists()) { index++; target = new File(pattern + '_' + dateFormat + "." + index); renameSucceeded = file.renameTo(target); } for (int i = count - 1; i >= 1 && renameSucceeded; i--) { file = new File(pattern + "." + i); if (file.exists()) { target = new File(pattern + '.' + (i + 1)); renameSucceeded = file.renameTo(target); } } if (renameSucceeded) { // Rename fileName to fileName.1 index = 1; target = new File(pattern + '_' + dateFormat + "." + 1); file = new File(pattern); renameSucceeded = file.renameTo(target); // // if file rename failed, reopen file with append = true // if (!renameSucceeded) { File f = new File(pattern); append = true; try { open(f, append); } catch (IOException ex) { reportError(null, ex, ErrorManager.OPEN_FAILURE); } } } } if (renameSucceeded) { File f = new File(pattern); try { open(f, false); } catch (IOException ex) { reportError(null, ex, ErrorManager.OPEN_FAILURE); } } setLevel(oldLevel); } /** * Format and publish a <tt>LogRecord</tt>. * * @param record description of the log event. A null record is * silently ignored and is not published */ public synchronized void publish(LogRecord record) { if (!isLoggable(record)) { return; } String msg; try { msg = getFormatter().format(record); } catch (Exception ex) { // We don't want to throw an exception here, but we // report the exception to any registered ErrorManager. reportError(null, ex, ErrorManager.FORMAT_FAILURE); return; } try { if (!doneHeader) { writerHandler.write(getFormatter().getHead(this)); doneHeader = true; } if (writerHandler == null) { File f = new File(pattern); open(f, append); } writerHandler.write(msg); } catch (Exception ex) { // We don't want to throw an exception here, but we // report the exception to any registered ErrorManager. reportError(null, ex, ErrorManager.WRITE_FAILURE); } flush(); if (limit > 0 && meter.written >= limit) { // We performed access checks in the "init" method to make sure // we are only initialized from trusted code. So we assume // it is OK to write the target files, even if we are // currently being called from untrusted code. // So it is safe to raise privilege here. AccessController.doPrivileged(new PrivilegedAction() { public Object run() { rotate(); return null; } }); } } /** * Close all the files. * * @exception SecurityException if a security manager exists and if * the caller does not have <tt>LoggingPermission("control")</tt>. */ public synchronized void close() throws SecurityException { flushAndClose(); } private static class InitializationErrorManager extends ErrorManager { Exception lastException; public void error(String msg, Exception ex, int code) { lastException = ex; } } // Private native method to check if we are in a set UID program. private static native boolean isSetUID(); }
然后是Util类的代码
import java.io.IOException; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; public class Utils { private static Logger log; /** * @serial Class that issued logging call */ protected static String sourceClassName; /** * @serial Method that issued logging call */ protected static String sourceMethodName; private transient boolean needToInferCaller; static { inferCaller(); Handler handler = configure("log.log",1000,1,true); try { log = Logger.getLogger(sourceClassName); log.addHandler(handler); log.setLevel(Level.ALL); } catch (Exception ex) { System.out.println("can't init the Logger, caused by: " + ex); } } public static void debug(String info) { inferCaller(); log.logp(Level.SEVERE, sourceClassName, sourceMethodName, info); } public static void debug(String info,Throwable thrown){ inferCaller(); log.logp(Level.SEVERE, sourceClassName, sourceMethodName, info,thrown); } public static void info(String info) { inferCaller(); log.logp(Level.INFO, sourceClassName, sourceMethodName, info); } public static void info(String info,Throwable thrown){ inferCaller(); log.logp(Level.INFO, sourceClassName, sourceMethodName, info,thrown); } public static void warning(String info) { inferCaller(); log.logp(Level.WARNING, sourceClassName, sourceMethodName, info); } public static void warning(String info,Throwable thrown){ inferCaller(); log.logp(Level.WARNING, sourceClassName, sourceMethodName, info,thrown); } public static void error(String info) { inferCaller(); log.logp(Level.SEVERE, sourceClassName, sourceMethodName, info); } public static void error(String info,Throwable thrown){ inferCaller(); log.logp(Level.SEVERE, sourceClassName, sourceMethodName, info,thrown); } private static void init() { inferCaller(); log = Logger.getLogger(Utils.sourceClassName); } // Private method to infer the caller's class and method names private static void inferCaller() { // needToInferCaller = false; // Get the stack trace. StackTraceElement stack[] = (new Throwable()).getStackTrace(); // First, search back to a method in the Logger class. int ix = 0; while (ix < stack.length) { StackTraceElement frame = stack[ix]; String cname = frame.getClassName(); if (cname.equals("com.lhsm.logger.Utils")) { stack[ix] = stack[2]; break; } ix++; } // Now search for the first frame before the "Logger" class. while (ix < stack.length) { StackTraceElement frame = stack[ix]; String cname = frame.getClassName(); if (!cname.equals("com.lhsm.logger.Utils")) { // We've found the relevant frame. sourceClassName = cname; sourceMethodName = frame.getMethodName(); return; } ix++; } // We haven't found a suitable frame, so just punt. This is // OK as we are only committed to making a "best effort" here. } /** * * @param pattern 为生成的输出文件名称指定一个模式。 * @param limit 指定要写入到任意文件的近似最大量(以字节为单位)。如果该数为 0,则没有限制(默认为无限制)。.不能小于0 * @param count (1为不限滚动),这里指定个数滚动文件没有实现 * @param append 指定是否应该将 FileHandler 追加到任何现有文件上。 * @return */ public static Handler configure(String pattern,int limit,int count,boolean append) { Handler handler = null; if (limit < 0 || pattern.length() < 1) { throw new IllegalArgumentException(); } try { handler = new RollingFileHandler(pattern, limit, count, append); } catch (IOException ex) { Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex); } catch (SecurityException ex) { Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex); } return handler; } /** * @return the sourceClassName */ public String getSourceClassName() { if (needToInferCaller) { inferCaller(); } return sourceClassName; } /** * @return the sourceMethodName */ public String getSourceMethodName() { if (needToInferCaller) { inferCaller(); } return sourceMethodName; } }
下面是一个测试Foo类
public class Foo { private int i =0; public Foo(int i) { this.i = i; } public void doIt() { Utils.debug("Debug..."+i); Utils.info("Info..."+i); Utils.warning("Warn..."+i); Utils.error("Error..."+i); } public void doFooIt() { Utils.debug("Debug..."+i); Utils.info("Info..."+i); Utils.warning("Warn..."+i); Utils.error("Error..."+i); } }
public class LogTest { public static void main(String[] args) { for (int i = 0; i < 10000; i++) { Foo foo = new Foo(i); foo.doIt(); foo.doFooIt(); } } }
以上就是实现的全部代码
- LogDemo.rar (27.3 KB)
- 下载次数: 31
发表评论
文章已被作者锁定,不允许评论。
相关推荐
虽然JDK的内置日志框架提供了基础的日志功能,但其灵活性和可扩展性相较于Log4j或Logback等第三方框架略显不足。因此,开发者经常选择这些第三方库,以获得更丰富的特性,如更精细的配置选项、更高效的性能和更好的...
本文将深入探讨Java中的log日志组件,包括JDK内置的日志(jdkLog)、Apache的Commons Logging(commonLog)以及流行的log4j。了解这些组件的特点和用法,将提升你对Java日志处理的理解。 首先,我们来看看JDK内置的...
总的来说,Log4j2作为日志框架的新一代产品,提供了许多增强的功能和优化,能够更好地满足开发者对日志管理的需求。对于大型企业和复杂系统,正确配置和使用Log4j2可以极大地提升系统的可维护性和稳定性。
log4j的主要优势在于其灵活性和可扩展性,允许用户通过配置文件自定义日志记录的方式,无需修改应用程序代码。 #### 二、日志记录的目的 在应用程序中记录日志主要有以下三个目的: 1. **监视代码中变量的变化...
log4j日志写入redis扩展 一. 环境log4j 1.2.17 + jedis 2.9.0 + 1.2.31 + jdk8二. log4j.properties相关配置具体配置信息在resource下的配置文件log4j.properties:log4j.appender.D=org.apache.log4j....
### 日志框架总结:JUL、Log4j、Log4j2、Logback及门面技术 ...而对于复杂的企业级应用,则可能需要考虑使用更加强大和灵活的日志框架如Logback或Log4j2,并结合日志门面技术SLF4j来进一步增强系统的可维护性和扩展性。
虽然JDK Logger在简单场景下已经足够使用,但在大型项目中,可能需要更强大和灵活的日志框架,如Log4j或Logback。这些框架提供了更多功能,如异步日志处理、更高级的过滤规则和更丰富的插件体系。 ### 总结 JDK ...
在Linux环境下搭建Kafka,你需要修改`config/server.properties`文件,配置包括broker.id(每个Kafka节点的唯一标识)、zookeeper.connect(指向Zookeeper集群的连接字符串)、log.dirs(Kafka日志数据存储路径)等...
Log4j 2相较于Log4j 1.x在性能、可扩展性和灵活性方面有了显著提升,引入了新的API和组件,优化了日志处理机制。 一、Log4j 2概述 Log4j 2的核心设计理念是提供高性能、低延迟的日志记录,并且支持异步日志记录,这...
- **Filter**: 过滤器允许对日志事件进行条件筛选,根据预定义的规则决定哪些日志事件被处理。 - **Level**: 日志级别用于定义日志信息的严重性,通常包括DEBUG、INFO、WARN、ERROR和FATAL。 2. **Log4j的功能** ...
这是因为`commons-logging`的接口使得代码对日志库的依赖变得透明,而`log4j`的强大功能则提供了实际的日志记录服务。这种组合并不会增加额外的学习和维护成本,反而简化了配置和使用。`commons-logging`会自动检测...
在log4j推出时,其优异性能曾引起Sun公司注意,甚至考虑将其纳入JDK1.4中替代原有的日志工具,但因JDK1.4接近完成而未能实现。尽管如此,log4j凭借其优势在Java开发中占据了主导地位,成为首选的日志记录解决方案。 ...
总的来说,log-sys是一个结合了现代微服务架构理念和技术的分布式日志系统,它利用Spring Cloud的智能化服务治理和Docker的容器化优势,提供了高效、可扩展的日志解决方案。对于需要处理大规模日志数据的企业和...
对于大型分布式系统而言,Log4j 2.7的可扩展性和灵活性使其成为理想的日志解决方案。 解压`apache-log4j-2.7-bin`压缩包后,通常会包含`log4j-api-2.7.jar`(API库)、`log4j-core-2.7.jar`(核心实现库)、文档、...
8. **其他依赖库**:如log4j.jar用于日志记录,commons-lang3.jar、commons-logging.jar等Apache Commons库,还有javassist.jar用于动态字节码操作。 在实际开发中,你可能还需要其他的jar包来支持额外的功能,如...
同时,通过配置logback或log4j等日志框架,可以实现详细的日志记录,方便问题排查。 9. 安全性:Jetty支持基本的身份验证、SSL/TLS加密以及角色权限控制,确保Web应用的安全性。 10. 扩展性:Jetty的设计允许通过...
4. **JDK自带日志**:如果上述条件均不满足,则检查JDK版本是否支持日志记录功能(通常从JDK 1.4开始提供),如果是,则使用JDK自带的日志实现。 5. **SimpleLog**:最后,如果上述所有选项都不可用,则使用Commons-...