精华内容
下载资源
问答
  • java 日志查看_Java日志

    2021-02-12 17:02:39
    日志对于一个系统来说非常重要,查找异常信息、分析系统运行情况等都需要用到...JDK的java.util.logging包第三方日志工具(commons-logging/slf4j,log4j/logback)JDK的java.util.logging包JDK1.4引入了java.util....

    日志对于一个系统来说非常重要,查找异常信息、分析系统运行情况等都需要用到日志。所以无论是JDK还是第三方都提供了关于日志的相关工具,本文分别介绍以下几种工具,以及各种工具间的整合、原理。

    JDK的java.util.logging包

    第三方日志工具(commons-logging/slf4j,log4j/logback)

    JDK的java.util.logging包

    JDK1.4引入了java.util.logging包,包中主要的类包括:Logger、LogManager、Handler、Formatter。首先看一段比较简单的示例代码:

    packageme.likeyao.jdk.logger;importjava.util.logging.Formatter;importjava.util.logging.Handler;importjava.util.logging.Level;importjava.util.logging.LogRecord;importjava.util.logging.Logger;public classJDKLoggerTest {public static voidmain(String[] args) {

    Logger logger= Logger.getLogger("logger");

    logger.info("hello world");

    Handler handler= newHandler() {

    @Overridepublic voidpublish(LogRecord record) {

    }

    @Overridepublic voidflush() {

    }

    @Overridepublic void close() throwsSecurityException {

    }

    };

    handler.setFormatter(newFormatter() {

    @OverridepublicString format(LogRecord record) {return null;

    }

    });

    logger.setLevel(Level.INFO);

    logger.log(Level.FINEST,"hello world");

    }

    }

    通过Logger.getLogger(name)方法可以获取logger对象,logger对象有三个比较重要的概念:level、handler、formatter。level称为日志级别,在java.util.logging包中定义了java.util.logging.Level类,里面包含SEVERE/WARNING/INFO/CONFIG/FINE/FINER/FINEST(从高到低)7种日志级别。设置日志级别会过滤掉一部分日志,例如当日志级别设置为INFO级别时,CONFIG/FINE/FINER/FINEST级别的日志就会被忽略。handler解决的问题是日志输出到哪里,是到控制台(java.util.logging.ConsoleHandler),还是到文件(java.util.logging.FileHandler),或者是写到Socket中(java.util.logging.SocketHandler)。formatter定义了日志输出的格式,可以是XML(java.util.logging.XMLFormatter),也可以自己实现JSON格式的Fomatter。

    logger对象是如何生成的

    生成logger对象涉及到java.util.logging.LogManager类,LogManager中用到了单例模式,在static块中初始化了LoggerManager实例对象。生成logger对象的过程:

    2dd358b3b9c3c0de0a84129ff770c900.png

    从图中可以看到,logger对象是在LoggerManager中创建的。LoggerManager中有一个叫userContext的LoggerContext对象,userContext缓存了所有的logger对象(缓存在namedLoggers中),并维护了一套logger对象的父子结构。namedLoggers的定义:

    private final Hashtable namedLoggers = new Hashtable<>();

    LoggerWeakRef继承自java.lang.ref.WeakReference,namedLoggers并不直接持有logger对象,当持有logger的对象被垃圾回收之后,只有一个weekreference指向logger,方便垃圾回收logger对象。

    JDK logger其他一些有意思的东西

    有一个Logger.getLogger方法是两参数的,public static Logger getLogger(String name, String resourceBundleName),第二个参数最终会变成java.util.ResourceBundle对象,可以用来做国际化。

    java.util.logging.Handler可以设置java.util.logging.Filter更灵活的过滤日志。

    第三方日志工具(commons-logging/slf4j,log4j/logback)

    首先把四个工具分成了两组,commons-logging/slf4j和log4j/logback。log4j/logback功能与java.util.logging包类似,提供实际的日志功能。commons-logging/slf4j是门面,作用是统一日志操作,屏蔽底层不同日志组件的差异。

    commons-logging

    commons-logging是apache的项目,使用commons-logging的代码:

    packageme.likeyao.java.logger;importorg.apache.commons.logging.Log;importorg.apache.commons.logging.LogFactory;public classJCLTest {private static Log logger = LogFactory.getLog(JCLTest.class);public static void main(String[] args) throwsException {

    logger.info("hello world");

    }

    }

    代码中用到了commons-logging日志对象(org.apache.commons.logging.Log),日志对象工厂(org.apache.commons.logging.LogFactory)。前面有说过commons-logging是一个统一操作的门面,不涉及具体的日志功能,那日志对象是怎么产生的?查看Log对象的继承关系:

    0ba3d22d50e8fff723d61b1a3f0fef81.png

    commons-logging分别为支持的日志工具提供了一个Log类的实现类,在列表中看到了Log4JLogger和Jdk14Logger等,意味着commons-logging可以log4j、java.util.logging组合使用。因为没有对应的logback实现,所以也就无法一起使用。下图解释commons-logging如何决定具体生成哪种Logger对象:

    8c6884977f577c87d58ae0ea98510392.png

    LogFactory在static块中初始化了HashTable对象factories,以ClassLoader为key,LogFactory为value缓存了所有LogFactory对象。主要看一下LogFactoryImpl的discoverLogImplementation方法是如何发现底层使用的日志工具(省略了方法一部分内容):

    private static final String[] classesToDiscover ={

    LOGGING_IMPL_LOG4J_LOGGER,//org.apache.commons.logging.impl.Log4JLogger

    "org.apache.commons.logging.impl.Jdk14Logger","org.apache.commons.logging.impl.Jdk13LumberjackLogger","org.apache.commons.logging.impl.SimpleLog"};privateLog discoverLogImplementation(String logCategory)

    ...

    Log result= null;//查看commons-logging.properties和System.getProperty是否配置了org.apache.commons.logging.log

    String specifiedLogClassName =findUserSpecifiedLogClassName();if (specifiedLogClassName != null) {

    ...//如果有配置,直接使用配置的类创建Log

    result =createLogFromClass(specifiedLogClassName,

    logCategory,true);

    ...returnresult;

    }

    ...//如果没有,遍历classesToDiscover数组,如果使用指定的ClassLoader Class.forName能加载到类,就创建Log对象

    for(int i=0; i

    result= createLogFromClass(classesToDiscover[i], logCategory, true);

    }if (result == null) {throw newLogConfigurationException

    ("No suitable Log implementation");

    }returnresult;

    }

    整个初始化Log对象的流程:

    fcb2699c6f81af336458faaa37b7a84e.png

    commons-logging中的classloader

    网上搜commons-logging,可以看到不少文章都是在讲关于classloader的问题,贴出比较详细的一篇的链接:《Taxonomy of class loader problems encountered when using Jakarta Commons Logging》。文章中用的commons-logging本版较老,这里用commons-logging-1.2+log4k-1.2.17模拟一种场景,看看新commons-logging有什么改变。代码:

    packageme.likeyao.java.logger;importjava.io.File;importjava.net.URL;importjava.net.URLClassLoader;importorg.apache.commons.logging.Log;importorg.apache.commons.logging.LogFactory;public classJCLTest3 {public static void main(String[] args) throwsException {//自定义classloader,模仿web容器classloader,自己加载优先

    ChildClassLoader childClassLoader = newChildClassLoader(new URL[] { new File("c:/tmpclass/commons-logging-1.2.jar").toURL(),new File("C:/respository3/log4j/log4j/1.2.17/log4j-1.2.17.jar").toURL()});

    Thread.currentThread().setContextClassLoader(childClassLoader);

    Log log= LogFactory.getLog(JCLTest3.class);

    log.error("hello world");

    }

    }class ChildClassLoader extendsURLClassLoader {publicChildClassLoader(URL[] urls) {super(urls, ClassLoader.getSystemClassLoader());

    }

    @Overrideprotected Class> loadClass(String name, booleanresolve)throwsClassNotFoundException {synchronized(getClassLoadingLock(name)) {

    Class c=findLoadedClass(name);try{

    c=findClass(name);if(resolve) {

    resolveClass(c);

    }

    }catch(Exception e){

    }if (c == null) {

    c= super.loadClass(name, resolve);

    }returnc;

    }

    }

    }

    命令行执行:java -cp .;commons-logging-1.2.jar me.likeyao.java.logger.JCLTest3。输出结果:执行没有抛异常,日志是通过JDK java.util.logging打出来了,而不是log4j。

    c5e93e9a89e2386865dddec45a21e023.png

    可以从代码中分析出为什么会产生这样的结果。这里用到了两种类加载器:系统类加载器(AppClassLoader)和自定义的ChildClassLoader,系统类加载器能加载到当前编译目录的class文件和commons-logging.jar,ChildClassLoader加载了commons-logging.jar和log4j.jar,线程上下文加载器被设置为ChildClassLoader。当运行java命令时,随着程序运行会使用系统类加载器加载Log类、LogFactory类,查看上面discoverLogImplementation方法源码,由于没有配置org.apache.commons.logging.log属性,具体使用哪个Log的实现类会通过遍历classesToDiscover数组决定。下面看一下classesToDiscover[0]时的情况:

    private Log createLogFromClass(String logAdapterClassName, //org.apache.commons.logging.impl.Log4JLogger

    String logCategory,booleanaffectState)throwsLogConfigurationException {

    ...//通过logAdapterClassName所制定的类创建的对象,方法返回的结果

    Log logAdapter = null;

    ...//获取classloader,这里会返回ChildClassLoader,即main方法中设置的线程上下文加载器

    ClassLoader currentCL =getBaseClassLoader();for(;;) {try{

    ...

    Class c;try{//因为ChildClassLoader加载器可以获取到org.apache.commons.logging.impl.Log4JLogger类,正常得到c

    c = Class.forName(logAdapterClassName, true, currentCL);

    }catch(ClassNotFoundException originalClassNotFoundException) {

    ...

    }//创建org.apache.commons.logging.impl.Log4JLogger对象,这里o的classloader是ChildClassLoader

    constructor =c.getConstructor(logConstructorSignature);

    Object o=constructor.newInstance(params);//注意下面的注释,因为Log和o的类加载器不一致,所以不进入if分支//Note that we do this test after trying to create an instance//[rather than testing Log.class.isAssignableFrom(c)] so that//we don't complain about Log hierarchy problems when the//adapter couldn't be instantiated anyway.

    if (o instanceofLog) {

    logAdapterClass=c;

    logAdapter=(Log) o;break;

    }//Oops, we have a potential problem here. An adapter class//has been found and its underlying lib is present too, but//there are multiple Log interface classes available making it//impossible to cast to the type the caller wanted. We//certainly can't use this logger, but we need to know whether//to keep on discovering or terminate now.//

    //The handleFlawedHierarchy method will throw//LogConfigurationException if it regards this problem as//fatal, and just return if not.//根据allowFlawedHierarchy参数判断是否抛出LogConfigurationException,如果不抛异常,只是简单return,进入下一个循环

    handleFlawedHierarchy(currentCL, c);

    }catch(NoClassDefFoundError e) {

    ...break;

    }catch(ExceptionInInitializerError e) {

    ...break;

    }catch(LogConfigurationException e) {//call to handleFlawedHierarchy above must have thrown//a LogConfigurationException, so just throw it on

    throwe;

    }catch(Throwable t) {

    ...

    }if (currentCL == null) {break;

    }//try the parent classloader//currentCL = currentCL.getParent();

    currentCL =getParentClassLoader(currentCL);

    }

    ...returnlogAdapter;

    }

    classesToDiscover[0]的调用中,logAdapter并没有指向org.apache.commons.logging.impl.Log4JLogger对象,而是返回了null。所以进入下一次循环classesToDiscover[1](org.apache.commons.logging.impl.Jdk14Logger),这一次因为Log类和org.apache.commons.logging.impl.Jdk14Logger类都是由系统类加载器加载,所以最终执行的结果日志由java.util.logging打出。commons-logging使用classloader来加载Resource和发现底层具体日志工具,在web容器或者OSGI这些需要用类加载器做隔离的情况下的确会出现一些问题。

    SLF4J/LOG4J

    另一种日志门面SLF4J,它采用“静态绑定”的方式避免了commons-logging中有关类加载的一些问题。下面的把SLF4J和LOG4J放到一起,首先还是比较简单的使用代码:

    packageme.likeyao.slf4j.logger;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;public classSLF4JTest {public static voidmain(String[] args) {

    Logger logger= LoggerFactory.getLogger(SLF4JTest.class);

    logger.error("hello world");

    }

    }

    使用方式上看与commons-logging类似,除了类名上有一些区别。下图的是SLF4J整合LOG4J时Logger初始化时序图:

    9507b6680b71411f8485ff0005b691b6.png

    这里对几个类用了不同的颜色,蓝色代表类在slf4j-api包中,黄色代表类在slf4j-log4j12包中,红色代表类在log4j包中。相比commons-logging运行时通过classloader来发现底层日志工具,SLF4J是通过在不同的“桥梁包”里放置同名类org.slf4j.impl.StaticLoggerBinder来实现日志工具的绑定。例如,如果需要将SLF4J与java.util.logging整合,需要加入slf4j-jdk14-1.7.12,包中的StaticLoggerBinder类返回的loggerfactory是org.slf4j.impl.JDK14LoggerFactory;如果是SLF4J与log4j整合,需要加入slf4j-log4j12-1.7.12,包中的StaticLoggerBinder类返回的loggerfactory是org.slf4j.impl.Log4jLoggerFactory。这就是SLF4J的静态绑定。

    LOG4J是常用的日志工具,与java.util.logging(jul)非常像,一些概念也是共通的。例如logger都是父子结构的、jul的handler对应log4j的appender、formater对应layout、也都存在filter。为了理清log4j中各个类的关系,整理一份类图:

    bd9488fb6a377d967cbe0233e4586eaa.png

    整个类图的核心是org.apache.log4j.Category,但从1.2版本后log4j不会直接产生Category对象,而是Logger对象。Logger类继承自Category,扩展了一个日志级别:trace。当调用Logger对象的info/warn等方法时会生成一个LoggerEvent对象,AppenderAttachableImpl会遍历所有的appender调用doAppend方法。如果event没有被Filter过滤掉,那最终会经过Layout格式化,输出到appender指定的地方。LOG4J提供了很多appender供使用,这一点比JDK的hander强大很多。

    Appender的初始化在LogManager的static块中进行,最终解析发生在org.apache.log4j.xml.DOMConfigurator类中,logger、root、appender都在这里解析。

    if (tagName.equals(CATEGORY) ||tagName.equals(LOGGER)) {

    parseCategory(currentElement);

    }else if(tagName.equals(ROOT_TAG)) {

    parseRoot(currentElement);

    }else if(tagName.equals(RENDERER_TAG)) {

    parseRenderer(currentElement);

    }else if(tagName.equals(THROWABLE_RENDERER_TAG)) {if (repository instanceofThrowableRendererSupport) {

    ThrowableRenderer tr=parseThrowableRenderer(currentElement);if (tr != null) {

    ((ThrowableRendererSupport) repository).setThrowableRenderer(tr);

    }

    }

    }else if (!(tagName.equals(APPENDER_TAG)||tagName.equals(CATEGORY_FACTORY_TAG)||tagName.equals(LOGGER_FACTORY_TAG))) {

    quietParseUnrecognizedElement(repository, currentElement, props);

    }

    LOGBACK

    logback是log4j的一个替代品,初始化和打日志代码流程相似。为什么要从log4j切换到logback,logback网站上已经给出了(Reasons to prefer logback over log4j)。要使用SLF4J+logback需要引入三个包:slf4j-api、logback-core、logback-classic。这里和log4j对比,介绍一下两种日志工具的父子结构。无论是java.util.logging还是log4j/logback都为logger对象提供了父子结构,这样做有什么好处?我觉得主要是这样logger对象会有一个树形的层次结构,底层的logger可以复用父logger中的一些配置,比如日志级别,appender等。从log4j和logback的配置文件中,也可以看出这一点,通过为某个包名的logger指定appender和日志级别,可以作用所有这个包下的logger。例如:

    log4j和logback在处理父子结构时有一些差别,先看log4j的代码:

    synchronized(ht) {

    Object o=ht.get(key);if(o == null) {

    logger=factory.makeNewLoggerInstance(name);

    logger.setHierarchy(this);

    ht.put(key, logger);

    updateParents(logger);returnlogger;

    }else if(o instanceofLogger) {return(Logger) o;

    }else if (o instanceofProvisionNode) {//System.out.println("("+name+") ht.get(this) returned ProvisionNode");

    logger =factory.makeNewLoggerInstance(name);

    logger.setHierarchy(this);

    ht.put(key, logger);

    updateChildren((ProvisionNode) o, logger);

    updateParents(logger);returnlogger;

    }else{//It should be impossible to arrive here

    return null; //but let's keep the compiler happy.

    }

    }

    log4j在创建logger时,如果父节点是一个logger,那只维护一个子logger对父logger的引用。如果父节点不存在,就创建一些ProvisionNode对象(这是一个Vector的子类),保存所有下面子的logger。举个例子:当获取名称为x.y.z的logger时,首先会创建logger(x.y.z);然后查找父logger x.y,如果x.y不存在,就创建一个ProvisionNode对象,把logger(x.y.z)放到ProvisionNode对象中;然后继续向上搜索名称为x的logger,就将logger(x.y.z)的parent设置为logger(x)。当调用logger(x.y.z)对象的info/warn等方法时,如果logger(x.y.z)没有设置日志级别和appender,就是沿着parent向上搜索,直到rootLogger为止。

    logback的结构稍微有一些区别,所有的节点都是Logger对象,对象中有指向parent和children的引用,并且创建节点时,会把parent的日志级别直接复制到自己对象中。

    //if the desired logger does not exist, them create all the loggers//in between as well (if they don't already exist)

    String childName;while (true) {int h =LoggerNameUtil.getSeparatorIndexOf(name, i);if (h == -1) {

    childName=name;

    }else{

    childName= name.substring(0, h);

    }//move i left of the last point

    i = h + 1;synchronized(logger) {

    childLogger=logger.getChildByName(childName);if (childLogger == null) {

    childLogger=logger.createChildByName(childName);

    loggerCache.put(childName, childLogger);

    incSize();

    }

    }

    logger=childLogger;if (h == -1) {returnchildLogger;

    }

    }

    总结

    SL4J/COMMONS-LOGGING、LOG4J、LOGBACK、JUL都是常用的Java日志工具,基本思想都是通过Factory生成logger对象,然后由LogManager管理/缓存logger对象,同时维护一个父子结构方便复用配置。logger对象包含三要素:日志级别、输出到哪里、格式化。

    展开全文
  • 工欲善其事必先利其器在投奔怒海——一个Domino老程序员眼里的Java开发我提到目前所做的Java开发中遇到的大量日志之问题。服务器控制台刷屏似地滚动,日志文件飞快地增长,debug的时候相关信息常常被例常日志淹没,...

    工欲善其事必先利其器

    在投奔怒海——一个Domino老程序员眼里的Java开发我提到目前所做的Java开发中遇到的大量日志之问题。服务器控制台刷屏似地滚动,日志文件飞快地增长,debug的时候相关信息常常被例常日志淹没,在众多Logger滔滔不绝的输出下,要找出错误所在有时都挺费眼。日志的作用无可置疑,大型项目中日志海量产生也不少见。在以前的Domino开发中,Domino服务器在产生日志方面相当节制,程序员对日志的依赖程度也不高。转换到Java开发,我用一直最喜爱的文本编辑器EditPlus肉搏了一段时间(如果用Windows自带的记事本,打开动辄十几甚至几十兆的日志都有些困难),越来越迫切感觉到需要更专业的武器。Java Log Viewer(日志查看器)是我想像中的这款工具的名称,具备的功能包括:

    1.       可以手动重载日志。这样既可以防止自动跟踪日志影响当前关注的内容,又可以在需要时方便地载入最新的日志。

    2.       对不同级别的日志项着色标注。

    3.       可依据级别过滤日志。

    4.       方便搜索。

    上网一搜索便发现这是很多人想要的,并且与很多工具一样,问题已经不是缺乏,而是在众多候选者里选择。

    OtrosLogViewer

    根据Java Log Viewer这三个关键词的搜索结果和StackOverflow上的对应问题讨论,经过一番试用和比较【注1】,我确定OtrosLogViewer(http://code.google.com/p/otroslogviewer/)就是我所要的。

    除了我原先设想的功能,OtrosLogViewer还提供了以下便利:

    5.       以列表的形式分栏显示日志项,底部显示当前选中行的详细内容,并且表格的列可裁剪。

    6.       可以依据时间、级别、Logger名称、线程等条件过滤日志。

    7.       可迅速定位到上一条或下一条某个级别的日志。

    8.       可标记日志,还能根据许多实用的条件自动标记。

    9.       预设对多种格式日志的支持,并且有一个编辑器方便自定义需解析的Log4j日志模式(pattern)。

    不仅如此,软件的界面美观,操作友好。

    演示

    下面就以我所打交道的JBoss AS 7.1产生的日志来例示OtrosLogViewer的用法。

    50971317_1

    启动后界面

    除了菜单栏的基本命令,OtrosLogViewer的功能都由按钮或快捷菜单提供,操作上符合直觉,用户需要的功能都以便捷的方式出现在合适的地方。它没有一般软件的设置界面,各种设置都结合在操作的视图里。

    OtrosLogViewer有两组基本功能,Open XXX Log和Tail XXX Log,前者是用于打开一个静止的日志文件,后者则可自动刷新(即tail跟踪的含义)一个live的日志文件。软件支持包括Log4j普通文本和XML等多种格式的解析,并且有相应的菜单命令。如果不确定日志采用的格式,OtrosLogViewer也能在打开日志时自动检测。预设的Log4j日志模式为

    %d{yyyy-MM-ddHH:mm:ss,SSS} %-5p [%t] %m%n

    我所用的JBoss AS 7.1(从JBoss配置文件standalone.xml或者Web管理界面均可看到默认的日志处理器的模式为

    %d{HH:mm:ss,SSS}%-5p [%c] (%t) %s%E%n

    为了解析这样的日志,可以调用菜单里的Tools -> Show Log4j pattern parser editor。

    50971317_2

    将其中的相关初始配置改为

    pattern=TIMESTAMP LEVEL [CLASS] (THREAD)  MESSAGE

    dateFormat=HH:mm:ss,SSS

    在同一个界面里可以看到载入的日志文件,修改模式后可以随时测试解析结果。成功后将模式保存为新的pattern文件。软件的两组Open和Tail菜单里都会自动添加采用这个新模式的命令。

    打开一个日志文件,所有的日志条目已经列表显示,时间列自动只显示日期的时间部分。不同级别的日志很醒目地用不同颜色的图标区分。选中行日志的详细信息在下面的视图显示,包括错误堆栈和SOAP Message都有格式化和着色显示。用上十分钟,你就会发现仅仅这些阅读日志的效率大大提高。工具栏左边有搜索框,右边有按钮可以定位到上一条或下一条各种级别的日志。每一条日志都可以做标记(Mark)或者加注释(Note),主视图左边的工具视图可以设置和显示过滤和常用的自动标记功能。特别要说明的是列表视图上方的两个图标,第一个可切换是否自动读取新日志,第二个图标则控制在自动刷新的状态下列表中的当前行是否跟随读取的最新行。这两项功能结合起来,在读取live日志时十分方便。

    50971317_3

    最后再展示一下选中日志后快捷菜单里的丰富选项,过滤和删除都很实用,能够快速排除无关的日志。

    50971317_4

    注1:Apache的Chainsaw已经多年未更新,bug不少,性能不佳。

    一个直接以Java Log Viewer命名的项目过于简单,且只适用于java.util.logging生成的日志。

    StackOverflow一个被人推荐的LogExpert在目前的1.5版本上有一个明显且重大的bug,无论是否设置跟踪,软件都会自动跳到最新的日志行。

    展开全文
  • grep查询关键字--指定时间数据grep "10:35" catalina.out查询时间段数据sed -n '/10:30:35/,/10:35:35/p' catalina.outLog位置:/var/log/message 系统启动后的信息和错误日志,是Red Hat Linux中最常用的日志之一/...

    grep查询关键字--指定时间数据

    grep "10:35" catalina.out

    查询时间段数据

    sed -n '/10:30:35/,/10:35:35/p' catalina.out

    Log位置:

    /var/log/message 系统启动后的信息和错误日志,

    是Red Hat Linux中最常用的日志之一

    /var/log/secure 与安全相关的日志信息

    /var/log/maillog 与邮件相关的日志信息

    /var/log/cron 与定时任务相关的日志信息

    /var/log/spooler 与UUCP和news设备相关的日志信息

    /var/log/boot.log 守护进程启动和停止相关的日志消息

    tail

    参数:

    tail [ -f ] [ -c Number | -n Number | -m Number | -b Number | -k Number ] [ File ]

    参数解释:

    -f 该参数用于监视File文件增长。

    -c Number 从 Number 字节位置读取指定文件

    -n Number 从 Number 行位置读取指定文件。

    -m Number 从 Number 多字节字符位置读取指定文件,比方你的文件假设包括中文字,假设指定-c参数,可能导致截断,但使用-m则会避免该问题。

    -b Number 从 Number 表示的512字节块位置读取指定文件。

    -k Number 从 Number 表示的1KB块位置读取指定文件。

    File 指定操作的目标文件名称

    上述命令中,都涉及到number,假设不指定,默认显示10行。Number前面可使用正负号,表示该偏移从顶部还是从尾部開始计算。

    tail可运行文件一般在/usr/bin/以下

    实例:

    1、tail -f filename 说明:监视filename文件的尾部内容(默认10行,相当于增加参数 -n 10),刷新显示在屏幕上。退出,按下CTRL+C。

    2、tail -n 20 filename 说明:显示filename最后20行。

    3、tail -r -n 10 filename 说明:逆序显示filename最后10行

    head

    head 仅仅显示前面几行

    head -n 10 test.log 查询日志文件中的头10行日志;

    head -n -10 test.log 查询日志文件除了最后10行的其他所有日志

    grep

    grep [options]

    主要参数: [options]主要参数:

    -c:只输出匹配行的计数。

    -I:不区分大 小写(只适用于单字符)。

    -h:查询多文件时不显示文件名。

    -l:查询多文件时只输出包含匹配字符的文件名。

    -n:显示匹配行及 行号。

    -s:不显示不存在或无匹配文本的错误信息。

    -v:显示不包含匹配文本的所有行。

    pattern正则表达式主要参数:

    : 忽略正则表达式中特殊字符的原有含义。

    ^:匹配正则表达式的开始行。

    $: 匹配正则表达式的结束行。

    :到匹配正则表达式的行结束。

    [ ]:单个字符,如[A]即A符合要求 。

    [ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。

    。:所有的单个字符。

    - :有字符,长度可以为0

    sed

    用sed命令

    sed -n '5,10p' filename 这样你就可以只查看文件的第5行到第10行。

    cat

    cat主要有三大功能:

    1.一次显示整个文件。$ cat filename

    2.从键盘创建一个文件。$ cat > filename 只能创建新文件,不能编辑已有文件.

    3.将几个文件合并为一个文件: $cat file1 file2 > file

    参数:

    -n 或 --number 由 1 开始对所有输出的行数编号

    -b 或 --number-nonblank 和 -n 相似,只不过对于空白行不编号

    -s 或 --squeeze-blank 当遇到有连续两行以上的空白行,就代换为一行的空白行

    -v 或 --show-nonprinting 例: 把 textfile1 的档案内容加上行号后输入 textfile2 这个档案里

    cat -n textfile1 > textfile2 把 textfile1 和 textfile2 的档案内容加上行号(空白行不加)之后将内容附加到 textfile3 里。

    cat -b textfile1 textfile2 >> textfile3 把test.txt文件扔进垃圾箱,赋空值test.txt

    cat /dev/null > /etc/test.txt 注意:>意思是创建,>>是追加。千万不要弄混了

    tac (反向列示)

    tac 是将 cat 反写过来,所以他的功能就跟 cat 相反, cat 是由第一行到最后一行连续显示在萤幕上, 而 tac 则是由最后一行到第一行反向在萤幕上显示出来!

    混合使用命令

    A. tail web.2016-06-06.log -n 300 -f 查看底部即最新300条日志记录,并实时刷新

    B. grep 'nick' | tail web.2016-04-04.log -C 10 查看字符‘nick’前后10条日志记录, 大写C

    C. cat -n test.log |tail -n +92|head -n 20 tail -n +92表示查询92行之后的日志

    head -n 20 则表示在前面的查询结果里再查前20条记录

    展开全文
  • over-slf4j 是从log4j桥接到slf4j jcl-over-slf4j是commons-logging桥接到slf4j 四、备注 commons-logging的简写为jcl java.util.logging的简写为jul,为java内置的日志类型 五、slf4j日志架构 六、slf4j-ext的用处...

    一、slf4j+log4j2

    maven的jar包依赖:

    org.apache.logging.log4j

    log4j-slf4j-impl

    2.11.1

    8590ed52fe93fc2f9a05641abab49b55.png

    二、slf4j+logback

    maven的jar包依赖:

    ch.qos.logback

    logback-classic

    1.2.3

    fca77ad86b1a94ae25f4f690ce1240da.png

    三、slf4j的桥接

    jul-to-slf4j是从jul桥接到slf4j

    log4j-over-slf4j 是从log4j桥接到slf4j

    jcl-over-slf4j是commons-logging桥接到slf4j

    四、备注

    commons-logging的简写为jcl

    java.util.logging的简写为jul,为java内置的日志类型

    五、slf4j日志架构

    164e32745b669f6e8ba1707384adc11a.png

    六、slf4j-ext的用处:

    七、logback配置:

    Logback默认配置的步骤:

    1、尝试在classpath下查找文件 logback.groovy

    2、如果文件不存在,则查找文件logback-test.xml

    3、如果文件不存在,则查找文件logback.xml

    4、如果都不存在,logback用BasicConfigurator自动对自己进行配置,这会导致记录输出到控制台。

    打印配置详情可以通过下面的语句:

    import org.slf4j.LoggerFactory;

    importch.qos.logback.classic.LoggerContext;importch.qos.logback.core.util.StatusPrinter;

    LoggerContext lc=(LoggerContext) LoggerFactory.getILoggerFactory();

    StatusPrinter.print(lc);

    9e3c7506c6dd96236aa62b2714b176b1.png

    参考文献:

    展开全文
  • Java GC类型Java中的GC有哪几种类型?参数描述UseSerialGC虚拟机运行在Client模式的默认值,打开此开关参数后,使用Serial+Serial Old收集器组合进行垃圾收集。UseParNewGC打开此开关参数后,使用ParNew+Serial Old...
  • Java GC日志查看

    2020-10-11 22:42:32
    Java GC日志查看
  • Java GC类型Java中的GC有哪几种类型?参数描述UseSerialGC虚拟机运行在Client模式的默认值,打开此开关参数后,使用Serial+Serial Old收集器组合进行垃圾收集。UseParNewGC打开此开关参数后,使用ParNew+Serial Old...
  • GC日志查看可以通过在java命令种加入参数来指定对应的gc类型,打印gc日志信息并输出至文件等策略。GC的日志是以替换的方式(>)写入的,而不是追加(>>),如果下次写入到同一个文件中的话,以前的GC内容会被...
  • Java GC类型Java中的GC有哪几种类型?参数描述UseSerialGC虚拟机运行在Client模式的默认值,打开此开关参数后,使用Serial+Serial Old收集器组合进行垃圾收集。UseParNewGC打开此开关参数后,使用ParNew+Serial Old...
  • Java GC类型Java中的GC有哪几种类型?参数描述UseSerialGC虚拟机运行在Client模式的默认值,打开此开关参数后,使用Serial+Serial Old收集器组合进行垃圾收集。UseParNewGC打开此开关参数后,使用ParNew+Serial Old...
  • Java GC日志查看和分析

    2019-11-07 19:57:04
    javaGC日志查看可以通过在java命令种加入参数来指定对应的gc类型,打印gc日志信息并输出至文件等策略。 -XX:+PrintGC 输出GC日志 -XX:+PrintGCDetails 输出GC的详细日志 -XX:+PrintGCTimeStamps 输出GC的时间戳(以...
  • -s 或 –squeeze-blank 当遇到有连续两行以上的空白行,就代换为一行的空白行 -v 或 –show-nonprinting 2、more命令: 以百分比的形式查看日志。 3、less命令: 跟more功能差不多,只不过less支持前后翻阅文件。 4...
  • 查看客户端java日志

    2013-12-03 14:30:00
    通过 Java 控制面板启用 Java 控制台 Windows 8 使用搜索来查找控制面板 按 Windows 徽标键 + W 以打开搜索框来搜索设置,或者将鼠标指针拖动到屏幕的右下角,然后单击搜索图标。 在搜索框中输入 Java 控制...
  • mark-sweep perm gen total 262144K, used 44072K [0x00000007f0000000, 0x0000000800000000, 0x0000000800000000) } 上面是我的一个GC日志,我想问这种日志该怎么看呢?之前只是学过一些理论的东西,头一次接触真正...
  • linux查看日志文件内容命令tail、cat、tac、head、echotail -f test.log你会看到屏幕不断有内容被打印出来. 这时候中断第一个进程Ctrl-C,---------------------------linux 如何显示一个文件的某几行(中间几行)从第...
  • 日志 JLogg是一个JavaFX基于端口它在本质上是在大型搜索日志文件做了一个日志文件搜索工具。 特征 搜索日志文件(使用ctrl / command + F) 使用正则表达式(使用ctrl / command + H)突出显示日志文件中的行 ...
  • import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.net.URLEncoder; /** * @author Sue * @...
  • java GC 日志查看

    2016-05-11 17:05:00
     java GC 日志查看  操作了java 这么久,终于遇到了查看gc日志的时候了,原因是这样的,数据库的数据查询出来用java进行一些分析的,随着数据库数据查出来数据多了起来,web服务器响应时间越来越慢,开始第一...
  • 1、查看该项目最近1000行日志,并且实时查看日志的更新tail -f /var/log/server.log -n 10002、只查看日志尾1000行,不会随着日志更新结果也更新cat /var/log/server.log | tail -n 10003、只查看日志头1000行,不会...
  • 日志技术选型Log 门面层选型《阿里巴巴 Java 开发规范》【强制】应用中不可使用日志系统(Log4J、Logback)中的 API,而应依赖使用日志框架 SLF4J 中的 API。使用门面模式的日志框架,有利于维护和各个类的日志处理...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,828
精华内容 2,331
关键字:

java日志查看

java 订阅