- 浏览: 104759 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
newzhq:
经常写博客是个好习惯,向你学习。
javascript深入理解js闭包 -
Action-人生:
newzhq 写道闭包其实跟js的语言结构有关系。为什么会出现 ...
javascript深入理解js闭包 -
Action-人生:
小_情兽_ 写道[color=blue][/color]摸不着 ...
$.extend(),与$.fn.extend() 讲解(一) -
Action-人生:
先生葛 写道文中有错 别误人子弟啊[color=red][ ...
$.extend(),与$.fn.extend() 讲解(一) -
小_情兽_:
[color=blue][/color]摸不着头脑 楼上说的 ...
$.extend(),与$.fn.extend() 讲解(一)
[size=xx-large][size=medium]log4的使用方法:log4是具有日志记录功能,主要通过一个配置文件来对程序进行监测
有两种配置方式:一种程序配置,一种文件配置
有三个主要单元要了解,Logger,appender,layout.
logger是进行记录的主要类,appender是记录的方式,layout是记录的格式
logger七种日志级别:debug,info,warn,error,fatal,all,off
最常用的应该是debug()和info();而warn()、error()、fatal()仅在相应事件发生后才使用
appender主要分三类,终端输出,文件输出,流输出
ConsoleAppender
FileAppender
WriterAppender
layout也分三类:简单格式,html格式,匹配格式
SimpleLayout
HTMLLayout
PatternLayout
输出简写:(用在PatternLayout)
%m 输出代码中指定的消息
%p 输出优先级
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。一般使用了它就不需使用%c了
[按照下面步骤来写吧!就可以得到我们所想要的日志文件哦!]
[按照顺序就可以将日志文件读出来了!]作用实例:
程序配置一般过程:
1.得到特定名称的logger
2.得到其中一个layout
3.根据layout得到appender
4.logger添加appender
5.logger设置级别
6.logger输出有级别的日志信息
程序:
Logger logger = Logger.getLogger(Test.class.getName()) //取得logger
SimpleLayout simpleLayut = new SimpleLayout() //取得layout
FileAppender fa = new FileAppender(simpleLayout,"test.log") //取得ppender
logger.addAppender(fa) //添加appender
logger.set((Level)Level.DEBUG) //设置级别
logger.debug("hihihihih") //记录信息
文件配置过程:
1.得到特定名称的logger
2.加载配置文件 (配置文件做了2-5的工作)
3.logger输出有级别的日志信息
文件配置程序:
1.Logger logger = Logger.getLogger(Test.class.getName()) //取得logger
2.使用下面的配置加载
3.输出信息
文件配置分properties,xml
读取properties:Propnfigure("logTest.properties");
读取xml:nfigure("src/logTest.xml");
告别System.out.print()—J2SDK1.4新增Java日志框架 (一)
作为一名Java 程序员,最熟悉的、使用最多的调用恐怕莫过于System.out.print(“…”)。当你没有调试工具而要跟踪一个变量的值得时候;当你需要显示捕获的Exception、Error的时候;当你想知道程序在运行的时候究竟发生了什么的时候,通常的做法就是调用System.out.print把他们在终端、控制台上打印出来。这种方式对于输出信息的分类、格式化及永久保存带来诸多不便。虽然我们可以把它写入一个文件然后进行分析,但是这要需要编写额外的程序代码,其成本不可忽视!而由此给目标系统本身增加的复杂程度不可避免的使开发、调试陷入一个深深的迷潭。
[要知道一点:如果说能不写的代码最好不要写!]
JDK1.4的推出,使得这一切即将成为历史。让我们向System.out.print()告别吧,使用Java Logging API为自己的程序构建一个完整的日志记录系统!
一、第一个实例先看一个简单的实例:
1 import java.util.logging.*;
2 public class SimpleLoggingTest {
3 public static void main(String args[]) {
4 //程序的其它处理
5 //使用Logger的静态方法获得一个匿名 //Logger
6 Logger logger1 = Logger.getAnonymousLogger();
7 //记录消息
8 logger1.log(Level.INFO,"第一条日志记录");
9 //程序的其它处理
10 }
11 }
实例1
注意:编译、执行该程序需要JDK1.4及以上版本的支持。
运行该程序,可以在控制台看到程序运行结果:
2003-1-14 15:09:40 SimpleLoggingTest main信息: 第一条日志记录首先,程序引用java.util.Logging包(第1行)。接着,在适当的时候获得一个Logger(记录器)类的实例(第6行,获取一个匿名的Logger)。最后,在程序需要记录信息的地方调用Logger类的log方法进行记录(第8行,记录一个INFO级别的消息)。
二、Java Logging API
Java Logging API封装在JDK1.4.0的java.util.Logging 包中。它通过产生便于最终用户、系统管理员、故障维护工程师以及软件开发团队(工程师)进行分析的日志记录为软件的开发调试和维护提供便利的手段。它捕获操作系统平台和执行程序的安全故障、配置错误、执行瓶颈和(或)Bug等数据信息,以纯文本、XML或程序员自定的某种方式将其格式化成日志记录,然后传递给内存、系统输出流、控制台、文件、Sockets等多种系统资源进行缓存和输出。
(一)、该软件包中的关键类。
n Logger: 应用程序进行日志记录调用的主要实体。 Logger对象用于记录特定系统或应用程序的消息。
n LogRecord: 用于在日志框架和单个记录处理程序之间传递记录请求。
n Handler: 日志数据的最终输出处理器。它将LogRecord对象导出到各种目标,包括内存、输出流、控制台、文件和套接字。多种Handler子类可供用于这种用途。
图一
n Level: 定义一组标准的记录级别,可用于控制记录的输出。可以把程序配置为只输出某些级别的记录,而忽略其他级别的输出。
n Filter: 精细过滤、控制记录的内容,比记录级别所提供的控制准确得多。记录API支持通用的过滤器机制,这种机制允许应用程序代码添加任意过滤器以便控制记录的输出。
n Formatter: 为LogRecord对象的格式化提供支持。
图二
n LogManager: Java Logging框架中唯一的、全局的对象,用于维护与Logger记录器及日志服务的一系列共享的数据结构及状态。它负责整个日志框架的初始化、维护一组全局性的Handle对象、维护一个树形结构的Logger的名字空间、诊测日志框架配置文件的改变从而重新读入并应用相关的参数以及负责程序停止运行时整个日志框架的清理工作。
(二)Logger
1、Logger的命名空间
在SimpleLoggingTest.java实例中,我们使用了一个匿名的(没有命名的)Logger对象。在Java Logging 框架中,Logger是可以命名的。Logger的名字空间与java类的名字空间相同的结构相同:使用“。”间隔的字符串。Logger的名字空间体现了Logger的层次结构。例如:命名为“a.b”的Logger是命名为“a.b.c”的“父”(上一级)Logger记录器。Logger的命名可以是任意的字符串,一般情况下,使用包或类的名字为Logger 进行命名。
Logger的名字空间由全局单列类LogManager的实例进行创建、维护。
[貌似在处理数据库的时候的DriverManage来管理数据库驱动一样了!]
匿名Logger不被存储在命名空间中。
2、创建Logger实例
Logger对象可以通过调用工厂方法getLogger或getAnonymousLogger获取。
//获取一个名为“A”的Logger对象
Logger loggerA= Logger.getLogger(“A”);
// 获取一个名为“A.B”的Logger对象,其上级记录器为loggerA.
Logger loggerAB= Logger.getLogger(“A.B”);
//获取一个匿名Logger对象
Logger loggerTmp = Logger.getAnonymousLogger();
对非匿名Logger,getLogger先在命名空间中查找同名的Logger对象,如果有,则返回该Logger对象;如果不存在,则在命名空间中创建注册一个新的Logger对象,并与其上级Logger对象相关联。
匿名Logger对象属于创建它的对象的私有对象,只能由创建它的对象使用,记录一些临时性的日志信息。而命名Logger对象使全局性的,在日志框架的生存期内,除了创建它的对象外还,可由其它对象用于记录日志信息。
匿名的Logger对象由一个全局的的root Logger “” 对象(root Logger的名字为空)。这意味着所有匿名Logger对象将从root Logger “”中继承行为。
匿名Logger对象通常用于java Applet应用中。它去掉了在运行过程中的一班性的安全检查,允许其创建类对象对Logger的控制、状态信息进行修改,如:setLevel设置Logger的日志消息记录级别;addHandle增加Logger的Handle(处理器)对象等。
一个Logger对象可以拥有有零个到多个Handler实例。当没有Handler时,如不禁止日志记录沿名字空间向上传递,那该Logger对象的日志消息记录将有其拥有Handler实例的上级Logger进行处理。当一个Logger对象拥有多个 Handler实例对象时,其记录的日志数据将被所有的Handler逐一进行处理。
(三)、Handler
Handler对象接收传来的日志消息将其输出。Handler可以把日志消息输出到多种目标资源,如:输出到控制台进行显示、写入日志文件、传送到网络上的远程日志服务进行处理、写入系统日志等任何物理资源
告别System.out.print()—J2SDK1.4新增Java日志框架(二)
Handler对象在创建时使用LogManager对象的相关属性的默认值(如Handler的Filter、Formatter、Level等对象属性)进行初始化。
Handler对象可通过调用setLevel(Level.OFF)暂停工作;通过调用setLevel设置适当的记录日志消息级别恢复工作。
Handler是一个抽象类。在J2SDK1.4中,其子类及它们之间的关系见图一。
1、 MemoryHandler Handler的子类,在内存中的一个循环缓冲区用于缓存日志记录请求。通常MemoryHandler只简单的把传入的LogRecords存储到它的内存中。这种缓存的开销非常低廉,它去掉了格式化所产生的系统消耗。当某个触发条件满足时,MemoryHandler将其缓冲的数据push(发布)到目标Handler,由后者执行实际的输出。有三种模式触发MemoryHandler进行push操作:a、传入的LogRecords的级别高于 MemoryHandler预先定义的push级别;b、有其他对象显式的调用其push方法;c、其子类重载了log方法,逐一检索每个传入的 LogRecords,若符合特定的标准则进行push操作。
实例:假设我们需要跟踪一个生产环境中的一个很少出现的Bug.在大多数场合,系统化产生大量的日志记录,而我们仅只关心记录中最近的几条,那么我们只需要使用MemoryHandler对日志记录进行缓存,当且仅当某个事件发生时将最近的几条记录从内存中 dump到制定的文件中。
//MemoryHandlerTest.java
import java.util.logging.*;
import java.io.*;
public class MemoryHandlerTest {
FileHandler fhandler;
Logger logger;
MemoryHandler mhandler;
MemoryHandlerTest() {
try {
//构造名为my.log的日志记录文件
fhandler = new FileHandler("my.log");
int numRec = 5;
//构造一个5个日志记录的MemoryHandler,
//其目标Handler为一个FileHandler
mhandler = new MemoryHandler (fhandler, numRec, Level.OFF) ;
//构造一个记录器
logger = Logger.getLogger("com.mycompany");
//为记录器添加一个MemoryHandler
logger.addHandler(mhandler);
} catch (IOException e) {
}
}
public static void main(String args[]) {
MemoryHandlerTest mt = new MemoryHandlerTest();
int trigger = (int)(Math.random()*100);
for (int i=1;i<100;i++) {
//在MemoryHandler中缓存日志记录
mt.logger.log(Level.INFO,"日志记录"+i);
if (i==trigger) {
//触发事件成立,显式调用MemoryHandler的
//push方法触发目标Handler输出日志记录到
//my.log文件中
//当且仅当这个事件成立的时候就触发这个事件了!
mt.mhandler.push();
break;
}
}
}
}
实例2
2、FileHandler 文件处理器。
StreamHandler流处理器将日志记录以流的形式输出。FileHandler、ConsoleHandler、SocketHandler为StreamHandler的子类。 ConsoleHandler将日志记录输出到控制终端。前面的实例(实例2除外)都将日记记录数据输出到控制台。
FileHandler将日志记录输出到特定的文件,或循环的几个日志文件中。日志文件可以设置容量大小。当日志文件达到限定的容量时将被自动清空,重头开始写入新的日志记录数据。
例:创建一个容量为1Mb的文件处理器
int limit = 1000000; // 1 Mb
FileHandler fh = new FileHandler("my.log", limit, 1);
对于循环的日志文件,每个文件将被指定容量限制。当当前的日志文件的长度达到制定值后该文件被关闭,新的日志文件被创建,旧的文件将在文件名模板后追加序号。如此产生多个顺序编号的日志记录文件。
例:
try { // 创建一个拥有3个日志文件,每个容量为1Mb的文件处理器
String pattern = "my%g.log";
int limit = 1000000; // 1 Mb
int numLogFiles = 3;
FileHandler fh = new FileHandler(pattern, limit, numLogFiles);
…
} catch (IOException e) {
}
(四)、Level
Level对象定义了一组日志消息的级别,用于控制日志消息的输出。一个级别对应一个整型值。日志消息级别按照其整数值的大小排定优先级。在Logger对象中设定一个级别,则大于等于该级别的日志消息将会被传递到某个Handler对象进行输出处理。
J2SDK1.4的Java Logging框架中定义了以下消息级别:
级别名称
int值(Windows 2000环境)
OFF
2147483647
SEVERE
1000
WARNING
900
INFO
800
CONFIG
700
FINE
500
FINER
400
FINEST
300
ALL
-2147483648
表一
Level.OFF具有最高的级别。将Logger的Level级别设置成Level.OFF
让我们看看消息级别是怎样工作的:LoggingLevelTest.java
import java.util.logging.*;
public class LoggingLevelTest {
public static void main(String args[]) {
//使用Logger的静态方法获得一个匿名Logger
Logger logger1 = Logger.getAnonymousLogger();
//设置Logger对象记录的最低日志消息级别
logger1.setLevel(Level.FINER);
//记录消息
logger1.severe("SEVERE级消息");
logger1.warning("WARNING级消息");
nfig("CONFIG级消息");
("INFO级消息");
logger1.fine("FINE级消息");
logger1.finer("FINER级消息");
logger1.finest("FINEST级消息");
}
}
实例3
运行结果:2003-1-15 7:02:03 LoggingLevelTest main服务器: SEVERE级消息2003-1-15 7:02:04 LoggingLevelTest main警告: WARNING级消息2003-1-15 7:02:04 LoggingLevelTest main配置: CONFIG级消息
告别System.out.print()—J2SDK1.4新增Java日志框架(三)
2003-1-15 7:02:04 LoggingLevelTest main信息: INFO级消息可以看出,优先级低于INFO的日志消息不被记录。
Level的构造函数为protected便于程序员开发自己的消息级别类。
import java.util.logging.*;
//自定义消息级别
class myLevel extends Level{
//定义自己的消息级别SYSE
public static final Level SYSE = new myLevel("SYSE", Level.SEVERE.intValue()+10);
public myLevel(String ln,int v) {
super(ln,v);
}
}
public class MyLevelTest {
public static void main(String args[]) {
Logger logger1 = Logger.getAnonymousLogger();
//设置消息级别
logger1.setLevel(myLevel.SYSE);
//记录消息
logger1.log(myLevel.SYSE,"SYSE消息");
logger1.severe("SVERE消息");
}
}
实例4
运行结果:
2003-1-15 15:40:04 MyLevelTest main
SYSE: SYSE消息
只有SYSE消息被记录,SVERE消息不被记录,因为自定义级别SYSE高于SEVERE.
(五)Formatter
Formatter负责对LogRecords进行格式化。每个记录处理器Handler同一个Formatter对象相关联。Formatter对象接收从Handler传来的LogRecord,将其格式化成字符串后返回给Handler进行输出。
Formatter是一个抽象类。在J2SDK1.4中,其子类及它们之间的关系见图二。
自定义扩展Formatter类。实例:MyFormatterTest.java
import java.util.Date;
import java.util.logging.*;
//创建每条日志记录以行的日志格式:
//时间<空格>消息级别<空格>消息ID<空格>日志信息内容<换行>
class MyFormatter extends Formatter {
public String format(LogRecord rec) {
StringBuffer buf = new StringBuffer(1000);
buf.append(new Date().toLocaleString()); //时间
buf.append(' ');
buf.append(rec.getLevel()); //消息级别
buf.append(' ');
buf.append(rec.getMillis()); //作为消息ID
buf.append(' ');
buf.append(formatMessage(rec));//格式化日志记录数据
buf.append('\n'); //换行
return buf.toString();
}
}
public class MyFormatterTest {
public static void main(String args[]){
//创建记录器
Logger log1 = Logger.getLogger("MyLogger");
//创建记录处理器
Handler mh = new ConsoleHandler();
//为记录处理器设置Formatter
mh.setFormatter(new MyFormatter());
//为记录器添加记录处理器
log1.addHandler(mh);
//禁止消息处理将日志消息上传给父级处理器
log1.setUseParentHandlers(false);
//记录消息
log1.severe("消息1");
log1.warning("消息2");
("消息3");
nfig("消息4");
}
}
实例5
程序运行结果:
2003-1-15 16:59:38 SEVERE 1042621178968 消息1 2003-1-15 16:59:40 WARNING 1042621178985 消息2 2003-1-15 16:59:41 INFO 1042621179105 消息3
三、配置文件
J2SDK1.4的Java Logging框架的配置文件(Windows):%J2SDK1.4_HOME%/jre/lig/logging.properties从配置文件可以看到:(一)自定义日志配置文件:java -Djnfig.file=myfile(二)全局Handler在Java VM启动时被加载。
(二)全局Handler默认为java.util.logging.ConsoleHandler. handlers= java.util.logging.ConsoleHandler所以我们的任何日志记录动作都会在控制台进行显示。
(三)缺省的消息记录级别为:INFO。level= INFO在缺省情况下我们在控制台看不见低于INFO级别的日志消息。
(四)缺省的Handler消息格式为java.util.logging.SimpleFormatter
四、日志框架在程序测试中的应用
Logger类提供了两个的方法:Logger.entering() Logger.exiting() .这对我们调试自己的方法调用提供了便利的方式。
例子:记录方法调用的输入参数和输出参数 方法myMethod将一个int 追加在一个对象之后。
运行该程序应将logging.properties的
java.util.logging.ConsoleHandler.level = INFO改为:java.util.logging.ConsoleHandler.level = ALL
import java.util.logging.*;
public class MyClass {
public String myMethod(int p1, Object p2) {
Logger logger = Logger.getLogger("com.mycompany.MyClass");
if (logger.isLoggable(Level.FINER)) {
logger.entering(this.getClass().getName(), "myMethod",
new Object[]{new Integer(p1), p2});
}
String tmp = p2.toString() + p1;
if (logger.isLoggable(Level.FINER)) {
logger.exiting(this.getClass().getName(), "myMethod", tmp);
}
return tmp;
}
public static void main(String args[]) {
MyClass mc = new MyClass();
String rslt = mc.myMethod(123,"Hello");
}
}
后记
J2SDK1.4引入的日志记录框架为构建简易的日志记录系统提供了便利的解决方案。虽然还有期它的一些专用日志包如Log4j,但从简单的打印输出到严密的、可扩展的日志记录框架,J2SDK1.4的日志系统已经足以满足一般的系统开发的要求
Log4j基本使用方法
Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式。日志信息的优先级从高到低有ERROR、WARN、 INFO、DEBUG,分别用来指定这条日志信息的重要程度;日志信息的输出目的地指定了日志将打印到控制台还是文件中;而输出格式则控制了日志信息的显示内容。
3.1.定义配置文件
Log4j支持两种配置文件格式,一种是XML格式的文件,一种是Java特性文件(键=值)。下面我们介绍使用Java特性文件做为配置文件的方法:
1.配置根Logger,其语法为:
log4j.rootLogger = [ level ] , appenderName, appenderName, … 其中,level 是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG.通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。
appenderName就是指定日志信息输出到哪个地方。您可以同时指定多个输出目的地。
2.配置日志信息输出目的地Appender,其语法为
log4j.appender.appenderName = fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1 = value1
…
log4j.appender.appenderName.option = valueN
其中,Log4j提供的appender有以下几种:org.apache.log4j.ConsoleAppender(控制台),org.apache.log4j.FileAppender(文件),org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
3.配置日志信息的格式(布局),其语法为:
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1 = value1
…
log4j.appender.appenderName.layout.option = valueN
其中,Log4j提供的layout有以下几种:org.apache.log4j.HTMLLayout(以HTML表格形式布局),org.apache.log4j.PatternLayout(可以灵活地指定布局模式),org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
3.2.在代码中使用Log4j
下面将讲述在程序代码中怎样使用Log4j.
3.2.1.得到记录器
使用Log4j,第一步就是获取日志记录器,这个记录器将负责控制日志信息。其语法为:
public static Logger getLogger( String name),
通过指定的名字获得记录器,如果必要的话,则为这个名字创建一个新的记录器。Name一般取本类的名字,比如:
static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName () ) ;
3.2.2.读取配置文件
当获得了日志记录器之后,第二步将配置Log4j环境,其语法为:Bnfigure (): 自动快速地使用缺省Log4j环境。
Propnfigure ( String configFilename) :读取使用Java的特性文件编写的配置文件。
nfigure ( String filename ) :读取XML形式的配置文件。
3.2.3.插入记录信息(格式化日志信息)
当上两个必要步骤执行完毕,您就可以轻松地使用不同优先级别的日志记录语句插入到您想记录日志的任何地方,其语法如下:
Logger.debug ( Object message ) ; ( Object message ) ;Logger.warn ( Object message ) ;Logger.error ( Object message ) ;
[原来这样来插入信息啊!!!]
三、Appender组件[要将日志文件信息输出到什么 地方]
Appender组件决定将日志信息输出到什么地方。支持以下目的地:
. 控制台(Console);
. 文件(File);
. GUI组件(GUI component);
. 套接口服务器(Remote socket server);
. NT的事件记录器(NT Event Logger);
. UNIX Syslog守护进程(Remote UNIX Syslog daemon);
一个Logger可同时对应多个Appender,示例:myLogger配置二个Appender: 一个file, 一个是console:
log4j.logger.myAppender=WARN,file,console
log4j.appender.file=org.apache.log4j.RollingFileAppender log4j.appender.file.File=log.txt
nsole=org.apache.log4j.ConsoleAppender
四、Layout组件[以什么形式进行日志输出]
Layout组件决定日志输出格式,有以下几种类型.apache.log4j.HTMLLayout(以HTML表格形式布局).apache.log4j.PatternLayout(可以灵活地指定布局模式).apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串).apache.log4j.TTCCLayout(包含日志产生的时间、线程和类别等信息);
五、Log4J的基本用法
[看看如何来定义配置文件吧!这个东西比较重要哦!]
1. 定义配置文件Log4J支持二种配置文件格式:XML和Java属性文件(采用“键=值”形式)。以下为Java属性文件格式配置文件:
。 配置Logger组件
配置root Logger语法为:log4j.rootLogger=priority],appenderName,appenderName,……
#实例是这样来配置的:#configure root logger log4j.rootLogger=INFO,console #表示级别为INFO,输出格式为控制台
配置自定义Logger组件语法为:log4j.logger.loggerName=priority],appenderName,appenderName,……
#define a logger named myLogger log4j.logger.myLogger=WARN #看看这个格式 与我们的标准格式是不是一样的啊呵呵!
#define a second logger that is a child to myLogger log4j.logger.myLogger.mySonLogger=,file #将日志内容输出到文件并且级别为WARN
其中:priority为日志级别,可选值包括FATAL、ERROR、WARN、INFO、DEBUG、ALL;appenderName指定Appender组件,可指定多个;[可能保存到控制台也可能到文件]
.配置Appender组件
配置日志信息输出目的地Appender, 语法为:
log4j.appender.appenderName=fully.ualified.name.of.appender.class
log4j.appender.appenderName.option1=value1
...
log4j.appender.appenderName.optionN=valueN
Log4J提供的Appender有以下几种:可以取到这几种值哦!
a. org.apache.log4j.ConsoleAppender(控制台);
b. org.apache.log4j.FileAppender(文件);
c. org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件);
d. org.apache.log4j.RollingFileAppender(文件大小到指定尺寸产生一个新的文件);
e. org.apache.log4j.WriteAppender(将日志信息以流格式发送到任意指定地方);
[配置好日志信息输出到哪个目的地方去哦!]
看实例吧:
#define an appender named console, which is set to be a ConsoleAppender
nsole=org.apache.log4j.ConsoleAppender
#配置到控制台的配置文件是这样来写的!
# define an appender named file, which is set to be a RollingFileAppender
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=log.txt
#配置到一个文本文件
.配置Layout组件
配置Layout组件语法为:
[配置要输出的格式哦!]
log4j.appender.appenderName.layout=fully.ualified.name.of.appender.class
log4j.appender.appenderName.layout.option1=value1
...
log4j.appender.appenderName.layout.optionN=valueN
来分析一下这个实例吧:
## LAYOUTS ##
# assian a SimpleLayout to console appender
nsole.layout=org.apache.log4j.SimpleLayout
#表示是要进行简单的输出
# assian a PatternLayout to file appender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%t%p-%m%n
#按照模式进行输出来!
下面为一配置文件示例,文件名为log4j.properties:
## LOGGERS ##
#configure root logger
log4j.rootLogger=INFO,console
#define a logger named myLogger
log4j.logger.myLogger=WARN
#define a second logger that is a child to myLogger
log4j.logger.myLogger.mySonLogger=,file
## APPENDERS ##
#define an appender named console, which is set to be a ConsoleAppender
nsole=org.apache.log4j.ConsoleAppender
# define an appender named file, which is set to be a RollingFileAppender
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=log.txt
## LAYOUTS ##
# assian a SimpleLayout to console appender
nsole.layout=org.apache.log4j.SimpleLayout
# assian a PatternLayout to file appender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%t%p-%m%n
总结:如何来写配置文件?
1.配置Logger组件
语法如下:
#configure root logger
log4j.rootLogger=INFO,console
#表示级别为INFO,输出格式为控制台
#配置自定义Logger组件语法为:log4j.logger.loggerName=priority],appenderName,appenderName,...
#define a logger named myLogger
log4j.logger.myLogger=WARN
2.配置Appender组件
配置日志信息输出目的地Appender。就是说到底是输出到哪种格式下面去!
#define an appender named console, which is set to be a ConsoleAppender
nsole=org.apache.log4j.ConsoleAppender
3.配置Layout组件
配置到底是以什么格式进行输出来的。可以用简单格式或XML或匹配格式等!
## LAYOUTS ##
# assian a SimpleLayout to console appender
nsole.layout=org.apache.log4j.SimpleLayout
#表示格式为简单格式了!
OK了。就是这样一个顺序进行配置文件哦!
[好了,配置文件写好了之后如何来在程序中使用呢?]
2. 程序中使用Log4j
1. 获得日志记录器:
获得rootLogger:Logger rootLogger=Logger.getRootLogger();//根日志记录器获得自定义Logger:
Logger myLogger =Logger.getLogger("log4j.logger.myLogger");
本程序是这样来写的:
//Get an instance of the myLogger
Logger myLogger = Logger.getLogger("myLogger");
//Get an instance of the childLogger
Logger mySonLogger = Logger.getLogger("myLogger.mySonLogger");
2.读取配置文件。配置好环境
a. Bnfigure(): 自动快速地使用默认Log4J环境;
b. nfigure(String configFilename): 读取使用Java属性格式的配置文件并配置Log4J环境;
c. nfigure(String filename): 读取XML形式的配置文件并配置LOG4J环境;
本程序是这样写的:
Propnfigure("test/com/log4j.properties");
使用配置文件来读取哦!
3.输出日志信息;
在程序代码中需要生成日志的地方,调用Logger的各种输出日志方法输出不同级别的日志,例如:
myLogger.debug("Thie is a log message from the " + myLogger.getName());
好了,下面就是我们的代码部分哦!
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class Test {
public static void main(String[] args) {
//Get an instance of the myLogger
Logger myLogger = Logger.getLogger("myLogger");
//Get an instance of the childLogger
Logger mySonLogger = Logger.getLogger("myLogger.mySonLogger");
//Load the proerties using the PropertyConfigurator
Propnfigure("log4j.properties");
//Log Messages using the Parent Logger
myLogger.debug("Thie is a log message from the " + myLogger.getName());
("Thie is a log message from the " + myLogger.getName());
myLogger.warn("Thie is a log message from the " + myLogger.getName());
myLogger.error("Thie is a log message from the " + myLogger.getName());
myLogger.fatal("Thie is a log message from the " + myLogger.getName());
mySonLogger.debug("Thie is a log message from the " + mySonLogger.getName());
("Thie is a log message from the " + mySonLogger.getName());
mySonLogger.warn("Thie is a log message from the " + mySonLogger.getName());
mySonLogger.error("Thie is a log message from the " + mySonLogger.getName());
mySonLogger.fatal("Thie is a log message from the " + mySonLogger.getName());
}
}[/size][/size]
有两种配置方式:一种程序配置,一种文件配置
有三个主要单元要了解,Logger,appender,layout.
logger是进行记录的主要类,appender是记录的方式,layout是记录的格式
logger七种日志级别:debug,info,warn,error,fatal,all,off
最常用的应该是debug()和info();而warn()、error()、fatal()仅在相应事件发生后才使用
appender主要分三类,终端输出,文件输出,流输出
ConsoleAppender
FileAppender
WriterAppender
layout也分三类:简单格式,html格式,匹配格式
SimpleLayout
HTMLLayout
PatternLayout
输出简写:(用在PatternLayout)
%m 输出代码中指定的消息
%p 输出优先级
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。一般使用了它就不需使用%c了
[按照下面步骤来写吧!就可以得到我们所想要的日志文件哦!]
[按照顺序就可以将日志文件读出来了!]作用实例:
程序配置一般过程:
1.得到特定名称的logger
2.得到其中一个layout
3.根据layout得到appender
4.logger添加appender
5.logger设置级别
6.logger输出有级别的日志信息
程序:
Logger logger = Logger.getLogger(Test.class.getName()) //取得logger
SimpleLayout simpleLayut = new SimpleLayout() //取得layout
FileAppender fa = new FileAppender(simpleLayout,"test.log") //取得ppender
logger.addAppender(fa) //添加appender
logger.set((Level)Level.DEBUG) //设置级别
logger.debug("hihihihih") //记录信息
文件配置过程:
1.得到特定名称的logger
2.加载配置文件 (配置文件做了2-5的工作)
3.logger输出有级别的日志信息
文件配置程序:
1.Logger logger = Logger.getLogger(Test.class.getName()) //取得logger
2.使用下面的配置加载
3.输出信息
文件配置分properties,xml
读取properties:Propnfigure("logTest.properties");
读取xml:nfigure("src/logTest.xml");
告别System.out.print()—J2SDK1.4新增Java日志框架 (一)
作为一名Java 程序员,最熟悉的、使用最多的调用恐怕莫过于System.out.print(“…”)。当你没有调试工具而要跟踪一个变量的值得时候;当你需要显示捕获的Exception、Error的时候;当你想知道程序在运行的时候究竟发生了什么的时候,通常的做法就是调用System.out.print把他们在终端、控制台上打印出来。这种方式对于输出信息的分类、格式化及永久保存带来诸多不便。虽然我们可以把它写入一个文件然后进行分析,但是这要需要编写额外的程序代码,其成本不可忽视!而由此给目标系统本身增加的复杂程度不可避免的使开发、调试陷入一个深深的迷潭。
[要知道一点:如果说能不写的代码最好不要写!]
JDK1.4的推出,使得这一切即将成为历史。让我们向System.out.print()告别吧,使用Java Logging API为自己的程序构建一个完整的日志记录系统!
一、第一个实例先看一个简单的实例:
1 import java.util.logging.*;
2 public class SimpleLoggingTest {
3 public static void main(String args[]) {
4 //程序的其它处理
5 //使用Logger的静态方法获得一个匿名 //Logger
6 Logger logger1 = Logger.getAnonymousLogger();
7 //记录消息
8 logger1.log(Level.INFO,"第一条日志记录");
9 //程序的其它处理
10 }
11 }
实例1
注意:编译、执行该程序需要JDK1.4及以上版本的支持。
运行该程序,可以在控制台看到程序运行结果:
2003-1-14 15:09:40 SimpleLoggingTest main信息: 第一条日志记录首先,程序引用java.util.Logging包(第1行)。接着,在适当的时候获得一个Logger(记录器)类的实例(第6行,获取一个匿名的Logger)。最后,在程序需要记录信息的地方调用Logger类的log方法进行记录(第8行,记录一个INFO级别的消息)。
二、Java Logging API
Java Logging API封装在JDK1.4.0的java.util.Logging 包中。它通过产生便于最终用户、系统管理员、故障维护工程师以及软件开发团队(工程师)进行分析的日志记录为软件的开发调试和维护提供便利的手段。它捕获操作系统平台和执行程序的安全故障、配置错误、执行瓶颈和(或)Bug等数据信息,以纯文本、XML或程序员自定的某种方式将其格式化成日志记录,然后传递给内存、系统输出流、控制台、文件、Sockets等多种系统资源进行缓存和输出。
(一)、该软件包中的关键类。
n Logger: 应用程序进行日志记录调用的主要实体。 Logger对象用于记录特定系统或应用程序的消息。
n LogRecord: 用于在日志框架和单个记录处理程序之间传递记录请求。
n Handler: 日志数据的最终输出处理器。它将LogRecord对象导出到各种目标,包括内存、输出流、控制台、文件和套接字。多种Handler子类可供用于这种用途。
图一
n Level: 定义一组标准的记录级别,可用于控制记录的输出。可以把程序配置为只输出某些级别的记录,而忽略其他级别的输出。
n Filter: 精细过滤、控制记录的内容,比记录级别所提供的控制准确得多。记录API支持通用的过滤器机制,这种机制允许应用程序代码添加任意过滤器以便控制记录的输出。
n Formatter: 为LogRecord对象的格式化提供支持。
图二
n LogManager: Java Logging框架中唯一的、全局的对象,用于维护与Logger记录器及日志服务的一系列共享的数据结构及状态。它负责整个日志框架的初始化、维护一组全局性的Handle对象、维护一个树形结构的Logger的名字空间、诊测日志框架配置文件的改变从而重新读入并应用相关的参数以及负责程序停止运行时整个日志框架的清理工作。
(二)Logger
1、Logger的命名空间
在SimpleLoggingTest.java实例中,我们使用了一个匿名的(没有命名的)Logger对象。在Java Logging 框架中,Logger是可以命名的。Logger的名字空间与java类的名字空间相同的结构相同:使用“。”间隔的字符串。Logger的名字空间体现了Logger的层次结构。例如:命名为“a.b”的Logger是命名为“a.b.c”的“父”(上一级)Logger记录器。Logger的命名可以是任意的字符串,一般情况下,使用包或类的名字为Logger 进行命名。
Logger的名字空间由全局单列类LogManager的实例进行创建、维护。
[貌似在处理数据库的时候的DriverManage来管理数据库驱动一样了!]
匿名Logger不被存储在命名空间中。
2、创建Logger实例
Logger对象可以通过调用工厂方法getLogger或getAnonymousLogger获取。
//获取一个名为“A”的Logger对象
Logger loggerA= Logger.getLogger(“A”);
// 获取一个名为“A.B”的Logger对象,其上级记录器为loggerA.
Logger loggerAB= Logger.getLogger(“A.B”);
//获取一个匿名Logger对象
Logger loggerTmp = Logger.getAnonymousLogger();
对非匿名Logger,getLogger先在命名空间中查找同名的Logger对象,如果有,则返回该Logger对象;如果不存在,则在命名空间中创建注册一个新的Logger对象,并与其上级Logger对象相关联。
匿名Logger对象属于创建它的对象的私有对象,只能由创建它的对象使用,记录一些临时性的日志信息。而命名Logger对象使全局性的,在日志框架的生存期内,除了创建它的对象外还,可由其它对象用于记录日志信息。
匿名的Logger对象由一个全局的的root Logger “” 对象(root Logger的名字为空)。这意味着所有匿名Logger对象将从root Logger “”中继承行为。
匿名Logger对象通常用于java Applet应用中。它去掉了在运行过程中的一班性的安全检查,允许其创建类对象对Logger的控制、状态信息进行修改,如:setLevel设置Logger的日志消息记录级别;addHandle增加Logger的Handle(处理器)对象等。
一个Logger对象可以拥有有零个到多个Handler实例。当没有Handler时,如不禁止日志记录沿名字空间向上传递,那该Logger对象的日志消息记录将有其拥有Handler实例的上级Logger进行处理。当一个Logger对象拥有多个 Handler实例对象时,其记录的日志数据将被所有的Handler逐一进行处理。
(三)、Handler
Handler对象接收传来的日志消息将其输出。Handler可以把日志消息输出到多种目标资源,如:输出到控制台进行显示、写入日志文件、传送到网络上的远程日志服务进行处理、写入系统日志等任何物理资源
告别System.out.print()—J2SDK1.4新增Java日志框架(二)
Handler对象在创建时使用LogManager对象的相关属性的默认值(如Handler的Filter、Formatter、Level等对象属性)进行初始化。
Handler对象可通过调用setLevel(Level.OFF)暂停工作;通过调用setLevel设置适当的记录日志消息级别恢复工作。
Handler是一个抽象类。在J2SDK1.4中,其子类及它们之间的关系见图一。
1、 MemoryHandler Handler的子类,在内存中的一个循环缓冲区用于缓存日志记录请求。通常MemoryHandler只简单的把传入的LogRecords存储到它的内存中。这种缓存的开销非常低廉,它去掉了格式化所产生的系统消耗。当某个触发条件满足时,MemoryHandler将其缓冲的数据push(发布)到目标Handler,由后者执行实际的输出。有三种模式触发MemoryHandler进行push操作:a、传入的LogRecords的级别高于 MemoryHandler预先定义的push级别;b、有其他对象显式的调用其push方法;c、其子类重载了log方法,逐一检索每个传入的 LogRecords,若符合特定的标准则进行push操作。
实例:假设我们需要跟踪一个生产环境中的一个很少出现的Bug.在大多数场合,系统化产生大量的日志记录,而我们仅只关心记录中最近的几条,那么我们只需要使用MemoryHandler对日志记录进行缓存,当且仅当某个事件发生时将最近的几条记录从内存中 dump到制定的文件中。
//MemoryHandlerTest.java
import java.util.logging.*;
import java.io.*;
public class MemoryHandlerTest {
FileHandler fhandler;
Logger logger;
MemoryHandler mhandler;
MemoryHandlerTest() {
try {
//构造名为my.log的日志记录文件
fhandler = new FileHandler("my.log");
int numRec = 5;
//构造一个5个日志记录的MemoryHandler,
//其目标Handler为一个FileHandler
mhandler = new MemoryHandler (fhandler, numRec, Level.OFF) ;
//构造一个记录器
logger = Logger.getLogger("com.mycompany");
//为记录器添加一个MemoryHandler
logger.addHandler(mhandler);
} catch (IOException e) {
}
}
public static void main(String args[]) {
MemoryHandlerTest mt = new MemoryHandlerTest();
int trigger = (int)(Math.random()*100);
for (int i=1;i<100;i++) {
//在MemoryHandler中缓存日志记录
mt.logger.log(Level.INFO,"日志记录"+i);
if (i==trigger) {
//触发事件成立,显式调用MemoryHandler的
//push方法触发目标Handler输出日志记录到
//my.log文件中
//当且仅当这个事件成立的时候就触发这个事件了!
mt.mhandler.push();
break;
}
}
}
}
实例2
2、FileHandler 文件处理器。
StreamHandler流处理器将日志记录以流的形式输出。FileHandler、ConsoleHandler、SocketHandler为StreamHandler的子类。 ConsoleHandler将日志记录输出到控制终端。前面的实例(实例2除外)都将日记记录数据输出到控制台。
FileHandler将日志记录输出到特定的文件,或循环的几个日志文件中。日志文件可以设置容量大小。当日志文件达到限定的容量时将被自动清空,重头开始写入新的日志记录数据。
例:创建一个容量为1Mb的文件处理器
int limit = 1000000; // 1 Mb
FileHandler fh = new FileHandler("my.log", limit, 1);
对于循环的日志文件,每个文件将被指定容量限制。当当前的日志文件的长度达到制定值后该文件被关闭,新的日志文件被创建,旧的文件将在文件名模板后追加序号。如此产生多个顺序编号的日志记录文件。
例:
try { // 创建一个拥有3个日志文件,每个容量为1Mb的文件处理器
String pattern = "my%g.log";
int limit = 1000000; // 1 Mb
int numLogFiles = 3;
FileHandler fh = new FileHandler(pattern, limit, numLogFiles);
…
} catch (IOException e) {
}
(四)、Level
Level对象定义了一组日志消息的级别,用于控制日志消息的输出。一个级别对应一个整型值。日志消息级别按照其整数值的大小排定优先级。在Logger对象中设定一个级别,则大于等于该级别的日志消息将会被传递到某个Handler对象进行输出处理。
J2SDK1.4的Java Logging框架中定义了以下消息级别:
级别名称
int值(Windows 2000环境)
OFF
2147483647
SEVERE
1000
WARNING
900
INFO
800
CONFIG
700
FINE
500
FINER
400
FINEST
300
ALL
-2147483648
表一
Level.OFF具有最高的级别。将Logger的Level级别设置成Level.OFF
让我们看看消息级别是怎样工作的:LoggingLevelTest.java
import java.util.logging.*;
public class LoggingLevelTest {
public static void main(String args[]) {
//使用Logger的静态方法获得一个匿名Logger
Logger logger1 = Logger.getAnonymousLogger();
//设置Logger对象记录的最低日志消息级别
logger1.setLevel(Level.FINER);
//记录消息
logger1.severe("SEVERE级消息");
logger1.warning("WARNING级消息");
nfig("CONFIG级消息");
("INFO级消息");
logger1.fine("FINE级消息");
logger1.finer("FINER级消息");
logger1.finest("FINEST级消息");
}
}
实例3
运行结果:2003-1-15 7:02:03 LoggingLevelTest main服务器: SEVERE级消息2003-1-15 7:02:04 LoggingLevelTest main警告: WARNING级消息2003-1-15 7:02:04 LoggingLevelTest main配置: CONFIG级消息
告别System.out.print()—J2SDK1.4新增Java日志框架(三)
2003-1-15 7:02:04 LoggingLevelTest main信息: INFO级消息可以看出,优先级低于INFO的日志消息不被记录。
Level的构造函数为protected便于程序员开发自己的消息级别类。
import java.util.logging.*;
//自定义消息级别
class myLevel extends Level{
//定义自己的消息级别SYSE
public static final Level SYSE = new myLevel("SYSE", Level.SEVERE.intValue()+10);
public myLevel(String ln,int v) {
super(ln,v);
}
}
public class MyLevelTest {
public static void main(String args[]) {
Logger logger1 = Logger.getAnonymousLogger();
//设置消息级别
logger1.setLevel(myLevel.SYSE);
//记录消息
logger1.log(myLevel.SYSE,"SYSE消息");
logger1.severe("SVERE消息");
}
}
实例4
运行结果:
2003-1-15 15:40:04 MyLevelTest main
SYSE: SYSE消息
只有SYSE消息被记录,SVERE消息不被记录,因为自定义级别SYSE高于SEVERE.
(五)Formatter
Formatter负责对LogRecords进行格式化。每个记录处理器Handler同一个Formatter对象相关联。Formatter对象接收从Handler传来的LogRecord,将其格式化成字符串后返回给Handler进行输出。
Formatter是一个抽象类。在J2SDK1.4中,其子类及它们之间的关系见图二。
自定义扩展Formatter类。实例:MyFormatterTest.java
import java.util.Date;
import java.util.logging.*;
//创建每条日志记录以行的日志格式:
//时间<空格>消息级别<空格>消息ID<空格>日志信息内容<换行>
class MyFormatter extends Formatter {
public String format(LogRecord rec) {
StringBuffer buf = new StringBuffer(1000);
buf.append(new Date().toLocaleString()); //时间
buf.append(' ');
buf.append(rec.getLevel()); //消息级别
buf.append(' ');
buf.append(rec.getMillis()); //作为消息ID
buf.append(' ');
buf.append(formatMessage(rec));//格式化日志记录数据
buf.append('\n'); //换行
return buf.toString();
}
}
public class MyFormatterTest {
public static void main(String args[]){
//创建记录器
Logger log1 = Logger.getLogger("MyLogger");
//创建记录处理器
Handler mh = new ConsoleHandler();
//为记录处理器设置Formatter
mh.setFormatter(new MyFormatter());
//为记录器添加记录处理器
log1.addHandler(mh);
//禁止消息处理将日志消息上传给父级处理器
log1.setUseParentHandlers(false);
//记录消息
log1.severe("消息1");
log1.warning("消息2");
("消息3");
nfig("消息4");
}
}
实例5
程序运行结果:
2003-1-15 16:59:38 SEVERE 1042621178968 消息1 2003-1-15 16:59:40 WARNING 1042621178985 消息2 2003-1-15 16:59:41 INFO 1042621179105 消息3
三、配置文件
J2SDK1.4的Java Logging框架的配置文件(Windows):%J2SDK1.4_HOME%/jre/lig/logging.properties从配置文件可以看到:(一)自定义日志配置文件:java -Djnfig.file=myfile(二)全局Handler在Java VM启动时被加载。
(二)全局Handler默认为java.util.logging.ConsoleHandler. handlers= java.util.logging.ConsoleHandler所以我们的任何日志记录动作都会在控制台进行显示。
(三)缺省的消息记录级别为:INFO。level= INFO在缺省情况下我们在控制台看不见低于INFO级别的日志消息。
(四)缺省的Handler消息格式为java.util.logging.SimpleFormatter
四、日志框架在程序测试中的应用
Logger类提供了两个的方法:Logger.entering() Logger.exiting() .这对我们调试自己的方法调用提供了便利的方式。
例子:记录方法调用的输入参数和输出参数 方法myMethod将一个int 追加在一个对象之后。
运行该程序应将logging.properties的
java.util.logging.ConsoleHandler.level = INFO改为:java.util.logging.ConsoleHandler.level = ALL
import java.util.logging.*;
public class MyClass {
public String myMethod(int p1, Object p2) {
Logger logger = Logger.getLogger("com.mycompany.MyClass");
if (logger.isLoggable(Level.FINER)) {
logger.entering(this.getClass().getName(), "myMethod",
new Object[]{new Integer(p1), p2});
}
String tmp = p2.toString() + p1;
if (logger.isLoggable(Level.FINER)) {
logger.exiting(this.getClass().getName(), "myMethod", tmp);
}
return tmp;
}
public static void main(String args[]) {
MyClass mc = new MyClass();
String rslt = mc.myMethod(123,"Hello");
}
}
后记
J2SDK1.4引入的日志记录框架为构建简易的日志记录系统提供了便利的解决方案。虽然还有期它的一些专用日志包如Log4j,但从简单的打印输出到严密的、可扩展的日志记录框架,J2SDK1.4的日志系统已经足以满足一般的系统开发的要求
Log4j基本使用方法
Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式。日志信息的优先级从高到低有ERROR、WARN、 INFO、DEBUG,分别用来指定这条日志信息的重要程度;日志信息的输出目的地指定了日志将打印到控制台还是文件中;而输出格式则控制了日志信息的显示内容。
3.1.定义配置文件
Log4j支持两种配置文件格式,一种是XML格式的文件,一种是Java特性文件(键=值)。下面我们介绍使用Java特性文件做为配置文件的方法:
1.配置根Logger,其语法为:
log4j.rootLogger = [ level ] , appenderName, appenderName, … 其中,level 是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG.通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。
appenderName就是指定日志信息输出到哪个地方。您可以同时指定多个输出目的地。
2.配置日志信息输出目的地Appender,其语法为
log4j.appender.appenderName = fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1 = value1
…
log4j.appender.appenderName.option = valueN
其中,Log4j提供的appender有以下几种:org.apache.log4j.ConsoleAppender(控制台),org.apache.log4j.FileAppender(文件),org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
3.配置日志信息的格式(布局),其语法为:
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1 = value1
…
log4j.appender.appenderName.layout.option = valueN
其中,Log4j提供的layout有以下几种:org.apache.log4j.HTMLLayout(以HTML表格形式布局),org.apache.log4j.PatternLayout(可以灵活地指定布局模式),org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
3.2.在代码中使用Log4j
下面将讲述在程序代码中怎样使用Log4j.
3.2.1.得到记录器
使用Log4j,第一步就是获取日志记录器,这个记录器将负责控制日志信息。其语法为:
public static Logger getLogger( String name),
通过指定的名字获得记录器,如果必要的话,则为这个名字创建一个新的记录器。Name一般取本类的名字,比如:
static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName () ) ;
3.2.2.读取配置文件
当获得了日志记录器之后,第二步将配置Log4j环境,其语法为:Bnfigure (): 自动快速地使用缺省Log4j环境。
Propnfigure ( String configFilename) :读取使用Java的特性文件编写的配置文件。
nfigure ( String filename ) :读取XML形式的配置文件。
3.2.3.插入记录信息(格式化日志信息)
当上两个必要步骤执行完毕,您就可以轻松地使用不同优先级别的日志记录语句插入到您想记录日志的任何地方,其语法如下:
Logger.debug ( Object message ) ; ( Object message ) ;Logger.warn ( Object message ) ;Logger.error ( Object message ) ;
[原来这样来插入信息啊!!!]
三、Appender组件[要将日志文件信息输出到什么 地方]
Appender组件决定将日志信息输出到什么地方。支持以下目的地:
. 控制台(Console);
. 文件(File);
. GUI组件(GUI component);
. 套接口服务器(Remote socket server);
. NT的事件记录器(NT Event Logger);
. UNIX Syslog守护进程(Remote UNIX Syslog daemon);
一个Logger可同时对应多个Appender,示例:myLogger配置二个Appender: 一个file, 一个是console:
log4j.logger.myAppender=WARN,file,console
log4j.appender.file=org.apache.log4j.RollingFileAppender log4j.appender.file.File=log.txt
nsole=org.apache.log4j.ConsoleAppender
四、Layout组件[以什么形式进行日志输出]
Layout组件决定日志输出格式,有以下几种类型.apache.log4j.HTMLLayout(以HTML表格形式布局).apache.log4j.PatternLayout(可以灵活地指定布局模式).apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串).apache.log4j.TTCCLayout(包含日志产生的时间、线程和类别等信息);
五、Log4J的基本用法
[看看如何来定义配置文件吧!这个东西比较重要哦!]
1. 定义配置文件Log4J支持二种配置文件格式:XML和Java属性文件(采用“键=值”形式)。以下为Java属性文件格式配置文件:
。 配置Logger组件
配置root Logger语法为:log4j.rootLogger=priority],appenderName,appenderName,……
#实例是这样来配置的:#configure root logger log4j.rootLogger=INFO,console #表示级别为INFO,输出格式为控制台
配置自定义Logger组件语法为:log4j.logger.loggerName=priority],appenderName,appenderName,……
#define a logger named myLogger log4j.logger.myLogger=WARN #看看这个格式 与我们的标准格式是不是一样的啊呵呵!
#define a second logger that is a child to myLogger log4j.logger.myLogger.mySonLogger=,file #将日志内容输出到文件并且级别为WARN
其中:priority为日志级别,可选值包括FATAL、ERROR、WARN、INFO、DEBUG、ALL;appenderName指定Appender组件,可指定多个;[可能保存到控制台也可能到文件]
.配置Appender组件
配置日志信息输出目的地Appender, 语法为:
log4j.appender.appenderName=fully.ualified.name.of.appender.class
log4j.appender.appenderName.option1=value1
...
log4j.appender.appenderName.optionN=valueN
Log4J提供的Appender有以下几种:可以取到这几种值哦!
a. org.apache.log4j.ConsoleAppender(控制台);
b. org.apache.log4j.FileAppender(文件);
c. org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件);
d. org.apache.log4j.RollingFileAppender(文件大小到指定尺寸产生一个新的文件);
e. org.apache.log4j.WriteAppender(将日志信息以流格式发送到任意指定地方);
[配置好日志信息输出到哪个目的地方去哦!]
看实例吧:
#define an appender named console, which is set to be a ConsoleAppender
nsole=org.apache.log4j.ConsoleAppender
#配置到控制台的配置文件是这样来写的!
# define an appender named file, which is set to be a RollingFileAppender
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=log.txt
#配置到一个文本文件
.配置Layout组件
配置Layout组件语法为:
[配置要输出的格式哦!]
log4j.appender.appenderName.layout=fully.ualified.name.of.appender.class
log4j.appender.appenderName.layout.option1=value1
...
log4j.appender.appenderName.layout.optionN=valueN
来分析一下这个实例吧:
## LAYOUTS ##
# assian a SimpleLayout to console appender
nsole.layout=org.apache.log4j.SimpleLayout
#表示是要进行简单的输出
# assian a PatternLayout to file appender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%t%p-%m%n
#按照模式进行输出来!
下面为一配置文件示例,文件名为log4j.properties:
## LOGGERS ##
#configure root logger
log4j.rootLogger=INFO,console
#define a logger named myLogger
log4j.logger.myLogger=WARN
#define a second logger that is a child to myLogger
log4j.logger.myLogger.mySonLogger=,file
## APPENDERS ##
#define an appender named console, which is set to be a ConsoleAppender
nsole=org.apache.log4j.ConsoleAppender
# define an appender named file, which is set to be a RollingFileAppender
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=log.txt
## LAYOUTS ##
# assian a SimpleLayout to console appender
nsole.layout=org.apache.log4j.SimpleLayout
# assian a PatternLayout to file appender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%t%p-%m%n
总结:如何来写配置文件?
1.配置Logger组件
语法如下:
#configure root logger
log4j.rootLogger=INFO,console
#表示级别为INFO,输出格式为控制台
#配置自定义Logger组件语法为:log4j.logger.loggerName=priority],appenderName,appenderName,...
#define a logger named myLogger
log4j.logger.myLogger=WARN
2.配置Appender组件
配置日志信息输出目的地Appender。就是说到底是输出到哪种格式下面去!
#define an appender named console, which is set to be a ConsoleAppender
nsole=org.apache.log4j.ConsoleAppender
3.配置Layout组件
配置到底是以什么格式进行输出来的。可以用简单格式或XML或匹配格式等!
## LAYOUTS ##
# assian a SimpleLayout to console appender
nsole.layout=org.apache.log4j.SimpleLayout
#表示格式为简单格式了!
OK了。就是这样一个顺序进行配置文件哦!
[好了,配置文件写好了之后如何来在程序中使用呢?]
2. 程序中使用Log4j
1. 获得日志记录器:
获得rootLogger:Logger rootLogger=Logger.getRootLogger();//根日志记录器获得自定义Logger:
Logger myLogger =Logger.getLogger("log4j.logger.myLogger");
本程序是这样来写的:
//Get an instance of the myLogger
Logger myLogger = Logger.getLogger("myLogger");
//Get an instance of the childLogger
Logger mySonLogger = Logger.getLogger("myLogger.mySonLogger");
2.读取配置文件。配置好环境
a. Bnfigure(): 自动快速地使用默认Log4J环境;
b. nfigure(String configFilename): 读取使用Java属性格式的配置文件并配置Log4J环境;
c. nfigure(String filename): 读取XML形式的配置文件并配置LOG4J环境;
本程序是这样写的:
Propnfigure("test/com/log4j.properties");
使用配置文件来读取哦!
3.输出日志信息;
在程序代码中需要生成日志的地方,调用Logger的各种输出日志方法输出不同级别的日志,例如:
myLogger.debug("Thie is a log message from the " + myLogger.getName());
好了,下面就是我们的代码部分哦!
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class Test {
public static void main(String[] args) {
//Get an instance of the myLogger
Logger myLogger = Logger.getLogger("myLogger");
//Get an instance of the childLogger
Logger mySonLogger = Logger.getLogger("myLogger.mySonLogger");
//Load the proerties using the PropertyConfigurator
Propnfigure("log4j.properties");
//Log Messages using the Parent Logger
myLogger.debug("Thie is a log message from the " + myLogger.getName());
("Thie is a log message from the " + myLogger.getName());
myLogger.warn("Thie is a log message from the " + myLogger.getName());
myLogger.error("Thie is a log message from the " + myLogger.getName());
myLogger.fatal("Thie is a log message from the " + myLogger.getName());
mySonLogger.debug("Thie is a log message from the " + mySonLogger.getName());
("Thie is a log message from the " + mySonLogger.getName());
mySonLogger.warn("Thie is a log message from the " + mySonLogger.getName());
mySonLogger.error("Thie is a log message from the " + mySonLogger.getName());
mySonLogger.fatal("Thie is a log message from the " + mySonLogger.getName());
}
}[/size][/size]
发表评论
-
JAVA方法可变参数
2019-04-23 16:53 428参考来自于别人, ---定义可变参数方法--- publ ... -
java编译和类加载详述
2019-04-19 10:54 627来源于https://blog.csdn.net/ ... -
JDK动态代理
2019-04-18 14:48 0JDK动态代理几个基本常识点 ClassLoader, Cla ... -
链接地址
2018-05-28 16:26 0http://www.cnblogs.com/linjiqin ... -
static final long serialversionuid解释
2017-03-06 09:47 664serialVersionUID 用来表明类的不同版本间的兼容 ... -
Web项目中 .classpath、.mymetadata、.project文件的作用
2017-02-28 14:00 632http://blog.csdn.net/u010466666 ... -
用cxf生成webservice的java客户端代码
2017-02-16 10:20 684http://www.cnblogs.com/hf8051/p ... -
java项目打成jar包
2017-02-15 19:47 1033来自于http://www.cnblogs.com/tiang ... -
ResultSet相关ResultSetMetaData详细
2015-04-17 13:34 594http://www.cnblogs.com/chinafin ... -
Log4j的日志的使用
2015-02-26 09:28 452http://blog.csdn.net/wuhailin20 ... -
X-Forwarded-For 和 X-Real-IP 的区别?
2015-01-19 11:24 1279X-Forwarded-For 和 X-Rea ... -
微信公众平台开发
2015-01-04 15:03 543http://blog.csdn.net/lyq8479/ar ... -
关于多线程的几个问题(面试小问题,Java篇)
2015-01-04 10:08 542面试官想考考我多线程 ... -
精)JAVA线程池原理以及几种线程池类型介绍
2014-12-24 22:24 527http://blog.csdn.net/it_man/art ... -
JUnit Assert方法总结
2014-09-24 10:36 685JUnit Assert方法总结 junit中的assert方 ... -
java 参数后面的三个点表示什么意思
2014-08-08 10:24 1073java 参数后面的三个点表示什么意思 2013-06- ... -
log4j基本的properties配置
2014-05-19 14:37 839log4j基本的properties配置 #to conlos ... -
别人的百度网盘
2013-11-19 15:53 806http://pan.baidu.com/share/home ... -
struts2文件下载
2013-10-20 15:55 1112Struts2文件下载 目录: struts.xm ... -
正则表达式
2013-10-09 13:41 600连接百度文库http://wenku.baidu.com/vi ...
相关推荐
可以设置全局或特定日志器的级别,控制不同级别的日志输出。 #### 格式化 `spdlog`允许自定义日志格式。例如,你可以设置日志包含时间戳、线程ID、日志级别等信息: ```cpp auto logger = spdlog::daily_file_...
如果系统原本使用JCL,但希望转向SLF4J,可以通过引入jcl-over-slf4j、log4j-over-slf4j和jul-over-slf4j这样的桥接器jar包,将原有的日志调用重定向到SLF4J,从而实现日志输出的统一。 log4j2作为log4j的升级版,...
### Python日志输出——Logging模块浅析与使用 #### 概述 日志记录是软件开发中的重要组成部分,它能够帮助开发者追踪程序运行时的状态、调试错误以及进行性能分析等。在Python中,`logging`模块是进行日志管理的...
### MyEclipse下Tomcat日志输出和内存溢出解决方法 #### 一、问题背景与概述 在使用MyEclipse进行开发时,经常会遇到Tomcat服务器启动后,在部署SSH(Struts+Spring+Hibernate)项目多次后出现崩溃的情况。这通常...
3. **指定日志输出通道**: ``` [Sysname] info-center loghost 1.2.0.1 channel loghost ``` 这里`1.2.0.1`是日志服务器的IP地址。 4. **关闭所有模块日志状态**: ``` [Sysname] info-center source ...
- **Log接口**:提供了六个级别的日志输出选项——FATAL、ERROR、WARN、INFO、DEBUG 和 TRACE。这些级别按照严重性递减的顺序排列。 - **LogFactory接口**:用于获取具体的日志实现对象。通过这种方式,可以在不修改...
Android系统提供了内置的日志系统,包括`Log.d()`, `Log.e()`, `Log.w()`, `Log.i()`等方法,用于输出不同级别的日志信息。这些信息可以在设备的adb shell中通过`logcat`命令查看。然而,在实际应用中,当遇到异常...
配置包括日志级别(DEBUG、INFO、WARN、ERROR等)、日志输出目的地(控制台、文件、网络等)、日志格式(包括时间戳、线程名、级别、类名等信息)以及自定义布局和过滤器。 7. **日志性能优化** 日志框架对性能的...
3. **查看日志输出**:运行程序后,可以在控制台或指定的日志文件中查看输出的日志信息。 #### 五、总结 Log4j是一个非常强大的日志记录工具,通过其灵活的配置和丰富的功能,可以满足不同场景下的日志需求。本文...
这样一来,日志输出将通过`cronolog`工具按日期进行自动分割。 3. **重启Tomcat**: - 完成上述步骤后,重启Tomcat以应用新的配置。 #### 效果验证与后续管理 1. **效果验证**: - 重启Tomcat后,日志文件应被...
二、Linux日志文件概述 Linux系统的日志通常存储在/var/log目录下,不同类型的日志文件记录了系统、应用和服务的不同信息。例如,`/var/log/messages`记录了系统级别的消息,`/var/log/auth.log`记录了认证活动,而...
### Log4j中配置日志文件相对路径方法详解 #### 概述 在软件开发过程中,日志记录是一项重要的功能,它有助于开发者调试...开发者可以根据自己的需求选择最适合的配置方式,确保日志文件能够在不同的环境中正确输出。
- **Logger**: 日志记录器,负责实际的日志输出,通过不同的级别(DEBUG, INFO, WARN, ERROR, FATAL)来控制日志信息的输出。 - **Appender**: 输出目的地,可以是控制台、文件、网络、数据库等,决定日志信息被...
#### 一、概述与目的 syslog-ng是一款功能强大的开源日志管理系统,它能够高效地收集、过滤并转发来自不同来源的日志数据。通过使用syslog-ng,我们可以实现对日志数据的有效管理和监控,从而帮助我们更好地了解...
本篇概述将详细介绍ThinkPHP的调试模式和日志记录功能的用法和配置。 首先,我们来了解调试模式。ThinkPHP的调试模式是通过设置APP_DEBUG变量来开启的。默认情况下,调试模式是关闭的。当开发者需要进行调试时,...
- **Appender**:日志输出的目标。可以配置输出到控制台、文件等。 - **Layout**:日志输出的格式。 - **Additivity**:是否将日志同时输出到父级日志器,默认为 true。如果设为 false,则只输出到指定的日志器。 #...
Log4j的核心设计理念在于提供高度可配置的日志系统,使得开发人员可以根据实际需求调整日志的级别、输出目的地以及日志格式等。 #### 二、Log4j的基本组件 Log4j主要由以下几个核心组件组成: 1. **Logger** - ...
PyLogging库是对这个模块的一个小封装,旨在简化日志的配置和输出,使得开发者能更方便地管理和格式化日志信息。在`ansrivas-pylogging-f38bc72`这个压缩包中,我们很可能是找到了一个由用户ansrivas编写的对`...
日志类概述 CLog是一个轻量级的日志类,提供了基本的日志记录功能,支持格式化输出变量。该类主要由两个文件组成,一个是头文件CLog.h,另一个是实现文件CLog.cpp。 CLog.h头文件 CLog.h头文件中定义了CLog类的...