- 浏览: 984785 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
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]
下面来看这一句的具体含义:
//StaticLoggerBinder
//ContextInitializer
//JoranConfigurator
//JoranConfiguratorBase
//GenericConfigurator
//LoggerContext
//ch.qos.logback.classic.Logger
//如果无配置文件,则使用BasicConfigurator,简单的控制台输出
总结:
从上面可以看出logback与sfl4j的整合,实际上是通过实现类StaticLoggerBinder,LoggerFactory加载
StaticLoggerBinder,StaticLoggerBinder通过静态语句块来,初始化LoggerContext,而LoggerContext实现
的ILoggerFactory接口,从LoggerContext获取的Logger实际为ch.qos.logback.classic.Logger,
即org.slf4j.Logger的实现类。
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的实现类。
发表评论
-
一次服务器事故处理过程及教训
2017-02-24 18:50 1169java虚拟机内存查看相关 ... -
slf4j + Logback使用
2016-10-23 19:44 1381使用logback轻松管理日志: http://blog.cs ... -
slf4j + Log4j 详解
2016-10-23 19:40 1767Log4j初始化详解:http://donald-draper ... -
sfl4j与log4j使用
2016-10-23 11:24 2437slf4j-api、slf4j-log4j12以及log4j之 ... -
Log4j日志输出详解
2016-10-23 00:46 2857Log4j初始化详解:http://donald-draper ... -
Log4j初始化详解
2016-10-22 22:36 4009java中volatile关键字的含义:http://www. ... -
log4j的使用
2016-10-22 11:56 631Log4j使用教程:http://www.codeceo.co ... -
Spring集成log4j,日志初始化过程详解
2016-06-22 17:41 7781以前研究过slf4j-log4j的使用,但具体初始化过程不是很 ...
相关推荐
Logback 是 SLF4J 推荐的日志实现,它由 log4j 的创始人设计,提供了高速、灵活且可靠的日志记录功能。 使用 SLF4J 和 Logback 进行日志记录配置的主要目的是: 1. 为 Spring 的开发提供了一个更快速更广泛的入门...
SLF4J(Simple Logging Facade for Java)和Logback是Java开发中广泛使用的日志框架,它们提供了灵活的日志记录解决方案。SLF4J是一个接口层,它为各种日志框架提供了统一的抽象,而Logback是SLF4J的一个实现,用于...
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配置应用详解 #### 一、引言 在软件开发过程中,日志记录是一项非常重要的工作。良好的日志系统可以帮助开发者快速定位问题、优化程序性能以及监控应用程序的状态。SLF4J(Simple Logging Facade for ...
SLF4J(Simple Logging Facade for Java)是Java中的一种日志门面(Logging Facade),它为各种日志框架提供了一个简单的统一接口,如Log4j、Java Util Logging、Logback等。通过SLF4J,开发者可以在运行时绑定任意...
"Logback + SLF4J Web项目源码" 提示我们这是一个基于Logback和SLF4J的日志管理系统,用于web应用程序。Logback是Java平台上的一个日志框架,它是一个替代log4j的更高效、更灵活的工具。SLF4J(Simple Logging ...
其中,logback-classic实现了SLF4J(Simple Logging Facade for Java)接口,使得我们能够方便地切换不同的日志实现,而logback-access则与Servlet容器集成,提供HTTP访问日志功能。 二、Spring MVC与Logback集成 ...
**Slf4j日志框架详解** Slf4j(Simple Logging Facade for Java)是一个用于日志系统的简单 facade,它允许最终用户在部署他们的应用时使用他们希望的日志库。Slf4j提供了一个统一的API,使得开发人员能够在不更换...
`logback-classic`是Logback的用户接口,`logback-core`是其核心库,而`log4j-over-slf4j`则允许将Log4j的日志调用桥接到SLF4J。 ```xml <!-- logback日志配置开始 --> <groupId>ch.qos.logback <artifactId>...
Logback是另一个由SLF4J(Simple Logging Facade for Java)项目的作者Ceki Gülcü创建的日志框架,它是对Log4j的改进版。Logback具有更高的性能和更低的内存消耗。在项目中,它被用来记录系统运行时的各种信息,...
**Logback-SLF4J配置文件详解** 在Java开发中,日志管理是不可或缺的一部分,Logback和SLF4J(Simple Logging Facade for Java)是广泛使用的日志框架。SLF4J提供了一个接口层,允许开发者选择任何底层的日志实现,...
### SLF4J 使用手册详解 #### 一、SLF4J 概述 SLF4J(Simple Logging Facade for Java)是一个用于多种日志框架的简化接口或抽象层,旨在将日志的创建者与具体的日志实现进行解耦。通过这种方式,开发人员可以在...
2. SLF4J-nop-1.7.3.jar详解: - **版本号**:1.7.3表示这是SLF4J NOP绑定的一个特定版本,1.7是主版本号,3是次版本号。这个版本可能包含了修复的bug、性能改进或新特性。 - **NOP实现**:当使用SLF4J-nop时,...
《Java日志框架Logback与SLF4J详解》 在Java开发中,日志记录是不可或缺的一部分,它能够帮助开发者追踪程序运行状态,定位问题,优化性能。Logback和SLF4J(Simple Logging Facade for Java)是Java世界中广泛使用...
例如,我们可以使用log4j-over-slf4j将SLF4J桥接到Log4j上,也可以使用slf4j-log4j12将SLF4J桥接到Log4j 1.2上。 log4j-over-slf4j和slf4j-log4j12是两个不同的桥接器,它们之间的桥接和绑定机制可能会导致堆栈溢出...
SLF4J(Simple Logging Facade for Java)是一个为各种日志框架提供一个简单统一的API,例如Log4j、Java Util Logging、Logback等。它的目标是允许最终用户在部署时插入所需的日志框架。SLF4J-Log4j12-1.5.2是SLF4J...
SLF4J(Simple Logging Facade for Java)是一个日志抽象层,为不同的日志实现(如log4j、logback)提供一个通用的接口。这样,开发者可以在不修改代码的情况下更换日志实现。 1. 引入依赖:在项目中引入SLF4J的API...
logback-classic 是 log4j 的一个改良版本,同时它完整实现了 slf4j API,使你可以很方便地更换成其它日志系统如 log4j 或 JDK14 Logging。 在 logback 中,Logger 是日志的记录器,把它关联到应用的对应的 context...
在这里,我们关注的是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...