1log4j 概述

log4j 环境包括三个主要组件:
logger(日志记录器):控制要启用或禁用哪些日志记录语句。可以对日志记录器指定如下级别: ALL 、 DEBUG 、 INFO 、 WARN 、 ERROR , FATAL 。
layout(布局):根据用户的愿望格式化日志记录请求。
appender:向目的地发送格式化的输出。
2.理解 appender
log4j 框架允许向任何日志记录器附加多个 appender。可以在任何时候对某个日子记录器添加(或删除)appender。附随 log4j 分发的 appender 有多个,包括:
ConsoleAppender;FileAppender;SMTPAppender ;JDBCAppender;JMSAppender;NTEventLogAppender;SyslogAppender。
也可以创建自己的自定义 appender。
3.本工程设计的目标
通过自建appender类,来实现:
[1]在控制台输出日志;
[2]在log文件输出日志;
[3]在应用程序中建立日志模块(在UI层表现为建立一个日志面板),输出日志;
[4]对于不同包路径下的日志独立输出(在UI层表现为分不同的面板输出)。
4.预备知识
你可以在下面2篇文章中找到Log4j的相关基础介绍。
Log4j配置说明
Log4j使用实例
5.项目文件分布与效果
文件分布如图一所示。我们对于com.log.one包下的所有java文件中的日志信息输出到log one模块(图二);对于com.log.two包下的所有java文件中的日志信息输出到log two模块(图四)。本文只象征性的建立了两个测试文件,分别放在两个包下。
com.log.one.LogTestOne.java
public class LogTestOne {
private final static Logger log = Logger.getLogger(LogTestOne.class);
public void doLog(){
log.debug("TestOne debug");
log.info("TestOne info");
log.warn("TestOne warn");
log.error("TestOne error");
log.fatal("TestOne fatal");
}
}
 
com.log.two.LogTestTwo.java
public class LogTestTwo {
private final static Logger log = Logger.getLogger(LogTestTwo.class);
public void doLog() {
log.debug("TestTwo debug");
log.info("TestTwo info");
log.warn("TestTwo warn");
log.error("TestTwo error");
log.fatal("TestTwo fatal");
}
}
 
图一
 
对于应用程序中的日志模块,提供一些UI层的基本操作,包括清空(图二,图四);变灰(图三);复制到粘贴板。
The Main Text象征性的表示主应用程序的所有操作。
图二
 
图三
 
图四
 
同时在控制台输出所有日志信息。(图五)
图五
 
    同时在文本文件中输出所有日志信息。(图六)
图六
6log4j.xml
本项目使用如下日志配置文件,将其放在项目的classpath下。
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false"> 
<!-- =================== -->
<!-- Appenders           -->
<!-- =================== -->
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler"/>
<param name="Target" value="System.out"/>
<param name="Threshold" value="DEBUG"/>
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%-5p %l%m%n"/>
</layout>
</appender>
<appender name="FILE" class="org.apache.log4j.RollingFileAppender">
<errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler"/>
<param name="File" value="logui.log"/>
<param name="Threshold" value="INFO"/>
<param name="Append" value="false"/>
<param name="MaxFileSize" value="5000KB"/>
<param name="MaxBackupIndex" value="50"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c{1}] %m%n"/>
</layout>    
</appender>
<appender name="ONE" class="com.log.utils.LogOneAppender">
<errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler"/>
</appender>
<appender name="TWO" class="com.log.utils.LogTwoAppender">
<errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler"/>
</appender>
<!-- =============== -->
<!-- Loggers         -->
<!-- =============== -->
<logger name="com.log.one">
<level value="DEBUG" />
<appender-ref ref="ONE"/>
<appender-ref ref="CONSOLE"/>
</logger>
<logger name="com.log.two">
<level value="DEBUG" />
<appender-ref ref="TWO"/>
<appender-ref ref="CONSOLE"/>
</logger>
<root>
<priority value="INFO" />
<appender-ref ref="FILE"/>
</root>
</log4j:configuration>
这里除常规的CONSOLE和FILE appender,增加两个appender,ONE和TWO,分别通过自建类LogOneAppender和LogTwoAppender定义。
public class LogOneAppender extends AppenderSkeleton{
public LogOneAppender() {}
protected void append(LoggingEvent event) {
LogUI.log(event);
}
public void close() {}
public boolean requiresLayout() {
return false;
}
}
 
