软件封装工具(牛人自制升降工具)

平时Java项目的开发通常需要统一管理日志(Log)的输出,例如控制日志信息输送的目的地(控制台、文件等),控制每一条日志的输出格式,把日志分为不同的级别等。常用的比较成熟的Java日志管理工具有Apache的Log4j等。但有时我们平时一时兴趣想写个小Dmeo或小工具,想较好的控制日志的输出,引入专业的日志管理库又显得比较繁琐,下面我就自己封装一个简单的日志工具类(LogUtils.java)。

大家好,又见面了,我是你们的朋友全栈君。

本文链接: http://blog.csdn.net/xietansheng/article/details/70478082

平时 Java 项目的开发通常需要统一管理日志(Log)的输出,例如控制日志信息输送的目的地(控制台、文件等),控制每一条日志的输出格式,把日志分为不同的级别等。常用的比较成熟的 Java 日志管理工具有 Apache 的 Log4j 等。但有时我们平时一时兴趣想写个小Dmeo或小工具,想较好的控制日志的输出,引入专业的日志管理库又显得比较繁琐,下面我就自己封装一个简单的日志工具类(LogUtils.java),需要用时拷贝即用。

LogUtils工具类支持 4 种日志级别(debug、info、warn、error),可以把日志信息格式化输出到 控制台 或 文件。

使用方法如下:

package com.xiets.log;

import java.io.File;

public class Main { 
   

    private static final String TAG = "Main";

    public static void main(String[] args) throws Exception { 
   
        // (可选) 设置日志输出级别, 默认为 INFO 级别
        LogUtils.setLogOutLevel(LogUtils.Level.DEBUG);

        // (可选) 设置日志输出文件(追加到文件尾部)
        LogUtils.setLogOutFile(new File("MyLog.log"));

        // (可选) 设置日志输出位置(是否输出到控制台 和 是否输出到文件), 默认只输出到控制台, 不输出到文件
        LogUtils.setLogOutTarget(true, true);

        // 输出日志
        LogUtils.debug(TAG, "The debug log.");
        LogUtils.info(TAG, "The info log.");
        LogUtils.warn(TAG, "The warn log.");
        LogUtils.error(TAG, "The error log.");
    }

}

LogUtils.java日志工具类的封装:

package com.xiets.log;

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.Date;

/** * 日志输出工具 <br/><br/> * * 可以输出到控制台和指定的文件中, 分为4个级别, 由低到高分别为: debug, info, warn, error * * <br/><br/> * * 输出级别: * * <ul> * <li> debug: 输出 debug, info, warn, error </li> * <li> info: 输出 info, warn, error </li> * <li> warn: 输出 warn, error </li> * <li> error: 输出 error </li> * </ul> * * 默认为 info 输出级别 * * <p/> * * Demo: * * <pre>{@code * // (可选) 设置日志输出级别, 默认为 INFO 级别 * LogUtils.setLogOutLevel(LogUtils.Level.DEBUG); * * // (可选) 设置日志输出文件(追加到文件尾部) * LogUtils.setLogOutFile(new File("MyLog.log")); * * // (可选) 设置日志输出位置(是否输出到控制台 和 是否输出到文件), 默认只输出到控制台, 不输出到文件 * LogUtils.setLogOutTarget(true, true); * * // 输出日志 * LogUtils.debug("TAG", "The debug log."); * LogUtils.info("TAG", "The info log."); * LogUtils.warn("TAG", "The warn log."); * LogUtils.error("TAG", "The error log."); * }</pre> * * @author xietansheng */
public class LogUtils { 
   

    /** 每条 Log 的 tag 输出的最大长度, 超过部分将被截断 */
    private static final int TAG_MAX_LENGTH = 20;

    /** 每条 Log 的 message 输出的最大长度, 超过部分将被截断 */
    private static final int MESSAGE_MAX_LENGTH = 1024;

