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

平时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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 让我教你怎么做个人_如何制作app平台

    让我教你怎么做个人_如何制作app平台我们都知道,开发一个app很大程度依赖服务端:服务端提供接口数据,然后我们展示;另外,开发一个app,还需要美工协助切图。没了接口,没了美工,app似乎只能做成单机版或工具类app,真的是这样的吗?先来展示下我的个人app,没有服务端,没有美工完成的,换言之,我干了所有人的活:这个app叫“微言”,他对于我意义很重大,最初微言只是我一个练手的项目,刚刚工作,技术有限,微言只是sqlite

    2022年10月21日
    4
  • Git创建远程分支并提交代码到远程分支「建议收藏」

    Git创建远程分支并提交代码到远程分支「建议收藏」1、可以通过gitbranch-r命令查看远端库的分支情况如图所示,远程仓库只有一个master分支2、从已有的分支创建新的分支(如从master分支),创建一个dev分支但此时并没有在远程仓库上创建分支如图所示还是只有一个master分支3、建立本地到远端仓库的链接–这样代码才能提交上去使用命令行gitpush–set-…

    2022年6月30日
    27
  • linux查看网卡信息 命令_linux查看哪个网卡在用

    linux查看网卡信息 命令_linux查看哪个网卡在用1.ifconfig#查看信息此时会得到网卡编号2.ethtool网卡编号就可以得到相关信息了

    2022年10月10日
    2
  • MPC-HC播放器_mp238播放器设置说明

    MPC-HC播放器_mp238播放器设置说明以下内容均来自互联网本文仅作参考,请使用MPC-HC最新版本结合自身硬件条件和实际播放情况进行设置和调整!启动MPC-HC,先设置语言:(最新版本会自动选择对应的系统语言)View-Language-Chinese=>界面变为中文进视图-选项:播放器:建议勾选「保存设置至.ini文件中」格式:建议勾选全部视频类格式,其中QuickTi

    2025年11月14日
    5
  • mysql一主多从 读写分离_MySQL主从复制原理

    mysql一主多从 读写分离_MySQL主从复制原理文章目录前言一、基本概念1.读写分离(1)什么是读写分离(2)为什么要读写分离(3)什么时候要读写分离(4)主从复制与读写分离2.MySQL主从复制(1)mysql支持的复制类型(2)主从复制的工作过程(3)mysql主从复制高延迟的原因(4)mysql主从复制高延迟的解决办法3.常见的MySQL读写分离方式(1)基于程序代码内部实现(2)基于中间代理层实现二、MySQL主从复制架构搭建1.服务器配置2.实验前准备3.mysql主从服务器时间同步4.主服务器

    2022年8月13日
    5
  • 慎用域名url转发功能_url转发域名可以带端口吗

    慎用域名url转发功能_url转发域名可以带端口吗许多域名注册商或虚拟主机商都提供一种免费的URL转发功能,让拥有一个主网站并同时拥有多个域名的用户实现多个域名指向同一个网站或网站子目录,但具体是通过什么机制实现的则大都讳忌莫深,往往只说“通过服务器的特殊技术设置”。同时,大多数服务商提供的URL转发还包括两种,不隐藏路径的URL转发与隐藏路径的URL转发,其中,不隐藏路径的URL转发指在跳转后浏览器地址栏显示真正的目标地址,而隐藏路径的URL转…

    2022年10月18日
    2

发表回复

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

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