public class LogTwoAppender extends AppenderSkeleton{
public LogTwoAppender() {}
protected void append(LoggingEvent event) {
LogUI.log(event);
}
public void close() {}
public boolean requiresLayout() {
return false;
}
}
在logger中通过logger name,com.log.one和com.log.two指定到上述的appender。
7.主界面设计LogUI.java
主面板为frame,其中嵌入LogPanel。log类的实体是一个Log4Jmonitor类的实例,通过它的addLogArea方法可以添加日志模块,其中的第二个参数对应log4j配置文件中的logger name。这里还提供一个Cache功能,即如果在主类(LogUI)或日志类(Log4Jmonitor)还没有实例化之前,已经有日志信息,则进行缓存。
public class LogUI {
private static LogUI instance;
private static JFrame frame;
private Log4JMonitor logMonitor;
private static List<Object> logCache = new ArrayList<Object>();
public LogUI() {
instance = this;
}
///UI
private void buildUI() {
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.getContentPane().add(buildContentPanel(), BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setSize(100, 75);
}
private Component buildContentPanel() {
JSplitPane contentSplit = new JSplitPane();
contentSplit.setTopComponent(new JTextArea("The Main Text"));
contentSplit.setBottomComponent(buildLogPanel());
contentSplit.setDividerLocation(550);
contentSplit.setResizeWeight(1);
return contentSplit;
}
private Component buildLogPanel() {
logMonitor = new Log4JMonitor();
logMonitor.addLogArea("log one", "com.log.one", true).setLevel(
Level.DEBUG);
logMonitor.addLogArea("log two", "com.log.two", true).setLevel(
Level.DEBUG);
for (Object message : logCache) {
logMonitor.logEvent(message);
}
return logMonitor;
}
public void show() {
buildUI();
frame.setVisible(true);
}
Log
public static synchronized void log(final Object msg) {
if (instance == null || instance.logMonitor == null) {
logCache.add(msg);
return;
}
if (SwingUtilities.isEventDispatchThread()) {
instance.logMonitor.logEvent(msg);
} else {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
instance.logMonitor.logEvent(msg);
}
});
}
}
//Test Cases
public void doTests(){
LogTestOne one=new LogTestOne();
one.doLog();
LogTestTwo two=new LogTestTwo();
two.doLog();
}
public static void main(String[] args) throws Exception {
frame = new JFrame("LogUI ");
LogUI logUi = new LogUI();
logUi.show();
logUi.doTests();
}
}
8log类的实体Log4Jmonitor
通过此类来建立日志模块。其中用到的JlogList.java(见附件)提供对日志模块的所有基本功能。addLogArea方法增加日志模块。logEvent方法对输出的日志事件类型做出判断,对该日志所属的日志模块(本实例为com.log.one和com.log.two)做出判断。
public class Log4JMonitor extends JTabbedPane {
private JLogList defaultLogArea;
public Log4JMonitor() {
super(JTabbedPane.BOTTOM, JTabbedPane.SCROLL_TAB_LAYOUT);
}
public JLogList addLogArea(String title, String loggerName,
boolean isDefault) {
JLogList logArea = new JLogList(title);
logArea.addLogger(loggerName, !isDefault);
addTab(title, logArea);
if (isDefault)
defaultLogArea = logArea;
return logArea;
}
public void logEvent(Object msg) {
if (msg instanceof LoggingEvent) {
LoggingEvent event = (LoggingEvent) msg;
String loggerName = event.getLoggerName();
for (int c = 0; c < getTabCount(); c++) {
Component tabComponent = getComponentAt(c);
if (tabComponent instanceof JLogList) {
JLogList logArea = (JLogList) tabComponent;
if (logArea.monitors(loggerName)) {
logArea.addLine(msg);
}
}
}
} else if (defaultLogArea != null) {
defaultLogArea.addLine(msg);
}
}
public boolean hasLogArea(String loggerName) {
for (int c = 0; c < getTabCount(); c++) {
Component tabComponent = getComponentAt(c);
if (tabComponent instanceof JLogList) {
JLogList logArea = (JLogList) tabComponent;
if (logArea.monitors(loggerName)) {
return true;
}
}
}
return false;
}
}
 

转载于:https://www.cnblogs.com/qingyuuu/p/4791112.html