    /** 日期前缀格式化 */
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd HH:mm:ss.SSS");

    /** 日志当前的输出级别, 默认为 INFO 级别 */
    private static Level logOutLevel = Level.INFO;

    /** 是否输出到控制台, 默认输出 */
    private static boolean isOutToConsole = true;

    /** 是否输出到文件 */
    private static boolean isOutToFile = false;

    /** 日志输出文件, 追加到文件尾 */
    private static File logOutFile;

    /** 日志文件输出流, 追加到文件尾 */
    private static RandomAccessFile logOutFileStream;

    public static void setLogOutLevel(Level currentLevel) { 
   
        if (currentLevel == null) { 
   
            currentLevel = Level.INFO;
        }
        LogUtils.logOutLevel = currentLevel;
    }

    public static synchronized void setLogOutFile(File logOutFile) throws IOException { 
   
        LogUtils.logOutFile = logOutFile;
        
        if (logOutFileStream != null) { 
   
            closeStream(logOutFileStream);
            logOutFileStream = null;
        }
        
        if (LogUtils.logOutFile != null) { 
   
            try { 
   
                logOutFileStream = new RandomAccessFile(LogUtils.logOutFile, "rw");
                logOutFileStream.seek(LogUtils.logOutFile.length());
            } catch (IOException e) { 
   
                closeStream(logOutFileStream);
                logOutFileStream = null;
                throw e;
            }
        }
    }

    public static void setLogOutTarget(boolean isOutToConsole, boolean isOutToFile) { 
   
        LogUtils.isOutToConsole = isOutToConsole;
        LogUtils.isOutToFile = isOutToFile;
    }

    public static void debug(String tag, String message) { 
   
        printLog(Level.DEBUG, tag, message, false);
    }

    public static void info(String tag, String message) { 
   
        printLog(Level.INFO, tag, message, false);
    }

    public static void warn(String tag, String message) { 
   
        printLog(Level.WARN, tag, message, false);
    }

    public static void error(String tag, String message) { 
   
        printLog(Level.ERROR, tag, message, true);
    }

    public static void error(String tag, Exception e) { 
   
        if (e == null) { 
   
            error(tag, (String) null);
            return;
        }
        
        PrintStream printOut = null;
        
        try { 
   
            ByteArrayOutputStream bytesBufOut = new ByteArrayOutputStream();
            printOut = new PrintStream(bytesBufOut);
            e.printStackTrace(printOut);
            printOut.flush();
            error(tag, new String(bytesBufOut.toByteArray(), "UTF-8"));
            
        } catch (Exception e1) { 
   
            e1.printStackTrace();
            
        } finally { 
   
            closeStream(printOut);
        }
    }

    private static void printLog(Level level, String tag, String message, boolean isOutToErr) { 
   
        if (level.getLevelValue() >= logOutLevel.getLevelValue()) { 
   
            String log = DATE_FORMAT.format(new Date()) +
                    " " +
                    level.getTag() +
                    "/" +
                    checkTextLengthLimit(tag, TAG_MAX_LENGTH) +
                    ": " +
                    checkTextLengthLimit(message, MESSAGE_MAX_LENGTH);

            if (isOutToConsole) { 
   
                outLogToConsole(isOutToErr, log);
            }
            if (isOutToFile) { 
   
                outLogToFile(log);
            }
        }
    }

    private static void outLogToConsole(boolean isOutToErr, String log) { 
   
        if (isOutToErr) { 
   
            // System.err 和 System.out 是两个不同的输出流通道, 如果极短时间内连
            // 续输出 log 到 err 和 out, 控制台上的打印顺序可能会不完全按时序打印.
            System.err.println(log);
        } else { 
   
            System.out.println(log);
        }
    }

    private static synchronized void outLogToFile(String log) { 
   
        if (logOutFileStream != null) { 
   
            try { 
   
                logOutFileStream.write((log + "\n").getBytes("UTF-8"));
            } catch (IOException e) { 
   
                e.printStackTrace();
            }
        }
    }

