zoukankan      html  css  js  c++  java
  • 输出高效的日志信息

      日志系统(Log System)是将信息输出到一个或者多个目标上的一种机制。一个日志器(Logger)有下面几个组件。

    • 一个或多个处理器(Handler):处理器决定目标和日志消息的格式。可以把日志消息输出到控制台上、写到文件中或保存到数据库中。
    • 一个名称(Name):一般来说,类中的日志记录器的名称是基于它的包名和类名的。
    • 一个级别(Level):日志消息有一个关联的级别来表示它的重要性。日志记录器也有一个级别用来决定它要输出什么级别的消息。日志记录器仅输出与它的级别相同重要或者更重要的消息。

      使用日志系统有以下两个主要目的:

    • 当捕获到异常时尽可能多地输出信息,这有助于定位并解决错误;
    • 输出关于程序正在执行的类和方法的信息。

      在本节,我们将学习如何使用java.util.logging包提供的类来将一个日志系统增加到并发应用程序中。

    1. 创建一个名为MyFormatter的类,继承java.util.logging.Formatter类。然后,实现抽象format()方法。它以LogRecord对象为参数,返回一个带有日志消息的String对象。

    import java.util.Date;
    import java.util.logging.Formatter;
    import java.util.logging.LogRecord;
    
    public class MyFormatter extends Formatter {
    
        @Override
        public String format(LogRecord record) {
            StringBuilder sb = new StringBuilder();
            sb.append("["+record.getLevel()+"] - ");
            sb.append(new Date(record.getMillis())+" : ");
            sb.append(record.getSourceClassName()+"."+record.getSourceMethodName()+" : ");
            sb.append(record.getMessage()+"
    ");
            return sb.toString();
        }
    
    }

    2. 创建一个名为MyLogger的类。

    import java.io.IOException;
    import java.util.logging.FileHandler;
    import java.util.logging.Formatter;
    import java.util.logging.Handler;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    
    public class MyLogger {
        private static Handler handler;
        
        public static Logger getLogger(String name){
            Logger logger = Logger.getLogger(name);
            logger.setLevel(Level.ALL);
            try {
                if(handler==null){
                    handler = new FileHandler("D:\recipe8.log");
                    Formatter format = new MyFormatter();
                    handler.setFormatter(format);
                }
                if(logger.getHandlers().length==0){
                    logger.addHandler(handler);
                }
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return logger;
        }
    }

    3. 创建一个名为Task的类,实现Runnable接口。它是用来测试Logger对象的任务。

    import java.util.concurrent.TimeUnit;
    import java.util.logging.Logger;
    
    public class Task implements Runnable {
            
        @Override
        public void run() {
            try {            
                Logger logger = MyLogger.getLogger(this.getClass().getName());
                logger.entering(Thread.currentThread().getName(), "run()");
                TimeUnit.SECONDS.sleep(2);
                logger.exiting(Thread.currentThread().getName(), "exit()",
                        Thread.currentThread());
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }    
        
    }

    4. 实现范例的主类Main,并实现main()方法。

    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    
    public class Main {
    
        public static void main(String[] args) {
            Logger logger = MyLogger.getLogger("Core");
            logger.entering("Core", "main()",args);
            Thread threads[] = new Thread[5];
            for(int i=0;i<threads.length;i++){
                logger.log(Level.INFO, "Launching thread: ", +i);
                Task task = new Task();
                threads[i] = new Thread(task);
                logger.log(Level.INFO, "Thread created: "+threads[i].getName());
                threads[i].start();
            }
            logger.log(Level.INFO, "Five Threads created. Waiting for its finalization.");
            try {
                for(int i=0;i<threads.length;i++){
                    threads[i].join();
                    logger.log(Level.INFO, "Thread has finished its execution", threads[i]);
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            logger.exiting("Core", "main()");
        }
    }

    5. 控制台输出结果如下

    十月 28, 2015 7:40:16 下午 Main main
    信息: Launching thread: 
    十月 28, 2015 7:40:16 下午 Main main
    信息: Thread created: Thread-1
    十月 28, 2015 7:40:16 下午 Main main
    信息: Launching thread: 
    十月 28, 2015 7:40:16 下午 Main main
    信息: Thread created: Thread-2
    十月 28, 2015 7:40:16 下午 Main main
    信息: Launching thread: 
    十月 28, 2015 7:40:16 下午 Main main
    信息: Thread created: Thread-3
    十月 28, 2015 7:40:16 下午 Main main
    信息: Launching thread: 
    十月 28, 2015 7:40:16 下午 Main main
    信息: Thread created: Thread-4
    十月 28, 2015 7:40:16 下午 Main main
    信息: Launching thread: 
    十月 28, 2015 7:40:16 下午 Main main
    信息: Thread created: Thread-5
    十月 28, 2015 7:40:16 下午 Main main
    信息: Five Threads created. Waiting for its finalization.
    十月 28, 2015 7:40:18 下午 Main main
    信息: Thread has finished its execution
    十月 28, 2015 7:40:18 下午 Main main
    信息: Thread has finished its execution
    十月 28, 2015 7:40:18 下午 Main main
    信息: Thread has finished its execution
    十月 28, 2015 7:40:18 下午 Main main
    信息: Thread has finished its execution
    十月 28, 2015 7:40:18 下午 Main main
    信息: Thread has finished its execution
    View Code

    6. 日志recipe8.log内容如下:

    [FINER] - Wed Oct 28 19:40:16 CST 2015 : Core.main() : ENTRY
    [INFO] - Wed Oct 28 19:40:16 CST 2015 : Main.main : Launching thread: 
    [INFO] - Wed Oct 28 19:40:16 CST 2015 : Main.main : Thread created: Thread-1
    [INFO] - Wed Oct 28 19:40:16 CST 2015 : Main.main : Launching thread: 
    [INFO] - Wed Oct 28 19:40:16 CST 2015 : Main.main : Thread created: Thread-2
    [FINER] - Wed Oct 28 19:40:16 CST 2015 : Thread-1.run() : ENTRY
    [INFO] - Wed Oct 28 19:40:16 CST 2015 : Main.main : Launching thread: 
    [INFO] - Wed Oct 28 19:40:16 CST 2015 : Main.main : Thread created: Thread-3
    [INFO] - Wed Oct 28 19:40:16 CST 2015 : Main.main : Launching thread: 
    [FINER] - Wed Oct 28 19:40:16 CST 2015 : Thread-3.run() : ENTRY
    [INFO] - Wed Oct 28 19:40:16 CST 2015 : Main.main : Thread created: Thread-4
    [INFO] - Wed Oct 28 19:40:16 CST 2015 : Main.main : Launching thread: 
    [FINER] - Wed Oct 28 19:40:16 CST 2015 : Thread-2.run() : ENTRY
    [FINER] - Wed Oct 28 19:40:16 CST 2015 : Thread-4.run() : ENTRY
    [INFO] - Wed Oct 28 19:40:16 CST 2015 : Main.main : Thread created: Thread-5
    [INFO] - Wed Oct 28 19:40:16 CST 2015 : Main.main : Five Threads created. Waiting for its finalization.
    [FINER] - Wed Oct 28 19:40:16 CST 2015 : Thread-5.run() : ENTRY
    [FINER] - Wed Oct 28 19:40:18 CST 2015 : Thread-1.exit() : RETURN {0}
    [INFO] - Wed Oct 28 19:40:18 CST 2015 : Main.main : Thread has finished its execution
    [FINER] - Wed Oct 28 19:40:18 CST 2015 : Thread-3.exit() : RETURN {0}
    [FINER] - Wed Oct 28 19:40:18 CST 2015 : Thread-4.exit() : RETURN {0}
    [FINER] - Wed Oct 28 19:40:18 CST 2015 : Thread-2.exit() : RETURN {0}
    [INFO] - Wed Oct 28 19:40:18 CST 2015 : Main.main : Thread has finished its execution
    [INFO] - Wed Oct 28 19:40:18 CST 2015 : Main.main : Thread has finished its execution
    [INFO] - Wed Oct 28 19:40:18 CST 2015 : Main.main : Thread has finished its execution
    [FINER] - Wed Oct 28 19:40:18 CST 2015 : Thread-5.exit() : RETURN {0}
    [INFO] - Wed Oct 28 19:40:18 CST 2015 : Main.main : Thread has finished its execution
    [FINER] - Wed Oct 28 19:40:18 CST 2015 : Core.main() : RETURN
    View Code

      在上面的实现类中,已使用LogRecord类的下列方法来获取日志消息的信息。

    • getLevel():返回消息级别。
    • getMillis():返回发送消息到Logger对象时的时间(从1970开始计算的毫秒数)。
    • getSourceClassName():返回发送消息到Logger的类的名称。
    • getSourceMessageName():返回发送消息到Logger的方法的名称。
    • getMessage()方法返回日志消息。

      在主程序中,使用了下列方法。

    • entering():输出FINER级别的消息表示方法开始执行。
    • exiting():输出FINER级别的消息表示方法停止执行。
    • log():输出带有指定级别的消息。

      也有其他类库比java.util.logging包提供了更完全的日志系统,如Log4j或slf4j类库。但是java.util.logging包是Java API的一部分,并且它的所有方法都是安全的,所以用在并发应用程序中没有问题。

  • 相关阅读:
    微信公众号开发的时候code失效的问题
    微信公众平台测试号通过网页授权获取用户的信息
    做了一些mysql的习题 感觉用来应付面试是足够了
    springMVC在使用重定向跳转
    jsp获取标签数据
    再来一次atm机 用文本做的
    django mysql数据库配置
    django url控制器
    django初始要做的事情
    flask学习
  • 原文地址:https://www.cnblogs.com/gaopeng527/p/4918093.html
Copyright © 2011-2022 走看看