如何自建appender扩展Log4j框架相关推荐

  1. 学习如何用自己的 appender 来扩展 log4j 框架

    2003 年 9 月 29 日 日志记录不仅是开发和测试周期中的一个重要元素――提供关键调试信息,而且对于系统已部署到生产环境之后调试错误也是很有用的――提供修复错误所需的准确上下文信息.在本文中,O ...

  2. 扩展log4j系列[二]为DailyRollingFileAppender加上maxBackupIndex属性

    在log4j的大多数appender中,都有maxBackupIndex属性,但是这个DailyRollingFileAppender没有,也就是说它会每天滚一个文件,却没有办法控制文件总个数.这绝对 ...

  3. 在多变环境中长期定位和建图的通用框架

    点云PCL免费知识星球,点云论文速读. 文章:A General Framework for Lifelong Localization and Mapping in Changing Environ ...

  4. Log4j框架配置文件

    Log4j框架配置文件 1 Log4j的配置文件分类 Log4j支持两种配置文件格式:一中是以log4j.properties ,另一种是 log4j.xml 2 Log4j的配置文件例子 ##自定义 ...

  5. 扩展 junit 框架_JUnit 5扩展模型的生命周期

    扩展 junit 框架 JUnit5最终版本即将来临 (当前是M4),我已经开始尝试如何编写扩展了. 在JUnit5中 ,您没有使用Runners , Rules , ClassRules等,而是只有 ...

  6. 扩展 junit 框架_JUnit 5 –扩展模型

    扩展 junit 框架 我们已经对Java最普遍的测试框架的下一个版本了解很多. 现在,让我们看一下JUnit 5扩展模型,该模型将允许库和框架将自己的实现添加到JUnit中. 总览 建立 基本 建筑 ...

  7. 论文翻译:DeepFaceLab:一个简单,灵活的可扩展换脸框架

    DeepFaceLab:一个简单,灵活的可扩展换脸框架 时间有限,翻译仓促,为个人学习所用,仅供参考. DeepFaceLab: A simple, flexible and extensible f ...

  8. 【tornado建站】tornado框架搭建

    [tornado建站]tornado框架搭建 首先需要先思考你的网站需要建成什么样子. 比如我打算开一个博客,然后提供一些绘图的小工具,还有放一些个人介绍等,就暂时定义了以下几个类: import t ...

  9. php扩展的框架,新一代轻量级PHP扩展框架 Asf

    一.Asf 是什么? 全称 API Services Framework, 用C语言编写的轻量级PHP扩展框架, 专注于 API 开发. 二.解决了什么问题? 2.1 把复杂的逻辑简单化(降低错误率, ...

最新文章

  1. Linux下安装二进制版mysql-8.0.15
  2. Pwnium CTF2014 – MatterOfCombination writeup
  3. 本地YUM源配置并设置成本地同步网络源,摆脱依赖包
  4. PyQt5初级——2
  5. 【分析】浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang)
  6. ios不行安卓可以 微信签名_王者荣耀安卓、iOS互通来了!现在可以互看好友资料...
  7. 任正非解读华为“狼文化”;丰巢高管:不会放弃超时收费;Debian 10.4 发布 | 极客头条...
  8. 2.抽象工厂(Abstract Factory)
  9. ftp等远程登录工具的星号密码查看方法
  10. 看我七十二变-TC还能改包名哦
  11. python调用手机蓝牙_python bluetooth蓝牙信息获取蓝牙设备类型的方法
  12. linux配置静态ip命令,Linux设置静态IP地址
  13. 小米tts语音引擎下载_在手机和 AIoT 双战场打拼的小爱同学,会把语音助手带向何方?...
  14. 2018年大数据的发展趋势,小白学前必备
  15. html几个重要标签用法(div,p,span,ul,li,dl,dt,dd,a,img,h,strong,em)
  16. 自建ipa下载服务器的方法(最简单,使用在线工具)
  17. 华为服务器2488H V6的ibmc接口配置
  18. 埃尼阿克计算机怎么运行的
  19. 我的世界服务器中怎么无限血,我的世界如何用指令调无限血 | 手游网游页游攻略大全...
  20. 一文详解云原生DevOps(认识、熟悉、上手,DevOps,Docker,Jenkins,SonarQube,Harbor)

热门文章

  1. 肌电信号的包络matlab程序_基于matlab的肌电信号处理程序
  2. hexo html代码高亮,使用 prismjs 自定义 Hexo 代码高亮
  3. python列表使用判断_浅谈Python数据类型判断及列表脚本操作
  4. java fieldposition_Java FieldPosition toString()用法及代码示例
  5. drawpolygon收尾不连接_门窗施工全流程,80%的设计师都不了解!
  6. 微信小程序引用php函数,微信小程序Page中data数据操作和函数调用详细介绍
  7. c语言清空文件内容_C 语言清空输入缓冲区的几个手段
  8. 电信充q币短信怎么发_移动、联通、电信话费快来领!微信小额提现免手续费方法!刚需羊毛!...
  9. CentOS(rsync+crond实现定时备份)
  10. 从java中安装webolgc_Javaweb| 文件下载