`
Donald_Draper
  • 浏览: 972140 次
社区版块
存档分类
最新评论

slf4j + Logback详解

阅读更多
Log4j初始化详解:http://donald-draper.iteye.com/blog/2332385
Log4j日志输出详解:http://donald-draper.iteye.com/admin/blogs/2332395
slf4j +  Log4j的使用:http://donald-draper.iteye.com/admin/blogs/2332407
slf4j + Log4j 详解:http://donald-draper.iteye.com/admin/blogs/2332417
使用logback轻松管理日志 http://blog.csdn.net/mydeman/article/details/6716925
Logback日志使用详解:http://www.cnblogs.com/davidwang456/p/4448011.html
logback的介绍-配置:http://sunney2010.iteye.com/blog/1404723
slf4j +  Logback的使用:http://donald-draper.iteye.com/admin/blogs/2332438
上一篇讲了slf4j + Logback的使用,其中获取Logger的一句为
[url]private static Logger log = LoggerFactory.getLogger(testLogback.class);[/url]
下面来看这一句的具体含义:
public final class LoggerFactory
{
    static final String CODES_PREFIX = "http://www.slf4j.org/codes.html";
    static final String NO_STATICLOGGERBINDER_URL = "http://www.slf4j.org/codes.html#StaticLoggerBinder";
    static final String MULTIPLE_BINDINGS_URL = "http://www.slf4j.org/codes.html#multiple_bindings";
    static final String NULL_LF_URL = "http://www.slf4j.org/codes.html#null_LF";
    static final String VERSION_MISMATCH = "http://www.slf4j.org/codes.html#version_mismatch";
    static final String SUBSTITUTE_LOGGER_URL = "http://www.slf4j.org/codes.html#substituteLogger";
    static final String LOGGER_NAME_MISMATCH_URL = "http://www.slf4j.org/codes.html#loggerNameMismatch";
    static final String UNSUCCESSFUL_INIT_URL = "http://www.slf4j.org/codes.html#unsuccessfulInit";
    static final String UNSUCCESSFUL_INIT_MSG = "org.slf4j.LoggerFactory could not be successfully initialized. See also http://www.slf4j.org/codes.html#unsuccessfulInit";
    static final int UNINITIALIZED = 0;
    static final int ONGOING_INITIALIZATION = 1;
    static final int FAILED_INITIALIZATION = 2;
    static final int SUCCESSFUL_INITIALIZATION = 3;
    static final int NOP_FALLBACK_INITIALIZATION = 4;
    static int INITIALIZATION_STATE = 0;
    static SubstituteLoggerFactory TEMP_FACTORY = new SubstituteLoggerFactory();
    static NOPLoggerFactory NOP_FALLBACK_FACTORY = new NOPLoggerFactory();
    static final String DETECT_LOGGER_NAME_MISMATCH_PROPERTY = "slf4j.detectLoggerNameMismatch";
    static boolean DETECT_LOGGER_NAME_MISMATCH = Boolean.getBoolean("slf4j.detectLoggerNameMismatch");
    private static final String API_COMPATIBILITY_LIST[] = {
        "1.6", "1.7"
    };
    private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";
   //根据class,获取Logger
public static Logger getLogger(Class clazz)
    {
        Logger logger = getLogger(clazz.getName());
        if(DETECT_LOGGER_NAME_MISMATCH)
        {
            Class autoComputedCallingClass = Util.getCallingClass();
            if(nonMatchingClasses(clazz, autoComputedCallingClass))
            {
                Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", new Object[] {
                    logger.getName(), autoComputedCallingClass.getName()
                }));
                Util.report("See http://www.slf4j.org/codes.html#loggerNameMismatch for an explanation");
            }
        }
        return logger;
    }
    //根据class name 获取Logger
     public static Logger getLogger(String name)
    {
        //获取LoggerFactory
        ILoggerFactory iLoggerFactory = getILoggerFactory();
	//从LoggerFactory获取Logger
        return iLoggerFactory.getLogger(name);
    }
    //获取LoggerFactory
     public static ILoggerFactory getILoggerFactory()
    {
        if(INITIALIZATION_STATE == 0)
        {
            INITIALIZATION_STATE = 1;
	    //执行初始化
            performInitialization();
        }
        switch(INITIALIZATION_STATE)
        {
        case 3: // '\003'
	    //返回Log4jLoggerFactory
            return StaticLoggerBinder.getSingleton().getLoggerFactory();

        case 4: // '\004'
	//如果状态为4,则返回NOPLoggerFactory
            return NOP_FALLBACK_FACTORY;

        case 2: // '\002'
            throw new IllegalStateException("org.slf4j.LoggerFactory could not be successfully initialized. See also http://www.slf4j.org/codes.html#unsuccessfulInit");
        //如果初始化状态为1,返回临时LoggerFactory,SubstituteLoggerFactory
        case 1: // '\001'
            return TEMP_FACTORY;
        }
        throw new IllegalStateException("Unreachable code");
    }
    //执行初始化
     private static final void performInitialization()
    {
        //绑定日志工场
        bind();
        if(INITIALIZATION_STATE == 3)
	    //验证配置
            versionSanityCheck();
    }
    //绑定日志工场
     private static final void bind()
    {
        try
        {
	    //获取具体LoggerBinder类,默认为StaticLoggerBinder,在slf4j-log4j12-1.7.9.jar 中
            Set staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
            reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
            StaticLoggerBinder.getSingleton();
            INITIALIZATION_STATE = 3;
            reportActualBinding(staticLoggerBinderPathSet);
	    //从SubstituteLoggerFactory获取具体sfl4j的Logger实现,并用SubstituteLogger代理类去包装
            fixSubstitutedLoggers();
        }
	catch(NoClassDefFoundError ncde)
        {
            String msg = ncde.getMessage();
            if(messageContainsOrgSlf4jImplStaticLoggerBinder(msg))
            {
	        //初始化状态为4,返回NOPLoggerFactory,无配置Logger
                INITIALIZATION_STATE = 4;
                Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
                Util.report("Defaulting to no-operation (NOP) logger implementation");
                Util.report("See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.");
            } else
            {
                failedBinding(ncde);
                throw ncde;
            }
        }
        catch(NoSuchMethodError nsme)
        {
            String msg = nsme.getMessage();
            if(msg != null && msg.indexOf("org.slf4j.impl.StaticLoggerBinder.getSingleton()") != -1)
            {
	        //org.slf4j.LoggerFactory could not be successfully initialized
                INITIALIZATION_STATE = 2;
                Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
                Util.report("Your binding is version 1.5.5 or earlier.");
                Util.report("Upgrade your binding to version 1.6.x.");
            }
            throw nsme;
        }
	catch(Exception e)
        {
            failedBinding(e);
            throw new IllegalStateException("Unexpected initialization failure", e);
        }

    }
    //获取StaticLoggerBinderPathS
    private static Set findPossibleStaticLoggerBinderPathSet()
    {
        Set staticLoggerBinderPathSet = new LinkedHashSet();
        try
        {
            ClassLoader loggerFactoryClassLoader = org/slf4j/LoggerFactory.getClassLoader();
            Enumeration paths;
            if(loggerFactoryClassLoader == null)
                paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
            else
	        // private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";
                paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH);
            URL path;
            for(; paths.hasMoreElements(); staticLoggerBinderPathSet.add(path))
                path = (URL)paths.nextElement();

        }
        return staticLoggerBinderPathSet;
    }
    //report多bind
    private static void reportMultipleBindingAmbiguity(Set staticLoggerBinderPathSet)
    {
        if(isAmbiguousStaticLoggerBinderPathSet(staticLoggerBinderPathSet))
        {
            Util.report("Class path contains multiple SLF4J bindings.");
            URL path;
            for(Iterator iterator = staticLoggerBinderPathSet.iterator(); iterator.hasNext(); Util.report((new StringBuilder()).append("Found binding in [").append(path).append("]").toString()))
                path = (URL)iterator.next();

            Util.report("See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.");
        }
    }
   //report实际绑定
    private static void reportActualBinding(Set staticLoggerBinderPathSet)
    {
        if(isAmbiguousStaticLoggerBinderPathSet(staticLoggerBinderPathSet))
            Util.report((new StringBuilder()).append("Actual binding is of type [").append(StaticLoggerBinder.getSingleton().getLoggerFactoryClassStr()).append("]").toString());
    }
    //从SubstituteLoggerFactory获取具体sfl4j的Logger实现,并用SubstituteLogger代理类去包装
    //如果日志Logger为sfl4j的Logger的实现,则用SubstituteLogger去代理具体的实现Logger
    private static final void fixSubstitutedLoggers()
    {
       //从临时工厂SubstituteLoggerFactory,获取所有Loggers
        List loggers = TEMP_FACTORY.getLoggers();
        if(loggers.isEmpty())
            return;
        Util.report("The following set of substitute loggers may have been accessed");
        Util.report("during the initialization phase. Logging calls during this");
        Util.report("phase were not honored. However, subsequent logging calls to these");
        Util.report("loggers will work as normally expected.");
        Util.report("See also http://www.slf4j.org/codes.html#substituteLogger");
        SubstituteLogger subLogger;
        for(Iterator i$ = loggers.iterator(); i$.hasNext(); Util.report(subLogger.getName()))
        {
            subLogger = (SubstituteLogger)i$.next();
            subLogger.setDelegate(getLogger(subLogger.getName()));
        }

        TEMP_FACTORY.clear();
    }
    //验证配置,校验文件
    private static final void versionSanityCheck()
    {
        try
        {
            String requested = StaticLoggerBinder.REQUESTED_API_VERSION;
            boolean match = false;
            for(int i = 0; i < API_COMPATIBILITY_LIST.length; i++)
                if(requested.startsWith(API_COMPATIBILITY_LIST[i]))
                    match = true;

            if(!match)
            {
                Util.report((new StringBuilder()).append("The requested version ").append(requested).append(" by your slf4j binding is not compatible with ").append(Arrays.asList(API_COMPATIBILITY_LIST).toString()).toString());
                Util.report("See http://www.slf4j.org/codes.html#version_mismatch for further details.");
            }
        }
    }
}

//StaticLoggerBinder
public class StaticLoggerBinder
    implements LoggerFactoryBinder
{
    public static String REQUESTED_API_VERSION = "1.6";
    static final String NULL_CS_URL = "http://logback.qos.ch/codes.html#null_CS";
    private static StaticLoggerBinder SINGLETON;
    private static Object KEY = new Object();
    private boolean initialized;
    private LoggerContext defaultLoggerContext;
    private final ContextSelectorStaticBinder contextSelectorBinder = ContextSelectorStaticBinder.getSingleton();

    static 
    {
        SINGLETON = new StaticLoggerBinder();
	//初始化
        SINGLETON.init();
    }
   private StaticLoggerBinder()
    {
        initialized = false;
        defaultLoggerContext = new LoggerContext();
        defaultLoggerContext.setName("default");
    }

    public static StaticLoggerBinder getSingleton()
    {
        return SINGLETON;
    }
    //初始化
     void init()
    {
        try
        {
            try
            {
	        //配置defaultLoggerContext
                (new ContextInitializer(defaultLoggerContext)).autoConfig();
            }
            catch(JoranException je)
            {
                Util.report("Failed to auto configure default logger context", je);
            }
            StatusPrinter.printInCaseOfErrorsOrWarnings(defaultLoggerContext);
            contextSelectorBinder.init(defaultLoggerContext, KEY);
            initialized = true;
        }
        catch(Throwable t)
        {
            Util.report((new StringBuilder()).append("Failed to instantiate [").append(ch/qos/logback/classic/LoggerContext.getName()).append("]").toString(), t);
        }
    }
}

//ContextInitializer
public class ContextInitializer
{
    public static final String GROOVY_AUTOCONFIG_FILE = "logback.groovy";
    public static final String AUTOCONFIG_FILE = "logback.xml";
    public static final String TEST_AUTOCONFIG_FILE = "logback-test.xml";
    public static final String CONFIG_FILE_PROPERTY = "logback.configurationFile";
    public static final String STATUS_LISTENER_CLASS = "logback.statusListenerClass";
    public static final String SYSOUT = "SYSOUT";
    final LoggerContext loggerContext;
    public ContextInitializer(LoggerContext loggerContext)
    {
        this.loggerContext = loggerContext;
    }
     public void autoConfig()
        throws JoranException
    {
        StatusListenerConfigHelper.installIfAsked(loggerContext);
	//获取配置资源,先找logback.groovy,logback-test.xml,logback.xml
        URL url = findURLOfDefaultConfigurationFile(true);
        if(url != null)
	    //根据资源配置LogContext
            configureByResource(url);
        else
            BasicConfigurator.configure(loggerContext);
    }
    //获取配置资源,先找logback.groovy,logback-test.xml,logback.xml
    public URL findURLOfDefaultConfigurationFile(boolean updateStatus)
    {
        ClassLoader myClassLoader = Loader.getClassLoaderOfObject(this);
        URL url = findConfigFileURLFromSystemProperties(myClassLoader, updateStatus);
        if(url != null)
            return url;
        url = getResource("logback.groovy", myClassLoader, updateStatus);
        if(url != null)
            return url;
        url = getResource("logback-test.xml", myClassLoader, updateStatus);
        if(url != null)
            return url;
        else
            return getResource("logback.xml", myClassLoader, updateStatus);
    }
    //根据资源配置LogContext
    public void configureByResource(URL url)
        throws JoranException
    {
        if(url == null)
            throw new IllegalArgumentException("URL argument cannot be null");
        if(url.toString().endsWith("groovy"))
            if(EnvUtil.isGroovyAvailable())
            {
                GafferUtil.runGafferConfiguratorOn(loggerContext, this, url);
            } else
            {
                StatusManager sm = loggerContext.getStatusManager();
                sm.add(new ErrorStatus("Groovy classes are not available on the class path. ABORTING INITIALIZATION.", loggerContext));
            }
        if(url.toString().endsWith("xml"))
        {
            JoranConfigurator configurator = new JoranConfigurator();
	    //设置LogContext
            configurator.setContext(loggerContext);
	    //根据资源配置LogContext
            configurator.doConfigure(url);
        }
    }
}

//JoranConfigurator
public class JoranConfigurator extends JoranConfiguratorBase
{
    public void addInstanceRules(RuleStore rs)
    {
        super.addInstanceRules(rs);
        rs.addRule(new Pattern("configuration"), new ConfigurationAction());
        rs.addRule(new Pattern("configuration/contextName"), new ContextNameAction());
        rs.addRule(new Pattern("configuration/contextListener"), new LoggerContextListenerAction());
        rs.addRule(new Pattern("configuration/insertFromJNDI"), new InsertFromJNDIAction());
        rs.addRule(new Pattern("configuration/evaluator"), new EvaluatorAction());
        rs.addRule(new Pattern("configuration/appender/sift"), new SiftAction());
        rs.addRule(new Pattern("configuration/appender/sift/*"), new NOPAction());
        rs.addRule(new Pattern("configuration/logger"), new LoggerAction());
        rs.addRule(new Pattern("configuration/logger/level"), new LevelAction());
        rs.addRule(new Pattern("configuration/root"), new RootLoggerAction());
        rs.addRule(new Pattern("configuration/root/level"), new LevelAction());
        rs.addRule(new Pattern("configuration/logger/appender-ref"), new AppenderRefAction());
        rs.addRule(new Pattern("configuration/root/appender-ref"), new AppenderRefAction());
        rs.addRule(new Pattern("*/if"), new IfAction());
        rs.addRule(new Pattern("*/if/then"), new ThenAction());
        rs.addRule(new Pattern("*/if/then/*"), new NOPAction());
        rs.addRule(new Pattern("*/if/else"), new ElseAction());
        rs.addRule(new Pattern("*/if/else/*"), new NOPAction());
        if(PlatformInfo.hasJMXObjectName())
            rs.addRule(new Pattern("configuration/jmxConfigurator"), new JMXConfiguratorAction());
        rs.addRule(new Pattern("configuration/include"), new IncludeAction());
        rs.addRule(new Pattern("configuration/consolePlugin"), new ConsolePluginAction());
    }
    protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry)
    {
        DefaultNestedComponentRules.addDefaultNestedComponentRegistryRules(registry);
    }
}

//JoranConfiguratorBase
public abstract class JoranConfiguratorBase extends GenericConfigurator

//GenericConfigurator
public abstract class GenericConfigurator extends ContextAwareBase
{ 
//根据资源配置LogContext
public final void doConfigure(URL url)
        throws JoranException
    {
        try
        {
	    //设置LogContext的URL
            informContextOfURLUsedForConfiguration(url);
            URLConnection urlConnection = url.openConnection();
            urlConnection.setUseCaches(false);
            InputStream in = urlConnection.getInputStream();
	    //根据输入流,配置LogContext
            doConfigure(in);
            in.close();
        }
        catch(IOException ioe)
        {
            String errMsg = (new StringBuilder()).append("Could not open URL [").append(url).append("].").toString();
            addError(errMsg, ioe);
            throw new JoranException(errMsg, ioe);
        }
    }
    //设置LogContext的URL
      protected void informContextOfURLUsedForConfiguration(URL url)
    {
        getContext().putObject(CoreConstants.URL_OF_LAST_CONFIGURATION_VIA_JORAN, url);
    }
    public final void doConfigure(InputStream inputStream)
        throws JoranException
    {
        doConfigure(new InputSource(inputStream));
    }
    //根据输入流源,配置LogContext
    public final void doConfigure(InputSource inputSource)
        throws JoranException
    {
        SaxEventRecorder recorder = new SaxEventRecorder();
        recorder.setContext(context);
        recorder.recordEvents(inputSource);
        buildInterpreter();
        synchronized(context.getConfigurationLock())
        {
            interpreter.play(recorder.saxEventList);
        }
    }
     protected Interpreter interpreter;
}

//LoggerContext
public class LoggerContext extends ContextBase
    implements ILoggerFactory, LifeCycle
{

    public LoggerContext()
    {
        noAppenderWarning = 0;
        packagingDataEnabled = true;
        maxCallerDataDepth = 8;
        started = false;
        resetCount = 0;
        loggerCache = new Hashtable();
        loggerContextRemoteView = new LoggerContextVO(this);
        root.setLevel(Level.DEBUG);
        loggerCache.put("ROOT", root);
        initEvaluatorMap();
        size = 1;
    }
    //获取Logger,ch.qos.logback.classic.Logger
    public volatile Logger getLogger(String x0)
    {
        return getLogger(x0);
    }
    final ch.qos.logback.classic.Logger root = new ch.qos.logback.classic.Logger("ROOT", null, this);
    private int size;
    private int noAppenderWarning;
    private final List loggerContextListenerList = new ArrayList();
    private Hashtable loggerCache;
    private LoggerContextVO loggerContextRemoteView;
    private final TurboFilterList turboFilterList = new TurboFilterList();
    private boolean packagingDataEnabled;
    private int maxCallerDataDepth;
    boolean started;
    int resetCount;
}

//ch.qos.logback.classic.Logger
public final class Logger
    implements org.slf4j.Logger, LocationAwareLogger, AppenderAttachable, Serializable
{
 Logger(String name, Logger parent, LoggerContext loggerContext)
    {
        additive = true;
        this.name = name;
        this.parent = parent;
        this.loggerContext = loggerContext;
        buildRemoteView();
        instanceCount++;
    }

    public final Level getEffectiveLevel()
    {
        return Level.toLevel(effectiveLevelInt);
    }
    //产生Info日志
    public void info(String msg)
    {
        filterAndLog_0_Or3Plus(FQCN, null, Level.INFO, msg, null, null);
    }
    private final void filterAndLog_0_Or3Plus(String localFQCN, Marker marker, Level level, String msg, Object params[], Throwable t)
    {
        FilterReply decision = loggerContext.getTurboFilterChainDecision_0_3OrMore(marker, this, level, msg, params, t);
        if(decision == FilterReply.NEUTRAL)
        {
            if(effectiveLevelInt > level.levelInt)
                return;
        } else
        if(decision == FilterReply.DENY)
            return;
        buildLoggingEventAndAppend(localFQCN, marker, level, msg, params, t);
    }
}

//如果无配置文件,则使用BasicConfigurator,简单的控制台输出

public class BasicConfigurator
{
    public static void configure(LoggerContext lc)
    {
        StatusManager sm = lc.getStatusManager();
        if(sm != null)
            sm.add(new InfoStatus("Setting up default configuration.", lc));
        ConsoleAppender ca = new ConsoleAppender();
        ca.setContext(lc);
        ca.setName("console");
        PatternLayoutEncoder pl = new PatternLayoutEncoder();
        pl.setContext(lc);
        pl.setPattern("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");
        pl.start();
        ca.setEncoder(pl);
        ca.start();
        Logger rootLogger = lc.getLogger("ROOT");
        rootLogger.addAppender(ca);
    }
    public static void configureDefaultContext()
    {
        LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
        configure(lc);
    }

    static final BasicConfigurator hiddenSingleton = new BasicConfigurator();

}

总结:
从上面可以看出logback与sfl4j的整合,实际上是通过实现类StaticLoggerBinder,LoggerFactory加载
StaticLoggerBinder,StaticLoggerBinder通过静态语句块来,初始化LoggerContext,而LoggerContext实现
的ILoggerFactory接口,从LoggerContext获取的Logger实际为ch.qos.logback.classic.Logger,
即org.slf4j.Logger的实现类。
分享到:
评论

相关推荐

    详解Spring Boot 使用slf4j+logback记录日志配置

    Logback 是 SLF4J 推荐的日志实现,它由 log4j 的创始人设计,提供了高速、灵活且可靠的日志记录功能。 使用 SLF4J 和 Logback 进行日志记录配置的主要目的是: 1. 为 Spring 的开发提供了一个更快速更广泛的入门...

    详解slf4j+logback在java工程中的配置

    SLF4J(Simple Logging Facade for Java)和Logback是Java开发中广泛使用的日志框架,它们提供了灵活的日志记录解决方案。SLF4J是一个接口层,它为各种日志框架提供了统一的抽象,而Logback是SLF4J的一个实现,用于...

    slf4j+log4j2配置使用

    SLF4J(Simple Logging Facade for Java)是一个Java的日志接口,而Log4j2是一个具体的日志实现框架。Log4j2是Log4j的升级版,提供了更加灵活和强大的日志处理能力,包括异步日志、延迟加载、日志脱敏等功能。接下来...

    slf4j日志demo项目 logback.xml配置详解

    slf4j日志demo项目 logback.xml配置详解,slf4j日志demo项目 logback.xml配置详解,slf4j日志demo项目 logback.xml配置详解,slf4j日志demo项目 logback.xml配置详解

    SLF4J配置应用

    ### SLF4J配置应用详解 #### 一、引言 在软件开发过程中,日志记录是一项非常重要的工作。良好的日志系统可以帮助开发者快速定位问题、优化程序性能以及监控应用程序的状态。SLF4J(Simple Logging Facade for ...

    slf4j日志框架的源代码分享

    SLF4J(Simple Logging Facade for Java)是Java中的一种日志门面(Logging Facade),它为各种日志框架提供了一个简单的统一接口,如Log4j、Java Util Logging、Logback等。通过SLF4J,开发者可以在运行时绑定任意...

    logback + slf4j web项目源码

    "Logback + SLF4J Web项目源码" 提示我们这是一个基于Logback和SLF4J的日志管理系统,用于web应用程序。Logback是Java平台上的一个日志框架,它是一个替代log4j的更高效、更灵活的工具。SLF4J(Simple Logging ...

    如何将应用的log4j替换成logback详解

    `logback-classic`是Logback的用户接口,`logback-core`是其核心库,而`log4j-over-slf4j`则允许将Log4j的日志调用桥接到SLF4J。 ```xml &lt;!-- logback日志配置开始 --&gt; &lt;groupId&gt;ch.qos.logback &lt;artifactId&gt;...

    spring+logback中间包1.6

    其中,logback-classic实现了SLF4J(Simple Logging Facade for Java)接口,使得我们能够方便地切换不同的日志实现,而logback-access则与Servlet容器集成,提供HTTP访问日志功能。 二、Spring MVC与Logback集成 ...

    Slf4j日志相关jar包

    **Slf4j日志框架详解** Slf4j(Simple Logging Facade for Java)是一个用于日志系统的简单 facade,它允许最终用户在部署他们的应用时使用他们希望的日志库。Slf4j提供了一个统一的API,使得开发人员能够在不更换...

    MyEclipse工程文件:SSH+druid+logback+jackson

    Logback是另一个由SLF4J(Simple Logging Facade for Java)项目的作者Ceki Gülcü创建的日志框架,它是对Log4j的改进版。Logback具有更高的性能和更低的内存消耗。在项目中,它被用来记录系统运行时的各种信息,...

    logbackーslf4j-配置文件实例 难得

    **Logback-SLF4J配置文件详解** 在Java开发中,日志管理是不可或缺的一部分,Logback和SLF4J(Simple Logging Facade for Java)是广泛使用的日志框架。SLF4J提供了一个接口层,允许开发者选择任何底层的日志实现,...

    slf4j使用手册

    ### SLF4J 使用手册详解 #### 一、SLF4J 概述 SLF4J(Simple Logging Facade for Java)是一个用于多种日志框架的简化接口或抽象层,旨在将日志的创建者与具体的日志实现进行解耦。通过这种方式,开发人员可以在...

    slf4j-nop-1.7.3.jar

    2. SLF4J-nop-1.7.3.jar详解: - **版本号**:1.7.3表示这是SLF4J NOP绑定的一个特定版本,1.7是主版本号,3是次版本号。这个版本可能包含了修复的bug、性能改进或新特性。 - **NOP实现**:当使用SLF4J-nop时,...

    logback-1.2.3&slf4j-1.7.25.rar

    《Java日志框架Logback与SLF4J详解》 在Java开发中,日志记录是不可或缺的一部分,它能够帮助开发者追踪程序运行状态,定位问题,优化性能。Logback和SLF4J(Simple Logging Facade for Java)是Java世界中广泛使用...

    hibernate3.3.1接口实现包 slf4j-log4j12-1.5.2

    SLF4J(Simple Logging Facade for Java)是一个为各种日志框架提供一个简单统一的API,例如Log4j、Java Util Logging、Logback等。它的目标是允许最终用户在部署时插入所需的日志框架。SLF4J-Log4j12-1.5.2是SLF4J...

    hibernate annotation+slf4j

    SLF4J(Simple Logging Facade for Java)是一个日志抽象层,为不同的日志实现(如log4j、logback)提供一个通用的接口。这样,开发者可以在不修改代码的情况下更换日志实现。 1. 引入依赖:在项目中引入SLF4J的API...

    logback配置详解

    logback-classic 是 log4j 的一个改良版本,同时它完整实现了 slf4j API,使你可以很方便地更换成其它日志系统如 log4j 或 JDK14 Logging。 在 logback 中,Logger 是日志的记录器,把它关联到应用的对应的 context...

    logback jar包和logback.xml配置文件打包下载 小白新手学Java

    在这里,我们关注的是SLF4J的API库`slf4j-api-1.7.26.jar`,以及Logback的两个核心组件`logback-core-1.2.3.jar`和`logback-classic-1.2.3.jar`,以及配置文件`logback.xml`。 首先,`slf4j-api-1.7.26.jar`是SLF4J...

    详解log4j-over-slf4j与slf4j-log4j12共存stack overflow异常分析

    例如,我们可以使用log4j-over-slf4j将SLF4J桥接到Log4j上,也可以使用slf4j-log4j12将SLF4J桥接到Log4j 1.2上。 log4j-over-slf4j和slf4j-log4j12是两个不同的桥接器,它们之间的桥接和绑定机制可能会导致堆栈溢出...

Global site tag (gtag.js) - Google Analytics