    private static String checkTextLengthLimit(String text, int maxLength) { 
   
        if ((text != null) && (text.length() >  maxLength)) { 
   
            text = text.substring(0, maxLength - 3) + "...";
        }
        return text;
    }

    private static void closeStream(Closeable stream) { 
   
        if (stream != null) { 
   
            try { 
   
                stream.close();
            } catch (Exception e) { 
   
                // nothing
            }
        }
    }

    public static enum Level { 
   
        DEBUG("D", 1), INFO("I", 2), WARN("W", 3), ERROR("E", 4);

        private String tag;

        private int levelValue;

        private Level(String tag, int levelValue) { 
   
            this.tag = tag;
            this.levelValue = levelValue;
        }

        public String getTag() { 
   
            return tag;
        }

        public int getLevelValue() { 
   
            return levelValue;
        }
    }

}

控制台输出结果:

result.png

日志文件输出结果:

result-file.png


软件封装工具(牛人自制升降工具)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/128987.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 有序的hashmap_在待排序的元素基本有序的前提下

    有序的hashmap_在待排序的元素基本有序的前提下如何给HashMap中的值排序?这个问题很多人都遇到过,很常见的一个方案是使用LinkedHashMap,因为LinkedHashMap可以记住元素放入的顺序,可以认为是真正的“有序”(想让HashMap有序是不可能的),我比较喜欢。然而问题是往往数据已经封装在了HashMap中,我们必须手动的排序后再放入LinkedHashMap,这当然也就成了思路,代码实现起来也很简单,写出来看起来还挺舒服的…

    2025年8月5日
    3
  • mac系统webstorm快捷键

    mac系统webstorm快捷键WebStorm是jetbrains公司旗下一款JavaScript开发工具。被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaSscriptIDE”等。与IntelliJIDEA同源,继承了IntelliJIDEA强大的JS部分的功能.现将最常用的快捷键挑出来备忘,既能方便记忆,又能提高工作效率。快捷键作用…

    2022年5月23日
    45
  • cpu流水线工作原理_嵌入式工作原理

    cpu流水线工作原理_嵌入式工作原理现在的CPU处理器一般都是超流水线工作,动不动就是10级以上流水线,超高主频,这两者之间有什么关系呢?今天就跟大家科普下CPU流水线的工作原理,以及他们之间的关系。说到流水线,很多人会想到富士康;说到富士康,很多人会想到张全蛋。作为富士康3号流水线资深质检员,下面就请张全蛋给大家科普下什么是流水线,大家鼓掌欢迎。MichealJack眼中的流水线大家好,我是张全蛋,英文名叫MichealJack,法文名叫霍雷呆-杰Q赖,大家也可以叫我查理。作为iPhone手机3号流水线的资.

    2022年8月20日
    7
  • 如何自己搭建服务器_文件服务器搭建

    如何自己搭建服务器_文件服务器搭建FlashFXP使用其实就是为了实现文件的上传和下载,它要结合

    2025年10月25日
    4
  • 软件著作权需要源代码吗_版权生成软件官网

    软件著作权需要源代码吗_版权生成软件官网工作过程写了一个上位机软件,想申请一个软件著作权,其中有一项是提供项目源代码;一个一个文件打开去复制有点太愚蠢了,就想找找有没有什么自动化处理的工具;还真的找到一个,下面分享给大家我是怎么用的;1.解压压缩包,打开工程:2.我用的是VS2017打开毫无障碍:3.最好先清理解决方案,然后再编译运行:4.最后就能见到自动化处理工具了:5.需要的话评论里留言,我再分享给大家;…

    2022年9月22日
    2
  • goland 激活码 2021.8_在线激活

    (goland 激活码 2021.8)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~S32PGH0SQB-eyJsaWNlbnNlSWQiOi…

    2022年3月25日
    110

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号