1.基本日志
要生成简单的日志记录,可以使用全局日志记录器(global logger)并调用其info方法:
Logger.getGlobal().info("File->Open menu item selected");在默认情况下,这条记录会显示以下内容
May 10,2019 10:12:15 PM LoggingImageViewer fileOpen INFO: File->Open menu item selected但是,如果在适当的地方(如main开始)调用
Logger.getGlobal().setLevel(Level.OFF);将会取消所有日志
2.高级日志
在一个专业的应用程序中,不要将所有的日志都记录到一个全局日志记录器中,而是可以自定义日志记录器。 可以调用getLogger方法创建或获取记录器:
private static final Logger myLogger=Logger.getLogger("com.mycompany.myapp");与包名类似,日志记录器也具有层次结构。事实上,与包名相比,日志记录器的层次性更强。对包来说,一个包的名字与其父包的名字之间没有语义关系,但是日志记录器的父与子之间将共享某些属性。例如,如果对com.mycompany日志记录器设置了日志级别,它的子记录器也会继承这个级别。 通常,有以下七个日志记录器级别:
SEVEREWARNINGINFOCONFIGFINEFINERFINEST在默认情况下,只记录前三个级别。也可以设置其他的级别,例如,
logger.setLevel(Level.FINE);现在,FINE和更高级别的记录都可以记录下来。 还可以使用Level.ALL开启所有级别的记录,或者使用Level.OFF关闭所有级别的记录。 对于所有的级别有下面几种记录方法:
logger.warning(message); logger.fine(message);同时。还可以使用log方法指定级别,例如:
logger.log(Level.FINE,message);默认的日志记录将显示包含日志调用的类名和方法名,如同堆栈所显示的那样。但是如果虚拟机对执行过程进行优化,就得不到准确的调用信息。此时可以调用logp方法获得调用类和方法的确切位置,这个方法的签名为:
void logp(Level l,String className,String methodName, String message)下面有一些用来跟踪执行流的方法:
void entering(String className,String methodName) void entering(String className,String methodName,Object parm) void entering(String calssName,String methodName,Object[] params) void exiting(String className,String methodName) void exiting(String className,String methodName,Object result)例如:
int read(String file,String pattern) { logger.entering("com.mycompany.mylib.Reader","read",new Object[]{file,pattern}); ....... logger.exiting("com.mycompany.mylib.Reader","read",count); return count; }这些调用将生成FINER级别和以字符串ENTRY和RETURN开始的日志记录。 记录日志的常见用途是记录哪些不可预料的异常。可以使用下面两个方法提供日志记录中包含的异常描述内容。
void throwing(String className,String methodName,Throwable t) void log(Level l,String message,Throwable t)典型的用法:
if(..) { IOException exception=new IOException("..."); logger.throwing("com.mycompany.mylib.Reader","read",exception); throw exception; }还有
try { ....... } catch(IOException e) { Logger.getLogger("com.mycompany.myapp").log(Level.WARNING,"Reading image",e); }调用throwing可以记录一条FINER级别的记录和一条以THROW开始的信息。 记录日志的常见用途是记录那些不可预料的异常。使用下面两个方法提供日志记录中包含的异常描述内容。
void throwing(String className, String methodName,Throwable t) void log(Level l,String message,Throwable t)典型用法:
if(...) { IOException exception= new IOException("......"); logger.throwing("com.mycompany.mylib.Reader","read",exception); throw exception; }还有
try { ....... } catch(IOException e) { Logger.getLogger("com.mycompany.myapp").log(Level.WARNING,"Reading imagr", e); }3.修改日志管理器配置 可以通过编辑配置文件来修改日志系统的各种属性。默认情况,配置文件在:
jre/lib/logging.properties要想使用另一个配置文件,就要将java.util.logging.config.file特性设置为配置文件的存储位置,并用下列命令启动应用程序:
java -Djava.util.logging.config.file=configFile MainClass修改默认的日志记录级别,需要编辑配置文件,并修改一下命令行:
.level=INFO可以通过添加以下内容来指定自己的日志记录级别:
com.company.myapp.level=FINE即在日志记录器名后面加后缀.level 日志记录并不将消息发送到控制台上,这是处理器的任务。另外,处理器也有级别。要想在控制台上看到FINE级别的消息,就需要进行下列设置:
java.util.logging.ConsoleHandler.level=FINE4.本地化 我们尽可能希望将日志消息本地化,以便让全球用户都可以阅读它。 本地化的应用程序包含资源包(resource bundle)中的本地特定信息。资源包由各个地区(如美国或德国)的映射集合组成。例如某个资源包可能将字符串“readingFile”映射成英文的“Reading File”或者德文的。 一个程序可以包含多个资源包,一个用于菜单;其他用于日志消息。每个资源包都有一个名字(如com.mycompany.logmessage)要想将映射添加到一个资源包中,需要为每个地区创建一个文件。英文消息映射位于com/mycompany/logmessage_en.properties文件中。可以将这些文件与应用程序的类文件放在一起,以便ResourceBundle类自动地对它们进行定位。这些文件都是纯文本文件,其组成:
readingFile=Achtung! Datei wird eingelesen renamingFile=Datei wird umbenannt在请求日志记录器时,可以指定一个资源包:
Logger logger=Logger.getLogger(loggerName,"com.mycompany.logmessages");然后,为日志消息指定资源包的关键字,而不是实际的日志消息字符串
logger.info("redingFile");通常需要在本地化的消息中增加一些参数,因此,消息应该包括占位符{0},、{1}等。例如,要想在日志消息中包含文件名,就应该用下列方式包括占位符:
Reading file{0}. Achtung! Datet {0} wird eingelesen.然后通过调用下面的一个方法向占位符传递具体的值:
logger.log(Level.INFO,"readingFile",fileName); logger.log(Level.INFO,"readingFile",new Object[] {oldName,newName});处理器 在默认情况下,日志记录器将记录发送到ConsoleHandler中,并由他输出到System.err流中。特别是,日志记录器还会将记录发送到父处理器中,而最终的处理器(命名为"")有一个ConsoleHandler。