[logback] 01/02: Import Upstream version 1.1.2
Markus Koschany
apo at moszumanska.debian.org
Fri Apr 7 14:27:34 UTC 2017
This is an automated email from the git hooks/post-receive script.
apo pushed a commit to branch jessie
in repository logback.
commit 2aba0b0ea0d74b76461ff392ab420edcf1e5555a
Author: Markus Koschany <apo at debian.org>
Date: Fri Apr 7 16:20:11 2017 +0200
Import Upstream version 1.1.2
---
LICENSE.txt | 2 +-
docs/access.html | 375 ++-
docs/beagle/index.html | 3 -
docs/bugreport.html | 4 -
docs/cla.txt | 62 +-
docs/codes.html | 133 +-
docs/css/maven-base.css | 306 +--
docs/css/print.css | 14 +-
docs/css/screen.css | 36 +-
docs/demo.html | 4 -
docs/dependencies.html | 21 +-
docs/documentation.html | 7 +-
docs/download.html | 78 +-
docs/faq.html | 10 +-
docs/images/follow_us.png | Bin 16337 -> 0 bytes
docs/images/setup/remove_evaluator_template.jpg | Bin 57480 -> 0 bytes
docs/images/setup/remove_gen_src.jpg | Bin 68932 -> 0 bytes
docs/index.html | 6 -
docs/js/dsl.js | 2 +-
docs/js/jquery.cookies.2.2.0.js | 450 +++
docs/js/popup.js | 102 +
docs/license.html | 6 +-
docs/mailinglist.html | 4 -
docs/manual/appenders.html | 361 +--
docs/manual/appenders_ja.html | 2871 --------------------
docs/manual/architecture.html | 2 -
docs/manual/architecture_ja.html | 619 -----
docs/manual/configuration.html | 226 +-
docs/manual/configuration_ja.html | 1273 ---------
docs/manual/encoders.html | 2 -
docs/manual/encoders_ja.html | 175 --
docs/manual/filters.html | 22 +-
docs/manual/filters_ja.html | 818 ------
docs/manual/groovy.html | 7 +-
docs/manual/groovy_ja.html | 364 ---
docs/manual/index.html | 1 -
docs/manual/index_ja.html | 115 -
docs/manual/introduction.html | 5 +-
docs/manual/introduction_ja.html | 165 --
docs/manual/jmxConfig.html | 2 -
docs/manual/jmxConfig_ja.html | 290 --
docs/manual/layouts.html | 53 +-
docs/manual/layouts_ja.html | 1645 -----------
docs/manual/loggingSeparation.html | 8 +-
docs/manual/loggingSeparation_ja.html | 270 --
docs/manual/mdc.html | 17 +-
docs/manual/mdc_ja.html | 542 ----
docs/manual/menu.js | 14 -
docs/manual/menu_ja.js | 16 -
docs/manual/migrationFromLog4j.html | 2 -
docs/manual/migrationFromLog4j_ja.html | 157 --
docs/manual/onJoran.html | 9 +-
docs/manual/onJoran_ja.html | 433 ---
docs/manual/receivers.html | 16 +-
docs/manual/receivers_ja.html | 343 ---
docs/manual/usingSSL.html | 26 +-
docs/manual/usingSSL_ja.html | 811 ------
docs/news.html | 431 +--
docs/project-reports.html | 46 +-
docs/reasonsToSwitch.html | 4 -
docs/setup.html | 175 +-
docs/templates/creative.js | 2 +-
docs/templates/footer.js | 2 +-
docs/templates/left.js | 14 +-
docs/templates/right.js | 28 +-
docs/volunteer.html | 4 -
logback-access/pom.xml | 39 +-
.../ch/qos/logback/access/AccessConstants.java | 28 +-
.../java/ch/qos/logback/access/PatternLayout.java | 234 +-
.../qos/logback/access/PatternLayoutEncoder.java | 23 +-
.../logback/access/ViewStatusMessagesServlet.java | 52 +-
.../access/boolex/JaninoEventEvaluator.java | 87 +-
.../java/ch/qos/logback/access/db/DBAppender.java | 200 +-
.../ch/qos/logback/access/db/script/db2.sql | 0
.../ch/qos/logback/access/db/script/db2l.sql | 0
.../ch/qos/logback/access/db/script/hsqldb.sql | 0
.../qos/logback/access/db/script/msSQLServer.sql | 0
.../ch/qos/logback/access/db/script/mysql.sql | 0
.../ch/qos/logback/access/db/script/oracle.sql | 0
.../ch/qos/logback/access/db/script/postgresql.sql | 0
.../qos/logback/access/filter/CountingFilter.java | 107 +-
.../qos/logback/access/filter/PeriodicStats.java | 87 +-
.../qos/logback/access/filter/StatisticalView.java | 45 +-
.../logback/access/filter/StatisticalViewImpl.java | 206 +-
.../ch/qos/logback/access/filter/StatsByDay.java | 22 +-
.../ch/qos/logback/access/filter/StatsByHour.java | 22 +-
.../qos/logback/access/filter/StatsByMinute.java | 22 +-
.../ch/qos/logback/access/filter/StatsByMonth.java | 28 +-
.../ch/qos/logback/access/filter/StatsByWeek.java | 27 +-
.../qos/logback/access/html/DefaultCssBuilder.java | 104 +-
.../ch/qos/logback/access/html/HTMLLayout.java | 102 +-
.../ch/qos/logback/access/html/UrlCssBuilder.java | 34 +-
.../logback/access/jetty/JettyServerAdapter.java | 57 +-
.../qos/logback/access/jetty/RequestLogImpl.java | 399 ++-
.../logback/access/jetty/RequestLogRegistry.java | 22 +-
.../logback/access/joran/JoranConfigurator.java | 61 +-
.../access/joran/action/ConfigurationAction.java | 60 +-
.../access/joran/action/EvaluatorAction.java | 10 +-
.../AccessEventPreSerializationTransformer.java | 18 +-
.../ch/qos/logback/access/net/SMTPAppender.java | 99 +-
.../qos/logback/access/net/SSLSocketAppender.java | 27 +-
.../qos/logback/access/net/SimpleSocketServer.java | 89 +-
.../ch/qos/logback/access/net/SocketAppender.java | 28 +-
.../java/ch/qos/logback/access/net/SocketNode.java | 80 +-
.../ch/qos/logback/access/net/URLEvaluator.java | 76 +-
.../access/net/server/SSLServerSocketAppender.java | 24 +-
.../access/net/server/ServerSocketAppender.java | 24 +-
.../logback/access/pattern/AccessConverter.java | 80 +-
.../access/pattern/ContentLengthConverter.java | 19 +-
.../qos/logback/access/pattern/DateConverter.java | 71 +-
.../access/pattern/ElapsedSecondsConverter.java | 24 -
.../access/pattern/ElapsedTimeConverter.java | 9 +-
.../access/pattern/EnsureLineSeparation.java | 30 +-
.../access/pattern/FullRequestConverter.java | 36 +-
.../access/pattern/FullResponseConverter.java | 172 +-
.../access/pattern/LineSeparatorConverter.java | 10 +-
.../access/pattern/LocalIPAddressConverter.java | 23 +-
.../logback/access/pattern/LocalPortConverter.java | 10 +-
.../ch/qos/logback/access/pattern/NAConverter.java | 11 +-
.../access/pattern/QueryStringConverter.java | 23 -
.../access/pattern/RemoteHostConverter.java | 10 +-
.../access/pattern/RemoteIPAddressConverter.java | 9 +-
.../access/pattern/RemoteUserConverter.java | 20 +-
.../access/pattern/RequestAttributeConverter.java | 33 +-
.../access/pattern/RequestContentConverter.java | 10 +-
.../access/pattern/RequestCookieConverter.java | 33 +-
.../access/pattern/RequestHeaderConverter.java | 43 +-
.../access/pattern/RequestMethodConverter.java | 10 +-
.../access/pattern/RequestParameterConverter.java | 46 +-
.../access/pattern/RequestProtocolConverter.java | 10 +-
.../access/pattern/RequestURIConverter.java | 9 +-
.../access/pattern/RequestURLConverter.java | 9 +-
.../access/pattern/ResponseContentConverter.java | 10 +-
.../access/pattern/ResponseHeaderConverter.java | 53 +-
.../access/pattern/ServerNameConverter.java | 9 +-
.../logback/access/pattern/SessionIDConverter.java | 23 -
.../access/pattern/StatusCodeConverter.java | 9 +-
.../access/pattern/ThreadNameConverter.java | 24 -
.../ch/qos/logback/access/servlet/TeeFilter.java | 30 +-
.../access/servlet/TeeHttpServletRequest.java | 81 +-
.../access/servlet/TeeHttpServletResponse.java | 77 +-
.../access/servlet/TeeServletInputStream.java | 81 +-
.../access/servlet/TeeServletOutputStream.java | 103 +-
.../java/ch/qos/logback/access/servlet/Util.java | 32 +-
.../access/sift/AccessEventDiscriminator.java | 280 +-
.../access/sift/AppenderFactoryUsingJoran.java | 16 +-
.../ch/qos/logback/access/sift/SiftAction.java | 55 +-
.../qos/logback/access/sift/SiftingAppender.java | 36 +-
.../access/sift/SiftingJoranConfigurator.java | 74 +-
.../ch/qos/logback/access/spi/AccessContext.java | 118 +-
.../ch/qos/logback/access/spi/AccessEvent.java | 983 +++----
.../ch/qos/logback/access/spi/IAccessEvent.java | 123 +-
.../ch/qos/logback/access/spi/ServerAdapter.java | 13 +-
.../main/java/ch/qos/logback/access/spi/Util.java | 28 +-
.../ch/qos/logback/access/tomcat/LogbackValve.java | 572 ++--
.../logback/access/tomcat/TomcatServerAdapter.java | 51 +-
.../src/test/input/joran/tomcat/logback-access.xml | 11 -
.../ch/qos/logback/access/AccessTestConstants.java | 21 -
.../java/ch/qos/logback/access/AllAccessTest.java | 16 +-
.../java/ch/qos/logback/access/TeztConstants.java | 19 +
.../access/boolex/JaninoEventEvaluatorTest.java | 85 +-
.../ch/qos/logback/access/boolex/PackageTest.java | 4 +-
.../qos/logback/access/db/DBAppenderHSQLTest.java | 339 +--
.../access/db/DBAppenderHSQLTestFixture.java | 195 +-
.../access/db/DBAppenderIntegrationTest.java | 168 +-
.../java/ch/qos/logback/access/db/PackageTest.java | 6 +-
.../access/dummy/DummyAccessEventBuilder.java | 19 +-
.../ch/qos/logback/access/dummy/DummyRequest.java | 537 ++--
.../ch/qos/logback/access/dummy/DummyResponse.java | 227 +-
.../logback/access/dummy/DummyServerAdapter.java | 38 +-
.../access/dummy/DummyServletOutputStream.java | 42 -
.../ch/qos/logback/access/filter/PackageTest.java | 4 +-
.../qos/logback/access/filter/StatsByDayTest.java | 104 +-
.../qos/logback/access/jetty/JettyBasicTest.java | 154 +-
.../qos/logback/access/jetty/JettyFixtureBase.java | 129 +-
.../JettyFixtureWithListAndConsoleAppenders.java | 73 +-
.../ch/qos/logback/access/jetty/PackageTest.java | 6 +-
.../qos/logback/access/joran/ConditionalTest.java | 94 +-
.../access/joran/JoranConfiguratorTest.java | 72 +-
.../ch/qos/logback/access/joran/PackageTest.java | 6 +-
.../ch/qos/logback/access/net/NOPOutputStream.java | 10 +-
.../ch/qos/logback/access/net/PackageTest.java | 4 +-
.../logback/access/net/SerializationPerfTest.java | 146 +-
.../qos/logback/access/net/URLEvaluatorTest.java | 104 +-
.../qos/logback/access/pattern/ConverterTest.java | 333 +--
.../ch/qos/logback/access/pattern/PackageTest.java | 7 +-
.../ch/qos/logback/access/servlet/PackageTest.java | 4 +-
.../qos/logback/access/servlet/TeeFilterTest.java | 13 +-
.../access/servlet/TeeHttpServletResponseTest.java | 67 -
.../ch/qos/logback/access/sift/PackageTest.java | 6 +-
.../logback/access/sift/SiftingAppenderTest.java | 94 +-
.../access/spi/AccessEventSerializationTest.java | 117 +-
.../ch/qos/logback/access/spi/PackageTest.java | 4 +-
.../access/testUtil/NotifyingListAppender.java | 16 +-
.../logback/access/tomcat/LogbackValveTest.java | 97 -
.../src/test/resources/logback-asResource.xml | 11 -
logback-classic/osgi-build.xml | 24 +-
logback-classic/pom.xml | 142 +-
logback-classic/src/IBUNDLE-META-INF/MANIFEST.MF | 9 +-
.../classic/boolex/EvaluatorTemplate.groovy | 2 +-
.../logback/classic/gaffer/AppenderDelegate.groovy | 23 +-
.../classic/gaffer/AsyncAppenderDelegate.groovy | 30 +
.../classic/gaffer/ComponentDelegate.groovy | 9 +-
.../classic/gaffer/ConfigurationContributor.groovy | 2 +-
.../classic/gaffer/ConfigurationDelegate.groovy | 352 ++-
.../classic/gaffer/GafferConfigurator.groovy | 2 +-
.../qos/logback/classic/gaffer/NestedType.groovy | 4 +-
.../qos/logback/classic/gaffer/PropertyUtil.groovy | 104 +-
.../java/ch/qos/logback/classic/AsyncAppender.java | 54 +-
.../ch/qos/logback/classic/BasicConfigurator.java | 70 +-
.../ch/qos/logback/classic/ClassicConstants.java | 63 +-
.../main/java/ch/qos/logback/classic/Level.java | 481 ++--
.../main/java/ch/qos/logback/classic/Logger.java | 1525 +++++------
.../java/ch/qos/logback/classic/LoggerContext.java | 662 +++--
.../java/ch/qos/logback/classic/PatternLayout.java | 218 +-
.../logback/classic/ViewStatusMessagesServlet.java | 26 +-
.../logback/classic/boolex/GEventEvaluator.java | 104 +-
.../ch/qos/logback/classic/boolex/IEvaluator.java | 7 +-
.../classic/boolex/JaninoEventEvaluator.java | 224 +-
.../logback/classic/boolex/OnErrorEvaluator.java | 17 +-
.../logback/classic/boolex/OnMarkerEvaluator.java | 43 +-
.../java/ch/qos/logback/classic/db/DBAppender.java | 460 ++--
.../java/ch/qos/logback/classic/db/DBHelper.java | 40 +-
.../java/ch/qos/logback/classic/db/SQLBuilder.java | 78 +-
.../qos/logback/classic/db/names/ColumnName.java | 31 +-
.../logback/classic/db/names/DBNameResolver.java | 8 +-
.../classic/db/names/DefaultDBNameResolver.java | 14 +-
.../classic/db/names/SimpleDBNameResolver.java | 46 +-
.../ch/qos/logback/classic/db/names/TableName.java | 6 +-
.../ch/qos/logback/classic/db/script/db2.sql | 0
.../ch/qos/logback/classic/db/script/h2.sql | 0
.../ch/qos/logback/classic/db/script/hsqldb.sql | 0
.../ch/qos/logback/classic/db/script/mssql.sql | 0
.../ch/qos/logback/classic/db/script/mysql.sql | 0
.../ch/qos/logback/classic/db/script/oracle.sql | 0
.../qos/logback/classic/db/script/postgresql.sql | 0
.../ch/qos/logback/classic/db/script/sqllite.sql | 0
.../classic/db/script/sybaseSqlAnywhere.sql | 0
.../classic/encoder/PatternLayoutEncoder.java | 24 +-
.../ch/qos/logback/classic/filter/LevelFilter.java | 38 +-
.../logback/classic/filter/ThresholdFilter.java | 44 +-
.../ch/qos/logback/classic/gaffer/GafferUtil.java | 79 +-
.../classic/helpers/MDCInsertingServletFilter.java | 82 +-
.../logback/classic/html/DefaultCssBuilder.java | 65 +-
.../classic/html/DefaultThrowableRenderer.java | 73 +-
.../ch/qos/logback/classic/html/HTMLLayout.java | 180 +-
.../ch/qos/logback/classic/html/UrlCssBuilder.java | 33 +-
.../qos/logback/classic/jmx/JMXConfigurator.java | 439 +--
.../logback/classic/jmx/JMXConfiguratorMBean.java | 34 +-
.../java/ch/qos/logback/classic/jmx/MBeanUtil.java | 96 +-
.../logback/classic/joran/JoranConfigurator.java | 96 +-
.../classic/joran/ReconfigureOnChangeTask.java | 168 --
.../joran/ReconfigureOnChangeTaskListener.java | 12 -
.../classic/joran/action/ConfigurationAction.java | 182 +-
.../classic/joran/action/ConsolePluginAction.java | 68 +-
.../classic/joran/action/ContextNameAction.java | 27 +-
.../classic/joran/action/EvaluatorAction.java | 8 +-
.../classic/joran/action/InsertFromJNDIAction.java | 87 +-
.../joran/action/JMXConfiguratorAction.java | 91 +-
.../logback/classic/joran/action/LevelAction.java | 50 +-
.../logback/classic/joran/action/LoggerAction.java | 106 +-
.../joran/action/LoggerContextListenerAction.java | 82 +-
.../classic/joran/action/ReceiverAction.java | 83 +-
.../classic/joran/action/RootLoggerAction.java | 56 +-
.../java/ch/qos/logback/classic/jul/JULHelper.java | 93 +-
.../logback/classic/jul/LevelChangePropagator.java | 139 +-
.../ch/qos/logback/classic/layout/TTLLLayout.java | 61 -
.../ch/qos/logback/classic/log4j/XMLLayout.java | 272 +-
.../qos/logback/classic/net/JMSQueueAppender.java | 309 +--
.../ch/qos/logback/classic/net/JMSQueueSink.java | 185 +-
.../qos/logback/classic/net/JMSTopicAppender.java | 306 ++-
.../ch/qos/logback/classic/net/JMSTopicSink.java | 185 +-
.../LoggingEventPreSerializationTransformer.java | 27 +-
.../ch/qos/logback/classic/net/ReceiverBase.java | 114 +-
.../ch/qos/logback/classic/net/SMTPAppender.java | 174 +-
.../qos/logback/classic/net/SSLSocketAppender.java | 41 +-
.../qos/logback/classic/net/SSLSocketReceiver.java | 93 +-
.../logback/classic/net/SimpleSSLSocketServer.java | 71 +-
.../logback/classic/net/SimpleSocketServer.java | 368 +--
.../ch/qos/logback/classic/net/SocketAcceptor.java | 11 +-
.../ch/qos/logback/classic/net/SocketAppender.java | 40 +-
.../ch/qos/logback/classic/net/SocketNode.java | 155 +-
.../ch/qos/logback/classic/net/SocketReceiver.java | 315 +--
.../ch/qos/logback/classic/net/SyslogAppender.java | 271 +-
.../classic/net/server/RemoteAppenderClient.java | 27 +-
.../net/server/RemoteAppenderServerListener.java | 36 +-
.../net/server/RemoteAppenderServerRunner.java | 44 +-
.../net/server/RemoteAppenderStreamClient.java | 190 +-
.../net/server/SSLServerSocketAppender.java | 46 +-
.../net/server/SSLServerSocketReceiver.java | 70 +-
.../classic/net/server/ServerSocketAppender.java | 46 +-
.../classic/net/server/ServerSocketReceiver.java | 271 +-
.../qos/logback/classic/pattern/Abbreviator.java | 4 +-
.../classic/pattern/CallerDataConverter.java | 202 +-
.../classic/pattern/ClassNameOnlyAbbreviator.java | 22 +-
.../classic/pattern/ClassOfCallerConverter.java | 18 +-
.../logback/classic/pattern/ClassicConverter.java | 4 +-
.../classic/pattern/ContextNameConverter.java | 14 +-
.../qos/logback/classic/pattern/DateConverter.java | 74 +-
.../classic/pattern/EnsureExceptionHandling.java | 97 +-
.../pattern/ExtendedThrowableProxyConverter.java | 16 +-
.../classic/pattern/FileOfCallerConverter.java | 16 +-
.../logback/classic/pattern/LevelConverter.java | 8 +-
.../classic/pattern/LineOfCallerConverter.java | 16 +-
.../classic/pattern/LineSeparatorConverter.java | 8 +-
.../pattern/LocalSequenceNumberConverter.java | 12 +-
.../logback/classic/pattern/LoggerConverter.java | 8 +-
.../qos/logback/classic/pattern/MDCConverter.java | 96 +-
.../logback/classic/pattern/MarkerConverter.java | 18 +-
.../logback/classic/pattern/MessageConverter.java | 8 +-
.../classic/pattern/MethodOfCallerConverter.java | 16 +-
.../logback/classic/pattern/NamedConverter.java | 60 +-
.../pattern/NopThrowableInformationConverter.java | 12 +-
.../logback/classic/pattern/PropertyConverter.java | 42 +-
.../classic/pattern/RelativeTimeConverter.java | 26 +-
.../RootCauseFirstThrowableProxyConverter.java | 50 +-
.../classic/pattern/SyslogStartConverter.java | 153 +-
.../TargetLengthBasedClassNameAbbreviator.java | 194 +-
.../logback/classic/pattern/ThreadConverter.java | 8 +-
.../pattern/ThrowableHandlingConverter.java | 12 +-
.../classic/pattern/ThrowableProxyConverter.java | 306 +--
.../java/ch/qos/logback/classic/pattern/Util.java | 31 +-
.../color/HighlightingCompositeConverter.java | 27 +-
.../classic/selector/ContextJNDISelector.java | 264 +-
.../logback/classic/selector/ContextSelector.java | 20 +-
.../classic/selector/DefaultContextSelector.java | 58 +-
.../selector/servlet/ContextDetachingSCL.java | 64 +-
.../selector/servlet/LoggerContextFilter.java | 45 +-
.../classic/sift/AppenderFactoryUsingJoran.java | 15 +-
.../classic/sift/ContextBasedDiscriminator.java | 71 +-
.../sift/JNDIBasedContextDiscriminator.java | 80 +-
.../classic/sift/MDCBasedDiscriminator.java | 120 +-
.../ch/qos/logback/classic/sift/SiftAction.java | 52 +-
.../qos/logback/classic/sift/SiftingAppender.java | 33 +-
.../classic/sift/SiftingJoranConfigurator.java | 83 +-
.../ch/qos/logback/classic/spi/CallerData.java | 176 +-
.../logback/classic/spi/ClassPackagingData.java | 114 +-
.../ch/qos/logback/classic/spi/Configurator.java | 33 -
.../ch/qos/logback/classic/spi/EventArgUtil.java | 59 +-
.../ch/qos/logback/classic/spi/ILoggingEvent.java | 83 +-
.../qos/logback/classic/spi/IThrowableProxy.java | 19 +-
.../qos/logback/classic/spi/LoggerComparator.java | 24 +-
.../logback/classic/spi/LoggerContextAware.java | 22 +-
.../classic/spi/LoggerContextAwareBase.java | 53 +-
.../logback/classic/spi/LoggerContextListener.java | 27 +-
.../qos/logback/classic/spi/LoggerContextVO.java | 125 +-
.../qos/logback/classic/spi/LoggerRemoteView.java | 31 +-
.../ch/qos/logback/classic/spi/LoggingEvent.java | 621 ++---
.../ch/qos/logback/classic/spi/LoggingEventVO.java | 410 +--
.../classic/spi/PackagingDataCalculator.java | 396 +--
.../ch/qos/logback/classic/spi/PlatformInfo.java | 28 +-
.../java/ch/qos/logback/classic/spi/STEUtil.java | 76 +-
.../classic/spi/StackTraceElementProxy.java | 119 +-
.../ch/qos/logback/classic/spi/ThrowableProxy.java | 248 +-
.../logback/classic/spi/ThrowableProxyUtil.java | 271 +-
.../qos/logback/classic/spi/ThrowableProxyVO.java | 186 +-
.../qos/logback/classic/spi/TurboFilterList.java | 90 +-
.../classic/turbo/DuplicateMessageFilter.java | 97 +-
.../classic/turbo/DynamicThresholdFilter.java | 232 +-
.../qos/logback/classic/turbo/LRUMessageCache.java | 70 +-
.../ch/qos/logback/classic/turbo/MDCFilter.java | 44 +-
.../logback/classic/turbo/MDCValueLevelPair.java | 33 +-
.../ch/qos/logback/classic/turbo/MarkerFilter.java | 68 +-
.../qos/logback/classic/turbo/MatchingFilter.java | 40 +-
.../classic/turbo/ReconfigureOnChangeFilter.java | 356 +--
.../ch/qos/logback/classic/turbo/TurboFilter.java | 71 +-
.../logback/classic/util/ContextInitializer.java | 259 +-
.../classic/util/ContextSelectorStaticBinder.java | 129 +-
.../classic/util/CopyOnInheritThreadLocal.java | 26 +-
.../classic/util/DefaultNestedComponentRules.java | 24 +-
.../java/ch/qos/logback/classic/util/EnvUtil.java | 41 +-
.../java/ch/qos/logback/classic/util/JNDIUtil.java | 28 +-
.../classic/util/LevelToSyslogSeverity.java | 42 +-
.../logback/classic/util/LogbackMDCAdapter.java | 299 +-
.../qos/logback/classic/util/LoggerNameUtil.java | 70 +-
.../classic/util/StatusListenerConfigHelper.java | 64 +
.../java/org/slf4j/impl/StaticLoggerBinder.java | 144 +-
.../main/java/org/slf4j/impl/StaticMDCBinder.java | 40 +-
.../java/org/slf4j/impl/StaticMarkerBinder.java | 55 +-
.../gaffer/ConfigurationDelegateTest.groovy | 29 +-
.../classic/gaffer/GafferConfiguratorTest.groovy | 11 +-
.../logback/classic/gaffer/PropertyUtilTest.groovy | 2 +-
.../groovy/issues/logback811/LineNumTest.groovy | 2 +-
.../appenderRefWithNonAppenderAttachable.groovy | 30 -
.../src/test/input/gaffer/asyncAppender.groovy | 3 +-
.../src/test/input/gaffer/conversionRule.groovy | 13 -
.../test/input/gaffer/evaluatorWithMatcher.groovy | 13 -
.../src/test/input/gaffer/onTheFly.groovy | 13 -
.../test/input/gaffer/propertyCascading0.groovy | 13 -
.../test/input/gaffer/propertyCascading1.groovy | 13 -
.../test/input/gaffer/propertyCascading2.groovy | 13 -
.../test/input/gaffer/sift/noDiscriminator.groovy | 13 -
.../src/test/input/gaffer/sift/sample0.groovy | 13 -
.../src/test/input/gaffer/sift/sample1.groovy | 13 -
logback-classic/src/test/input/gaffer/smoke.groovy | 13 -
logback-classic/src/test/input/gaffer/x.groovy | 13 -
.../src/test/input/issue/logback-1159.xml | 30 -
.../src/test/input/joran/packagingDataDisabled.xml | 16 -
.../src/test/input/joran/packagingDataEnabled.xml | 16 -
.../input/joran/roct/inclusion/topByResource.xml | 8 -
.../test/input/joran/roct/inclusion/topLevel0.xml | 9 -
.../src/test/input/joran/roct/scan 1.groovy | 19 -
.../src/test/input/joran/roct/scan 1.xml | 9 -
.../src/test/input/joran/roct/scan_logback_474.xml | 14 -
.../depratedSizeAndTimeBasedFNATPWarning.xml | 26 -
.../src/test/input/joran/rolling/timeAndSize.xml | 11 +-
.../rolling/timeAndSizeWithoutIntegerToken.xml | 21 -
.../rolling/timeAndSizeWithoutMaxFileSize.xml | 23 -
.../rolling/totalSizeCapSmallerThanMaxFileSize.xml | 22 -
logback-classic/src/test/input/joran/scan1.xml | 10 +
.../src/test/input/joran/sift/fileAppender.xml | 26 -
.../src/test/input/joran/sift/lbclassic203.xml | 25 +
.../src/test/input/joran/sift/logback_416.xml | 25 -
logback-classic/src/test/input/joran/unique.xml | 4 +-
.../src/test/input/joran/valueOfConvention.xml | 26 -
logback-classic/src/test/input/listAppender.xml | 17 -
.../{joran/roct => turbo}/inclusion/inner0.xml | 0
.../test/input/turbo/inclusion/topByResource.xml | 8 +
.../src/test/input/turbo/inclusion/topLevel0.xml | 9 +
logback-classic/src/test/input/turbo/scan 1.groovy | 6 +
logback-classic/src/test/input/turbo/scan 1.xml | 9 +
.../src/test/input/turbo/scan_logback_474.xml | 14 +
.../test/input/{joran/roct => turbo}/scan_perf.xml | 0
.../ch/qos/logback/classic/AllClassicTest.java | 28 +-
.../ch/qos/logback/classic/AsyncAppenderTest.java | 120 +-
.../qos/logback/classic/ClassicTestConstants.java | 21 +-
.../src/test/java/ch/qos/logback/classic/Foo.java | 23 +-
.../test/java/ch/qos/logback/classic/HLogger.java | 748 ++---
.../ch/qos/logback/classic/HLoggerContext.java | 165 +-
.../classic/LoggerContextConcurrentResetTest.java | 104 -
.../logback/classic/LoggerContextDeadlockTest.java | 70 +-
.../qos/logback/classic/LoggerContextPerfTest.java | 116 +-
.../ch/qos/logback/classic/LoggerContextTest.java | 458 ++--
.../classic/LoggerMessageFormattingTest.java | 106 +-
.../ch/qos/logback/classic/LoggerPerfTest.java | 418 +--
.../logback/classic/LoggerSerializationTest.java | 250 +-
.../java/ch/qos/logback/classic/LoggerTest.java | 382 +--
.../ch/qos/logback/classic/LoggerTestHelper.java | 24 +-
.../test/java/ch/qos/logback/classic/MDCTest.java | 42 +-
.../java/ch/qos/logback/classic/MDCTestThread.java | 44 +-
.../java/ch/qos/logback/classic/PackageTest.java | 11 +-
.../ch/qos/logback/classic/PatternLayoutTest.java | 363 +--
.../classic/ScenarioBasedLoggerContextTest.java | 140 +-
.../classic/TurboFilteringInLoggerTest.java | 290 +-
.../classic/boolex/ConditionalWithoutJanino.java | 51 +-
.../classic/boolex/GEventEvaluatorTest.java | 264 +-
.../classic/boolex/JaninoEventEvaluatorTest.java | 450 +--
.../classic/boolex/OnMarkerEvaluatorTest.java | 73 +-
.../ch/qos/logback/classic/boolex/PackageTest.java | 4 +-
.../ch/qos/logback/classic/control/CLCTest.java | 47 +-
.../qos/logback/classic/control/ControlLogger.java | 302 +-
.../classic/control/ControlLoggerContext.java | 120 +-
.../qos/logback/classic/control/CreateLogger.java | 23 +-
.../qos/logback/classic/control/PackageTest.java | 3 +-
.../ch/qos/logback/classic/control/Scenario.java | 28 +-
.../logback/classic/control/ScenarioAction.java | 2 +-
.../qos/logback/classic/control/ScenarioMaker.java | 133 +-
.../classic/control/ScenarioRandomUtil.java | 191 +-
.../ch/qos/logback/classic/control/SetLevel.java | 33 +-
.../java/ch/qos/logback/classic/corpus/Corpus.java | 123 +-
.../ch/qos/logback/classic/corpus/CorpusModel.java | 499 ++--
.../logback/classic/corpus/ExceptionBuilder.java | 50 +-
.../qos/logback/classic/corpus/LogStatement.java | 30 +-
.../classic/corpus/MessageArgumentTuple.java | 22 +-
.../ch/qos/logback/classic/corpus/RandomUtil.java | 45 +-
.../qos/logback/classic/corpus/TextFileUtil.java | 69 +-
.../logback/classic/corpusTest/RandomUtilTest.java | 66 +-
.../classic/corpusTest/TextFileUtilTest.java | 33 +-
.../qos/logback/classic/db/DBAppenderH2Test.java | 326 +--
.../classic/db/DBAppenderH2TestFixture.java | 221 +-
.../qos/logback/classic/db/DBAppenderHSQLTest.java | 317 +--
.../classic/db/DBAppenderHSQLTestFixture.java | 280 +-
.../classic/db/DBAppenderIntegrationTest.java | 398 +--
.../ch/qos/logback/classic/db/PackageTest.java | 7 +-
.../ch/qos/logback/classic/db/SQLBuilderTest.java | 177 +-
.../db/names/DefaultDBNameResolverTest.java | 70 +-
.../qos/logback/classic/db/names/PackageTest.java | 5 +-
.../classic/db/names/SimpleDBNameResolverTest.java | 231 +-
.../encoder/LayoutInsteadOfEncoderTest.java | 53 +-
.../qos/logback/classic/encoder/PackageTest.java | 4 +-
.../classic/encoder/PatternLayoutEncoderTest.java | 78 +-
.../qos/logback/classic/html/HTMLLayoutTest.java | 388 +--
.../ch/qos/logback/classic/html/PackageTest.java | 2 +-
.../logback/classic/html/XHTMLEntityResolver.java | 51 +-
.../logback/classic/issue/DarioCampagna/Main.java | 28 +-
.../ch/qos/logback/classic/issue/LBCORE63.java | 120 +-
.../ch/qos/logback/classic/issue/PackageTest.java | 6 +-
.../issue/lbclassic135/LoggingRunnable.java | 45 +-
.../lbclassic135/LoggingToFileThroughput.java | 133 +-
.../issue/lbclassic135/lbclassic139/Accessor.java | 43 +-
.../lbclassic139/LB139_DeadlockTest.java | 65 +-
.../lbclassic135/lbclassic139/PackageTest.java | 23 +
.../issue/lbclassic135/lbclassic139/Worker.java | 85 +-
.../lbclassic180/HtmlEscapedMessageConverter.java | 8 +-
.../logback/classic/issue/lbclassic180/Main.java | 30 +-
.../issue/lbclassic203/ConcurrentSiftingTest.java | 61 +
.../lbclassic203/InstanceCountingAppender.java | 30 +
.../classic/issue/lbclassic203/PackageTest.java | 23 +
.../classic/issue/lbclassic323/Barebones.java | 43 +-
.../logback/classic/issue/lbclassic323/Simple.java | 37 +-
.../logback/classic/issue/lbclassic330/Main.java | 30 +-
.../lbclassic36/DateFormatOriginal_tzest.java | 410 +--
.../issue/lbclassic36/DateFormatPerf_Tapp.java | 64 +-
...DateFormattingThreadedThroughputCalculator.java | 44 +-
.../SelectiveDateFormattingRunnable.java | 118 +-
.../logback/classic/issue/lbcore211/Lbcore211.java | 32 +-
.../logback/classic/issue/lbcore224/Reduce.java | 248 +-
.../logback/classic/issue/lbcore243/Common.java | 6 +-
.../lbcore243/PerformanceComparatorLog4j.java | 69 +-
.../lbcore243/PerformanceComparatorLogback.java | 71 +-
.../qos/logback/classic/issue/lbcore26/Main.java | 25 +-
.../qos/logback/classic/issue/lbcore_155/Main.java | 26 +-
.../logback/classic/issue/lbcore_155/OThread.java | 48 +-
.../classic/issue/logback1159/LogbackListener.java | 37 -
.../issue/logback1159/LogbackListenerTest.java | 66 -
.../classic/issue/logback1159/LoggingError.java | 16 -
.../issue/logback416/ConcurrentSiftingTest.java | 62 -
.../issue/logback416/InstanceCountingAppender.java | 32 -
.../classic/issue/logback416/PackageTest.java | 23 -
.../classic/issue/logback474/LoggingAppender.java | 18 +-
.../logback/classic/jmx/JMXConfiguratorTest.java | 244 +-
.../ch/qos/logback/classic/jmx/PackageTest.java | 7 +-
.../logback/classic/joran/EvaluatorJoranTest.java | 139 +-
.../classic/joran/JoranConfiguratorTest.java | 767 +++---
.../ch/qos/logback/classic/joran/PackageTest.java | 5 +-
.../classic/joran/ReconfigureOnChangeTaskTest.java | 472 ----
.../classic/joran/conditional/ConditionalTest.java | 214 +-
.../classic/joran/conditional/PackageTest.java | 5 +-
.../classic/jul/LevelChangePropagatorTest.java | 138 +-
.../ch/qos/logback/classic/jul/PackageTest.java | 4 +-
.../qos/logback/classic/layout/TTLLLayoutTest.java | 33 -
.../qos/logback/classic/log4j/XMLLayoutTest.java | 209 --
.../ch/qos/logback/classic/multiJVM/Checker.java | 99 +-
.../logback/classic/multiJVM/FileAppenderPerf.java | 108 +-
.../logback/classic/multiJVM/LoggingThread.java | 49 +-
.../classic/multiJVM/SafeModeFileAppender.java | 116 +-
.../multiJVM/SafeModeRollingFileAppender.java | 143 +-
.../logback/classic/net/CounterBasedEvaluator.java | 74 +-
.../classic/net/DilutedSMTPAppenderTest.java | 170 +-
.../classic/net/ExternalMockSocketServer.java | 118 +-
.../logback/classic/net/JMSQueueAppenderTest.java | 212 +-
.../classic/net/JMSQueueAppenderTestApp.java | 74 +-
.../logback/classic/net/JMSTopicAppenderTest.java | 388 +--
.../classic/net/JMSTopicAppenderTestApp.java | 75 +-
.../qos/logback/classic/net/NOPOutputStream.java | 33 +-
.../ch/qos/logback/classic/net/PackageTest.java | 8 +-
.../classic/net/SMTPAppender_GreenTest.java | 610 ++---
.../classic/net/SMTPAppender_SubethaSMTPTest.java | 619 ++---
.../logback/classic/net/SSLSocketReceiverTest.java | 37 +-
.../logback/classic/net/SerializationPerfTest.java | 336 +--
.../classic/net/SocketAppenderMessageLossTest.java | 158 +-
.../java/ch/qos/logback/classic/net/SocketMin.java | 152 +-
.../logback/classic/net/SocketReceiverTest.java | 414 +--
.../logback/classic/net/SyslogAppenderTest.java | 417 ++-
.../qos/logback/classic/net/mock/MockAppender.java | 44 +-
.../classic/net/mock/MockObjectMessage.java | 447 +--
.../ch/qos/logback/classic/net/mock/MockQueue.java | 20 +-
.../classic/net/mock/MockQueueConnection.java | 127 +-
.../net/mock/MockQueueConnectionFactory.java | 32 +-
.../logback/classic/net/mock/MockQueueSender.java | 131 +-
.../logback/classic/net/mock/MockQueueSession.java | 200 +-
.../logback/classic/net/mock/MockSyslogServer.java | 88 +-
.../ch/qos/logback/classic/net/mock/MockTopic.java | 20 +-
.../classic/net/mock/MockTopicConnection.java | 127 +-
.../net/mock/MockTopicConnectionFactory.java | 32 +-
.../classic/net/mock/MockTopicPublisher.java | 214 +-
.../logback/classic/net/mock/MockTopicSession.java | 311 +--
.../server/InstrumentedServerSocketReceiver.java | 114 +-
.../classic/net/server/MockSSLConfiguration.java | 28 +-
.../net/server/MockSSLParametersConfiguration.java | 24 +-
.../net/server/RemoteAppenderStreamClientTest.java | 99 +-
.../net/server/SSLServerSocketReceiverTest.java | 47 +-
.../server/ServerSocketReceiverFunctionalTest.java | 123 +-
.../net/server/ServerSocketReceiverTest.java | 122 +-
.../classic/net/testObjectBuilders/Builder.java | 10 +-
.../LoggingEventBuilderInContext.java | 28 +-
.../LoggingEventWithParametersBuilder.java | 42 +-
.../net/testObjectBuilders/MinimalSerBuilder.java | 21 +-
.../TrivialLoggingEventBuilder.java | 26 +-
.../TrivialLoggingEventVOBuilder.java | 12 +-
.../qos/logback/classic/pattern/ConverterTest.java | 672 +++--
.../ExtendedThrowableProxyConverterTest.java | 137 +-
.../logback/classic/pattern/MDCConverterTest.java | 80 +-
.../classic/pattern/MarkerConverterTest.java | 125 +-
.../qos/logback/classic/pattern/PackageTest.java | 9 +-
.../RootCauseFirstThrowableProxyConverterTest.java | 151 +-
.../classic/pattern/SyslogStartConverterTest.java | 194 +-
.../TargetLengthBasedClassNameAbbreviatorTest.java | 234 +-
.../pattern/ThrowableProxyConverterTest.java | 318 +--
.../qos/logback/classic/rolling/PackageTest.java | 4 +-
.../TimeBasedRollingWithConfigFileTest.java | 333 +--
.../logback/classic/rolling/UniqueFileTest.java | 60 +-
.../classic/selector/ContextDetachingSCLTest.java | 117 +-
.../classic/selector/ContextJNDISelectorTest.java | 118 +-
.../qos/logback/classic/selector/PackageTest.java | 6 +-
.../classic/sift/MDCBasedDiscriminatorTest.java | 73 +-
.../ch/qos/logback/classic/sift/PackageTest.java | 6 +-
.../logback/classic/sift/SiftingAppenderTest.java | 586 ++--
.../logback/classic/spi/BasicContextListener.java | 83 +-
.../qos/logback/classic/spi/BogusClassLoader.java | 41 +-
.../ch/qos/logback/classic/spi/CPDCSpecial.java | 8 +-
.../ch/qos/logback/classic/spi/CallerDataTest.java | 49 +-
.../logback/classic/spi/ContextListenerTest.java | 94 +-
.../logback/classic/spi/DummyThrowableProxy.java | 97 +-
.../logback/classic/spi/LocalFirstClassLoader.java | 87 +-
.../logback/classic/spi/LoggerComparatorTest.java | 51 +-
.../spi/LoggingEventSerializationPerfTest.java | 159 +-
.../classic/spi/LoggingEventSerializationTest.java | 343 +--
.../qos/logback/classic/spi/LoggingEventTest.java | 98 +-
.../ch/qos/logback/classic/spi/LuckyCharms.java | 22 +-
.../ch/qos/logback/classic/spi/PackageTest.java | 10 +-
.../classic/spi/PackagingDataCalculatorTest.java | 168 +-
.../qos/logback/classic/spi/PubLoggingEventVO.java | 349 +--
.../logback/classic/spi/ThrowableProxyTest.java | 270 +-
.../classic/spi/special/CPDCSpecialImpl.java | 45 +-
.../logback/classic/testUtil/SampleConverter.java | 14 +-
.../classic/turbo/DebugUsersTurboFilter.java | 44 +-
.../classic/turbo/DuplicateMessageFilterTest.java | 110 +-
.../logback/classic/turbo/LRUMessageCacheTest.java | 38 +-
.../logback/classic/turbo/MarkerFilterTest.java | 96 +-
.../qos/logback/classic/turbo/NOPTurboFilter.java | 13 +-
.../ch/qos/logback/classic/turbo/PackageTest.java | 5 +-
.../classic/turbo/ReconfigureOnChangeTest.java | 664 ++---
.../qos/logback/classic/turbo/ReconfigurePerf.java | 99 +-
.../ch/qos/logback/classic/turbo/lru/Event.java | 30 +-
.../ch/qos/logback/classic/turbo/lru/LRUCache.java | 40 +-
.../logback/classic/turbo/lru/LRUCacheTest.java | 178 +-
.../qos/logback/classic/turbo/lru/Simulator.java | 111 +-
.../ch/qos/logback/classic/turbo/lru/T_Entry.java | 49 +-
.../qos/logback/classic/turbo/lru/T_LRUCache.java | 106 +-
.../qos/logback/classic/turbo/lru/X_LRUCache.java | 40 +-
.../util/ContextInitializerAutoConfigTest.java | 70 +-
.../classic/util/ContextInitializerTest.java | 301 +-
.../util/InitializationIntegrationTest.java | 18 +-
.../classic/util/LevelToSyslogSeverityTest.java | 33 +-
.../classic/util/LogbackMDCAdapterTest.java | 393 ++-
.../logback/classic/util/LoggerNameUtilTest.java | 153 +-
.../qos/logback/classic/util/MockConfigurator.java | 27 -
.../logback/classic/util/MockInitialContext.java | 24 +-
.../classic/util/MockInitialContextFactory.java | 46 +-
.../ch/qos/logback/classic/util/PackageTest.java | 7 +-
.../ch/qos/logback/classic/util/TestHelper.java | 81 -
.../ch/qos/logback/classic/util/TeztHelper.java | 81 +
.../src/test/java/integrator/Activator.java | 61 +-
.../src/test/java/org/dummy/DummyLBAppender.java | 40 +-
.../src/test/java/org/dummy/Log4jInvocation.java | 111 +-
.../test/java/org/slf4j/LoggerFactoryFriend.java | 8 +-
.../org/slf4j/impl/InitializationOutputTest.java | 62 +-
.../impl/MultithreadedInitializationTest.java | 106 -
.../src/test/java/org/slf4j/impl/PackageTest.java | 4 +-
.../slf4j/impl/RecursiveInitializationTest.java | 54 +-
.../java/org/slf4j/impl/RecursiveLBAppender.java | 56 +-
.../org/slf4j/impl/StaticLoggerBinderFriend.java | 10 +-
.../test/java/org/slf4j/test_osgi/BundleTest.java | 52 +-
.../slf4j/test_osgi/CheckingBundleListener.java | 51 +-
.../test/java/org/slf4j/test_osgi/FelixHost.java | 151 +-
.../slf4j/test_osgi/FrameworkErrorListener.java | 49 +-
...ERVICES_ch_qos_logback_classic_spi_Configurator | 1 -
...ISABLED-ch.qos.logback.classic.spi.Configurator | 1 -
logback-classic/src/test/resources/README.txt | 2 +-
.../src/test/resources/recursiveInit.xml | 2 +-
logback-classic/src/test/resources/test.groovy | 13 -
logback-core/pom.xml | 55 +-
.../main/java/ch/qos/logback/core/Appender.java | 39 +-
.../java/ch/qos/logback/core/AppenderBase.java | 163 +-
.../ch/qos/logback/core/AsyncAppenderBase.java | 427 ++-
.../ch/qos/logback/core/BasicStatusManager.java | 182 +-
.../java/ch/qos/logback/core/ConsoleAppender.java | 132 +-
.../src/main/java/ch/qos/logback/core/Context.java | 210 +-
.../main/java/ch/qos/logback/core/ContextBase.java | 395 ++-
.../java/ch/qos/logback/core/CoreConstants.java | 344 ++-
.../java/ch/qos/logback/core/FileAppender.java | 400 ++-
.../src/main/java/ch/qos/logback/core/Layout.java | 98 +-
.../main/java/ch/qos/logback/core/LayoutBase.java | 130 +-
.../java/ch/qos/logback/core/LifeCycleManager.java | 51 +-
.../java/ch/qos/logback/core/LogbackException.java | 21 +-
.../ch/qos/logback/core/OutputStreamAppender.java | 367 +--
.../ch/qos/logback/core/PropertyDefinerBase.java | 8 +-
.../logback/core/UnsynchronizedAppenderBase.java | 170 +-
.../logback/core/boolex/EvaluationException.java | 22 +-
.../ch/qos/logback/core/boolex/EventEvaluator.java | 56 +-
.../logback/core/boolex/EventEvaluatorBase.java | 49 +-
.../core/boolex/JaninoEventEvaluatorBase.java | 104 +-
.../java/ch/qos/logback/core/boolex/Matcher.java | 174 +-
.../core/db/BindDataSourceToJNDIAction.java | 112 +-
.../ch/qos/logback/core/db/ConnectionSource.java | 56 +-
.../qos/logback/core/db/ConnectionSourceBase.java | 203 +-
.../ch/qos/logback/core/db/DBAppenderBase.java | 243 +-
.../main/java/ch/qos/logback/core/db/DBHelper.java | 34 +-
.../core/db/DataSourceConnectionSource.java | 65 +-
.../core/db/DriverManagerConnectionSource.java | 114 +-
.../qos/logback/core/db/JNDIConnectionSource.java | 116 +-
.../ch/qos/logback/core/db/dialect/DBUtil.java | 218 +-
.../ch/qos/logback/core/db/dialect/H2Dialect.java | 12 +-
.../qos/logback/core/db/dialect/HSQLDBDialect.java | 12 +-
.../qos/logback/core/db/dialect/MsSQLDialect.java | 16 +-
.../qos/logback/core/db/dialect/MySQLDialect.java | 12 +-
.../qos/logback/core/db/dialect/OracleDialect.java | 10 +-
.../logback/core/db/dialect/PostgreSQLDialect.java | 14 +-
.../ch/qos/logback/core/db/dialect/SQLDialect.java | 6 +-
.../logback/core/db/dialect/SQLDialectCode.java | 12 +-
.../qos/logback/core/db/dialect/SQLiteDialect.java | 11 +-
.../core/db/dialect/SybaseSqlAnywhereDialect.java | 26 +-
.../ch/qos/logback/core/encoder/ByteArrayUtil.java | 84 +-
.../ch/qos/logback/core/encoder/EchoEncoder.java | 40 +-
.../java/ch/qos/logback/core/encoder/Encoder.java | 58 +-
.../ch/qos/logback/core/encoder/EncoderBase.java | 41 +-
.../core/encoder/EventObjectInputStream.java | 217 +-
.../core/encoder/LayoutWrappingEncoder.java | 272 +-
.../core/encoder/NonClosableInputStream.java | 26 +-
.../logback/core/encoder/ObjectStreamEncoder.java | 113 +-
.../logback/core/filter/AbstractMatcherFilter.java | 38 +-
.../qos/logback/core/filter/EvaluatorFilter.java | 62 +-
.../java/ch/qos/logback/core/filter/Filter.java | 58 +-
.../ch/qos/logback/core/helpers/CyclicBuffer.java | 272 +-
.../ch/qos/logback/core/helpers/NOPAppender.java | 8 +-
.../core/helpers/ThrowableToStringArray.java | 97 +-
.../ch/qos/logback/core/helpers/Transform.java | 173 +-
.../logback/core/hook/DelayingShutdownHook.java | 59 -
.../ch/qos/logback/core/hook/ShutdownHook.java | 24 -
.../ch/qos/logback/core/hook/ShutdownHookBase.java | 42 -
.../java/ch/qos/logback/core/hook/package.html | 17 -
.../java/ch/qos/logback/core/html/CssBuilder.java | 6 +-
.../ch/qos/logback/core/html/HTMLLayoutBase.java | 427 +--
.../qos/logback/core/html/IThrowableRenderer.java | 9 +-
.../logback/core/html/NOPThrowableRenderer.java | 9 +-
.../logback/core/joran/GenericConfigurator.java | 236 +-
.../logback/core/joran/JoranConfiguratorBase.java | 121 +-
.../joran/action/AbstractEventEvaluatorAction.java | 157 +-
.../ch/qos/logback/core/joran/action/Action.java | 101 +-
.../qos/logback/core/joran/action/ActionConst.java | 32 +-
.../qos/logback/core/joran/action/ActionUtil.java | 87 +-
.../logback/core/joran/action/AppenderAction.java | 151 +-
.../core/joran/action/AppenderRefAction.java | 82 +-
.../core/joran/action/ContextPropertyAction.java | 17 +-
.../core/joran/action/ConversionRuleAction.java | 99 +-
.../core/joran/action/DefinePropertyAction.java | 140 +-
.../core/joran/action/IADataForBasicProperty.java | 20 +-
.../joran/action/IADataForComplexProperty.java | 59 +-
.../logback/core/joran/action/ImplicitAction.java | 30 +-
.../logback/core/joran/action/IncludeAction.java | 345 +--
.../qos/logback/core/joran/action/NOPAction.java | 12 +-
.../core/joran/action/NestedBasicPropertyIA.java | 133 +-
.../core/joran/action/NestedComplexPropertyIA.java | 273 +-
.../logback/core/joran/action/NewRuleAction.java | 82 +-
.../qos/logback/core/joran/action/ParamAction.java | 76 +-
.../logback/core/joran/action/PropertyAction.java | 191 +-
.../core/joran/action/ShutdownHookAction.java | 88 -
.../core/joran/action/StatusListenerAction.java | 89 +-
.../logback/core/joran/action/TimestampAction.java | 80 +-
.../logback/core/joran/conditional/Condition.java | 4 +-
.../logback/core/joran/conditional/ElseAction.java | 14 +-
.../logback/core/joran/conditional/IfAction.java | 217 +-
.../conditional/PropertyEvalScriptBuilder.java | 46 +-
.../conditional/PropertyWrapperForScripts.java | 62 +-
.../logback/core/joran/conditional/ThenAction.java | 12 +-
.../joran/conditional/ThenOrElseActionBase.java | 96 +-
.../ch/qos/logback/core/joran/event/BodyEvent.java | 58 +-
.../ch/qos/logback/core/joran/event/EndEvent.java | 18 +-
.../logback/core/joran/event/InPlayListener.java | 7 +-
.../ch/qos/logback/core/joran/event/SaxEvent.java | 58 +-
.../logback/core/joran/event/SaxEventRecorder.java | 335 +--
.../qos/logback/core/joran/event/StartEvent.java | 50 +-
.../logback/core/joran/event/stax/BodyEvent.java | 45 +-
.../logback/core/joran/event/stax/EndEvent.java | 28 +-
.../logback/core/joran/event/stax/StartEvent.java | 81 +-
.../logback/core/joran/event/stax/StaxEvent.java | 38 +-
.../core/joran/event/stax/StaxEventRecorder.java | 149 +-
.../qos/logback/core/joran/node/ComponentNode.java | 16 +-
.../logback/core/joran/spi/ActionException.java | 16 +-
.../core/joran/spi/ConfigurationWatchList.java | 119 +-
.../qos/logback/core/joran/spi/ConsoleTarget.java | 123 +-
.../qos/logback/core/joran/spi/DefaultClass.java | 4 +-
.../joran/spi/DefaultNestedComponentRegistry.java | 44 +-
.../ch/qos/logback/core/joran/spi/ElementPath.java | 187 +-
.../logback/core/joran/spi/ElementSelector.java | 258 +-
.../ch/qos/logback/core/joran/spi/EventPlayer.java | 84 +-
.../core/joran/spi/HostClassAndPropertyDouble.java | 85 +-
.../core/joran/spi/InterpretationContext.java | 287 +-
.../ch/qos/logback/core/joran/spi/Interpreter.java | 475 ++--
.../qos/logback/core/joran/spi/JoranException.java | 18 +-
.../ch/qos/logback/core/joran/spi/NoAutoStart.java | 2 +-
.../logback/core/joran/spi/NoAutoStartUtil.java | 30 +-
.../ch/qos/logback/core/joran/spi/RuleStore.java | 47 +-
.../logback/core/joran/spi/SimpleRuleStore.java | 295 +-
.../ch/qos/logback/core/joran/spi/XMLUtil.java | 17 +-
.../joran/util/ConfigurationWatchListUtil.java | 123 +-
.../logback/core/joran/util/PropertySetter.java | 754 ++---
.../core/joran/util/StringToObjectConverter.java | 185 +-
.../core/joran/util/beans/BeanDescription.java | 71 -
.../joran/util/beans/BeanDescriptionCache.java | 53 -
.../joran/util/beans/BeanDescriptionFactory.java | 69 -
.../logback/core/joran/util/beans/BeanUtil.java | 136 -
.../ch/qos/logback/core/layout/EchoLayout.java | 8 +-
.../core/net/AbstractSSLSocketAppender.java | 101 +-
.../logback/core/net/AbstractSocketAppender.java | 732 ++---
.../logback/core/net/AutoFlushingObjectWriter.java | 60 -
.../logback/core/net/DefaultSocketConnector.java | 168 +-
.../ch/qos/logback/core/net/JMSAppenderBase.java | 274 +-
.../qos/logback/core/net/LoginAuthenticator.java | 24 +-
.../java/ch/qos/logback/core/net/ObjectWriter.java | 33 -
.../qos/logback/core/net/ObjectWriterFactory.java | 39 -
.../java/ch/qos/logback/core/net/QueueFactory.java | 39 -
.../ch/qos/logback/core/net/SMTPAppenderBase.java | 1115 ++++----
.../ch/qos/logback/core/net/SocketConnector.java | 68 +-
.../qos/logback/core/net/SyslogAppenderBase.java | 494 ++--
.../ch/qos/logback/core/net/SyslogConstants.java | 146 +-
.../qos/logback/core/net/SyslogOutputStream.java | 104 +-
.../net/server/AbstractServerSocketAppender.java | 351 +--
.../ch/qos/logback/core/net/server/Client.java | 36 +-
.../qos/logback/core/net/server/ClientVisitor.java | 6 +-
.../core/net/server/ConcurrentServerRunner.java | 332 +--
.../core/net/server/RemoteReceiverClient.java | 35 +-
.../net/server/RemoteReceiverServerListener.java | 36 +-
.../net/server/RemoteReceiverServerRunner.java | 55 +-
.../net/server/RemoteReceiverStreamClient.java | 193 +-
.../net/server/SSLServerSocketAppenderBase.java | 83 +-
.../logback/core/net/server/ServerListener.java | 62 +-
.../qos/logback/core/net/server/ServerRunner.java | 44 +-
.../core/net/server/ServerSocketListener.java | 105 +-
.../ssl/ConfigurableSSLServerSocketFactory.java | 88 +-
.../core/net/ssl/ConfigurableSSLSocketFactory.java | 108 +-
.../core/net/ssl/KeyManagerFactoryFactoryBean.java | 107 +-
.../logback/core/net/ssl/KeyStoreFactoryBean.java | 267 +-
.../main/java/ch/qos/logback/core/net/ssl/SSL.java | 25 +-
.../ch/qos/logback/core/net/ssl/SSLComponent.java | 10 +-
.../qos/logback/core/net/ssl/SSLConfigurable.java | 112 +-
.../core/net/ssl/SSLConfigurableServerSocket.java | 60 +-
.../core/net/ssl/SSLConfigurableSocket.java | 60 +-
.../qos/logback/core/net/ssl/SSLConfiguration.java | 38 +-
.../core/net/ssl/SSLContextFactoryBean.java | 567 ++--
.../net/ssl/SSLNestedComponentRegistryRules.java | 27 +-
.../core/net/ssl/SSLParametersConfiguration.java | 394 +--
.../core/net/ssl/SecureRandomFactoryBean.java | 123 +-
.../net/ssl/TrustManagerFactoryFactoryBean.java | 107 +-
.../logback/core/pattern/CompositeConverter.java | 52 +-
.../ch/qos/logback/core/pattern/Converter.java | 58 +-
.../ch/qos/logback/core/pattern/ConverterUtil.java | 81 +-
.../qos/logback/core/pattern/DynamicConverter.java | 155 +-
.../ch/qos/logback/core/pattern/FormatInfo.java | 223 +-
.../logback/core/pattern/FormattingConverter.java | 88 +-
.../core/pattern/IdentityCompositeConverter.java | 10 +-
.../qos/logback/core/pattern/LiteralConverter.java | 19 +-
.../logback/core/pattern/PatternLayoutBase.java | 246 +-
.../core/pattern/PatternLayoutEncoderBase.java | 75 +-
.../logback/core/pattern/PostCompileProcessor.java | 17 +-
.../core/pattern/ReplacingCompositeConverter.java | 50 +-
.../ch/qos/logback/core/pattern/SpacePadder.java | 82 +-
.../logback/core/pattern/color/ANSIConstants.java | 27 +-
.../pattern/color/BlackCompositeConverter.java | 10 +-
.../core/pattern/color/BlueCompositeConverter.java | 10 +-
.../pattern/color/BoldBlueCompositeConverter.java | 10 +-
.../pattern/color/BoldCyanCompositeConverter.java | 10 +-
.../pattern/color/BoldGreenCompositeConverter.java | 10 +-
.../color/BoldMagentaCompositeConverter.java | 10 +-
.../pattern/color/BoldRedCompositeConverter.java | 12 +-
.../pattern/color/BoldWhiteCompositeConverter.java | 10 +-
.../color/BoldYellowCompositeConverter.java | 10 +-
.../core/pattern/color/CyanCompositeConverter.java | 10 +-
.../color/ForegroundCompositeConverterBase.java | 34 +-
.../core/pattern/color/GrayCompositeConverter.java | 10 +-
.../pattern/color/GreenCompositeConverter.java | 10 +-
.../pattern/color/MagentaCompositeConverter.java | 10 +-
.../core/pattern/color/RedCompositeConverter.java | 10 +-
.../pattern/color/WhiteCompositeConverter.java | 10 +-
.../pattern/color/YellowCompositeConverter.java | 10 +-
.../qos/logback/core/pattern/parser/Compiler.java | 228 +-
.../logback/core/pattern/parser/CompositeNode.java | 75 +-
.../core/pattern/parser/FormattingNode.java | 61 +-
.../ch/qos/logback/core/pattern/parser/Node.java | 138 +-
.../core/pattern/parser/OptionTokenizer.java | 212 +-
.../ch/qos/logback/core/pattern/parser/Parser.java | 381 +--
.../core/pattern/parser/SimpleKeywordNode.java | 76 +-
.../ch/qos/logback/core/pattern/parser/Token.java | 180 +-
.../logback/core/pattern/parser/TokenStream.java | 320 +--
.../core/pattern/util/AlmostAsIsEscapeUtil.java | 39 +-
.../logback/core/pattern/util/AsIsEscapeUtil.java | 29 +-
.../qos/logback/core/pattern/util/IEscapeUtil.java | 4 +-
.../core/pattern/util/RegularEscapeUtil.java | 126 +-
.../core/pattern/util/RestrictedEscapeUtil.java | 24 +-
.../core/property/FileExistsPropertyDefiner.java | 60 +-
.../property/ResourceExistsPropertyDefiner.java | 69 +-
.../logback/core/read/CyclicBufferAppender.java | 82 +-
.../ch/qos/logback/core/read/ListAppender.java | 12 +-
.../logback/core/recovery/RecoveryCoordinator.java | 81 +-
.../core/recovery/ResilientFileOutputStream.java | 71 +-
.../core/recovery/ResilientOutputStreamBase.java | 227 +-
.../core/recovery/ResilientSyslogOutputStream.java | 53 +-
...aultTimeBasedFileNamingAndTriggeringPolicy.java | 61 +-
.../core/rolling/FixedWindowRollingPolicy.java | 278 +-
.../logback/core/rolling/RollingFileAppender.java | 365 ++-
.../ch/qos/logback/core/rolling/RollingPolicy.java | 70 +-
.../logback/core/rolling/RollingPolicyBase.java | 111 +-
.../qos/logback/core/rolling/RolloverFailure.java | 17 +-
.../core/rolling/SizeAndTimeBasedFNATP.java | 233 +-
.../rolling/SizeAndTimeBasedRollingPolicy.java | 43 -
.../core/rolling/SizeBasedTriggeringPolicy.java | 80 +-
.../TimeBasedFileNamingAndTriggeringPolicy.java | 103 +-
...TimeBasedFileNamingAndTriggeringPolicyBase.java | 179 +-
.../core/rolling/TimeBasedRollingPolicy.java | 444 ++-
.../qos/logback/core/rolling/TriggeringPolicy.java | 21 +-
.../logback/core/rolling/TriggeringPolicyBase.java | 25 +-
.../core/rolling/helper/ArchiveRemover.java | 11 +-
.../rolling/helper/AsynchronousCompressor.java | 36 +
.../core/rolling/helper/CompressionMode.java | 4 +-
.../core/rolling/helper/CompressionRunnable.java | 35 +
.../logback/core/rolling/helper/Compressor.java | 428 ++-
.../core/rolling/helper/DateTokenConverter.java | 119 +-
.../core/rolling/helper/DefaultArchiveRemover.java | 138 +
.../core/rolling/helper/FileFilterUtil.java | 175 +-
.../core/rolling/helper/FileNamePattern.java | 351 ++-
.../logback/core/rolling/helper/FileStoreUtil.java | 79 +-
.../core/rolling/helper/IntegerTokenConverter.java | 38 +-
.../core/rolling/helper/MonoTypedConverter.java | 6 +-
.../core/rolling/helper/PeriodicityType.java | 15 +-
.../logback/core/rolling/helper/RenameUtil.java | 182 +-
.../core/rolling/helper/RollingCalendar.java | 427 ++-
.../helper/SizeAndTimeBasedArchiveRemover.java | 41 +-
.../rolling/helper/TimeBasedArchiveRemover.java | 253 +-
.../core/rolling/helper/TokenConverter.java | 56 +-
.../sift/AbstractAppenderFactoryUsingJoran.java | 56 +-
.../logback/core/sift/AbstractDiscriminator.java | 33 +-
.../ch/qos/logback/core/sift/AppenderFactory.java | 15 +-
.../ch/qos/logback/core/sift/AppenderTracker.java | 81 +-
.../logback/core/sift/DefaultDiscriminator.java | 19 +-
.../ch/qos/logback/core/sift/Discriminator.java | 32 +-
.../qos/logback/core/sift/SiftingAppenderBase.java | 206 +-
.../core/sift/SiftingJoranConfiguratorBase.java | 99 +-
.../logback/core/spi/AbstractComponentTracker.java | 520 ++--
.../qos/logback/core/spi/AppenderAttachable.java | 74 +-
.../logback/core/spi/AppenderAttachableImpl.java | 196 +-
.../ch/qos/logback/core/spi/ComponentTracker.java | 145 +-
.../java/ch/qos/logback/core/spi/ContextAware.java | 21 +-
.../ch/qos/logback/core/spi/ContextAwareBase.java | 123 +-
.../ch/qos/logback/core/spi/ContextAwareImpl.java | 117 +-
.../qos/logback/core/spi/CyclicBufferTracker.java | 69 +-
.../logback/core/spi/DeferredProcessingAware.java | 4 +-
.../ch/qos/logback/core/spi/FilterAttachable.java | 38 +-
.../qos/logback/core/spi/FilterAttachableImpl.java | 66 +-
.../java/ch/qos/logback/core/spi/FilterReply.java | 7 +-
.../java/ch/qos/logback/core/spi/LifeCycle.java | 10 +-
.../java/ch/qos/logback/core/spi/LogbackLock.java | 7 +-
.../core/spi/PreSerializationTransformer.java | 4 +-
.../ch/qos/logback/core/spi/PropertyContainer.java | 8 +-
.../ch/qos/logback/core/spi/PropertyDefiner.java | 14 +-
.../ch/qos/logback/core/spi/ScanException.java | 27 +-
.../ch/qos/logback/core/status/ErrorStatus.java | 20 +-
.../ch/qos/logback/core/status/InfoStatus.java | 18 +-
.../qos/logback/core/status/NopStatusListener.java | 10 +-
.../core/status/OnConsoleStatusListener.java | 27 +-
.../core/status/OnErrorConsoleStatusListener.java | 12 +-
.../status/OnPrintStreamStatusListenerBase.java | 122 +-
.../java/ch/qos/logback/core/status/Status.java | 43 +-
.../ch/qos/logback/core/status/StatusBase.java | 283 +-
.../ch/qos/logback/core/status/StatusListener.java | 4 +-
.../logback/core/status/StatusListenerAsList.java | 19 +-
.../ch/qos/logback/core/status/StatusManager.java | 104 +-
.../ch/qos/logback/core/status/StatusUtil.java | 322 ++-
.../core/status/ViewStatusMessagesServletBase.java | 274 +-
.../ch/qos/logback/core/status/WarnStatus.java | 19 +-
.../main/java/ch/qos/logback/core/subst/Node.java | 190 +-
.../core/subst/NodeToStringTransformer.java | 269 +-
.../java/ch/qos/logback/core/subst/Parser.java | 216 +-
.../main/java/ch/qos/logback/core/subst/Token.java | 77 +-
.../java/ch/qos/logback/core/subst/Tokenizer.java | 189 +-
.../ch/qos/logback/core/util/AggregationType.java | 17 +-
.../logback/core/util/CachingDateFormatter.java | 49 +-
.../qos/logback/core/util/CharSequenceState.java | 20 +-
.../core/util/CharSequenceToRegexMapper.java | 157 +-
.../java/ch/qos/logback/core/util/CloseUtil.java | 76 +-
.../ch/qos/logback/core/util/ContentTypeUtil.java | 42 +-
.../java/ch/qos/logback/core/util/ContextUtil.java | 141 +-
.../logback/core/util/DatePatternToRegexUtil.java | 62 +-
.../logback/core/util/DefaultInvocationGate.java | 113 -
.../ch/qos/logback/core/util/DelayStrategy.java | 12 +-
.../java/ch/qos/logback/core/util/Duration.java | 172 +-
.../core/util/DynamicClassLoadingException.java | 10 +-
.../java/ch/qos/logback/core/util/EnvUtil.java | 81 +-
.../qos/logback/core/util/ExecutorServiceUtil.java | 65 +-
.../java/ch/qos/logback/core/util/FileSize.java | 94 +-
.../java/ch/qos/logback/core/util/FileUtil.java | 182 +-
.../java/ch/qos/logback/core/util/FixedDelay.java | 64 +-
.../core/util/IncompatibleClassException.java | 20 +-
.../ch/qos/logback/core/util/InvocationGate.java | 68 +-
.../main/java/ch/qos/logback/core/util/Loader.java | 298 +-
.../ch/qos/logback/core/util/LocationUtil.java | 86 +-
.../ch/qos/logback/core/util/OptionHelper.java | 418 +--
.../logback/core/util/PropertySetterException.java | 22 +-
.../core/util/StatusListenerConfigHelper.java | 79 -
.../ch/qos/logback/core/util/StatusPrinter.java | 297 +-
.../logback/core/util/StringCollectionUtil.java | 151 +-
.../java/ch/qos/logback/core/util/SystemInfo.java | 12 +-
.../java/ch/qos/logback/core/util/TimeUtil.java | 123 +-
logback-core/src/test/input/.gitignore | 1 +
logback-core/src/test/input/compress2.txt | 34 +
logback-core/src/test/input/compress3.txt | 42 -
.../test/java/ch/qos/logback/core/AllCoreTest.java | 22 +-
.../ch/qos/logback/core/AsyncAppenderBaseTest.java | 401 +--
.../qos/logback/core/BasicStatusManagerTest.java | 92 +-
.../java/ch/qos/logback/core/ContextBaseTest.java | 199 +-
.../logback/core/FileAppenderResilienceTest.java | 146 +-
.../core/FileAppenderResilience_AS_ROOT_Test.java | 184 +-
.../ch/qos/logback/core/LifeCycleManagerTest.java | 24 +-
.../qos/logback/core/MockLifeCycleComponent.java | 37 +-
.../qos/logback/core/OutputStreamAppenderTest.java | 187 +-
.../test/java/ch/qos/logback/core/PackageTest.java | 9 +-
.../core/PrudentFileAppenderInterruptTest.java | 93 -
.../core/appender/AbstractAppenderTest.java | 74 +-
.../logback/core/appender/ConsoleAppenderTest.java | 239 +-
.../logback/core/appender/DummyAppenderTest.java | 49 +-
.../logback/core/appender/DummyWriterAppender.java | 11 +-
.../logback/core/appender/FileAppenderTest.java | 214 +-
.../ch/qos/logback/core/appender/PackageTest.java | 8 +-
.../logback/core/appender/XTeeOutputStream.java | 30 +-
.../ch/qos/logback/core/boolex/MatcherTest.java | 112 +-
.../contention/AbstractMultiThreadedHarness.java | 39 +-
.../core/contention/MultiThreadedHarness.java | 38 +-
.../contention/RunnableWithCounterAndDone.java | 28 +-
.../contention/ThreadedThroughputCalculator.java | 37 +-
.../WaitOnExecutionMultiThreadedHarness.java | 11 +-
.../logback/core/encoder/ByteArrayUtilTest.java | 56 +-
.../ch/qos/logback/core/encoder/DummyEncoder.java | 132 +-
.../ch/qos/logback/core/encoder/NopEncoder.java | 16 +-
.../core/encoder/ObjectEncodeDecodeTest.java | 98 +-
.../ch/qos/logback/core/encoder/PackageTest.java | 4 +-
.../qos/logback/core/helpers/CyclicBufferTest.java | 73 +-
.../logback/core/helpers/FileFilterUtilTest.java | 49 +-
.../ch/qos/logback/core/helpers/PackageTest.java | 4 +-
.../core/helpers/ThrowableToStringArrayTest.java | 110 +-
.../java/ch/qos/logback/core/issue/LBCORE97.java | 267 +-
.../qos/logback/core/issue/LOGBACK_849/Basic.java | 87 +-
.../ch/qos/logback/core/issue/LockThroughput.java | 51 +-
.../ch/qos/logback/core/issue/LockingInJava.java | 111 +-
.../qos/logback/core/issue/NoLockThroughput.java | 37 +-
.../ch/qos/logback/core/issue/NoLockingInJava.java | 99 +-
.../logback/core/issue/SelectiveLockRunnable.java | 130 +-
.../core/issue/lbcore258/FileLockSimulator.java | 90 +-
.../ch/qos/logback/core/joran/PackageTest.java | 16 +-
.../qos/logback/core/joran/SimpleConfigurator.java | 60 +-
.../core/joran/SkippingInInterpreterTest.java | 127 +-
.../logback/core/joran/TrivialConfigurator.java | 34 +-
.../core/joran/TrivialConfiguratorTest.java | 253 +-
.../joran/action/AsLowerCasePropertyDefiner.java | 22 +-
.../joran/action/DefinePropertyActionTest.java | 111 +-
.../logback/core/joran/action/DummyAttributes.java | 82 +-
.../core/joran/action/IncludeActionTest.java | 361 +--
.../qos/logback/core/joran/action/PackageTest.java | 6 +-
.../core/joran/action/PropertyActionTest.java | 252 +-
.../core/joran/action/ext/BadBeginAction.java | 47 +-
.../core/joran/action/ext/BadEndAction.java | 43 +-
.../logback/core/joran/action/ext/HelloAction.java | 39 +-
.../logback/core/joran/action/ext/IncAction.java | 59 +-
.../logback/core/joran/action/ext/StackAction.java | 11 +-
.../logback/core/joran/action/ext/TouchAction.java | 43 +-
.../IfThenElseAndIncludeCompositionTest.java | 99 +-
.../core/joran/conditional/IfThenElseTest.java | 203 +-
.../core/joran/conditional/PackageTest.java | 5 +-
.../conditional/PropertyEvalScriptBuilderTest.java | 183 +-
.../logback/core/joran/event/InPlayFireTest.java | 84 +-
.../qos/logback/core/joran/event/ListenAction.java | 33 +-
.../qos/logback/core/joran/event/PackageTest.java | 4 +-
.../core/joran/event/SaxEventRecorderTest.java | 130 +-
.../joran/event/stax/StaxEventRecorderTest.java | 122 +-
.../logback/core/joran/implicitAction/Cake.java | 38 +-
.../logback/core/joran/implicitAction/Fruit.java | 38 +-
.../core/joran/implicitAction/FruitContext.java | 24 +-
.../joran/implicitAction/FruitContextAction.java | 58 +-
.../joran/implicitAction/ImplicitActionTest.java | 167 +-
.../core/joran/implicitAction/PackageTest.java | 4 +-
.../ch/qos/logback/core/joran/replay/Fruit.java | 42 +-
.../core/joran/replay/FruitConfigurationTest.java | 141 +-
.../core/joran/replay/FruitConfigurator.java | 65 +-
.../logback/core/joran/replay/FruitContext.java | 24 +-
.../logback/core/joran/replay/FruitFactory.java | 74 +-
.../core/joran/replay/FruitFactoryAction.java | 51 +-
.../qos/logback/core/joran/replay/FruitShell.java | 82 +-
.../core/joran/replay/FruitShellAction.java | 84 +-
.../qos/logback/core/joran/replay/PackageTest.java | 4 +-
.../logback/core/joran/replay/WeightytFruit.java | 19 +-
.../qos/logback/core/joran/spi/CaseCombinator.java | 133 +-
.../logback/core/joran/spi/CaseCombinatorTest.java | 50 +-
.../core/joran/spi/ConfigurationWatchListTest.java | 22 +-
.../spi/DefaultNestedComponentRegistryTest.java | 42 +-
.../qos/logback/core/joran/spi/DoNotAutoStart.java | 23 +-
.../core/joran/spi/ElementSelectorTest.java | 274 +-
.../core/joran/spi/NoAutoStartUtilTest.java | 26 +-
.../ch/qos/logback/core/joran/spi/PackageTest.java | 7 +-
.../core/joran/spi/SimpleRuleStoreTest.java | 349 +--
.../ch/qos/logback/core/joran/util/Citrus.java | 15 -
.../java/ch/qos/logback/core/joran/util/House.java | 285 +-
.../ch/qos/logback/core/joran/util/Orange.java | 9 -
.../qos/logback/core/joran/util/PackageTest.java | 4 +-
.../core/joran/util/PropertySetterTest.java | 411 +--
.../ch/qos/logback/core/layout/DummyLayout.java | 29 +-
.../java/ch/qos/logback/core/layout/NopLayout.java | 10 +-
.../core/net/AbstractSSLSocketAppenderTest.java | 58 +-
.../net/AbstractSocketAppenderIntegrationTest.java | 130 -
.../core/net/AbstractSocketAppenderTest.java | 702 ++---
.../core/net/AutoFlushingObjectWriterTest.java | 113 -
.../core/net/DefaultSocketConnectorTest.java | 216 +-
.../java/ch/qos/logback/core/net/PackageTest.java | 11 +-
.../logback/core/net/SyslogAppenderBaseTest.java | 60 +-
.../ch/qos/logback/core/net/mock/MockContext.java | 96 +-
.../logback/core/net/mock/MockExecutorService.java | 61 +
.../net/mock/MockScheduledExecutorService.java | 83 -
.../server/AbstractServerSocketAppenderTest.java | 121 +-
.../net/server/ConcurrentServerRunnerTest.java | 241 +-
.../InstrumentedServerSocketAppenderBase.java | 142 +-
.../ch/qos/logback/core/net/server/MockClient.java | 57 +-
.../logback/core/net/server/MockClientVisitor.java | 24 +-
.../logback/core/net/server/MockEventQueue.java | 18 +-
.../core/net/server/MockServerListener.java | 81 +-
.../logback/core/net/server/MockServerRunner.java | 73 +-
.../qos/logback/core/net/server/PackageTest.java | 10 +-
.../net/server/RemoteReceiverStreamClientTest.java | 95 +-
.../server/SSLServerSocketAppenderBaseTest.java | 59 +-
.../ServerSocketAppenderBaseFunctionalTest.java | 87 +-
.../core/net/server/ServerSocketListenerTest.java | 203 +-
.../logback/core/net/server/ServerSocketUtil.java | 74 +-
.../net/ssl/KeyManagerFactoryFactoryBeanTest.java | 45 +-
.../core/net/ssl/KeyStoreFactoryBeanTest.java | 69 +-
.../ch/qos/logback/core/net/ssl/PackageTest.java | 13 +-
.../logback/core/net/ssl/SSLConfigurationTest.java | 16 +-
.../core/net/ssl/SSLContextFactoryBeanTest.java | 147 +-
.../net/ssl/SSLParametersConfigurationTest.java | 215 +-
.../qos/logback/core/net/ssl/SSLTestConstants.java | 14 +-
.../core/net/ssl/SecureRandomFactoryBeanTest.java | 64 +-
.../ssl/TrustManagerFactoryFactoryBeanTest.java | 45 +-
.../core/net/ssl/mock/MockContextAware.java | 74 +-
.../ssl/mock/MockKeyManagerFactoryFactoryBean.java | 32 +-
.../core/net/ssl/mock/MockKeyStoreFactoryBean.java | 23 +-
.../core/net/ssl/mock/MockSSLConfigurable.java | 150 +-
.../net/ssl/mock/MockSecureRandomFactoryBean.java | 23 +-
.../mock/MockTrustManagerFactoryFactoryBean.java | 33 +-
.../ch/qos/logback/core/pattern/Converter123.java | 8 +-
.../qos/logback/core/pattern/ConverterHello.java | 8 +-
.../logback/core/pattern/ExceptionalConverter.java | 14 +-
.../ch/qos/logback/core/pattern/PackageTest.java | 6 +-
.../qos/logback/core/pattern/SpacePadderTest.java | 140 +-
.../parser/AbstractPatternLayoutBaseTest.java | 143 +-
.../logback/core/pattern/parser/CompilerTest.java | 442 +--
.../core/pattern/parser/FormatInfoTest.java | 173 +-
.../core/pattern/parser/OptionTokenizerTest.java | 238 +-
.../logback/core/pattern/parser/PackageTest.java | 9 +-
.../logback/core/pattern/parser/ParserTest.java | 466 ++--
.../core/pattern/parser/SamplePatternLayout.java | 28 +-
.../pattern/parser/SamplePatternLayoutTest.java | 116 +-
.../core/pattern/parser/TokenStreamTest.java | 728 ++---
.../core/read/CyclicBufferAppenderTest.java | 43 +-
.../ch/qos/logback/core/recovery/PackageTest.java | 6 +-
.../core/recovery/RecoveryCoordinatorTest.java | 93 +-
.../core/recovery/ResilientOutputStreamTest.java | 67 +-
.../core/rolling/CollisionDetectionTest.java | 141 -
.../qos/logback/core/rolling/ConfigParameters.java | 52 -
.../core/rolling/DefaultRolloverChecker.java | 47 +-
.../logback/core/rolling/FileMatchFunction.java | 4 +-
.../ch/qos/logback/core/rolling/FileOpener.java | 17 +-
.../JVMExitBeforeCompressionISDoneTest.java | 113 -
.../core/rolling/MultiThreadedRollingTest.java | 440 +--
.../ch/qos/logback/core/rolling/PackageTest.java | 11 +-
.../qos/logback/core/rolling/RenameUtilTest.java | 167 +-
.../core/rolling/RollingFileAppenderTest.java | 420 ++-
.../qos/logback/core/rolling/RolloverChecker.java | 8 +-
.../core/rolling/ScaffoldingForRollingTests.java | 419 ++-
.../core/rolling/SizeAndTimeBasedFNATP_Test.java | 373 ++-
.../logback/core/rolling/SizeBasedRollingTest.java | 190 +-
.../rolling/SizeBasedTriggeringPolicyTest.java | 58 +
...BasedFileNamingAndTriggeringPolicyBaseTest.java | 154 +-
.../logback/core/rolling/TimeBasedRollingTest.java | 402 +--
.../TimeBasedRollingWithArchiveRemoval_Test.java | 940 +++----
.../qos/logback/core/rolling/ZRolloverChecker.java | 23 +-
.../logback/core/rolling/helper/CompressTest.java | 175 +-
.../core/rolling/helper/FileNamePatternTest.java | 230 +-
.../core/rolling/helper/FileStoreUtilTest.java | 58 +-
.../logback/core/rolling/helper/PackageTest.java | 5 +-
.../core/rolling/helper/RollingCalendarTest.java | 227 +-
.../qos/logback/core/sift/AppenderTrackerTest.java | 217 +-
.../java/ch/qos/logback/core/sift/PackageTest.java | 6 +-
.../core/spi/AppenderAttachableImplLockTest.java | 84 +-
.../core/spi/AppenderAttachableImplTest.java | 261 +-
.../core/spi/CyclicBufferTrackerSimulator.java | 194 +-
.../qos/logback/core/spi/CyclicBufferTrackerT.java | 429 ++-
.../logback/core/spi/CyclicBufferTrackerTest.java | 92 +-
.../java/ch/qos/logback/core/spi/PackageTest.java | 8 +-
.../spi/ScenarioBasedCyclicBufferTrackerTest.java | 81 +-
.../ch/qos/logback/core/status/PackageTest.java | 6 +-
.../ch/qos/logback/core/status/StatusBaseTest.java | 123 +-
.../ch/qos/logback/core/status/StatusChecker.java | 60 +-
.../ch/qos/logback/core/status/StatusUtilTest.java | 49 +-
.../logback/core/status/TrivialStatusListener.java | 34 +-
.../core/subst/NodeToStringTransformerTest.java | 214 +-
.../ch/qos/logback/core/subst/PackageTest.java | 6 +-
.../java/ch/qos/logback/core/subst/ParserTest.java | 322 +--
.../ch/qos/logback/core/subst/TokenizerTest.java | 274 +-
.../core/testUtil/DelayingListAppender.java | 28 +-
.../qos/logback/core/testUtil/EnvUtilForTests.java | 83 +-
.../ch/qos/logback/core/testUtil/FileTestUtil.java | 22 +-
.../logback/core/testUtil/FileToBufferUtil.java | 73 +-
.../ch/qos/logback/core/testUtil/NPEAppender.java | 10 +-
.../ch/qos/logback/core/testUtil/RandomUtil.java | 26 +-
.../logback/core/testUtil/StringListAppender.java | 54 +-
.../logback/core/util/CachingFotmatterTest.java | 40 -
.../core/util/CharSequenceToRegexMapperTest.java | 82 -
.../java/ch/qos/logback/core/util/Compare.java | 282 +-
.../qos/logback/core/util/ContentTypeUtilTest.java | 44 +-
.../qos/logback/core/util/CoreTestConstants.java | 24 +-
.../logback/core/util/DatePatternToRegexTest.java | 210 +-
.../core/util/DefaultInvocationGateTest.java | 82 -
.../ch/qos/logback/core/util/DurationTest.java | 152 +-
.../ch/qos/logback/core/util/FileSizeTest.java | 76 +-
.../ch/qos/logback/core/util/FileUtilTest.java | 130 +-
.../logback/core/util/FixedRateInvocationGate.java | 19 -
.../ch/qos/logback/core/util/LocationUtilTest.java | 112 +-
.../ch/qos/logback/core/util/OptionHelperTest.java | 455 ++--
.../java/ch/qos/logback/core/util/PackageTest.java | 12 +-
.../ch/qos/logback/core/util/ResilienceUtil.java | 61 +-
.../core/util/StatusListenerConfigHelperTest.java | 51 -
.../qos/logback/core/util/StatusPrinterTest.java | 173 +-
.../core/util/StringCollectionUtilTest.java | 87 +-
.../ch/qos/logback/core/util/TeeOutputStream.java | 36 +-
.../ch/qos/logback/core/util/TimeUtilTest.java | 192 +-
logback-examples/pom.xml | 87 +-
logback-examples/setClasspath.cmd | 8 +-
logback-examples/setClasspath.sh | 8 +-
.../chapters/appenders/ConfigurationTester.java | 51 +-
.../appenders/CountingConsoleAppender.java | 85 +-
.../src/main/java/chapters/appenders/IO.java | 260 +-
.../java/chapters/appenders/IOPerformance.java | 235 +-
.../chapters/appenders/conf/access/logback-DB.xml | 14 +
.../appenders/conf/access/logback-SMTP.xml | 21 +
.../chapters/appenders/conf/logback-Console.xml | 15 +
.../appenders/conf/logback-HtmlToConsole.xml | 18 +
.../chapters/appenders/conf/logback-JMSQueue.xml | 17 +
.../chapters/appenders/conf/logback-JMSTopic.xml | 17 +
.../java/chapters/appenders/conf/logback-MDC.xml | 13 +
.../conf/logback-PrudentTimeBasedRolling.xml | 19 +
.../appenders/conf/logback-RollingFixedWindow.xml | 22 +
.../appenders/conf/logback-RollingSizeBased.xml | 23 +
.../appenders/conf/logback-RollingTimeBased.xml | 21 +
.../java/chapters/appenders/conf/logback-SMTP.xml | 19 +
.../appenders/conf/logback-SMTPWithHtml.xml | 20 +
.../java/chapters/appenders/conf/logback-async.xml | 16 +
.../appenders/conf/logback-fileAppender.xml | 17 +
.../appenders/conf/logback-sizeAndTime.xml | 25 +
.../chapters/appenders/conf/logback-syslog.xml | 13 +
.../conf/logback-timestamp-contextBirth.xml | 22 +
.../chapters/appenders/conf/logback-timestamp.xml | 20 +
.../java/chapters/appenders/countingConsole.xml | 19 +
.../appenders/db/append-and-share-with-jndi.xml | 39 +
.../append-toMySQL-with-datasource-and-pooling.xml | 17 +
.../db/append-toMySQL-with-datasource.xml | 21 +
.../db/append-toMySQL-with-driverManager.xml | 17 +
.../java/chapters/appenders/db/append-via-jndi.xml | 11 +
.../chapters/appenders/db/append-with-c3p0.xml | 25 +
.../appenders/db/append-with-datasource.xml | 29 +
.../appenders/db/append-with-drivermanager.xml | 19 +
.../appenders/db/append-with-pooled-datasource.xml | 30 +
.../appenders/mail/CounterBasedEvaluator.java | 57 +-
.../main/java/chapters/appenders/mail/EMail.java | 66 +-
.../java/chapters/appenders/mail/Marked_EMail.java | 64 +-
.../chapters/appenders/mail/customBufferSize.xml | 20 +
.../main/java/chapters/appenders/mail/gmailSSL.xml | 22 +
.../java/chapters/appenders/mail/gmailSTARTTLS.xml | 21 +
.../main/java/chapters/appenders/mail/mail1.xml | 17 +
.../main/java/chapters/appenders/mail/mail2.xml | 18 +
.../main/java/chapters/appenders/mail/mail3.xml | 24 +
.../mail/mailWithMDCBasedDiscriminator.xml | 27 +
.../chapters/appenders/mail/mailWithMarker.xml | 24 +
.../mail/mailWithMarker_GEventEvaluator.xml | 24 +
.../appenders/mail/mailWithMarker_Janino.xml | 25 +
.../java/chapters/appenders/sift/SiftExample.java | 54 +-
.../chapters/appenders/sift/access-siftingFile.xml | 22 +
.../main/java/chapters/appenders/sift/byUserid.xml | 21 +
.../appenders/socket/ConsolePluginClient.java | 177 +-
.../chapters/appenders/socket/SocketClient1.java | 76 +-
.../chapters/appenders/socket/SocketClient2.java | 64 +-
.../java/chapters/appenders/socket/client1.xml | 23 +
.../java/chapters/appenders/socket/client2.xml | 28 +
.../java/chapters/appenders/socket/server1.xml | 47 +
.../java/chapters/appenders/socket/server2.xml | 25 +
.../java/chapters/appenders/socket/ssl/client.xml | 28 +
.../chapters/appenders/socket/ssl/keystore.jks | Bin 0 -> 2168 bytes
.../java/chapters/appenders/socket/ssl/server.xml | 22 +
.../chapters/appenders/socket/ssl/truststore.jks | Bin 0 -> 861 bytes
.../java/chapters/appenders/sub/sample/Bar.java | 30 +-
.../src/main/java/chapters/architecture/Bar.java | 10 +-
.../chapters/architecture/MyAppWithConfigFile.java | 34 +-
.../java/chapters/architecture/SelectionRule.java | 44 +-
.../java/chapters/architecture/sample-config-1.xml | 15 +
.../java/chapters/architecture/sample-config-2.xml | 24 +
.../java/chapters/architecture/sample-config-3.xml | 26 +
.../configuration/AddStatusListenerApp.java | 27 +-
.../src/main/java/chapters/configuration/Foo.java | 11 +-
.../main/java/chapters/configuration/MyApp1.java | 17 +-
.../main/java/chapters/configuration/MyApp2.java | 26 +-
.../main/java/chapters/configuration/MyApp3.java | 42 +-
.../java/chapters/configuration/additivityFlag.xml | 26 +
.../chapters/configuration/containingConfig.xml | 12 +
.../java/chapters/configuration/contextName.xml | 15 +
.../configuration/contextScopedVariable.xml | 15 +
.../main/java/chapters/configuration/duplicate.xml | 19 +
.../java/chapters/configuration/includedConfig.xml | 13 +
.../java/chapters/configuration/insertFromJNDI.xml | 18 +
.../main/java/chapters/configuration/multiple.xml | 21 +
.../configuration/onConsoleStatusListener.xml | 21 +
.../java/chapters/configuration/restricted.xml | 25 +
.../main/java/chapters/configuration/sample0.xml | 17 +
.../main/java/chapters/configuration/sample1.xml | 17 +
.../main/java/chapters/configuration/sample2.xml | 23 +
.../main/java/chapters/configuration/sample3.xml | 24 +
.../main/java/chapters/configuration/sample4.xml | 21 +
.../src/main/java/chapters/configuration/scan1.xml | 17 +
.../src/main/java/chapters/configuration/scan2.xml | 15 +
.../configuration/variableSubstitution1.xml | 15 +
.../configuration/variableSubstitution2.xml | 13 +
.../configuration/variableSubstitution3.xml | 15 +
.../configuration/variableSubstitution4.xml | 15 +
.../chapters/configuration/variables1.properties | 1 +
.../chapters/configuration/variables2.properties | 3 +
.../main/java/chapters/filters/FilterEvents.java | 60 +-
.../src/main/java/chapters/filters/GoMDC.java | 41 +-
.../main/java/chapters/filters/SampleFilter.java | 16 +-
.../java/chapters/filters/SampleTurboFilter.java | 53 +-
.../java/chapters/filters/accessEventEvaluator.xml | 17 +
.../chapters/filters/accessEventEvaluator2.xml | 21 +
.../java/chapters/filters/basicConfiguration.xml | 12 +
.../java/chapters/filters/basicEventEvaluator.xml | 19 +
.../java/chapters/filters/duplicateMessage.xml | 16 +
.../java/chapters/filters/evaluatorWithMatcher.xml | 25 +
.../java/chapters/filters/levelFilterConfig.xml | 17 +
.../src/main/java/chapters/filters/mdcfilter.xml | 23 +
.../java/chapters/filters/sampleFilterConfig.xml | 16 +
.../chapters/filters/sampleTurboFilterConfig.xml | 16 +
.../chapters/filters/thresholdFilterConfig.xml | 20 +
.../main/java/chapters/filters/turboFilters.xml | 25 +
.../java/chapters/introduction/HelloWorld1.java | 10 +-
.../java/chapters/introduction/HelloWorld2.java | 16 +-
.../chapters/layouts/CallerEvaluatorExample.java | 40 +-
.../layouts/ExceptionEvaluatorExample.java | 43 +-
.../java/chapters/layouts/MySampleConverter.java | 14 +-
.../main/java/chapters/layouts/MySampleLayout.java | 32 +-
.../java/chapters/layouts/MySampleLayout2.java | 58 +-
.../main/java/chapters/layouts/PatternSample.java | 42 +-
.../main/java/chapters/layouts/SampleLogging.java | 32 +-
.../main/java/chapters/layouts/TestException.java | 10 +-
.../main/java/chapters/layouts/TrivialMain.java | 48 +-
.../chapters/layouts/callerEvaluatorConfig.xml | 18 +
.../chapters/layouts/exceptionEvaluatorConfig.xml | 16 +
.../src/main/java/chapters/layouts/highlighted.xml | 16 +
.../java/chapters/layouts/htmlLayoutConfig1.xml | 14 +
.../main/java/chapters/layouts/log4jXMLLayout.xml | 14 +
.../chapters/layouts/mySampleConverterConfig.xml | 15 +
.../java/chapters/layouts/sampleLayoutConfig.xml | 12 +
.../java/chapters/layouts/sampleLayoutConfig2.xml | 16 +
.../src/main/java/chapters/mdc/NumberCruncher.java | 13 +-
.../java/chapters/mdc/NumberCruncherClient.java | 92 +-
.../java/chapters/mdc/NumberCruncherServer.java | 226 +-
.../src/main/java/chapters/mdc/SimpleMDC.java | 110 +-
.../main/java/chapters/mdc/UserServletFilter.java | 77 +-
.../src/main/java/chapters/mdc/mdc1.xml | 16 +
.../src/main/java/chapters/mdc/simpleMDC.xml | 15 +
.../chapters/migrationFromLog4j/Log4jMain.java | 12 +-
.../chapters/migrationFromLog4j/LogbackMain.java | 25 +-
.../migrationFromLog4j/TrivialLog4jAppender.java | 22 +-
.../migrationFromLog4j/TrivialLog4jLayout.java | 23 +-
.../migrationFromLog4j/TrivialLogbackAppender.java | 66 +-
.../migrationFromLog4j/TrivialLogbackLayout.java | 9 +-
.../migrationFromLog4j/log4jTrivial.properties | 3 +
.../migrationFromLog4j/logback-trivial.xml | 10 +
.../java/chapters/onJoran/SimpleConfigurator.java | 50 +-
.../chapters/onJoran/calculator/AddAction.java | 67 +-
.../chapters/onJoran/calculator/Calculator1.java | 36 +-
.../chapters/onJoran/calculator/Calculator2.java | 46 +-
.../onJoran/calculator/ComputationAction1.java | 50 +-
.../onJoran/calculator/ComputationAction2.java | 43 +-
.../chapters/onJoran/calculator/LiteralAction.java | 43 +-
.../onJoran/calculator/MultiplyAction.java | 59 +-
.../chapters/onJoran/calculator/calculator1.xml | 3 +
.../chapters/onJoran/calculator/calculator2.xml | 10 +
.../chapters/onJoran/calculator/calculator3.xml | 15 +
.../chapters/onJoran/helloWorld/HelloWorld.java | 26 +-
.../onJoran/helloWorld/HelloWorldAction.java | 12 +-
.../java/chapters/onJoran/helloWorld/hello.xml | 2 +
.../java/chapters/onJoran/implicit/NOPAction.java | 13 +-
.../java/chapters/onJoran/implicit/PrintMe.java | 35 +-
.../onJoran/implicit/PrintMeImplicitAction.java | 21 +-
.../java/chapters/onJoran/implicit/implicit1.xml | 21 +
.../onJoran/newRule/NewRuleCalculator.java | 38 +-
.../main/java/chapters/onJoran/newRule/newRule.xml | 23 +
.../chapters/receivers/socket/AppenderExample.java | 67 +-
.../chapters/receivers/socket/ReceiverExample.java | 44 +-
.../java/chapters/receivers/socket/appender1.xml | 22 +
.../java/chapters/receivers/socket/appender2.xml | 28 +
.../java/chapters/receivers/socket/appender3.xml | 21 +
.../java/chapters/receivers/socket/appender4.xml | 27 +
.../java/chapters/receivers/socket/receiver1.xml | 26 +
.../java/chapters/receivers/socket/receiver2.xml | 32 +
.../java/chapters/receivers/socket/receiver3.xml | 28 +
.../java/chapters/receivers/socket/receiver4.xml | 34 +
logback-site/pom.xml | 28 +-
logback-site/src/site/pages/access.html | 375 ++-
logback-site/src/site/pages/beagle/index.html | 3 -
logback-site/src/site/pages/bugreport.html | 4 -
logback-site/src/site/pages/cla.txt | 62 +-
logback-site/src/site/pages/codes.html | 133 +-
logback-site/src/site/pages/css/screen.css | 36 +-
logback-site/src/site/pages/demo.html | 4 -
logback-site/src/site/pages/dependencies.html | 17 +-
logback-site/src/site/pages/documentation.html | 7 +-
logback-site/src/site/pages/download.html | 74 +-
logback-site/src/site/pages/faq.html | 4 -
logback-site/src/site/pages/index.html | 6 -
logback-site/src/site/pages/js/dsl.js | 2 +-
.../src/site/pages/js/jquery.cookies.2.2.0.js | 450 +++
logback-site/src/site/pages/js/popup.js | 102 +
logback-site/src/site/pages/license.html | 6 +-
logback-site/src/site/pages/mailinglist.html | 4 -
logback-site/src/site/pages/manual/appenders.html | 357 +--
.../src/site/pages/manual/appenders_ja.html | 2871 --------------------
.../src/site/pages/manual/architecture.html | 2 -
.../src/site/pages/manual/architecture_ja.html | 619 -----
.../src/site/pages/manual/configuration.html | 226 +-
.../src/site/pages/manual/configuration_ja.html | 1273 ---------
logback-site/src/site/pages/manual/encoders.html | 2 -
.../src/site/pages/manual/encoders_ja.html | 175 --
logback-site/src/site/pages/manual/filters.html | 22 +-
logback-site/src/site/pages/manual/filters_ja.html | 818 ------
logback-site/src/site/pages/manual/groovy.html | 7 +-
logback-site/src/site/pages/manual/groovy_ja.html | 364 ---
logback-site/src/site/pages/manual/index.html | 1 -
logback-site/src/site/pages/manual/index_ja.html | 115 -
.../src/site/pages/manual/introduction.html | 3 -
.../src/site/pages/manual/introduction_ja.html | 165 --
logback-site/src/site/pages/manual/jmxConfig.html | 2 -
.../src/site/pages/manual/jmxConfig_ja.html | 290 --
logback-site/src/site/pages/manual/layouts.html | 53 +-
logback-site/src/site/pages/manual/layouts_ja.html | 1645 -----------
.../src/site/pages/manual/loggingSeparation.html | 2 -
.../site/pages/manual/loggingSeparation_ja.html | 270 --
logback-site/src/site/pages/manual/mdc.html | 17 +-
logback-site/src/site/pages/manual/mdc_ja.html | 542 ----
logback-site/src/site/pages/manual/menu.js | 14 -
logback-site/src/site/pages/manual/menu_ja.js | 16 -
.../src/site/pages/manual/migrationFromLog4j.html | 2 -
.../site/pages/manual/migrationFromLog4j_ja.html | 157 --
logback-site/src/site/pages/manual/onJoran.html | 7 +-
logback-site/src/site/pages/manual/onJoran_ja.html | 433 ---
logback-site/src/site/pages/manual/receivers.html | 16 +-
.../src/site/pages/manual/receivers_ja.html | 343 ---
logback-site/src/site/pages/manual/usingSSL.html | 26 +-
.../src/site/pages/manual/usingSSL_ja.html | 811 ------
logback-site/src/site/pages/news.html | 431 +--
logback-site/src/site/pages/reasonsToSwitch.html | 4 -
logback-site/src/site/pages/setup.html | 153 +-
logback-site/src/site/pages/templates/creative.js | 2 +-
logback-site/src/site/pages/templates/footer.js | 2 +-
logback-site/src/site/pages/templates/left.js | 14 +-
logback-site/src/site/pages/templates/right.js | 28 +-
logback-site/src/site/pages/volunteer.html | 4 -
.../src/site/resources/images/follow_us.png | Bin 16337 -> 0 bytes
.../images/setup/remove_evaluator_template.jpg | Bin 57480 -> 0 bytes
.../site/resources/images/setup/remove_gen_src.jpg | Bin 68932 -> 0 bytes
pom.xml | 287 +-
src/main/assembly/dist.xml | 11 -
src/main/clas/signed-clas.txt | 29 +-
src/main/licenseHeader.txt | 2 +-
1466 files changed, 64532 insertions(+), 89631 deletions(-)
diff --git a/LICENSE.txt b/LICENSE.txt
index 59dfd38..f008d84 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -2,7 +2,7 @@ Logback LICENSE
---------------
Logback: the reliable, generic, fast and flexible logging framework.
-Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+Copyright (C) 1999-2012, QOS.ch. All rights reserved.
This program and the accompanying materials are dual-licensed under
either the terms of the Eclipse Public License v1.0 as published by
diff --git a/docs/access.html b/docs/access.html
index 2825b39..50e5a90 100644
--- a/docs/access.html
+++ b/docs/access.html
@@ -17,34 +17,30 @@
<div id="left">
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="templates/right.js" type="text/javascript"></script>
- </div>
-
<div id="content">
-
+
<h2>HTTP-access logs with logback-access, Jetty and Tomcat</h2>
<div class="author">
- Authors: Ceki Gülcü, Sébastien Pennec
- </div>
+ Authors: Ceki Gülcü, Sébastien Pennec
+ </div>
<script src="../templates/creative.js" type="text/javascript"></script>
- <h1>Introduction</h1>
+ <h1>Introduction</h1>
<p>The logback-access module, part of the standard logback
distribution, integrates with Servlet containers such as Jetty or
Tomcat to provide rich and powerful HTTP-access log functionality.
</p>
-
- <p>Logback was designed as a modular framework from the
- start. Making logback-core reusable under different circumstances
- without much recoding was one of our main goals. In accordance
- with this strategy, logback-access builds on top of logback-core
- and can thus provide much of the functionality of logback-classic
- but in the scope of HTTP-access logging. </p>
+
+ <p>Logback was designed as a modular framework from the
+ start. Making logback-core reusable under different circumstances
+ without much recoding was one of our main goals. In accordance
+ with this strategy, logback-access builds on top of logback-core
+ and can thus provide much of the functionality of logback-classic
+ but in the scope of HTTP-access logging. </p>
<p>It should be noted that while logback-access requires
logback-core, it is independent of logback-classic as well as
@@ -54,18 +50,18 @@
level of a web-application.
</p>
- <h1><a name="tomcat" href="#tomcat">Logback-access under Tomcat</a></h1>
-
+ <h1><a name="tomcat" href="#tomcat">Logback-access under Tomcat</a></h1>
+
- <p>To use logback-access with Tomcat, after downloading the
- logback distribution, place the files
- <em>logback-core-1.1.9.jar</em> and
- <em>logback-access-1.1.9.jar</em> under
- $TOMCAT_HOME/lib/ directory, where $TOMCAT_HOME is the folder
- where you have installed Tomcat.
+ <p>To use logback-access with Tomcat, after downloading the
+ logback distribution, place the files
+ <em>logback-core-1.1.2.jar</em> and
+ <em>logback-access-1.1.2.jar</em> under
+ $TOMCAT_HOME/lib/ directory, where $TOMCAT_HOME is the folder
+ where you have installed Tomcat.
</p>
<p class="highlight">Deploying recent versions of logback-access
@@ -73,52 +69,44 @@
server to crash.</p>
<p><span class="label notice">Tomcat 7.x</span> This version of
- logback-access has been tested with Tomcat version 7.0.62. It will
+ logback-access has been tested with Tomcat version 7.0.21. It will
not work with Tomcat 6.x.
- </p>
+ </p>
<p><span class="label notice">Tomcat 6.x</span> Logback-access
version 0.9.30 will deploy on Tomcat 6.x.</p>
- <h2>LogbackValve</h2>
-
- <p>The <a
- href="xref/ch/qos/logback/access/tomcat/LogbackValve.html">
- <code>ch.qos.logback.access.tomcat.LogbackValve</code></a> class
- extends Tomcat's <code><a
- href="http://tomcat.apache.org/tomcat-5.5-doc/catalina/docs/api/org/apache/catalina/valves/ValveBase.html">
- ValveBase</a></code> class. Valves are usually associated together
- to form a processing pipeline.
- </p>
-
- <p>To configure Tomcat in order to use <code>LogbackValve</code>,
- add the following lines to the tomcat server configuration file,
- namely <em>$TOMCAT_HOME/conf/server.xml</em>:
- </p>
- <pre class="source"><Valve className="ch.qos.logback.access.tomcat.LogbackValve"/></pre>
-
- <p>This line is usually nested within an <code><Engine></code>
- or <code><Host></code> element.
- </p>
-
- <p>By default, <code>LogbackValve</code> looks for a configuration
- file called <em>logback-access.xml</em>, in the same folder where
- <em>server.xml</em> is located, that is in
- <em>$TOMCAT_HOME/conf/</em>. This configuration file contains
- directives for configuring logback-access components. It is used
- to specify appenders where the logging requests will be
- sent. Please refer to the <a href="#configuration">logback-access
- configuration section</a> further below.
- </p>
-
- <p>If the <code>LogbackValve</code> is not able to read a configuration file
- from the filesystem, it will attempt to load it as a resource (i.e.
- getClassLoader().getResourceAsStream()). This might be helpful in scenarios
- where your application is embedding Tomcat (e.g. using Spring Boot.) As
- mentioned above, if no filename is set, it defaults to looking for a
- resource named logback-access.xml.
- </p>
-
+ <h2>LogbackValve</h2>
+
+ <p>The <a
+ href="xref/ch/qos/logback/access/tomcat/LogbackValve.html">
+ <code>ch.qos.logback.access.tomcat.LogbackValve</code></a> class
+ extends Tomcat's <code><a
+ href="http://tomcat.apache.org/tomcat-5.5-doc/catalina/docs/api/org/apache/catalina/valves/ValveBase.html">
+ ValveBase</a></code> class. Valves are usually associated together
+ to form a processing pipeline.
+ </p>
+
+ <p>To configure Tomcat in order to use <code>LogbackValve</code>,
+ add the following lines to the tomcat server configuration file,
+ namely <em>$TOMCAT_HOME/conf/server.xml</em>:
+ </p>
+ <pre class="source"><Valve className="ch.qos.logback.access.tomcat.LogbackValve"/></pre>
+
+ <p>This line is usually nested within an <code><Engine></code>
+ or <code><Host></code> element.
+ </p>
+
+ <p>By default, <code>LogbackValve</code> looks for a configuration
+ file called <em>logback-access.xml</em>, in the same folder where
+ <em>server.xml</em> is located, that is in
+ <em>$TOMCAT_HOME/conf/</em>. This configuration file contains
+ directives for configuring logback-access components. It is used
+ to specify appenders where the logging requests will be
+ sent. Please refer to the <a href="#configuration">logback-access
+ configuration section</a> further below.
+ </p>
+
<p>In order to help with troubleshooting, by default, the
<code>LogbackValve</code> will print its internal status at its
initialization. Typical output would look as:
@@ -127,6 +115,7 @@
<p class="source">21:56:09,921 |-INFO in c.q.lb.access.j.a.ConfigurationAction - Ignoring debug attribute.
21:56:09,921 |-INFO in c.q.lb.core.j.a.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
21:56:09,921 |-INFO in c.q.lb.core.j.a.AppenderAction - Naming appender as [STDOUT]
+21:56:10,000 |-INFO in c.q.lb.core.j.a.NestedComponentIA - Pushing component [layout] on top of the object stack.
21:56:10,015 |-INFO in c.q.lb.core.j.a.AppenderAction - Popping appender named [STDOUT] from the object stack
21:56:10,015 |-INFO in c.q.lb.core.j.a.AppenderRefAction - Attaching appender named [STDOUT] to ch.qos.logback.access.tomcat.LogbackValve[Catalina]
21:56:10,015 |-INFO in c.q.lb.access.j.a.ConfigurationAction - End of configuration.</p>
@@ -172,42 +161,42 @@
</p>
- <h1><a name="jetty" href="#jetty">Logback-access under
- Jetty</a></h1>
-
- <p>After downloading the logback distribution, place the files
- <em>logback-core-VERSION.jar</em> and
- <em>logback-access-VERSION.jar</em> under $JETTY_HOME/lib
- directory, where $JETTY_HOME is the folder where you have
- installed Jetty. Versions of logback-access 0.9.31 and later
- target Jetty versions 7.x and 8.x. Logback-access versions 0.9.30
- and earlier target Jetty version 6.x.
- </p>
-
- <h3>Logback's implementation of
- <code>org.eclipse.jetty.server.RequestLog</code> interface</h3>
-
- <p>The <a
- href="xref/ch/qos/logback/access/jetty/RequestLogImpl.html">
- <code>ch.qos.logback.access.jetty.RequestLogImpl</code></a> class
- implements Jetty's <code><a
- href="http://download.eclipse.org/jetty/stable-7/apidocs/org/eclipse/jetty/server/RequestLog.html">RequestLog</a></code>
- interface. Jetty delegates the management of access logging
- functionality to implementations of this interface.
- </p>
-
- <p>In logback, a logging destination is called an "appender" which
- can be directly attached to a
- <code>ch.qos.logback.access.jetty.RequestLogImpl</code> instance.
- </p>
-
-
- <p>In order to configure Jetty to use logback-access's
- <code>RequestLogImpl</code>, please add the following lines to
- Jetty's main configuration file, namely
- <em>$JETTY_HOME/etc/jetty.xml</em>:
- </p>
- <pre class="prettyprint source"><Ref id="RequestLogHandler">
+ <h1><a name="jetty" href="#jetty">Logback-access under
+ Jetty</a></h1>
+
+ <p>After downloading the logback distribution, place the files
+ <em>logback-core-VERSION.jar</em> and
+ <em>logback-access-VERSION.jar</em> under $JETTY_HOME/lib
+ directory, where $JETTY_HOME is the folder where you have
+ installed Jetty. Versions of logback-access 0.9.31 and later
+ target Jetty versions 7.x and 8.x. Logback-access versions 0.9.30
+ and earlier target Jetty version 6.x.
+ </p>
+
+ <h3>Logback's implementation of
+ <code>org.eclipse.jetty.server.RequestLog</code> interface</h3>
+
+ <p>The <a
+ href="xref/ch/qos/logback/access/jetty/RequestLogImpl.html">
+ <code>ch.qos.logback.access.jetty.RequestLogImpl</code></a> class
+ implements Jetty's <code><a
+ href="http://download.eclipse.org/jetty/stable-7/apidocs/org/eclipse/jetty/server/RequestLog.html">RequestLog</a></code>
+ interface. Jetty delegates the management of access logging
+ functionality to implementations of this interface.
+ </p>
+
+ <p>In logback, a logging destination is called an "appender" which
+ can be directly attached to a
+ <code>ch.qos.logback.access.jetty.RequestLogImpl</code> instance.
+ </p>
+
+
+ <p>In order to configure Jetty to use logback-access's
+ <code>RequestLogImpl</code>, please add the following lines to
+ Jetty's main configuration file, namely
+ <em>$JETTY_HOME/etc/jetty.xml</em>:
+ </p>
+ <pre class="prettyprint source"><Ref id="RequestLogHandler">
<Set name="requestLog">
<New id="requestLogImpl" class="ch.qos.logback.access.jetty.RequestLogImpl">
</New>
@@ -250,13 +239,13 @@
directives for configuring logback components such as appenders
and layouts.
</p>
-
- <p>As long the path is specified, you can place the logback
- configuration file in any location. Here is another example of a
- Jetty configuration file, including the path to the logback-access
- configuration file here named <em>myaccess.xml</em>.
- </p>
-
+
+ <p>As long the path is specified, you can place the logback
+ configuration file in any location. Here is another example of a
+ Jetty configuration file, including the path to the logback-access
+ configuration file here named <em>myaccess.xml</em>.
+ </p>
+
<pre class="prettyprint source"><Ref id="RequestLogHandler">
<Set name="requestLog">
<New id="requestLogImpl" class="ch.qos.logback.access.jetty.RequestLogImpl">
@@ -281,21 +270,21 @@
<h1><a name="configuration" href="#configuration">Logback-access
configuration</a></h1>
-
-
+
+
<p>Although similar, the format of <em>logback-access.xml</em>
configuration file is slightly different than the configuration file
format logback-classic. Appenders and Layouts are declared the
exact same way. However, in the access module there is no notion of
loggers and consequently logger elements are disallowed.
- </p>
+ </p>
<h3>Example 1: basic logback-access configuration</h3>
- <p>
- Here is a small but fully functional <em>logback-access.xml</em>
- configuration file:
- </p>
+ <p>
+ Here is a small but fully functional <em>logback-access.xml</em>
+ configuration file:
+ </p>
<pre class="prettyprint source"><configuration>
<!-- always a good activate OnConsoleStatusListener -->
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
@@ -308,16 +297,16 @@
<appender-ref ref="STDOUT" />
</configuration></pre>
- <p>
- It declares a <code>ConsoleAppender</code> which prints its output
- on the console. The <code>ConsoleAppender</code> contains an
- <code>Encoder</code> object responsible for formatting output. The
- log format is specified by the "%h %l %u %user %date "%r" %s %b"
- pattern which incidentally corresponds to the Common Log Format
- (CLF). This format is recognized by log analyzers such as <a
- href="http://www.analog.cx/">Analog</a> or <a
- href="http://awstats.sourceforge.net/">AWStats</a>.
- </p>
+ <p>
+ It declares a <code>ConsoleAppender</code> which prints its output
+ on the console. The <code>ConsoleAppender</code> contains an
+ <code>Encoder</code> object responsible for formatting output. The
+ log format is specified by the "%h %l %u %user %date "%r" %s %b"
+ pattern which incidentally corresponds to the Common Log Format
+ (CLF). This format is recognized by log analyzers such as <a
+ href="http://www.analog.cx/">Analog</a> or <a
+ href="http://awstats.sourceforge.net/">AWStats</a>.
+ </p>
<p>The words "common" or "clf" are interpreted as shorthands for
the said pattern. Thus, the following are all equivalent:
@@ -346,11 +335,11 @@
<h3>Example 2: RollingFileAppender</h3>
- <p>The configuration file below configures a daily rolling
- <code>RollingFileAppender</code>. Note that due to the
- <em>.zip</em> suffix included in the value for <span
- class="option">fileNamePattern</span> option, the log files are not
- only rolled daily, but they are also automatically compressed.</p>
+ <p>The configuration file below configures a daily rolling
+ <code>RollingFileAppender</code>. Note that due to the
+ <em>.zip</em> suffix included in the value for <span
+ class="option">fileNamePattern</span> option, the log files are not
+ only rolled daily, but they are also automatically compressed.</p>
<pre class="prettyprint source"><configuration>
@@ -370,62 +359,62 @@
<appender-ref ref="FILE" />
</configuration></pre>
-
+
<p>These two examples should give you an idea of the possibilities
offered by logback-access. In principle, most if not all of the
features available in logback-classic are also available in
logback-access.
- </p>
+ </p>
<h3>PatternLayout</h3>
- <p>Logback-access ships with an http-specific implementation of <a
- href="xref/ch/qos/logback/access/PatternLayout.html">
- <code>PatternLayout</code></a>. For detailed instructions on how
- to use the <code>PatternLayout</code>, please refer to the <a
- href="manual/layouts.html#AccessPatternLayout">corresponding
- chapter</a> of the logback manual.
- </p>
-
- <h2>JMX Components</h2>
-
- <p>Logback-access integrates with JMX servers to publish
- information about its components.
- </p>
-
- <p>Both <code>RequestLogImpl</code> and <code>LogbackValve</code>
- expose data and can be updated via JMX. A special filter, covered
- further down this document, publishes statistical data on access
- logs.
- </p>
-
-
- <h3>Configuring Tomcat for JMX</h3>
-
- <p>In order to configure Tomcat for JMX, please add the following
- lines to the <em>$TOMCAT_HOME/bin/catalina.sh</em> shell script
- (or its MS Windows equivalent):
- </p>
-
+ <p>Logback-access ships with an http-specific implementation of <a
+ href="xref/ch/qos/logback/access/PatternLayout.html">
+ <code>PatternLayout</code></a>. For detailed instructions on how
+ to use the <code>PatternLayout</code>, please refer to the <a
+ href="manual/layouts.html#AccessPatternLayout">corresponding
+ chapter</a> of the logback manual.
+ </p>
+
+ <h2>JMX Components</h2>
+
+ <p>Logback-access integrates with JMX servers to publish
+ information about its components.
+ </p>
+
+ <p>Both <code>RequestLogImpl</code> and <code>LogbackValve</code>
+ expose data and can be updated via JMX. A special filter, covered
+ further down this document, publishes statistical data on access
+ logs.
+ </p>
+
+
+ <h3>Configuring Tomcat for JMX</h3>
+
+ <p>In order to configure Tomcat for JMX, please add the following
+ lines to the <em>$TOMCAT_HOME/bin/catalina.sh</em> shell script
+ (or its MS Windows equivalent):
+ </p>
+
<div class="source"><pre>CATALINA_OPTS="-Dcom.sun.management.jmxremote"
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.ssl=false"
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.authenticate=false"</pre></div>
- <p>After you launch Tomcat, you can access the MBeans exposed by
- Tomcat via the JConsole application, which can be started with the
- following command:
- </p>
+ <p>After you launch Tomcat, you can access the MBeans exposed by
+ Tomcat via the JConsole application, which can be started with the
+ following command:
+ </p>
<pre class="source">jconsole</pre>
- <p>If you prefer MX4J to access your components via a web-based
- interface, here is a short summary of the steps to follow. After
- <a href="http://mx4j.sourceforge.net/">downloading MX4J</a>, place
- the <em>mx4j-impl.jar</em> file in the <em>$TOMCAT_HOME/bin/</em>
- directory, and the <em>mx4j-tools.jar</em> file in the
- <em>$TOMCAT_HOME/common/lib/</em> directory. Once that is done,
- add the following lines to the
- <em>$TOMCAT_HOME/bin/catalina.sh</em> shell script:
- </p>
+ <p>If you prefer MX4J to access your components via a web-based
+ interface, here is a short summary of the steps to follow. After
+ <a href="http://mx4j.sourceforge.net/">downloading MX4J</a>, place
+ the <em>mx4j-impl.jar</em> file in the <em>$TOMCAT_HOME/bin/</em>
+ directory, and the <em>mx4j-tools.jar</em> file in the
+ <em>$TOMCAT_HOME/common/lib/</em> directory. Once that is done,
+ add the following lines to the
+ <em>$TOMCAT_HOME/bin/catalina.sh</em> shell script:
+ </p>
<div class="source"><pre><!-- at the beginning of the file -->
CATALINA_OPTS="-Dcom.sun.management.jmxremote"
@@ -434,9 +423,9 @@ CATALINA_OPTS="$CATALINA_OPTS -Djavax.management.builder.initial=mx4j.server.MX4
<!-- in the "Add on extra jar files to CLASSPATH" section -->
CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/mx4j-impl.jar</pre></div>
- <p>Finally, declare a new <code>Connector</code> in the
- <em>$TOMCAT_HOME/conf/server.xml</em> file: </p>
-
+ <p>Finally, declare a new <code>Connector</code> in the
+ <em>$TOMCAT_HOME/conf/server.xml</em> file: </p>
+
<pre class="prettyprint source"><Connector port="8050"
handler.list="mx"
mx.enabled="true"
@@ -444,19 +433,19 @@ CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/mx4j-impl.jar</pre></div>
mx.httpPort="8082"
protocol="AJP/1.3" /></pre>
- <p> Once Tomcat is started, you should be able to reach your JMX
- components by pointing your browser at the following URL:
- </p>
+ <p> Once Tomcat is started, you should be able to reach your JMX
+ components by pointing your browser at the following URL:
+ </p>
<pre class="source">http://localhost:8082/</pre>
- <h3>Configuring Jetty</h3>
-
- <p>
- Configuring Jetty to publish JMX components requires a few modifications to the
- <em>$JETTY_HOME/etc/jetty.xml</em> configuration file. Here are the elements that need to be
- added:
- </p>
+ <h3>Configuring Jetty</h3>
+
+ <p>
+ Configuring Jetty to publish JMX components requires a few modifications to the
+ <em>$JETTY_HOME/etc/jetty.xml</em> configuration file. Here are the elements that need to be
+ added:
+ </p>
<pre class="prettyprint source"><Call id="MBeanServer" class="java.lang.management.ManagementFactory" name="getPlatformMBeanServer"/>
<!-- initialize the Jetty MBean container -->
@@ -472,15 +461,15 @@ CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/mx4j-impl.jar</pre></div>
</Call>
</Get></pre>
- <p>Once Jetty is started with this configuration, all available
- components can be reviewed at:
- </p>
+ <p>Once Jetty is started with this configuration, all available
+ components can be reviewed at:
+ </p>
<pre class="prettyprint source">http://localhost:8082/</pre>
- <p>Logback-access' <code>RequestLogImpl</code> should be
- available, including its <code>start()</code> and
- <code>stop()</code> methods.
- </p>
+ <p>Logback-access' <code>RequestLogImpl</code> should be
+ available, including its <code>start()</code> and
+ <code>stop()</code> methods.
+ </p>
<h2><a name="teeFilter"
@@ -533,7 +522,7 @@ CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/mx4j-impl.jar</pre></div>
<pattern>%fullRequest%n%n%fullResponse</pattern>
</encoder>
</appender>
-
+
<appender-ref ref="STDOUT" />
</configuration></pre>
diff --git a/docs/beagle/index.html b/docs/beagle/index.html
index 4323e7c..e88e254 100644
--- a/docs/beagle/index.html
+++ b/docs/beagle/index.html
@@ -23,9 +23,6 @@
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="../templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="../templates/right.js" type="text/javascript"></script>
- </div>
<div id="content">
diff --git a/docs/bugreport.html b/docs/bugreport.html
index 75f032e..253034b 100644
--- a/docs/bugreport.html
+++ b/docs/bugreport.html
@@ -15,10 +15,6 @@
<div id="left">
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script type="text/javascript" src="templates/right.js" ></script>
- </div>
-x
<div id="content">
diff --git a/docs/cla.txt b/docs/cla.txt
index ed13608..cce3714 100644
--- a/docs/cla.txt
+++ b/docs/cla.txt
@@ -1,23 +1,21 @@
- QOS.CH Sarl
+ QOS.ch
Individual Contributor License Agreement ("Agreement")
This agreement is an adaptation of the Apache Software Foundation ICL
-agreement where references to ASF have been replaced by QOS.CH. We
-thank the ASF for allowing QOS.CH Sarl to make use of their ICL
-agreement.
-
-Thank you for your interest in QOS.CH Sarl, hereafter referred to as
-just QOS.CH. In order to clarify the intellectual property license
-granted with Contributions from any person or entity, QOS.CH must have
-a Contributor License Agreement ("CLA") on file that has been signed
-by each Contributor, indicating agreement to the license terms
-below. This license is for your protection as a Contributor as well as
-the protection of QOS.CH and its users; it does not change your rights
-to use your own Contributions for any other purpose. If you have not
-already done so, please complete and send an original signed Agreement
-to QOS.CH, rue de la Ria 8B, 1462 Yvonand, Switzerland. Please read
-this document carefully before signing and keep a copy for your
-records.
+agreement where references to ASF have been replaced by QOS.ch. We
+thank the ASF for allowing QOS.ch to make use of their ICL agreement.
+
+Thank you for your interest in QOS.ch. In order to clarify the
+intellectual property license granted with Contributions from any
+person or entity, QOS.ch must have a Contributor License Agreement
+("CLA") on file that has been signed by each Contributor, indicating
+agreement to the license terms below. This license is for your
+protection as a Contributor as well as the protection of QOS.ch and
+its users; it does not change your rights to use your own
+Contributions for any other purpose. If you have not already done so,
+please complete and send an original signed Agreement to QOS.ch, rue
+Enning 4, 1003 Lausanne, Switzerland. Please read this document
+carefully before signing and keep a copy for your records.
Full name: ____________________________ E-Mail: ___________________
@@ -29,17 +27,17 @@ records.
You accept and agree to the following terms and conditions for Your
-present and future Contributions submitted QOS.CH. In return, QOS.CH
+present and future Contributions submitted QOS.ch. In return, QOS.ch
shall not use Your Contributions in a way that is contrary to the
-public benefit. Except for the license granted herein to QOS.CH and
-recipients of software distributed by QOS.CH, You reserve all right,
+public benefit. Except for the license granted herein to QOS.ch and
+recipients of software distributed by QOS.ch, You reserve all right,
title, and interest in and to Your Contributions.
1. Definitions.
"You" (or "Your") shall mean the copyright owner or legal entity
authorized by the copyright owner that is making this Agreement
- with QOS.CH. For legal entities, the entity making a Contribution
+ with QOS.ch. For legal entities, the entity making a Contribution
and all other entities that control, are controlled by, or are
under common control with that entity are considered to be a single
Contributor. For the purposes of this definition, "control" means
@@ -50,28 +48,28 @@ title, and interest in and to Your Contributions.
"Contribution" shall mean any original work of authorship,
including any modifications or additions to an existing work, that
- is intentionally submitted by You to QOS.CH for inclusion in, or
- documentation of, any of the products owned or managed by QOS.CH
+ is intentionally submitted by You to QOS.ch for inclusion in, or
+ documentation of, any of the products owned or managed by QOS.ch
(the "Work"). For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
- to QOS.CH or its representatives, including but not limited to
+ to QOS.ch or its representatives, including but not limited to
communication on electronic mailing lists, source code control
systems, and issue tracking systems that are managed by, or on
- behalf of, QOS.CH for the purpose of discussing and improving the
+ behalf of, QOS.ch for the purpose of discussing and improving the
Work, but excluding communication that is conspicuously marked or
otherwise designated in writing by You as "Not a Contribution."
2. Grant of Copyright License. Subject to the terms and conditions of
- this Agreement, You hereby grant to QOS.CH and to recipients of
- software distributed by QOS.CH a perpetual, worldwide,
+ this Agreement, You hereby grant to QOS.ch and to recipients of
+ software distributed by QOS.ch a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable copyright
license to reproduce, prepare derivative works of, publicly
display, publicly perform, sublicense, and distribute Your
Contributions and such derivative works.
3. Grant of Patent License. Subject to the terms and conditions of
- this Agreement, You hereby grant to QOS.CH and to recipients of
- software distributed by QOS.CH a perpetual, worldwide,
+ this Agreement, You hereby grant to QOS.ch and to recipients of
+ software distributed by QOS.ch a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable (except as
stated in this section) patent license to make, have made, use,
offer to sell, sell, import, and otherwise transfer the Work, where
@@ -91,7 +89,7 @@ title, and interest in and to Your Contributions.
that you create that includes your Contributions, you represent
that you have received permission to make Contributions on behalf
of that employer, that your employer has waived such rights for
- your Contributions to QOS.CH.
+ your Contributions to QOS.ch.
5. You represent that each of Your Contributions is Your original
creation (see section 7 for submissions on behalf of others). You
@@ -111,14 +109,14 @@ title, and interest in and to Your Contributions.
INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
7. Should You wish to submit work that is not Your original creation,
- You may submit it to QOS.CH separately from any Contribution,
+ You may submit it to QOS.ch separately from any Contribution,
identifying the complete details of its source and of any license
or other restriction (including, but not limited to, related
patents, trademarks, and license agreements) of which you are
personally aware, and conspicuously marking the work as "Submitted
on behalf of a third-party: [named here]".
-8. You agree to notify QOS.CH of any facts or circumstances of which
+8. You agree to notify QOS.ch of any facts or circumstances of which
you become aware that would make these representations inaccurate
in any respect.
diff --git a/docs/codes.html b/docs/codes.html
index eee7f2a..36d0468 100644
--- a/docs/codes.html
+++ b/docs/codes.html
@@ -31,10 +31,6 @@
<div id="left">
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script type="text/javascript" src="templates/right.js" ></script>
- </div>
-
<div id="content">
<h2><a name="top">Logback error messages and their meanings</a></h2>
@@ -287,21 +283,7 @@
<code>RollingPolicy</code> at the same time.
</p>
- <!-- ============================================================= -->
-
- <h3 class="doAnchor" name="#sat_missing_integer_token">Missing
- integer token, that is %i, in FileNamePattern [...].
-
- </h3>
- <p>The %i conversion token is mandatory for <a
- href="manual/appenders.html#SizeAndTimeBasedFNATP">size and time
- based archiving</a>. In case the %i token is missing,
- <code>SizeAndTimeBasedFNATP</code> attached to
- <code>RollingFileAppender</code> will detect the omission and will
- not start.
- </p>
-
<!-- ============================================================= -->
@@ -398,52 +380,7 @@
<code>RollingFileAppender</code> will emit an error message and
refuse to start.</p>
- <!-- ============================================================= -->
-
- <h3 class="doAnchor" name="rfa_collision_in_dateFormat">The date
- format in <span class="option">fileNamePattern</span> will result in
- collisions in the names of archived log files.
- </h3>
-
- <p>This error message is output when the date time pattern in the %d
- token within the <span class="option">fileNamePattern</span> is not
- collision free. For example, the following
- code>fileNamePattern</code> will result in the same log archive
- every day of the week after the first week of the month.
- </p>
-
- <pre class="source">myapp-%d{yyyy-MM-<span class="bold red">uu</span>}.log.zip</pre>
-
- <p>As such collisions will result in log data loss,
- <code>RollingFileAppender</code> will check for a variety of such
- possible collisions and will not start if any collisions are
- detected.</p>
-
- <!-- ============================================================= -->
-
- <h3 class="doAnchor" name="earlier_fa_collision"><span
- class="option">File</span>/<span
- class="option">FileNamePattern</span> option has the same value "..." as
- that given for appender [...] defined earlier.
- </h3>
-
-
- <p>If a <code>FileAppender</code>/<code>RollingFileAppender</code>
- defined earlier has the same <span class="option">File</span> option
- as the current appender, then those two appenders are in collision
- as <code>FileAppender</code> instances cannot share the same output
- target. To prevent loss of data, the current appender will not
- start. Make sure that each appender has a unique <span
- class="option">File</span> option.
- </p>
-
- <p>By analogy the same restriction applies to the <span
- class="option">FileNamePattern</span> option of
- RollingFileAppender. Make sure that each RollingFileAppender has a
- unique <span class="option">FileNamePattern</span> option</p>
-
- <!-- =============================================================
- -->
+ <!-- ============================================================= -->
<h3 class="doAnchor" name="renamingError">Failed to rename file [x]
as [y].</h3>
@@ -473,22 +410,18 @@
permission which is different than the permission to "write" to the
file.</p>
- <p class="highlight">File rename operations during rollover can be
- avoided altogether by omitting the <span class="option">file</span>
- property in RollingFileAppender.</p>
<p>In practice, it can be hard to set the right permissions or to
- ensure that there are no file handle references to log files.</p>
-
- <p>Under many circumstances, it can be more robust to avoid file
- renaming during rollover altogether. This is as easy as omitting the
- <span class="option">file</span> property in
- <code>RollingFileAppender</code>, as shown in the next configuration
- snippet.
+ ensure that there are no file handle references to log files. Under
+ such circumstances, it can be easier to avoid file renaming
+ altogether. File renaming can be avoided by omitting the <span
+ class="option">file</span> property in
+ <code>TimeBasedRollingPolicy</code>, as shown in the next
+ configuration snippet.
</p>
<pre class="prettyprint source"><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <b><!-- <span class="option">file</span> property left unset/blank --></b>
+ <!-- <span class="option">file</span> property left unset/blank -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>mylog.%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
@@ -507,8 +440,8 @@
<p>On the Unix platform, the basic/quick rename method supplied by
the JDK does not work if the source and target files are located on
different file systems. In order to deal with this contingency,
- logback will resort to renaming by copying if all of the following
- three conditions are met:</p>
+ logback will resort to renaming by copying if all following three
+ conditions are met:</p>
<ol>
<li>quick renaming fails, </li>
@@ -522,10 +455,6 @@
<p>The code for determining the file system of a file requires Java
7. No rename by copying will be performed on Java 6 or earlier.</p>
- <p>As explained in the Windows section above, renaming can be
- avoided altogether by omitting the <span class="option">file</span>
- property.
- </p>
<!-- ============================================================= -->
<h3 class="doAnchor" name="fwrp_parentFileName_not_set">The <span
@@ -714,7 +643,47 @@ return false;</pre>
</configuration>
</pre>
-
+ <!-- =========================================================== -->
+
+ <h3 class="doAnchor" name="remote_no_host">No remote host or address
+ is set for <code>SocketRemote</code>
+
+ </h3>
+
+ <p>A remote host or address is mandatory for SocketRemote. </p>
+ <p>You can specify the remote host in the configuration file
+ as follows.
+ </p>
+
+ <pre class="prettyprint source"><remote class="ch.qos.logback.classic.net.SocketRemote">
+ ...
+ <host>127.0.0.1</host>
+ ...
+</remote></pre>
+
+
+
+
+ <!-- ============================================================= -->
+
+ <h3 class="doAnchor" name="socket_no_port">No remote port is set for
+ <code>SocketRemote</code>
+ </h3>
+
+ <p>A remote port is mandatory for SocketRemote.</p>
+
+ <p>You can specify the remote port in the configuration file
+ like this:
+ </p>
+
+ <pre class="prettyprint source"><remote class="ch.qos.logback.classic.net.SocketRemote">
+ ...
+ <port>4560</port>
+ ...
+</remote></pre>
+
+
+
<script src="templates/footer.js" type="text/javascript"></script>
</div>
</body>
diff --git a/docs/css/maven-base.css b/docs/css/maven-base.css
index 53153e9..584ba23 100644
--- a/docs/css/maven-base.css
+++ b/docs/css/maven-base.css
@@ -1,155 +1,151 @@
-body {
- margin: 0px;
- padding: 0px;
-}
-img {
- border:none;
-}
-table {
- padding:0px;
- width: 100%;
- margin-left: -2px;
- margin-right: -2px;
-}
-acronym {
- cursor: help;
- border-bottom: 1px dotted #feb;
-}
-table.bodyTable th, table.bodyTable td {
- padding: 2px 4px 2px 4px;
- vertical-align: top;
-}
-div.clear{
- clear:both;
- visibility: hidden;
-}
-div.clear hr{
- display: none;
-}
-#bannerLeft, #bannerRight {
- font-size: xx-large;
- font-weight: bold;
-}
-#bannerLeft img, #bannerRight img {
- margin: 0px;
-}
-.xleft, #bannerLeft img {
- float:left;
-}
-.xright, #bannerRight {
- float:right;
-}
-#banner {
- padding: 0px;
-}
-#banner img {
- border: none;
-}
-#breadcrumbs {
- padding: 3px 10px 3px 10px;
-}
-#leftColumn {
- width: 170px;
- float:left;
- overflow: auto;
-}
-#bodyColumn {
- margin-right: 1.5em;
- margin-left: 197px;
-}
-#legend {
- padding: 8px 0 8px 0;
-}
-#navcolumn {
- padding: 8px 4px 0 8px;
-}
-#navcolumn h5 {
- margin: 0;
- padding: 0;
- font-size: small;
-}
-#navcolumn ul {
- margin: 0;
- padding: 0;
- font-size: small;
-}
-#navcolumn li {
- list-style-type: none;
- background-image: none;
- background-repeat: no-repeat;
- background-position: 0 0.4em;
- padding-left: 16px;
- list-style-position: outside;
- line-height: 1.2em;
- font-size: smaller;
-}
-#navcolumn li.expanded {
- background-image: url(../images/expanded.gif);
-}
-#navcolumn li.collapsed {
- background-image: url(../images/collapsed.gif);
-}
-#navcolumn li.none {
- text-indent: -1em;
- margin-left: 1em;
-}
-#poweredBy {
- text-align: center;
-}
-#navcolumn img {
- margin-top: 10px;
- margin-bottom: 3px;
-}
-#poweredBy img {
- display:block;
- margin: 20px 0 20px 17px;
-}
-#search img {
- margin: 0px;
- display: block;
-}
-#search #q, #search #btnG {
- border: 1px solid #999;
- margin-bottom:10px;
-}
-#search form {
- margin: 0px;
-}
-#lastPublished {
- font-size: x-small;
-}
-.navSection {
- margin-bottom: 2px;
- padding: 8px;
-}
-.navSectionHead {
- font-weight: bold;
- font-size: x-small;
-}
-.section {
- padding: 4px;
-}
-#footer {
- padding: 3px 10px 3px 10px;
- font-size: x-small;
-}
-#breadcrumbs {
- font-size: x-small;
- margin: 0pt;
-}
-.source {
- padding: 12px;
- margin: 1em 7px 1em 7px;
-}
-.source pre {
- margin: 0px;
- padding: 0px;
-}
-#navcolumn img.imageLink, .imageLink {
- padding-left: 0px;
- padding-bottom: 0px;
- padding-top: 0px;
- padding-right: 2px;
- border: 0px;
- margin: 0px;
-}
+body {
+ margin: 0px;
+ padding: 0px;
+}
+img {
+ border:none;
+}
+table {
+ padding:0px;
+ width: 100%;
+ margin-left: -2px;
+ margin-right: -2px;
+}
+acronym {
+ cursor: help;
+ border-bottom: 1px dotted #feb;
+}
+table.bodyTable th, table.bodyTable td {
+ padding: 2px 4px 2px 4px;
+ vertical-align: top;
+}
+div.clear{
+ clear:both;
+ visibility: hidden;
+}
+div.clear hr{
+ display: none;
+}
+#bannerLeft, #bannerRight {
+ font-size: xx-large;
+ font-weight: bold;
+}
+#bannerLeft img, #bannerRight img {
+ margin: 0px;
+}
+.xleft, #bannerLeft img {
+ float:left;
+}
+.xright, #bannerRight {
+ float:right;
+}
+#banner {
+ padding: 0px;
+}
+#banner img {
+ border: none;
+}
+#breadcrumbs {
+ padding: 3px 10px 3px 10px;
+}
+#leftColumn {
+ width: 170px;
+ float:left;
+ overflow: auto;
+}
+#bodyColumn {
+ margin-right: 1.5em;
+ margin-left: 197px;
+}
+#legend {
+ padding: 8px 0 8px 0;
+}
+#navcolumn {
+ padding: 8px 4px 0 8px;
+}
+#navcolumn h5 {
+ margin: 0;
+ padding: 0;
+ font-size: small;
+}
+#navcolumn ul {
+ margin: 0;
+ padding: 0;
+ font-size: small;
+}
+#navcolumn li {
+ list-style-type: none;
+ background-image: none;
+ background-repeat: no-repeat;
+ background-position: 0 0.4em;
+ padding-left: 16px;
+ list-style-position: outside;
+ line-height: 1.2em;
+ font-size: smaller;
+}
+#navcolumn li.expanded {
+ background-image: url(../images/expanded.gif);
+}
+#navcolumn li.collapsed {
+ background-image: url(../images/collapsed.gif);
+}
+#poweredBy {
+ text-align: center;
+}
+#navcolumn img {
+ margin-top: 10px;
+ margin-bottom: 3px;
+}
+#poweredBy img {
+ display:block;
+ margin: 20px 0 20px 17px;
+}
+#search img {
+ margin: 0px;
+ display: block;
+}
+#search #q, #search #btnG {
+ border: 1px solid #999;
+ margin-bottom:10px;
+}
+#search form {
+ margin: 0px;
+}
+#lastPublished {
+ font-size: x-small;
+}
+.navSection {
+ margin-bottom: 2px;
+ padding: 8px;
+}
+.navSectionHead {
+ font-weight: bold;
+ font-size: x-small;
+}
+.section {
+ padding: 4px;
+}
+#footer {
+ padding: 3px 10px 3px 10px;
+ font-size: x-small;
+}
+#breadcrumbs {
+ font-size: x-small;
+ margin: 0pt;
+}
+.source {
+ padding: 12px;
+ margin: 1em 7px 1em 7px;
+}
+.source pre {
+ margin: 0px;
+ padding: 0px;
+}
+#navcolumn img.imageLink, .imageLink {
+ padding-left: 0px;
+ padding-bottom: 0px;
+ padding-top: 0px;
+ padding-right: 2px;
+ border: 0px;
+ margin: 0px;
+}
diff --git a/docs/css/print.css b/docs/css/print.css
index f09d546..26ad7f0 100644
--- a/docs/css/print.css
+++ b/docs/css/print.css
@@ -1,7 +1,7 @@
-#banner, #footer, #leftcol, #breadcrumbs, .docs #toc, .docs .courtesylinks, #leftColumn, #navColumn {
- display: none !important;
-}
-#bodyColumn, body.docs div.docs {
- margin: 0 !important;
- border: none !important
-}
+#banner, #footer, #leftcol, #breadcrumbs, .docs #toc, .docs .courtesylinks, #leftColumn, #navColumn {
+ display: none !important;
+}
+#bodyColumn, body.docs div.docs {
+ margin: 0 !important;
+ border: none !important
+}
diff --git a/docs/css/screen.css b/docs/css/screen.css
index f4c2b61..3b996d5 100644
--- a/docs/css/screen.css
+++ b/docs/css/screen.css
@@ -37,6 +37,22 @@ p.menu {
font-size: smaller;
}
+
+#leftOld {
+ position: absolute;
+ font-size: 80%;
+ left: 0px;
+ width: 15em;
+ color: #564b47;
+ margin: 4px 0px 0px 4px;
+ padding: 0px;
+ border: 1px solid #cccccc;
+ background-color: #fff8e8;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+
#left {
position: absolute;
left: 0px;
@@ -59,6 +75,7 @@ p.menu {
#left a, #right a {
display: block;
+ width: 95.5%;
margin: 0px;
padding: 2px;
border: solid 1px #fff8e8;
@@ -83,18 +100,6 @@ p.menu_header {
-moz-border-radius: 3px;
border-radius: 3px;
}
-.pub {
- text-align: center;
-}
-
-#left .pub a:hover {
- background-color: transparent;
- border: solid 0px #FFFFFF;
-}
-
-#left img {
- border: none;
-}
#left div.jobadd {
font-size: 140%;
@@ -135,6 +140,13 @@ p.menu_header {
font-size: 80%;
}
+#left img {
+ display: block;
+ margin: 20px 0 20px 17px;
+ border: none;
+ width: 90px;
+ height: 30px;
+}
#headerLine {
background-color:#FFD0A0;
diff --git a/docs/demo.html b/docs/demo.html
index 2617059..8f88992 100644
--- a/docs/demo.html
+++ b/docs/demo.html
@@ -16,10 +16,6 @@
<div id="left">
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="templates/right.js" type="text/javascript"></script>
- </div>
-
<div id="content">
diff --git a/docs/dependencies.html b/docs/dependencies.html
index b7bd49b..5559c83 100644
--- a/docs/dependencies.html
+++ b/docs/dependencies.html
@@ -17,16 +17,14 @@
<div id="left">
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script type="text/javascript" src="templates/right.js" ></script>
- </div>
-
<div id="content">
<h1>Dependencies per module</h1>
- <p>As of version 1.1.3, logback requires JDK 1.6.</p>
+ <p>As of version 1.0.12, logback requires JDK 1.6 to build,
+ however, it is inteded to run under JDK 1.5 (with the exception of
+ SSL related functionality).</p>
<p>Each logback module has a different set of dependencies. These
are listed below in a separate table per module.</p>
@@ -41,6 +39,11 @@
<tr>
<td>Overall</td>
+ <td><ul><li>JDK 1.5</li></ul></td>
+ </tr>
+
+ <tr>
+ <td>ch.qos.logback.core.net.ssl.*</td>
<td><ul><li>JDK 1.6</li></ul></td>
</tr>
@@ -48,7 +51,7 @@
<td><code>JaninoEventEvaluatorBase</code> and derived classes</td>
<td>
<ul>
- <li><a href="http://janino.net">Janino</a> version 2.7.8</li>
+ <li><a href="http://janino.net">Janino</a> version 2.6.1</li>
</ul>
</td>
</tr>
@@ -83,7 +86,7 @@
<td>Overall</td>
<td>
<ul>
- <li>JDK 1.6
+ <li>JDK 1.5
</li>
</ul>
</td>
@@ -105,7 +108,7 @@
<td>
<ul>
<li><a href="http://www.slf4j.org">slf4j-api</a> version
- <span class="big red">1.7.15 or later</span>
+ 1.7.6
</li>
</ul>
</td>
@@ -202,7 +205,7 @@
<td>ch.qos.logback.access.tomcat.*</td>
<td>
<ul>
- <li><a href="http://tomcat.apache.org">Tomcat</a> version 7.0.59
+ <li><a href="http://tomcat.apache.org">Tomcat</a> version 7.0.21
</li>
</ul>
</td>
diff --git a/docs/documentation.html b/docs/documentation.html
index 21a191d..fbc7857 100644
--- a/docs/documentation.html
+++ b/docs/documentation.html
@@ -17,9 +17,6 @@
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script type="text/javascript" src="templates/right.js" ></script>
- </div>
<div id="content">
@@ -29,9 +26,7 @@
available.</p>
<ul>
- <li><a href="manual/index.html"><b>The logback manual</b></a><ul>
- <li><a href="manual/index_ja.html">和訳 (Japanese translation)</a></li>
- </ul></li>
+ <li><a href="manual/index.html"><b>The logback manual</b></a></li>
<li><a href="reasonsToSwitch.html">Reasons to switch to logback
from log4j</a></li>
diff --git a/docs/download.html b/docs/download.html
index 387c304..3f164a3 100644
--- a/docs/download.html
+++ b/docs/download.html
@@ -10,17 +10,18 @@
<link rel="stylesheet" type="text/css" href="css/_print.css" media="print" />
<link rel="stylesheet" type="text/css" href="css/popup.css" media="screen" />
</head>
- <body>
- <script type="text/javascript">prefix='';</script>
- <script type="text/javascript" src="templates/header.js" ></script>
- <script type="text/javascript" src="js/jquery-min.js"></script>
+ <body onload="centerPopup(); loadPopup();">
+ <script type="text/javascript">prefix='';</script>
+
+ <script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js" ></script>
+ <script type="text/javascript" src="js/jquery.cookies.2.2.0.js"></script>
+ <script type="text/javascript" src="js/popup.js" ></script>
+
+ <script src="templates/header.js" type="text/javascript"></script>
<div id="left">
<noscript>Please turn on Javascript to view this menu</noscript>
- <script type="text/javascript" src="templates/left.js" ></script>
- </div>
- <div id="right">
- <script type="text/javascript" src="templates/right.js" ></script>
+ <script src="templates/left.js" type="text/javascript"></script>
</div>
<div id="popupContents">
@@ -51,8 +52,8 @@
</p>
<ul>
- <li><a href="dist/logback-1.1.9.zip">logback-1.1.9.zip</a></li>
- <li><a href="dist/logback-1.1.9.tar.gz">logback-1.1.9.tar.gz</a></li>
+ <li><a href="dist/logback-1.1.2.zip">logback-1.1.2.zip</a></li>
+ <li><a href="dist/logback-1.1.2.tar.gz">logback-1.1.2.tar.gz</a></li>
</ul>
@@ -90,10 +91,9 @@
</dt>
<dd>
- Lilith is a Logging- and AccessEvent viewer for logback.
+ <p>Lilith is a Logging- and AccessEvent viewer for logback.</p>
</dd>
- <br/>
<!-- ============================================================ -->
<dt>
<a
@@ -102,13 +102,11 @@
</dt>
<dd>
- Consists of several akka-based logback utilities, including
+ <p>Consists of several akka-based logback utilities, including
ActorAppender, HoptoadActorAppender and Logstash redis
appender.
-
+ </p>
</dd>
-
- <br/>
<!-- ============================================================ -->
<dt>
@@ -118,10 +116,11 @@
</dt>
<dd>
- Logback-Android brings the power of Logback to Android.
+ <p>Logback-Android brings the power of Logback to Android.
+ </p>
</dd>
- <br/>
+
<!-- ============================================================ -->
<dt>
<a
@@ -130,42 +129,24 @@
</dt>
<dd>
- Logback Appender writing to Amazon SimpleDB. See also <a
+ <p>Logback Appender writing to Amazon SimpleDB. See also <a
href="http://www.peecho.com/blog/logging-the-cloud-with-simpledb.html">Logging
- the cloud with SimpleDB</a>.
+ the cloud with SimpleDB</a>.</p>
</dd>
- <br/>
<!-- ============================================================ -->
<dt>
- <a
- href="https://github.com/carlspring/logback-configuration/">logback-configuration</a>
- by Martin Todorov
- </dt>
-
- <dd>
- A service layer (using Spring) and a REST interface which
- provides methods to: add or update loggers, resolve a log
- file, resolve the logback configuration file, and upload a
- logback configuration file and reload it.
-
- </dd>
-
- <br/>
- <!-- ============================================================ -->
- <!--
- <dt>
<a href="http://perf4j.codehaus.org/">Perf4J</a> by Alex
Devine, Doran Chakraborty et al.
</dt>
<dd>
- Perf4J is a set of utilities for calculating and displaying
- performance statistics for Java code.
+ <p>Perf4J is a set of utilities for calculating and displaying
+ performance statistics for Java code.</p>
</dd>
- -->
-
+
+
<!-- ============================================================ -->
<dt>
<a
@@ -177,18 +158,7 @@
href="http://graylog2.org/">Graylog2</a> server via GELF
messages.
</dd>
- <br/>
- <!-- ============================================================ -->
- <dt>
- <a
- href="https://github.com/sbabcoc/logback-testng">Logback-testng</a>
- by Scott Babcock
- </dt>
-
- <dd>Logback appender for TestNG Reporter. </dd>
-
- <!-- ============================================================ -->
-
+
</dl>
<p/>
diff --git a/docs/faq.html b/docs/faq.html
index 8c43313..82acc59 100644
--- a/docs/faq.html
+++ b/docs/faq.html
@@ -17,10 +17,6 @@
<div id="left">
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="templates/right.js" type="text/javascript"></script>
- </div>
-
<div id="content">
<h2>
@@ -317,8 +313,8 @@
<p>Logback jar files must be present on Jetty's class
path. These files are
- <em>logback-core-1.1.9.jar</em> and
- <em>logback-classic-1.1.9.jar</em>. These files
+ <em>logback-core-1.1.2.jar</em> and
+ <em>logback-classic-1.1.2.jar</em>. These files
should be placed under the <em>$JETTY_HOME/lib</em>
directory.
</p>
@@ -326,7 +322,7 @@
<p>Since Jetty uses an older version of SLF4J internally,
we recommend that the old version be replaced by
- <em>slf4j-api-1.7.22.jar</em>. This file can be
+ <em>slf4j-api-1.7.6.jar</em>. This file can be
downloaded from the <a
href="http://www.slf4j.org/download.html">SLF4J</a> project.
</p>
diff --git a/docs/images/follow_us.png b/docs/images/follow_us.png
deleted file mode 100644
index fe3a388..0000000
Binary files a/docs/images/follow_us.png and /dev/null differ
diff --git a/docs/images/setup/remove_evaluator_template.jpg b/docs/images/setup/remove_evaluator_template.jpg
deleted file mode 100644
index be9455d..0000000
Binary files a/docs/images/setup/remove_evaluator_template.jpg and /dev/null differ
diff --git a/docs/images/setup/remove_gen_src.jpg b/docs/images/setup/remove_gen_src.jpg
deleted file mode 100644
index 7be5c95..0000000
Binary files a/docs/images/setup/remove_gen_src.jpg and /dev/null differ
diff --git a/docs/index.html b/docs/index.html
index 68fc4b7..5655b81 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -17,10 +17,6 @@
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="templates/right.js" type="text/javascript"></script>
- </div>
-
<div id="content">
<h2>Logback Project</h2>
@@ -83,7 +79,6 @@
<li><a href="http://syncope.apache.org/">Apache Syncope</a></li>
<li><a href="http://myfaces.apache.org/tobago/">Apache Tobago</a></li>
<li><a href="http://www.jfrog.org/products.php">Artifactory</a></li>
- <li><a href="https://github.com/nhl/bootique">Bootique</a></li>
<li><a href="http://cia.sourceforge.net/">Citizen Intelligence Agency</a></li>
<li><a href="http://www.dcache.org/">dCache</a></li>
</ul>
@@ -114,7 +109,6 @@
<td valign="top">
<ul>
<li><a href="http://www.playframework.org/">Play Framework</a></li>
- <li><a href="https://github.com/psi-probe/psi-probe/">PSI probe</a></li>
<li><a href="http://www.red5.org">Red5</a></li>
<li><a href="http://scalate.fusesource.org/">Scalate</a></li>
<li><a href="http://www.scalatra.org/2.0/book/">Scalatra</a></li>
diff --git a/docs/js/dsl.js b/docs/js/dsl.js
index 92faee2..d564dc4 100644
--- a/docs/js/dsl.js
+++ b/docs/js/dsl.js
@@ -15,7 +15,7 @@ function asGroovy(id) {
inner = inner.replace(/</gi, '<');
inner = inner.replace(/>/gi, '>');
- inner = inner.replace(/<span class="[^"]*"?>/gi, '');
+ inner = inner.replace(/<span class="?\w{3,5}"?>/gi, '');
inner = inner.replace(/<\/span>/gi, '');
inner = inner.replace(/<br>/gi, '');
inner = inner.replace(/ /gi, '');
diff --git a/docs/js/jquery.cookies.2.2.0.js b/docs/js/jquery.cookies.2.2.0.js
new file mode 100644
index 0000000..6b7183a
--- /dev/null
+++ b/docs/js/jquery.cookies.2.2.0.js
@@ -0,0 +1,450 @@
+/**
+ * Copyright (c) 2005 - 2010, James Auldridge
+ * All rights reserved.
+ *
+ * Licensed under the BSD, MIT, and GPL (your choice!) Licenses:
+ * http://code.google.com/p/cookies/wiki/License
+ *
+ */
+var jaaulde = window.jaaulde || {};
+jaaulde.utils = jaaulde.utils || {};
+jaaulde.utils.cookies = ( function()
+{
+ var resolveOptions, assembleOptionsString, parseCookies, constructor, defaultOptions = {
+ expiresAt: null,
+ path: '/',
+ domain: null,
+ secure: false
+ };
+ /**
+ * resolveOptions - receive an options object and ensure all options are present and valid, replacing with defaults where necessary
+ *
+ * @access private
+ * @static
+ * @parameter Object options - optional options to start with
+ * @return Object complete and valid options object
+ */
+ resolveOptions = function( options )
+ {
+ var returnValue, expireDate;
+
+ if( typeof options !== 'object' || options === null )
+ {
+ returnValue = defaultOptions;
+ }
+ else
+ {
+ returnValue = {
+ expiresAt: defaultOptions.expiresAt,
+ path: defaultOptions.path,
+ domain: defaultOptions.domain,
+ secure: defaultOptions.secure
+ };
+
+ if( typeof options.expiresAt === 'object' && options.expiresAt instanceof Date )
+ {
+ returnValue.expiresAt = options.expiresAt;
+ }
+ else if( typeof options.hoursToLive === 'number' && options.hoursToLive !== 0 )
+ {
+ expireDate = new Date();
+ expireDate.setTime( expireDate.getTime() + ( options.hoursToLive * 60 * 60 * 1000 ) );
+ returnValue.expiresAt = expireDate;
+ }
+
+ if( typeof options.path === 'string' && options.path !== '' )
+ {
+ returnValue.path = options.path;
+ }
+
+ if( typeof options.domain === 'string' && options.domain !== '' )
+ {
+ returnValue.domain = options.domain;
+ }
+
+ if( options.secure === true )
+ {
+ returnValue.secure = options.secure;
+ }
+ }
+
+ return returnValue;
+ };
+ /**
+ * assembleOptionsString - analyze options and assemble appropriate string for setting a cookie with those options
+ *
+ * @access private
+ * @static
+ * @parameter options OBJECT - optional options to start with
+ * @return STRING - complete and valid cookie setting options
+ */
+ assembleOptionsString = function( options )
+ {
+ options = resolveOptions( options );
+
+ return (
+ ( typeof options.expiresAt === 'object' && options.expiresAt instanceof Date ? '; expires=' + options.expiresAt.toGMTString() : '' ) +
+ '; path=' + options.path +
+ ( typeof options.domain === 'string' ? '; domain=' + options.domain : '' ) +
+ ( options.secure === true ? '; secure' : '' )
+ );
+ };
+ /**
+ * parseCookies - retrieve document.cookie string and break it into a hash with values decoded and unserialized
+ *
+ * @access private
+ * @static
+ * @return OBJECT - hash of cookies from document.cookie
+ */
+ parseCookies = function()
+ {
+ var cookies = {}, i, pair, name, value, separated = document.cookie.split( ';' ), unparsedValue;
+ for( i = 0; i < separated.length; i = i + 1 )
+ {
+ pair = separated[i].split( '=' );
+ name = pair[0].replace( /^\s*/, '' ).replace( /\s*$/, '' );
+
+ try
+ {
+ value = decodeURIComponent( pair[1] );
+ }
+ catch( e1 )
+ {
+ value = pair[1];
+ }
+
+ if( typeof JSON === 'object' && JSON !== null && typeof JSON.parse === 'function' )
+ {
+ try
+ {
+ unparsedValue = value;
+ value = JSON.parse( value );
+ }
+ catch( e2 )
+ {
+ value = unparsedValue;
+ }
+ }
+
+ cookies[name] = value;
+ }
+ return cookies;
+ };
+
+ constructor = function(){};
+
+ /**
+ * get - get one, several, or all cookies
+ *
+ * @access public
+ * @paramater Mixed cookieName - String:name of single cookie; Array:list of multiple cookie names; Void (no param):if you want all cookies
+ * @return Mixed - Value of cookie as set; Null:if only one cookie is requested and is not found; Object:hash of multiple or all cookies (if multiple or all requested);
+ */
+ constructor.prototype.get = function( cookieName )
+ {
+ var returnValue, item, cookies = parseCookies();
+
+ if( typeof cookieName === 'string' )
+ {
+ returnValue = ( typeof cookies[cookieName] !== 'undefined' ) ? cookies[cookieName] : null;
+ }
+ else if( typeof cookieName === 'object' && cookieName !== null )
+ {
+ returnValue = {};
+ for( item in cookieName )
+ {
+ if( typeof cookies[cookieName[item]] !== 'undefined' )
+ {
+ returnValue[cookieName[item]] = cookies[cookieName[item]];
+ }
+ else
+ {
+ returnValue[cookieName[item]] = null;
+ }
+ }
+ }
+ else
+ {
+ returnValue = cookies;
+ }
+
+ return returnValue;
+ };
+ /**
+ * filter - get array of cookies whose names match the provided RegExp
+ *
+ * @access public
+ * @paramater Object RegExp - The regular expression to match against cookie names
+ * @return Mixed - Object:hash of cookies whose names match the RegExp
+ */
+ constructor.prototype.filter = function( cookieNameRegExp )
+ {
+ var cookieName, returnValue = {}, cookies = parseCookies();
+
+ if( typeof cookieNameRegExp === 'string' )
+ {
+ cookieNameRegExp = new RegExp( cookieNameRegExp );
+ }
+
+ for( cookieName in cookies )
+ {
+ if( cookieName.match( cookieNameRegExp ) )
+ {
+ returnValue[cookieName] = cookies[cookieName];
+ }
+ }
+
+ return returnValue;
+ };
+ /**
+ * set - set or delete a cookie with desired options
+ *
+ * @access public
+ * @paramater String cookieName - name of cookie to set
+ * @paramater Mixed value - Any JS value. If not a string, will be JSON encoded; NULL to delete
+ * @paramater Object options - optional list of cookie options to specify
+ * @return void
+ */
+ constructor.prototype.set = function( cookieName, value, options )
+ {
+ if( typeof options !== 'object' || options === null )
+ {
+ options = {};
+ }
+
+ if( typeof value === 'undefined' || value === null )
+ {
+ value = '';
+ options.hoursToLive = -8760;
+ }
+
+ else if( typeof value !== 'string' )
+ {
+ if( typeof JSON === 'object' && JSON !== null && typeof JSON.stringify === 'function' )
+ {
+ value = JSON.stringify( value );
+ }
+ else
+ {
+ throw new Error( 'cookies.set() received non-string value and could not serialize.' );
+ }
+ }
+
+
+ var optionsString = assembleOptionsString( options );
+
+ document.cookie = cookieName + '=' + encodeURIComponent( value ) + optionsString;
+ };
+ /**
+ * del - delete a cookie (domain and path options must match those with which the cookie was set; this is really an alias for set() with parameters simplified for this use)
+ *
+ * @access public
+ * @paramater MIxed cookieName - String name of cookie to delete, or Bool true to delete all
+ * @paramater Object options - optional list of cookie options to specify ( path, domain )
+ * @return void
+ */
+ constructor.prototype.del = function( cookieName, options )
+ {
+ var allCookies = {}, name;
+
+ if( typeof options !== 'object' || options === null )
+ {
+ options = {};
+ }
+
+ if( typeof cookieName === 'boolean' && cookieName === true )
+ {
+ allCookies = this.get();
+ }
+ else if( typeof cookieName === 'string' )
+ {
+ allCookies[cookieName] = true;
+ }
+
+ for( name in allCookies )
+ {
+ if( typeof name === 'string' && name !== '' )
+ {
+ this.set( name, null, options );
+ }
+ }
+ };
+ /**
+ * test - test whether the browser is accepting cookies
+ *
+ * @access public
+ * @return Boolean
+ */
+ constructor.prototype.test = function()
+ {
+ var returnValue = false, testName = 'cT', testValue = 'data';
+
+ this.set( testName, testValue );
+
+ if( this.get( testName ) === testValue )
+ {
+ this.del( testName );
+ returnValue = true;
+ }
+
+ return returnValue;
+ };
+ /**
+ * setOptions - set default options for calls to cookie methods
+ *
+ * @access public
+ * @param Object options - list of cookie options to specify
+ * @return void
+ */
+ constructor.prototype.setOptions = function( options )
+ {
+ if( typeof options !== 'object' )
+ {
+ options = null;
+ }
+
+ defaultOptions = resolveOptions( options );
+ };
+
+ return new constructor();
+} )();
+
+( function()
+{
+ if( window.jQuery )
+ {
+ ( function( $ )
+ {
+ $.cookies = jaaulde.utils.cookies;
+
+ var extensions = {
+ /**
+ * $( 'selector' ).cookify - set the value of an input field, or the innerHTML of an element, to a cookie by the name or id of the field or element
+ * (field or element MUST have name or id attribute)
+ *
+ * @access public
+ * @param options OBJECT - list of cookie options to specify
+ * @return jQuery
+ */
+ cookify: function( options )
+ {
+ return this.each( function()
+ {
+ var i, nameAttrs = ['name', 'id'], name, $this = $( this ), value;
+
+ for( i in nameAttrs )
+ {
+ if( ! isNaN( i ) )
+ {
+ name = $this.attr( nameAttrs[ i ] );
+ if( typeof name === 'string' && name !== '' )
+ {
+ if( $this.is( ':checkbox, :radio' ) )
+ {
+ if( $this.attr( 'checked' ) )
+ {
+ value = $this.val();
+ }
+ }
+ else if( $this.is( ':input' ) )
+ {
+ value = $this.val();
+ }
+ else
+ {
+ value = $this.html();
+ }
+
+ if( typeof value !== 'string' || value === '' )
+ {
+ value = null;
+ }
+
+ $.cookies.set( name, value, options );
+
+ break;
+ }
+ }
+ }
+ } );
+ },
+ /**
+ * $( 'selector' ).cookieFill - set the value of an input field or the innerHTML of an element from a cookie by the name or id of the field or element
+ *
+ * @access public
+ * @return jQuery
+ */
+ cookieFill: function()
+ {
+ return this.each( function()
+ {
+ var n, getN, nameAttrs = ['name', 'id'], name, $this = $( this ), value;
+
+ getN = function()
+ {
+ n = nameAttrs.pop();
+ return !! n;
+ };
+
+ while( getN() )
+ {
+ name = $this.attr( n );
+ if( typeof name === 'string' && name !== '' )
+ {
+ value = $.cookies.get( name );
+ if( value !== null )
+ {
+ if( $this.is( ':checkbox, :radio' ) )
+ {
+ if( $this.val() === value )
+ {
+ $this.attr( 'checked', 'checked' );
+ }
+ else
+ {
+ $this.removeAttr( 'checked' );
+ }
+ }
+ else if( $this.is( ':input' ) )
+ {
+ $this.val( value );
+ }
+ else
+ {
+ $this.html( value );
+ }
+ }
+
+ break;
+ }
+ }
+ } );
+ },
+ /**
+ * $( 'selector' ).cookieBind - call cookie fill on matching elements, and bind their change events to cookify()
+ *
+ * @access public
+ * @param options OBJECT - list of cookie options to specify
+ * @return jQuery
+ */
+ cookieBind: function( options )
+ {
+ return this.each( function()
+ {
+ var $this = $( this );
+ $this.cookieFill().change( function()
+ {
+ $this.cookify( options );
+ } );
+ } );
+ }
+ };
+
+ $.each( extensions, function( i )
+ {
+ $.fn[i] = this;
+ } );
+
+ } )( window.jQuery );
+ }
+} )();
\ No newline at end of file
diff --git a/docs/js/popup.js b/docs/js/popup.js
new file mode 100644
index 0000000..4c70b2f
--- /dev/null
+++ b/docs/js/popup.js
@@ -0,0 +1,102 @@
+/***************************/
+//@Author: Adrian "yEnS" Mato Gondelle
+//@website: www.yensdesign.com
+//@email: yensamg at gmail.com
+//@license: Feel free to use it, but keep this credits please!
+/***************************/
+
+//SETTING UP OUR POPUP
+//0 means disabled; 1 means enabled;
+var popupStatus = 0;
+
+//loading popup with jQuery magic!
+function loadPopup() {
+ var surveyCookie = $.cookies.get("SURVEY");
+ if(surveyCookie) {
+ popupStatus = 0;
+ return;
+ }
+ //loads popup only if it is disabled
+ if(popupStatus==0){
+ $("#backgroundPopup").css({
+ "opacity": "0.7"
+ });
+ $("#backgroundPopup").fadeIn("slow");
+ $("#popupContents").fadeIn("slow");
+ popupStatus = 1;
+ }
+}
+
+function getDateInSixMonths() {
+ var date = new Date();
+ date.setDate(date.getDate()+180);
+ return date;
+}
+
+//disabling popup with jQuery magic!
+function disablePopup(){
+ //disables popup only if it is enabled
+ if(popupStatus==1){
+ $("#backgroundPopup").fadeOut("slow");
+ $("#popupContents").fadeOut("slow");
+ popupStatus = 0;
+ $.cookies.set("SURVEY", "NO", {expiresAt: getDateInSixMonths()});
+ }
+}
+
+//centering popup
+function centerPopup(){
+ //request data for centering
+ var windowWidth = document.documentElement.clientWidth;
+ var windowHeight = document.documentElement.clientHeight;
+ var popupHeight = $("#popupContents").height();
+ var popupWidth = $("#popupContents").width();
+ //centering
+ $("#popupContents").css({
+ "position": "absolute",
+ "top": windowHeight/2-popupHeight/2,
+ "left": windowWidth/2-popupWidth/2
+ });
+ //only need force for IE6
+
+ $("#backgroundPopup").css({
+ "height": windowHeight
+ });
+
+}
+
+
+//CONTROLLING EVENTS IN jQuery
+$(document).ready(function(){
+
+ //LOADING POPUP
+ //Click the button event!
+ $("#button").click(function(){
+ //centering with css
+ centerPopup();
+ //load popup
+ loadPopup();
+ });
+
+ //CLOSING POPUP
+ //Click the x event!
+ $("#popupContentsClose").click(function(){
+ disablePopup();
+ });
+ //Click out event!
+ $("#backgroundPopup").click(function(){
+ //disablePopup();
+ });
+ //Press Escape event!
+ $(document).keypress(function(e){
+ if(e.keyCode==27 && popupStatus==1){
+ disablePopup();
+ }
+ });
+
+ $("#announce").click(function(){
+ $.cookies.set("SURVEY", "YES", {expiresAt: getDateInSixMonths()});
+ window.location='http://www.qos.ch/mailman/listinfo/announce';
+ });
+});
+
diff --git a/docs/license.html b/docs/license.html
index dfc4fa2..e9c4a32 100644
--- a/docs/license.html
+++ b/docs/license.html
@@ -17,10 +17,6 @@
<div id="left">
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script type="text/javascript" src="templates/right.js" ></script>
- </div>
-
<div id="content">
<div class="section">
@@ -33,7 +29,7 @@
formally:</p>
<p class="source">Logback: the reliable, generic, fast and flexible logging framework.
-Copyright (C) 1999-2017, QOS.ch. All rights reserved.
+Copyright (C) 1999-2012, QOS.ch. All rights reserved.
This program and the accompanying materials are dual-licensed under
either the terms of the <a href="http://www.eclipse.org/legal/epl-v10.html">Eclipse Public License v1.0</a> as published by
diff --git a/docs/mailinglist.html b/docs/mailinglist.html
index 92b7477..cb55a46 100644
--- a/docs/mailinglist.html
+++ b/docs/mailinglist.html
@@ -18,10 +18,6 @@
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script type="text/javascript" src="templates/right.js" ></script>
- </div>
-
<div id="content">
<h2>Project Mailing Lists</h2>
diff --git a/docs/manual/appenders.html b/docs/manual/appenders.html
index 75e296b..ff04d78 100644
--- a/docs/manual/appenders.html
+++ b/docs/manual/appenders.html
@@ -28,9 +28,6 @@
<h1>Chapter 4: Appenders</h1>
- <a href="appenders_ja.html">和訳 (Japanese translation)</a>
-
-
<div class="quote">
<p><em>There is so much to tell about the Western country in
@@ -351,7 +348,7 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
<p class="example">Example: ConsoleAppender configuration
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-Console.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback_Console');">View as .groovy</span>
@@ -520,7 +517,7 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
</p>
<p class="example">Example: FileAppender configuration
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-fileAppender.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-fileAppender');">View as .groovy</span>
<pre id="logback-fileAppender" class="prettyprint source"><configuration>
@@ -561,7 +558,7 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
<p class="example">Example: Uniquely named FileAppender
configuration by timestamp
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-timestamp.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-timestamp');">View as .groovy</span>
<pre id="logback-timestamp" class="prettyprint source"><configuration>
@@ -597,7 +594,7 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
denotes the date pattern used to convert the current time (at which
the configuration file is parsed) into a string. The date pattern
should follow the conventions defined in <a
- href="https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a>. The
+ href="http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a>. The
<span class="attr">timeReference</span> attribute denotes the time
reference for the time stamp. The default is the
interpretation/parsing time of the configuration file, i.e. the
@@ -610,7 +607,7 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
<p>Experiment with the <code><timestamp></code> element by
running the command:</p>
- <p class="command">java chapters.appenders.ConfigurationTester src/main/resources/chapters/appenders/conf/logback-timestamp.xml</p>
+ <p class="command">java chapters.appenders.ConfigurationTester src/main/java/chapters/appenders/conf/logback-timestamp.xml</p>
<p>To use the logger context birth date as time reference, you
would set the <span class="attr">timeReference</span> attribute to
@@ -618,7 +615,7 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
<p class="example">Example: Timestamp using context birth date as time reference
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-timestamp-contextBirth.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp-contextBirth.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-timestamp-contextBirth');">View as .groovy</span>
<pre id="logback-timestamp-contextBirth" class="prettyprint source"><configuration>
@@ -772,7 +769,9 @@ public interface RollingPolicy extends LifeCycle {
================= -->
- <h4 class="doAnchor" name="TimeBasedRollingPolicy">TimeBasedRollingPolicy </h4>
+ <h4 class="doAnchor"
+ name="TimeBasedRollingPolicy">TimeBasedRollingPolicy
+ </h4>
<p><a
href="../xref/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.html">
@@ -839,69 +838,28 @@ public interface RollingPolicy extends LifeCycle {
interpreted as directory separators.
</p>
- <h5>Multiple %d specifiers</h5>
-
- <p>It is possible to specify multiple %d specifiers but only
- one of which can be primary, i.e. used to infer the rollover
+ <p>It is possible to specify multiple %d tokens but only one
+ of which can be primary, i.e. used to infer the rollover
period. All other tokens <em>must</em> be marked as auxiliary
by passing the 'aux' parameter (see examples below).</p>
-
- <p>Multiple %d specifiers allow you to organize archive files
- in a folder structure different than that of the roll-over
- period. For example, the file name pattern shown below
- organizes log folders by year and month but roll-over log
- files every day at midnight.</p>
-
- <pre>/var/log/<b>%d{yyyy/MM, aux}</b>/myapplication.<b>%d{yyyy-MM-dd}</b>.log</pre>
-
- <h5>TimeZone</h5>
-
- <p>Under certain circumstances, you might wish to roll-over
- log files according to a clock in a timezone different than
- that of the host. It is possible to pass a timezone argument
- following the date-and-time pattern within the %d conversion
- specifier. For example:</p>
-
- <pre>aFolder/test.<b>%d</b>{yyyy-MM-dd-HH, <b>UTC</b>}.log</pre>
-
- <p>If the specified timezone identifier is unknown or
- misspelled, the GMT timezone is assumed as dictated by the <a
- href="http://docs.oracle.com/javase/6/docs/api/java/util/TimeZone.html#getTimeZone(java.lang.String)">TimeZone.getTimeZone(String)</a>
- method specification.
- </p>
</td>
</tr>
<tr>
<td><span class="prop" container="tbrp">maxHistory</span></td>
<td>int</td>
- <td>The optional <span class="prop">maxHistory</span> property
- controls the maximum number of archive files to keep,
- asynchronously deleting older files. For example, if you
- specify monthly rollover, and set maxHistory to 6, then 6
- months worth of archives files will be kept with files older
- than 6 months deleted. Note as old archived log files are
- removed, any folders which were created for the purpose of log
- file archiving will be removed as appropriate.
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="tbrp">totalSizeCap</span></td>
- <td>int</td>
- <td><p>The optional <span class="prop">totalSizeCap</span>
- property controls the total size of all archive files. Oldest
- archives are deleted asynchronously when the total size cap is
- exceeded. The <span class="prop">totalSizeCap</span> property
- requires <span class="option">maxHistory</span> property to be
- set as well. Moreover, the "max history" restriction is always
- applied first and the "total size cap" restriction applied
- second. </p>
+ <td>The optional <span class="prop">maxHistory</span>
+ property controls the maximum number of archive files to keep,
+ deleting older files. For example, if you specify monthly
+ rollover, and set maxHistory to 6, then 6 months worth of
+ archives files will be kept with files older than 6 months
+ deleted. Note as old archived log files are removed, any
+ folders which were created for the purpose of log file
+ archiving will be removed as appropriate.
</td>
</tr>
<tr >
- <td><span class="prop"
- container="tbrp">cleanHistoryOnStart</span></td>
+ <td><span class="prop" container="tbrp">cleanHistoryOnStart</span></td>
<td>boolean</td>
<td>
<p>If set to true, archive removal will be executed on
@@ -1021,15 +979,6 @@ public interface RollingPolicy extends LifeCycle {
at the beginning of every minute.
</td>
</tr>
- <tr>
- <td class="small">
- <em>/wombat/foo%d{yyyy-MM-dd_HH-mm, UTC}.log</em>
- </td>
- <td>Rollover at the beginning of every minute.</td>
- <td>Similar to previous cases, except that file names will be
- expressed in UTC.
- </td>
- </tr>
<tr>
@@ -1058,7 +1007,8 @@ public interface RollingPolicy extends LifeCycle {
</p>
- <p><code>TimeBasedRollingPolicy</code> supports automatic file
+ <p>Just like <code>FixedWindowRollingPolicy</code>,
+ <code>TimeBasedRollingPolicy</code> supports automatic file
compression. This feature is enabled if the value of the <span
class="prop">fileNamePattern</span> option ends with <em>.gz</em>
or <em>.zip</em>.
@@ -1156,7 +1106,7 @@ public interface RollingPolicy extends LifeCycle {
<p class="example">Example: Sample configuration of a
<code>RollingFileAppender</code> using a
<code>TimeBasedRollingPolicy</code>
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-RollingTimeBased.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingTimeBased.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-RollingTimeBased');">View as .groovy</span>
<pre id="logback-RollingTimeBased" class="prettyprint source"><configuration>
@@ -1166,10 +1116,8 @@ public interface RollingPolicy extends LifeCycle {
<!-- daily rollover -->
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
- <!-- keep 30 days' worth of history capped at 3GB total size -->
+ <!-- keep 30 days' worth of history -->
<maxHistory>30</maxHistory>
- <totalSizeCap>3GB</totalSizeCap>
-
</rollingPolicy></b>
<encoder>
@@ -1191,7 +1139,7 @@ public interface RollingPolicy extends LifeCycle {
<p class="example">Example: Sample configuration of a
<code>RollingFileAppender</code> using a
<code>TimeBasedRollingPolicy</code>
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-PrudentTimeBasedRolling');">View as .groovy</span>
<pre id="logback-PrudentTimeBasedRolling" class="prettyprint source"><configuration>
@@ -1201,7 +1149,6 @@ public interface RollingPolicy extends LifeCycle {
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
- <totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
@@ -1214,81 +1161,6 @@ public interface RollingPolicy extends LifeCycle {
</root>
</configuration></pre>
-
-
- <h3 class="doAnchor" name="SizeAndTimeBasedRollingPolicy">Size and
- time based rolling policy</h3>
-
-
- <p>Sometimes you may wish to archive files essentially by date but
- at the same time limit the size of each log file, in particular if
- post-processing tools impose size limits on the log files. In
- order to address this requirement, logback ships with
- <code>SizeAndTimeBasedRollingPolicy</code>.</p>
-
- <p>Note that <code>TimeBasedRollingPolicy</code> already allows
- limiting the combined size of archived log files. If you only wish
- to limit the combined size of log archives, then
- <code>TimeBasedRollingPolicy</code> described above and setting
- the <a href="#tbrpTotalSizeCap"><span
- class="option">totalSizeCap</span></a> property should be amply
- sufficent.
- </p>
-
- <p>Here is a sample configuration file demonstrating time and size
- based log file archiving.</p>
-
- <p class="example">Example: Sample configuration for
- <code>SizeAndTimeBasedFNATP</code>
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-sizeAndTime.xml)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-sizeAndTime');">View as .groovy</span>
- <pre id="logback-sizeAndTime" class="prettyprint source"><configuration>
- <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <file>mylog.txt</file>
- <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
- <!-- rollover daily -->
- <fileNamePattern><b>mylog-%d{yyyy-MM-dd}.<span class="big">%i</span>.txt</b></fileNamePattern>
- <b><!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB --></b>
- <b><maxFileSize>100MB</maxFileSize></b>
- <maxHistory>60</maxHistory>
- <totalSizeCap>20GB</totalSizeCap>
- </rollingPolicy>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
-
- <root level="DEBUG">
- <appender-ref ref="ROLLING" />
- </root>
-
-</configuration></pre>
-
- <p>Note the "%i" conversion token in addition to "%d". <b>Both the
- %i and %d tokens are mandatory.</b> Each time the current log file
- reaches <span class="prop">maxFileSize</span> before the current
- time period ends, it will be archived with an increasing index,
- starting at 0.</p>
-
- <p>Size and time based archiving supports deletion of old archive
- files. You need to specify the number of periods to preserve with
- the <span class="prop">maxHistory</span> property. When your
- application is stopped and restarted, logging will continue at the
- correct location, i.e. at the largest index number for the current
- period.
- </p>
-
- <p>In versions prior to 1.1.7, this document mentioned a component
- called <code>SizeAndTimeBasedFNATP</code>. However, given that
- <code>SizeAndTimeBasedFNATP</code> offers a simpler configuration
- structure, we no longer document
- <code>SizeAndTimeBasedFNATP</code>. Nevertheless, earlier
- configuration files using <code>SizeAndTimeBasedFNATP</code> will
- continue to work just fine. In fact,
- <code>SizeAndTimeBasedRollingPolicy</code> is implemented with a
- <code>SizeAndTimeBasedFNATP</code> subcomponent.</p>
<h4 class="doAnchor" name="FixedWindowRollingPolicy">FixedWindowRollingPolicy</h4>
@@ -1440,7 +1312,7 @@ public interface RollingPolicy extends LifeCycle {
</p>
<p class="example">Example: Sample configuration of a <code>RollingFileAppender</code> using a
- <code>FixedWindowRollingPolicy</code> (logback-examples/src/main/resources/chapters/appenders/conf/logback-RollingFixedWindow.xml)</p>
+ <code>FixedWindowRollingPolicy</code> (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingFixedWindow.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-RollingFixedWindow');">View as .groovy</span>
<pre id="logback-RollingFixedWindow" class="prettyprint source"><configuration>
@@ -1467,6 +1339,64 @@ public interface RollingPolicy extends LifeCycle {
</configuration></pre>
+ <h3 class="doAnchor" name="SizeAndTimeBasedFNATP">Size <b>and</b>
+ time based archiving
+ </h3>
+
+ <p>Sometimes you may wish to archive files essentially by date but
+ at the same time limit the size of each log file, in particular if
+ post-processing tools impose size limits on the log files. In
+ order to address this requirement, logback ships with a
+ sub-component for <code>TimeBasedRollingPolicy</code> called
+ <code>SizeAndTimeBasedFNATP</code>, where FNATP stands for File
+ Naming And Triggering Policy.</p>
+
+ <p>Here is a sample configuration file demonstrating time and size
+ based log file archiving.</p>
+
+ <p class="example">Example: Sample configuration for
+ <code>SizeAndTimeBasedFNATP</code>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-sizeAndTime.xml)</p>
+
+ <span class="asGroovy" onclick="return asGroovy('logback-sizeAndTime');">View as .groovy</span>
+ <pre id="logback-sizeAndTime" class="prettyprint source"><configuration>
+ <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>mylog.txt</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <!-- rollover daily -->
+ <fileNamePattern><b>mylog-%d{yyyy-MM-dd}.<span class="big">%i</span>.txt</b></fileNamePattern>
+ <b><timeBasedFileNamingAndTriggeringPolicy</b>
+ <b>class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"></b>
+ <!-- or whenever the file size reaches 100MB -->
+ <b><maxFileSize>100MB</maxFileSize></b>
+ <b></timeBasedFileNamingAndTriggeringPolicy></b>
+ </rollingPolicy>
+ <encoder>
+ <pattern>%msg%n</pattern>
+ </encoder>
+ </appender>
+
+
+ <root level="DEBUG">
+ <appender-ref ref="ROLLING" />
+ </root>
+
+</configuration></pre>
+
+ <p>Note the "%i" conversion token in addition to "%d". Each time
+ the current log file reaches <span
+ class="prop">maxFileSize</span> before the current time period
+ ends, it will be archived with an increasing index, starting at
+ 0.</p>
+
+ <p>Size and time based archiving supports deletion of old archive
+ files. You need to specify the number of periods to preserve with
+ the <span class="prop">maxHistory</span> property. When your
+ application is stopped and restarted, logging will continue at the
+ correct location, i.e. at the largest index number for the current
+ period.
+ </p>
+
<h2>
<a name="TriggeringPolicy" href="#TriggeringPolicy">Overview of
triggering policies</a>
@@ -1535,7 +1465,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
<p class="example">Example: Sample configuration of a
<code>RollingFileAppender</code> using a
<code>SizeBasedTriggeringPolicy</code>
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-RollingSizeBased.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingSizeBased.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-RollingSizeBased');">View as .groovy</span>
<pre id="logback-RollingSizeBased" class="prettyprint source"><configuration>
@@ -1700,15 +1630,15 @@ public interface TriggeringPolicy<E> extends LifeCycle {
<td><span class="prop" container="socket">queueSize</span></td>
<td><code>int</code></td>
<td>
- <p>The <span class="prop">queueSize</span> property takes an
- integer (greater than zero) representing the number of logging
+ <p>The <span class="prop">queueSize</span> property takes a
+ non-negative integer representing the number of logging
events to retain for delivery to the remote receiver. When
- the queue size is one, event delivery to the remote
+ the queue size is zero, event delivery to the remote
receiver is synchronous. When the queue size is greater
- than one, new events are enqueued, assuming that there is
- space available in the queue. Using a queue length greater
- than one can improve performance by eliminating delays caused
- by transient network delays.
+ than zero, new events are enqueued, assuming that there is
+ space available in the queue. Using a non-zero queue length
+ can improve performance by eliminating delays caused by
+ transient network delays.
</p>
<p>See also the <span class="prop">eventDelayLimit</span>
@@ -1829,7 +1759,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
</p>
<p class="example">Example: SocketAppender configuration
- (logback-examples/src/main/resources/chapters/appenders/socket/client1.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/socket/client1.xml)</p>
<span class="asGroovy" onclick="return asGroovy('client1');">View as .groovy</span>
<pre id="client1" class="prettyprint source"><configuration>
@@ -1942,7 +1872,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
</p>
<p class="example">Example: SSLSocketAppender configuration
- (logback-examples/src/main/resources/chapters/appenders/socket/ssl/client.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/socket/ssl/client.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sslclient');">View as .groovy</span>
<pre id="sslclient" class="prettyprint source"><configuration debug="true">
@@ -2100,7 +2030,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
</p>
<p class="example">Example: Basic ServerSocketAppender Configuration
- (logback-examples/src/main/resources/chapters/appenders/socket/server4.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/socket/server4.xml)</p>
<pre id="SocketReceiver" class="prettyprint source"><configuration debug="true">
<appender name="SERVER"
class="ch.qos.logback.classic.net.server.ServerSocketAppender">
@@ -2126,7 +2056,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
<code>SSLServerSocketAppender</code>.</p>
<p class="example">Example: Basic SSLServerSocketAppender Configuration
- (logback-examples/src/main/resources/chapters/appenders/socket/ssl/server3.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/socket/ssl/server3.xml)</p>
<pre id="SocketReceiver" class="prettyprint source"><configuration debug="true">
<appender name="SERVER"
class="ch.qos.logback.classic.net.server.SSLServerSocketAppender">
@@ -2322,7 +2252,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
</p>
<p>If you don't specify a <span
class="prop">cyclicBufferTracker</span>, an instance of <a
- href="../xref/ch/qos/logback/core/spi/CyclicBufferTracker.html">CyclicBufferTracker</a>
+ href="../xref/ch/qos/logback/core/spi/CyclicBufferTrackerImpl.html">CyclicBufferTrackerImpl</a>
will be automatically created. By default, this instance
will keep events in a cyclic buffer of size 256. You may
change the size with the help of the <span
@@ -2364,7 +2294,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
<td><code>String</code></td>
<td>The outgoing email message will be encoded in the
designated <a
- href="https://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html">charset</a>. The
+ href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">charset</a>. The
default charset encoding is "UTF-8" which works well for most
purposes.
</td>
@@ -2487,7 +2417,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
<code>Email</code> application:
</p>
- <p class="example">Example: A sample <code>SMTPAppender</code> configuration (logback-examples/src/main/resources/chapters/appenders/mail/mail1.xml)</p>
+ <p class="example">Example: A sample <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/mail/mail1.xml)</p>
<span class="asGroovy" onclick="return asGroovy('mail1');">View as .groovy</span>
<pre id="mail1" class="prettyprint source"><configuration>
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
@@ -2587,7 +2517,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
desires, you may set a different buffer size as shown in the next example.
</p>
- <p class="example">Example: <code>SMTPAppender</code> configuration with a custom bufer size (logback-examples/src/main/resources/chapters/appenders/mail/customBufferSize.xml)</p>
+ <p class="example">Example: <code>SMTPAppender</code> configuration with a custom bufer size (logback-examples/src/main/java/chapters/appenders/mail/customBufferSize.xml)</p>
<pre class="prettyprint source"><configuration>
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
<smtpHost>${smtpHost}</smtpHost>
@@ -2685,7 +2615,7 @@ public class CounterBasedEvaluator extends ContextAwareBase implements EventEval
</p>
<p class="example">Example: <code>SMTPAppender</code> with custom
- <code>Evaluator</code> and buffer size (logback-examples/src/main/resources/chapters/appenders/mail/mail3.xml)</p>
+ <code>Evaluator</code> and buffer size (logback-examples/src/main/java/chapters/appenders/mail/mail3.xml)</p>
<span class="asGroovy" onclick="return asGroovy('mail3');">View as .groovy</span>
<pre id="mail3" class="prettyprint source"><configuration>
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
@@ -2735,7 +2665,7 @@ logger.error(<b>notifyAdmin</b>,
</p>
<p class="example">Example: <code>SMTPAppender</code> with
- <code>OnMarkerEvaluator</code> (logback-examples/src/main/resources/chapters/appenders/mail/mailWithMarker.xml)</p>
+ <code>OnMarkerEvaluator</code> (logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker.xml)</p>
<span class="asGroovy" onclick="return asGroovy('mailWithMarker');">View as .groovy</span>
<pre id="mailWithMarker" class="prettyprint source"><configuration>
@@ -2779,7 +2709,7 @@ logger.error(<b>notifyAdmin</b>,
</p>
<p class="example">Example: <code>SMTPAppender</code> with
- <code>JaninoEventEvaluator</code> (logback-examples/src/main/resources/chapters/appenders/mail/mailWithMarker_Janino.xml)</p>
+ <code>JaninoEventEvaluator</code> (logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker_Janino.xml)</p>
<span class="asGroovy" onclick="return asGroovy('mailWithMarker_Janino');">View as .groovy</span>
<pre id="mailWithMarker_Janino" class="prettyprint source"><configuration>
@@ -2801,7 +2731,7 @@ logger.error(<b>notifyAdmin</b>,
href="filters.html#GEventEvaluator">GEventEvaluator</a>.</p>
<p class="example">Example: the same with
- <code>GEventEvaluator</code> (logback-examples/src/main/resources/chapters/appenders/mail/mailWithMarker_GEvent.xml)</p>
+ <code>GEventEvaluator</code> (logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker_GEvent.xml)</p>
<span class="asGroovy" onclick="return asGroovy('mailWithMarker_GEventEvaluator');">View as .groovy</span>
<pre id="mailWithMarker_GEventEvaluator" class="prettyprint source"><configuration>
@@ -2833,7 +2763,7 @@ logger.error(<b>notifyAdmin</b>,
connection is encrypted right from the start.
</p>
- <h3 class="doAnchor" name="gmailSSL">SMTPAppender configuration
+ <h3> class="doAnchor"name="gmailSSL">SMTPAppender configuration
for Gmail (SSL)</h3>
<p>The next example shows you how to configure
@@ -2841,7 +2771,7 @@ logger.error(<b>notifyAdmin</b>,
<p class="example">Example:: <code>SMTPAppender</code> to Gmail
using SSL
- (logback-examples/src/main/resources/chapters/appenders/mail/gmailSSL.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/mail/gmailSSL.xml)</p>
<span class="asGroovy" onclick="return asGroovy('gmailSSLExample');">View as .groovy</span>
<pre id="gmailSSLExample" class="prettyprint source"><configuration>
@@ -2873,7 +2803,7 @@ logger.error(<b>notifyAdmin</b>,
<p>The next example shows you how to configure
<code>SMTPAppender</code> for Gmail for the STARTTLS protocol. </p>
- <p class="example">Example: <code>SMTPAppender</code> to GMAIL using STARTTLS (logback-examples/src/main/resources/chapters/appenders/mail/gmailSTARTTLS.xml)</p>
+ <p class="example">Example: <code>SMTPAppender</code> to GMAIL using STARTTLS (logback-examples/src/main/java/chapters/appenders/mail/gmailSTARTTLS.xml)</p>
<span class="asGroovy" onclick="return asGroovy('gmailSTARTTLSExample');">View as .groovy</span>
<pre id="gmailSTARTTLSExample" class="prettyprint source"><configuration>
@@ -2919,7 +2849,7 @@ logger.error(<b>notifyAdmin</b>,
<p class="example">Example: <code>SMTPAppender</code> with
MDCBasedDsicriminator
- (logback-examples/src/main/resources/chapters/appenders/mail/mailWithMDCBasedDiscriminator.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/mail/mailWithMDCBasedDiscriminator.xml)</p>
<span class="asGroovy" onclick="return asGroovy('mailWithMDCBasedDiscriminator');">View as .groovy</span>
<pre id="mailWithMDCBasedDiscriminator" class="prettyprint source"><configuration>
@@ -3311,7 +3241,7 @@ logger.error(<b>notifyAdmin</b>,
The following configuration file is what one would need.
</p>
- <p class="example">Example: <code>DBAppender</code> configuration (logback-examples/src/main/resources/chapters/appenders/db/append-toMySQL-with-driverManager.xml)</p>
+ <p class="example">Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-driverManager.xml)</p>
<span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-driverManager');">View as .groovy</span>
<pre id="append-toMySQL-with-driverManager" class="prettyprint source"><configuration>
@@ -3331,7 +3261,7 @@ logger.error(<b>notifyAdmin</b>,
<p>
The correct driver must be declared. Here, the <code>com.mysql.jdbc.Driver</code>
- class is used. The <span class="prop">url</span> must begin with <em>jdbc:mysql://</em>.
+ class is used. The <span class="prop">url</span> must begin with <em>jdbc:myslq://</em>.
</p>
<p>
@@ -3391,7 +3321,7 @@ logger.error(<b>notifyAdmin</b>,
<code>javax.sql.DataSource</code>.
</p>
- <p class="example">Example: <code>DBAppender</code> configuration (logback-examples/src/main/resources/chapters/appenders/db/append-with-datasource.xml)</p>
+ <p class="example">Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-with-datasource.xml)</p>
<span class="asGroovy" onclick="return asGroovy('append-with-datasource');">View as .groovy</span>
@@ -3500,7 +3430,7 @@ logger.error(<b>notifyAdmin</b>,
<p class="example">Example: <code>DBAppender</code> configuration
by <code>JNDIConnectionSource</code>
- (logback-examples/src/main/resources/chapters/appenders/db/append-via-jndi.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/db/append-via-jndi.xml)</p>
<span class="asGroovy" onclick="return asGroovy('append-via-jndi');">View as .groovy</span>
@@ -3544,7 +3474,7 @@ logger.error(<b>notifyAdmin</b>,
<p class="example">Example: <code>DBAppender</code> configuration
without pooling
- (logback-examples/src/main/resources/chapters/appenders/db/append-toMySQL-with-datasource.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource.xml)</p>
<span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource');">View as .groovy</span>
<pre id="append-toMySQL-with-datasource" class="prettyprint source"><configuration>
@@ -3581,7 +3511,7 @@ logger.error(<b>notifyAdmin</b>,
<p class="example">Example: <code>DBAppender</code> configuration
with pooling
- (logback-examples/src/main/resources/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml)</p>
<span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource-and-pooling');">View as .groovy</span>
<pre id="append-toMySQL-with-datasource-and-pooling" class="prettyprint source"><configuration>
@@ -3710,7 +3640,7 @@ logger.error(<b>notifyAdmin</b>,
<p>Here is a sample configuration using a
<code>SyslogAppender</code>.</p>
- <p class="example">Example: <code>SyslogAppender</code> configuration (logback-examples/src/main/resources/chapters/appenders/conf/logback-syslog.xml)</p>
+ <p class="example">Example: <code>SyslogAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-syslog.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-syslog');">View as .groovy</span>
<pre id="logback-syslog" class="prettyprint source"><configuration>
@@ -3809,7 +3739,7 @@ logger.debug("Alice says hello"); </p>
<p class="example">Example: <code>SiftingAppender</code>
configuration
- (logback-examples/src/main/resources/chapters/appenders/sift/byUserid.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/sift/byUserid.xml)</p>
<span class="asGroovy" onclick="return asGroovy('byUserid');">View as .groovy</span>
@@ -3967,28 +3897,7 @@ import static ch.qos.logback.classic.ClassicConstants.FINALIZE_SESSION_MARKER;
flush the logging events from the queue. This can be achieved by
<a href="configuration.html#stopContext">stopping the
LoggerContext</a> which will close all appenders, including any
- <code>AsyncAppender</code> instances. <code>AsyncAppender</code>
- will wait for the worker thread to flush up to the timeout specified
- in <span class="prop">maxFlushTime</span>. If you find that queued events
- are being discarded during close of the <code>LoggerContext</code>, you
- may need to increase the time out. Specifying a value of 0 for
- <span class="prop">maxFlushTime</span> will force the <code>AsyncAppender</code>
- to wait for all queued events to be flushed before returning from
- the stop method.
- </p>
-
- <p><span class="label">Post shutdown cleanup</span>
- Depending on the mode of JVM shutdown, the worker thread processing the
- queued events can be interrupted causing events to be strandeds in the
- queue. This generally occurs when the <code>LoggerContext</code> is not
- stopped cleanly or when the JVM terminates outside of the typical control
- flow. In order to avoid interrupting the worker thread under these
- conditions, a shutdown hook can be inserted to the JVM runtime that
- <a href="configuration.html#stopContext">stops the LoggerContext properly</a>
- after JVM shutdown has been initiated. A shutdown hook may also be the
- preferred method for cleanly shutting down Logback when other shutdown hooks
- attempt to log events.
- </p>
+ <code>AsyncAppender</code> instances.</p>
<p>Here is the list of properties admitted by
@@ -4029,28 +3938,6 @@ import static ch.qos.logback.classic.ClassicConstants.FINALIZE_SESSION_MARKER;
class="prop">includeCallerData</span> property to true.
</td>
</tr>
- <tr>
- <td><span class="prop" container="async">maxFlushTime</span></td>
- <td><code>int</code></td>
- <td>Depending on the queue depth and latency to the referenced appender,
- the <code>AsyncAppender</code> may take an unacceptable amount of
- time to fully flush the queue. When the <code>LoggerContext</code> is
- stopped, the <code>AsyncAppender stop</code> method waits
- up to this timeout for the worker thread to complete. Use
- <span class="prop">maxFlushTime</span> to specify a maximum queue flush
- timeout in milliseconds. Events that cannot be processed within this
- window are discarded. Semantics of this value are identical to that of
- <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#join(long)">Thread.join(long)</a>.
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="async">neverBlock</span></td>
- <td><code>boolean</code></td>
- <td>If <code>false</code> (the default) the appender will block on
- appending to a full queue rather than losing the message. Set to
- <code>true</code> and the appender will just drop the message and
- will not block your application.</td>
- </tr>
</table>
<p>By default, event queue is configured with a maximum capacity
@@ -4098,7 +3985,7 @@ import static ch.qos.logback.classic.ClassicConstants.FINALIZE_SESSION_MARKER;
<p class="example">Example: <code>AsyncAppender</code>
configuration
- (logback-examples/src/main/resources/chapters/appenders/conc/logback-async.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conc/logback-async.xml)</p>
<span class="asGroovy" onclick="return asGroovy('asyncAppender');">View as .groovy</span>
@@ -4234,7 +4121,7 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
href="../xref/chapters/appenders/CountingConsoleAppender.html"><code>CountingConsoleAppender</code></a>
can be configured like any other appender. See sample
configuration file
- <em>logback-examples/src/main/resources/chapters/appenders/countingConsole.xml</em>
+ <em>logback-examples/src/main/java/chapters/appenders/countingConsole.xml</em>
for an example.
</p>
@@ -4316,7 +4203,7 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
</p>
<p class="example">Example: <code>SMTPAppender</code>
configuration
- (logback-examples/src/main/resources/chapters/appenders/conf/access/logback-smtp.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/access/logback-smtp.xml)</p>
<pre class="prettyprint source"><appender name="SMTP"
class="ch.qos.logback.access.net.SMTPAppender">
@@ -4481,7 +4368,7 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
<p>Here is a sample configuration that uses <code>DBAppender</code>.</p>
- <p class="example">Example: DBAppender configuration <em>(logback-examples/src/main/resources/chapters/appenders/conf/access/logback-DB.xml)</em></p>
+ <p class="example">Example: DBAppender configuration <em>(logback-examples/src/main/java/chapters/appenders/conf/access/logback-DB.xml)</em></p>
<pre class="prettyprint source"><configuration>
@@ -4521,7 +4408,7 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
<p>Below is an example configuration file.</p>
- <p class="example">Example: SiftingAppender configuration (logback-examples/src/main/resources/chapters/appenders/conf/sift/access-siftingFile.xml)</p>
+ <p class="example">Example: SiftingAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/sift/access-siftingFile.xml)</p>
<pre class="prettyprint source"><configuration>
<appender name="SIFTING" class="ch.qos.logback.access.sift.SiftingAppender">
@@ -4532,8 +4419,8 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
<defaultValue>NA</defaultValue>
</Discriminator>
<sift>
- <appender name="ch.qos.logback:logback-site:jar:1.1.9" class="ch.qos.logback.core.FileAppender">
- <file>byUser/ch.qos.logback:logback-site:jar:1.1.9.log</file>
+ <appender name="ch.qos.logback:logback-site:jar:1.1.2" class="ch.qos.logback.core.FileAppender">
+ <file>byUser/ch.qos.logback:logback-site:jar:1.1.2.log</file>
<layout class="ch.qos.logback.access.PatternLayout">
<pattern>%h %l %u %t \"%r\" %s %b</pattern>
</layout>
diff --git a/docs/manual/appenders_ja.html b/docs/manual/appenders_ja.html
deleted file mode 100644
index 5bc0a73..0000000
--- a/docs/manual/appenders_ja.html
+++ /dev/null
@@ -1,2871 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第4章 アペンダー</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content" class="chapter">
-
- <h1>第4章 アペンダー</h1>
-
- <div class="quote">
-
- <p><em>西部について教えたいことが多すぎるのでどこから始めたらいいのかわからないよ。1つを選べば残りの100を捨てることになってしまう。最初の1つを決めるにはどうしたいいんだろう?</em></p>
-
- <p>—JOHN STEINBECK, <em>East of Eden</em></p>
- </div>
-
-
- <script src="../templates/creative.js" type="text/javascript"></script>
- <script src="../templates/setup.js" type="text/javascript"></script>
-
- <h2 class="doAnchor" name="whatIsAnAppender">アペンダーについて</h2>
-
- <p>logback はロギングイベントを出力する仕事を、アペンダーと呼ばれるコンポーネントに任せています。<a href="http://logback.qos.ch/xref/ch/qos/logback/core/Appender.html"><code>ch.qos.logback.core.Appender</code></a>インターフェイスを実装したものがアペンダーとして利用できます。このインターフェイスに宣言された重要なメソッドは次のとおりです。</p>
- <pre class="prettyprint source">package ch.qos.logback.core;
-
-import ch.qos.logback.core.spi.ContextAware;
-import ch.qos.logback.core.spi.FilterAttachable;
-import ch.qos.logback.core.spi.LifeCycle;
-
-
-public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachable {
-
- public String getName();
- public void setName(String name);
- <b>void doAppend(E event);</b>
-
-}</pre>
-
- <p><code>Appender</code>インターフェイスのほとんどのメソッドはゲッター、あるいはセッターです。<code>doAppend()</code>メソッドだけは特別で、唯一の引数として型<em>E</em>のオブジェクトを取ります。<em>E</em>の実際の型は、logbackモジュールによって異なります。logback-classic モジュールの場合、<em>E</em>は<a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/spi/ILoggingEvent.html">ILoggingEvent</a>になるでしょうし、logback-access モジュールでは<a href="http://logback.qos.ch/apidocs/ch/qos/logback/access/spi/AccessEvent.html">AccessEvent</a>になるでしょう。<code>doAppend()</code>メソッドは、おそらくlogbackフレームワークの中で最 [...]
- </p>
-
- <p>アペンダーには名前を付けられます。設定ファイル中で参照しやすいようにするためです。<code>Appender</code>インターフェイスは<code>FilterAttachable</code>インターフェイスを継承しています。つまり、アペンダーのインスタンスには一つ以上のフィルターを割り当てられるのです。フィルターについては、後の章で詳しく説明します。
- </p>
-
- <p>アペンダーには、ロギングイベントを出力することについて最終的な責任があります。しかし、アペンダー自体が書式化をするのではなく、<code>Layout</code>あるいは<code>Encoder</code>オブジェクトに処理を委譲します。レイアウトやエンコーダーは、ただ一つのアペンダーにだけ関連付けられ、そのアペンダーだけが参照することになります。アペンダーによっては、組み込みの、あるいは固定の書式が指定されています。そういうアペンダーには、レイアウトもエンコーダーも不要です。たとえば、 <code>SocketAppender</code>は、ロギングイベントを接続したリモートホストに転送する前に単純にシリアライズするだけです。
- </p>
-
-
- <h2 class="doAnchor" name="AppenderBase">AppenderBase</h2>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/AppenderBase.html">ch.qos.logback.core.AppenderBase</a></code>は、<code>Appender</code>インターフェイスを実装した抽象クラスです。このクラスは、どんなアペンダーにも必要な共通の機能として、名前や活性化状態やレイアウト、フィルターに対するゲッターおよびセッターメソッドが実装されています。logback の配布物に含まれるアペンダーはすべてこのクラスの派生クラスです。<code>AppenderBase</code>は抽象クラスですが、<code>Append</code>インターフェイスの<code>doAppend()</code>メソッドを実装しています。<code>AppenderBase</code>クラスの話は、実際にソースコードの抜粋を見ながら進めるのが一番わかりやすいと思います。
- </p>
-
-<pre class="prettyprint source">public synchronized void doAppend(E eventObject) {
-
- // prevent re-entry.
- if (guard) {
- return;
- }
-
- try {
- guard = true;
-
- if (!this.started) {
- if (statusRepeatCount++ < ALLOWED_REPEATS) {
- addStatus(new WarnStatus(
- "Attempted to append to non started appender [" + name + "].",this));
- }
- return;
- }
-
- if (getFilterChainDecision(eventObject) == FilterReply.DENY) {
- return;
- }
-
- // ok, we now invoke the derived class's implementation of append
- this.append(eventObject);
-
- } finally {
- guard = false;
- }
-}</pre>
-
- <p><code>doAppend()</code>メソッドはsynchronizedメソッドになっています。つまり、別のスレッドから同じアペンダーに安全にロギングできるのです。スレッド<em>T</em>が<code>doAppend()</code>メソッドを実行している間は、<em>T</em>だけが排他的にアペンダーにアクセスできるので、他のスレッドからの呼び出しはキューイングされます。
- </p>
-
- <p>synchronized が不適切な場合もあります。そういうときのために、logback の配布物には<a href="http://logback.qos.ch/xref/ch/qos/logback/core/AppenderBase.html"><code>AppenderBase</code></a>とよく似た<a href="http://logback.qos.ch/xref/ch/qos/logback/core/UnsynchronizedAppenderBase.html"><code>ch.qos.logback.core.UnsynchronizedAppenderBase</code></a>も含まれています。ややこしくなるので、<code>UnsynchronizedAppenderBase</code>については本章の後半で説明します。
- </p>
-
-
- <p><code>doAppend()</code>メソッドでは、まず最初にguard変数にtrueが設定されているかどうかをチェックします。trueだったら、ただちに終了します。そうでなければ、まずguard変数にtrueを設定してから次の処理に進みます。guard変数によって、<code>doAppend()</code>メソッドを再帰的に呼び出してしまうことを防いでいるのです。あるコンポーネントが、ログを取得するために<code>append()</code>というメソッドを呼び出したとしましょう。そうすると、今呼び出したアペンダーと同じアペンダーを直接呼び出すことになってしまうので、無限ループした結果スタックオーバーフローが発生してしまいます。
- </p>
-
- <p>次の式では<code>started</code>フィールドにtrueが設定されているかどうかをチェックします。trueでなければ、警告メッセージを出力して<code>doAppend()</code>メソッドは終了します。これは、クローズされたアペンダーには何も書き込めなくなるということです。<code>Appender</code>オブジェクトは<code>LifeCycle</code>インターフェイスを実装しているので、つまり<code>start()</code>メソッド、<code>stop()</code>メソッド、<code>isStarted()</code>メソッドを実装しています。Joran設定フレームワークは、アペンダーの全てのプロパティを設定してから、アペンダーを開始して活性化状態をアクティブにするため<code>start()</code>メソッドを呼び出します。アペンダーにもよりますが、指定されていないプロパティがあったり、プロパティに指定した値の影響で、開始できないことがあります。たとえば、<code>FIleAppender</ [...]
- </p>
-
- <p>アペンダーが開始できなかったとき、あるいは、停止してしまったときは、logback の内部状態管理システムによって警告メッセージが出力されます。何度か(ロギングを?)試みたあと、同じ内容の警告メッセージで溢れかえってしまうのを避けるため、<code>doAppend()</code>メソッドは警告メッセージを出力しないようになります。
- </p>
-
- <p>その次の<code>if</code>文では割り当てられたフィルターの応答をチェックします。フィルターチェインの応答によって、ロギングイベントを拒否するか受け入れるかが決まります。フィルターチェインが何も決めなかったら、デフォルトでロギングイベントは受け入れられるようになっています。
- </p>
-
- <p>その後は、派生クラスで実装されてた<code>append()</code>メソッドを呼び出します。このメソッドは、実際に適切なデバイスへロギングイベントを出力します。
- </p>
-
- <p>最後にguard変数が開放され、キューイングされた<code>doAppend()</code>メソッドの呼び出しが処理できるようになります。
- </p>
-
- <p>ここの説明では "プロパティ" という言葉の代わりに "オプション" という言葉を使いました。これは、JavaBeanの規約に従ったゲッターおよびセッターメソッドが用意された属性のことです。</p>
-
- <h1>logback-coreモジュール</h1>
-
- <p>logback-coreモジュールは、他のモジュールを構築する基盤となるモジュールです。一般的に、logbac-core モジュールのコンポーネントは、ある程度の(少なくとも最小限の)カスタマイズが必要です。以降の節では、カスタマイズしないでもすぐに利用できるアペンダーを紹介していきます。
- </p>
-
-
-
- <h2 class="doAnchor" name="OutputStreamAppender">OutputStreamAppender</h2>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/core/OutputStreamAppender.html"><code>OutputStreamAppender</code></a>は<code>java.io.OutputStream</code>にロギングイベントを出力します。このクラスは他のアペンダーを構築するための基本的なサービスを提供するものです。普通なら、利用者が<code>OutputStreamAppender</code>を直接インスタンス化することはありません。<code>java.io.OutputStream</code>を文字列で表現することはできないので、設定ファイルから<code>OutputStream</code>オブジェクトを指定することはできないのです。簡単に言うと、設定ファイルでは<code>OutputStreamAppender</code>を設定することはできません。しかし、<code>OutputStreamAppender</code>に設定できるプロパテ [...]
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
-
- <tr>
- <td><span class="prop" name="osaEncoder">encoder</span></td>
-
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/encoder/Encoder.html"><code>Encoder</code></a></td>
-
- <td><code>OutputStreamAppender</code>への出力を書式化する。エンコーダについては<a href="./05-encoders.html">別の章</a>で説明しています。
- </td>
- </tr>
-
- </table>
-
- <p><code>OutputStreamAppender</code>は<code>ConsoleAppender</code> 、 <code>FileAppender</code>の基底クラスです。<code>RollingFileAppender</code>の基底クラスはFileAppenderなので、これも含めておきます。次の図は<code>OutputStreamAppender</code>とそのサブクラスの関係を図示したものです。
- </p>
-
- <img src="images/chapters/appenders/appenderClassDiagram.jpg" alt="OutputStreamAppenderとサブクラスを示すUML図">
-
-
- <h2 class="doAnchor" name="ConsoleAppender">ConsoleAppender</h2>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/ConsoleAppender.html">ConsoleAppender</a></code>は名前のとおり、ロギングイベントをコンソールに出力します。正確に言うと、<em>System.out</em>あるいは<em>System.err</em>に出力します。デフォルトではSystem.outが使われます。<code>ConsoleAppender</code>は、利用者が指定したエンコーダーを使ってロギングイベントを書式化します。エンコーダーについては別の章で説明します。<em>System.out</em>と<em>System.err</em>の型は<code>java.io.PrintStream</code>です。つまり、いずれもバッファIO操作のための<code>OutputStreamWriter</code>にラップされているということです。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="conApp">encoder</span></td>
- <td>
- <a href="http://logback.qos.ch/xref/ch/qos/logback/core/encoder/Encoder.html"><code>Encoder</code></a>
- </td>
- <td><code>OutputStreamAppender</code>と同じです。</td>
- </tr>
- <tr>
- <td><span class="prop" container="conApp">target</span></td>
- <td><code>String</code></td>
- <td>文字列で、<em>System.out</em>か<em>System.err</em>を指定します。デフォルトは<em>System.outに</em>です。
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="conApp">withJansi</span></td>
- <td><code>boolean</code></td>
- <td><span class="prop">withJansi</span>プロパティの値にはデフォルトで<code>false</code>が設定されています。<span class="prop">withJansi</span>プロパティに<code>true</code>を指定すると、<a href="http://jansi.fusesource.org/">Jansi</a>ライブラリが有効化され、Windowsマシン上でANSIカラーコードがサポートされるようになります。Windows のホスト上でこのプロパティにtrueを指定する場合、クラスパス上にjansiライブラリのjarファイルを置かなければなりません。なお、UnixベースのOSであるLinuxやMac OS Xのターミナルは、デフォルトでANSIカラーコードをサポートしています。
-
- <p>Eclipse IDEから利用する場合は、<a href="http://www.mihai-nita.net/eclipse/">ANSI in Eclipse Console</a>プラグインをインストールしてみましょう。
- </p>
- </td>
- </tr>
-
- </table>
-
- <p><code>ConsoleAppender</code>の設定サンプルを見てください。
- </p>
-
-
-
- <p class="example">例:ConsoleAppenderの設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-Console.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback_Console');">Groovyで表示</span>
-
- <pre id="logback_Console" class="prettyprint source"><configuration>
-
- <b><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <!-- encoders are assigned the type
- ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
- <encoder>
- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
- </encoder>
- </appender></b>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p><em>logback-examples</em>ディレクトリに移動して、<a href="http://logback.qos.ch/setup.html">クラスパスを設定</a>すれば、次のコマンドで上の設定ファイルを使って実行できます。</p>
-
- <p class="source">java <a href="http://logback.qos.ch/xref/chapters/appenders/ConfigurationTester.html">chapters.appenders.ConfigurationTester</a> src/main/java/chapters/appenders/conf/logback-Console.xml</p>
-
-
- <h2 class="doAnchor" name="FileAppender">FileAppender</h2>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/core/FileAppender.html"><code>FileAppender</code></a>は<code>OutputStreamAppender</code>の派生クラスで、ファイルにロギングイベントを出力します。<span class="prop">file</span>オプションで対象のファイルを指定します。既にファイルが存在するとき、ファイル内容を切り捨てるか、追加するかどうかは、<span class="prop">append</span>プロパティの値に応じて決まります。
- </p>
-
- <table class="bodyTable properties striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="fileApppender">append</span></td>
- <td><code>boolean</code></td>
- <td>trueの場合、既存のファイルの末尾にロギングイベントを追加します。<span class="prop">append</span>プロパティがfalseの場合、既存のファイルの内容は捨てられてしまいます。デフォルトは<span class="option">true</span>です。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="fileApppender">encoder</span></td>
- <td>
- <a href="http://logback.qos.ch/xref/ch/qos/logback/core/encoder/Encoder.html"><code>Encoder</code></a>
- </td>
- <td><code>OutputStreamAppender</code>と同じです。</td>
- </tr>
-
-
- <tr>
- <td><span class="prop" container="fileApppender">file</span></td>
- <td><code>String</code></td>
- <td>書き込み先のファイル名です。ファイルが存在しない場合、新しく作成します。Windowsプラットフォームの利用者は、バックスラッシュをエスケープするの忘れがちなので注意してください。たとえば、<em>c:\temp\test.log</em>という文字列は意図したように解釈されません。<em>'\t'</em>はエスケープシーケンスの<em>タブ文字{\u0009}</em>として解釈されるでしょう。<em>c:/temp/test.log</em>と書くか、<em>c:\\temp\\test.log</em>のように書けばよいでしょう。デフォルト値はありません。
-
- <p>指定したファイルの親ディレクトリが存在しない場合、 <code>FileAppender</code>は途中の全てのディレクトリを作成します。
- </p>
- </td>
- </tr>
-
-
- <tr>
- <td><span class="prop" name="prudent">prudent</span></td>
- <td><code>boolean</code></td>
-
- <td>prudentモードでは、指定されたファイルに安全に書き込むようになります。同じファイルを対象にした他の<code>FileAppender</code>がいるとしても、それが別のJVMで動いているとしても、ましてや別のホストで動いているとしても、です。デフォルト値は<code>false</code>です。
-
- <p>prudent モードは、<a href="./appenders.html#prudentWithRolling">多少の制限</a>はあるものの、<code>RollingFileAppender</code>と組み合わせて利用することもできます。</p>
-
- <p>prudent モードがtrueなら、<span class="prop">append</span>プロパティも自動的にtrueになります。
- </p>
-
- <p>prudentモードは排他的なファイルロックを使用します。ファイルロックを使うと、ロギングイベントの出力にかかるコストがおよそ3倍程度になることが分かっています。標準的なPCで、<b>ローカル</b>のハードディスク上のファイルへ一つロギングイベントを出力をするとき、prudentモードがオフの場合はおよそ10マイクロ秒かかります。prudentモードをオンにすると、30マイクロ秒になります。言い換えると、prudentモードがオフの場合は毎秒100,000回のロギングイベントが処理できるのに対して、prudentモードがオンの場合は毎秒33,000回しか処理できなくなるということです。
- </p>
-
- <p>prudentモードでは、複数のJVMから同じファイルに行うIO操作を効果的にシリアライズします。したがって、JVMの数が多くなればなるほど、IO操作ごとの待ち時間が長くなります。IO操作の<em>合計時間</em>が、毎秒20回オーダーのロギング要求が処理できる程度であれば、性能への影響は無視してもよいでしょう。アプリケーションが毎秒100回以上のIO操作をするようであれば、きっと性能影響があるので<span class="prop">prudent</span>モードを使うのはやめてください。
- </p>
-
- <p><span class="label">ネットワークファイルロック</span>ネットワークファイルシステム上のログファイルを対象にすると非常にコストが高くなります。ネットワークファイルシステム越しのファイルロックは、プロセスがすでに所有しているロックをリリースする前に再取得する、という振る舞いに強く依存していることも同じくらい重要です。したがって1つのプロセスがログファイルを占有していると、他のプロセスからはデッドロックしているように見えるので、ロックを待ち続けることになってしまいます。
- </p>
-
- <p>prudentモードは、ネットワークの速度と同じくらいの影響をOSの実装からも受けます。私たちの提供しているとても小さいアプリケーションの<a href="https://gist.github.com/2794241">FileLockSimulator</a>を使えば、あなたの環境でprudentモードがどのように振る舞うかシミュレートできます。
- </p>
-
-
- </td>
-
- </tr>
- </table>
-
- <p><span class="label notice">即時フラッシュ</span>
-デフォルトでは、それぞれのロギングイベントは、最終的な出力ストリームに即時にフラッシュされます。これは、あなたのアプリケーションがアペンダーをちゃんとクローズしていない場合、ロギングイベントが失われないようにするためのより安全な方法です。しかし、ロギング要求のスループットが大幅に増加してしまう場合には、<code>Encorder</code>の<span class="prop">immediateFlush</span>プロパティに<code>false</code>を指定することもできます。エンコーダー、特に<a href="./encoders.html#LayoutWrappingEncoder"><code>LayoutWrappingEncoder</code></a>については別の章で説明します。</p>
-
- <p><code>FileAppender</code>の設定例を見てください。</p>
-
- <p class="example">例:FileAppenderの設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-fileAppender.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-fileAppender');">Groovyとして表示</span>
- <pre id="logback-fileAppender" class="prettyprint source"><configuration>
-
- <b><appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <file>testFile.log</file>
- <append>true</append>
- <!-- encoders are assigned the type
- ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
- <encoder>
- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
- </encoder>
- </appender></b>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
- <p><em>logback-examples</em>ディレクトリに移動すれば、次のコマンドで上の設定ファイルを使って実行できます。
-</p>
-
- <p class="source">java chapters.appenders.ConfigurationTester
- src/main/java/chapters/appenders/conf/logback-fileAppender.xml</p>
-
-
- <h3 class="doAnchor" name="uniquelyNamed">ファイル名を一意にする(タイムスタンプを使う)</h3>
-
- <p>アプリケーションの開発フェーズの間や、アプリケーションを実行している時間が短い(たとえば、バッチアプリケーション)場合は、アプリケーションを実行するたびに新しいログファイルを作るほうがよいでしょう。<code>timestamp要素</code>を使えば簡単に実現できます。以下に例を示します。</p>
-
-
- <p class="example">例:タイムスタンプを使ってファイル名を一意にするFileAppenderの設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-timestamp.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-timestamp');">Groovyとして表示</span>
- <pre id="logback-timestamp" class="prettyprint source"><configuration>
-
- <!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
- the key "bySecond" into the logger context. This value will be
- available to all subsequent configuration elements. -->
- <b><timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/></b>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <!-- use the previously created timestamp to create a uniquely
- named log file -->
- <file><b>log-${bySecond}.txt</b></file>
- <encoder>
- <pattern>%logger{35} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <p>timestamp要素には、<span class="attr">key属性</span>および<span class="attr">datePattern属性</span>という2つの必須属性と、<span class="attr">timeReference属性</span>という任意属性があります。<span class="attr">key属性</span>には、<a href="./configuration.html#variableSubstitution">変数</a>と同じく、他の設定要素からタイムスタンプを参照するときの名前を指定します。<span class="attr">datePattern</span>属性には、設定ファイルを解釈した時点の日時を文字列に変換するための日付パターン文字列を指定します。日付パターン文字列に指定できるのは、<a href="https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat [...]
- </p>
-
- <p>次のコマンドを実行して、<code>timestamp要素</code>がどうなるのか試してみましょう。</p>
-
- <p class="command">java chapters.appenders.ConfigurationTester src/main/java/chapters/appenders/conf/logback-timestamp.xml</p>
-
- <p>ロガーコンテキストを生成した日時を基準時間として使う場合、<span class="attr">timeReference属性</span>に"contextBirth"を指定します。</p>
-
-
- <p class="example">例:タイムスタンプの基準時間にロガーコンテキストを生成した日時を使用する(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/blogback-timestamp-contextBirth.xml">logback-examples/src/main/java/chapters/appenders/conf/blogback-timestamp-contextBirth.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-timestamp-contextBirth');">Groovyとして表示</span>
- <pre id="logback-timestamp-contextBirth" class="prettyprint source"><configuration>
- <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"
- <b>timeReference="contextBirth"</b>/>
- ...
-</configuration></pre>
-
- <h2 class="doAnchor" name="RollingFileAppender">RollingFileAppender</h2>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/core/rolling/RollingFileAppender.html"><code>RollingFileAppender</code></a>は<code>FileAppender</code>を拡張して、ログファイルを切り替えられるようにしたものです。たとえば、<code>RollingFileAppender</code>では、<em>log.txt</em>という名前のファイルにログを出力するようにした上で、一定の条件が満たされたら、出力先を別のファイルに変えることができます。
- </p>
-
- <p><code>RollingFileAppender</code>と連携する2つの重要なサブコンポーネントがあります。一つは<code>RollingPolicy</code>です。これはファイルを切り替えるために必要な処理を行います。<a href="./appenders.html#onRollingPolicies">詳しくは後述します</a>。もう一つは<code>TriggeringPolicy</code>です。これはいつ切り替えるのか決定するものです。こちらも<a href="./appenders.html#TriggeringPolicy">詳しくは後述します</a>。つまり、<code>RollingPolicy</code>が<em>what</em>を、<code>TriggeringPolicy</code>が<em>when</em>を表しているのです。</p>
-
- <p>どんな使い方をするにしても、<code>RollingFileAppender</code>には<code>RollingPolicy</code>と<code>TriggeringPolicy</code>の両方を設定しなければなりません。<code>RollingPolicy</code>は<code>TriggeringPolicy</code>インターフェイスを実装しているので、少なくともRollingPolicyだけは明示的に設定しなければなりません。
- </p>
-
- <p><code>RollingFileAppender</code>で利用出来るプロパティは次のとおりです。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="rfa">file</span></td>
- <td><code>String</code></td>
- <td><code>FileAppender</code>と同じです。</td>
- </tr>
- <tr>
- <td><span class="prop" container="rfa">append</span></td>
- <td><code>boolean</code></td>
- <td><code>FileAppender</code>と同じです。</td>
- </tr>
- <tr>
- <td><span class="prop" container="rfa">encoder</span></td>
- <td>
- <a href="http://logback.qos.ch/xref/ch/qos/logback/core/encoder/Encoder.html"><code>Encoder</code></a>
- </td>
- <td><code>OutputStreamAppender</code>と同じです。</td>
- </tr>
- <tr>
- <td><span class="prop" container="rfa">rollingPolicy</span></td>
- <td><code>RollingPolicy</code></td>
- <td>このオプションに指定するのは、<code>RollingFileAppender</code>がファイルを切り替える際に処理を委譲するコンポーネントです。詳細は後述します。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="rfa">triggeringPolicy</span></td>
- <td><code>TriggeringPolicy</code></td>
- <td>このオプションに指定するのは、<code>RollingFileAppender</code>にファイルを切り替えるタイミングを通知するコンポーネントです。詳細は後述します。
- </td>
- </tr>
- <tr>
- <td valign="top"><span class="prop" name="prudentWithRolling">prudent</span></td>
-
- <td valign="top"><code>boolean</code></td>
-
- <td valign="top">
- prudentモードでは、<a href="./appenders.html#FixedWindowRollingPolicy"><code>FixedWindowRollingPolicy</code></a>はサポートされていません。
-
- <p> <a href="./appenders.html#TimeBasedRollingPolicy"><code>TimeBasedRollingPolicy</code></a>を使えば<code>RollingFileAppender</code>でもprudentモードを利用できますが、二つの制限があります。
- </p>
-
- <ol>
- <li>purudentモードでは、ファイル圧縮オプションをサポートしていませんし、利用することもできません。(他のJVMがログファイルを圧縮している間、書き込むことはできません)</li>
-
- <li><code>FileAppender</code>の<span class="prop">file</span>プロパティを指定することはできません。空のままにしておかなければなりません。ほとんどのOSでは、他のプロセスが開いているファイルの名前を変えることはできません。
- </li>
-
- </ol>fileプロパティについては<code>FileAppender</code>の説明を参照してください。
- </td>
- </tr>
- </table>
-
- <h3 class="doAnchor" name="onRollingPolicies">ローリングポリシーの概要</h3>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/core/rolling/RollingPolicy.html"><code>RollingPolicy</code></a>は、ファイルの切り替えに伴う移動や名前の変更を行います。</p>
-
- <p><code>RollingPolicy</code>インターフェイスは次のようなものです。</p>
-
- <pre class="prettyprint source">package ch.qos.logback.core.rolling;
-
-import ch.qos.logback.core.FileAppender;
-import ch.qos.logback.core.spi.LifeCycle;
-
-public interface RollingPolicy extends LifeCycle {
-
- <b>public void rollover() throws RolloverFailure;</b>
- public String getActiveFileName();
- public CompressionMode getCompressionMode();
- public void setParent(FileAppender appender);
-}</pre>
-
- <p><code>rollover</code>メソッドによって、現在のログファイルのアーカイブ処理を行います。<code>getActiveFileName()</code>メソッドは、今まさにログを出力しているはずのログファイル名を算出するために呼び出されます。<code>getCompressionMode</code>メソッドの名前が示すとおり、RollingPolicyにはファイル圧縮モードを決める役割もあります。<code>RollingPolicy</code>から親となるアペンダーへの参照は、<code>setParent()</code>メソッドによって設定します。
- </p>
-
- <!-- =================
- ================= -->
-
-
- <h4 class="doAnchor" name="TimeBasedRollingPolicy">TimeBasedRollingPolicy</h4>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.html">TimeBasedRollingPolicy</a></code>はおそらく一番人気のあるポリシーです。これは、ファイル切り替えポリシーを日付や月などの日時に基いて定義するものです。
- <code>TimeBasedRollingPolicy</code>にはファイルを切り替えるタイミングを通知する役割もあります。実際に、 <code>TimeBasedTriggeringPolicy</code>は<code>RollingPolicy</code>と<code>TriggeringPolicy</code>の<em>両方</em>のインターフェイスを実装しています。
- </p>
-
- <p><code>TimeBasedRollingPolicy</code>には、必須プロパティの<span class="prop">fileNamePattern</span>と、いくつかの任意のプロパティが設定できます。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="tbrp">fileNamePattern</span></td>
- <td><code>String</code></td>
- <td><span class="prop">fileNamePattern</span>プロパティは必須プロパティで、切り替えるときのログファイル名を指定します。指定する値には、ファイル名と<em>%d変換指示子</em>が含まれます。<em>%d変換指示子</em>には、<code>java.text.SimpleDateFormat</code>クラスで定義された日付時刻のパターン文字列を指定します。日付時刻パターンが省略された場合、パターン文字列として<em>yyyy-MM-dd</em>が使われます。<b>ファイルの切り替え周期は、<span class="prop">fileNamePattern</span>に指定された値から推測されます。</b>
-
-
- <p><code>TimeBasedRollingPolicyの親アペンダーである<code>RollingFileAppender</code>の<span class="prop">file</span>プロパティは、指定することもできるし省略することもできます。</code><span class="prop">file</span>プロパティにファイル名を指定した場合、ログを出力するファイルとアーカイブファイルの場所を別々にすることができます。ログは常に<span class="prop">file</span>プロパティで指定されたファイルに出力されます。
-そうすると、有効なログファイルを常に同じ名前にしておくことができます。<span class="prop">file</span>プロパティを省略した場合、有効なログファイル名は、<span class="prop">fileNamePattern</span>プロパティに指定した値に基いて定期的に新しい名前になります。この振る舞いを明確に説明する例を以降に示します。
- </p>
-
- <p>%d{}変換指示子の内側に書かれる日付と時刻のパターン文字列は、java.text.SimpleDateFormatの規約にしたがったものです。<span class="option">fileNamePattern</span>プロパティの中であれば、日付と時刻のパターン文字列の中でも外でも、スラッシュ'/'およびバックスラッシュ'\'はディレクトリの区切り文字として扱われます。
- </p>
-
- <p>%dトークンはいくつでも指定することができますが、ファイル切り替え周期を推測するために使われるのは最初のものだけです。他のすべてのトークンには、'aux'パラメータを指定して補助であるという印を<em>付けなければなりません</em>。</p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="tbrp">maxHistory</span></td>
- <td>int</td>
- <td><span class="prop">maxHistory</span>プロパティは、任意プロパティです。削除せずに保持しておくアーカイブファイルの最大数を指定します。たとえば毎月切り替えるつもりでmaxHistoryに6を指定した場合、過去6ヶ月以内のアーカイブファイルは保持され、過去6ヶ月より古いファイルは削除されるでしょう。古くなったファイルだけが削除されるので、logbackが作成したディレクトリは削除されないので注意してください。
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="tbrp">cleanHistoryOnStart</span></td>
- <td>boolean</td>
- <td>
- <p>trueを指定した場合、アペンダーの開始時に古いアーカイブを削除します。デフォルトではfalseが設定されています。</p>
-
- <p>通常は、ファイルを切り替えるタイミングで古いアーカイブも削除されます。しかし、アプリケーションによっては切り替えのタイミングが来るまで実行し続けないことがあります。そういう短命なアプリケーションでは、古いアーカイブを削除するタイミングが来ない可能性があるのです。<span class="prop">cleanHistoryOnStart</span>プロパティにtrueを指定しておけば、アペンダーの開始時に古いアーカイブを削除することができます。</p>
- </td>
- </tr>
- </table>
-
-
- <p><code>fileNamePattern</code>の値とその効果について具体例を示します。</p>
-
-
-
- <table class="bodyTable striped">
- <tr>
- <th>
- <span class="prop">fileNamePattern</span>
- </th>
- <th>切り替えタイミング</th>
- <th>具体例</th>
- </tr>
- <tr>
- <td class="small">
- <em>/wombat/foo.%d</em>
- </td>
- <td>毎日深夜に切り替え。<em>%d変換指示子</em>に日付時刻パターンが省略されているので、デフォルトの<em>yyyy-MM-dd</em>が指定されたことになります。このパターン文字列の場合は、毎日切り替えることになります。
- </td>
-
- <td>
- <p><span class="prop">file</span>プロパティを指定しない場合:2006年11月23日中は<em>/wombat/foo.2006-11-23</em>に出力されます。23日の24時(24日の0時)以降、24日中は<em>/wombat/foo.2006-11-24</em>に出力されます。
- </p>
-
- <p><span class="prop">file</span>プロパティに<em>/wombat/foo.txt</em>を指定した場合:2006年11月23日中は<em>/wombat/foo.txt</em>に出力されます。23日24時(24日0時)に<em>foo.txt</em>は<em>/wombat/foo.2006-11-23</em>に変更されます。24日中は、新しく作成された<em>/wombat/foo.txt</em>に出力されます。
- </p>
-
- </td>
- </tr>
-
-
- <tr>
- <td class="small">
- <em>/wombat/%d{yyyy/MM}/foo.txt</em>
- </td>
- <td>月初めに切り替え。</td>
- <td>
- <p><span class="prop">file</span>プロパティを指定しない場合:2006年10月中は、<em>/wombat/2006/10/foo.txt</em>に出力されます。10月31日の24時(つまり11月1日の0時)以降、11月中は<em>/wombat/2006/11/foo.txt</em>に出力されます。
- </p>
-
- <p><span class="prop">file</span>プロパティに<em>/wombat/foo.txt</em>を指定した場合:出力先は常に<em>/wombat/foo.txt</em>です。2006年10月中は、<em>/wombat/foo.txt</em>に出力されます。10月31日の24時(つまり11月1日の0時)に<em>/wombat/foo.txt</em>は<em>/wombat/2006/10/foo.txt</em>に変更されます。11月中は、新しく作成された<em>/wombat/foo.txt</em>に出力されます。11月30日の24時(つまり12月1日の0時)に<em>/wombat/foo.txt</em>は<em>/wombat/2006/11/foo.txt</em>に変更されます。
- </p>
- </td>
- </tr>
- <tr>
- <td class="small">
- <em>/wombat/foo.%d{yyyy-ww}.log</em>
- </td>
-
- <td>週初めに切り替え。週の最初の日は、ロケールに依存するので注意してください。</td>
-
- <td>前の例と同じですが、切り替えが発生するのは週の初日です。
- </td>
- </tr>
- <tr>
- <td class="small">
- <em>/wombat/foo%d{yyyy-MM-dd_HH}.log</em>
- </td>
- <td>毎時0分に切り替え。</td>
- <td>前の例と同じですが、切り替えが発生するのは毎時0分です。
- </td>
- </tr>
- <tr>
- <td class="small">
- <em>/wombat/foo%d{yyyy-MM-dd_HH-mm}.log</em>
- </td>
- <td>毎分0秒に切り替え。</td>
- <td>前の例と同じですが、切り替えが発生するのは毎分0秒です。
-
- </td>
- </tr>
-
-
- <tr>
- <td class="small">
- <em>/foo/%d{yyyy-MM,<b>aux</b>}/%d.log</em>
- </td>
- <td>毎日深夜に切り替え。年と月からなる名前のフォルダにアーカイブを作成する。
- </td>
- <td>この例では、最初の%dトークンは補助(<b>aux</b>iliary)であるという印が付いています。したがって、日付時刻パターンの省略された二つ目の%dトークンが最初のものとして使われます。したがって、切り替えタイミングは日次(%dのデフォルトパターン)になり、アーカイブするフォルダ名はそのときの年と月になります。例えば、2006年11月中にアーカイブされたファイルはすべて<em>/foo/2006-11</em>というフォルダに置かれます。例えば<em>/foo/2006-11/2006-11-14.log</em>のようになります。
- </td>
-
- </tr>
- </table>
-
- <p>スラッシュまたはバックスラッシュ文字はフォルダ(ディレクトリ)の区切り文字として扱われます。存在しないフォルダは必要に応じて作成されるので、別々のフォルダにログファイルを作るのは簡単です。
- </p>
-
-
- <p><code>TimeBasedRollingPolicy</code>は、<code>FixedWindowRollingPolicy</code>のように自動ファイル圧縮をサポートしています。<span class="prop">fileNamePattern</span>オプションの値が<em>.gz</em>または<em>.zip</em>で終わっている場合、このフィーチャが有効になります。
- </p>
-
- <table class="bodyTable striped">
- <tr class="a">
- <th><span class="prop">fileNamePattern</span></th>
- <th>切り替えタイミング</th>
- <th>具体例</th>
- </tr>
- <tr>
- <td><em>/wombat/foo.%d.gz</em></td>
- <td>毎日深夜に切り替え。アーカイブファイルは自動的にgz圧縮する。</td>
- <td>
- <p><span class="prop">file</span>プロパティを指定しない場合:2009年11月23日中は<em>/wombat/foo.2009-11-23</em>に出力します。23日24時(24日0時)になったら、それまでログを出力していたファイルはgz圧縮されて<em>/wombat/foo.2009-11-23.gz</em>になります。11月24日中は<em>/wombat/folder/foo.2009-11-24</em>に出力されます。
- </p>
-
- <p><span class="prop">file</span>プロパティに<em>/wombat/foo.txt</em>を指定した場合:2009年11月23中は<em>/wombat/foo.txt</em>に出力されます。23日24時(24日0時)にgz圧縮されて<em>/wombat/foo.2009-11-23.gz</em>になります。11月24日中は新しく作られた<em>/wombat/foo.txt</em>に出力されます。24日24時(25日0時)に<em>/wombat/foo.txt</em>はgz圧縮されて<em>/wombat/foo.2009-11-24.gz</em>になります。
- </p>
- </td>
- </tr>
- </table>
-
- <p><span class="prop">fileNamePattern</span>には2つの目的があります。1つは、パターン文字列を処理して、logbackに切り替えタイミングを指示することです。もう1つはアーカイブファイル名を決めることです。パターン文字列の形が違っても切り替えタイミングが同じになることがあるので気をつけてください。パターン文字列が<em>yyyy at MM</em>でも<em>yyyy-MM</em>でも、切り替えタイミングは毎月ですが、アーカイブファイル名は異なります。
- </p>
-
- <p><span class="prop">file</span>プロパティを設定すると、アクティブなログファイルの場所とアーカイブファイルの場所を別々にすることができます。ログは<span class="prop">file</span>プロパティで指定したファイルに出力されます。つまり、アクティブなログファイルの名前は常に同じになるのです。ただし、<span class="prop">file</span>プロパティを省略した場合、アクティブなログファイルの名前は<span class="prop">fileNamePattern</span>に基づいたものになります。<span class="prop">file</span>オプションを設定しなければ、<a href="http://logback.qos.ch/codes.html#renamingError">ログファイルの名前変更エラー</a>を割けられます。これは外部からログファイルを参照している間に切り替えようとすると発生するエラーです。存在するときに発生する。
- </p>
-
- <p><span class="prop">maxHistory</span>プロパティは、削除せずに保持しておくアーカイブファイルの最大数を指定します。たとえば、切り替えタイミングが毎月で、<span class="prop">maxHistory</span>に6を指定していたら、6ヶ月以内のアーカイブは保持されますが、6ヶ月を超える古いアーカイブは削除されます。古いアーカイブは削除されてしまうので注意しましょう。logbackによって作られたフォルダも必要に応じて削除されてしまいます。
- </p>
-
- <p>技術的な都合により、ファイルの切り替えは時間ベースではなくロギングイベントの到着ベースで行われます。例えば、2002年3月8日時点で<span class="prop">fileNamePattern</span>に<em>YYYY-MM-DD</em>(毎日切り替え)が指定されていることにしましょう。すると、8日24時(9日0時)を過ぎてから最初のロギングイベントが到着した際にファイルの切り替えが行われます。しばらくロギングイベントが発生しなかった場合、たとえば0時を過ぎてから23分47秒後にロギングイベントが発生した場合、3月9日0時0分ではなく、0時23分47秒にファイルの切り替えが行われることになります。したがって、ファイル切り替えにはロギングイベントの頻度に応じた遅延が伴います。どれくらいの遅延があろうとも、切り替えアルゴリズムは常に正しく動作します。したがってあらゆるロギングイベントはそれが発生した時刻に基いて適切なファイルに出力されます。
- </p>
-
- <p><code>RollingFileAppender</code>と<code>TimeBasedRollingPolicy</code>の設定例を見てください。
- </p>
-
- <p class="example">例:<code>RollingFileAppender</code>と<code>TimeBasedRollingPolicy</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-RollingTimeBased.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-RollingTimeBased.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-RollingTimeBased');">Groovyとして表示</span>
- <pre id="logback-RollingTimeBased" class="prettyprint source"><configuration>
- <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <file>logFile.log</file>
- <b><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <!-- daily rollover -->
- <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
-
- <!-- keep 30 days' worth of history -->
- <maxHistory>30</maxHistory>
- </rollingPolicy></b>
-
- <encoder>
- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
- <p>次の例はprudentモードの例です。
- </p>
-
- <p class="example">例:prudentモードにした<code>RollingFileAppender</code>と<code>TimeBasedRollingPolicy</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-PrudentTimeBasedRolling');">Groovyとして表示</span>
- <pre id="logback-PrudentTimeBasedRolling" class="prettyprint source"><configuration>
- <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <b><!-- Support multiple-JVM writing to the same log file --></b>
- <b><prudent>true</prudent></b>
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
- <maxHistory>30</maxHistory>
- </rollingPolicy>
-
- <encoder>
- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <h4 class="doAnchor" name="FixedWindowRollingPolicy">FixedWindowRollingPolicy</h4>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.html">FixedWindowRollingPolicy</a></code>を使うと、固定幅アルゴリズムに従ってファイルの名前を変更することができます。
- </p>
-
- <p><span class="prop">fileNamePattern</span>オプションには、アーカイブファイル名のパターンを指定します。このオプションは必須<em>で</em>、パターン文字列中のどこかに整数トークンの<em>%i</em>を含めなければなりません。
- </p>
-
- <p><code>FixedWindowRollingPolicy</code>のプロパティは次のとおりです。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="fwrp">minIndex</span></td>
- <td><code>int</code></td>
- <td>
- <p>このオプションには固定幅の添字の下限値を指定します。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="fwrp">maxIndex</span></td>
- <td><code>int</code></td>
- <td>
- <p>このオプションには固定幅の添字の上限値を指定します。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="fwrp">fileNamePattern</span></td>
- <td><code>String</code></td>
- <td>
- <p>このオプションには<code>FixedWindowRollingPolicy</code>がログファイルをアーカイブするファイル名のパターン文字列を指定します。パターン文字列には<em>%i</em>を含めなければなりません。これは、現在の幅に追加する位置の添字になります。
- </p>
- <p>例えば、パターン文字列が<em>MyLogFile%i.log</em>、<em>minIndex</em>が1、<em>maxIndex</em>が3だとしたら、アーカイブファイル名は<em>MyLogFile1.log</em>、<em>MyLogFile2.log</em>、<em>MyLogFile3.log</em>のいずれかになります。
- </p>
- <p>自動ファイル圧縮を有効にする場合もこのプロパティで指定することになります。例えば、<span class="prop">fileNamePattern</span>に<em>MyLogFile%i.log.zip</em>が指定されている場合、アーカイブされたファイルは<em>zip形式</em>で圧縮されることになります。<em>gz形式</em>も有効です。
- </p>
- </td>
- </tr>
- </table>
-
- <p>固定幅切り替えポリシーでは、指定した窓の大きさによってはたくさんのファイル名を変更しなければなりません。ですので、あまりに大きな値を指定することは極力避けるようにしてください。利用者が指定した窓が大きすぎる場合、現在の実装は窓の大きさを自動的に20にしてします。
- </p>
-
- <p>固定幅切り替えポリシーの具体的な例を見ていきましょう。それぞれ、<span class="prop">minIndex</span>が<em>1</em>、<span class="prop">maxIndex</span>が<em>3</em>、<span class="prop">fileNamePattern</span>が<em>foo%i.log</em>、<span class="prop">file</span>プロパティが<em>foo.log</em>となっていることを想定しています。;
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>切り替え回数</th>
- <th>現在の出力対象</th>
- <th>アーカイブファイル</th>
- <th>説明</th>
- </tr>
- <tr>
- <td>0</td>
- <td>foo.log</td>
- <td>-</td>
- <td>まだ切り替えは発生していません。logbackは最初に指定されたファイルにログを出力しています。
- </td>
- </tr>
- <tr>
- <td>1</td>
- <td>foo.log</td>
- <td>foo1.log</td>
- <td>切り替えが発生しました。<em>foo.log</em>が<em>foo1.log</em>という名前に変更されました。新しく<em>foo.log</em>が作成され、現在の出力対象になりました。
- </td>
- </tr>
- <tr>
- <td>2</td>
- <td>foo.log</td>
- <td>foo1.log、foo2.log</td>
- <td>切り替えが発生しました。<em>foo1.log</em>が<em>foo2.log</em>という名前に変更され、<em>foo.log</em>が<em>foo1.log</em>という名前に変更されました。新しく<em>foo.log</em>が作成され、現在の出力対象になりました。
- </td>
- </tr>
- <tr>
- <td>3</td>
- <td>foo.log</td>
- <td>foo1.log、foo2.log、foo3.log</td>
- <td>切り替えが発生しました。<em>foo2.log</em>が<em>foo3.log</em>という名前に変更され、<em>foo1.log</em>が<em>foo2.log</em>という名前に変更され、<em>foo.log</em>が<em>foo1.log</em>という名前に変更されました。新しく<em>foo.log</em>が作成され、現在の出力対象になりました。
-
- </td>
- </tr>
- <tr>
- <td>4</td>
- <td>foo.log</td>
- <td>foo1.log、foo2.log、foo3.log</td>
- <td>以降の切り替えでは、最初にアーカイブ<em>foo3.log</em>を削除します。その他のファイルは、前のステップと同じように、添字を増やした名前に変更されます。以降は、常に1つのログファイル、3つのアーカイブファイルが存在することになります。
- </td>
- </tr>
- </table>
-
- <p><code>RollingFileAppender</code>と<code>FixedWindowRollingPolicy</code>の設定例を次に示します。<span class="prop">fileNamePattern</span>オプションに同じ情報が含まれているとはいえ、 <span class="prop">File</span>オプションは必須なので注意してください。
- </p>
-
- <p class="example">例:<code>RollingFileAppender</code>と<code>FixedWindowRollingPolicy</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-RollingFixedWindow.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-RollingFixedWindow.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-RollingFixedWindow');">Groovyとして表示</span>
- <pre id="logback-RollingFixedWindow" class="prettyprint source"><configuration>
- <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <b><file>test.log</file></b>
-
- <b><rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
- <fileNamePattern>tests.%i.log.zip</fileNamePattern>
- <minIndex>1</minIndex>
- <maxIndex>3</maxIndex>
- </rollingPolicy></b>
-
- <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
- <maxFileSize>5MB</maxFileSize>
- </triggeringPolicy>
- <encoder>
- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <h3 class="doAnchor" name="SizeAndTimeBasedFNATP">日時<b>と</b>サイズに基づいたログファイルのアーカイブ</h3>
-
- <p>基本的には日付でファイルをアーカイブしたいけど、後続処理ツールに指定できるログファイルにサイズ制限があるので、ログファイルのサイズも制限したいことがあるでしょう。そんなときは、logbackの配布物に含まれる<code>TimeBasedRollingPolicy</code>のサブコンポーネントである<code>SizeAndTimeBasedFNATP</code>を使うとよいでしょう。FNATP は File Naming And Triggering Policy の略です。</p>
-
- <p>日時とサイズに基づいてログファイルをアーカイブする設定ファイルの例を示します。</p>
-
- <p class="example">例:<code>SizeAndTimeBasedFNATP</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-sizeAndTime.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-sizeAndTime.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-sizeAndTime');">Groovyとして表示</span>
- <pre id="logback-sizeAndTime" class="prettyprint source"><configuration>
- <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <file>mylog.txt</file>
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <!-- rollover daily -->
- <fileNamePattern><b>mylog-%d{yyyy-MM-dd}.<span class="big">%i</span>.txt</b></fileNamePattern>
- <b><timeBasedFileNamingAndTriggeringPolicy</b>
- <b>class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"></b>
- <!-- or whenever the file size reaches 100MB -->
- <b><maxFileSize>100MB</maxFileSize></b>
- <b></timeBasedFileNamingAndTriggeringPolicy></b>
- </rollingPolicy>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
-
- <root level="DEBUG">
- <appender-ref ref="ROLLING" />
- </root>
-
-</configuration></pre>
-
- <p>"%d"トークンに加えて、"%i"トークンがあることに気づきましたか。次の切り替えタイミングがくるまでの間に、現在のログファイルが<span class="prop">maxFileSize</span>に指定したサイズを越えたら、添字を加算してアーカイブします。添字は0から始まります。</p>
-
- <p>日時とサイズに基づいたログファイルのアーカイブをしていても、古いアーカイブを削除することができます。残しておくアーカイブの数を<span class="prop">maxHistory</span>プロパティで指定しなければなりません。アプリケーションが停止してその後再起動した場合でも、正しい添字のファイルにログを出力します。
- </p>
-
- <h2>
- <a name="TriggeringPolicy" href="./appenders.html#TriggeringPolicy">トリガーポリシーについて</a>
- </h2>
-
- <p><code>RollingFileAppender</code>にファイルを切り替えるタイミングを通知するのが<a href="http://logback.qos.ch/xref/ch/qos/logback/core/rolling/TriggeringPolicy.html"><code>TriggeringPolicy</code></a>です。</p>
-
- <p><code>TriggeringPolicy</code>インターフェイスには1つだけメソッドが宣言されています。</p>
-
- <pre class="prettyprint source">package ch.qos.logback.core.rolling;
-
-import java.io.File;
-import ch.qos.logback.core.spi.LifeCycle;
-
-public interface TriggeringPolicy<E> extends LifeCycle {
-
- <b>public boolean isTriggeringEvent(final File activeFile, final <E> event);</b>
-}</pre>
-
- <p><code>isTriggeringEvent()</code>メソッドには、二つの引数があります。1つは現在有効なファイル、もう1つは処理中のロギングイベントです。これらのパラメータに基づいて、ファイルの切り替えをするべきかどうかを判断します。
- </p>
-
- <p>最もよく使われているトリガーポリシーは<code>TimeBasedRollingPolicy</code>です。これはローリングポリシーの別名です。他のローリングポリシーの説明と合わせて<a href="./appenders.html#TimeBasedRollingPolicy">説明</a>したとおりです。</p>
-
- <h4><a name="SizeBasedTriggeringPolicy" href="./appenders.html#SizeBasedTriggeringPolicy">SizeBasedTriggeringPolicy</a></h4>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.html">SizeBasedTriggeringPolicy</a></code>は現在有効なファイルのサイズを判断します。指定したサイズより大きくなった場合、<code>RollingFileAppender</code>に現在のファイルを切り替えるよう通知します。
- </p>
-
- <p><code>SizeBasedTriggeringPolicy</code>は<span class="prop">maxFileSize</span>パラメータだけを受け付けます。デフォルトは10MBです。</p>
-
- <p><span class="prop">maxFileSize</span>オプションはバイト、キロバイト、メガバイト、ギガバイト単位で指定できます。それぞれ<em>KB</em>、<em>MB</em>、<em>GB</em>という接尾辞を使うこともできます。たとえば、<em>5000000</em>、<em>5000KB</em>、<em>5MB</em>、<em>2GB</em>はすべて正しい値です。最初の三つは同じ値になります。
- </p>
-
- <p>ファイルサイズが5MBを越えたら切り替える場合の
-<code>RollingFileAppender</code>と<code>SizeBasedTriggeringPolicy</code>の設定例を見てみましょう。
- </p>
-
- <p class="example">例:<code>RollingFileAppender</code>と<code>SizeBasedTriggeringPolicy</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-RollingSizeBased.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-RollingSizeBased.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-RollingSizeBased');">Groovyとして表示</span>
- <pre id="logback-RollingSizeBased" class="prettyprint source"><configuration>
- <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <file>test.log</file>
- <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
- <fileNamePattern>test.%i.log.zip</fileNamePattern>
- <minIndex>1</minIndex>
- <maxIndex>3</maxIndex>
- </rollingPolicy>
-
- <b><triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
- <maxFileSize>5MB</maxFileSize>
- </triggeringPolicy></b>
- <encoder>
- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx -->
- <a name="Classic"></a>
- <h2>logback-classicモジュール</h2>
-
-
- <p>ロギングイベントはlogback-coreモジュールの中ではジェネリック型ですが、logback-classicでは<code>ILoggingEvent</code>のインスタンスになります。logback-classicでは、<code>ILoggingEvent</code>のインスタンスの具体的なパイプライン処理を行います。
-
- </p>
-
- <h3 class="doAnchor" name="SocketAppender">SocketAppenderとSSLSocketAppender</h3>
-
- <p>ここまでに紹介してきたアペンダーは、ローカルリソースだけにログを出力するものでした。対照的に、 <code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/SocketAppender.html">SocketAppender</a></code>はログをシリアライズした<code>ILoggingEvent</code>のインスタンスとしてリモートホストに送信するものとして設計されています。<code>SocketAppender</code>では、ロギングイベントを平文で送信します。<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/SSLSocketAppender.html">SSLSocketAppender</a></code>では、暗号化された安全なチャネルを介してロギングイベントを送信します。</p>
-
- <p>シリアライズされたロギングイベントの実際の型は、<code>ILoggingEvent</code>インターフェイスを実装した<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/spi/LoggingEventVO.html"><code>LoggingEventVO</code></a>です。ロギングイベントがどれだけ心配なのはわかりますが、リモートロギングが盗聴されることはありません。★受信したロギングイベントをデシリアライズしたら、ローカルで生成されたものとまったく同じように扱われます。それぞれのマシンで実行されている<code>SocketAppender</code>のインスタンスの出力書式がどれも同じになっていれば、中央ログサーバに直接ロギング出力を送りつけることができます。<code>SocketAppender</code>に割り当てられたレイアウトをリモートサーバに送ることはありません。シリアライズされたイベントを送信するからです。<code>SocketAppender< [...]
- </p>
-
- <p>ロギングイベントはネイティブのTCP実装によって自動的にバッファへ保存されます。つまり、リモートサーバへの通信速度がクライアントでロギングイベントを生成する速度より遅かったとしても、クライアントアプリケーションが通信速度に影響を受けることはない、ということです。通信速度がロギングイベントを生成する速度よりも遅ければ、クライアントは通信速度に合わせた速度でしか処理を進めることができません。極端な具体例ですが、リモートサーバへのネットワーク接続がダウンしている場合、最終的にクライアントはブロックしてしまいます。また、ネットワーク接続は生きててもリモートサーバがダウンしている場合、ロギングイベントはサーバが利用できないために破棄されてしまいますが、クライアントがブロックされることはありません。
- </p>
-
- <p>あらゆるロガーに<code>SocketAppender</code>が割り当てられていなかったとしても、コネクタースレッドが生きているかぎりGCに回収されることはありません。コネクタースレッドが死ぬのは、リモートサーバへの接続がダウンしたときだけです。このGCに伴う問題を回避するには、<code>SocketAppender</code>を明示的にクローズしなければなりません。長時間稼働するアプリケーションでは、非常に多くの<code>SocketAppender</code>のインスタンスを生成、破棄することになるので、このGCに伴う問題には注意してください。ほとんどのアプリケーションでは無視してもたいして問題になりません。<code>SocketAppender</code>をホストしているJVMが、<code>SocketAppender</code>をクローズする前に終了してしまうとしたら、それが明示的に行われるとしても、あるいは、GCの後であろうとも、通信用のパイプの中に残っていた未送信のデータは失われてしまうでしょう。これはWindowsベースの [...]
- </p>
-
- <p>リモートサーバは<span class="prop">remotehost</span>プロパティと<span class="prop">port</span>プロパティで指定します。
- <code>SocketAppender</code>のプロパティを表にまとめました。<code>SSLSocketAppender</code>にはこれよりも多くのプロパティが追加されています。詳しくは<a href="./usingSSL.html">SSLを使用する</a>の章を参照してください。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="socket">includeCallerData</span></td>
- <td><code>boolean</code></td>
- <td>
- <p><span class="prop" container="socket">includeCallerDataオプション</span>には真偽値を指定します。trueの場合、リモートホストでログの送信者情報が利用できるようになります。デフォルトでは発信者情報をサーバに送信しません。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="socket">port</span></td>
- <td><code>int</code></td>
- <td>
- <p>リモートサーバのポート番号です。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="socket">reconnectionDelay</span></td>
- <td><code><a href="http://logback.qos.ch/apidocs/ch/qos/logback/core/util/Duration.html">Duration</a></code></td>
- <td><span class="prop">reconnectionDelay</span>オプションには、待ち時間を表す文字列を指定します。たとえば、"10 seconds"と指定した場合、サーバへの接続が失敗するたびに10秒間待ってから、再接続を試みます。このオプションのデフォルト値は30秒です。0を指定すると再接続機能が無効になります。サーバへの接続が成功した場合、コネクタースレッドは存在しないはずなので注意してください。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="socket">queueSize</span></td>
- <td><code>int</code></td>
- <td>
- <p><span class="prop">queueSize</span>プロパティには、受信側に配信するために蓄えておくロギングイベントの数を、非負の整数で指定します。キューサイズが0の場合、イベントの配信は同期になります。キューサイズが0より大きい場合、キューに空きがあれば新しいロギングイベントはキューに入れられるようになります。キューの長さを0以外にすると、一時的なネットワークの遅延によって発生する配信の遅れを排除することができるので、性能が向上します。
- </p>
-
- <p><span class="prop">eventDelayLimit</span>プロパティのことも参照してください。</p>
-
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="socket">eventDelayLimit</span></td>
- <td><code><a href="http://logback.qos.ch/apidocs/ch/qos/logback/core/util/Duration.html">Duration</a></code></td>
- <td><span class="prop">eventDelayLimit</span>オプションには、"10 seconds"のような待ち時間を表す文字列を指定します。これは、ローカルキューが満杯になった際、蓄積されたロギングイベントを削除する前に待機する時間を表しています。リモートホストがロギングイベントを受信するのが継続的に遅い場合に発生する可能性があります。このオプションのデフォルト値は100ミリ秒です。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="socket">remoteHost</span></td>
- <td><code>String</code></td>
- <td>リモートサーバのホスト名です。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="socket">ssl</span></td>
- <td><code>SSLConfiguration</code></td>
- <td><code>SSLSocketAppender</code>だけがサポートするプロパティです。アペンダーから利用されるSSL設定を指定します。詳しくは<a href="./usingSSL.html">SSLを使用する</a>を参照してください。</td>
- </tr>
- </table>
-
- <h4>サーバ用のオプション</h4>
- <p>標準的なlogback-classicの配布物には、<code>SocketAppender</code>あるいは<code>SSLSocketAppender</code>からロギングイベントを受け取るための2つのサーバ用オプションが含まれています。</p>
- <ul>
- <li><code>ServerSocketReceiver</code>とそのSSL対応版の<code>SSLServerSocketReceiver</code>は、リモートホストのソケットアペンダーからロギングイベントを受け取るための受信用コンポーネントです。<em>logback.xml</em>で設定できるようになっています。設定内容については使用例と<a href="./receivers.html">レシーバーの章</a>を参照してください。
- </li>
- <li><code>SimpleSocketServer</code>とそのSSL対応版の<code>SimpleSSLSocketServer</code>は、スタンドアローンJavaアプリケーションから簡単に使うために用意されたものです。UnixシェルのCUI(コマンドラインインターフェイス)で設定できるようになっています。これらのアペンダーを設定したアプリケーションは、単純に<code>SocketAppender</code>または<code>SSLSocketAppender</code>のクライアントからロギングイベントが送信されてくるのを待ちます。受信したロギングイベントは、自身の設定に従ってロギングされます。使用例は次のとおりです。
- </li>
- </ul>
-
- <h4><a name="simpleSocketServer"></a> SimpleSocketServerの使い方</h4>
- <p><code>SimpleSocketServer</code>アプリケーションはコマンドライン引数を2つ取ります。<em>port</em>と<em>configFile</em>です。 <em>port</em>には待ち受けるポート番号を、<em>configFile</em>にはXML形式の設定ファイルを指定します。
- </p>
-
- <p><em>logback-examples</em>ディレクトリに移動してから、次のコマンドを実行すると<code>SimpleSocketServer</code>を開始できます。</p>
-
- <p class="source">java ch.qos.logback.classic.net.SimpleSocketServer 6000 \
- src/main/java/chapters/appenders/socket/server1.xml</p>
-
- <p>待ち受けるポート番号として6000、設定ファイルとして<em>server1.xml</em>を指定しています。この設定ファイルでは、ルートロガーに<code>ConsoleAppender</code>と<code>RollingFileAppender</code>を割り当てています。<code>SimpleSocketServer</code>を開始すれば、複数のロギングクライアントから<code>SocketAppender</code>を使ってロギングイベントを送信できるようになります。このマニュアルでは2つのクライアントを用意しています。<code>chapters.appenders.SocketClient1</code>と<code>chapters.appenders.SocketClient2</code>です。どちらもコンソールで利用者が何かキー入力するのを待つようになっています。利用者がキー入力したテキストはログレベルがDEBUGのロギングイベントに包まれてリモートサーバに送信されます。それぞれのクライアントの<code>Sock [...]
- </p>
-
- <p><code>SimpleSocketServer</code>をローカルホスト上で実行しているなら、次のようなコマンドで接続することができます。</p>
-
- <p class="source">java chapters.appenders.socket.SocketClient1 localhost 6000</p>
-
- <p>クライアントのコンソールに入力したテキストは、前の手順で開始した<code>SimpleSocketServer</code>のコンソールに1行ずつ出力されます。<code>SimpleSocketServer</code>を一旦停止してから再び開始しても、クライアント側では何もなかったかのように透過的に新しいサーバインスタンスに再接続します。しかし、切断中に発生したロギングイベントは単純に破棄されてしまい、取り返すことができません。
- </p>
-
- <p><code>SocketClient1</code>と違って、<code>SocketClient2</code>ではアプリケーション自体でlogbackを設定していません。XML形式の設定ファイルが必要です。設定ファイル<em>client1.xml</em>の内容は次のとおりです。<code>SocketAppender</code>を定義して、ルートロガーに割り当てています。
- </p>
-
- <p class="example">例:SocketAppenderの設定(<a href="http://logback.qos.ch/xref/chapters/appenders/socket/client1.xml">logback-examples/src/main/java/chapters/appenders/socket/client1.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('client1');">Groovyとして表示</span>
-<pre id="client1" class="prettyprint source"><configuration>
-
- <appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
- <remoteHost>${host}</remoteHost>
- <port>${port}</port>
- <reconnectionDelay>10000</reconnectionDelay>
- <includeCallerData>${includeCallerData}</includeCallerData>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SOCKET" />
- </root>
-
-</configuration></pre>
-
-<p>上記の設定スクリプトでは、<span class="prop">remoteHost</span>,
-<span class="prop">port</span>、<span class="prop">includeCallerData</span>の値が変数で指定されているのがわかりますか。これらの変数の値は、システムプロパティとして指定することができます。</p>
-
- <p class="source">java -Dhost=localhost -Dport=6000 -DincludeCallerData=false \
- chapters.appenders.socket.SocketClient2 src/main/java/chapters/appenders/socket/client1.xml</p>
-
- <p>このコマンドを実行すると、前の<code>SocketClient1</code>と同じ設定になります。
- </p>
-
- <p>ロギングイベントのシリアライズは非侵入型であることをもう一度アピールさせていただきます。デシリアライズされたロギングイベントは、普通のロギングイベントと全く同じ情報を持っています。したがって、自分が生成したロギングイベントであるかのように扱うことができるのです。ただし、デフォルトではシリアライズされたロギングイベントには送信者情報が含まれていません。この点を説明する例を示します。まず<code>SimpleSocketServer</code>を準備しましょう。</p>
-
- <p class="source"> java ch.qos.logback.classic.net.SimpleSocketServer 6000 \
- src/main/java/chapters/appenders/socket/server2.xml</p>
-
- <p>設定ファイル<em>server2.xml</em>では<code>ConsoleAppender</code>を定義しています。レイアウトには、他の情報と合わせて送信元のファイル名と行番号を指定しています。前のように設定ファイル<em>client1.xml</em>を引数として<code>SocketClient2</code>を起動します。サーバ側のコンソールに出力されたログには、送信元のファイル名と行番号の代わりに2つのクエスチョンマークが出力されているはずです。</p>
-
- <p class="source">2006-11-06 17:37:30,968 DEBUG [Thread-0] [?:?] chapters.appenders.socket.SocketClient2 - Hi</p>
-
- <p>この出力は簡単に変更できます。<code>SocketAppender</code>が送信者情報を含めるように設定するには、<span class="prop">includeCallerDataオプションにtrueを指定するだけです。</span>次のように実行すればよいです。</p>
-
- <pre class="source">java -Dhost=localhost -Dport=6000 -DincludeCallerData=true \
- chapters.appenders.socket.SocketClient2 src/main/java/chapters/appenders/socket/client1.xml</pre>
-
- <p>デシリアライズされたロギングイベントは、ローカルで生成されたロギングイベントと同じように扱うことができます。つまり、追加で何か処理するためにさらに別のリモートサーバに送信することができるのです。サーバを2つ用意して、最初のサーバがクライアントから受け取ったロギングイベントをトンネルのようにそのまま二つ目のサーバに転送するところを確認するのは、読者の演習課題にしておきます。
- </p>
-
- <h4><a name="simpleSSLSocketServer"></a> SimpleSSLSocketServerの使い方</h4>
-
- <p><code>SimpleSSLSocketServer</code>では、<code>SimpleSocketServer</code>と同様にコマンドライン引数で<em>port</em>と<em>configFile</em>を指定します。それに加えて、ロギングサーバのX.509証明書ファイルの場所とパスワードをシステムパラメータで指定しなければなりません。
- </p>
-
- <p><em>logback-examples</em>ディレクトリに移動してから、次のコマンドを実行すると<code>SimpleSSLSocketServer</code>を開始できます。</p>
-
- <p class="source">java -Djavax.net.ssl.keyStore=src/main/java/chapters/appenders/socket/ssl/keystore.jks \
- -Djavax.net.ssl.keyStorePassword=changeit \
- ch.qos.logback.classic.net.SimpleSSLSocketServer 6000 \
- src/main/java/chapters/appenders/socket/ssl/server.xml
- </p>
-
- <p>この例では、テストや検証で使う用のX.509証明書ファイルを指定して<code>SimpleSSLSocketServer</code>を実行しています。<strong>本番環境で<code>SimpleSSLSocketServer</code>を使う前に、ロギングサーバを識別するための正式なX.509証明書を手に入れなければなりません</strong> 。詳しくは<a href="./usingSSL.html">SSLを使用する</a>を参照してください。
- </p>
-
- <p>サーバの使用する設定ファイルのルート要素に<code>debug="true"</code>を指定しているので、サーバの開始ログを見ればSSLを設定していることがわかるでしょう。これはセキュリティポリシーが正しく設定されていることを確認するのに便利です。
- </p>
-
- <p>実行中の<code>SimpleSSLSocketServer</code>には、<code>SSLSocketAppender</code>を使って接続することができます。アペンダーの設定例は次のとおりです。</p>
-
- <p class="example">例:SSLSocketAppenderの設定(<a href="http://logback.qos.ch/xref/chapters/appenders/socket/ssl/client.xml">logback-examples/src/main/java/chapters/appenders/socket/ssl/client.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('sslclient');">Groovyとして表示</span>
-<pre id="sslclient" class="prettyprint source"><configuration debug="true">
-
- <appender name="SOCKET" class="ch.qos.logback.classic.net.SSLSocketAppender">
- <remoteHost>${host}</remoteHost>
- <port>${port}</port>
- <reconnectionDelay>10000</reconnectionDelay>
- <ssl>
- <trustStore>
- <location>${truststore}</location>
- <password>${password}</password>
- </trustStore>
- </ssl>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SOCKET" />
- </root>
-
-</configuration></pre>
-
- <p>前の例と同じく、<span class="prop">remoteHost</span>と<span class="prop">port</span>の値は変数になっています。また、<span class="prop">ssl</span>プロパティとネストしている<span class="prop">trustStore</span>プロパティが増えているので注意してください。locationとpasswordも変数になっています。例として用意したサーバが自己署名証明書を使っているので、これらの設定は必須です。<code>SSLSocketAppender</code>のSSL設定について、詳しくは<a href="./usingSSL.html">SSLを使用する</a>を参照してください。
- </p>
-
- <p>コマンドラインから、設定ファイルで使用している変数をシステムプロパティとして指定すれば、クライアントアプリケーションを実行することができます。</p>
-
- <p class="source">java -Dhost=localhost -Dport=6000 \
- -Dtruststore=file:src/main/java/chapters/appenders/socket/ssl/truststore.jks \
- -Dpassword=changeit \
- chapters.appenders.socket.SocketClient2 src/main/java/chapters/appenders/socket/ssl/client.xml
- </p>
-
- <p>前の例と同じく、クライアントアプリケーションのコンソールにメッセージを入力することができます。そうすると、メッセージは(安全な通信路上で)ロギングサーバに送信されます。そして、サーバ側のコンソールにログが出力されます。
- </p>
-
- <p>コマンドラインで指定した<em>truststore</em>プロパティには、信頼できるキーストアのURLを指定することに注意しましょう。<a href="./usingSSL.html">SSLを使用する</a>でも説明していますが、URLでクラスパス上のリソースを指定することもできます。</p>
-
- <p>前の例でサーバの起動時にいろいろと出力されているのと同じように、クライアントの設定ファイルのルート要素に<code>debug="true"</code>と指定しているので、クライアントの起動時にもSSL設定に関する情報が出力されています。ローカルポリシーの適合性の監査に役立つでしょう。
- </p>
-
-
- <h3 class="doAnchor" name="serverSocketAppender">ServerSocketAppenderとSSLServerSocketAppender</h3>
-
- <p>前に説明した<code>SocketAppender</code>コンポーネントとSSL対応版のSSLSocketAppenderは、ネットワークの向こう側のサーバにロギングイベントを配信するためのものです。アプリケーションがリモートロギングサーバに接続するために設計されています。場合によりますが、アプリケーションから特定のリモートロギングサーバへの接続を確立するのが不便だったり不可能だったりすることがあります。そういう場合のためにlogbackでは<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/server/ServerSocketAppender">ServerSocketAppender</a></code>が用意されています。
- </p>
-
- <p><code>ServerSocketAppender</code>は、特定のリモートロギングサーバとの接続を確立する代わりに、リモートクライアントからのTCPソケット接続を待ち受けます。アペンダーに送信されたロギングイベントは、接続しているクライアントに配布されます。接続しているクライアントがいなければ、ロギングイベントは<em>すぐに破棄されます</em>。
- </p>
-
- <p>logback は、普通の<code>ServerSocketAppender</code>だけでなく、SSL対応版の<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/server/SSLServerSocketAppender"><code>SSLServerSocketAppender</code></a>も用意しています。安全な、暗号化された通信路で接続したクライアントにロギングイベントを配布します。さらに、SSL対応版のアペンダーは、完全な相互認証をサポートしています。つまり、認証されたクライアントだけがロギングイベントを受信するためにアペンダーに接続できることが保証されるのです。
- </p>
-
- <p>通信路上でのロギングイベントの符号化方法は使用している<code>SocketAppender</code>に関わらず同一です。ロギングイベントは<code>ILoggingEvent</code>のインスタンスがシリアライズされたものです。接続を確立する方向だけが逆転しています。<code>SocketAppender</code>が特定のロギングサーバに対して接続を確立しようとする活性ピアとして振る舞うのに対して、<code>ServerSocketAppender</code>は受動的にクライアントからの接続を待ち受けます。</p>
-
- <p><code>ServerSocketAppender</code>の派生タイプは、logbackの他の<em>レシーバーコンポーネント</em>とは排他的に利用されることを想定しています。コンポーネントタイプに関する詳細については<a href="./receivers.html">レシーバー</a>を参照してください。</p>
-
- <p><code>ServerSocketAppender</code>の設定可能なプロパティを表にまとめました。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="serverSocketAppender">address</span></td>
- <td><code>String</code></td>
- <td>アペンダーが待ち受けるためのローカルネットワークインターフェイスに割り当てられたIPアドレス。このプロパティが指定されていない場合、アペンダーはすべてのネットワークインターフェイスで待ち受けます。</td>
- </tr>
- <tr>
- <td><span class="prop" container="serverSocketAppender">includeCallerData</span></td>
- <td><code>boolean</code></td>
- <td>
- <p>trueの場合、リモートホスト側で送信者情報が利用できるようになります。デフォルトでは、送信者情報はクライアントに送信されません。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="serverSocketAppender">port</span></td>
- <td><code>int</code></td>
- <td>
- <p>アペンダーが待ち受けるポート番号。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="serverSocketAppender">ssl</span></td>
- <td><code>SSLConfiguration</code></td>
- <td><code>SSLServerSocketAppender</code>でのみ使用出来るプロパティ。<a href="./usingSSL.html">SSLを使用する</a>で説明したように、アペンダーの使用するSSLの設定を指定します。</td>
- </tr>
- </table>
-
- <p><code>ServerSocketAppender</code>の使用例を次に示します。</p>
-
- <p class="example">例:ServerSocketAppenderの基本的な設定(<a href="http://logback.qos.ch/xref/chapters/appenders/socket/server4.xml">logback-examples/src/main/java/chapters/appenders/socket/server4.xml</a>)</p>
-<pre id="SocketReceiver" class="prettyprint source"><configuration debug="true">
- <appender name="SERVER"
- class="ch.qos.logback.classic.net.server.ServerSocketAppender">
- <port>${port}</port>
- <includeCallerData>${includeCallerData}</includeCallerData>
- </appender>
-
- <root level="debug">
- <appender-ref ref="SERVER" />
- </root>
-
-</configuration>
-</pre>
- <p>前の例との違いは、<em>class属性</em>に指定しているのが<code>SocketAppender</code>ではないこと、<span class="prop">remoteHost</span>プロパティが無いことだけなのがわかりましたか。このアペンダーはリモートロギングサーバに接続するのではなく、リモートホストからの接続を受動的に待ち受けます。
- </p>
-
- <p><code>SSLServerSocketAppender</code>の設定例は次のとおりです。</p>
-
- <p class="example">例:SSLServerSocketAppenderの基本的な設定(<a href="http://logback.qos.ch/xref/chapters/appenders/socket/server3.xml">logback-examples/src/main/java/chapters/appenders/socket/server3.xml</a>)</p>
-<pre id="SocketReceiver" class="prettyprint source"><configuration debug="true">
- <appender name="SERVER"
- class="ch.qos.logback.classic.net.server.SSLServerSocketAppender">
- <port>${port}</port>
- <includeCallerData>${includeCallerData}</includeCallerData>
- <ssl>
- <keyStore>
- <location>${keystore}</location>
- <password>${password}</password>
- </keyStore>
- </ssl>
- </appender>
-
- <root level="debug">
- <appender-ref ref="SERVER" />
- </root>
-
-</configuration>
-</pre>
-
- <p>前の例との主な違いは、<em>class属性</em>に<code>SSLServerSocketAppender</code>を指定していることと、ネストしている<span class="prop">ssl要素</span>があることです。この例ではアペンダー用のX.509証明書が置かれたキーストアが指定されています。SSLの設定について詳細は<a href="./usingSSL.html">SSLを使用する</a>を参照してください。
- </p>
-
- <p></p>
-
- <h3 class="doAnchor">SMTPAppender</h3>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/SMTPAppender.html"><code>SMTPAppender</code></a>は、一つ以上の固定サイズのバッファにロギングイベントを蓄積し、利用者が指定したイベントが発生したら適切なバッファを選んで内容をメールで送信します。SMTPによるメール送信は非同期で実行されます。デフォルトでは、ERRORレベルのロギングイベントがトリガとなってメールが送信されます。また、1つのバッファがすべてのロギングイベントから使用されます。
- </p>
-
- <p><code>SMTPAppender</code>の設定可能なプロパティを表にまとめました。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">smtpHost</span></td>
- <td><code>String</code></td>
- <td>SMTPサーバのホスト名。これは必須パラメータです。</td>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">smtpPort</span></td>
- <td><code>int</code></td>
- <td>SMTPサーバーの待ち受けポート番号。デフォルトでは25です。</td>
- </tr>
-
- <tr>
- <td><span class="prop" name="smtpTo">to</span></td>
- <td><code>String</code></td>
- <td>recipient のメールアドレスの<em>パターン</em>を指定します。指定したパターンは、送信されるメールそれぞれに対して、トリガとなったロギングイベントと共に評価されます。複数のrecipientを指定するときは、宛先アドレスをカンマ区切りにします。また、<code>to要素</code>を複数並べることもできます。
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">from</span></td>
- <td><code>String</code></td>
- <td><code>SMTPAppender</code>の送信するメールメッセージの originator を<a href="http://en.wikipedia.org/wiki/Email_address">一般的なメールアドレス形式</a>で指定します。送信者名を含めたい場合は "Adam Smith <smith at moral.org>" のようにします(XML形式の設定ファイルではブラケットを文字実態参照にします)。そうすると、メールでは "Adam Smith <smith at moral.org>" のようになります。
- </td>
- </tr>
- <tr>
- <td><span class="prop">subject</span></td>
- <td><code>String</code></td>
- <td>
- <p>メールの件名。<a href="./layouts.html#ClassicPatternLayout">PatternLayout</a>で利用できる全ての値を指定できます。レイアウトについては次の章で説明します。
- </p>
-
- <p>送信されるメールメッセージの件名には、メール送信をトリガしたロギングイベントを適用したパターンが指定されます。
- </p>
-
- <p><span class="prop">subject</span>オプションに指定されたパターンが "Log: %logger - %msg" で、"com.foo.Bar"ロガーが "Hello World" というメッセージのロギングイベントを発生して、このロギングイベントがトリガとなった場合、送信されるメールの件名は "Log: com.foo.Bar - Hello World" になるでしょう。
- </p>
-
- <p>デフォルトでは、"%logger{20} - %m" が設定されています。</p>
- </td>
-
- </tr>
- <tr>
- <td><span class="prop" container="smtp">discriminator</span></td>
- <td><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/sift/Discriminator.html">Discriminator</a></code></td>
- <td>
- <p><code>SMTPAppender</code>は、<span class="prop">弁別器</span>の返す値に基づいてバッファを選択して、発生したロギングイベントを振り分けます。デフォルトの弁別器は常に同じ値を返すので、全てのロギングイベントが常に同じバッファに振り分けられます。
- </p>
-
- <p>デフォルト以外の弁別器を指定すれば、特定のユーザー、ユーザーセッション、クライアントのIPアドレスに関連するロギングイベントを含むメールだけを送信することもできます。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" name="smtpAppender_Evaluator">evaluator</span></td>
- <td><code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/IEvaluator.html">IEvaluator</a></code></td>
- <td>
- <p>このオプションを指定するには、新しく<code>EventEvaluator要素</code>を宣言します。<code>SMTPAppender</code>の<code>Evaluator</code>として使いたいクラスの完全クラス名を、<span class="attr">class属性</span>に指定します。
- </p>
-
-
- <p>このオプションを指定しなかった場合、<code>SMTPAppender</code>は<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/OnErrorEvaluator.html">OnErrorEvaluator</a>のインスタンスを使用します。これは<em>ERROR</em>以上のロギングイベントが発生したらメール送信をトリガします。
- </p>
-
- <!--
- <p><code>EventEvaluator</code> objects are subclasses of the
- <code>JaninoEventEvaluatorBase</code> which depends on
- Janino. See the <a href="../dependencies.html">dependencies
- page</a> for more information.
- </p>
- -->
-
- <p>logback の配布物には他の評価器もいくつか含まれています。<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/OnMarkerEvaluator.html"><code>OnMarkerEvaluator</code></a>(詳しくは後述します)と、より強力な評価器の<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/JaninoEventEvaluator.html"><code>JaninoEventEvaluator</code></a>です。後者については<a href="./filters.html#evalutatorFilter">別の章</a>で紹介します。最新バージョンの配布物にはさらに強力な評価器である<a href="./filters.html#GEventEvaluator"><code>GEventEvaluator</code></a>が含まれます。
- </p>
-
- </td>
- </tr>
-
- <tr>
- <td valign="top"><span class="prop" container="smtp">cyclicBufferTracker</span></td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/CyclicBufferTracker.html"><code>CyclicBufferTracker</code></a>
- </td>
- <td>
- <p>名前が示す通り、<code>CyclicBufferTracker</code>クラスは循環バッファを追跡します。追跡は、前に説明した<span class="prop">弁別器</span>の返すキーに基づいて行われます。
- </p>
- <p><span class="prop">cyclicBufferTracker</span>指定しなかった場合、自動的に<a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/CyclicBufferTrackerImpl.html">CyclicBufferTrackerImpl</a>のインスタンスを生成して使用します。デフォルトで256個のロギングイベントを循環バッファに保持します。<span class="prop">bufferSize</span>オプションを指定してサイズを変更することもできます(下記参照)。</p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="smtp">username</span></td>
- <td><code>String</code></td> <td>平文のパスワード認証をするときに使用するユーザー名。デフォルトではnullです。</td>
- </tr>
- <tr class="alt">
- <td><span class="prop" container="smtp">password</span></td>
- <td><code>String</code></td>
- <td>平文のパスワード認証をするときに使用するパスワード。デフォルトではnullです。
-
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="smtp">STARTTLS</span> </td>
- <td><code>boolean</code></td>
- <td>trueを指定すると、サーバがサポートしているならSSL接続に切り替えるため、STARTTLSコマンドを発行します。接続が確立した時点では暗号化されていないので注意してください。デフォルトではfalseに設定されています。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="smtp">SSL</span></td>
- <td><code>boolean</code></td> <td>trueを指定するとサーバにSSL接続をします。デフォルトではfalseです。</td>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">charsetEncoding</span></td>
- <td><code>String</code></td>
- <td>送信されるメッセージは指定された<a href="https://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html">文字セット</a>でエンコードされます。デフォルトの文字セットは"UTF-8"ですが、ほとんどの場合十分でしょう。
- </td>
- </tr>
-
-
- <tr>
- <td><span class="prop" container="smtp">localhost</span></td>
- <td><code>String</code></td>
- <td>SMTPクライアントのホスト名が正しく設定されていない場合(例えば、ホスト名が完全修飾名ではない場合)、SMTPサーバの中にはそういうクライアントから送信された HELO/EHLO コマンドを拒否することがあります。この問題を解決するには、クライアントのホスト名として、<span class="prop">localhost</span>に完全修飾名を指定することができます。<a href="http://javamail.kenai.com/nonav/javadocs/com/sun/mail/smtp/package-summary.html">com.sun.mail.smtp</a>パッケージのドキュメントで説明されている "mail.smtp.localhost" パラメータも参考にしてください。</td>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">asynchronousSending</span></td>
- <td><code>boolean</code></td>
- <td>メール送信を非同期で行うかどうかを指定します。デフォルトはtrueです。しかし、非同期送信が不適切な場合もあります。たとえば、あなたのアプリケーションで致命的なエラーが発生した際、<code>SMTPAppender</code>でアラートメールを送信してから終了するとしても、その仕事を任されたスレッドにはメールを送信する時間が残されていないからです。そういう場合は同期的にメール送信をするためfalseを指定しましょう。
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">includeCallerData</span></td>
- <td><code>boolean</code></td>
- <td>デフォルトは<code>false</code>です。<span class="prop">asynchronousSending</span>が有効でログに送信者情報を含めたいときは<code>true</code>を指定しなければなりません。</td>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">sessionViaJNDI</span></td>
- <td><code>boolean</code></td>
- <td><code>javax.mail.Session</code>を使用してメールを送信します。デフォルトは<code>false</code>なので、<code>SMTPAppender</code>は利用者の指定した設定に従って<code>javax.mail.Session</code>インスタンスを構築します。<code>true</code>を指定するとJNDIから<code>javax.mail.Session</code>インスタンスを取得します。<span class="prop">jndiLocation</span>プロパティも参照してください。
-
- <p><span class="label">注意</span>JNDIから<code>Session</code>を取得すれば、設定する場所は減るし、同じ情報をあちこちで指定しなくてもよくなります。そうすると、アプリケーションはより<a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>になります。TomcatでJNDIリソースを設定する方法については<a href="http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html#JavaMail_Sessions">JNDIリソースハウツー</a>を参照してください。JNDIから<code>Session</code>オブジェクトを取得する場合は、ドキュメントに記載されているように、<em>mail.jar</em>と<em>activation.jar</em>をWebアプリケーションの<em>WEB-INF/lib</em>フォルダから取り除 [...]
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">jndiLocation</span></td>
- <td><code>String</code></td>
- <td>JNDIのjavax.mail.Sessionの位置を指定します。デフォルトは<span style="white-space:nowrap">"java:comp/env/mail/Session"</span>です。
- </td>
- </tr>
-
- </table>
-
- <p><code>SMTPAppender</code>は循環バッファで最新の256個のロギングイベントだけを保持します。バッファが一杯になったら古いロギングイベントを捨てます。したがって、<code>SMTPAppender</code>からメールで送信するロギングイベントの最大値は256個になります。つまり、アプリケーションコンテキストに妥当なメモリ量を割り当てられるよう、メモリ要件に合わせて制限できるということです。
- </p>
-
- <p><code>SMTPAppender</code>はJavaMail APIにも依存しています。テストされているJavaMail APIのバージョンは1.4です。JavaMail APIにはJavaBeans Activation フレームワークが必要です。<a href="http://java.sun.com/products/javamail/">JavaMail API</a>と<a href="http://java.sun.com/beans/glasgow/jaf.html">JavaBeans Activation フレームワーク</a>はそれぞれのウェブサイトからダウンロードすることができます。以降の例を試す前に、クラスパス上にこれらのjarファイルが配置されていることを確かめてください。
- </p>
-
- <p>サンプルアプリケーションでは、<a href="http://logback.qos.ch/xref/chapters/appenders/mail/EMail.html"><code>chapters.appenders.mail.EMail</code></a>がいくつかのログメッセージを生成したあとで、エラーメッセージを1つ生成しています。このアプリケーションの引数は二つあります。一つ目のパラメータは生成するロギングイベントの数となる整数値です。二つ目のパラメータはlogbackの設定ファイルです。<em>EMail</em>アプリケーションが最後に生成するロギングイベントのログレベルはERRORなので、メール送信をトリガします。
- </p>
-
- <p><code>Email</code>アプリケーションから使う設定ファイルは次のとおりです。</p>
-
- <p class="example">例:<code>SMTPAppender</code>の設定例(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/mail1.xml">logback-examples/src/main/java/chapters/appenders/mail/mail1.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('mail1');">Groovyとして表示</span>
- <pre id="mail1" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <smtpHost>ADDRESS-OF-YOUR-SMTP-HOST</smtpHost>
- <to>EMAIL-DESTINATION</to>
- <to>ANOTHER_EMAIL_DESTINATION</to> <!-- additional destinations are possible -->
- <from>SENDER-EMAIL</from>
- <subject>TESTING: %logger{20} - %m</subject>
- <layout class="ch.qos.logback.classic.PatternLayout">
- <pattern>%date %-5level %logger{35} - %message%n</pattern>
- </layout>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="EMAIL" />
- </root>
-</configuration></pre>
-
- <p>上記の設定ファイルで<code>chapters.appenders.mail.Email</code>アプリケーションを動かしてみる前に、smtpHostや<span class="prop">to</span>や<span class="prop">from</span>へ、あなたの環境に適した値を指定しなければなりません。設定ファイルに正しい値を指定したら次のコマンドを実行しましょう。</p>
-
-<div class="source"><pre>java chapters.appenders.mail.EMail 100 src/main/java/chapters/appenders/mail/mail1.xml</pre></div>
-
- <p>指定したrecipientには<code>PatternLayout</code>で指定したとおりに書式化された100個のロギングイベントが含まれたメールが届くはずです。Mozilla Thunderbird で受信したメールを開いたところを示します。
- </p>
-
- <p><img src="images/chapters/appenders/smtpAppender1.jpg" alt="結果の電子メール"></p>
-
- <p>設定ファイル<em>mail2.xml</em>では、<span class="prop">smtpHost</span>や<span class="prop">to</span>や<span class="prop">from</span>が変数で指定されています。<em>mail2.xml</em>の大事な部分を次に示します。
- </p>
-
- <pre class="prettyprint source"><appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <smtpHost>${smtpHost}</smtpHost>
- <to>${to}</to>
- <from>${from}</from>
- <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
-</appender></pre>
-
- <p>コマンドラインで必要なパラメータを指定します。</p>
-
-<div class="source"><pre>java -Dfrom=source at xyz.com -Dto=recipient at xyz.com -DsmtpHost=some_smtp_host \
- chapters.appenders.mail.EMail 10000 src/main/java/chapters/appenders/mail/mail2.xml
-</pre></div>
-
- <p>値はあなたの環境で利用できるものに置き換えてください。
- </p>
-
- <p>最後の例では、<code>PatternLayout</code>が<code>HTMLLayout</code>になっていました。これはログの内容をHTMLのテーブルとして書式化します。列の並びと順番は変更することができます。CSSも変更できます。<a href="./layouts.html#ClassicHTMLLayout">HTMLLayout</a>について詳しくはドキュメントを参照してください。
- </p>
-
- <p>循環バッファのサイズが256なので、recipientが受け取るメールでは256個のロギングイベントが綺麗にHTMLのテーブルに整形されるようになっています。<code>chapters.appenders.mail.Email</code>アプリケーションを実行して10000件のロギングイベントを生成しても、送信されるメールには最新の256件しか含まれないことになるので気をつけてください。
- </p>
-
- <p><img src="images/chapters/appenders/smtpAppender2.jpg" alt="第2回のメール"></p>
-
- <p>Mozilla ThunderbirdやEudoraやMS Outlookといったメールクライアントは、HTML形式のメールでもCSSをわりと上手く処理します。ですが、勝手にHTMLを平文テキストにダウングレードすることがあります。例えば、Thunderbird でHTMLメールを表示するには、"表示→メッセージ本文→オリジナルのHTML" でオプションを指定しなければなりません。Yahoo!メールはHTMLメールをサポートしており、CSSの対応具合はピカ一です。一方、Gmailは普通のHTMLテーブルはそのまま表示してくれますが、内部CSSによる整形はしてくれません。GmailはインラインCSSをサポートしていますが、インラインCSSを使うとHTMLソースコードが膨れ上がってしまうので、<code>HTMLLayout</code>ではインラインCSSを使用しません。</p>
-
- <h3 class="doAnchor" name="cyclicBufferSize">カスタムバッファサイズ</h3>
-
- <p>デフォルトでは、<code>SMTPAppender</code>から送信されるメッセージには最大で256件のロギングメッセージが含まれています。次の例に示すように、別のバッファサイズを指定することができます。
- </p>
-
- <p class="example">例: バッファサイズを変更した<code>SMTPAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/customBufferSize.xml">logback-examples/src/main/java/chapters/appender/mail/customBufferSize.xml</a>)</p>
- <pre class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <smtpHost>${smtpHost}</smtpHost>
- <to>${to}</to>
- <from>${from}</from>
- <subject>%logger{20} - %m</subject>
- <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
-
- <b><cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker"></b>
- <b><!-- send just one log entry per email --></b>
- <b><bufferSize>1</bufferSize></b>
- <b></cyclicBufferTracker></b>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="EMAIL" />
- </root>
-</configuration> </pre>
-
-
- <h3 class="doAnchor">トリガイベント</h3>
-
- <p>Evaluatorプロパティが指定されなかったら、<code>SMTPAppender</code>はデフォルトで<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/OnErrorEvaluator.html">OnErrorEvaluator</a>を使用して、ERRORレベルのロギングイベントの発生をトリガとしてメールを送信する。エラーの発生に応じて、メール送信をトリガするのはそれなりに合理的ですが、<code>EventEvaluator</code>インターフェイスの別の実装を指定すればデフォルトの振る舞いを上書きすることができます。
- </p>
-
- <p><code>SMTPAppender</code>は<code>evaluate()</code>メソッドを呼び出すことで、受け取ったロギングイベントを評価器に渡します。そのロギングイベントがメール送信をトリガするものなのか、単に循環バッファに入れておくだけでいいのかを判定するためです。評価器が評価した結果が真なら、メールを送信します。<code>SMTPAppender</code>の保持する評価器オブジェクトは1つだけです。このオブジェクトは、自身の内部状態を管理することができます。わかりにくいので、<code>CounterBasedEvaluator</code>クラスのコードで説明します。これはロギングイベントが1024件発生するたびにメール送信をトリガします。
- </p>
-
- <p class="example">例: 1024件ごとに評価値<code>true</code>を返す<code>EventEvaluator</code>インターフェイスの実装(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/CounterBasedEvaluator.java">logback-examples/src/main/java/chapters/appenders/mail/CounterBasedEvaluator.java</a>)</p>
-
- <pre class="prettyprint source">package chapters.appenders.mail;
-
-import ch.qos.logback.core.boolex.EvaluationException;
-import ch.qos.logback.core.boolex.EventEvaluator;
-import ch.qos.logback.core.spi.ContextAwareBase;
-
-public class CounterBasedEvaluator extends ContextAwareBase implements EventEvaluator {
-
- static int LIMIT = 1024;
- int counter = 0;
- String name;
-
- <b>public boolean evaluate(Object event) throws NullPointerException,
- EvaluationException {
- counter++;
-
- if (counter == LIMIT) {
- counter = 0;
-
- return true;
- } else {
- return false;
- }
- }</b>
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-}</pre>
-
- <p>このクラスは<code>ContextAwareBase</code>を継承して、<code>EventEvaluator</code>インターフェイスを実装しているのがわかるでしょうか。こうすれば、利用者は<code>EventEvaluator</code>としての中心機能に集中することができるし、基底クラスを使って共通する機能を提供できるようになります。
- </p>
-
- <p><code>SMTPAppender</code>の<span class="prop">evaluator</span>オプションを指定するということは、カスタム評価器を使うということです。次の設定ファイルではルートロガーに<code>SMTPAppender</code>を割り当てています。SMTPAppenderでは、<code>CounterBasedEvaluator</code>を評価器として指定しています。
- </p>
-
- <p class="example">例: <code>SMTPAppender</code>とカスタム<code>評価器</code>とバッファサイズの設定例(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/mail3.xml">logback-examples/src/main/java/chapters/appenders/mail/mail3.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('mail3');">Groovyとして表示</span>
- <pre id="mail3" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <b><evaluator class="chapters.appenders.mail.CounterBasedEvaluator" /></b>
- <smtpHost>${smtpHost}</smtpHost>
- <to>${to}</to>
- <from>${from}</from>
- <subject>%logger{20} - %m</subject>
-
- <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="EMAIL" />
- </root>
-</configuration></pre>
-
-
- <h3 class="doAnchor" name="OnMarkerEvaluator">マーカーに基づくトリガ</h3>
-
- <p>全てのERRORレベルのロギングイベントをトリガとしてメールを送信するデフォルトのポリシーは合理的ではありますが、メールを送信する機会が多すぎると対象になっているユーザのメールボックスを埋め尽くしてしまいます。logback の配布物には<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/OnMarkerEvaluator.html">OnMarkerEvaluator</a>というトリガポリシーも含まれています。これはマーカーに基づいてトリガするものです。原則として、利用者が指定したマーカーのロギングイベントが発生したときだけメール送信がトリガされます。次の例を見ればどういう動き方をするのかはっきりするでしょう。
- </p>
-
- <p><a href="http://logback.qos.ch/xref/chapters/appenders/mail/Marked_EMail.html">Marked_EMailの</a>アプリケーションには、ERRORレベルを含むいくつものロギング式があります。そのうちで、一つのロギング式にだけマーカーが指定されています。該当するコードは次のとおりです。
- </p>
-
- <pre class="prettyprint source">Marker notifyAdmin = MarkerFactory.getMarker("NOTIFY_ADMIN");
-logger.error(<b>notifyAdmin</b>,
- "This is a serious an error requiring the admin's attention",
- new Exception("Just testing"));</pre>
-
- <p>次の設定ファイルは、マーカーとしてNOTIFY_ADMINあるいはTRANSACTION_FAILUREを指定されたロギングイベントが発生したときだけメール送信をトリガするものです。
- </p>
-
- <p class="example">例: <code>OnMarkerEvaluator</code>を指定した<code>SMTPAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/mailWithMarker.xml">logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('mailWithMarker');">Groovyとして表示</span>
- <pre id="mailWithMarker" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <b><evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
- <marker>NOTIFY_ADMIN</marker>
- <!-- you specify add as many markers as you want -->
- <marker>TRANSACTION_FAILURE</marker>
- </evaluator></b>
- <smtpHost>${smtpHost}</smtpHost>
- <to>${to}</to>
- <from>${from}</from>
- <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
- </appender>
-
- <root>
- <level value ="debug"/>
- <appender-ref ref="EMAIL" />
- </root>
-</configuration></pre>
-
- <p>次のコマンドを実行してみましょう。</p>
-
- <pre class="source">java -Dfrom=source at xyz.com -Dto=recipient at xyz.com -DsmtpHost=some_smtp_host \
- chapters.appenders.mail.Marked_EMail src/main/java/chapters/appenders/mail/mailWithMarker.xml</pre>
-
-
- <h4 class="doAnchor" name="marker_JaninoEventEvaluator">JaninoEventEvaluatorを使ったマーカーに基づくトリガ</h4>
-
- <p>マーカーだけを対象にした<code>OnMarkerEvaluator</code>の代わりに、より汎用的な<a href="./filters.html#JaninoEventEvaluator"><code>JaninoEventEvaluator</code></a>を使うことができますし、それ以上に強力な<a href="./filters.html#GEventEvaluator"><code>GEventEvaluator</code></a>を使うことも出来ます。たとえば、次の設定ファイルは<code>OnMarkerEvaluator</code>の代わりに<code>JaninoEventEvaluator</code>を指定した以外は前の設定ファイルとまったく同じ内容になります。
- </p>
-
- <p class="example">例: <code>JaninoEventEvaluator</code>を指定した<code>SMTPAppender</code>の設定(logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker_Janino.xml)</p>
-
- <span class="asGroovy" onclick="return asGroovy('mailWithMarker_Janino');">Groovyとして表示</span>
- <pre id="mailWithMarker_Janino" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
- <expression>
- (marker != null) &&
- (marker.contains("NOTIFY_ADMIN") || marker.contains("TRANSACTION_FAILURE"))
- </expression>
- </evaluator>
- ... same as above
- </appender>
-</configuration></pre>
-
- <h4 class="doAnchor" name="marker_GEventEvaluator">GEventEvaluatorを使ったマーカーに基づくトリガ</h4>
-
- <p><a href="./filters.html#GEventEvaluator">GEventEvaluator</a>を使っている以外は前の例と同じ内容です。</p>
-
- <p class="example">例:<code>GEventEvaluator</code>を指定したSMTPAppenderの設定(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/mailWithMarker_GEvent.xml">logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker_GEvent.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('mailWithMarker_GEventEvaluator');">Groovyとして表示</span>
-
- <pre id="mailWithMarker_GEventEvaluator" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator">
- <expression>
- e.marker?.contains("NOTIFY_ADMIN") || e.marker?.contains("TRANSACTION_FAILURE")
- </expression>
- </evaluator>
- ... same as above
- </appender>
-</configuration></pre>
-
- <p>マーカーを指定されなかったロギングイベントの場合、e.markerはnullになるので注意してください。この例ではGroovyの<a href="http://groovy.codehaus.org/Null+Object+Pattern">安全なデリファレンス演算子</a>である .? 演算子を使っています。
- </p>
-
-
- <h3 class="doAnchor" name="smtpAuthentication">認証/ STARTTLS / SSL</h3>
-
- <p><code>SMTPAppender</code>では、平文のユーザーパスワード認証だけでなく、STARTTLSとSSLプロトコルの両方をサポートしています。STARTTLSとSSLの違いは、STARTTLSでは接続を確立するときは暗号化されないこと、そして、クライアントがSTARTTLSコマンドを発行してサーバがサポートしている場合はSSL接続に切り替えることです。SSLでは始めから通信が暗号化されます。
- </p>
-
- <h3>GmailにSSLで接続するSMTPAppenderの設定</h3>
-
- <p>次の例はGmailにSSLプロトコルで接続する<code>SMTPAppender</code>の設定です。</p>
-
- <p class="example">例:GmailにSSLで接続する<code>SMTPAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/gmaliSSL.xml">logback-examples/src/main/java/chapters/appenders/mail/gmaliSSL.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('gmailSSLExample');">Groovyとして表示</span>
- <pre id="gmailSSLExample" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <b><smtpHost>smtp.gmail.com</smtpHost></b>
- <b><smtpPort>465</smtpPort></b>
- <b><SSL>true</SSL></b>
- <b><username>YOUR_USERNAME at gmail.com</username></b>
- <b><password>YOUR_GMAIL_PASSWORD</password></b>
-
- <to>EMAIL-DESTINATION</to>
- <to>ANOTHER_EMAIL_DESTINATION</to> <!-- additional destinations are possible -->
- <from>YOUR_USERNAME at gmail.com</from>
- <subject>TESTING: %logger{20} - %m</subject>
- <layout class="ch.qos.logback.classic.PatternLayout">
- <pattern>%date %-5level %logger{35} - %message%n</pattern>
- </layout>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="EMAIL" />
- </root>
-</configuration></pre>
-
-
- <h3 class="doAnchor" name="gmailSTARTTLS">STARTTLSでGmailに接続するSMTPAppenderの設定</h3>
-
- <p>次の例はGmailにSTARTTLSで接続する<code>SMTPAppender</code>の設定です。
-</p>
-
- <p class="example">例:GmailにSTARTTLSで接続する<code>SMTPAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/gmailSTARTTLS.xml">logback-examples/src/main/java/chapters/appenders/mail/gmailSTARTTLS.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('gmailSTARTTLSExample');">Groovyとして表示</span>
- <pre id="gmailSTARTTLSExample" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <smtpHost>smtp.gmail.com</smtpHost>
- <smtpPort>587</smtpPort>
- <STARTTLS>true</STARTTLS>
- <username>YOUR_USERNAME at gmail.com</username>
- <password>YOUR_GMAIL_xPASSWORD</password>
-
- <to>EMAIL-DESTINATION</to>
- <to>ANOTHER_EMAIL_DESTINATION</to> <!-- additional destinations are possible -->
- <from>YOUR_USERNAME at gmail.com</from>
- <subject>TESTING: %logger{20} - %m</subject>
- <layout class="ch.qos.logback.classic.PatternLayout">
- <pattern>%date %-5level %logger - %message%n</pattern>
- </layout>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="EMAIL" />
- </root>
-</configuration></pre>
-
-
- <h3 class="doAnchor" name="smtpDiscriminator">MDCDiscriminatorを指定したSMTPAppenderの設定</h3>
-
-
- <p>前述したように、<code>SMTPAppender</code>にデフォルト以外の弁別器を指定すれば、特定のユーザ、ユーザセッション、送信元のIPアドレスを含むロギングイベントが発生した場合にだけメールメッセージを生成することができます。
- </p>
-
- <p>次の例は<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/sift/MDCBasedDiscriminator.html">MDCBasedDiscriminator</a>に"req.remoteHost"というキーを指定したものです。値として、架空のWebアプリケーションにアクセスしてきたクライアントのリモートホストのIPアドレスが設定されることを想定しています。Webアプリケーションなら<a href="./mdc.html#mis">MDCInsertingServletFilter</a>使ってMDCに値を設定することができます。
- </p>
-
- <p class="example">例:MDCDiscriminatorを指定した<code>SMTPAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/mailWithMDCBasedDiscriminator.xml">logback-examples/src/main/java/chapters/appenders/mail/mailWithMDCBasedDiscriminator.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('mailWithMDCBasedDiscriminator');">Groovyとして表示</span>
- <pre id="mailWithMDCBasedDiscriminator" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <smtpHost>ADDRESS-OF-YOUR-SMTP-HOST</smtpHost>
- <to>EMAIL-DESTINATION</to>
- <from>SENDER-EMAIL</from>
-
- <b><discriminator class="ch.qos.logback.classic.sift.MDCBasedDiscriminator"></b>
- <b><key>req.remoteHost</key></b>
- <b><defaultValue>default</defaultValue></b>
- <b></discriminator></b>
-
- <subject>${HOSTNAME} -- %X{req.remoteHost} %msg"</subject>
- <layout class="ch.qos.logback.classic.html.HTMLLayout">
- <pattern>%date%level%thread%X{req.remoteHost}%X{req.requestURL}%logger%msg</pattern>
- </layout>
- </appender>
-
- <root>
- <level level="DEBUG"/>
- <appender-ref ref="EMAIL" />
- </root>
-</configuration></pre>
-
- <p>こうすると、<code>SMTPAppender</code>の送信するメールそれぞれに<em>固有</em>のIPアドレスが記録されるようになるので、問題解決に役立ちます。
- </p>
-
- <h4 class="doAnchor" name="bufferManagement">高負荷システムにおけるバッファ管理(★要見直し)</h4>
-
- <p>内部的な事情ですが、弁別器が返す値ごとに循環バッファが作成されます。しかし、ほとんどの場合<span class="prop">maxNumberOfBuffers</span>(デフォルト値は64)はそのままです。バッファの数が<span class="prop">maxNumberOfBufferes</span>を越えてしまうと、一番最近更新されたバッファはすぐに自動的に破棄されてしまいます。もう一つの予防策として、直近の30分間に更新されなかったバッファはやはり自動的に破棄されてしまいます。</p>
-
- <p>毎分大量のトランザクションを処理するシステムでは、<span class="prop">maxNumberOfBuffers</span>(デフォルト値は64)が小さいと送信するメールに含まれるロギングイベントの数がとても少なくなってしまいます。大量のトランザクションが発生する場合、同じトランザクションには1つ以上のバッファが関連付けられてしまいます。弁別器が同じトランザクションには同じ値を返すので、バッファの破棄と生成が繰り返されてしまうからです。高負荷システムであっても、循環バッファの上限は<span class="prop">maxNumberOfBufferes</span>によって制御されてしまうので注意してください。
- </p>
-
- <p>ヨーヨー効果を避けるため、<code>SMTPAppender</code>は"FINALIZE_SESSION"というマーカーの指定されたロギングイベントを見つけたら、そのロギングイベントに対して弁別器の返す値に関連付けられたバッファを直ちに開放するようになっています。これにより、トランザクションの終了時に適切にバッファを廃棄できるようになります。そうすれば、<span class="prop">maxNumberOfBuffers</span>には、安全のためより大きな値の512や1024を指定することができます。メモリ不足の危険性はありません。
- </p>
-
- <p>循環バッファを管理するために協調的に機能する、3つの相補的な仕組みがあります。これらの仕組みが、高負荷システムであっても常に有効なバッファが利用できることを保証するのです。</p>
-
- <!-- =========================================================== -->
- <!-- =========================================================== -->
-
-
- <h3 class="doAnchor" name="DBAppender">DBAppender</h3>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/db/DBAppender.html"><code>DBAppender</code></a>はデータベース上の3つのテーブルに、Javaプログラミング言語に依存しない形式のロギングイベントを登録します。
- </p>
-
- <p>3つのテーブルとは、<em>logging_event</em>、<em>logging_event_property</em>、<em>logging_event_exception</em>です。<code>DBAppender</code>を使う前に事前に用意しておかなければなりません。logack の配布物にテーブルを作成するSQLスクリプトが含まれています。フォルダの場所は <em>logback-classic/src/main/java/ch/qos/logback/classic/db/script</em>です。一般的なデータベースそれぞれのスクリプトが用意されています。あなたの使用するデータベース用のスクリプトが無かったとしても、既存のスクリプトを参考にすれば自分で作るのは簡単です。logback の開発メンバーに教えてくれれば、喜んで今後のリリースに含めるようにします。
- </p>
-
- <p>あなたが使用しているJDBCドライバが、JDBC3.0で導入された<code>getGeneratedKeys()</code>メソッドをサポートしているなら、紹介したスクリプトでテーブルを作ること以外に必要な作業はありません。そうはいっても、データベースに対応する<code>SQLDialect</code>を指定しなければなりません。今のところ logback が対応しているSQL方言は、H2、HSQL、MS SQLServer、MySQL、Oracle、PostgreSQL、SQLite、Sybase です。</p>
-
- <p>データベースの種類と、<code>getGeneratedKeys()</code>メソッドの対応状況を表にまとめました。
- </p>
-
- <table class="bodyTable striped" border="0" cellpadding="4">
- <tr>
- <th>データベースの種類</th>
- <th>テストしたバージョン</th>
- <th>テストしたJDBCドライバのバージョン</th>
- <th>{0}getGeneratedKeys(){/0}メソッド
-の対応状況<br>
- </th>
-
- <th>logbackがSQL方言を提供しているかどうか
-<br></th>
- </tr>
-
- <tr>
- <td>DB2</td>
- <td>未テスト</td>
- <td>未テスト</td>
- <td>不明</td>
- <td>無し</td>
- </tr>
-
- <tr>
- <td>H2</td>
- <td>1.2.132</td>
- <td>-</td>
- <td>不明</td>
- <td>提供している</td>
- </tr>
-
- <tr>
- <td>HSQL</td>
- <td>1.8.0.7</td>
- <td>-</td>
- <td>未対応</td>
- <td>提供している</td>
- </tr>
-
- <tr>
- <td>Microsoft SQL Server</td>
- <td>2005</td>
- <td>2.0.1008.2(sqljdbc.jar)</td>
- <td>対応済み</td>
- <td>提供している
-</td>
- </tr>
-
- <tr>
- <td>MySQL</td>
- <td>5.0.22</td>
- <td>5.0.8(mysql-connector.jar)</td>
- <td>対応済み</td>
- <td>提供している
-</td>
- </tr>
-
- <tr>
- <td>PostgreSQL</td>
- <td>8.x</td>
- <td>8.4-701.jdbc4</td>
- <td>未対応</td>
- <td>提供している
-</td>
-
- </tr>
-
- <tr>
- <td>Oracle</td>
- <td>10g</td>
- <td>10.2.0.1(ojdbc14.jar)</td>
- <td>対応済み</td>
- <td>提供している
-</td>
- </tr>
-
- <tr>
- <td>SQLLite</td>
- <td>3.7.4</td>
- <td>-</td>
- <td>不明</td>
- <td>提供している
-</td>
- </tr>
-
-
- <tr>
- <td>Sybase SQLAnywhere</td>
- <td>10.0.1</td>
- <td>-</td>
- <td>不明</td>
- <td>提供している
-</td>
- </tr>
-
- </table>
-
- <p>検証したところ、"標準的"なPCでは1つのロギングイベントをデータベースに書き込むのにおよそ10ミリ秒かかるようです。コネクションプールを使えば1ミリ秒くらいは速くなるでしょう。一般的に利用できるほとんどのJDBCドライバではコネクションプールを使うことができるので、ぜひそうしてください。
- </p>
-
- <p><code>DBAppender</code>の設定方法はいろいろありますが、データベースに接続するツールや、データベース自体によって異なります。<code>DBAppender</code>の設定で重要なのは、<code>ConnectionSource</code>です。どういうものか簡単に説明しましょう。
- </p>
-
- <p><code>DBAppender</code>がデータベースに接続できたら、ロギングイベントは指定されたデータベースに送信されます。前述したとおり、logbackはロギングイベントを3つのテーブルに格納します。
- </p>
-
- <p><em>logging_event</em>テーブルには次のようなカラムがあります。</p>
- <table class="bodyTable striped">
- <tr>
- <th>カラム名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><b>timestamp</b></td>
- <td><code>big int</code></td>
- <td>ロギングイベントが作成された時のタイムスタンプ。</td>
- </tr>
- <tr>
- <td><b>formatted_message</b></td>
- <td><code>text</code></td>
-
- <td><code>org.slf4j.impl.MessageFormatter</code>で書式化されてからロギングイベントに設定されたメッセージ。引数のオブジェクトはメッセージにくっついています。</td>
- </tr>
- <tr>
- <td><b>logger_name</b></td>
- <td><code>varchar</code></td>
- <td>ロギング要求を発行したロガーの名前。</td>
- </tr>
- <tr>
- <td><b>level_string</b></td>
- <td><code>varchar</code></td>
- <td>ロギングイベントのレベル。</td>
- </tr>
- <tr>
- <td><b>reference_flag</b></td>
- <td><code>smallint</code></td>
- <td>
- <p>このフィールドは、ロギングイベントに例外オブジェクトが含まれているか、もしくは、<code>MDC</code>に関連する値が設定されていないかどうかを判定するため、logback が使用します。
- </p>
-
- <p>値は<code>ch.qos.logback.classic.db.DBHelper</code>が算出します。ロギングイベントに<code>MDC</code>あるいは<code>Context</code>プロパティが含まれるバア愛、このフラグ値は<em>1</em>になります。例外オブジェクトが含まれる場合は<em>2</em>になります。両方の要素が含まれている場合は<em>3</em>になります。
- </p>
- </td>
- </tr>
- <tr>
- <td><b>caller_filename</b></td>
- <td><code>varchar</code></td>
- <td>ロギング要求を発行した場所が含まれるファイル名。</td>
- </tr>
- <tr>
- <td><b>caller_class</b></td>
- <td><code>varchar</code></td>
- <td>ロギング要求を発行したクラス名。</td>
- </tr>
- <tr>
- <td><b>caller_method</b></td>
- <td><code>varchar</code></td>
- <td>ロギング要求を発行したメソッド名。</td>
- </tr>
- <tr>
- <td><b>caller_line</b></td>
- <td><code>char</code></td>
- <td>ロギング要求を発行した場所の行番号。</td>
- </tr>
- <tr>
- <td><b>event_id</b></td>
- <td><code>int</code></td>
- <td>データベースが払いだしたロギングイベントのID。</td>
- </tr>
- </table>
-
- <p><em>logging_event_property</em>には、<code>MDC</code>または<code>Context</code>に含まれるキーと値を格納します。次のようなカラムがあります。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>カラム名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><b>event_id</b></td>
- <td><code>int</code></td>
- <td>データベースが払いだしたロギングイベントのID。</td>
- </tr>
- <tr>
- <td><b>mapped_key</b></td>
- <td><code>varchar</code></td>
- <td><code>MDC</code>のキー値。</td>
- </tr>
- <tr>
- <td><b>mapped_value</b></td>
- <td><code>text</code></td>
- <td><code>MDC</code>の値。</td>
- </tr>
- </table>
-
- <p><em>logging_event_exception</em>テーブルには、次のようなカラムがあります。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>カラム名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><b>event_id</b></td>
- <td><code>int</code></td>
- <td>データベースが払いだしたロギングイベントのID。</td>
- </tr>
- <tr>
- <td><b>i</b></td>
- <td><code>smallint</code></td>
- <td>完全なスタックトレースを文字列化した際の各行の添字。</td>
- </tr>
- <tr>
- <td><b>trace_line</b></td>
- <td><code>varchar</code></td>
- <td>スタックトレースの文字列中の1行。</td>
- </tr>
- </table>
-
- <p><code>DBAppender</code>を使用した結果をもっと視覚的にわかりやすくお見せしましょう。次に示すのは、<code>DBAppender</code>がMySQLデータベースを使用した場合のスクリーンショットです。
- </p>
-
- <p><em>logging_event</em>テーブル</p>
-
- <img src="images/chapters/appenders/dbAppenderLE.gif" alt="ロギングイベントテーブル">
-
- <p><em>logging_event_exception</em>テーブル</p>
-
- <img src="images/chapters/appenders/dbAppenderLEException.gif" alt="ロギングイベント例外テーブル">
-
- <p><em>logging_event_property</em>テーブル</p>
-
- <img src="images/chapters/appenders/dbAppenderLEProperty.gif" alt="イベントログ記録Propertyテーブル">
-
-
- <h4>ConnectionSource</h4>
-
- <p><code>ConnectionSource</code>インターフェイスは、logbackが<code>java.sql.Connection</code>を取得するためのJDBC接続を透過的に取得するためのプラグイン可能な機能を提供するものです。<code>ConnectionSource</code>の実装クラスは3つあります。<code>DataSourceConnectionSource</code>、<code>DriverManagerConnectionSource</code>、<code>JNDIConnectionSource</code>です。
- </p>
-
- <p>最初に、<code>DriverManagerConnectionSource</code>を使ってMySQLデータベースに接続する例を見てみましょう。次の設定ファイルを見てください。
- </p>
-
- <p class="example">例: <code>DBAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/db/append-toMySQL-with-driveManger.xml">logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-driveManger.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-driverManager');">Groovyとして表示</span>
- <pre id="append-toMySQL-with-driverManager" class="prettyprint source"><configuration>
-
- <b><appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
- <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
- <driverClass>com.mysql.jdbc.Driver</driverClass>
- <url>jdbc:mysql://host_name:3306/datebase_name</url>
- <user>username</user>
- <password>password</password>
- </connectionSource>
- </appender></b>
-
- <root level="DEBUG" >
- <appender-ref ref="DB" />
- </root>
-</configuration></pre>
-
- <p>正しいJDBCドライバクラス名を指定してください。この例では<code>com.mysql.jdbc.Driver</code>です。<span class="prop">url</span>は<em>jdbc:mysql://</em>で始まらなければなりません。
- </p>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/db/DriverManagerConnectionSource.html">DriverManagerConnectionSource</a></code>は<code>ConnectionSource</code>の実装クラスで、JDBCの伝統的なやり方(接続用URLに基づくやり方)でデータベース接続を取得します。</p>
- <p>このクラスは<code>getConnection()</code>メソッドが呼ばれるたびに新しい<code>Connection</code>を生成することに注意してください。コネクションプーリングをサポートしているJDBCドライバーを使うか、コネクションプーリングを利用する<code>ConnectionSource</code>を自分で実装することをおすすめします。Java EE アプリケーションサーバの上で、<code>javax.sql.DataSource</code>をサポートしたJNDI実装を利用する場合は、後述する<a href="./appenders.html#JNDIConnectionSource"><code>JNDIConnectionSource</code></a>を参照してください。
- </p>
-<!--
-
- HAS TO BE TESTED
-
- <p>
- If you do not have another connection pooling mechanism built
- into your application, you can use the
- <a href="http://jakarta.apache.org/commons/dbcp/index.html">
- commons-dbcp </a> package from Apache:
- </p>
-
-<pre class="prettyprint source">
- <connectionSource
- class="ch.qos.logback.core.db.DriverManagerConnectionSource">
- <param name="driver" value="org.apache.commons.dbcp.PoolingDriver"/>
- <param name="url" value="jdbc:apache:commons:dbcp:/myPoolingDriver"/>
- </connectionSource>
-</pre>
-
- <p>
- Then the configuration information for the commons-dbcp
- package goes into the file <em>myPoolingDriver.jocl</em> and is
- placed in the classpath. See the
- <a href="http://jakarta.apache.org/commons/dbcp/index.html"> commons-dbcp </a>
- documentation for details.
- </p>
- -->
-
- <p><code>DataSource</code>を使ってデータベースに接続する場合もだいたい同じです。設定ファイルでは<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/db/DataSourceConnectionSource.html">DataSourceConnectionSource</a></code>を指定してください。JDBCの推奨するやり方(<code>javax.sql.DataSource</code>に基づくやり方)でデータベース接続(<code>Connection</code>)を取得します。
- </p>
-
- <p class="example">例: <code>DBAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/db/append-with-datasource.xml">logback-examples/src/main/java/chapters/appenders/db/append-with-datasource.xml</a>)</p>
-
-
- <span class="asGroovy" onclick="return asGroovy('append-with-datasource');">Groovyとして表示</span>
- <pre id="append-with-datasource" class="prettyprint source"><configuration debug="true">
-
- <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
- <b><connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
-
- <dataSource class="${dataSourceClass}">
- </b><!-- Joran cannot substitute variables
- that are not attribute values. Therefore, we cannot
- declare the next parameter like the others.
- -->
- <b><param name="${url-key:-url}" value="${url_value}"/>
- <serverName>${serverName}</serverName>
- <databaseName>${databaseName}</databaseName>
- </dataSource></b>
-
- <user>${user}</user>
- <password>${password}</password>
- </connectionSource>
- </appender>
-
- <root level="INFO">
- <appender-ref ref="DB" />
- </root>
-</configuration></pre>
-
- <p>この設定例ではたくさん変数を使っているので気をつけてください。1つの設定ファイルに接続情報の詳細をまとめておくと、logback と他のフレームワークで設定内容を共有できるので便利です。
- </p>
-
-<!-- TO BE TESTED
-
- <p>The connection created by
- <code>DataSourceConnectionSource</code> can be placed in a JNDI
- context by using <code>BindDataSourceToJNDIAction</code>. In that
- case, one has to specify the use of this class by adding a new
- rule to Joran, logback's configuration framework. Here is an
- excerpt of such a configuration file. </p>
-
-<div class="source"><pre><configuration>
- ..
- <b><newRule pattern="configuration/bindDataSourceToJNDI"
- actionClass="ch.qos.logback.core.db.BindDataSourceToJNDIAction"/>
-
- <bindDataSourceToJNDI /></b>
- ..
-</configuration></pre></div>
-
- <p> The <em>newRule</em> element teaches Joran to use specified
- action class with the given pattern. Then, we simply declare the
- given element. The action class will be called and our connection
- source will be bound to a JNDI context. </p>
-
- <p>This is a very powerful capability of Joran. If you'd like to
- read more about Joran, please see the <a
- href="onJoran.html">chapter to Joran</a>. </p>
-
- -->
-
- <h4 class="doAnchor" name="JNDIConnectionSource">JNDIConnectionSource</h4>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/db/JNDIConnectionSource.html">JNDIConnectionSource</a></code>もlogbackの配布物に含まれる<code>ConnectionSource</code>の実装クラスです。名前のとおり、JNDIから<code>javax.sql.DataSource</code>を取得し、そこから<code>java.sql.Connection</code>を取得します。<code>JNDIConnectionSource</code>は、Java EE アプリケーションサーバの内部か、アプリケーションサーバのクライアント(アプリケーションサーバの<code>javax.sql.DataSource</code>にリモートアクセスできることを想定しています)で使用することを念頭に設計されています。したがって、他にどんな便利機能を提供しているかはともかくとして、少なくともコネクションプーリングを [...]
-
- <p>次の例はTomcat用の設定ファイルから抜粋したものです。PostgreSQL で使うための設定ですが、サポートしているデータベースならどれでも同じように動くはずです。</p>
-
-<pre class="prettyprint source"><Context docBase="/path/to/app.war" path="/myapp">
- ...
- <Resource <b>name="jdbc/logging"</b>
- auth="Container"
- type="javax.sql.DataSource"
- username="..."
- password="..."
- driverClassName="org.postgresql.Driver"
- url="jdbc:postgresql://localhost/..."
- maxActive="8"
- maxIdle="4"/>
- ...
-</Context></pre>
-
- <p>Java EE アプリケーションサーバで定義した<code>DataSource</code>をlogbackの設定ファイルから参照するのは簡単です。</p>
-
- <p class="example">例:<code>JNDIConnectionSource</code>を使った<code>DBAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/db/append-via-jndi.xml">logback-examples/src/main/java/chapters/appenders/db/append-via-jndi.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('append-via-jndi');">Groovyとして表示</span>
-
-
-<pre id="append-via-jndi" class="prettyprint source"><configuration debug="true">
- <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
- <connectionSource class="ch.qos.logback.core.db.JNDIConnectionSource">
- <b><!-- please note the "java:comp/env/" prefix --></b>
- <b><jndiLocation>java:comp/env/jdbc/logging</jndiLocation></b>
- </connectionSource>
- </appender>
- <root level="INFO">
- <appender-ref ref="DB" />
- </root>
-</configuration></pre>
-
- <p>このクラスは引数無しのコンストラクタで<code>javax.naming.InitialContext</code>のインスタンスを生成するので注意してください。ほとんどの Java EE コンテナで正常に動作します。Java EE コンテナ以外で動かすときは、JNDIプロバイダのドキュメントで説明されたとおりに<em>jndi.properties</em>を用意してください。
- </p>
-
- <h4 class="doAnchor">コネクションプーリング</h4>
-
- <p>ロギングイベントはかなり高い頻度で生成されることがあります。ロギングイベントが生成されるのに合わせてデータベースに登録していなければなりません。そのためには、<code>DBAppender</code>でコネクションプーリングを利用するとよいでしょう。
- </p>
-
- <p><code>DBAppender</code>でコネクションプーリングを利用すると、著しく性能が改善することが実証されています。次の設定ファイルは、コネクションプーリング無しでMySQLデータベースにロギングイベントを登録するものです。
- </p>
-
- <p class="example">例: コネクションプーリング無しの<code>DBAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/db/append-toMySQL-with-datasource.xml">logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource');">Groovyとして表示</span>
- <pre id="append-toMySQL-with-datasource" class="prettyprint source"><configuration>
-
- <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
- <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
- <dataSource class="com.mysql.jdbc.jdbc2.optional.MysqlDataSource">
- <serverName>${serverName}</serverName>
- <port>${port$</port>
- <databaseName>${dbName}</databaseName>
- <user>${user}</user>
- <password>${pass}</password>
- </dataSource>
- </connectionSource>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="DB" />
- </root>
-</configuration></pre>
-
- <p>この設定ファイルでは、MySQLデータベースに500件のロギングイベントを送信するのになんと5秒もかかりました。つまり、1件あたり10ミリ秒もかかるのです。大規模なアプリケーションでは使いものにならないことがよくわかると思います。
- </p>
-
- <p><code>DBAppender</code>でコネクションプーリングを利用するには、外部ライブラリが必要です。次の例は<a href="http://sourceforge.net/projects/c3p0">c3p0</a>を使っています。c3p0を利用するには、まずダウンロードして、<em>c3p0-VERSION.jar</em>をクラスパス上に配置しなければなりません。
- </p>
-
- <p class="example">例: <code>DBAppender</code>でコネクションプーリングを利用する設定(<a href="http://logback.qos.ch/xref/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml">logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource-and-pooling');">Groovyとして表示</span>
- <pre id="append-toMySQL-with-datasource-and-pooling" class="prettyprint source"><configuration>
-
- <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
- <connectionSource
- class="ch.qos.logback.core.db.DataSourceConnectionSource">
- <b><dataSource
- class="com.mchange.v2.c3p0.ComboPooledDataSource">
- <driverClass>com.mysql.jdbc.Driver</driverClass>
- <jdbcUrl>jdbc:mysql://${serverName}:${port}/${dbName}</jdbcUrl>
- <user>${user}</user>
- <password>${password}</password>
- </dataSource></b>
- </connectionSource>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="DB" />
- </root>
-</configuration></pre>
-
- <p>この設定ファイルを使った場合、MySQLデータベースに500件のロギングイベントを送信するのにかかった時間は約0.5秒でした。1件あたりの所要時間は1ミリ秒です。つまり、10倍高速化できたことになります。
- </p>
-
- <h3 class="doAnchor" name="SyslogAppender">SyslogAppender</h3>
-
- <p>syslogプロトコルは非常に単純なプロトコルです。syslogの送信者は小さなメッセージをsyslogの受信者に送信します。一般的に受信者は<em>syslogデーモン</em>や<em>syslogサーバ</em>と呼ばれます。logbackは、<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/SyslogAppender.html"><code>SyslogAppender</code></a>を使ってリモートのsyslogデーモンにメッセージを送信することができます。
- </p>
-
- <p>SyslogAppenderの設定可能なプロパティは次のとおりです。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="syslog">syslogHost</span></td>
- <td><code>String</code></td>
- <td>syslogサーバのホスト名。</td>
- </tr>
- <tr>
- <td><span class="prop" container="syslog">port</span></td>
- <td><code>String</code></td>
- <td>syslogサーバーのポート番号。ほとんどの場合はデフォルト値の<em>514</em>を使うでしょう。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="syslog">facility</span></td>
- <td><code>String</code></td>
- <td>
- <p><span class="prop">facility</span>は、メッセージの送信元を区別するためのものです。</p>
- <p><span class="prop">facility</span>オプションには、次のいずれかの文字列を指定しなければなりません。<em>KERN、USER、MAIL、DAEMON、AUTH、SYSLOG、LPR、NEWS、UUCP、CRON、AUTHPRIV、FTP、NTP、AUDIT、ALERT、CLOCK、LOCAL0、LOCAL1、LOCAL2、LOCAL3、LOCAL4、のlocal5、LOCAL6、LOCAL7。</em>大文字小文字は区別されません。</p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="syslog">suffixPattern</span></td>
- <td><code>String</code></td>
- <td><p><span class="prop">suffixPattern</span>オプションには、syslogサーバに送信されるメッセージ中の任意部分の書式を指定します。デフォルトは<em>"[%thread] %logger %msg"</em>です。<code>PatternLayout</code>で使用できるものは、全て<span class="prop">suffixPattern</span>に指定することができます。
- </p>
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="syslog">stackTracePattern</span></td>
- <td><code>String</code></td>
- <td><p><span class="prop">stackTracePattern</span>プロパティには、スタックトレースの各行の先頭に表示する文字列を指定します。デフォルトはタブ文字、つまり "\t"です。<code>PatternLayout</code>で使用できるものは、全て<span class="prop">stackTracePattern</span>に指定することができます。</p>
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="syslog">throwableExcluded</span></td>
- <td><code>boolean</code></td>
- <td><code>true</code>を指定すると、Throwableに関連付けられているスタックトレースの情報を省略するようになります。デフォルトは<code>falese</code>です。ですので、syslogサーバにはスタックトレースの情報が送信されます。</td>
- </tr>
-
-
- </table>
-
- <p>ロギングイベントに対する syslog の severity(重要度)は、ロギングレベルを変換したものになります。<em>DEBUG</em>は<em>7</em>、<em>INFO</em>は6、<em>WARN</em>は<em>4</em>、<em>ERROR</em>は<em>3</em>に変換されます。
- </p>
-
- <p>syslog要求の書式には厳密なルールがあるので、<code>SyslogAppender</code>はレイアウトを使用しません。しかし、<span class="prop">suffixPattern</span>オプションを使えば思った通りの内容を表示することができます。
- </p>
-
- <p><code>SyslogAppender</code>の設定例を見てみましょう。</p>
-
- <p class="example">例: <code>SyslogAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-syslog.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-syslog.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('logback-syslog');">Groovyとして表示</span>
- <pre id="logback-syslog" class="prettyprint source"><configuration>
-
- <appender name="SYSLOG" class="ch.qos.logback.classic.net.SyslogAppender">
- <syslogHost>remote_home</syslogHost>
- <facility>AUTH</facility>
- <suffixPattern>[%thread] %logger %msg</suffixPattern>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SYSLOG" />
- </root>
-</configuration></pre>
-
- <p>この設定ファイルを試してみるときは、リモートsyslogデーモンが外部からのリクエストを受け付けるようになっていることを先に確認しておいてください。経験上、デフォルトではsyslogデーモンはネットワークからのリクエストを拒否するようになっていることが多いです。
- </p>
-
-
- <h3 class="doAnchor" name="SiftingAppender">SiftingAppender</h3>
-
- <p>名前のとおり、<code>SiftingAppender</code>は設定に基づいてロギングイベントを分配(あるいはふるいにかける)ことができます。例えば、<code>SiftingAppender</code>がユーザーセッションに基づいてロギングイベントを分配するようになっていれば、ユーザーごとにログファイルを生成するようになるでしょう。
- </p>
-
-
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="sift">timeout</span></td>
- <td><code><a href="http://logback.qos.ch/apidocs/ch/qos/logback/core/util/Duration.html">Duration</a></code></td>
- <td><span class="prop">タイムアウト時間</span>を経過してもアクセスされなかったアペンダーは、古くなったものと判断されます。古くなったアペンダーは閉じられて、<code>SiftingAppender</code>から切り離されます。デフォルトは30分です。</td>
- </tr>
- <tr>
- <td><span class="prop" container="sift">maxAppenderCount</span></td>
- <td><code>integer</code></td>
- <td><code>SiftingAppender</code>が作成して管理できるアペンダーの最大数を指定します。デフォルトはInteger.MAX_VALUEです。</td>
- </tr>
- </table>
-
- <p><code>SiftingAppender</code>は実行時にアペンダーを作成します。<code>SiftingAppender</code>の設定で指定された設定テンプレート(<code>sift要素</code>で囲まれた部分です。後で例を示します)に従って作成します。<code>SiftingAppender</code>には、子アペンダーのライフサイクルを管理する責任があります。たとえば、 <code>SiftingAppender</code>は古くなったアペンダー自動的に閉じて削除します。<span class="prop">タイムアウト時間</span>で指定された時間を過ぎてもアクセスの無かったアペンダーを無効とみなすのです。
- </p>
-
- <p>ロギングイベントが発生したら、<code>SiftingAppender</code>は委譲する子アペンダーを選択します。選択条件は弁別器によって実行時に計算されます。利用者は<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/sift/Discriminator.html">Discriminator</a></code>で選択条件を指定することができます。例を見てみましょう。
- </p>
-
- <h4>例</h4>
-
- <p><a href="http://logback.qos.ch/xref/chapters/appenders/sift/SiftExample.html">SiftExample</a>アプリケーションは、アプリケーションが起動したことを表すメッセージをロギングします。その後、MDCのキー"uesrid"に"Alice"を設定して、メッセージをロギングします。該当するコードは次のとおりです。</p>
-
- <p class="source">logger.debug("Application started");
-MDC.put("userid", "Alice");
-logger.debug("Alice says hello"); </p>
-
- <p><code>SiftingAppender</code>で使う設定ファイルのテンプレートは次のようになっています。</p>
-
-
- <p class="example">例: <code>SiftingAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/sift/byUserid.xml">logback-examples/src/main/java/chapters/appenders/sift/byUserid.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('byUserid');">Groovyとして表示</span>
-
- <pre id="byUserid" class="prettyprint source"><configuration>
-
- <b><appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender"></b>
- <!-- in the absence of the class attribute, it is assumed that the
- desired discriminator type is
- ch.qos.logback.classic.sift.MDCBasedDiscriminator -->
- <b><discriminator></b>
- <b><key><span class="green">userid</span></key></b>
- <b><defaultValue>unknown</defaultValue></b>
- <b></discriminator></b>
- <b><sift></b>
- <b><appender name="FILE-<span class="green">${userid}</span>" class="ch.qos.logback.core.FileAppender"></b>
- <b><file><span class="green">${userid}</span>.log</file></b>
- <b><append>false</append></b>
- <b><layout class="ch.qos.logback.classic.PatternLayout"></b>
- <b><pattern>%d [%thread] %level %mdc %logger{35} - %msg%n</pattern></b>
- <b></layout></b>
- <b></appender></b>
- <b></sift></b>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SIFT" />
- </root>
-</configuration></pre>
-
-
- <p>discriminator 要素にclass属性がない場合、<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/sift/MDCBasedDiscriminator.html">MDCBasedDiscriminator</a>が設定されます。弁別器は、<span class="prop">key</span>プロパティで指定されたキーのMDC値を返します。MDC値がnullの場合は、<span class="prop">defaultValue</span>プロパティで指定した値を返します。
- </p>
-
- <p><code>SiftingAppender</code>による子アペンダーの管理機能は独特なものです。上記の例では、<code>SiftingAppender</code>によって複数の<code>FileAppender</code>が作られます。それぞれの<code>FileAppender</code>はキー"userid"でMDCに登録された値によって区別されます。キー"uesrid"のMDC値が新しい値のときは、新しい<code>FileAppender</code>インスタンスをゼロから作ります。<code>SiftingAppender</code>は自分が作ったアペンダーを追跡し続けます。30分間使われなかったアペンダーは自動的に閉じられ、破棄されます。
- </p>
-
- <p><span class="label notice">変数の公開</span>出力先リソースが別々な複数のアペンダーのインスタンスを利用するにはどうしたらいいでしょうか?弁別器のキーが<a href="./configuration.html#variableSubstitution">変数</a>として公開されるので、上記の例の場合は、アペンダーの設定テンプレート内で"userid"を指定しています。こうすると、子アペンダーに別々の出力先を設定できるようになります。
- </p>
-
- <p><code>SiftExample</code>アプリケーションの引数に設定ファイル"byUserid.xml"を指定して実行すると、"unknown.log" と"Alice.log"という2つのログファイルが作成されます。
- </p>
-
- <p><span class="label">ローカルスコープの変数</span>logback 1.0.12 から、ネストされたアペンダーからローカルスコープの変数が利用できるようになりました。また、<em><code>sift要素</code>内</em>で<a href="./configuration.html#definingProps">変数を定義</a>したり、変数の値を<a href="./configuration.html#definingPropsOnTheFly">実行時に算出</a>できるようになりました。<code>sift要素</code>の外側で定義された変数の値を組み合わせることもできます。
- </p>
-
- <h4 class="doAnchor" name="siftGettingTimeoutRight">適切な<span class="prop">タイムアウト</span>を設定する</h4>
-
- <p>アプリケーションによっては、適切な<span class="prop">タイムアウト時間</span>を決めるのが難しいことがあります。<span class="prop">タイムアウト時間</span>が短すぎると、ネストされたアペンダーが削除された直後に新しく生成されるようになってしまいます。これは<em>ゴミ漁り</em>と呼ばれる事象です。<span class="prop">タイムアウト時間</span>が長すぎると、立て続けにアペンダーが生成されるとリソース不足になってしまうかもしれません。<span class="prop">maxAppenderCount</span>が小さすぎても同じようにゴミ漁りが発生するかもしれません。
- </p>
-
- <p>どんな場合でも、ネストされたアペンダーが不要になる箇所を特定するのは簡単でしょう。そういう場所が特定できたら、あるいはほぼ確実にそうだと言える場所が特定できたら、そこに書かれているロギング式に<a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/ClassicConstants.html#FINALIZE_SESSION_MARKER">FINALIZE_SESSION</a>マーカーを指定しましょう。SiftingAppenderは<code>FINALIZE_SESSION</code>マーカーを指定されたロギングイベントを見つけたら、関連付けられたアペンダーはもう破棄していいいものと判断します。破棄されることになったアペンダーは、数秒間到着するであろうロギングイベントに備えて活性化した後、何も到着しなければそのままクローズします。
- </p>
-
- <pre class="prettyprint source">import org.slf4j.Logger;
-import static ch.qos.logback.classic.ClassicConstants.FINALIZE_SESSION_MARKER;
-
- void job(String jobId) {
-
- MDC.put("jobId", jobId);
- logger.info("Starting job.");
-
- ... do whather the job needs to do
-
- // will cause the nested appender reach end-of-life. It will
- // linger for a few seconds.
- logger.info(FINALIZE_SESSION_MARKER, "About to end the job");
-
- try {
- .. perform clean up
- } catch(Exception e);
- // This log statement will be handled by the lingering appender.
- // No new appender will be created.
- logger.error("unexpected error while cleaning up", e);
- }
- }
-
-</pre>
-
- <h3 class="doAnchor" name="AsyncAppender">AsyncAppender</h3>
-
- <p>AsyncAppenderは<a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/spi/ILoggingEvent.html">ILoggingEvent</a>を非同期的にロギングします。単にイベントディスパッチャとして機能するので、意味のある仕事をさせるには他のアペンダーを参照させなければなりません。</p>
-
- <p><span class="label notice">80%を越えると消えてしまう</span>
-AsyncAppenderはロギングイベントを<a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html">BlockingQueue</a>に蓄積します。<code>AsyncAppender</code>のワーカースレッドは、キューの先頭からロギングイベントを取り出して、<code>AsyncAppender</code>に割り当てられたアペンダーに振り分けます。キューの使用量が80%を超えている場合、デフォルトではTRACE、DEBUG、および、INFOレベルのログを捨ててしまいます。これは、ロギングイベントを失ってしまうリスクに見合うだけの性能影響があります。
- </p>
-
- <p><span class="label">アプリケーションの停止と再デプロイ</span>
-アプリケーションを停止、あるいは<code>再デプロイ</code>する前に、 AsyncAppenderを停止しなければなりません。全てのロギングイベントをキューから吐き出すためです。そのためには、<a href="./configuration.html#stopContext">LoggerContextを停止</a>すればよいです。<code>AsyncAppender</code>を含む全てのアペンダーを閉じます。</p>
-
-
- <p><code>AsyncAppender</code>の設定可能なプロパティは次のとおりです。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="async">queueSize</span></td>
- <td><code>int</code></td>
- <td>キューの最大容量。デフォルトは256です。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="async">discardingThreshold</span></td>
- <td><code>int</code></td>
- <td>デフォルトは20%です。キューの使用量が閾値を越えたら、INFO以下のロギングイベントは破棄、WARN以上のロギングイベントだけをキューイングするようになります。0を指定するとロギングイベントを破棄しないようになります。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="async">includeCallerData</span></td>
- <td><code>boolean</code></td>
- <td>送信者情報の抽出自体に時間がかかることがあります。性能上の兼ね合いにより、デフォルトではロギングイベントをキューに追加するとき、関連する送信者情報を抽出しないようになっています。代わりに、スレッド名などが"軽い"情報だけを<a href="./mdc.html">MDC</a>にコピーします。trueを指定した場合、完全な送信者情報を含めるようになります。
- </td>
- </tr>
- </table>
-
- <p>デフォルトでは、イベントキューに登録可能な件数は256件になっています。キューが一杯になると、新しくロギングイベントを登録しようとしていたアプリケーションスレッドは、ワーカースレッドによってキューのロギングイベントが処理されるまで、ブロックします。キューの使用量が最大使用量を下回るまで、アプリケーションスレッドはロギング要求を発行できなくなります。したがって、ロギングイベントのバッファ使用量が最大値付近で推移しているとき、このアペンダーはほぼ同期的なロギングをすることになります。これは必ずしも悪いことではありません。このアペンダーは、ロギングイベントのバッファ使用量が閾値を超えるほどに増加するまでは、ロギング処理よりもアプリケーションの実行時間が長くなるように設計されています。
- </p>
-
- <p>アプリケーションのスループットを最大化するためには、アペンダーのイベントキューの大きさを最適化する必要があり、それはいくつもの要因が絡んでいます。次に示す要因のいずれか、あるいは全てが、擬似的な同期的動作をさせる可能性があります。</p>
-
- <ul>
- <li>アプリケーションスレッドが多すぎる</li>
- <li>アプリケーションの呼び出しごとのロギング要求が多すぎる</li>
- <li>ロギングイベントごとに付随する情報が多すぎる</li>
- <li>子アペンダーのレイテンシが遅すぎる</li>
- </ul>
-
- <p>一般的には、アプリケーションの使用するヒープを減らして、ロギングイベントのキューを大きくすればよいでしょう。
- </p>
-
-
- <p><span class="label notice">非可逆な振る舞い</span>
-上記の議論を踏まえながらブロックする可能性を減らすため、AsyncAppenderはデフォルトでは利用可能なキューが最大値の20%未満になったらTRACE、DEBUG、INFOレベルのロギングイベントを破棄し、WARNとERRORレベルのロギングイベントだけを残すようになっています。そうすると、TRACE、DEBUG、INFOレベルのロギングイベントにコストをかけなくてもよくなるので、非同期処理を妨げず、高い性能を維持することができます。しきい値<span class="prop">discardingThreshold</span>を0にすればロギングイベントを破棄しないようにすることもできます。
- </p>
-
- <p class="example">例: <code>AsyncAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conc/logback-async.xml">logback-examples/src/main/java/chapters/appenders/conc/logback-async.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('asyncAppender');">Groovyとして表示</span>
-
- <pre id="asyncAppender" class="prettyprint source"><configuration>
- <appender name="<b>FILE</b>" class="ch.qos.logback.core.FileAppender">
- <file>myapp.log</file>
- <encoder>
- <pattern>%logger{35} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <b><appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"></b>
- <b><appender-ref ref="FILE" /></b>
- <b></appender></b>
-
- <root level="DEBUG">
- <appender-ref ref="<b>ASYNC</b>" />
- </root>
-</configuration></pre>
-
-
- <h3 class="doAnchor" name="WriteYourOwnAppender">アペンダーを自作する</h3>
-
-
- <p><code>AppenderBase</code>を使えば簡単にアペンダーを自作することができます。この基底クラスでは、フィルターやステータスメッセージの管理などほとんどのアペンダーが備えている機能を提供するものです。派生クラスでやることと言えば、<code>append(Object eventObject)</code>メソッドを実装するだけです。
- </p>
-
- <p>次に示す<code>CountingConsoleAppender</code>は、限られた数のロギングイベントをコンソールに出力する自作アペンダーです。指定された数のロギングイベントを処理したらシャットダウンします。ロギングイベントを書式化するために<code>PatternLayoutEncoder</code>を使用します。そして、<code>limit</code>というプロパティを設定することができます。また、<code>append(Object eventObject)</code>メソッド以外にもいくつかメソッドを用意しなければなりません。例を見ればわかりますが、これらのパラメータは logback のさまざまな設定の仕組みによって自動的に設定されます。
- </p>
-
- <em>例4<span class="autoExec"></span>: <code>CountingConsoleAppender</code> (<a href="http://logback.qos.ch/xref/chapters/appenders/CountingConsoleAppender.java">logback-examples/src/main/java/chapters/appenders/CountingConsoleAppender.java</a>)</em>
- <pre class="prettyprint source">package chapters.appenders;
-
-import java.io.IOException;
-
-import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.AppenderBase;
-
-
-public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
- static int DEFAULT_LIMIT = 10;
- int counter = 0;
- int limit = DEFAULT_LIMIT;
-
- PatternLayoutEncoder encoder;
-
- public void setLimit(int limit) {
- this.limit = limit;
- }
-
- public int getLimit() {
- return limit;
- }
-
- @Override
- public void start() {
- if (this.encoder == null) {
- addError("No encoder set for the appender named ["+ name +"].");
- return;
- }
-
- try {
- encoder.init(System.out);
- } catch (IOException e) {
- }
- super.start();
- }
-
- public void append(ILoggingEvent event) {
- if (counter >= limit) {
- return;
- }
- // output the events as formatted by our layout
- try {
- this.encoder.doEncode(event);
- } catch (IOException e) {
- }
-
- // prepare for next event
- counter++;
- }
-
- public PatternLayoutEncoder getEncoder() {
- return encoder;
- }
-
- public void setEncoder(PatternLayoutEncoder encoder) {
- this.encoder = encoder;
- }
-}</pre>
-
- <p><code>start()</code>メソッドでは、<code>PatternLayoutEncoder</code>が設定されているかチェックしています。エンコーダーが設定されなかった場合、アペンダーの起動は失敗となり、エラーメッセージを出力します。
- </p>
-
- <p>この自作アペンダーの見どころは次の2点です。</p>
-
- <ul>
-
- <li>JavaBeans の規約通りにアクセサを定義したプロパティは、logbackの他の設定と同じように処理されます。<code>start()</code>メソッドはlogbackの設定処理から自動的に呼び出されるようになっています。アペンダーのさまざまなプロパティの設定と、一貫性を整える役割があります。
- </li>
-
- <li><code>AppenderBase.doAppend()</code>メソッドは派生クラスのappend()メソッドを呼び出します。実際の出力は<code>append()</code>が行います。レイアウトによってロギングイベントを書式化するのもこのメソッドです。
- </li>
- </ul>
-
- <p><a href="http://logback.qos.ch/xref/chapters/appenders/CountingConsoleAppender.html"><code>CountingConsoleAppender</code></a>は他のアペンダーと同じように定義することができます。設定ファイルの例として<a href="http://logback.qos.ch/xref/chapters/appenders/countingConsole.xml"><em>logback-examples/src/main/java/chapters/appenders/countingConsole.xml</em></a>も見てください。
- </p>
-
-
- <h2 class="doAnchor" name="logback_access">Logback Access</h2>
-
- <p>logback-classic のほとんどのアペンダーと同じものが logback-access にもあります。基本的には同じように動きます。以降の節ではそれらの使い方を説明します。
- </p>
-
- <h3 class="doAnchor" name="AccessSocketAppender">SocketAppenderとSSLSocketAppender</h3>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/access/net/SocketAppender.html">SocketAppender</a></code>は、シリアライズした<code>AccessEvent</code>をネットワーク上のリモートホストに送信するために設計されています。リモートロギングは、アクセスイベントが重要であろうとなかろうと盗聴できないようになっています。受信したイベントをデシリアライズした後は、自分で生成したロギングイベントと同じように扱うことができます。
- </p>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/access/net/SSLSocketAppender.html">SSLSocketAppender</a></code>は基本的な<code>SocketAppender</code>を拡張したもので、Secure Sockets Layer(SSL)を介してリモートホストにログを転送します。
- </p>
-
- <p>logback-access の<code>SocketAppender</code>で設定可能なプロパティは、logback-classic の<code>SocketAppender</code>と同じです。
- </p>
-
- <h3 class="doAnchor" name="AccessServerSocketAppender">ServerSocketAppenderとSSLServerSocketAppender</h3>
-
- <p><code>SocketAppender</code>と同様に、<a href="http://logback.qos.ch/xref/ch/qos/logback/access/net/server/ServerSocketAppender.html"><code>ServerSocketAppender</code></a>はシリアライズした<code>AccessEvent</code>をネットワーク上のリモートホストに送信するために設計されています。<code>ServerSocketAppender</code>はサーバとして動作します。つまり、外部のクライアントがTCP接続してくるのを待ち受けます。アペンダーに渡されたロギングイベントは、接続している全てのクライアントに配布されます。
- </p>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/access/net/server/SSLServerSocketAppender.html">SSLSocketAppender</a></code>は基本的な<code>ServerSocketAppender</code>を拡張したもので、Secure Sockets Layer(SSL)を介してリモートホストにログを転送します。
- </p>
-
- <p>logback-access の<code>ServerSocketAppender</code>で設定可能なプロパティは、logback-classic の<code>ServerSocketAppender</code>と同じです。
- </p>
-
-
- <h3 class="doAnchor" name="AccessSMTPAppender">SMTPAppender</h3>
-
- <p>logback-access の<code><a href="http://logback.qos.ch/xref/ch/qos/logback/access/net/SMTPAppender.html">SMTPAppender</a></code>は、logback-classic と同じように動作します。tだ、<span class="prop">評価器</span>の設定はだいぶ違います。デフォルトでは、 <code>URLEvaluator</code>オブジェクトが使用されます。この評価器はロギング要求のURLと突き合わせるURLのリストを持っています。いずれかのURLにマッチするロギング要求が発生したら、<code>SMTPAppender</code>はメールを送信します。
- </p>
-
- <p>logback-access の<code>SMTPAppender</code>の設定例を見てみましょう。
- </p>
- <p class="example">例: <code>SMTPAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/access/logback-smtp.xml">logback-examples/src/main/java/chapters/appenders/conf/access/logback-smtp.xml</a>)</p>
-
-<pre class="prettyprint source"><appender name="SMTP"
- class="ch.qos.logback.access.net.SMTPAppender">
- <layout class="ch.qos.logback.access.html.HTMLLayout">
- <pattern>%h%l%u%t%r%s%b</pattern>
- </layout>
-
- <b><Evaluator class="ch.qos.logback.access.net.URLEvaluator">
- <URL>url1.jsp</URL>
- <URL>directory/url2.html</URL>
- </Evaluator></b>
- <from>sender_email at host.com</from>
- <smtpHost>mail.domain.com</smtpHost>
- <to>recipient_email at host.com</to>
-</appender></pre>
-
- <p>このやり方では、特別な処理プロセスの中で重要な手順を通ったときにメールを送信するようなことができます。メールには、トリガとなったWebページにアクセスする一つ前のWebページが含まれます。他の情報を含めることもできます。
- </p>
-
- <h3 class="doAnchor" name="AccessDBAppender">DBAppender</h3>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/access/db/DBAppender.html"><code>DBAppender</code></a>はアクセスイベントをデータベースに登録するために使用します。
- </p>
-
- <p><code>DBAppender</code>は<em>access_event</em>テーブルと<em>access_event_header</em>テーブルを使います。いずれも<code>DBAppender</code>を使用する前に準備しなければなりません。テーブルを作成するSQLスクリプトはlogback の配布物に含まれています。<em>logback-access/src/main/java/ch/qos/logback/access/db/script</em>ディレクトリにあるはずです。一般的なデータベースそれぞれの専用スクリプトがあります。あなたの使用しているデータベース用のスクリプトが無かったとしても、他のスクリプトを参考にすれば簡単に作成できます。あなたの使っているデータベース用のスクリプトが無かった時は、作成したスクリプトをlogbackプロジェクトに送ってください。
- </p>
-
- <p><em>access_event</em>テーブルのカラムは次のとおりです。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>カラム名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><b>timestamp</b></td>
- <td><code>big int</code></td>
- <td>アクセスイベントの作成時のタイムスタンプ。</td>
- </tr>
- <tr>
- <td><b>requestURI</b></td>
- <td><code>varchar</code></td>
- <td>要求されたURI。</td>
- </tr>
- <tr>
- <td><b>requestURL</b></td>
- <td><code>varchar</code></td>
- <td>要求されたURL。これはリクエストメソッド、リクエストURI、リクエストプロトコルを組み合わせた文字列です。
- </td>
- </tr>
- <tr>
- <td><b>remoteHost</b></td>
- <td><code>varchar</code></td>
- <td>リモートホストの名前。</td>
- </tr>
- <tr>
- <td><b>remoteUser</b></td>
- <td><code>varchar</code></td>
- <td>リモートユーザの名前。
- </td>
- </tr>
- <tr>
- <td><b>remoteAddr</b></td>
- <td><code>varchar</code></td>
- <td>リモートIPアドレス。</td>
- </tr>
- <tr>
- <td><b>protocol</b></td>
- <td><code>varchar</code></td>
- <td><em>HTTP</em>または<em>HTTPS</em>などのリクエストプロトコル、。</td>
- </tr>
- <tr>
- <td><b>method</b></td>
- <td><code>varchar</code></td>
- <td>リクエストメソッド、<em>GET</em>か<em>POST</em>になるでしょう。</td>
- </tr>
- <tr>
- <td><b>serverName</b></td>
- <td><code>varchar</code></td>
- <td>リクエストを受け付けたサーバーの名前。</td>
- </tr>
- <tr>
- <td><b>event_id</b></td>
- <td><code>int</code></td>
- <td>アクセスイベントのデータベース上のID。</td>
- </tr>
- </table>
-
- <p><em>access_event_header</em>テーブルには、リクエストのヘッダ情報が登録されます。次のようなものです。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>カラム名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><b>event_id</b></td>
- <td><code>int</code></td>
- <td>アクセスイベントのデータベース上のID。</td>
- </tr>
- <tr>
- <td><b>header_key</b></td>
- <td><code>varchar</code></td>
- <td><em>User-Agent</em>などのリクエストヘッダー名。</td>
- </tr>
- <tr>
- <td><b>header_value</b></td>
- <td><code>varchar</code></td>
- <td><em>Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1) Gecko/20061010 Firefox/2.0</em>のようなリクエストヘッダー値。</td>
- </tr>
- </table>
-
- <p>logback-access の<code>DBAppender</code>に設定可能なプロパティは、logback-classic の<code>DBAppender</code>でも利用できます。logback-access の DBAppender でだけ設定可能なプロパティは次のとおりです。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td>
- <b>
- <span class="prop">insertHeaders</span>
- </b>
- </td>
- <td>
- <code>boolean</code>
- </td>
- <td>trueの場合、ロギング要求に含まれる全てのヘッダ情報を登録するようになります。
- </td>
- </tr>
- </table>
-
- <p><code>DBAppender</code>の設定例を見てください。</p>
-
- <p class="example">例:DBAppenderの設定(<em><a href="http://logback.qos.ch/xref/chapters/appenders/conf/access/logback-DB.xml</em>">logback-examples/src/main/java/chapters/appenders/conf/access/logback-DB.xml</em></a>)</p>
-
- <pre class="prettyprint source"><configuration>
-
- <appender name="DB" class="ch.qos.logback.access.db.DBAppender">
- <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
- <driverClass>com.mysql.jdbc.Driver</driverClass>
- <url>jdbc:mysql://localhost:3306/logbackdb</url>
- <user>logback</user>
- <password>logback</password>
- </connectionSource>
- <insertHeaders>true</insertHeaders>
- </appender>
-
- <appender-ref ref="DB" />
-</configuration></pre>
-
-
- <h3 class="doAnchor" name="AccessSiftingAppender">SiftingAppender</h3>
-
- <p>logback-access のSiftingAppenderは、logback-classic のSiftingAppenderとほとんど同じです。主な違いは、デフォルトの弁別器がMDCを参照するものではなく、<a href="http://logback.qos.ch/xref/ch/qos/logback/access/sift/AccessEventDiscriminator.html">AccessEventDiscriminator</a>になっていることです。AccessEventDiscriminatorは、その名のとおり、ネストされたアペンダーを選択するために、AccessEventのフィールドを使用します。指定されたフィールドの値がnullの場合<span class="prop">DefaultValue</span>プロパティの値が使用されます。
- </p>
-
- <p>AccessEventのフィールドとして指定できるのはCOOKIE、REQUEST_ATTRIBUTE、SESSION_ATTRIBUTE、REMOTE_ADDRESS、LOCAL_PORT、REQUEST_URIです。最初の3つのフィールドは単独で指定することはできません。<span class="prop">AdditionalKey要素</span>が必要なので注意してください。</p>
-
- <p>設定ファイルの例を示します。</p>
-
- <p class="example">例:SiftingAppenderの設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/sift/access-siftingFile.xml">logback-examples/src/main/java/chapters/appenders/conf/sift/access-siftingFile.xml</a>)</p>
-
- <pre class="prettyprint source"><configuration>
- <appender name="SIFTING" class="ch.qos.logback.access.sift.SiftingAppender">
- <Discriminator class="ch.qos.logback.access.sift.AccessEventDiscriminator">
- <Key>id</Key>
- <FieldName>SESSION_ATTRIBUTE</FieldName>
- <AdditionalKey>username</AdditionalKey>
- <defaultValue>NA</defaultValue>
- </Discriminator>
- <sift>
- <appender name="access-$id-$username" class="ch.qos.logback.core.FileAppender">
- <file>byUser/access-$id-$username.log</file>
- <layout class="ch.qos.logback.access.PatternLayout">
- <pattern>%h %l %u %t \"%r\" %s %b</pattern>
- </layout>
- </appender>
- </sift>
- </appender>
- <appender-ref ref="SIFTING" />
-</configuration></pre>
-
-
- <p>この例では<code>SiftingAppender</code>が<code>FileAppender</code>をネストしています。キー要素の値"id"は、ネストされた<code>FileAppender</code>で変数として使用することができます。デフォルトの弁別器でもある<code>AccessEventDiscriminator</code>は AdditionalKey 要素で指定した"username" を<code>AccessEvent</code>のセッション属性から探します。指定した属性が無かったら、defaultValue要素の値"NA"を使用します。セッション属性の"username"には、アプリケーションのログインユーザー名が含まれていることを想定しています。ユーザーごとのアクセスログは、<em>byUser</em>フォルダの下にユーザー名入りのファイル名で出力されます。
- </p>
-
-
- <script src="http://logback.qos.ch/templates/footer.js" type="text/javascript"></script>
-
-
- </div>
-
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/manual/architecture.html b/docs/manual/architecture.html
index 9cec151..b093ca6 100644
--- a/docs/manual/architecture.html
+++ b/docs/manual/architecture.html
@@ -27,8 +27,6 @@
<h1>Chapter 2: Architecture</h1>
- <a href="architecture_ja.html">和訳 (Japanese translation)</a>
-
<div class="quote">
<p><em>All true classification is genealogical.</em></p>
<p>—CHARLES DARWIN, <em>The Origin of Species</em></p>
diff --git a/docs/manual/architecture_ja.html b/docs/manual/architecture_ja.html
deleted file mode 100644
index 8a412cc..0000000
--- a/docs/manual/architecture_ja.html
+++ /dev/null
@@ -1,619 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第2章 アーキテクチャ</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第2章 アーキテクチャ</h1>
-
- <div class="quote">
- <p><em>本物の分類学とは、系統学のことなのだ。</em></p>
- <p>—CHARLES DARWIN, <em>The Origin of Species</em></p>
-
- <p><em>文字で書かれたものを読むだけで、得られた情報を具体的な問題に適用し、読んだことを自分のものとして考えること無しには、問題そのものを学ぶことは、不可能ではないが困難だ。さらに、私たちは自ら発見した時にこそ最も良い学びを得るのだ。</em>
- </p>
- <p>—DONALD KNUTH, <em>The Art of Computer Programming</em></p>
- </div>
-
-
- <script src="../templates/creative.js" type="text/javascript"></script>
-
- <h2>Logbackのアーキテクチャ</h2>
-
- <p>logback の基本的なアーキテクチャは、さまざまな状況に対応できるよう、十分に汎用的になっています。今のところ、logbackは三つのモジュールに分割されています(logback-core、logback-classic、logback-access)。
- </p>
-
- <p><em>coreモジュール</em>は、他の二つのモジュールの足回りとして使用されています。<em>classic</em>モジュールは、 <em>core</em>を拡張するものです。classic モジュールは、著しく改善されたバージョンのlog4jとも考えられます。logback-classic は <a href="http://www.slf4j.org">SLF4J API</a> を直接実装しているので、log4j や java.util.logging(JUL)などの他のロギング実装と切り替えることができます。三つ目の<em>access</em>と呼ばれるモジュールは、HTTPのアクセスログ機能を提供するため、サーブレットコンテナと統合しています。access モジュールについては<a href="http://logback.qos.ch/access.html">別のドキュメント</a>に記載されています。
- </p>
-
- <p>このドキュメントの残りの部分では、logback-classicモジュールのことを "logback" と表記しています。
- </p>
-
- <h2>ロガー、アペンダー、レイアウト</h2>
-
- <p>logback は三つの主要なクラス(<code>Logger</code> 、 0}Appender、<code>Layout</code> )で成り立っています。これらの三つのコンポーネントが協調することで、開発者はメッセージを適切な種類、レベルでロギングできるようになっています。また、書式化や出力先を実行中に変更できるようにもなっています。
- </p>
-
- <p><code>Logger</code>クラスは、logback-classicモジュールに含まれています。一方、 <code>Appender</code>と<code>Layout</code>インタフェイスは、logback-coreモジュールに含まれています。logback-core モジュールは共通モジュールなので、logger の責務を含まないのです。
- </p>
-
- <h3 class="doAnchor" name="LoggerContext">ロガーコンテキスト</h3>
-
- <p>どんなロギングAPIであっても単純な<code>System.out.println</code>に勝る第一の、そして最大の利点があります。それは、特定のロギング式を無効にしつつ、他のロギング式には一切影響を与えない機能です。この機能は、ロギング空間、すなわち、すべてのロギング式からなる空間が、開発者の選択した基準に基いて分類されていることを前提としています。logback-classic モジュールにおいて、この分類は logger に固有のものです。全てのロガーは <code>LoggerContext</code> に接続します。<code>LoggerContext</code> には、接続してきたロガーを階層的な木構造として配置する責務があります。
- </p>
-
- <p>ロガーは名前を持ったエンティティです。名前は大文字と小文字が区別され、階層的な命名規則に従うようになっています。</p>
-
- <div class="definition">
- <div class="deftitle">名前の階層</div>
- <p>あるロガーの名前が、他のロガーの名前の中で「.」(ドット)で区切られた前置詞となっているとき、それぞれが先祖と子孫となります。自分自身や、自分の子にも祖先がいない場合、そのロガーは親になります。
- </p>
- </div>
-
- <p>たとえば、<code>"com.foo"</code>という名前のロガーは、<code>"com.foo.Bar"</code> というロガーの親になります。同様に、 <code>"java"</code>は<code>"java.util"</code>の親であると同時に、<code>"java.util.Vector"</code> の祖先になります。この命名スキームは、ほとんどの開発者がきちんと理解しなければならないものです。
- </p>
-
- <p>ルートロガーは、ロガー階層の最上位に存在するものです。複数の階層構造すべてに含まれるという意味で、例外的な存在です。他のロガーと同じように、名前で取得することができます。こんな風に。</p>
-
- <pre class="prettyprint source">Logger rootLogger = LoggerFactory.getLogger(<a href="http://www.slf4j.org/apidocs/constant-values.html#org.slf4j.Logger.ROOT_LOGGER_NAME">org.slf4j.Logger.ROOT_LOGGER_NAME</a>);</pre>
-
- <p>他のロガーも、org.slf4j.LoggerFactory</html>クラスの静的クラスメソッドである<code>getLogger</code>によって取得することができます。このメソッドは、パラメータとして欲しいロガーの名前を受け付けます。<code>Logger</code>インタフェイスの基本的なメソッドをいくつか以下に示します。
-
-
- <pre class="prettyprint source">package org.slf4j;
-public interface Logger {
-
- // Printing methods:
- public void trace(String message);
- public void debug(String message);
- public void info(String message);
- public void warn(String message);
- public void error(String message);
-}</pre>
-
-
-
- <h3 class="doAnchor" name="effectiveLevel">有効レベル(別名レベルの継承)</h3>
-
- <p>ロガーにはレベルを割り当てることができます。利用できるレベル(TRACE、DEBUG、INFO、WARNおよびERROR)は<code>ch.qos.logback.classic.Level</code>クラスに定義されています。logback では Level クラスは final として宣言されており、サブクラス化出来ないことに注意してください。より柔軟性のあるアプローチは<code>Marker</code>オブジェクトとして利用可能です。
- </p>
-
- <p>レベルの割り当てられていないロガーは、直近の祖先に割り当てられたレベルを継承します。より正確に言うと次のようになります。</p>
-
- <div class="definition">
-
-
- <p>与えられたロガー<em>L</em>の有効なレベルは、ロガー階層において最初に見つかったロガーのレベルに等しい。階層は<em>L</em>から始まり、ロートロガーに向かって進んでいく。
- </p>
- </div>
-
- <p>最終的に全てのロガーがレベルを継承できるように、ルートロガーには必ずレベルが割り当てられています。デフォルトではDEBUGになっています。</p>
-
- <p>以下は、レベル継承ルールに従ってロガーに割り当てられた有効レベルの例です。
- </p>
-
- <em>例1</em>
- <table class="bodyTable">
- <tr>
- <th>ロガー名</th>
- <th>割り当てられたレベル</th>
- <th>有効レベル</th>
- </tr>
- <tr class="alt">
- <td>ルートロガー</td>
- <td>DEBUG</td>
- <td>DEBUG</td>
- </tr>
- <tr>
- <td>X</td>
- <td>なし</td>
- <td>DEBUG</td>
- </tr>
-
- <tr class="alt">
- <td>X.Y</td>
- <td>なし</td>
- <td>DEBUG</td>
- </tr>
- <tr>
- <td>X.Y.Z</td>
- <td>なし</td>
- <td>DEBUG</td>
- </tr>
- </table>
-
- <p>上記の例では、ルートロガーにだけレベルが割り当てられています。レベルは<code>DEBUG</code>で 、他の全てのロガーに継承されています。
- </p>
-
- <em>例2</em>
- <table class="bodyTable">
- <tr>
- <th>ロガー名</th>
- <th>割り当てられたレベル</th>
- <th>有効レベル</th>
- </tr>
- <tr class="alt" align="left">
- <td>ルート</td>
- <td>ERROR</td>
- <td>ERROR</td>
- </tr>
- <tr align="left">
- <td>X</td>
- <td>INFO</td>
- <td>INFO</td>
- </tr>
-
- <tr class="alt" align="left">
- <td>X.Y</td>
- <td>DEBUG</td>
- <td>DEBUG</td>
- </tr>
- <tr align="left">
- <td>X.Y.Z</td>
- <td>WARN</td>
- <td>WARN</td>
- </tr>
- </table>
-
- <p>上記の例では、すべてのロガーにレベルが割り当てられています。レベルの継承は何も仕事をしていません。
- </p>
-
- <em>例3</em>
- <table class="bodyTable">
- <tr>
- <th>ロガー名</th>
- <th>割り当てられたレベル</th>
- <th>有効レベル</th>
- </tr>
- <tr class="alt" align="left">
- <td>ルート</td>
- <td>DEBUG</td>
- <td>DEBUG</td>
- </tr>
-
- <tr align="left">
- <td>X</td>
- <td>INFO</td>
- <td>INFO</td>
- </tr>
- <tr class="alt" align="left">
- <td>X.Y</td>
- <td>なし</td>
- <td>INFO</td>
- </tr>
- <tr align="left">
- <td>X.Y.Z</td>
- <td>ERROR</td>
- <td>ERROR</td>
- </tr>
- </table>
-
- <p>上記の例では、ルートロガーにDEBUG、<code>X</code>にINFO、<code>X.Y.Z</code>にERRORが割り当てられています。<code>X.Y</code>は親である<code>X</code>からレベルを継承しています。</p>
-
- <em>例4</em>
- <table class="bodyTable">
-
- <tr>
- <th>ロガー名</th>
- <th>割り当てられたレベル</th>
- <th>有効レベル</th>
- </tr>
- <tr class="alt" align="left">
- <td>ルート</td>
- <td>DEBUG</td>
- <td>DEBUG</td>
- </tr>
-
- <tr align="left">
- <td>X</td>
- <td>INFO</td>
- <td>INFO</td>
- </tr>
- <tr class="alt" align="left">
- <td>X.Y</td>
- <td>なし</td>
- <td>INFO</td>
- </tr>
- <tr align="left">
- <td>X.Y.Z</td>
- <td>なし</td>
- <td>INFO</td>
- </tr>
- </table>
-
-
- <p>上記の例では、ルートロガーにDEBUG、<code>X</code>にINFOが割り当てられています。<code>X.Y</code>および<code>X.Y.Z</code>は、最も近い親からレベルを継承しています。
- </p>
-
- <h3 class="doAnchor" name="basic_selection">印字メソッドと基本的な選択ルール</h3>
-
- <p>定義によると、印字メソッドはロギング要求のレベルを決定するものです。例えば、<code>L</code>がロガーのインスタンスだとすると、式<code>L.info("..")</code>はINFOレベルのロギングであることになります。</p>
-
-
- <p>ロギング要求は、そのロガーの有効レベル以上である場合に<em>有効</em>となります。そうでなければ、ロギング要求は<em>無効</em>になります。前述のように、レベルが割り当てられていないロガーは最も近い祖先から継承します。このルールは次のように要約できます。
- </p>
-
-
- <div class="definition">
- <div class="deftitle">基本的な選択ルール</div>
-
- <p>有効レベル<em>q</em>のロガーに発行されたレベル<em>p</em>のログ要求は、<em>p>=q</em>を満たす場合有効になる。
- </p>
- </div>
-
- <p>このルールはlogbackの中核を為すものです。レベルは次のような順序であることを想定しています。<code>TRACE < DEBUG < INFO < WARN < ERROR</code></p>
-
- <p>以下は、選択ルールをより具体的に示したものです。垂直方向のラベルはロギング要求のレベル<em>p</em>です。そして水平方向のラベルはロガーの有効レベル<em>q</em>です。行(ロギング要求のレベル)と列(ロガーの有効レベル)の交点が、基本的な選択ルールの適用結果を表しています。
- </p>
-
- <table width="80%">
- <tr>
- <td class="lgray_bg" rowspan="2"><br>ロギング要求のレベル<em>p</em></td>
- <td align="center" colspan="6" style="border-top:1px solid #dddddd">ロガーの有効レベル<em>q</em></td>
- </tr>
- <tr align="left">
- <th style="border-bottom:1px solid #dddddd">TRACE</th>
- <th style="border-bottom:1px solid #dddddd">DEBUG</th>
- <th style="border-bottom:1px solid #dddddd">INFO</th>
- <th style="border-bottom:1px solid #dddddd">WARN</th>
- <th style="border-bottom:1px solid #dddddd">ERROR</th>
- <th style="border-bottom:1px solid #dddddd">OFF</th>
- </tr>
- <tr align="left">
- <th class="lgray_bg">TRACE</th>
- <td><span class="greenBold">YES</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- </tr>
-
- <tr align="left">
- <th class="lgray_bg">DEBUG</th>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- </tr>
- <tr align="left">
- <th class="lgray_bg">INFO</th>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- </tr>
- <tr align="left">
- <th class="lgray_bg">WARN</th>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- </tr>
- <tr align="left">
- <th class="lgray_bg">ERROR</th>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="redBold">NO</span></td>
- </tr>
- </table>
-
- <p>選択ルールのコード例を次に示します。</p>
-
- <pre class="prettyprint source">import ch.qos.logback.classic.Level;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-....
-
-// "com.foo"という名前のロガーを取得します。
-// ロガーのインスタンスはレベルを設定するために ch.qos.logback.classic.Logger とします。
-ch.qos.logback.classic.Logger logger =
- (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.foo");
-// レベルに<span class="blue">INFO</span>を設定します。setLevel() メソッドは logback のロガーにしかありません。
-.setLevel(Level. <span class="blue">INFO</span>);
-
-Logger barlogger = LoggerFactory.getLogger("com.foo.Bar");
-
-// このロギング要求は有効です。<span class="green bold">WARN</span> >= <span class="blue">INFO</span>
-logger.<span class="green bold">warn</span>("Low fuel level.");
-
-// このロギング要求は無効です。<span class="green bold">DEBUG</span> < <span class="blue">INFO</span>.
-logger.<span class="green bold">debug</span>("Starting search for nearest gas station.");
-
-// "com.foo.Bar" という名前のロガーは、"com.foo" ロガーからレベルを継承します。
-// したがって、このロギング要求は有効です。<span class="green bold">INFO</span> >= <span class="blue">INFO</span>.
-barlogger.<span class="green bold">info</span>("Located nearest gas station.");
-
-// このロギング要求は無効です。<span class="green bold">DEBUG</span> < <span class="blue">INFO</span>.
-barlogger.<span class="green bold">debug</span>("Exiting gas station search");</pre>
-
- <a name="RetrievingLoggers"></a>
- <h3>ロガーの取得</h3>
- <p><code><a href="http://logback.qos.ch/apidocs/org/slf4j/LoggerFactory.html#getLogger(java.lang.String)">LoggerFactory.getLogger</a></code>を呼び出しましょう。
-同じ名前なら、常に同じロガーインスタンスへの参照を返します。
- </p>
-
- <p>例えば次のような場合は常に同じインスタンスを返します。</p>
- <pre class="prettyprint source">Logger x = LoggerFactory.getLogger("wombat");
-Logger y = LoggerFactory.getLogger("wombat");</pre>
-
- <p>
- <code>x</code>と<code>y</code>は、<em>完全に</em>同じオブジェクトを参照します。
- </p>
-
- <p>このように、一度ロガーのインスタンスを設定すれば、わざわざ参照を渡さなくても、コード中のどこででも同じインスタンスを取得することができます。現実世界の生物の親子関係とは矛盾していますが、logback のロガーは親と子のどちらが先に生成されても問題ありません。ただし、「親」ロガーから子孫ロガーを見つけようとするときは、事前にインスタンス化しておく必要があります。
- </p>
- <p>logback の実行環境の設定は、アプリケーションの初期化時に行われるのが一般的です。設定ファイルを読み込むようにするとよいでしょう。方法についてはすぐ後で説明します。
- </p>
- <p>logback では、<em>コンポーネント</em>ごとにロガーの名前を付けるのが簡単です。ロガーをクラスごとにインスタンス化すれば、それぞれのロガーの名前はクラスの完全名になります。これはロガーを定義する簡単かつ便利な方法です。クラスの完全名であるロガーの名前をログに出力するようになっていれば、メッセージを出力した箇所を特定するのは簡単です。ですが、これはロガーの命名戦略としてごく一般的な方法の一つでしかありません。logback 自体にロガーのインスタンス数の制限はありません。従って、開発者は自由に名前を付けることが出来ます。
- </p>
-
- <p>とはいえ、ロガーの名前にそれが置かれたクラスの完全名を付けることは、一般的に最も良い方法であるということが共通認識になっています。
- </p>
-
- <a name="AppendersAndLayouts"></a>
- <h3>アペンダーとレイアウト</h3>
-
- <p>ロガーのレベルに応じてロギング要求の有効無効を選択できる機能は、logbackの機能の一部でしかありません。logback は、ロギング要求を複数の宛先の送りつけることができます。logback では、宛先のことをアペンダーと呼びます。現在利用できるアペンダーには、コンソール、ファイル、MySQLやPostgreSQLやOracleなどのデータベースへのリモート接続、JMS、リモートSyslogデーモンなどがあります。
-
- <!--It is also possible to log asynchronously. -->
- </p>
-
- <p>ロガーには一つ以上のアペンダーを割り当てることができます。</p>
-
- <p>指定されたロガーにアペンダーを割り当てるには、<code><a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/Logger.html#addAppender(ch.qos.logback.core.Appender)">addAppender</a></code>メソッドを使います。有効なロギング要求は、ロガーに割り当てられた全てのアペンダーについて、階層関係が上位のアペンダーから順に転送されます。別の言い方をすると、ロガー階層からアペンダーも引き継ぐということです。例えば、ルートロガーにコンソールアペンダーを割り当てたなら、有効なロギング要求は少なくともコンソールに出力されることになります。さらに、ロガー<em>L</em>にファイルアペンダーが割り当てられたなら、<em>L</em>とその子孫全てにおいて、有効なロギング要求はコンソールとファイルの両方に出力されます。ロガーの additivity フラグを false に設定すれば、アペンダーを継承しないように振る舞いを変更するこ [...]
- </p>
-
- <p>アペンダーの加算ルールをまとめると次のようになります。
- </p>
- <div class="definition">
-
- <h4 class="deftitle"><a href="./01-architecture.html#additivity" name="additivity">アペンダーの加算性</a></h4>
-
- <p>ロガー<em>L</em>のログ出力は、<em>L</em>とその祖先も割り当てられた全てのアペンダーに転送される。これが「アペンダーの加算性」の定義である。
- </p>
-
- <p>ロガー<em>L</em>の祖先<em>P</em>の aditivity フラグが false の場合、<em>L</em>の出力は<em>L</em>自身に割り当てられたアペンダーと、祖先<em>P</em>に割り当てられたアペンダーだけに転送される。<em>P</em>よりも祖先のロガーのアペンダーには転送されない。</p>
-
- <p>デフォルトでは、ロガーの aditivity は true になっています。
- </p>
-
- </div>以上を踏まえた例を次の表に示します。<table class="bodyTable">
- <tr>
- <th>ロガー名</th>
- <th>割り当てられたアペンダー</th>
- <th>aditivity フラグ</th>
- <th>宛先</th>
- <th>コメント</th>
- </tr>
- <tr>
- <td>root</td>
- <td>A1</td>
- <td>適用できません</td>
- <td>A1</td>
-
- <td>ルートロガーは、ロガー階層の最上位になるため、aditivity フラグは無効です。
- </td>
- </tr>
- <tr class="alt">
- <td>x</td>
- <td>A-x1、A-x2</td>
- <td>true</td>
- <td>A1、A-x1、A-x2</td>
- <td>「x」のアペンダーとルートロガーのアペンダーが対象</td>
- </tr>
- <tr>
- <td>x.y</td>
- <td>なし</td>
- <td>true</td>
- <td>A1、A-x1、A-x2</td>
- <td>「x」のアペンダーとルートロガーのアペンダーが対象</td>
- </tr>
- <tr class="alt">
- <td>x.y.z</td>
- <td>A-xyz1</td>
- <td>true</td>
- <td>A1、A-x1、A-x2、A-xyz1</td>
- <td>「x.y.z」のアペンダーと「×」のアペンダーとルートロガーのアペンダーが対象</td>
- </tr>
- <tr>
- <td>security</td>
- <td>A-sec</td>
- <td class="blue"><span class="blue">false</span></td>
- <td>A-sec</td>
-
- <td>aditivity フラグが<code>false</code>なので、アペンダーは加算されません。A-sec だけが対象になります
- </td>
- </tr>
- <tr class="alt">
- <td>security.access</td>
- <td>なし</td>
- <td>true</td>
- <td>A-sec</td>
- <td>「security」のaditivityフラグが<code>false</code>なので、「security」のアペンダーだけが加算されます
- </td>
- </tr>
- </table>
-
-
- <p>利用者は、ほとんどの場合出力先だけでなく出力形式もカスタマイズしたがるでしょう。アペンダーと<em>レイアウト</em>を関連付けることで実現できます。レイアウトは、利用者の指定したとおりにロギング要求を整形するものです。一方、アペンダーは整形されたメッセージを指定された宛先に転送します。利用者は、logback の標準配布物に含まれる<code>PatternLayout</code>を使って、C言語の<code>printf</code>関数で使うような変換指示子によって出力形式を指定します。
- </p>
-
- <p>PatternLayoutの変換パターンが "%-4relative [%thread] %-5level %logger{32} - %msg%n" のとき、出力は次のようになります。</p>
-
- <div class="prettyprint source"><pre>176 [main] DEBUG manual.architecture.HelloWorld2 - Hello world.</pre></div>
-
- <p>最初のフィールドはプログラムが開始してからの経過時間をミリ秒にしたものです。二番目のフィールドはログ要求を行ったスレッドです。三番目のフィールドはログ要求のレベルです。四番目のフィールドはログ要求を行ったロガーの名前です。'-' より後のテキストはログ要求に指定されたメッセージになります。</p>
-
-
- <h3 class="doAnchor" name="parametrized">パラメータ化ロギング</h3>
-
- <p>ogbakc-classicのロガーは、<a href="http://www.slf4j.org/api/org/slf4j/Logger.html">SLF4JのLoggerインターフェイス</a>に含まれる一つ以上のパラメータを受け取る出力メソッドを実装しています。これらのメソッドは、コードの読みやすさへの影響を最小限に抑えながら、性能を改善するために用意されたものです。
- </p>
-
- <p></p>
-
- <pre class="prettyprint source">logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));</pre>
-
- <p>こんな書き方をしているロギング式があった場合、メッセージを組み立てるために、整数<code>i</code>と<code>entry[i]</code>を文字列にするコスト、文字列を連結する中間的なコストがかかるでしょう。これは、ロギング要求が有効かどうかに関わらずかかってしまうコストです。
- </p>
-
- <p>パラメータ構築のコストを回避するには、ロギング式全体をテスト条件で囲む方法があります。
- </p>
-
- <pre class="prettyprint source">if(logger.isDebugEnabled()) {
- logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
-}</pre>
-
-
- <p>こうすると、DEBUGレベルのロギング要求が無効になっていればパラメータ構築のコストはかからないでしょう。しかし、有効になっている場合、<code>debugEnabled</code>と<code>debug</code>のそれぞれでロガーのレベルが有効かどうかを判定することになってしまいます。ロガーのレベルの評価はロギング要求に対して1%未満の時間しかかからないので、実際のオーバーヘッドは些細なものです。</p>
-
- <h4>より良い方法</h4>
-
- <p>メッセージフォーマットに基づいた便利な方法があります。<code>entry</code>が何らかのオブジェクトを指すものとして、次のように書くことが出来ます。</p>
-
-
- <pre class="prettyprint source">Object entry = new SomeObject();
-logger.debug("The entry is {}.", entry);</pre>
-
- <p>ロギング要求が有効かどうかを判断した後にだけ、そして、それが有効な場合にだけ、ロガーはメッセージを書式化して、'{}' を <code>entry</code> の文字列表現で置き換えます。つまり、ロギング要求が無効な場合、このやり方だとパラメータ構築のコストが発生しません。
- </p>
-
-
- <p>以下の二行からはまったく同じ出力が得られます。しかし、 ロギング要求が<em>無効</em>な場合、二行目のやり方は一行目のやり方に比べて少なくとも30倍は遅くなるでしょう。
- </p>
-
- <pre class="prettyprint source">logger.debug("The new entry is "+entry+".");
-logger.debug("The new entry is {}.", entry);</pre>
-
-
- <p>二つ置換場所を指定することもできます。たとえば、次のように書くことができます。</p>
-
- <pre class="prettyprint source">logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);</pre>
-
- <p>引数が三つ以上になる場合、<code>Object[]</code>でラップしなければなりません。たとえば、次のように書くことができます。</p>
-
-
- <pre class="prettyprint source">Object[] paramArray = {newVal, below, above};
-logger.debug("Value {} was inserted between {} and {}.", paramArray);</pre>
-
-
- <a name="UnderTheHood"></a>
- <h3>内部実装を覗いてみよう</h3>
-
- <p>ここまでで、logback の中心的なコンポーネントについて紹介してきました。次のステップに進む準備は完璧です。利用者が logback の出力メソッドを呼び出した時に、logback フレームワークの内部でどんなことが起きているのか見ていきましょう。利用者が<em>com.wombat</em>という名前のロガーについて、<code>info()</code>を呼び出した時の様子を分析してみましょう。
- </p>
-
- <h4>ステップ1. フィルタチェインの決定</h4>
-
- <p><code>TurboFilter</code>が存在するならそれが呼び出されます。Turbo Filter コンテキストにまたがる閾値を設定できるし、いろんなイベントを捨てることができます。捨てるイベントは、<code>Marker</code> 、 <code>Level</code> 、 <code>Logger</code> 、メッセージ、<code>Throwable</code>といったロギング要求に関係する情報から判断します。フィルタチェインの結果が <code>FilterReply.DENY</code> だったら処理中のロギング要求はその時点で破棄します。<code>FilterReply.NEUTRAL</code> だったら次のステップ(ステップ2)に進みます。<code>FilterReply.ACCEPT</code> だったら、次のステップを無視してステップ3にジャンプします。
- </p>
-
- <h4>ステップ2. <a href="./02-architecture.html#basic_selection">基本的な選択ルール</a>の適用</h4>
-
- <p>このステップでは、logback はロガーの有効レベルとロギング要求のレベルを比較します。比較した結果ロギング要求が無効の場合は残りの処理は行わず、ロギング要求を破棄します。ロギング要求が破棄されなければ、次のステップに進みます。
- </p>
-
- <h4>ステップ3. <code>LoggingEvent</code>オブジェクトの作成</h4>
-
- <p>ロギング要求がここまでのフィルタを通過したら、logback はロギング要求に含まれる必要な情報を全て格納した<code>ch.qos.logback.classic.LoggingEvent</code> オブジェクトを作成します。中には、ロギング要求を受け付けたロガーインスタンス、ロギング要求のレベル、ロギング要求に指定された例外オブジェクト、現在の時間、現在のスレッド、ロギング要求を起こしたクラスに関するさまざまな情報、<code>MDC</code>などが含まれます。フィールドによってはレイジーな初期化となるものがあります。つまり、必要になった時点で初期化される、ということです。<code>MDC</code>は、ロギング要求の付加情報となります。MDCについては<a href="./08-mdc.html">以降の章</a>で詳しく説明します。</p>
-
- <h4>ステップ4. アペンダーの起動</h4>
-
- <p><code>LoggingEvent</code>オブジェクトを作ったら、logback は利用可能な全てのアペンダーについて <code>doAppend()</code>メソッドを呼び出します。ロガーコンテキストから受け継いだアペンダーが対象になります。
- </p>
-
- <p>logback の配布物に含まれているアペンダーは、すべて <code>AppenderBase</code> 抽象クラスを継承しています。<code>doAppend()</code>メソッドは synchronized として宣言されており、スレッドセーフであることが保証されています。<code>AppenderBase</code>クラスの<code>doAppend()</code>メソッドでは、アペンダーに割り当てられたフィルターが存在する場合、それを呼び出します。カスタムフィルターは、実行時にアペンダーに割り当てることができるフィルターのことです。<a href="./07-filters.html">別の章</a>で説明しています。
- </p>
-
- <h4>ステップ5. メッセージの書式化</h4>
-
- <p>ロギングイベントを書式化するのはアペンダーの責任です。しかし、全てでは無いにしてもいくつかのアペンダーは書式化のタスクをレイアウトに委譲します。レイアウトは、<code>LoggingEvent</code>のインスタンスを書式化して、文字列として返します。アペンダーによっては(<code>SocketAppender</code>など)、ロギングイベントを文字列に変換するのではなく、シリアライズすることがあります。つまり、アペンダーはレイアウトを持っていることもあるし、持っていないこともあるのです。
- </p>
-
- <h4>ステップ6. <code>LoggingEvent</code>の送信</h4>
-
- <p>完全に書式化されたロギングイベントは、それぞれのアペンダーの宛先に送信されます。
- </p>
-
- <p>このUMLのシーケンス図は、ここまでで紹介してきたステップ全体を概観するものです。図をクリックすればより大きなサイズの図を見ることができます。
- </p>
-
- <a href="underTheHood.html">
- <img src="images/chapters/architecture/underTheHoodSequence2_small.gif">
- </a>
-
-
- <h3 class="doAnchor" name="performance">性能</h3>
-
- <p>ロギングについてよく議論の的になる課題の一つとして、必要な計算コストがあります。そこそこの規模のアプリケーションであっても、数千に及ぶログ要求を生成することになるので、性能に関心があるのは当然です。開発中に私たちが一番多くの力と時間を費やしたのは、logback の性能を測定することと、性能を調整することでした。私たちがどれだけの労力を費やしてきたとしてもそれとは関係無く、利用者は次のような性能問題に注意しなければなりません。
- </p>
-
- <h4>問題1. ロギングが完全にオフになっているときの性能</h4>
-
- <p>ルートロガーのレベルに最高レベルの<code>Level.OFF</code>を設定すると、完全にロギングをオフにすることができます。完全にロギングをオフにすると、ロギング要求のコストはメソッド呼び出しと整数比較だけになります。3.2GHz の Pentium D のマシンの場合、通常ならそのコストは 20 マイクロ秒程度になります。
- </p>
-
- <p>しかし、メソッド呼び出しによっては隠れたパラメータ構築のコストが含まれます。例えば、ロガー<em>x</em>について次のように実装されていると</p>
-
- <pre class="prettyprint source">x.debug("Entry number: " + i + "is " + entry[i]);</pre>
-
- <p>パラメータ構築のコストが含まれることになります。つまり、整数<code>i</code>と<code>entry[i]</code>を文字列に変換するコストと、中間文字列を連結するコストです。これらのコストは、メッセージがログに出力されるかどうかは関係無くかかります。
- </p>
-
- <p>パラメータ構築のコストは、パラメータの数にもよりますが非常に高くなることがあります。パラメータ構築のコストを回避するため、SLF4Jのパラメータ化されたロギングを利用することができます。</p>
-
- <pre class="prettyprint source">x.debug("Entry number: {} is {}", i, entry[i]);</pre>
-
- <p>このやり方の場合パラメータ構築のコストは発生しません。前の<code>debug()</code>メソッドの呼び出し方に比べると、圧倒的に速くなります。メッセージが書式化されるのは、割り当てられたアペンダーにロギング要求が送信されるときだけだからです。また、メッセージを書式化するコンポーネントには、高度な最適化が行われています。
- </p>
-
- <p>そうはいっても、非常に範囲の狭いループ中にロギング式があると、呼び出し回数が非常におおくなります。性能が劣化する可能性があるため、何のメリットもありません。たとえロギングがオフになっていても、狭い範囲のループにロギング式が含まれていると、アプリケーションの動作が緩慢になってしまいます。それに、ロギングをオンにすると非常に大量の(そして役に立たない)出力が生じます。
- </p>
-
- <h4>問題2. ロギングをオンにした状態で、ロギングするかどうかを判定する場合の性能</h4>
-
- <p>logbackでは、ロガー階層を渡り歩く必要がありません。ロガーは、インスタンスが作成された時点で自分の有効レベル(ロガー自体のレベルと受け継いたレベルを考慮した結果)を知っています。親ロガーのレベルを変更すると、全ての子ロガーは変更通知を受け取ります。したがって、ロガーは祖先ロガーに問い合わせること無く、有効レベルに基いてロギング要求を受け付けるか拒否するかを瞬時に判断することができます。
- </p>
-
-
- <h4>問題3. 実際にロギングする(書式化と出力デバイスへの書き込み)</h4>
-
- <p>これは、ログ出力を書式化し、宛先へ送信するコストです。レイアウト(フォーマッター)の処理を出来る限り高速化するために、同じように過大な労力を費やしました。同じことがアペンダーにも当てはまります。ローカルマシン上のファイルにロギングするとき、実際のロギングのコストは9マイクロ秒から12マイクロ秒程度になりました。リモートサーバ上のデータベースにロギングするとき、これが数ミリ秒に跳ね上がります。
- </p>
-
- <p>logback は豊富な機能を備えていますが、設計上の第一目標は高速な実行速度であり、第二目標として挙げられていたのは信頼性だけでした。logback のコンポーネントは、性能改善のため何度も書き直されています。
- </p>
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/manual/configuration.html b/docs/manual/configuration.html
index f4e0502..ef4474b 100644
--- a/docs/manual/configuration.html
+++ b/docs/manual/configuration.html
@@ -30,10 +30,7 @@
</div>
<div id="content" class="chapter">
- <h1>Chapter 3: Logback configuration</h1>
-
- <a href="configuration_ja.html">和訳 (Japanese translation)</a>
-
+ <h1>Chapter 3: Logback configuration</h1>
<div class="quote">
<p><em>In symbols one observes an advantage in discovery which
@@ -101,21 +98,7 @@
classpath</a>..</p>
</li>
- <li><p>If no such file is found, <a
- href="http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html">
- service-provider loading facility</a> (introduced in JDK 1.6) is
- used to resolve the implementation of <a
- href="../xref/ch/qos/logback/classic/spi/Configurator.html">
- <code>com.qos.logback.classic.spi.Configurator</code></a>
- interface by looking up the file
- <em>META-INF\services\ch.qos.logback.classic.spi.Configurator</em>
- in the class path. Its contents should specify the fully
- qualified class name of the desired <code>Configurator</code>
- implementation.
- </p>
- </li>
-
- <li><p>If none of the above succeeds, logback configures itself
+ <li><p>If neither file is found, logback configures itself
automatically using the <a
href="../xref/ch/qos/logback/classic/BasicConfigurator.html"><code>BasicConfigurator</code></a>
which will cause logging output to be directed to the console.
@@ -124,28 +107,21 @@
</ol>
- <p>The last step is meant as last-ditch effort to provide a
- default (but very basic) logging functionality in the absence of a
+ <p>The fourth and last step is meant to provide a default (but
+ very basic) logging functionality in the absence of a
configuration file.
</p>
<p>If you are using Maven and if you place the
- <em>logback-test.xml</em> under the <em>src/test/resources</em>
- folder, Maven will ensure that it won't be included in the
- artifact produced. Thus, you can use a different configuration
- file, namely <em>logback-test.xml</em> during testing, and another
- file, namely, <em>logback.xml</em>, in production.
+ <em>logback-test.xml</em> under the
+ <em>src/test/resources</em> folder, Maven will ensure that it
+ won't be included in the artifact produced. Thus, you can use a
+ different configuration file, namely <em>logback-test.xml</em>
+ during testing, and another file, namely, <em>logback.xml</em>, in
+ production. The same principle applies by analogy for Ant.
</p>
- <p><span class="label">Fast start-up</span> It takes about 100
- miliseconds for Joran to parse a given logback configuration
- file. To shave off those miliseconds at aplication start up, you
- can use the service-provider loading facility (item 4 above) to
- load your own custom <code>Configurator</code> class with <a
- href="../xref/ch/qos/logback/classic/BasicConfigurator.html">BasicConfigrator</a>
- serving as a good starting point.</p>
-
<h3 class="doAnchor" name="automaticConf">Automatically
configuring logback</h3>
@@ -258,7 +234,7 @@ public class Foo {
</p>
<p class="example">Example: Basic configuration file
- (logback-examples/src/main/resources/chapters/configuration/sample0.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/sample0.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sample0');">View as .groovy</span>
@@ -308,13 +284,13 @@ public class Foo {
<pre class="prettyprint lang-java source">
-public static void main(String[] args) {
- // assume SLF4J is bound to logback in the current environment
- <b>LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
- // print logback's internal status
- <b>StatusPrinter.print(lc);</b>
- ...
-}</pre>
+ public static void main(String[] args) {
+ // assume SLF4J is bound to logback in the current environment
+ <b>LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
+ // print logback's internal status
+ <b>StatusPrinter.print(lc);</b>
+ ...
+ }</pre>
<p>If everything goes well, you should see the following output on the console</p>
@@ -337,13 +313,6 @@ public static void main(String[] args) {
which allow convenient access to logback's internal state.
</p>
- <h4 class="doAnchor" name="dumpingStatusData">Status data</h4>
-
- <p class="highlight">Enabling output of status data usually goes a
- long way in the diagnosis of issues with logback. As such, it is
- highly recommended and should be considered as a recourse of
- <b>first</b> resort.</p>
-
<p>Instead of invoking <code>StatusPrinter</code> programmatically
from your code, you can instruct the configuration file to dump
status data, even in the absence of errors. To achieve this, you
@@ -357,9 +326,10 @@ public static void main(String[] args) {
<code>DEBUG</code>.)
</p>
+
<p class="example">Example: Basic configuration file using debug
mode
- (logback-examples/src/main/resources/chapters/configuration/sample1.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/sample1.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sample1');">View as .groovy</span>
<pre id="sample1" class="prettyprint source">
@@ -378,7 +348,7 @@ public static void main(String[] args) {
</root>
</configuration></pre>
- <p>Setting <code>debug="true"</code> within the
+ <p>Setting the <code>debug</code> attribute within the
<configuration> element will output status information,
assuming that:
</p>
@@ -401,7 +371,6 @@ public static void main(String[] args) {
every case.</p>
-
<p><span class="label">Forcing status output</span> In the absence
of status messages, tracking down a rogue <em>logback.xml</em>
configuration file can be difficult, especially in production where
@@ -414,29 +383,6 @@ public static void main(String[] args) {
generated in case of errors.
</p>
- <p>By the way, setting <code>debug="true"</code> is strictly
- equivalent to installing an
- <code>OnConsoleStatusListener</code>. Status listeners are
- disccussed further below. The installation of
- <code>OnConsoleStatusListener</code> is shown next. </p>
-
- <p class="example">Example: Registering a status listener
- (logback-examples/src/main/resources/chapters/configuration/onConsoleStatusListener.xml)</p>
- <span class="asGroovy" onclick="return asGroovy('onConsoleStatusListener');">View as .groovy</span>
- <pre id="onConsoleStatusListener" class="prettyprint source"><configuration>
- <b><statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /></b>
-
- ... the rest of the configuration file
-</configuration></pre>
-
-
- <p>Enabling output of status data, either via the debug attribute
- or equivalently by installing <code>OnConsoleStatusListener</code>,
- will go a long way in helping you diagnose logback issues. As such,
- enabling logback status data is very highly recommended and should
- be considered as a recourse of <b>first</b> resort.
- </p>
-
<h3 class="doAnchor" name="configFileProperty">Specifying the
location of the default configuration file as a system
property</h3>
@@ -475,7 +421,7 @@ public static void main(String[] args) {
<p class="example">Example: Scanning for changes in configuration
file and automatic re-configuration
- (logback-examples/src/main/resources/chapters/configuration/scan1.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/scan1.xml)</p>
<span class="asGroovy" onclick="return asGroovy('scan1');">View as .groovy</span>
<pre id="scan1" class="prettyprint source">
@@ -492,7 +438,7 @@ public static void main(String[] args) {
example:</p>
<p class="example">Example: Specifying a different scanning period
- (logback-examples/src/main/resources/chapters/configuration/scan2.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/scan2.xml)</p>
<span class="asGroovy" onclick="return asGroovy('scan2');">View as .groovy</span>
<pre id="scan2" class="prettyprint source">
<configuration scan="true" <b>scanPeriod="30 seconds"</b> >
@@ -543,55 +489,6 @@ public static void main(String[] args) {
</p>
- <h4 class="doAnchor" name="packagingData">Enabling packaging data in stack traces</h4>
-
- <p class="highlight">While useful, packaging data is expensive to
- compute, especially in applications with frequent exceptions.</p>
-
- <p><span class="label notice">NOTE</span> As of version 1.1.4,
- packaging data is disabled by default. </p>
-
- <p>If instructed to do so, logback can include packaging data for
- each line of the stack trace lines it outputs. Packaging data
- consists of the name and version of the jar file whence the class
- of the stack trace line originated. Packaging data can be very
- useful in identifying software versioning issues. However, it is
- rather expensive to compute, especially in application where
- exceptions are thrown frequently. Here is a sample output:</p>
-
- <pre>14:28:48.835 [btpool0-7] INFO c.q.l.demo.prime.PrimeAction - 99 is not a valid value
-java.lang.Exception: 99 is invalid
- at ch.qos.logback.demo.prime.PrimeAction.execute(PrimeAction.java:28) [classes/:na]
- at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431) <b>[struts-1.2.9.jar:1.2.9]</b>
- at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236) [struts-1.2.9.jar:1.2.9]
- at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432) [struts-1.2.9.jar:1.2.9]
- at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) <b>[servlet-api-2.5-6.1.12.jar:6.1.12]</b>
- at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502) [jetty-6.1.12.jar:6.1.12]
- at ch.qos.logback.demo.UserServletFilter.doFilter(UserServletFilter.java:44) [classes/:na]
- at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115) <b>[jetty-6.1.12.jar:6.1.12]</b>
- at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:361) [jetty-6.1.12.jar:6.1.12]
- at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417) [jetty-6.1.12.jar:6.1.12]
- at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230) [jetty-6.1.12.jar:6.1.12]</pre>
-
-
- <p>Packaging data is disabled by default but can be enabled by
- configuration:</p>
-
-<pre class="prettyprint source">
-<configuration <span class="big bold">packagingData="true"</span>>
- ...
-</configuration></pre>
-
- <p>Alternatively, packaging data can be enabled/disabled
- programmatically by invoking the <a
- href="../apidocs/ch/qos/logback/classic/LoggerContext.html#setPackagingDataEnabled(boolean)">setPackagingDataEnabled(boolean)</a>
- method in <code>LoggerContext</code>, as shown next:</p>
-
-
-<pre class="prettyprint lang-java source">
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- <b>lc.setPackagingDataEnabled(true);</b>
-</pre>
<h3 class="doAnchor" name="joranDirectly">Invoking
<code>JoranConfigurator</code> directly</h3>
@@ -738,7 +635,7 @@ public class MyApp3 {
within a configuration file. Here is an example.</p>
<p class="example">Example: Registering a status listener
- (logback-examples/src/main/resources/chapters/configuration/onConsoleStatusListener.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml)</p>
<span class="asGroovy" onclick="return asGroovy('onConsoleStatusListener');">View as .groovy</span>
<pre id="onConsoleStatusListener" class="prettyprint source"><configuration>
@@ -796,35 +693,12 @@ import ch.qos.logback.classic.LoggerContext;
<b>LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
<b>loggerContext.stop();</b></pre>
- <p>In web-applications the above code could be invoked from within
- the <a
+ <p>In web-applications, such code would be invoked from within the
+ <a
href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html#contextDestroyed(javax.servlet.ServletContextEvent)">contextDestroyed</a>
method of <code>ServletContextListener</code> in order to stop
logback-classic and release resources.
- </p>
- <h4 class="doAnchor" name="shutdownHook">Stopping logback-classic
- via a shutdown hook</h4>
-
- <p>Installing a JVM shutdown hook is a convenient way for shutting
- down logback and releasing associated resources.
- </p>
-
-
- <pre class="prettyprint source"><configuration debug="true">
- <!-- in the absence of the class attribute, assume
- ch.qos.logback.core.hook.DelayingShutdownHook -->
- <b><shutdownHook/></b>
- ....
-</configuration></pre>
-
- <p>The default shutdown hook, namely <a
- href="../apidocs/ch/qos/logback/core/hook/DelayingShutdownHook.html">DelayingShutdownHook</a>,
- can delay shutdown by a user specified duration. Note that you may
- install a shutdown hook of your own making by setting the <span
- class="attr">class</span> attribute to correspond to your shutdown
- hook's class name.</p>.
-
<h2 class="doAnchor" name="syntax">Configuration file syntax</h2>
<p>As you have seen thus far in the manual with plenty of examples
@@ -847,7 +721,7 @@ import ch.qos.logback.classic.LoggerContext;
possible to specify the allowed syntax with a DTD file or an XML
schema. Nevertheless, the very basic structure of the configuration
file can be described as, <code><configuration></code> element,
- containing zero or more <code><appender></code> elements,
+ followed by zero or more <code><appender></code> elements,
followed by zero or more <code><logger></code> elements,
followed by at most one <code><root></code> element. The
following diagram illustrates this basic structure.</p>
@@ -963,7 +837,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Setting the level of a logger
- (logback-examples/src/main/resources/chapters/configuration/sample2.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/sample2.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sample2');">View as .groovy</span>
<pre id="sample2" class="prettyprint source"><configuration>
@@ -1004,7 +878,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Setting the level of multiple loggers
- (logback-examples/src/main/resources/chapters/configuration/sample3.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/sample3.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sample3');">View as .groovy</span>
<pre id="sample3" class="source prettyprint"><configuration>
@@ -1086,7 +960,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Logger level sample
- (logback-examples/src/main/resources/chapters/configuration/sample4.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/sample4.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sample4');">View as .groovy</span>
<pre id="sample4" class="prettyprint source"><configuration>
@@ -1211,7 +1085,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Multiple loggers
- (logback-examples/src/main/resources/chapters/configuration/multiple.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/multiple.xml)</p>
<span class="asGroovy" onclick="return asGroovy('multiple');">View as .groovy</span>
<pre id="multiple" class="prettyprint source"><configuration>
@@ -1266,7 +1140,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Duplicate appender
- (logback-examples/src/main/resources/chapters/configuration/duplicate.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/duplicate.xml)</p>
<span class="asGroovy" onclick="return asGroovy('duplicate');">View as .groovy</span>
<pre id="duplicate" class="prettyprint source"><configuration>
@@ -1316,7 +1190,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Multiple appender
- (logback-examples/src/main/resources/chapters/configuration/restricted.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/restricted.xml)</p>
<span class="asGroovy" onclick="return asGroovy('restricted');">View as .groovy</span>
<pre id="restricted" class="prettyprint source"><configuration>
@@ -1359,7 +1233,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Additivity flag
- (logback-examples/src/main/resources/chapters/configuration/additivityFlag.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/additivityFlag.xml)</p>
<span class="asGroovy" onclick="return asGroovy('additivityFlag');">View as .groovy</span>
<pre id="additivityFlag" class="prettyprint source"><configuration>
@@ -1415,7 +1289,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Set the context name and display it
- (logback-examples/src/main/resources/chapters/configuration/contextName.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/contextName.xml)</p>
<span class="asGroovy" onclick="return asGroovy('contextName');">View as .groovy</span>
<pre id="contextName" class="prettyprint source"><configuration>
@@ -1448,11 +1322,10 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p>As in many scripting languages, logback configuration files
- support definition and substitution of variables. Variables have a
- <a href="#scopes">scope</a> (see below). Moreover, variables can be
+ support definition and substitution of variables. Variables can be
defined within the configuration file itself, in an external file,
in an external resource or even computed and <a
- href="#definingPropsOnTheFly">defined on the fly</a>.
+ href="#definingPropsOnTheFly">defined on the fly</a>.
</p>
<p class="highlight">Variable substitution can occur at any point in
@@ -1467,7 +1340,7 @@ import ch.qos.logback.classic.LoggerContext;
value held by the <em>aName</em> property.
</p>
-
+ <p>Variables have a <a href="#scopes">scope</a> (see below).</p>
<p>As they often come in handy, the HOSTNAME and CONTEXT_NAME
variables are automatically defined and have context scope.</p>
@@ -1487,7 +1360,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Simple Variable substitution
- (logback-examples/src/main/resources/chapters/configuration/variableSubstitution1.xml)
+ (logback-examples/src/main/java/chapters/configuration/variableSubstitution1.xml)
</p>
<span class="asGroovy" onclick="return asGroovy('variableSubstitution1');">View as .groovy</span>
@@ -1516,7 +1389,7 @@ import ch.qos.logback.classic.LoggerContext;
<p class="source">java -DUSER_HOME="/home/sebastien" MyApp2</p>
<p class="example">Example: System Variable substitution
- (logback-examples/src/main/resources/chapters/configuration/variableSubstitution2.xml)
+ (logback-examples/src/main/java/chapters/configuration/variableSubstitution2.xml)
</p>
<span class="asGroovy" onclick="return asGroovy('variableSubstitution2');">View as .groovy</span>
<pre id="variableSubstitution2" class="prettyprint source"><configuration>
@@ -1541,7 +1414,7 @@ import ch.qos.logback.classic.LoggerContext;
<p class="example">Example: Variable substitution using a
separate file
- (logback-examples/src/main/resources/chapters/configuration/variableSubstitution3.xml)
+ (logback-examples/src/main/java/chapters/configuration/variableSubstitution3.xml)
</p>
<span class="asGroovy" onclick="return asGroovy('variableSubstitution3');">View as .groovy</span>
<pre id="variableSubstitution3" class="prettyprint source"><configuration>
@@ -1567,7 +1440,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<em>Example: Variable file
- (logback-examples/src/main/resources/chapters/configuration/variables1.properties)</em>
+ (logback-examples/src/main/java/chapters/configuration/variables1.properties)</em>
<pre class="source">USER_HOME=/home/sebastien</pre>
@@ -1641,7 +1514,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: A variable defined in "context" scope
- (logback-examples/src/main/resources/chapters/configuration/contextScopedVariable.xml)
+ (logback-examples/src/main/java/chapters/configuration/contextScopedVariable.xml)
</p>
<span class="asGroovy" onclick="return
@@ -1695,7 +1568,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Nested variable references
- (logback-examples/src/main/resources/chapters/configuration/variables2.properties)</p>
+ (logback-examples/src/main/java/chapters/configuration/variables2.properties)</p>
<pre class="source">USER_HOME=/home/sebastien
fileName=myApp.log
@@ -1708,7 +1581,7 @@ fileName=myApp.log
<em>Example: Variable substitution using
a separate file
- (logback-examples/src/main/resources/chapters/configuration/variableSubstitution4.xml)</em>
+ (logback-examples/src/main/java/chapters/configuration/variableSubstitution4.xml)</em>
<pre class="prettyprint source"><configuration>
@@ -1944,7 +1817,7 @@ fileName=myApp.log
<p class="example">Example: Insert as properties env-entries
obtained via JNDI
- (logback-examples/src/main/resources/chapters/configuration/insertFromJNDI.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/insertFromJNDI.xml)</p>
<pre class="prettyprint source"><configuration>
<b><insertFromJNDI env-entry-name="java:comp/env/appName" as="<span class="green">appName"</span> /></b>
@@ -1977,7 +1850,7 @@ fileName=myApp.log
</p>
<p class="example">Example: File include
- (logback-examples/src/main/resources/chapters/configuration/containingConfig.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/containingConfig.xml)</p>
<pre class="prettyprint source"><configuration>
<b><include file="src/main/java/chapters/configuration/includedConfig.xml"/></b>
@@ -1994,7 +1867,7 @@ fileName=myApp.log
</p>
<p class="example">Example: File include
- (logback-examples/src/main/resources/chapters/configuration/includedConfig.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/includedConfig.xml)</p>
<pre class="source"><b class="green big"><included></b>
<appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
@@ -2037,7 +1910,7 @@ fileName=myApp.log
<p>If it cannot find the file to be included, logback will complain
by printing a status message. In case the included file is
- optional, you can suppress the warning message by setting <span
+ optional, you can suppres the error message by setting <span
class="attr">optional</span> attribute to <code>true</code> in the
<code><include></code> element.</p>
@@ -2100,6 +1973,7 @@ fileName=myApp.log
</p>
+
<script src="../templates/footer.js" type="text/javascript"></script>
</div>
</body>
diff --git a/docs/manual/configuration_ja.html b/docs/manual/configuration_ja.html
deleted file mode 100644
index 9bde5c1..0000000
--- a/docs/manual/configuration_ja.html
+++ /dev/null
@@ -1,1273 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第3章 logbackの設定</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content" class="chapter">
-
- <h1>第3章 logbackの設定</h1>
-
- <div class="quote">
- <p><em>物事の本質を正確に表現するときは、記号を使うのが最も適している。また、記号によって表現されたものがあれば、思考に費やす労力が驚くほど軽減されるのだ。</em>
- </p>
- <p>—GOTTFRIED WILHELM LEIBNIZ</p>
- </div>
-
-
- <script src="../templates/creative.js" type="text/javascript"></script>
-
-
- <p>設定スクリプトの例を示しながら、logback の設定方法を説明していきます。logback は Joran という設定フレームワークを利用しています。Joran については<a href="./11-onJoran.html">後の章</a>で紹介します。
- </p>
-
-
- <h2 class="doAnchor" name="auto_configuration">logback の設定</h2>
-
- <p>アプリケーションコードにロギング要求を埋め込むには、かなりの計画と作業が必要です。調査したところ、だいたいコード全体の4%ほどがロギングのために使われていました。したがって、そこそこの規模のアプリケーションであっても、数千行のロギング行が含まれることになるのです。その数を考えれば、私たちにロギング式を管理するためのツールが必要となる理由が理解できるのではないでしょうか。
- </p>
-
- <p>logback はプログラム的に設定することもできるし、XML や Groovy で記述された設定スクリプトで設定することもできます。なお、log4jユーザーのために、<em>log4j.propertiesファイル</em>を<em>logback.xml</em>に変換する<a href="http://logback.qos.ch/translator/">PropertiesTranslator</a>を用意しています。
-
- </p>
-
- <p>さて、logback が設定するところを順番に見ていきましょう。</p>
-
- <ol>
- <li>
- <p>logback は<a href="./faq.html#configFileLocation">クラスパス</a>上で<em>logback.groovy</em>というファイルを探します。</p>
- </li>
-
- <li>
- <p>見つからなかったら、今度は<a href="./faq.html#configFileLocation">クラスパス</a>上で<em>logback-test.xml</em>というファイルを探します。</p>
- </li>
-
- <li><p>見つからなかったら、今度は<a href="./faq.html#configFileLocation">クラスパス</a>上で<em>logback.xml</em>というファイルを探します。</p>
- </li>
-
- <li><p>何も見つからなかったら、自動的に<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/BasicConfigurator.html"><code>BasicConfigurator</code></a>を使って設定します。ロギング出力は直接コンソールに出力されるようになります。
- </p>
- </li>
-
- </ol>
-
- <p>四番目のステップは、設定ファイルが見つからなかった場合デフォルトの(ごく基本的な)設定をする、ということです。
- </p>
-
-
- <p>もし Maven を使用しているなら、<em>src/test/resources</em> フォルダの下に <em>logback-test.xml</em>を置いている場合でも、それがアーティファクトに入り込まないことは Maven によって保証されます。したがって、テスト用と実際の環境用で、<em>logback-test.xml</em>と<em>logback.xml</em>を使い分けることができます。Antでも原則的に同じことができます。
- </p>
-
-
- <h3 class="doAnchor" name="automaticConf">logback の自動設定</h3>
-
- <p>logback を設定する一番簡単な方法は、デフォルト設定を使わせることです。仮に<code>MyApp1</code>というアプリケーションがあるつもりで、これがどのように行われるのか詳しく見てみましょう。
- </p>
-
- <p class="example">例:<code>BasicConfigurator</code>の使用例(<a href="http://logback.qos.ch/xref/chapters/configuration/MyApp1.html">logback-examples/src/main/java/chapters/configuration/MyApp1.java</a>)</p>
-
- <pre class="prettyprint source">package manual.configuration;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MyApp1 {
- final static Logger logger = LoggerFactory.getLogger(MyApp1.class);
-
- public static void main(String[] args) {
- logger.info("Entering application.");
-
- Foo foo = new Foo();
- foo.doIt();
- logger.info("Exiting application.");
- }
-}</pre>
-
- <p>このクラスでは、ロガーを静的クラスメンバ変数として定義しています。その後、<code>Foo</code>クラスのオブジェクトを生成します。<code>Foo</code>クラスの定義は次のとおりです。</p>
-
- <p class="example">例:ロギングするクラスの例(<a href="http://logback.qos.ch/xref/chapters/configuration/Foo.html">logback-examples/src/main/java/chapters/configuration/Foo.java</a>)
- </p>
-
- <pre class="prettyprint source">package chapters.configuration;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class Foo {
- static final Logger logger = LoggerFactory.getLogger(Foo.class);
-
- public void doIt() {
- logger.debug("Did it again!");
- }
-}</pre>
-
-
- <p>この章で紹介しているサンプルプログラムを実行するには、クラスパスに所定のjarファイルを置いておかなければなりません。詳しくは<a href="http://logback.qos.ch/setup.html">セットアップ</a>の説明をを参照してください。
- </p>
-
- <p><em>logback-test.xml</em>も<em>logback.xml</em>も無い場合、logback は<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/BasicConfigurator.html"><code>BasicConfigurator</code></a>によって最小限の設定を行います。最小限の設定としてやることは、ルートロガーに<code>ConsoleAppender</code>を割り当てることだけです。出力は<code>PatternLayoutEncoder</code>によって書式化されます。<code>PatternLayoutEncoder</code>には、<em>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</em>という書式化パターンが設定されています。また、ルートロガーにはデフォルトで<code>DEBUG</code>レベルが割り当てられます。
- </p>
-
- <p><em>java chapters.configuration.MyApp1</em>を実行すると次のような出力が得られます。</p>
-
- <p class="source">16:06:09.031 [main] INFO chapters.configuration.MyApp1 - Entering application.
-16:06:09.046 [main] DEBUG chapters.configuration.Foo - Did it again!
-16:06:09.046 [main] INFO chapters.configuration.MyApp1 - Exiting application.</p>
-
-
- <p class="highlight">(あるとしたら)logback を設定するコード以外に、クライアントコードは一切logbackに依存しません。ロギングフレームワークとしてlogbackを使用するアプリケーションがコンパイル時に依存するのはSLF4Jであって、logbackではありません。
- </p>
-
- <p><code>MyApp1</code>アプリケーションとlogbackのリンクは、アプリケーションが呼び出した<code>org.slf4j.LoggerFactory</code>クラスと<code>org.slf4j.Logger</code>クラスによって行われます。これらのクラスは、使用するロガーを(クラスローダーから?)取得し、つなぎあわせます。<code>Foo</code>クラスからlogbackへの依存は、<code>org.slf4j.LoggerFactory</code>と<code>org.slf4j.Logger</code>のimportを介した間接的なものであることに注意しましょう。SLF4Jはあらゆるロギングフレームワークから利用するための抽象層を備えています。おかで、ほとんどのコードをあるロギングフレームワークから別のロギングフレームワークに移行するのがとても簡単になっています。
- </p>
-
- <h3><em>logback-test.xml</em>または<em>logback.xml</em>による自動設定</h3>
-
- <p>前述したとおり、logback はクラスパス上で<em>logback-test.xml</em>や<em>logback.xml</em>を探して自分を設定しようとします。次に示す設定ファイルは、<code>BasicConfigurator</code>によって行われるのとまったく同じ内容の設定です。
- </p>
-
- <p class="example">例:基本的な設定ファイル(<a href="http://logback.qos.ch/xref/chapters/configuration/sample0.xml">logback-examples/src/main/java/chapters/configuration/sample0.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('sample0');">Groovyで見る</span>
-
-
- <pre id="sample0" class="prettyprint source"><configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <!-- encoders are assigned the type
- ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>ファイル名を<em>sample0.xml</em>から<em>logback.xml</em>(または<em>logback-test.xml</em>)に変更して、クラスパスに含まれるフォルダに置きましょう。そして<em>MyApp1</em>アプリケーションを実行すると、前の実行例と同じ出力結果が得られるはずです。</p>
-
- <h4 class="doAnchor" name="automaticStatusPrinting">警告やエラーが発生した際、ステータスメッセージを自動的に出力する</h4>
-
- <p class="highlight">設定ファイルを解析している間に警告やエラーが発生した場合、logback は内部状態を表すメッセージを自動的にコンソールに出力します。</p>
-
- <p>出力が重複することを避けるため、利用者が明示的にステータスリスナーを登録していた場合(後で例を示します)ステータスの自動出力は無効になります。</p>
-
- <p>警告やエラーが起きていなくても logback の内部状態を出力させたければ、<code>StatusPrinter</code>クラスの<code>print()</code>メソッドを使えばよいです。次の<em>MyApp2</em>アプリケーションは、内部状態を出力するためのコードが二行追加されていることを除いて<em>MyApp1</em>とまったく同じです。</p>
-
- <p class="example">例:logbackの内部状態を出力する(<a href="http://logback.qos.ch/xref/chapters/configuration/MyApp2.html">logback-examples/src/main/java/chapters/configuration/MyApp2.java</a>)</p>
-
-
-<pre class="prettyprint lang-java source">
- public static void main(String[] args) {
- // SLF4J が logback を使うようになっていると想定
- <b>LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
- // logback の内部状態を出力
- <b>StatusPrinter.print(lc);</b>
- ...
- }</pre>
-
- <p>何も問題が無ければ、コンソールに次のような出力が表示されます。</p>
-
- <div class="source longline"><pre>17:44:58,578 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml]
-17:44:58,671 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
-17:44:58,671 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
-17:44:58,687 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
-17:44:58,812 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Popping appender named [STDOUT] from the object stack
-17:44:58,812 |-INFO in ch.qos.logback.classic.joran.action.LevelAction - root level set to DEBUG
-17:44:58,812 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[root]
-
-17:44:58.828 [main] INFO chapters.configuration.MyApp2 - Entering application.
-17:44:58.828 [main] DEBUG chapters.configuration.Foo - Did it again!
-17:44:58.828 [main] INFO chapters.configuration.MyApp2 - Exiting application.
-</pre></div>
-
- <p>出力結果の最後の方に、前の例で出力されたものと同じ行があることが分かるでしょう。logback の内部メッセージには気をつけるようにしてください。<code>Status</code>オブジェクトを使うと内部状態に簡単にアクセスできます。
- </p>
-
- <p>コード中で<code>StatusPrinter</code>をプログラム的に呼び出す代わりに、設定ファイルで内部ステータスを出力するように指定することができます。警告やエラーが起きなくてもです。そのためには<em>configuration</em>要素の<span class="attr">debug</span>属性を設定します。この要素はXML形式の設定ファイルにおける最上位要素です。後で例を示します。<span class="attr">debug</span>属性はステータス情報にだけしか影響しないことは覚えておいてください。繰り返しますが、logback の他の設定には<em>影響しません</em>。ロガーレベルについても同様です。(たとえそうなっていて欲しくても、ルートロガーのログレベルは<code>DEBUG</code>に<em>なりません</em>。)
- </p>
-
-
- <p class="example">例:基本的な設定ファイルをデバッグモードにする(<a href="http://logback.qos.ch/xref/chapters/configuration/sample1.xml">logbackexamples/src/main/java/chapters/configuration/sample1.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('sample1');">Groovyで見る</span>
-
- <pre id="sample1" class="prettyprint source">
-<configuration <span class="big bold">debug="true"</span>>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <!-- encoders are by default assigned the type
- ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>configuration 要素の<code>debug</code>属性が設定されていると、次のような内部ステータスが出力されます。</p>
- <ol>
- <li>設定ファイルが見つかったかどうか</li>
- <li>設定ファイルのXML文法が適格かどうか</li>
- </ol>
-
- <p>これらのいずれかの条件が満たされなかった場合、設定ファイルを読み込むことができないので、Joran には<span class="attr">debug</span>属性を理解することができません。見つかった設定ファイルがXMLとして不適格な場合、logback はエラーと判断し、自動的に内部状態をコンソールに出力します。ですが、設定ファイルが見つからなかった場合、logback は内部状態を自動的に出力することはありません。それだけではエラーと見做すには不十分だからです。<a href="http://logback.qos.ch/xref/chapters/configuration/MyApp2.html"><em>MyApp2</em></a>アプリケーションの例で示したように、<code>StatusPrinter.print()</code>をプログラム的に呼び出していれば、どんな場合でも内部ステータス情報を確実に出力するようになります。</p>
-
-
- <p>ステータスメッセージが無くても<span class="label">強制的に</span>内部ステータス情報を出力させていると、不正な<em>logback.xml</em>がどこにあるのか突き止めるのが難しくなります。アプリケーションのソースコードを簡単に変更できない商用環境においては特にそうです。不正な設定ファイルの場所を見つけやすくするには、システムプロパティの"logback.statusListenerClass"(<a href="./03-configuration.html#logback.statusLC">すぐ後で説明します</a>)に<code>StatusListener</code>を指定するとよいでしょう。そうすれば、強制的にステータスメッセージを出力させることができます。"logback.statusListenerClass" システムプロパティを使うと、エラーが発生したときに自動的に出力されるメッセージを抑止することもできます。
- </p>
-
- <h3 class="doAnchor" name="configFileProperty">システムプロパティでデフォルトの設定ファイルの場所を指定する</h3>
-
- <p>システムプロパティの<code>"logback.configurationFile"</code>を使えば、デフォルトの設定ファイルの場所を指定することができます。このプロパティにはURL形式の値を指定します。クラスパス上のリソースやアプリケーションの外部のファイルを指定することができます。
- </p>
-
- <p class="source">java <b>-Dlogback.configurationFile=/path/to/config.xml</b> chapters.configuration.MyApp1</p>
-
- <p>ファイルの拡張子は ".xml" か ".groovy" でなければならないので注意してください。他の拡張子の場合は無視します。<a href="./03-configuration.html#logback.statusLC">ステータスリスナーを明示的に登録</a>しておくと、設定ファイルの場所を突き止めるのに役立つでしょう。</p>
-
-
- <h3 class="doAnchor" name="autoScan">設定ファイルが変更されたら自動的に再読み込みする</h3>
-
- <p class="highlight">logback-classic は設定ファイルの変更を監視することができます。そして、なんらか変更があった場合は自動的に再読み込みすることができます。</p>
-
- <p><code>configuration</code>要素の<span class="attr">scan</span>属性を設定すると、設定ファイルの監視と自動的な再読み込みができるようになります。
-
- </p>
-
- <p class="example">例:設定ファイルの変更の監視と自動的な再読み込み(<a href="http://logback.qos.ch/xref/chapters/configuration/scan1.xml">logback-examples/src/main/java/chapters/configuration/scan1.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('scan1');">Groovyで見る</span>
-<pre id="scan1" class="prettyprint source">
-<configuration <b>scan="true"</b>>
- ...
-</configuration> </pre>
-
-
- <p>デフォルトでは、設定ファイルを一分毎に監視します。<code>configuration</code>要素の<span class="attr">scanPeriod</span>属性に、監視周期を設定することができます。設定値はミリ秒、秒、分または時間単位で指定することができます。以下に例を示します。</p>
-
- <p class="example">例:デフォルトとは異なる監視周期を指定する(<a href="http://logback.qos.ch/xref/chapters/configuration/scan2.xml">logback-examples/src/main/java/chapters/configuration/scan2.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('scan2');">Groovyで見る</span>
- <pre id="scan2" class="prettyprint source">
-<configuration scan="true" <b>scanPeriod="30 seconds"</b> >
- ...
-</configuration> </pre>
-
- <p>時間の単位を指定しなかった場合ミリ秒として扱われますが、たいていの場合不適切だと思いますので<span class="label">注意</span>してください。時間単位を指定することを忘れないでください。
- </p>
-
- <p>舞台裏で起きていることを説明しましょう。scan 属性に true を指定すると、<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.html">ReconfigureOnChangeFilter</a>という<code>TurboFilter</code>の派生クラスがインストールされます。TurboFiltersについては<a href="./filters.html#TurboFilter">後の章</a> で説明します。設定ファイルのスキャンは「内部スレッド」で行います。ロガーの出力メソッドが呼び出されるときは常にスキャンされるということです。(訳注:正確には、出力メソッドが呼び出されるたびにフィルタが評価されるので、その都度 logback のコンテキストに指定された ThreadExecutor にファイルをスキャンするタスクが投入されます。そして、ThreadExecutor の管理するスレッドによって実行されます。 [...]
- </p>
-
- <p class="highlight">設定ファイルを変更すると、何回かロギング処理を実行した後で、かつ、監視周期に基いて決定した遅延時間が経過したら、自動的に再読み込みします。
- </p>
-
- <p><em>どんな</em>ロガーであれ、ロガーレベルがどうであれ、出力メソッドを呼び出すと<code>ReconfigureOnChangeFilter</code>も呼び出すことになるので、間違いなく致命的な性能影響があります。したがって、監視周期が経過していようともいまいとも、とてもコストの高い処理になります。性能を改善するため、実際に<code>ReconfigureOnChangeFilter</code>が有効になるのは、<em>N</em>回のロギングごとに一回だけです。あなたのアプリケーションがどれくらいの頻度でロギングするのかにもよるのですが、logback は<em>N</em>の値を実行している環境に合わせて調整します。Nのデフォルト値は16です。CPUを占有するアプリケーションの場合最大で2^16(=65536)にまで増えます。
- </p>
-
- <p>簡単に言うとこうなります。設定ファイルを変更すると、何回かロギング処理を実行した後で、かつ、監視周期に基いて決定した遅延時間が経過したら、自動的に再読み込みします。
- </p>
-
-
-
- <h3 class="doAnchor" name="joranDirectly"><code>JoranConfigurator</code>を直接呼び出す</h3>
-
- <p>logback は、logbac-core に含まれる Joran という設定用ライブラリを利用しています。logback のデフォルトの設定の仕組みでは、<code>JoranConfigurator</code>を呼び出して、クラスパス上で見つけたデフォルトの設定ファイルを渡すようになっています。何か理由があってデフォルトの設定の仕組みを上書きしたい場合、<code>JoranConfigurator</code>を直接呼び出すことができます。次に示す<em>MyApp3</em>アプリケーションでは、設定ファイルを引数としてJoranConfiguratorを呼び出しています。</p>
-
- <p class="example">例:<code>JoranConfigurator</code>を直接呼び出す(<a href="http://logback.qos.ch/xref/chapters/configuration/MyApp3.html">logback-examples/src/mian/java/chapters/configuration/MyApp3.java</a>)</p>
-
-<pre class="prettyprint source">package chapters.configuration;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.core.joran.spi.JoranException;
-import ch.qos.logback.core.util.StatusPrinter;
-
-public class MyApp3 {
- final static Logger logger = LoggerFactory.getLogger(MyApp3.class);
-
- public static void main(String[] args) {
- // SLF4J が logback を使うようになっていると想定
- <b>LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
-
- <b>try {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(context);
- // デフォルト設定を取り消すために context.reset() を呼び出す
- // 複数の設定を積み重ねる場合は呼ばないようにする
- context.reset();
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- // StatusPrinter will handle this
- }
- StatusPrinter.printInCaseOfErrorsOrWarnings(context);</b>
-
- logger.info("Entering application.");
-
- Foo foo = new Foo();
- foo.doIt();
- logger.info("Exiting application.");
- }
-}</pre>
-
- <p>アプリケーションは、新しく生成した<code>JoranConfigurator</code>を、有効な<code>LoggerContext</code>に設定してから、ロガーコンテキストを初期化します。そして、アプリケーションの引数として渡された設定ファイルを使ってconfiguratorに設定させています。警告やエラーが発生した場合、内部ステータスが出力されます。複数の設定を積み重ねる場合は、<code>context.reset()</code>を呼び出さないようにしなければなりません。</p>
-
- <h3 class="doAnchor" name="viewingStatusMessages">ステータスメッセージの内容</h3>
-
- <p>logback は <code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/status/StatusManager.html">StatusManager</a></code>オブジェクトに内部ステータス情報を蓄積しています。このオブジェクトは<code>LoggerContext</code>からアクセスすることができます。
- </p>
-
- <p><code>StatusManager</code>があれば、logbackのコンテキストに関連付けられた全てのステータス情報にアクセスすることができます。メモリ使用量を妥当なレベルで抑えるため、<code>StatusManager</code>のデフォルト実装ではステータスメッセージを先頭と末尾に分けて格納しています。先頭には最初の<em>H</em>個のステータスメッセージを格納し、末尾には最後の<em>T</em>個のステータスメッセージを格納します。今のところ<em>H</em>も<em>T</em>も150になっていますが、将来的にこの値は変更されるかもしれません。</p>
-
- <p>logback-classic の配布物には、ViewStatusMessagesServlet というサーブレットが含まれています。このサーブレットは、<code>LoggerContext</code>に関連付けられた<code>StatusManager</code>の持つステータスメッセージを、HTML の表で描画します。出力サンプルは次のようになります。
- </p>
-
- <a href="./lbClassicStatus.jpg">
- <img src="images/chapters/configuration/lbClassicStatus.jpg" alt="クリックすると拡大します" width="90%">
- </a>
-
- <p>Webアプリケーションにこのサーブレットを追加するには、<em>WEB-INF/web.xml</em>に次の行を追加します。</p>
-
- <pre class="prettyprint source"> <servlet>
- <servlet-name>ViewStatusMessages</servlet-name>
- <servlet-class>ch.qos.logback.classic.ViewStatusMessagesServlet</servlet-class>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>ViewStatusMessages</servlet-name>
- <url-pattern>/lbClassicStatus</url-pattern>
- </servlet-mapping></pre>
-
- <p><code>ViewStatusMessages</code>サーブレットにアクセスするためのURLは次のようになります。
-<code>http://host/yourWebapp/lbClassicStatus</code>
- </p>
-
- <h3 class="doAnchor" name="statusListener">ステータスメッセージの待ち受け</h3>
-
- <p><code>StatusManager</code>に<code>StatusListener</code>を割り当てて、ステータスメッセージを受け取った応答として直ちに何らかの処理を実行させることができます。ただし、ステータスメッセージを受け取ることができるのは logback の設定が完了した後になります。ステータスリスナーを登録しておくと、人間が介入しなくてもlogbackの内部状態を監視できるようになるので便利です。
- </p>
-
- <p>logback の配布物には<code>StatusListener</code>を実装した<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/status/OnConsoleStatusListener.html">OnConsoleStatusListener</a></code>というクラスが含まれています。名前が表すとおり、<em>到着した</em>ステータスメッセージを全てコンソールに出力します。
- </p>
-
- <p>これは、StatusManager に<code>OnConsoleStatusListenerを登録する<a href="http://logback.qos.ch/xref/chapters/configuration/AddStatusListenerApp.html">サンプルコード</a>です。</code>
- </p>
-
- <pre class="prettyprint source"> LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- StatusManager statusManager = lc.getStatusManager();
- OnConsoleStatusListener onConsoleListener = new OnConsoleStatusListener();
- statusManager.add(onConsoleListener);</pre>
-
- <p>ステータスリスナーは、登録された後に発生したステータスメッセージだけしか受け取らないので気をつけてください。それより前のステータスメッセージは受け取りません。ですので、ステータスリスナーの登録を設定ファイルの一番最初の方に置いて、他のディレクティブよりも先に評価されるようにするとよいでしょう。</p>
-
- <p>また、これは一つ以上のステータスリスナーを登録できるということでもあります。例を示します。</p>
-
- <p class="example">例:ステータスリスナーの登録(<a href="http://logback.qos.ch/xref/chapters/configuration/onConsoleStatusListener.xml">logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('onConsoleStatusListener');">Groovyで見る</span>
- <pre id="onConsoleStatusListener" class="prettyprint source"><configuration>
- <b><statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /></b>
-
- ... the rest of the configuration file
-</configuration></pre>
-
- <h3 class="doAnchor" name="logback.statusLC">システムプロパティ "logback.statusListenerClass"</h3>
-
- <p>ステータスリスナーを登録するには、システムプロパティの "logback.statusListenerClass" に、リスナークラス名を設定する方法もあります。例を示します。</p>
-
- <p class="source">java <b>-Dlogback.statusListenerClass</b>=ch.qos.logback.core.status.OnConsoleStatusListener ...</p>
-
- <p>logback の配布物にはいくつかのステータスリスナー実装が含まれています。<a href="http://logback.qos.ch/xref/ch/qos/logback/core/status/OnConsoleStatusListener.html">OnConsoleStatusListener</a> は、受け取ったステータスメッセージを、コンソール(例えばSystem.out)に出力します。<a href="http://logback.qos.ch/xref/ch/qos/logback/core/status/OnErrorConsoleStatusListener.html">OnErrorConsoleStatusListener</a> は、受け取ったステータスメッセージをSystem.errに出力します。<a href="http://logback.qos.ch/xref/ch/qos/logback/core/status/NopStatusListener.html">NopStatusListener</a>は、受け取っ [...]
-
-
- <p>設定の途中でステータスリスナーを登録したり、システムプロパティの"logback.statusListenerClass" でステータスリスナーを指定した場合は、<a href="./03-configuration.html#automaticStatusPrinting">メッセージステータスの自動出力(エラー発生時)</a>が無効になるので気をつけてください。つまり、<code>NopStatusListener</code>を使うように設定すると、内部ステータスの出力を完全に止めることが出来るのです。</p>
-
- <p class="source">java <b>-Dlogback.statusListenerClass</b>=ch.qos.logback.core.status.NopStatusListener ...</p>
-
-
- <h3 class="doAnchor" name="stopContext">logback-classic を止める</h3>
-
- <p>logback-classic が使用しているリソースを解放するには、どんな場合でもlogbackコンテキストを停止することをお勧めします。コンテキストを停止すると、コンテキストに定義されたロガーに割り当てられている全てのアペンダーを閉じて、すべてのアクティブなスレッドを停止します。
- </p>
-
-<pre class="prettyprint lang-java source">
-import org.sflf4j.LoggerFactory;
-import ch.qos.logback.classic.LoggerContext;
-...
-
-// SLF4J が logback を使うようになっていると想定
-<b>LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
-<b>loggerContext.stop();</b></pre>
-
- <p>Webアプリケーションの場合、logback-classic を停止してリソースを開放するために、<code>ServletContextListener</code>の<a href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html#contextDestroyed(javax.servlet.ServletContextEvent)">contextDestroyed</a>メソッドから上記のようなコードを実行します。
-
- <h2 class="doAnchor" name="syntax">設定ファイルの構文</h2>
-
- <p>ここまでに、たくさんのわかりやすい例を見てきてお分かりのとおり、logback はコードを再コンパイルすること無く、ロギングの振る舞いを変えることができます。アプリケーションの特定の部分でロギングを無効にする、UNIX Syslog デーモンに直接出力する、データベースに出力する、ログの可視化ツールに出力する、別の logback サーバにロギングイベントを転送する、こういった色んな設定が実に簡単にできるようになっています。ロギングイベントの転送について補足すると、ログの転送はローカルサーバーのポリシーに従って行われます。例えば、ロギングイベントを二つ目のリモートlogbackサーバーに転送する、というようなものです。
- </p>
-
- <p>このセクションの残りの部分では、設定ファイルの構文を紹介します。
- </p>
-
- <p>すでに何度か読んできたとおり、logback の設定ファイル構文はとても柔軟になっています。そのため、DTD や XML スキーマによって定義することができません。そうは言っても設定ファイルの基本的な構成要素について説明しないと始まらないでしょう。次のように定義されています。<code>configuration</code>要素は、0以上の<code>appender</code>要素、0以上の<code>logger</code>要素、1つの<code>root</code>要素によって構成されています。次の図は、この基本構造を図示したものです。</p>
-
-
- <p align="left">
- <img src="images/chapters/configuration/basicSyntax.png" alt="基本的な構文" title="基本構成ファイルの構造">
- </p>
-
-
- <p class="highlight">タグ名に大文字と小文字のどちらを使うべきなのかわからないときは、<a href="http://en.wikipedia.org/wiki/CamelCase">キャメルケース規約</a>に従ってもらえれば、ほとんどの場合は合っていると思います。</p>
-
- <h4 class="doAnchor" name="caseSensitivity">タグ名の大文字小文字の区別</h4>
-
- <p>logback 0.9.17 以降のリリースから、タグ名の大文字小文字は区別しないと明記されるようになりました。例えば、<code><logger></code>と<code><Logger></code>と<code><LOGGER></code>はどれもconfiguration要素の子要素として正しく、同じように解釈されます。XMLとしての適格性ルールは有効なままなので、開きタグを<code><xyz></code>として書いたら、閉じタグは<code></xyz></code>でなければなりません。<code></XyZ></code>ではダメです。<a href="./onJoran.html#implicit">暗黙的なルール</a>として、タグ名については最初の一文字以外は大文字小文字を区別するようになっています。したがって、<code><xyz></code>と<code><Xyz></code>は同じものとみなされますが、<code><x [...]
- </p>
-
- <h4 class="doAnchor" name="loggerElement">ロガーの設定について、あるいは、<code>logger</code>要素について</h4>
-
- <p>ここでは、少なくとも<a href="./architecture.html#effectiveLevel">レベルの継承</a>と<a href="./architecture.html#basic_selection">基本的な選択ルール</a>についてある程度理解しておかなければなりません。そうでなければ、あなたがエジブト語の学者でも無い限り、logback の設定ファイルはヒエログラフよりも意味の無いものでしかないでしょう。
- </p>
-
- <p>ロガーは<code>logger</code>要素で設定します。<code>logger</code>要素には少なくとも一つの<span class="attr">name属性</span>が必要です。<span class="attr">level属性</span>、そして<em>true</em>または<em>false</em>を指定できる<span class="attr">additivity属性</span>は任意です。<span class="attr">level属性</span>にはTRACE、DEBUG、INFO、WARN、ERROR、ALLまたはOFFのいずれかの文字列を指定できます。大文字小文字は区別しません。大文字小文字を区別しない特別な値として<em>INHERITED</em>またはその同義語として<em>NULL</em>を指定すると、祖先から継承したロガーのレベルを強制的に使用することができます。ロガーのレベルを設定した後で、祖先ロガーのレベルを継承するべきだったことがわかった場合に便利です。
- </p>
-
- <p class="highlight">
- log4jとは違って、logback-classic はロガーを設定した時に割り当てたどんなアペンダーもくクローズ<em>しない</em>し削除もしないので注意してください。
- </p>
-
- <p><code>logger要素</code>には任意個の<code>appender-ref要素</code>を含めることができます。参照しているアペンダーがロガーに割り当てられます。log4jとは違って、logback-classic はロガーを設定した時に割り当てたどんなアペンダーもくクローズ<em>しない</em>し削除もしないので注意してください。
- </p>
-
-
-
- <h4 class="doAnchor" name="rootElement">ルートロガー、あるいは、<code>root</code>要素について</h4>
-
- <p>ルートロガーは<code>root</code>要素で設定します。たった一つ、<span class="attr">level属性</span>だけを指定できます。ルートロガーにはadditivity属性などの他の属性を指定することはできません。さらに、ルートロガーの名前は予め"ROOT"になっているので、name属性も指定することはできません。level属性にはTRACE、DEBUG、INFO、WARN、ERROR、ALLまたはOFFのいずれかの文字列を指定できます。大文字小文字は区別しません。ルートロガーにはINHERITEDまたはその同義語であるNULLを指定することはできません。</p>
-
- <p class="highlight">log4jとは違って、logback-classic はルートロガーを設定した時に割り当てたどんなアペンダーもくクローズ<em>しない</em>し削除もしないので注意してください。</p>
-
- <p><code>logger要素</code>と同じく、<code>root要素</code>には任意個の<code>appender-ref要素</code>を含めることができます。参照しているアペンダーがロガーに割り当てられます。log4jとは違って、logback-classic はルートロガーを設定した時に割り当てたどんなアペンダーもくクローズ<em>しない</em>し削除もしないので注意してください。
-</p>
-
- <h4>例</h4>
-
- <p>ロガーあるいはルートロガーにレベルを設定するのは非常に簡単です。例を示します。"chapters.configuration" パッケージのコンポーネントから出力されていたDEBUGメッセージが不要になったとしましょう。次の設定ファイルはそれを実現するための例です。
- </p>
-
- <p class="example">例:ロガーのレベルを設定する(<a href="http://logback.qos.ch/xref/chapters/configuration/sample2.xml">logback-examples/src/main/java/chapters/configuration/sample2.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('sample2');">Groovyで見る</span>
- <pre id="sample2" class="prettyprint source"><configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <!-- encoders are assigned the type
- ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <b><logger name="chapters.configuration" level="INFO"/></b>
-
- <!-- 厳密にはここでルートロガーのlevel要素を設定する必要はありません -->
- <!-- デフォルトでDEBUGが指定されるからです -->
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-
-</configuration></pre>
-
- <p>この設定ファイルを<em>MyApp3</em>アプリケーションの引数として渡すと、次のような出力が得られます。</p>
-
-<pre class="source">17:34:07.578 [main] INFO chapters.configuration.MyApp3 - Entering application.
-17:34:07.578 [main] INFO chapters.configuration.MyApp3 - Exiting application.</pre>
-
- <p><a href="http://logback.qos.ch/xref/chapters/configuration/Foo.html">"chapters.configuration.Foo</a>"のロガーが出力していたDEBUGメッセージが抑止されていることに気づきましたか。気になるならFooクラスを見なおしてください。</p>
-
- <p>あらゆるロガーのレベルを思った通りに設定することができます。次の設定ファイルでは、<em>chapters.configuration</em>ロガーのレベルをINFOに設定していますが、同時に<em>chapters.configuration.Foo</em>のレベルを<code>DEBUG</code>に設定しています。</p>
-
- <p class="example">例:複数のロガーのレベルを設定する(<a href="http://logback.qos.ch/xref/chapters/configuration/sample3.xml">logback-examples/src/main/java/chapters/configuration/sample3.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('sample3');">Groovyで見る</span>
- <pre id="sample3" class="source prettyprint"><configuration>
-
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>
- %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
- </pattern>
- </encoder>
- </appender>
-
- <b><logger name="chapters.configuration" level="INFO" /></b>
- <b><logger name="chapters.configuration.Foo" level="DEBUG" /></b>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-
-</configuration></pre>
-
- <p><code>MyApp3</code>アプリケーションの引数にこの設定ファイルを指定して実行すると、コンソールには次のように出力されます。</p>
-
-<p class="prettyprint source">17:39:27.593 [main] INFO chapters.configuration.MyApp3 - Entering application.
-17:39:27.593 [main] DEBUG chapters.configuration.Foo - Did it again!
-17:39:27.593 [main] INFO chapters.configuration.MyApp3 - Exiting application.</p>
-
- <p><code>JoranConfiguration</code>が<em>sample3.xml</em>を設定した後のロガーとそのレベルを表にまとめました。
- </p>
-
- <table class="bodyTable">
- <tr>
- <th>ロガー名</th>
- <th>割り当てられたレベル</th>
- <th>有効レベル</th>
- </tr>
- <tr>
- <td>root</td>
- <td><code>DEBUG</code></td>
- <td><code>DEBUG</code></td>
- </tr>
- <tr class="alt">
- <td>chapters.configuration</td>
- <td><code>INFO</code></td>
- <td><code>INFO</code></td>
- </tr>
- <tr>
- <td>chapters.configuration.MyApp3</td>
- <td><code>null</code></td>
- <td><code>INFO</code></td>
- </tr>
- <tr class="alt">
- <td>chapters.configuration.Foo</td>
- <td><code>DEBUG</code></td>
- <td><code>DEBUG</code></td>
- </tr>
- </table>
-
- <p>これは、<code>MyApp3</code>クラスの<code>INFO</code>レベルのロギング式2つと、<code>Foo</code>クラスのdoIt()メソッドにあるDEBUGレベルのロギング式がいずれも有効であるということです。ルートロガーのレベルは常に非null値が指定されること、デフォルトではDEBUGが指定されていることに注意しましょう。
- </p>
-
- <p><a href="./architecture.html#basic_selection">基本的な選択ルール</a>についても考えてみましょう。ロギング要求が呼び出されるかどうかは、アペンダーを割り当てられたロガーに指定されたレベルそのものではなく、ロガーの有効レベルによって決定されるというものです。logback はまず最初にロギング式が有効かどうかを判定します。有効な場合は、ロガーのレベルに依らず、ロガー階層で見つかったアペンダーを呼び出します。設定ファイル<em>sample4.xml</em>でその点を確認しましょう。</p>
-
- <p class="example">例:ロガーレベルのサンプル(<a href="http://logback.qos.ch/xref/chapters/configuration/sample4.xml">logback-examples/src/main/java/chapters/configuration/sample4.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('sample4');">Groovyで見る</span>
- <pre id="sample4" class="prettyprint source"><configuration>
-
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>
- %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
- </pattern>
- </encoder>
- </appender>
-
- <b><logger name="chapters.configuration" level="INFO" /></b>
-
- <!-- turn OFF all logging (children can override) -->
- <root <b>level="OFF"</b>>
- <appender-ref ref="STDOUT" />
- </root>
-
-</configuration></pre>
-
- <p><em>sample4.xml</em>を設定した後のロガーとそのレベルを表にまとめました。
- </p>
-
- <table class="bodyTable">
- <tr>
- <th>ロガー名</th>
- <th>割り当てられたレベル</th>
- <th>有効レベル</th>
- </tr>
- <tr>
- <td>root</td>
- <td><code>OFF</code></td>
- <td><code>OFF</code></td>
- </tr>
- <tr class="alt">
- <td>chapters.configuration</td>
- <td><code>INFO</code></td>
- <td><code>INFO</code></td>
- </tr>
- <tr>
- <td>chapters.configuration.MyApp3</td>
- <td><code>null</code></td>
- <td><code>INFO</code></td>
- </tr>
- <tr class="alt">
- <td>chapters.configuration.Foo</td>
- <td><code>null</code></td>
- <td><code>INFO</code></td>
- </tr>
- </table>
-
- <p><em>sample4.xml</em>では、ConsoleAppenderに<em>STDOUT</em>という名前を付けて、ルートロガーに割り当てています。ルートロガーのレベルは<code>OFF</code>です。しかし、<em>MyApp3</em>の引数として<em>sample4.xml</em>を指定して実行すると次のような出力になってしまいます。</p>
-
- <div class="source"><pre>17:52:23.609 [main] INFO chapters.configuration.MyApp3 - Entering application.
-17:52:23.609 [main] INFO chapters.configuration.MyApp3 - Exiting application.</pre></div>
-
- <p>つまり、<code>INFO</code>レベルが有効レベルとなっているロガーである<code>chapters.configuration.MyApp3</code>と<code>chapters.configuration.Foo</code>のどちらも、ルートロガーのレベルによる影響を受けていないのです。蛇足ですが、Java実装の中では<em>chapters.configuration</em>ロガーを直接参照しているところはありませんが、実際に存在しています。設定ファイルで宣言されいるからです。
- </p>
-
- <h4 class="doAnchor" name="configuringAppenders">アペンダーの設定</h4>
-
- <p>アペンダーの設定は<code>appender要素</code>で行います。この要素には<span class="attr">name属性</span>と<span class="attr">class属性</span>という二つの必須属性があります。<span class="attr">name属性</span>にはアペンダーの名前を、<span class="attr">class属性</span>にはアペンダーのクラスの完全名を指定します。<code>appender要素</code>には任意個の<code>layout要素</code>と<code>encoder要素</code>と<code>filter要素</code>を含めることができます。<code>appender要素</code>には、これらの一般的な要素とは別に、アペンダークラスのJavaBean規約に従ったプロパティを任意の数だけ含めることができます。logbackのコンポーネントのどんなプロパティでも違和感無く設定できるのは、<a href="./onJoran.html">Jora [...]
- </p>
-
- <p align="left">
- <img src="images/chapters/configuration/appenderSyntax.png" alt="アペンダの構文" title="アペンダー要素構文">
- </p>
-
- <p><code>layout要素</code>にはclass属性が必須です。レイアウトクラスの完全名を指定します。<code>appender要素</code>と同じく、<code>layout要素</code>にはレイアウトクラスのプロパティを含めることができます。レイアウトクラスとして<code>PatternLayout</code>を指定するのが一般的なので、その場合class属性は省略できるようになっています。これは<a href="./onJoran.html#defaultClassMapping">デフォルトのクラスマッピングルール</a>で定義されています。
- </p>
-
- <p><code>encoder要素</code>にはclass属性が必須です。エンコーダクラスの完全名を指定します。エンコーダクラスとして<code>PaternLayoutEncoder</code>を指定するのが一般的なので、その場合class属性を省略できるようになっています。これは<a href="./onJoran.html#defaultClassMapping">デフォルトのクラスマッピングルール</a>で定義されています。
- </p>
-
- <p>複数のアペンダーにログを出力するのも、さまざまなアペンダーを定義してロガーから参照するのも簡単です。設定ファイルの例を示しましょう。</p>
-
- <p class="example">例:複数のロガー(<a href="http://logback.qos.ch/xref/chapters/configuration/multiple.xml">logback-examples/src/main/java/chapters/configuration/multiple.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('multiple');">Groovyで見る</span>
- <pre id="multiple" class="prettyprint source"><configuration>
-
- <appender name="<b>FILE</b>" class="ch.qos.logback.core.FileAppender">
- <file>myApp.log</file>
-
- <encoder>
- <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
- </encoder>
- </appender>
-
- <appender name="<b>STDOUT</b>" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <b><appender-ref ref="FILE" /></b>
- <b><appender-ref ref="STDOUT" /></b>
- </root>
-</configuration></pre>
-
- <p>この設定スクリプトでは、<em>FILE</em>と<em>STDOUT</em>というアペンダーを定義しています。<em>FILE</em>は<em>myApp.log</em>というファイルへログを出力するアペンダーです。このアペンダーのエンコーダーは<code>PatternLayoutEncoder</code>で、日付、ログレベル、スレッド名、ロガー名、ソースコードファイル名、ロギング式の書かれたソースコードファイル中の行番号、メッセージ、改行文字を出力します。二つ目のアペンダーは<code></code>STDOUT[/0}という名前です。これはコンソールにログを出力するアペンダーです。このアペンダーのエンコーダーは、メッセージと改行文字だけを出力します。
- </p>
-
- <p>二つのアペンダーはルートロガーに割り当てられています。それぞれ<em>appender-ref要素</em>から名前で参照されています。それぞれのアペンダーにエンコーダーを指定していることに気づきましたか。普通エンコーダーは複数のアペンダーから共有できるように設計されていません。レイアウトにも同じことが言えます。このように、logbackの設定ファイルは、エンコーダーやレイアウトを共有するためのいかなる構文上の手段も提供しません。
- </p>
-
- <h4 class="doAnchor" name="cumulative">アペンダーの積み重ね</h4>
-
- <p>デフォルトでは<b>アペンダーは積み重ねられていきます</b>。つまり、ロガーに割り当てられたアペンダーにログを出力するのとまったく同様に、祖先ロガーに割り当てられたアペンダーにもログが出力されます。従って、同じアペンダーを複数のロガーに割り当てると、ログ出力が重複することになります。
- </p>
-
- <p class="example">例:アペンダーの重複(<a href="http://logback.qos.ch/xref/chapters/configuration/duplicate.xml">logback-examples/src/main/java/chapters/configuration/duplicate.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('duplicate');">Groovyで見る</span>
- <pre id="duplicate" class="prettyprint source"><configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <logger name="chapters.configuration">
- <appender-ref ref="STDOUT" />
- </logger>
-
- <root level="debug">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p><code>MyApp3</code>アプリケーションの引数に<em>duplicate.xml</em>を指定して実行すると、次のような出力が得られます。</p>
-
-<p class="source">14:25:36.343 [main] INFO chapters.configuration.MyApp3 - Entering application.
-14:25:36.343 [main] INFO chapters.configuration.MyApp3 - Entering application.
-14:25:36.359 [main] DEBUG chapters.configuration.Foo - Did it again!
-14:25:36.359 [main] DEBUG chapters.configuration.Foo - Did it again!
-14:25:36.359 [main] INFO chapters.configuration.MyApp3 - Exiting application.
-14:25:36.359 [main] INFO chapters.configuration.MyApp3 - Exiting application.</p>
-
- <p>ログ出力の重複には気をつけましょう。<em>STDOUT</em>という名前のアペンダーは、ルートロガーと<em>chapters.configuration</em>ロガーに割り当てられています。ルートロガーは全てのロガーの祖先ロガーです。<em>chapters.configuration</em>ロガーは<em>chapters.configuration.MyApp3</em>ロガーと<em>chapters.configuration.Foo</em>ロガーの親ロガーです。子孫にあたるこれら二つのロガーによるロギング要求は二重に出力されます。なぜなら、<em>STDOUT</em>アペンダーが、<em>chapters.configuration</em>ロガーと<em>ルート</em>ロガーの両方に割り当てられているからです。
- </p>
-
- <p>アペンダーが積み重ねられるようになっているのは、決して新しい利用者を罠にかけるためではありません。これは非常に便利なフィーチャなのです。例えば、システム中の全てのロガーによるメッセージをコンソールに出力させつつ、特定のロガーのメッセージだけを特別なアペンダーに出力させるように設定することができるのです。
- </p>
-
- <p class="example">例:複数のアペンダー(<a href="http://logback.qos.ch/xref/chapters/configuration/restricted.xml">logback-examples/src/main/java/chapters/configuration/restricted.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('restricted');">Groovyで見る</span>
- <pre id="restricted" class="prettyprint source"><configuration>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <file>myApp.log</file>
- <encoder>
- <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
- </encoder>
- </appender>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <logger name="chapters.configuration">
- <appender-ref ref="FILE" />
- </logger>
-
- <root level="debug">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>この例では、システム中の全てのロガーのメッセージはコンソールアペンダーに出力されます。そして、<em>chapters.configuration</em>ロガーとその子孫ロガーからのロギング要求は<em>myApp.log</em>ファイルにも出力されます。
- </p>
-
- <h4 class="doAnchor" name="overrridingCumulativity">デフォルトの積み重ねを止める</h4>
-
- <p>デフォルトの積み重ねがニーズに合わない場合は、aditivity フラグに false を設定して止めることができます。そうすれば、ロガーツリーのある枝から下の部分では、ツリーの他の部分と違って、ロガーに割り当てられたアペンダーにだけ出力するようになります。
- </p>
-
- <p class="example">例:aditivity フラグ(<a href="http://logback.qos.ch/xref/chapters/configuration/aditivityFlag.xml">logback-examples/src/main/java/chapters/configuration/aditivityFlag.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('additivityFlag');">Groovyで見る</span>
- <pre id="additivityFlag" class="prettyprint source"><configuration>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <file>foo.log</file>
- <encoder>
- <pattern>%date %level [%thread] %logger{10} [%file : %line] %msg%n</pattern>
- </encoder>
- </appender>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <logger name="chapters.configuration.Foo" <b>additivity="false"</b>>
- <appender-ref ref="FILE" />
- </logger>
-
- <root level="debug">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>この例では<em>chapters.configuration.Foo</em>ロガーに<em>FILE</em>というアペンダーが割り当てられています。また、<em>chapters.configuration.Foo</em>ロガーのaditivityフラグにfalseが指定されているので、ログは<em>FILE</em>アペンダーにだけ出力されて、ログ階層の先祖に割り当てられているアペンダーには出力されません。他のロガーが<em>chapters.configuration.Foo</em>ロガーのaditivityフラグの設定に気づくことはありません。<code>MyApp3</code>アプリケーションを<em>aditivityFlag.xml</em>を引数として実行すると、コンソールに<em>chapters.configuration.MyApp3</em>ロガーからの出力が表示されます。しかし、<em>chapters.configuration.Foo</em>ロガーの出力が<em>foo.log</em>以外に表れることはありません。
- </p>
-
- <h3 class="doAnchor" name="contextName">コンテキスト名の設定</h3>
-
- <p><a href="./architecture.html#LoggerContext">前の章</a>で述べたように、全てのロガーはロガーコンテキストに割り当てられます。ロガーコンテキストのデフォルトの名前は「default」です。しかし、<code>contextNameディレクティブ</code>を使えば別の名前を付けることが出来ます。ロガーコンテキストの名前は一度設定したら<a href="http://logback.qos.ch/apidocs/ch/qos/logback/core/ContextBase.html#setName(java.lang.String)">変更できない</a>ので注意してください。複数のアプリケーションが同じ対象にロギングする場合、アプリケーションを区別しやすくするには、コンテキストに名前を付けるのが簡単でわかりやすい方法です。
- </p>
-
- <p class="example">例:コンテキスト名を設定して表示する(<a href="http://logback.qos.ch/xref/chapters/configuration/contextName.xml">logback-examples/src/main/java/chapters/configuration/contextName.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('contextName');">Groovyで見る</span>
- <pre id="contextName" class="prettyprint source"><configuration>
- <b><contextName>myAppName</contextName></b>
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d <b>%contextName</b> [%t] %level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>これはロガーコンテキストに名前を付ける例です。レイアウトのパターンに変換指示語として<a href="./layouts.html#conversionWord">contextName</a>を指定すると、コンテキスト名が出力されます。</p>
-
- <!-- =============================================================== -->
-
- <h3 class="doAnchor" name="variableSubstitution">変数の置換</h3>
-
- <p>このドキュメントの以前のバージョンでは、「変数の置換」ではなく「プロパティの置換」と呼んでいました。<span class="label"></span>どちらも相互に置き換えられるくらい同じ意味の言葉ですが、前者のほうが明確に意味を表していると思います。
- </p>
-
- <p>よくあるスクリプト言語のように、logbackの設定ファイルは変数を定義して、値と置き換えられるようになっています。変数は設定ファイルの中で定義することもできるし、外部のファイルで定義することもできます。そして外部リソースでも定義することもできるし、何らか計算することさえできます。また、<a href="./03-configuration.html#definingPropsOnTheFly">実行時に定義する</a>こともできます。
- </p>
-
- <p class="highlight">値を指定できるところなら設定ファイル中のどこでも変数を置換することができます。</p>
-
- <p>値を指定できるところなら設定ファイル中のどこでも変数を置換することができます。
-変数の置換をする構文はUnixシェルとよく似ています。<em>${</em>から始まり<em>}</em>で終わる文字列は、<em>プロパティの値</em>への参照と見做されます。<em>aName</em>というプロパティの場合文字列の"${aName}"は、その値に置き換えられます。<em></em>
- </p>
-
- <p>変数には<a href="./03-configuration.html#scopes">スコープ</a>があります(後で説明します)。</p>
-
- <p>HOSTNAME変数とCONTEXT_NAME変数はよく使われるので、コンテキストスコープを持つ変数として自動的に定義されます。</p>
-
- <h4 class="doAnchor" name="definingProps">変数の定義</h4>
-
- <p>変数は、設定ファイルや外部のプロパティファイル、あるいは外部リソースを読み込むとき、それぞれで一度だけ定義することができます。歴史的な理由により、<code>property</code>XML要素を使って変数を定義することになっていますが、logback 1.0.7以降では<code>variable要素</code>を使うことも出来ます。これらの要素は完全に互換性があります。</p>
-
- <p>設定ファイルの先頭で変数を定義する例を見てみましょう。定義された変数は、設定ファイルの後半のほうでログ出力用ファイルの位置を指定するために使われています。
- </p>
-
- <p class="example">例:変数の置換(<a href="http://logback.qos.ch/xref/chapters/configuration/variableSubstitution1.xml">logback-examples/src/main/java/chapters/configuration/variableSubstitution1.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('variableSubstitution1');">Groovyで見る</span>
- <pre id="variableSubstitution1" class="prettyprint source"><configuration>
-
- <b><property name="USER_HOME" value="/home/sebastien" /></b>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <b><file>${USER_HOME}/myApp.log</file></b>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
- <p>次は、システムプロパティを使って同じことをしてみましょう。設定ファイル中にproperty要素が宣言されていないので、logback はそれをシステムプロパティから探します。Javaのシステムプロパティはコマンドラインで次のように指定します。</p>
-
- <p class="source">java -DUSER_HOME="/home/sebastien" MyApp2</p>
-
- <p class="example">例:システム変数の置換(<a href="http://logback.qos.ch/xref/chapters/configuration/variableSubstitution2.xml">logback-examples/src/main/java/chapters/configuration/variableSubstitution2.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('variableSubstitution2');">Groovyで見る</span>
- <pre id="variableSubstitution2" class="prettyprint source"><configuration>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <b><file>${USER_HOME}/myApp.log</file></b>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <p>複数の変数が必要なときは、変数の定義だけを含むファイルを別に用意したほうが便利な場合もあります。構成例を示します。
- </p>
-
- <p class="example">例:別ファイルを使用する変数の置換(<a href="http://logback.qos.ch/xref/chapters/configuration/variableSubstitution3.xml">logback-examples/src/main/java/chapters/configuration/variableSubstitution3.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('variableSubstitution3');">Groovyで見る</span>
- <pre id="variableSubstitution3" class="prettyprint source"><configuration>
-
- <b><property file="src/main/java/chapters/configuration/variables1.properties" /></b>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <b><file>${USER_HOME}/myApp.log</file></b>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
- <p>この設定ファイルでは<em>variables1.properties</em>という名前のファイルを参照しています。指定されたファイルで定義された変数がローカルスコープに定義されます。<em>variable.properties</em>の内容は次のようなものです。
- </p>
-
- <em>例:変数定義ファイル(logback-examples/src/main/java/chapters/configuration/variables1.properties)</em>
-
- <pre class="source">USER_HOME=/home/sebastien</pre>
-
- <p>ファイルの代わりにクラスパス上のリソースを指定することもできます。</p>
-
- <pre class="prettyprint source"><configuration>
-
- <b><property resource="resource1.properties" /></b>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <b><file>${USER_HOME}/myApp.log</file></b>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <h4 class="doAnchor" name="scopes">スコープ</h4>
-
- <p><em>ローカルスコープ</em>、<em>コンテキストスコープ</em>、<em>システムスコープ</em>のそれぞれで変数を定義することができます。デフォルトのスコープはローカルスコープです。OSの提供する環境変数の読み込みはできますが、書き込みは出来ません。</p>
-
-
- <p><span class="label">ローカルスコープ</span>。ローカルスコープで定義された変数は、その変数が定義されている設定ファイルの解釈、実行が終了するまで有効です。当然ながら、設定ファイルを解釈、実行するたびに、ローカルスコープの変数は新しく定義されることになります。</p>
-
- <p><span class="label">コンテキストスコープ</span>。コンテキストスコープで定義された変数は、コンテキストに登録されます。コンテキストが破棄されるまで、あるいは、コンテキストが初期化されるまで有効です。つまり、一度コンテキストスコープで定義された変数はコンテキストの一部となるのです。ですので、全てのロギングイベントから利用できますし、そのイベントをシリアライズして送信した先のリモートホストでも利用できます。
- </p>
-
- <p><span class="label">システムスコープ</span>。システムスコープで定義された変数は、JVMのシステムプロパティに登録されます。JVMが停止するか、初期化されるまで有効です。
- </p>
-
- <p class="highlight">最初にローカルスコープで変数を検索します。そしてコンテキストスコープ、システムスコープの順に検索し、最後に<a href="http://docs.oracle.com/javase/tutorial/essential/environment/env.html">OSの環境変数</a>を検索します。
- </p>
-
- <p>変数を置換する際、最初にローカルスコープで変数を検索します。そしてコンテキストスコープ、システムスコープの順に検索し、最後に<a href="http://docs.oracle.com/javase/tutorial/essential/environment/env.html">OSの環境変数</a>を検索します。
-
- </p>
-
- <p>変数のスコープは、<code>property要素</code>、<code>define要素</code>、<code>insertFromJNDI要素</code>の<span class="attr">scope属性</span>で指定します。<span class="attr">scope属性</span>に指定できるのは、"local"、"context"、"system" のいずれかの文字列です。scope属性を指定しなかった場合、スコープは常に"local"と見做されます。
- </p>
-
- <p class="example">例:変数をコンテキストスコープで定義する(<a href="http://logback.qos.ch/xref/chapters/configuration/contextScopedVariable.xml">logback-examples/src/main/java/chapters/configuration/contextScopedVariable.xml</a>)</p>
-
- <span class="asGroovy" onclick="return
- asGroovy('contextScopedVariable');">Groovyで見る</span>
- <pre id="contextScopedVariable" class="prettyprint source"><configuration>
-
- <property <b class="big">scope="context"</b> name="nodeId" value="firstNode" />
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <b><file>/opt/${nodeId}/myApp.log</file></b>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
- <p>この例では<em>nodeId変数</em>をコンテキストスコープで定義しています。この変数は全てのロギングイベントで有効であり、シリアライズ化して送信した先のリモートホストでも利用できます。</p>
-
-
- <h3 class="doAnchor" name="defaultValuesForVariables">変数のデフォルト値</h3>
-
- <p>特定の状況では、変数が宣言されていなかったり、値がnullの場合、デフォルト値が使えるようになっているほうが望ましいことがあります。<a href="http://tldp.org/LDP/abs/html/parameter-substitution.html">Bash</a>と同じく、<b>":-"</b>演算子を使ってデフォルト値を指定することができます。例えば、 <em>aName</em>という名前の変数が定義されていない場合、<code>"${aName <b>:-golden</b> }"</code>という文字列を変数置換した結果は"goleden"になります。</p>
-
- <h3 class="doAnchor" name="nestedSubst">変数のネスト</h3>
-
- <p>変数はネストすることができます。変数の名前として、デフォルト値として、値として、他の変数を指定することができます。</p>
-
-
- <h4>値のネスト</h4>
- <p>変数の値を定義するとき、他の変数を指定することができます。例えば、宛先のディレクトリだけでなく、ファイル名も変数で指定したい場合、それぞれの変数をまとめた第三の変数"destination"を定義して、それを利用できるのです。プロパティファイルの例を示します。
- </p>
-
- <p class="example">例:変数のネスト(<a href="http://logback.qos.ch/xref/chapters/configuration/variables2.properties">logback-examples/src/main/java/chapters/configuration/variables2.properties</a>)</p>
-
- <pre class="source">USER_HOME=/home/sebastien
-fileName=myApp.log
-<b>destination=${USER_HOME}/${fileName}</b></pre>
-
- <p>"destination"変数の定義で、"USER_HOME"変数と"fileName"変数を組み合わせていることが分かりますか。
- </p>
-
- <em>例:別のファイルを使用した変数の置換(logback-examples/src/main/java/chapters/configuration/variableSubstitution4.xml)</em>
-
- <pre class="prettyprint source"><configuration>
-
- <property file="variables2.properties" />
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <b><file>${destination}</file></b>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <h4>名前のネスト</h4>
-
- <p>変数を参照するとき、変数の名前として、他の変数を指定することができます。たとえば、"uesrid"変数に"alice"という文字列が指定されていることにしましょう。そうすると、"${${userid}.password}"という文字列は、"alice.password"変数を参照することになるのです。</p>
-
- <h4>デフォルト値のネスト</h4>
-
- <p>変数のデフォルト値に他の変数を指定することができます。たとえば、'id'変数に値が割り当てられておらず、'userid'変数には"alice"という文字列が指定されていることにしましょう。そうすると、"${id<b>:-</b>${userid}}" という文字列は"alice"という文字列になるのです。
- </p>
-
-
- <!-- ==============================================================
- -->
- <h3 class="doAnchor" name="hostname">HOSTNAME変数</h3>
-
- <p>あると便利なので、<code>HOSTNAME</code>変数は自動的にコンテキストスコープに定義されるようになっています。</p>
-
- <!-- ============================================================== -->
- <h3 class="doAnchor" name="context_name">CONTEXT_NAME変数</h3>
-
- <p>変数名のとおり、<code>CONTEXT_NAME</code>変数には、現在のロギングコンテキストの名前が設定されています。</p>
-
- <!-- ============================================================== -->
-
- <h3 class="doAnchor" name="timestamp">タイムスタンプを設定する</h3>
-
- <p><em>timestamp要素</em>を使うと、現在の日付と時刻に応じた値を持つプロパティを定義することができます。<em>timestamp要素</em>については<a href="./appenders.html#uniquelyNamed">後続の章</a>で説明します。</p>
-
- <!-- ============================================================== -->
- <h3 class="doAnchor" name="definingPropsOnTheFly">実行時に変数を定義する</h3>
-
- <p><code>define要素</code>を使うと動的に変数を定義できます。define要素には二つの必須属性<span class="attr">name属性</span>と<span class="attr">class属性</span>があります。<span class="attr">name属性</span>には変数の名前を指定します。<span class="attr">class属性</span>には<a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/PropertyDefiner.html">PropertyDefiner</a>インターフェイスを実装したクラスの完全名を指定します。<code>PropertyDefiner</code>の<code>getPropertyValue()</code>メソッドの返す値が、変数の値になります。<span class="attr">scope属性</span>で<a href="./03-configuration.html#scop [...]
- </p>
-
- <p>以下に例を示します。</p>
-
- <pre class="prettyprint source"><configuration>
-
- <define name="rootLevel" class="a.class.implementing.PropertyDefiner">
- <shape>round</shape>
- <color>brown</color>
- <size>24</size>
- </define>
-
- <root level="${rootLevel}"/>
-</configuration></pre>
-
- <p>この例では、"a.class.implementing.PropertyDefiner"クラスのプロパティとして、shape、color、sizeを指定しています。指定したプロパティのセッターメソッドが<code>PropertyDefiner</code>クラスに定義されていれば、logback は設定ファイルで指定されたプロパティの値をインスタンスに設定することができます。</p>
-
-
-
- <p>logback の配布物には現在のところ非常に単純な二つの<code>PropertyDefiner</code>実装クラスが含まれてます。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>実装クラス名</th>
- <th>説明</th>
- </tr>
-
- <tr>
- <td><a href="http://logback.qos.ch/apidocs/ch/qos/logback/core/property/FileExistsPropertyDefiner.html"><code>FileExistsPropertyDefiner</code></a>
- </td>
- <td><span class="prop">path</span>プロパティに指定したファイルが存在していれば"true"を、そうでなければ"false"を返します。
- </td>
- </tr>
- <tr>
- <td><a href="http://logback.qos.ch/apidocs/ch/qos/logback/core/property/FileExistsPropertyDefiner.html"><code>ResourceExistsPropertyDefiner</code></a>
- </td>
- <td>クラスパス上に指定された<span class="prop">リソース</span>が存在すれば"true"を、そうでなければ"false"を返します。
- </td>
- </tr>
- </table>
-
- <!-- ============================================================== -->
-
- <h3 class="doAnchor" name="conditional">設定ファイル内の条件分岐</h3>
-
- <p>開発環境、テスト環境、本番環境のような環境ごとに用意されたlogback設定ファイルと格闘しなければならないことがよくあります。これらの設定ファイルの内容はほとんど同じですが、少しだけ異なる箇所があります。同じような設定ファイルの重複を避けるため、logback は設定ファイル中で条件分岐できるようになっています。<code>if要素</code>、<code>then要素</code>、<code>else要素</code>を使えば、さまざまな環境用のファイルを一つにまとめることができるのです。条件分岐できるようにするため、<a href="http://logback.qos.ch/setup.html#janino">Jainoライブラリ</a>を使用しています。
- </p>
-
- <p>条件分岐式の一般的な形式を次に示します。</p>
-
- <pre class="prettyprint source">
- <!-- if-then form -->
- <if condition="some conditional expression">
- <then>
- ...
- </then>
- </if>
-
- <!-- if-then-else form -->
- <if condition="some conditional expression">
- <then>
- ...
- </then>
- <else>
- ...
- </else>
- </if></pre>
-
- <p>condition属性に指定するのはJavaの条件式です。コンテキストスコープとシステムスコープの変数が利用できます。<code>property()</code>メソッドか、その省略形である<code>p()</code>メソッドの引数としてヘンス名を渡すと、その値を文字列として返します。たとえば、"k"という値の変数の値にアクセスするには、<code>property("k")</code>あるいは<code>p("k")</code>という書き方をします。変数"k"が未定義ならproperty()メソッドは空文字列を返します。nullではありません。つまり、nullチェックは不要です。</p>
-
- <p><code>isDefined()</code>メソッドを使うと、変数が定義されているかどうかを確かめることが出来ます。たとえば、変数"k"が定義されているかどうかをチェックするには<code>isDefined("k")</code>と書けばよいです。他にも、nullチェックをするための<code>isNull()</code>メソッドが用意されています。
-
-例: <code>isNull("k")</code></p>
-
- <pre class="prettyprint source"><configuration debug="true">
-
- <b><if condition='property("HOSTNAME").contains("torino")'></b>
- <b><then></b>
- <appender name="CON" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d %-5level %logger{35} - %msg %n</pattern>
- </encoder>
- </appender>
- <root>
- <appender-ref ref="CON" />
- </root>
- <b></then></b>
- <b></if></b>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <file>${randomOutputDir}/conditional.log</file>
- <encoder>
- <pattern>%d %-5level %logger{35} - %msg %n</pattern>
- </encoder>
- </appender>
-
- <root level="ERROR">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <p><code>configuratoin要素</code>の中なら<em>どこにでも</em>条件分岐を置くことが出来ます。if-then-else式をネストすることもできます。しかし、XML文法は非常に面倒ですし、汎用プログラミング言語の基盤には不適切です。したがって、条件分岐が多すぎると、設定ファイルはあっという間に他の人には理解できないものになってしまいます。ましてや、後で自分が読み返しても理解できないでしょう。
- </p>
-
-
- <!-- ============================================================== -->
-
- <h3 class="doAnchor" name="insertFromJNDI">JNDIから変数を取得する</h3>
-
- <p>特定の状況下では、JNDIに格納されたenvの内容を参照したいこともあるでしょう。<code>insertFromJNDIディレクティブ</code>を使うと、JNDIに格納されたenvを取得して、ローカルスコープの変数<span class="attr">として</span>取り込むことができます。他の変数と同じく、<em>scope属性</em>に指定した<a href="./03-configuration.html#scopes">別のスコープ</a>に新しい変数を登録することができます。
- </p>
-
- <p class="example">例:JNDI経由で取得したenvを変数として登録する(<a href="http://logback.qos.ch/xref/chapters/configuration/insertFromJNDI.xml">logback-examples/src/main/java/chapters/configuration/insertFromJNDI.xml</a>)</p>
-
- <pre class="prettyprint source"><configuration>
- <b><insertFromJNDI env-entry-name="java:comp/env/appName" as="<span class="green">appName"</span> /></b>
- <b><contextName><span class="green">${appName}</span></contextName></b>
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d ${CONTEXT_NAME} %level %msg %logger{50}%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-</configuration></pre>
-
- <p>この例は、env の "java:comp/env/appName"を<span class="variable">appName</span>という名前の変数として登録するものです。<code>contextNameディレクティブ</code>で指定しているコンテキスト名には、その前に定義されている<code>insertFromJNDIディレクティブ</code>で登録した変数を使用していることがわかりますか。
- </p>
-
- <h3 class="doAnchor" name="fileInclusion">ファイルの取り込み</h3>
-
- <p>Joranは、設定ファイルの一部として別のファイルを読み込むことができます。そのためには、<code>include要素</code>として宣言します。</p>
-
- <p class="example">例:ファイルの取り込み(<a href="http://logback.qos.ch/xref/chapters/configuration/containingConfig.xml">logback-examples/src/main/java/chapters/configuration/containingConfig.xml</a>)</p>
-
- <pre class="prettyprint source"><configuration>
- <b><include file="src/main/java/chapters/configuration/includedConfig.xml"/></b>
-
- <root level="DEBUG">
- <appender-ref ref="includedConsole" />
- </root>
-
-</configuration></pre>
-
- <p>取り込まれるファイルでは、全ての要素が<code>included要素</code>の中に入っていなければなりません。<code>ConsoleAppender</code>を宣言する例を示します。</p>
-
- <p class="example">例:ファイルの取り込み(<a href="http://logback.qos.ch/xref/chapters/configuration/includedConfig.xml">logback-examples/src/main/java/chapters/configuration/includedConfig.xml</a>)</p>
-
- <pre class="source"><b class="green big"><included></b>
- <appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>"%d - %m%n"</pattern>
- </encoder>
- </appender>
-<b class="green big"></included></b></pre>
-
-
- <p>繰り返しになりますが、取り込まれるファイルでは、<code class="big green">included要素</code>が必須です。</p>
-
- <p>include する対象として指定するのは、外部ファイルだけではなく、クラスパス上のリソースでも、URLでもよいです。</p>
-
- <ul>
-
- <li><b>ファイルの場合:</b><br>ファイルを取り込むには<span class="attr">file属性</span>を使用します。相対パスを指定できますが、カレントディレクトリとして使われるのはアプリケーションが設定したものになります。設定ファイルのパスとは無関係なので注意してください。</li>
-
- <li><p><b>リソースの場合:</b><br>クラスパス上のファイルなどのリソースを取り込むには<span class="attr">resource属性</span>を使用します。</p>
-
- <pre class="prettyprint source"><include resource="includedConfig.xml"/></pre>
-
- </li>
-
- <li><p><b>URLの場合:</b><br>URLから取得できるコンテンツを取り込むには<span class="attr">url属性</span>を使用します。</p>
-
- <pre class="prettyprint source"><include url="http://some.host.com/includedConfig.xml"/></pre>
-
- </li>
- </ul>
-
- <p>指定されたファイルが存在しなかった場合、logback はステータスメッセージを出力してそのことを報告します。取り込もうとしているファイルが<span class="attr">任意の</span>ものである場合、<code>include要素のoptional属性に<code>true</code>を指定しておけば、エラーメッセージを抑止することができます。</code></p>
-
-
- <pre class="prettyprint source"><include optional="true" ..../></pre>
-
- <!-- ==================== ContextListener =================== -->
- <h2 class="doAnchor" name="contextListener">コンテキストリスナーを追加する</h2>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/spi/LoggerContextListener.html">LoggerContextListener</a>インターフェイスのインスタンスは、ロガーコンテキストのライフサイクルに関連するイベントを待ち受けます。
- </p>
-
-
- <p><code>JMXConfigurator</code>は<code>LoggerContextListener</code>インターフェイスの実装の一つです。詳しくは<a href="./jmxConfig.html">後の章</a>で説明します。
- </p>
-
- <h3 class="doAnchor" name="LevelChangePropagator">LevelChangePropagator</h3>
-
- <p>バージョン0.9.25から、logback-classic の配布物には<code>LoggerContextListener</code>インターフェイスの実装である<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/jul/LevelChangePropagator.html">LevelChangePropagator</a>が含まれるようになりました。これは、logback-classic のあらゆるロガーのレベルの変更を捉えて、java.util.logging フレームワークに伝播します。ログレベルの変化を伝播するのはコストが高いので、ロギング式を無効にすることで改善されたはずの性能が台無しになってしまいます。<a href="http://download.oracle.com/javase/1.5.0/docs/api/java/util/logging/LogRecord.html?is-external=true">LogRecord</a>のインスタンスはロギング式が有効な [...]
- </p>
-
-
- <p>contextListener要素に<code>LevelChangePropagator</code>を登録するには次のようにします。</p>
-
- <pre class="prettyprint source"><configuration debug="true">
- <b><contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/></b>
- ....
-</configuration></pre>
-
- <p>LevelChangePropagatorのプロパティ<span class="option">resetJUL</span>を指定すると、j.u.l.loggers に指定されていたレベルがすべて初期化されます。ただし、ハンドラーはそのまま残ります。</p>
-
- <pre class="prettyprint source"><configuration debug="true">
- <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
- <b><resetJUL>true</resetJUL></b>
- </contextListener>
- ....
-</configuration></pre>
- <p>
- </p>
-
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/manual/encoders.html b/docs/manual/encoders.html
index 674b676..3b359c7 100644
--- a/docs/manual/encoders.html
+++ b/docs/manual/encoders.html
@@ -27,8 +27,6 @@
<h1>Chapter 5: Encoders</h1>
- <a href="encoders_ja.html">和訳 (Japanese translation)</a>
-
<div class="quote">
<p><b>ACTION THIS DAY</b> Make sure they have all they want on
extreme priority and report to me that this has been done.
diff --git a/docs/manual/encoders_ja.html b/docs/manual/encoders_ja.html
deleted file mode 100644
index 89398bb..0000000
--- a/docs/manual/encoders_ja.html
+++ /dev/null
@@ -1,175 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"></meta>
- <title>第5章 エンコーダ</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第5章 エンコーダー</h1>
-
- <div class="quote">
- <p><b>ACTION THIS DAY</b>
-彼らの要求するものを全て最優先にして、それが終わったら報告してくれ。
- </p>
- <p>アラン・チューリングと彼の同僚の暗号解読者が署名した破格の予算請求書について、1941年10月、チャーチル首相がヘイスティングス・イスメイ将軍に伝えた言葉</p>
- </div>
-
- <script src="../templates/creative.js" type="text/javascript"></script>
- <script src="../templates/setup.js" type="text/javascript"></script>
-
-
- <h2 class="doAnchor">エンコーダーとは何か</h2>
-
- <p>エンコーダーの役割は、ロギングイベントをバイト配列に変換するだけでなく、そのバイト配列を<code>OutputStream</code>に書き込むことです。エンコーダーはlogback 0.9.19から導入されました。以前のバージョンでは、ほとんどのアペンダーはロギングイベントを文字列に変換して<code>java.io.Writer</code>に書き込むのをレイアウトに任せていました。また、以前のバージョンでは、利用者は<code>FileAppender</code>に<code>PatternLayout</code>をネストしていました。logback 0.9.19になってから、<code>FileAppender</code>もその派生クラスも、<a href="http://logback.qos.ch/codes.html#layoutInsteadOfEncoder">エンコーダーを利用するようになり、レイアウトを使わなくなりました</a>。
- </p>
-
- <p>どうしてこんな破壊的な変更をしたのか?</p>
-
- <p>詳細は次章で説明しますが、レイアウトにできるのはロギングイベントを文字列に変換することだけです。また、レイアウトはロギングイベントを書き込む間何もできません。ロギングイベントをまとめてバッチ的に処理することができないのです。対照的にエンコーダーはバイト配列を書式化している間だけでなく、書式化されたバイト配列を書き込んでいる間も完全に主導権を握っています。
- </p>
-
- <p>現時点では、利便性のあるエンコーダーは<code>PatternLayoutEncoder</code>だけです。単に<code>PatternLayout</code>をラップしただけで、ほとんどの仕事は任せてしまいます。一見すると、エンコーダーは不必要な複雑さだけをもたらしているようにも見えます。しかし、私たちは新しく強力なエンコーダーが登場することによってこういった印象を上書きしてくれることに期待しています。</p>
-
- <h2 class="doAnchor" name="interface">エンコーダーインターフェイス</h2>
-
- <p>エンコーダーの役割は、到着したロギングイベントをバイト配列に変換すること<b>と</b>変換されたバイト配列を適切な<code>OutputStream</code>に書き込むことです。前述したように、エンコーダーは親のアペンダーが管理している<code>OutputStream</code>に対して、いつ、どんなバイト配列を書き込むのか完全に制御することができます。<a href="http://logback.qos.ch/xref/ch/qos/logback/core/encoder/Encoder.html">エンコーダのインターフェイス</a>を見てみましょう。
-
- </p>
- <pre class="prettyprint source">package ch.qos.logback.core.encoder;
-
-public interface Encoder<E> extends ContextAware, LifeCycle {
-
- /**
- * This method is called when the owning appender starts or whenever output
- * needs to be directed to a new OutputStream, for instance as a result of a
- * rollover.
- */
- void init(OutputStream os) throws IOException;
-
- /**
- * Encode and write an event to the appropriate {@link OutputStream}.
- * Implementations are free to defer writing out of the encoded event and
- * instead write in batches.
- */
- void doEncode(E event) throws IOException;
-
-
- /**
- * This method is called prior to the closing of the underling
- * {@link OutputStream}. Implementations MUST not close the underlying
- * {@link OutputStream} which is the responsibility of the owning appender.
- */
- void close() throws IOException;
-}</pre>
-
- <p>見ての通り、<code>Encoder</code>インターフェイスには少ししかメソッドが宣言されていません。ですが、これらのメソッドだけで驚くほどたくさんの仕事ができるのです。
- </p>
-
-
- <h2 class="doAnchor">LayoutWrappingEncoder</h2>
-
- <p>logback0.9.19より前は、ほとんどのアペンダーがログの出力形式の面倒をレイアウトにまかせていました。レイアウトインターフェイスを使用するコードが大量に残っているので、レイアウトとエンコーダーを仲介する方法が必要でした。それをするのが<a href="http://logback.qos.ch/xref/ch/qos/logback/core/encoder/LayoutWrappingEncoder.html">LayoutWrappingEncoder</a>です。LayoutWrappingEncoder はエンコーダーインターフェイスを実装しています。そして、ラップしたレイアウトにロギングイベントを文字列に変換する仕事を委譲します。
- </p>
-
- <p><code>LayoutWrappingEncoder</code>のコードを一部抜粋して紹介します。レイアウトインスタンスにどうやって委譲しているのかがわかるでしょうか。。</p>
-
- <pre class="prettyprint source">package ch.qos.logback.core.encoder;
-
-public class LayoutWrappingEncoder<E> extends EncoderBase<E> {
-
- protected Layout<E> layout;
- private Charset charset;
- private boolean immediateFlush = true;
-
- public void doEncode(E event) throws IOException {
- String txt = layout.doLayout(event);
- outputStream.write(convertToBytes(txt));
- if (immediateFlush)
- outputStream.flush();
- }
-
- private byte[] convertToBytes(String s) {
- if (charset == null) {
- return s.getBytes();
- } else {
- return s.getBytes(charset);
- }
- }
-}</pre>
-
- <p><code>doEncode()</code>メソッドは、まず最初に受け取ったロギングイベントをラップしたレイアウトで文字列に変換します。そして変換結果の文字列を、使用者が指定した文字セットで符号化してバイト配列に変換します。次に、変換されたバイト配列を親アペンダーの<code>OutputStream</code>に書き込みます。デフォルトでは<code>OutputStream</code>をすぐにフラッシュします。ただし、<span class="prop">immediateFlush</span>プロパティに明示的にfalseが指定されているときはフラッシュしません。<span class="prop">immediateFlush</span>プロパティにfalseを指定しておくと、ロギングのスループットが大幅に向上します。設定例については、次の<code>PatternLayoutEncoder</code>のところで紹介します。
- </p>
-
-
- <h2 class="doAnchor">PatternLayoutEncoder</h2>
-
- <p><code>PatternLayout</code>は最も広く使われているレイアウトです。この一般的なユースケースに対応するため、logbackは<code>PatternLayoutEncoder</code>を提供しています。これは、<code>PatternLayout</code>のインスタンスだけをラップするようにした<code>LayoutWrappingEncoder</code>の派生クラスです。
- </p>
-
- <p>logback0.9.19の頃は、<code>FileAppender</code>やその派生クラスの設定には必ず<code>PatternLayout</code>が使われていました。今は代わりに<code>PatternLayoutEncoder</code>を使わなければなりません。これについては、<a href="http://logback.qos.ch/codes.html#layoutInsteadOfEncoder">logbackのエラーコード</a>でも説明しています。
- </p>
-
- <h4 class="doAnchor" name="immediateFlush"><span class="prop">immediateFlush</span>プロパティ</h4>
-
- <p><code>PatternLayoutEncoder</code> は<a href="http://logback.qos.ch/xref/ch/qos/logback/core/encoder/LayoutWrappingEncoder.html"><code>LayoutWrappingEncoder</code></a>の派生クラスなので、<span class="prop">immediateFlush</span>プロパティを設定することができます。<span class="prop">immediateFlush</span>のデフォルト値は"true"です。出力ストリームをすぐにフラッシュすることで、ロギングイベントがディスクに書き込まれること、アプリケーションが終了するときにちゃんとアペンダーを閉じなかったときでも、ロギングイベントが失われないことを保証することができます。一方、このプロパティに"false"を指定すると、(それが必要なのかどうかはわかりませんが)ロギングのスループットが5倍にまで向上する可能性があります。前述したとおり [...]
- </p>
-
- <p><code>FileAppender</code>に<code>PatternLayoutEncoder</code>を指定した設定例を見てみましょう。<span class="prop">immediateFlush</span>プロパティにはfalseを指定しています。</p>
-
-<pre class="prettyprint"><appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <file>foo.log</file>
- <encoder>
- <pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern>
- <!-- this quadruples logging throughput -->
- <b><immediateFlush>false</immediateFlush></b>
- </encoder>
-</appender></pre>
-
-
- <h4 class="doAnchor" name="outputPatternAsHeader">ヘッダに出力形式を入れる</h4>
-
- <p>ログファイルの解析を容易にするため、logbackはログファイルの先頭にログの出力形式を出力することができます。この機能はデフォルトでは<b>無効</b>になっています。<code>PatternLayoutEncoder</code>の<span class="prop">outputPatternAsHeader</span>プロパティにtrueを指定すれば、有効化することができます。以下に例を示します。</p>
-
-<pre class="prettyprint"><appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <file>foo.log</file>
- <encoder>
- <pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern>
- <b><outputPatternAsHeader>true</outputPatternAsHeader></b>
- </encoder>
-</appender></pre>
-
- <p>この設定を使うと次のように出力されます。</p>
-
- <pre>#logback.classic pattern: %d [%thread] %-5level %logger{36} - %msg%n
-2012-04-26 14:54:38,461 [main] DEBUG com.foo.App - Hello world
-2012-04-26 14:54:38,461 [main] DEBUG com.foo.App - Hi again
-...</pre>
-
- <p>先頭行の"#logback.classic pattern"が出力形式として出力されたヘッダです。</p>
-
-
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-
- </div>
- </body>
-</html>
\ No newline at end of file
diff --git a/docs/manual/filters.html b/docs/manual/filters.html
index 610f9f7..fc15ae5 100644
--- a/docs/manual/filters.html
+++ b/docs/manual/filters.html
@@ -30,8 +30,6 @@
<h1>Chapter 7: Filters</h1>
- <a href="filters_ja.html">和訳 (Japanese translation)</a>
-
<div class="quote">
<p><em>Have lots of ideas and throw away the bad ones. You aren't
going to have good ideas unless you have lots of ideas and some
@@ -137,7 +135,7 @@ public class SampleFilter extends Filter<ILoggingEvent> {
</p>
<em>Example: SampleFilter configuration
- (logback-examples/src/main/resources/chapters/filters/SampleFilterConfig.xml)</em>
+ (logback-examples/src/main/java/chapters/filters/SampleFilterConfig.xml)</em>
<span class="asGroovy" onclick="return asGroovy('SampleFilterConfig');">View as .groovy</span>
<pre id="SampleFilterConfig" class="prettyprint source"><configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
@@ -194,7 +192,7 @@ public class SampleFilter extends Filter<ILoggingEvent> {
</p>
<em>Example: Sample LevelFilter configuration
- (logback-examples/src/main/resources/chapters/filters/levelFilterConfig.xml)</em>
+ (logback-examples/src/main/java/chapters/filters/levelFilterConfig.xml)</em>
<span class="asGroovy" onclick="return asGroovy('levelFilterConfig');">View as .groovy</span>
<pre id="levelFilterConfig" class="prettyprint source"><configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
@@ -227,7 +225,7 @@ public class SampleFilter extends Filter<ILoggingEvent> {
</p>
<em>Example: Sample ThresholdFilter configuration
- (logback-examples/src/main/resources/chapters/filters/thresholdFilterConfig.xml)</em>
+ (logback-examples/src/main/java/chapters/filters/thresholdFilterConfig.xml)</em>
<span class="asGroovy" onclick="return asGroovy('thresholdFilterConfig');">View as .groovy</span>
<pre id="thresholdFilterConfig" class="prettyprint source"><configuration>
<appender name="CONSOLE"
@@ -529,7 +527,7 @@ public class SampleFilter extends Filter<ILoggingEvent> {
<p>Here is a concrete example.</p>
<em>Example: Basic event evaluator usage
- (logback-examples/src/main/resources/chapters/filters/basicEventEvaluator.xml)</em>
+ (logback-examples/src/main/java/chapters/filters/basicEventEvaluator.xml)</em>
<span class="asGroovy" onclick="return asGroovy('basicEventEvaluator');">View as .groovy</span>
<pre id="basicEventEvaluator" class="prettyprint source longline"><configuration>
@@ -663,7 +661,7 @@ java chapters.filters.FilterEvents src/main/java/chapters/filters/basicConfigura
<p>An example should clarify the point:</p>
- <em>Example: Defining matchers in an event evaluator (logback-examples/src/main/resources/chapters/filters/evaluatorWithMatcher.xml)</em>
+ <em>Example: Defining matchers in an event evaluator (logback-examples/src/main/java/chapters/filters/evaluatorWithMatcher.xml)</em>
<span class="asGroovy" onclick="return asGroovy('evaluatorWithMatcher');">View as .groovy</span>
<pre id="evaluatorWithMatcher" class="prettyprint source"><configuration debug="true">
@@ -820,7 +818,7 @@ public class SampleTurboFilter extends TurboFilter {
</p>
<em>Example: Basic custom <code>TurboFilter</code> configuration
- (logback-examples/src/main/resources/chapters/filters/sampleTurboFilterConfig.xml)</em>
+ (logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml)</em>
<span class="asGroovy" onclick="return asGroovy('sampleTurboFilterConfig');">View as .groovy</span>
@@ -860,7 +858,7 @@ public class SampleTurboFilter extends TurboFilter {
<em>Example: <code>MDCFilter</code> and <code>MarkerFilter</code>
configuration
- (logback-examples/src/main/resources/chapters/filters/turboFilters.xml)</em>
+ (logback-examples/src/main/java/chapters/filters/turboFilters.xml)</em>
<span class="asGroovy" onclick="return asGroovy('turboFilters');">View as .groovy</span>
<pre id="turboFilters" class="prettyprint source"><configuration>
@@ -989,7 +987,7 @@ logger.debug("Hello {}.", name1);</pre>
<em>Example: <code>DuplicateMessageFilter</code>
- configuration (logback-examples/src/main/resources/chapters/filters/duplicateMessage.xml)</em>
+ configuration (logback-examples/src/main/java/chapters/filters/duplicateMessage.xml)</em>
<span class="asGroovy" onclick="return asGroovy('duplicateMessage');">View as .groovy</span>
<pre id="duplicateMessage" class="prettyprint source"><configuration>
@@ -1149,7 +1147,7 @@ logger.debug("Hello {}.", name1);</pre>
(Not Found)</a> HTTP response code. Every request resulting in a
404 will be printed on the console.</p>
-<em>Example: Access Evaluator (logback-examples/src/main/resources/chapters/filters/accessEventEvaluator.xml)</em>
+<em>Example: Access Evaluator (logback-examples/src/main/java/chapters/filters/accessEventEvaluator.xml)</em>
<pre class="prettyprint source"><configuration>
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
@@ -1171,7 +1169,7 @@ logger.debug("Hello {}.", name1);</pre>
</p>
- <em>Example 6.10: Access Evaluator (logback-examples/src/main/resources/chapters/filters/accessEventEvaluator2.xml)</em>
+ <em>Example 6.10: Access Evaluator (logback-examples/src/main/java/chapters/filters/accessEventEvaluator2.xml)</em>
<pre class="prettyprint source"><configuration>
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
diff --git a/docs/manual/filters_ja.html b/docs/manual/filters_ja.html
deleted file mode 100644
index 8ed082a..0000000
--- a/docs/manual/filters_ja.html
+++ /dev/null
@@ -1,818 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第7章 フィルター</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第7章 フィルター</h1>
-
- <div class="quote">
- <p><em>たくさんのアイデアを集めて悪いものを捨てていこう。たくさんのアイデアと、自分なりの基準が無ければ、いいアイデアに巡り会えることはない。</em></p>
-
- <p>—LINUS PAULING</p>
- </div>
-
- <script src="../templates/creative.js" type="text/javascript"></script>
-
- <p>ここまでに、<a href="http://logback.qos.ch/manual/architecture.html#basic_selection">基本的な選択ルール</a>がlogback-classicモジュールの中核を担っていることを説明してきました。本章では、それに加えてフィルタリングの方法を紹介します。
- </p>
-
-
- <p>logbackのフィルターは、三値論理に基づいて合成や連結を駆使して、任意に複雑な条件を実現することができます。主に Linux の iptables から着想を得たものです。
- </p>
-
- <script src="../templates/setup.js" type="text/javascript"></script>
-
- <h2>logback-classicモジュール</h2>
-
-
- <p>logback-classic モジュールには二種類のフィルターがあります。通常フィルターとターボフィルターです。
- </p>
-
- <h3 class="doAnchor" name="filter">通常フィルター</h3>
-
- <p>通常フィルターとは、<a href="http://logback.qos.ch/xref/ch/qos/logback/core/filter/Filter.html"><code>Filter</code></a>抽象クラスを継承したものです。本質的には<code>ILoggingEvent</code>を引数にとる<code>decide()</code>メソッドを実装することが目的です。
- </p>
-
-
- <p>フィルターは順序付きリストにまとめて扱われます。また、三値論理に基づいて扱われます。それぞれのフィルターの<code>decide(ILoggingEvent event)</code>メソッドが順番に呼び出されます。このメソッドは<a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/FilterReply.html"><code>FilterReply</code></a>列挙型の値である、<code>DENY</code> 、 <code>NEUTRAL</code>または<code>ACCEPT</code>を返します。<code>decide()</code>メソッドが<code>DENY</code>を返したら、そのロギングイベントは残りのフィルターに渡されることなく、ただちに破棄されます。<code>NEUTRAL</code>を返したら、リスト内の次のフィルターに渡されます。リストの末尾に到達したら、そのロギングイベントは通常通りに処理されることになります。<code>ACCEPT [...]
- </p>
-
- <p>logback-classicモジュールでは、<code>Appender</code>にフィルターを追加することが出来ます。アペンダーに複数のフィルターを登録すれば、ロギングイベントをさまざまな条件で篩にかけられるようになります。ロギングメッセージの内容やMDCの内容、時刻や日付などロギングイベントのあらゆる内容を判定できるのです。
- </p>
-
- <h3 class="doAnchor" name="yourOwnFilter">フィルターを自作する</h3>
-
- <p>フィルターを自作するのは簡単です。<code>Filter</code>抽象クラスを継承して<code>decide()</code>メソッドを実装するだけです。
- </p>
-
- <p>例としてSampleFilterクラスを見てください。<code>decide()</code>メソッドがACCEPTを返すのは、ロギングイベントのメッセージに "sample" という文字列が含まれる場合だけです。その他の場合はNEUTRALを返すようになっています。
- </p>
-
- <p class="example">例:基本的な自作フィルター(<a href="http://logback.qos.ch/xref/chapters/filters/SampleFilter.html">logback-examples/src/main/java/chapters/filters/SampleFilter.java</a>)</p>
-
- <pre class="prettyprint source">package chapters.filters;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.filter.Filter;
-import ch.qos.logback.core.spi.FilterReply;
-
-public class SampleFilter extends Filter<ILoggingEvent> {
-
- @Override
- public FilterReply decide(ILoggingEvent event) {
- if (event.getMessage().contains("sample")) {
- return FilterReply.ACCEPT;
- } else {
- return FilterReply.NEUTRAL;
- }
- }
-}</pre>
-
- <p>次の設定ファイルでは、<code>ConsoleAppender</code>に<code>SampleFilter</code>を割り当てています。
- </p>
-
- <p class="example">例:SampleFilterの設定(<a href="http://logback.qos.ch/xref/chapters/filters/SampleFilterConfig.xml">logback-examples/src/main/java/chapters/filters/SampleFilterConfig.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('SampleFilterConfig');">Groovyとして表示</span>
- <pre id="SampleFilterConfig" class="prettyprint source"><configuration>
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-
- <b><filter class="chapters.filters.SampleFilter" /></b>
-
- <encoder>
- <pattern>
- %-4relative [%thread] %-5level %logger - %msg%n
- </pattern>
- </encoder>
- </appender>
-
- <root>
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>設定フレームワークの Joran を使えばフィルターのプロパティやサブコンポーネントを指定するのも簡単です。フィルタークラスにフィールドのセッターメソッドを追加すれば、<code>filter要素</code>にネストしてプロパティの値を指定することができます。
- </p>
-
- <p>たいていの場合フィルタリング条件には2つの直行する条件が含まれています。マッチするかどうかの条件と、何を返すのかの条件です。たとえば、メッセージが"foobar"だったらACCEPTを返し、そうでなければNEUTRALを返すフィルターもありますし、メッセージが"foobar"だったらNEUTRALを返し、そうでなければDENYを返すフィルターもあります。
- </p>
-
- <p>logback の配布物には、この直交性に焦点を当てた<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/filter/AbstractMatcherFilter.html">AbstractMatcherFilter</a></code>が含まれています。このクラスはフィルター条件の判定結果に基づいて何らかの値を返すスケルトンです。判定結果が真の時に返す値を<em>OnMatch</em>プロパティに、偽の時に返す値を<em>OnMismatch</em>プロパティに指定することができます。logbackの配布物に含まれるほとんどの通常フィルターは<code>AbstractMatcherFilter</code>を継承しています。
- </p>
-
- <h3 class="doAnchor" name="levelFilter">LevelFilter</h3>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/filter/LevelFilter.html">LevelFilter</a></code>は、ロギングイベントのログレベルの正確なマッチングに基づいたフィルタリングをします。ログレベルが設定されたレベルと等しければ、<span class="option">omMatch</span>プロパティあるいは<span class="option">omMismach</span>プロパティに設定された値に応じて、ロギングイベントを受け入れるか拒否するかが決まります。設定ファイルを見てみましょう。
- </p>
-
- <p class="example">例:LevelFilterの設定例(<a href="http://logback.qos.ch/xref/chapters/filters/levelFilterConfig.xml">logback-examples/src/main/java/chapters/filters/levelFilterConfig.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('levelFilterConfig');">Groovyとして表示</span>
- <pre id="levelFilterConfig" class="prettyprint source"><configuration>
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <b><filter class="ch.qos.logback.classic.filter.LevelFilter">
- <level>INFO</level>
- <onMatch>ACCEPT</onMatch>
- <onMismatch>DENY</onMismatch>
- </filter></b>
- <encoder>
- <pattern>
- %-4relative [%thread] %-5level %logger{30} - %msg%n
- </pattern>
- </encoder>
- </appender>
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-</configuration></pre>
-
- <h3 class="doAnchor" name="thresholdFilter">ThresholdFilter</h3>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/filter/ThresholdFilter.html">ThresholdFilter</a></code>は、ログレベルが指定されたしきい値より低いロギングイベントをフィルタリングします。ログレベルがしきい値と同じかより高い場合、<code>ThresholdFilter</code>の<code>decide()</code>はNEUTRALを返します。一方、しきい値より低いログレベルのロギングイベントは拒否します。設定ファイルを見てみましょう。
- </p>
-
- <p class="example">例:ThresholdFilterの設定例(<a href="http://logback.qos.ch/xref/chapters/filters/thresholdFilterConfig.xml">logback-examples/src/main/java/chapters/filters/thresholdFilterConfig.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('thresholdFilterConfig');">Groovyとして表示</span>
- <pre id="thresholdFilterConfig" class="prettyprint source"><configuration>
- <appender name="CONSOLE"
- class="ch.qos.logback.core.ConsoleAppender">
- <!-- deny all events with a level below INFO, that is TRACE and DEBUG -->
- <b><filter class="ch.qos.logback.classic.filter.ThresholdFilter">
- <level>INFO</level>
- </filter></b>
- <encoder>
- <pattern>
- %-4relative [%thread] %-5level %logger{30} - %msg%n
- </pattern>
- </encoder>
- </appender>
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-</configuration></pre>
-
-
- <h2 class="doAnchor" name="evalutatorFilter">EvaluatorFilter</h2>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/core/filter/EvaluatorFilter.html"><code>EvaluatorFilter</code></a>は内部で<code>EventEvaluator</code>を使用する汎用的なフィルターです。名前のとおり、ロギングイベントが<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/boolex/EventEvaluator.html">EventEvaluator</a></code>に指定された条件を満たすかどうかを評価します。評価結果がなんであれ、<code>EvaluatorFilter</code>に設定された<span class="option">onMatch</span>プロパティまたは<span class="option">onMismatch</span>プロパティの値を返します。
- </p>
-
-
- <p><code>EventEvaluator</code>は抽象クラスです。つまり、<code>EventEvaluator</code>を継承すれば、独自のイベント評価ロジックを実装することができます。
- </p>
-
-
- <!-- ======================== GEventEvaluator ========================= -->
-
- <h3 class="doAnchor" name="GEventEvaluator">GEventEvaluator</h3>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/GEventEvaluator.html">GEventEvaluator</a>は<a href="http://logback.qos.ch/xref/ch/qos/logback/core/boolex/EventEvaluator.html"><code>EventEvaluator</code></a>の派生クラスで、評価条件に結果が真偽値になるGroovy言語で書かれた任意の式を指定することができます。私たちはこのGroovy言語で書かれた式のことを "Groovy評価式" と呼んでいます。Groovy評価式を使うと、ロギングイベントをこれまでにないくらい柔軟にフィルタリングできるようになります。<code>GEventEvaluator</code> を使うにはGroovyのランタイムが必要です。設定ドキュメントの<a href="http://logback.qos.ch/setup.html#groovy"> [...]
- </p>
-
- <p>Groovy評価式は設定ファイルを解釈する際にコンパイルされます。どのように実行させるのかか、利用者が考える必要はありません。しかし、Groovy言語として間違いが無いことを保証するのは使用者の責任です。
- </p>
-
- <p>Groovy評価式は一度に1つのロギングイベントを扱います。logbackは、ロギングイベントを<a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/spi/ILoggingEvent.html">ILoggingEvnet</a>型の変数'<em>event</em>'あるいは'<em>e</em>'として用意します。また、ログレベルのTRACE、DBUG、INFO、WARN、ERROR は、Groovy評価式から同じ名前の変数として使用することが出来ます。したがって、"event.level == DEBUG" と "e.level == DEBUG" は同じ意味のGroovy評価式ということになります。ロギングイベントのログレベルがDEBUGの場合、式の値は<code>true</code>になります。他の比較演算子を使うときは、ログレベルの変数に<code>toInt()</code>演算子を適用して、整数値として評価しなければなりません。
- </p>
-
- <p>具体的な例を見てみましょう。</p>
-
- <span class="asGroovy" onclick="return asGroovy('GEventEvaluator');">Groovyとして表示</span>
- <pre id="GEventEvaluator" class="prettyprint source"><configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <b><filter class="ch.qos.logback.core.filter.EvaluatorFilter">
- <evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator">
- <expression>
- e.level.toInt() >= WARN.toInt() && <!-- Stands for && in XML -->
- !(e.mdc?.get("req.userAgent") =~ /Googlebot|msnbot|Yahoo/ )
- </expression>
- </evaluator>
- <OnMismatch>DENY</OnMismatch>
- <OnMatch>NEUTRAL</OnMatch>
- </filter></b>
- <encoder>
- <pattern>
- %-4relative [%thread] %-5level %logger - %msg%n
- </pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
-
- <p>この設定は、ログレベルがWARN以上で、ユーザーエージェントがクローラー(GooglebotやmsnbotやYahoo)以外のロギングイベントのメッセージをコンソールに出力します。ロギングイベントに関連付けられた MDC の "req.userAgent" の値を正規表現<code>/Googlebot|msnbot|Yahoo/</code>で評価して、ユーザーエージェントを判定しています。MDCがnullになることもあるので、Groovyの<a href="http://groovy.codehaus.org/Null+Object+Pattern">安全なデリファレンス演算子</a>(?.)を使っています。同じことをJava言語で実装するともっと長くなってしまうでしょう。
- </p>
-
- <p>ユーザーエージェント文字列がいつMDCに登録されたのか疑問に思うかもしれません。説明しておくべきでしたが、logbackの配布物に含まれている<a href="http://logback.qos.ch/manual/mdc.html#mis"><code>MDCInsertingServletFilter</code></a>を使っています。詳しくは後の章で説明します。
- </p>
-
- <!-- ==================== JaninoEventEvaluator ======================== -->
-
- <h3 class="doAnchor" name="JaninoEventEvaluator">JaninoEventEvaluator</h3>
-
-
- <p>logback-classicの配布物には、<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/JaninoEventEvaluator.html">JaninoEventEvaluator</a>という<code>EventEvaluator</code>の別の実装クラスが含まれています。これは、booleanを返す任意のJava言語のブロックを評価するものです。私たちはこのJava言語で書かれた式のことを"<em>Java評価式</em>”と呼んでいます。Java評価式を使うとロギングイベントを柔軟にフィルタリングできるようになります。<code>JaninoEventEvaluator</code>を使用するには<a href="http://docs.codehaus.org/display/JANINO/Home">Janinoライブラリ</a>が必要です。設定方法は設定ドキュメントの<a href="http://logback.qos.ch/setup.html# [...]
- </p>
-
- <p>Java評価式は設定ファイルを解釈する間にコンパイルされます。どのように呼び出すのか、利用者は気にすることはありません。ですが、Java言語の式が真偽値を返すものであることを保証するのは利用者の責任です。</p>
-
-
- <p>Java評価式は一度に1つのロギングイベントを扱います。logback-classicは、ロギングイベントのいろいろなフィールドをJava評価式から参照できる変数として自動的に公開します。公開する変数の名前は大文字小文字を区別するものです。表にまとめました。
- </p>
-
- <table class="bodyTable">
- <tr>
- <th>変数名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td>event</td>
- <td><code>LoggingEvent</code></td>
-
- <td>ロギング要求に関連付けられたロギングイベントそのもの。以下の変数はロギングイベントから参照することができます。たとえば、 <code>event.getMessage()</code>は<em>message</em>変数と同じ文字列を返します。
- </td>
- </tr>
-
- <tr class="alt">
- <td>message</td>
- <td><code>String</code></td>
- <td>ロギング要求に指定されたメッセージそのものです。ロガー<em>l</em>について l.info("Hello {}", name); というロギング式があったとき、"Hello {}" がメッセージとなります。</td> </tr>
-
- <tr>
- <td>formattedMessage</td>
- <td><code>String</code></td>
- <td>ロギング要求の書式化されたメッセージ。ロガー<em>l</em>について l.info("Hello {}", name); というロギング式があったとき、nameの値が"Alice"なら、"Hello Alice" が書式化されたメッセージになります。</td>
- </tr>
-
- <tr class="alt">
- <td>logger</td>
- <td><code>String</code></td>
- <td>ロガーの名前。
- </td>
- </tr>
-
- <tr>
- <td>loggerContext</td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/spi/LoggerContextVO.html"><code>LoggerContextVO</code></a></td>
- <td>ロギングイベントが割り当てられたロガーコンテキストの、値オブジェクトとしてのビュー。
- </td>
- </tr>
-
-
- <tr class="alt">
- <td>level</td>
- <td><code>int</code></td>
- <td>ログレベルに対応する整数値。ログレベルを含む評価式を簡潔にするため、<em>DEBUG</em>、<em>INFO
-</em>、<em>WARN</em>、<em>ERROR</em>が利用できるようになっています。たとえば、<em> level > INFO </em> は正しい評価式です。
- </td>
- </tr>
-
- <tr>
- <td>timeStamp
- </td>
- <td><code>long</code></td>
- <td>ロギングイベントの作成時のタイムスタンプ。
- </td>
- </tr>
- <tr class="alt">
- <td>marker</td>
- <td><code>Marker</code></td>
- <td>ロギング要求に関連付けられた<code>Marker</code>オブジェクト。マーカーオブジェクトがnullの場合もあるので、<code>NullPointerException</code>を避けるためにnullチェックをするのは使用者の責任です。
- </td>
- </tr>
- <tr>
- <td>mdc</td>
- <td><code>Map</code></td>
- <td>ロギングイベントの作成時に関連付けられたMDC。<em>mdc.get("MYKEY")</em>とすると値を参照できます。logback-classic 0.9.30以降では、'mdc'変数は決してnullになりません。
-
- <p>Janino はジェネリクスをサポートしていないので、<code>java.util.Map</code>には型パラメータがありません。つまり、<code>mdc.get()</code>の返り値の型は<code>Object</code>であって<code>String</code>ではないのです。戻り値で<code>String</code>のメソッドを実行するには、<code>String</code>にキャストしなければなりません。こんな感じです。
- <code>((String) mdc.get("k")).contains("val")</code>
- </p>
- </td>
- </tr>
-
- <tr class="alt">
- <td>throwable</td>
- <td>java.lang.Throwable</td>
- <td>ロギングイベントに例外オブジェクトが関連付けられていないときは、"throwable"変数はnullになります。"throwable"変数はシリアライズすると失われてしまいます。したがって、リモートサーバ側ではこの値は常にnullになります。ローカルとリモートで同じ評価式を使いたい場合は、次項の<code>throwableProxy</code>変数を使用してください。
- </td>
- </tr>
-
- <tr>
- <td>throwableProxy</td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/spi/IThrowableProxy.html"><code>IThrowableProxy</code></a></td>
- <td>ロギングイベント関連付けられた例外オブジェクトのプロキシオブジェクト。例外オブジェクトが関連付けられていないとき、"throwableProxy"変数はnullになります。"throwable"変数と違って、例外オブジェクトがロギングイベントに関連付けられているときは、シリアライズされてリモートサーバに渡された後でも "throwableProxy"変数の値はnullになりません。
- </td>
- </tr>
-
-
-
- </table>
-
- <p>具体的な例を見てみましょう。</p>
-
- <p class="example">例:評価式の基本的な使い方(<a href="http://logback.qos.ch/xref/chapters/filters/basicEventEvaluator.xml">logback-examples/src/main/java/chapters/filters/basicEventEvaluator.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('basicEventEvaluator');">Groovyとして表示</span>
- <pre id="basicEventEvaluator" class="prettyprint source longline"><configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <b><filter class="ch.qos.logback.core.filter.EvaluatorFilter">
- <evaluator> <!-- defaults to type ch.qos.logback.classic.boolex.JaninoEventEvaluator -->
- <expression><span class="green">return message.contains("billing");</span></expression>
- </evaluator>
- <OnMismatch>NEUTRAL</OnMismatch>
- <OnMatch>DENY</OnMatch>
- </filter></b>
- <encoder>
- <pattern>
- %-4relative [%thread] %-5level %logger - %msg%n
- </pattern>
- </encoder>
- </appender>
-
- <root level="INFO">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>設定ファイル中の太字部分で、<code>ConsoleAppender</code>に<code>EvaluatorFilter</code>を追加しています。<code>EvaluationFilter</code>に追加されたのは<code>JaninoEventEvaluator</code>です。<code>evaluator要素</code>の<span class="attr">class属性</span>を省略すると、Joranはデフォルトの<code>JaninoEventEvaluator</code>を使用します。これはJoranが暗黙的にコンポーネントの型を推測する<a href="http://logback.qos.ch/manual/onJoran.html#defaultClassMapping">珍しいケース</a>の1つです。
- </p>
-
- <p><em>expression要素</em>に指定されているのは評価式です。<code>return message.contains("billing");</code>という式の値は真偽値です。<em>message変数</em>は、<code>JaninoEventEvaluator</code>が自動的に公開した変数です。
- </p>
-
- <p><span class="option">OnMismatch</span>プロパティにNEUTRALが、<span class="option">OnMatch</span>プロパティにDENYが指定されているので、このフィルターはメッセージに"billing"という文字列の含まれているロギングイベントをすべて拒否することになります。
- </p>
-
- <p><a href="http://logback.qos.ch/xref/chapters/filters/FilterEvents.html"><code>FilterEvents</code></a>アプリケーションでは、0〜9までの連番を付けられた10個のロギング要求を生成します。まずはフィルター無しで<code>FilterEvents</code>を実行してみましょう。</p>
-
-<div class="source"><pre>
-java chapters.filters.FilterEvents src/main/java/chapters/filters/basicConfiguration.xml
-</pre></div>
-
- <p>次のように、全てのロギング要求が出力されます。</p>
-
-<div class="source"><pre>0 [main] INFO chapters.filters.FilterEvents - logging statement 0
-0 [main] INFO chapters.filters.FilterEvents - logging statement 1
-0 [main] INFO chapters.filters.FilterEvents - logging statement 2
-0 [main] DEBUG chapters.filters.FilterEvents - logging statement 3
-0 [main] INFO chapters.filters.FilterEvents - logging statement 4
-0 [main] INFO chapters.filters.FilterEvents - logging statement 5
-0 [main] ERROR chapters.filters.FilterEvents - <b>billing statement 6</b>
-0 [main] INFO chapters.filters.FilterEvents - logging statement 7
-0 [main] INFO chapters.filters.FilterEvents - logging statement 8
-0 [main] INFO chapters.filters.FilterEvents - logging statement 9</pre></div>
-
-
-
- <p>この中から"billing statement"を取り除きたいものとします。上記の<em>basicEventEvaluator.xml</em>では、メッセージに"billing"を含むロギングイベントをフィルタリングするので、まさに今欲しいものです。</p>
-
- <p><em>basicEventEvaluator.xml</em>を使って実行してみましょう。</p>
- <p class="source">java chapters.filters.FilterEvents src/main/java/chapters/filters/basicEventEvaluator.xml</p>
- <p>次のような出力になります。</p>
-
- <p class="source">0 [main] INFO chapters.filters.FilterEvents - logging statement 0
-0 [main] INFO chapters.filters.FilterEvents - logging statement 1
-0 [main] INFO chapters.filters.FilterEvents - logging statement 2
-0 [main] DEBUG chapters.filters.FilterEvents - logging statement 3
-0 [main] INFO chapters.filters.FilterEvents - logging statement 4
-0 [main] INFO chapters.filters.FilterEvents - logging statement 5
-0 [main] INFO chapters.filters.FilterEvents - logging statement 7
-0 [main] INFO chapters.filters.FilterEvents - logging statement 8
-0 [main] INFO chapters.filters.FilterEvents - logging statement 9</p>
-
-
- <p>Java評価式にはJavaのコードブロックを指定できます。つまり次のようなものでも正しい式なのです。</p>
-
- <pre class="prettyprint source"><evaluator>
- <expression>
- if(logger.startsWith("org.apache.http"))
- return true;
-
- if(mdc == null || mdc.get("entity") == null)
- return false;
-
- String payee = (String) mdc.get("entity");
-
- if(logger.equals("org.apache.http.wire") && <!-- & encoded as & -->
- payee.contains("someSpecialValue") &&
- !message.contains("someSecret")) {
- return true;
- }
-
- return false;
- </expression>
-</evaluator></pre>
-
-
- <h2 class="doAnchor" name="matcher">マッチャー</h2>
-
- <p><code>String</code>の<a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#matches%28java.lang.String%29">matchs()</a>メソッドを使えば文字列のパターンマッチをすることができます。ですが、毎回<code>Pattern</code>(正規表現)オブジェクトをコンパイルするコストがかかるので、つまりフィルターが呼び出されるたびにコストがかかることになってしまいます。このオーバーヘッドを無くすため、<a href="http://logback.qos.ch/xref/ch/qos/logback/core/boolex/Matcher.html">Matcher</a>オブジェクトを事前に複数用意することができます。定義したマッチャーオブジェクトは評価式の中から名前で参照できるようになります。</p>
-
- <p>マッチャーの使用例を見てみましょう。</p>
-
- <p class="example">例:マッチャーの定義(<a href="http://logback.qos.ch/xref/chapters/filters/evaluatorWithMatcher.xml">logback-examples/src/main/java/chapters/filters/evaluatorWithMatcher.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('evaluatorWithMatcher');">Groovyとして表示</span>
-
- <pre id="evaluatorWithMatcher" class="prettyprint source"><configuration debug="true">
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
- <evaluator>
- <b><matcher>
- <Name>odd</Name>
- <!-- filter out odd numbered statements -->
- <regex>statement [13579]</regex>
- </matcher>
-
- <expression>odd.matches(formattedMessage)</expression></b>
- </evaluator>
- <OnMismatch>NEUTRAL</OnMismatch>
- <OnMatch>DENY</OnMatch>
- </filter>
- <encoder>
- <pattern>%-4relative [%thread] %-5level %logger - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p><em>evaluatorWithMatcher.xml</em>の設定を使ってみましょう。</p>
- <p class="source">java chapters.filters.FilterEvents src/main/java/chapters/filters/evaluatorWithMatcher.xml</p>
- <p>コンソールには次のように出力されます。</p>
-
- <p class="source">260 [main] INFO chapters.filters.FilterEvents - logging statement 0
-264 [main] INFO chapters.filters.FilterEvents - logging statement 2
-264 [main] INFO chapters.filters.FilterEvents - logging statement 4
-266 [main] ERROR chapters.filters.FilterEvents - billing statement 6
-266 [main] INFO chapters.filters.FilterEvents - logging statement 8</p>
-
- <p>マッチャーを追加したければ、<code>matcher要素</code>を追加すればよいでしょう。</p>
-
-
-
-
-
- <!-- ================================================================ -->
- <!-- ===================== TURBO FILTER ============================= -->
- <!-- ================================================================ -->
-
- <h2 class="doAnchor" name="TurboFilter">TurboFilters</h2>
-
- <p><code>ターボフィルター</code>とは、<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/turbo/TurboFilter.html"><code>TurboFilter</code></a>抽象クラスを継承したオブジェクトのことです。通常フィルターと同様に、三値論理でロギングイベントを評価します。
- </p>
-
- <p>全体的に前に説明したフィルターと同じように動作します。ただし、<code>Filter</code>と<code>TurboFilter</code>には大きな違いが2つあります。
- </p>
-
- <p><code>TurboFilter</code>はロギングコンテキストに紐付けられています。したがって、アペンダーが使用されたときにだけ呼ばれるのではなく、ロギング要求が発生するたびに呼ばれることになります。つまり、ターボフィルターの有効範囲はアペンダーに割り当てられたフィルターよりも広いのです。
- </p>
-
- <p>さらに重要なのは、ターボフィルターが呼ばれるのは<code>LoggingEvent</code>オブジェクトが作成される前だということです。
- <code>TurboFilter</code>オブジェクトは、ロギング要求をフィルタリングするのにロギングイベントを必要としません。つまり、ターボフィルターはロギングイベントの高速なフィルタリングを意図したものなのです。
- </p>
-
-
- <h3 class="doAnchor" name="yourOwnTurboFilter">ターボフィルターを自作する</h3>
-
- <p><code>ターボフィルター</code>を自作するには、<code>TurboFilter</code>抽象クラスを継承するだけです。前述のとおり、フィルターを自作するには<code>decide()</code>メソッドを実装するだけでいいのです。少し複雑なフィルターの実装例を見てみましょう。</p>
-
- <p class="example">例:基本的な自作<code>TurboFilter</code>(<a href="http://logback.qos.ch/xref/chapters/filters/SampleTurboFilter.html">logback-examples/src/main/java/chapters/filters/SampleTurboFilter.java</a>)</p>
-
-<pre class="prettyprint source">package chapters.filters;
-
-import org.slf4j.Marker;
-import org.slf4j.MarkerFactory;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.turbo.TurboFilter;
-import ch.qos.logback.core.spi.FilterReply;
-
-public class SampleTurboFilter extends TurboFilter {
-
- String marker;
- Marker markerToAccept;
-
- @Override
- public FilterReply decide(Marker marker, Logger logger, Level level,
- String format, Object[] params, Throwable t) {
-
- if (!isStarted()) {
- return FilterReply.NEUTRAL;
- }
-
- if ((markerToAccept.equals(marker))) {
- return FilterReply.ACCEPT;
- } else {
- return FilterReply.NEUTRAL;
- }
- }
-
- public String getMarker() {
- return marker;
- }
-
- public void setMarker(String markerStr) {
- this.marker = markerStr;
- }
-
- @Override
- public void start() {
- if (marker != null && marker.trim().length() > 0) {
- markerToAccept = MarkerFactory.getMarker(marker);
- super.start();
- }
- }
-}
-</pre>
-
- <p>この<code>ターボフィルター</code>は、特定のマーカーが含まれているロギングイベントを受け付けます。マーカーが見つからなかったら、チェーン内の次のフィルターに引き継ぎます。
- </p>
-
- <p>柔軟性を考慮して、チェックするマーカーを設定ファイルで指定できるよう、アクセサメソッドが定義されています。他にも、設定ファイルの解釈中に、指定されたオプションをチェックするため、<code>start()</code>メソッドを実装しています。
- </p>
-
- <p>自作した<code>ターボフィルター</code>を使う設定ファイルは次のとおりです。
- </p>
-
- <p class="example">例:基本的な自作<code>TurboFilter</code>の設定(<a href="http://logback.qos.ch/xref/chapters/filters/sampleTurboFilterConfig.xml">logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('sampleTurboFilterConfig');">Groovyとして表示</span>
-
- <pre id="sampleTurboFilterConfig" class="prettyprint source"><configuration>
- <b><turboFilter class="chapters.filters.SampleTurboFilter">
- <Marker>sample</Marker>
- </turboFilter></b>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>
- %-4relative [%thread] %-5level %logger - %msg%n
- </pattern>
- </encoder>
- </appender>
-
- <root>
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>logback-classicの配布物にはいくつか<code>TurboFilter</code>の実装クラスが含まれています。<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/turbo/MDCFilter.html"><code>MDCFilter</code></a>を使うとMDC内の指定された値の存在をチェックすることができますし、<a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/turbo/DynamicThresholdFilter.html"><code>DynamicThresholdFilter</code></a>を使うとMDCのキーまたはレベルをしきい値でフィルタリングすることができます。また、<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/turbo/MarkerFilter.html"><code>MarkerFilter [...]
-
- <p><code>MDCFilter</code>と<code>MarkerFilter</code>の両方を使う設定を見てみましょう。
- </p>
-
- <p class="example">例:<code>MDCFilter</code>と<code>MarkerFilter</code>の設定例(<a href="http://logback.qos.ch/xref/chapters/filters/turboFilters.xml">logback-examples/src/main/java/chapters/filters/turboFilters.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('turboFilters');">Groovyとして表示</span>
- <pre id="turboFilters" class="prettyprint source"><configuration>
-
- <turboFilter class="ch.qos.logback.classic.turbo.MDCFilter">
- <MDCKey>username</MDCKey>
- <Value>sebastien</Value>
- <OnMatch>ACCEPT</OnMatch>
- </turboFilter>
-
- <turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
- <Marker>billing</Marker>
- <OnMatch>DENY</OnMatch>
- </turboFilter>
-
- <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%date [%thread] %-5level %logger - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="INFO">
- <appender-ref ref="console" />
- </root>
-</configuration></pre>
-
- <p>次のコマンドを実行してみましょう。</p>
-
- <p class="source">java chapters.filters.FilterEvents src/main/java/chapters/filters/turboFilters.xml</p>
-
- <p>前に見たように、<a href="http://logback.qos.ch/xref/chapters/filters/FilterEvents.html"><code>FilterEvents</code></a>アプリケーションは0〜9の連番を付けて10個のロギング要求を生成します。3番目と6番目を除く他のロギング要求のログレベルは<em>INFO</em>です。これはルートロガーに割り当てたログレベルと同じです。3番目のロギング要求のログレベルは<em>DEBUGレベル</em>で、これは有効レベルを下回っています。ですが、3番目のロギング要求を生成する直前に、MDCのキー"username"には値"sebastien"が設定され、直後に取り除かれています。そして、<code>MDCFIlter</code>はこのロギング要求だけを受け入れるようになっています。6番目のロギング要求はログレベル<em>ERROR</em>で、かつ、"billing" というマーカーが指定されています。このロギング要求はMarkerFilter(二つ目のターボフィルター) [...]
- </p>
-
- <p>結果として、<code>FilterEvents</code>アプリケーションに<em>turboFilters.xml</em>を指定した場合は次のように出力されます。</p>
-
- <p class="source">2006-12-04 15:17:22,859 [main] INFO chapters.filters.FilterEvents - logging statement 0
-2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 1
-2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 2
-2006-12-04 15:17:22,875 [main] DEBUG chapters.filters.FilterEvents - logging statement 3
-2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 4
-2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 5
-2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 7
-2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 8
-2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 9</p>
-
-
- <p>有効レベルは<em>INFO</em>なのに、3番目のロギング要求、つまり、ログレベルがDEBUGのロギング要求が出力されています。これは最初の<code>TurboFilter</code>が受け入れたからです。
- </p>
-
- <p>また、6番目のロギング要求はログレベルが<em>ERROR</em>なのに出力されていません。二つ目の<code>TurboFilter</code>の<span class="option">OnMatch</span>プロパティに<em>DENY</em>が指定されていたからです。
- </p>
-
-
-
-
- <h3 class="doAnchor" name="DuplicateMessageFilter">DuplicateMessageFilter</h3>
-
- <p><code>DuplicateMessageFilter</code>の利点は異なる見え方をします。メッセージの重複を検出し、一定回数以上繰り返す場合は、メッセージを破棄します。
- </p>
-
- <p>繰り返しの検出は、単純に文字列が一致するかどうかを見ています。数文字違うだけでそれは別のメッセージとして扱われるので、重複メッセージとしては検出しません。たとえばこんな風に書いたとしましょう。</p>
-
- <pre class="prettyprint source">logger.debug("Hello "+name0);
-logger.debug("Hello "+name1);</pre>
-
- <p><code>name0</code>と<code>name1</code>が別の値だとしたら、これらのメッセージは別のものであるとみなされます。利用者のニーズによりますが、将来のリリースでは文字列の類似度をチェックすることになりそうです。完全に同一ではないけどよく似ているメッセージの繰り返しを排除するたmです。
- </p>
-
- <p>ロギングメッセージに引数を指定している場合、書式化される前のメッセージが判定対象になるので注意してください。たとえば次の二つのロギング式のメッセージ部分はどちらも同じ "Hello {}." なので、これは重複メッセージと判定されます。
- </p>
-
- <pre class="prettyprint source">logger.debug("Hello {}.", name0);
-logger.debug("Hello {}.", name1);</pre>
-
- <p>繰り返しを許容する回数は<span class="option">AllowedRepetitions</span>プロパティで指定します。allowedRepetitionsプロパティに1を指定した場合、最初のメッセージは出力されて、2番目のメッセージは破棄されます。同様に、2を指定したら、1番目、2番目のメッセージは出力されて、三番目以降のメッセージは破棄されます。デフォルトは5が設定されています。
- </p>
-
- <p>繰り返しを検出するには、内部的に古いメッセージへの参照をキャッシュしておかなければなりません。このキャッシュのサイズは<span class="option">CacheSize</span>プロパティによって決まります。デフォルトは100(個)が設定されています。
- </p>
-
-
- <p class="example">例:<code>DuplicateMessageFilter</code>の設定例(<a href="http://logback.qos.ch/xref/chapters/filters/duplicateMessage.xml">logback-examples/src/main/java/chapters/filters/duplicateMessage.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('duplicateMessage');">Groovyとして表示</span>
- <pre id="duplicateMessage" class="prettyprint source"><configuration>
-
- <b><turboFilter class="ch.qos.logback.classic.turbo.DuplicateMessageFilter"/></b>
-
- <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%date [%thread] %-5level %logger - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="INFO">
- <appender-ref ref="console" />
- </root>
-</configuration></pre>
-
- <p><code>FilterEvents</code>アプリケーションに<em>duplicateMessage.xml</em>を指定した場合の出力は次のようになります。</p>
-
- <p class="source">2008-12-19 15:04:26,156 [main] INFO chapters.filters.FilterEvents - logging statement 0
-2008-12-19 15:04:26,156 [main] INFO chapters.filters.FilterEvents - logging statement 1
-2008-12-19 15:04:26,156 [main] INFO chapters.filters.FilterEvents - logging statement 2
-2008-12-19 15:04:26,156 [main] INFO chapters.filters.FilterEvents - logging statement 4
-2008-12-19 15:04:26,156 [main] INFO chapters.filters.FilterEvents - logging statement 5
-2008-12-19 15:04:26,171 [main] ERROR chapters.filters.FilterEvents - billing statement 6</p>
-
- <p>"logging statement 0" は、書式化する前のメッセージ"logging statement {}" によって出力された<em>最初</em>のメッセージです。"logging statement 1"が1回目の<em>繰り返し</em>、"logging statement 2"が2回目の繰り返しとなります。<em>3回目</em>の繰り返しとなる"logging statement 3"はログレベルがDEBUGのはずなので、<a href="http://logback.qos.ch/manual/architecture.html#basic_selection">基本的な選択ルール</a>によって破棄されました。つまり、ターボフィルターは基本的な選択ルールを含む他のフィルターに先駆けて呼び出されるということなのです。したがって、後続の処理チェインの中で破棄されてしまうのですが、<code>DuplicateMessageFilter</code>は"logging statement 3"を繰り返しメッセージだと判断したはずです。し [...]
- </p>
-
- <h1 class="doAnchor" name="logbac-access">logback-access モジュール</h1>
-
- <p>logback-access モジュールは logback-classic モジュールとほとんど同じ機能を提供します。具体的には、<code>Filter</code>オブジェクトはlogback-classic と同じように利用可能できますし、同じように動作します。一点だけ大きく違うころがあって、それは<code>LoggingEvent</code>のインスタンスではなく <a href="http://logback.qos.ch/xref/ch/qos/logback/access/spi/AccessEvent.html"><code>AccessEvent</code></a>のインスタンスを使うということです。現時点では、logback-access の配布物に含まれているフィルターの数はそれほど多くありません。追加のフィルターを提案したいときは、logback-dev メーリングリスト宛に連絡してください。
- </p>
-
- <h2 class="doAnchor" name="countingFilter"><code>CountingFilter</code></h2>
-
- <p>logback-access では、<a href="http://logback.qos.ch/manual/xref/ch/qos/logback/access/filter/CountingFilter.html"><code>CountingFilter</code></a>を使ってWebサーバへのアクセス統計情報を集めることができます。<code>CountingFilter</code>は、初期化時に実行プラットフォームの JMX サーバーに自身を MBean として登録します。その後は、MBean に統計情報を問い合わせることができるようになります。分平均、時間平均、日平均、週平均、月平均などです。他にも、集計単位の一つ前の情報と全体の合計を参照することができます。
- </p>
-
- <p><code>CountingFilter</code>を使用する設定ファイルを見てみましょう。</p>
-
- <pre class="prettyprint source"><configuration>
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
-
- <b><filter class="ch.qos.logback.access.filter.CountingFilter">
- <name>countingFilter</name>
- </filter></b>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%h %l %u %t \"%r\" %s %b</pattern>
- </encoder>
- </appender>
-
- <appender-ref ref="STDOUT" />
-</configuration></pre>
-
- <p><code>CountingFilter</code>の収集する統計情報は、例えば<code>jconsole</code>から JMX サーバにアクセスして参照することができます。</p>
-
-
- <img alt="jconsoleを経由してCountingFilterにアクセス" src="images/chapters/filters/countingFilter.png">
-
-
- <h3 class="doAnchor" name="access_EvalutorFilter">EvaluatorFilter</h3>
-
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/core/filter/EvaluatorFilter.html"><code>EvaluatorFilter</code></a>は<code>EventEvaluator</code>をカプセル化した汎用的なフィルターです。名前が示すように、 <code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/boolex/EventEvaluator.html">EventEvaluator</a></code>は指定された条件を評価して、イベントがその条件を満たすかどうかを判定します。条件を満たす場合もそうでない場合も、<code>EvaluatorFilter</code>の<span class="option">onMatch</span>プロパティ、または、<span class="option">onMismatch</span>プロパティに指定された値を返します。<code>Eva [...]
-
-
- <p><code>EventEvaluator</code>は抽象クラスです。
-つまり、<code>EventEvaluator</code>を継承すれば、独自のイベント評価ロジックを実装することができます。
-logback-accessの配布物には<a href="http://logback.qos.ch/xref/ch/qos/logback/access/boolex/JaninoEventEvaluator.html">JaninoEventEvaluator</a>という実装クラスが含まれています。これは、booleanを返す任意のJava言語のブロックを評価するものです。私たちはこのJava言語で書かれた式のことを"<em>Java評価式</em>”と呼んでいます。
-Java評価式を使うとロギングイベントを柔軟にフィルタリングできるようになります。
-<code>JaninoEventEvaluator</code>を使用するには<a href="http://docs.codehaus.org/display/JANINO/Home">Janinoライブラリ</a>が必要です。
-設定方法は設定ドキュメントの<a href="http://logback.qos.ch/setup.html#janino">対応するセクション</a>を参照してください。
-
- </p>
-
- <p>Java評価式は設定ファイルを解釈する間にコンパイルされます。
-どのように呼び出すのか、利用者は気にすることはありません。
-ですが、Java言語の式が真偽値を返すものであることを保証するのは利用者の責任です。
-</p>
-
-
- <p>Java評価式は一度に1つのイベントを扱います。logback-accessは、<code>AccessEvent</code>を<b><code>event</code></b>という名前の変数として公開します。<code>event</code>変数を介して、HTTPリクエストやHTTP応答に関連付けられたさまざまなデータを参照することができます。正確なところは<a href="http://logback.qos.ch/xref/ch/qos/logback/access/spi/AccessEvent.html">AccessEvent</a>クラスの<code>ソースコード</code>を読んでください。
- </p>
-
- <p>次の設定ファイルでは、応答コード<a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5">404(Not Found)</a>をひっかけます。つまり、応答コードが404になったHTTPリクエストをすべてコンソールに出力するのです。</p>
-
- <p class="example">例:Access Evaluator(<a href="http://logback.qos.ch/xref/chapters/filters/accessEventEvaluator.xml">logback-examples/src/main/java/chapters/filters/accessEventEvaluator.xml</a>)</p>
-
-<pre class="prettyprint source"><configuration>
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <b><filter class="ch.qos.logback.core.filter.EvaluatorFilter">
- <evaluator>
- <expression>event.getStatusCode() == 404</expression>
- </evaluator>
- <onMismatch>DENY</onMismatch>
- </filter></b>
- <encoder><pattern>%h %l %u %t %r %s %b</pattern></encoder>
- </appender>
-
- <appender-ref ref="STDOUT" />
-</configuration></pre>
-
- <p>次の設定ファイルでは、やはり404エラーをひっかけているのですが、CSSファイルを要求したものだけをひっかけています。
- </p>
-
-
- <p class="example">例6.10:Access Evaluator(<a href="http://logback.qos.ch/xref/chapters/filters/accessEventEvaluator2.xml">logback-examples/src/main/java/chapters/filters/accessEventEvaluator2.xml</a>)</p>
-
- <pre class="prettyprint source"><configuration>
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
- <evaluator name="Eval404">
- <expression>
- <b>(event.getStatusCode() == 404)</b>
- <b>&&</b> <!-- ampersand characters need to be escaped -->
- <b>!(event.getRequestURI().contains(".css"))</b>
- </expression>
- </evaluator>
- <onMismatch>DENY</onMismatch>
- </filter>
-
- <encoder><pattern>%h %l %u %t %r %s %b</pattern></encoder>
- </appender>
-
- <appender-ref ref="STDOUT" />
-</configuration>
- </pre>
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-
- </div>
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/manual/groovy.html b/docs/manual/groovy.html
index 0c43100..7d34167 100644
--- a/docs/manual/groovy.html
+++ b/docs/manual/groovy.html
@@ -31,11 +31,8 @@
<div id="content" class="chapter">
<h1>Chapter 12: Groovy Configuration</h1>
-
- <a href="groovy_ja.html">和訳 (Japanese translation)</a>
-
- <div class="quote">
+ <div class="quote">
<p><em>It is better to be a human being dissatisfied than a pig
satisfied; better to be a Socrates dissatisfied than a fool
satisfied. And if the fool or the pig thinks otherwise, it is
@@ -252,7 +249,7 @@ root(DEBUG, ["FILE"])</pre>
formatted according to the <code>datePattern</code> parameter. The
<code>datePattern</code> parameter should follow the conventions
defined by <a
- href="https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a>. If
+ href="http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a>. If
the <code>timeReference</code> value is unspecified, it defaults
to -1, in which case current time, that is time when the
configuration file is parsed, is used as the time
diff --git a/docs/manual/groovy_ja.html b/docs/manual/groovy_ja.html
deleted file mode 100644
index fcf22ab..0000000
--- a/docs/manual/groovy_ja.html
+++ /dev/null
@@ -1,364 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第12章 Groovyによる設定</title>
-
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
-
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content" class="chapter">
-
- <h1>第12章 Groovyによる設定</h1>
-
- <div class="quote">
- <p><em>満足した豚になるより不満を抱えた人間になるほうがずっと良い。ましてや、満足気な愚か者になるより不満だらけのソクラテス派になるほうがずっと良い。豚や愚か者がこれとは異なる主張をしたとしても、それは彼らに良いとされる側の経験が無いからなのだ。
- </em>
- </p>
- <p>-ジョン·スチュアート·ミル、 <em>功利主義</em></p>
- </div>
- <script src="../templates/creative.js" type="text/javascript"></script>
-
-
- <p>ドメイン固有言語やDSLはかなり普及しています。XMLベースのlogbackの設定は、DSLのインスタンスとみなすことができます。XMLの性質上、設定ファイルは非常に冗長でかさばるものになります。さらに、logbackのコードの大部分はXMLベースの設定ファイル処理専用のJoranと呼ばれるものです。Joranは、変数置換や条件分岐、および実行時の拡張など、気の利いた機能をサポートしています。しかし、Joranの問題は複雑さだけではありません。ユーザーエクスペリエンスは不十分ですし、直感とはかけ離れています。
- </p>
-
- <p>この章で説明するGroovyベースのDSLは、一貫性があり、直感的で、かつ、強力であることを目指しています。XMLの設定ファイルでできることはすべて、それもより短い行数で実現することができます。Groovyスタイルの設定ファイルへの移行を支援するために、<a href="http://logback.qos.ch/translator/asGroovy.html">既存の<em>logback.xml</em>を自動的に<em>logback.groovy</em>へ変換するツールを用意しました</a>。
- </p>
-
-
- <h2 class="doAnchor">基本的な哲学</h2>
-
- <p>基本的なルールを説明します。<em>logback.groovy</em>はGroovyのプログラムです。Groovy言語はJava言語のスーパーセットなので、Javaにできるあらゆる設定アクションと同じことを<em>logback.groovy</em>で実行することができます。ですが、logbackをJavaの構文でプログラム的に設定するのはかなり厄介なので、logback専用の拡張構文を追加しました。logback専用の拡張構文はできるだけ少なくなるようにしましたし、実際のところほんのわずかしかありません。Groovyに慣れているとしても本章に目を通してもらって、<em>logback.groovy</em>を書くのは非常に簡単であることを理解してください。Groovyに不慣れな方であっても、<em>logback.xml</em>を使い続けるより<em>logback.groovy</em>の記法のほうがずっとわかりやすいと思えるようになるはずです。
- </p>
-
- <p>改めて整理します。<em>logback.groovy</em>は最小限のlogback専用の拡張がなされたGroovyプログラムです。<em>logback.groovy</em>の中では、クラスのimportや変数定義、変数評価、GString のMavenProject: ch.qos.logback:logback-site:1.1.9 @ C:\\home\\ceki\\logback\\logback-site\\pom.xml記法、if-else構文などのGroovyの機能は<em>全て</em>利用可能です。</p>
-
- <h2 class="doAnchor">自動import</h2>
-
- <p><span class="label">logback1.0.10以降</span>決まりきったものになる共通するクラスやパッケージのimportをしなくてもすむように、自動的にimportします。したがって、組み込みのアペンダーやレイアウトについてはわざわざimport文を書かなくても設定だけでよいのです。もちろん、デフォルトのimportでカバーされていないクラスやパッケージがあるなら、それは自分でやらなければなりません。</p>
-
- <p>デフォルトのimport対象は次のとおりです。</p>
-
- <ul>
- <li><span class="code">import ch.qos.logback.core.*;</span></li>
- <li><span class="code">import ch.qos.logback.core.encoder.*;</span></li>
- <li><span class="code">import ch.qos.logback.core.read.*;</span></li>
- <li><span class="code">import ch.qos.logback.core.rolling.*;</span></li>
- <li><span class="code">import ch.qos.logback.core.status.*;</span></li>
- <li><span class="code">import ch.qos.logback.classic.net.*;</span></li>
- <li><span class="code">import ch.qos.logback.classic.encoder.PatternLayoutEncoder;</span></li>
- </ul>
-
- <p>さらに、<span class="code">ch.qos.logback.classic.Level</span>の全ての定数は、大文字バージョンと小文字バージョンのそれぞれでstatic importされます。つまり、スクリプトでは<em>INFO</em>と<em>info</em>のどちらでも利用できます。</p>
-
-
- <h2 class="doAnchor" name="sift">SiftingAppenderはサポートされなくなりました</h2>
-
- <p><span class="label">logback1.0.12以降</span>Groovy設定ファイルでは<code>SiftingAppender</code>はサポートされなくなりました。需要がありそうなら復活するかもしれません。</p>
-
- <h2 class="doAnchor" name="entensions"><em>logback.groovy</em>用の拡張構文</h2>
-
- <p><span class="green">基本的に<em>logback.groovyの構文</em>は、次に説明する半ダースほどのメソッドで構成されています。これらは実際に定義する順番とは逆順に並んでいます。</span>厳密に言えば、これらのメソッドの呼び出し順序は1つの例外(アペンダーはそれを割り当てるロガーの前に定義しなければならない)を除いて重要ではありません。</p>
-
-
-
- <!-- ========================================================== -->
-
- <h3> • <span class="code">root(Level level, List<String> appenderNames = [])</span></h3>
-
- <p><code>root</code>メソッドはルートロガーのログレベルを設定するために使用します。第二引数のappenderName(<code>List<String></code>)は任意で、ルートロガーに割り当てるアペンダーを名前で指定します。引数に値を指定しなければ、空のリストが指定されたものとして扱います。。Groovyでは空のリストを<code>[]</code>で記述します。</p>
-
- <p>ルートロガーのログレベルにWARNを設定するには次のように記述します。</p>
-
- <pre class="prettyprint source">root(WARN)</pre>
-
- <p>ルートロガーのログレベルにINFOを設定し、"CONSOLE"アペンダーと"FILE"アペンダーを割り当てるには次のように記述します。</p>
-
- <pre class="prettyprint source">root(INFO, ["CONSOLE", "FILE"])</pre>
-
- <p>"CONSOLE"と"FILE"という名前のアペンダーはすでに定義されているものとします。アペンダーの定義の仕方はすぐ後で説明します。
- </p>
-
- <!-- ========================================================== -->
-
- <h3>• <span class="code">logger(String name, Level level, List<String> appenderNames = [], <br> Boolean additivity = null)</span></h3>
-
- <p><code>logger()</code>メソッドは引数を四つとります。後ろの二つは任意です。第一引数にはロガーの名前を指定します。第二引数にはロガーのログレベルを指定します。ログレベルに<code>null</code>を指定すると、直近の祖先ロガーに指定されたログレベルを<a href="./01-architecture.html#effectiveLevel">継承</a>するという意味になります。第三引数は<code>List<String></code>で任意です。省略した場合は空のリストを指定したものとして扱います。リストにはロガーに割り当てるアペンダーの名前を並べます。第四引数は<code>Boolean</code>でこちらも任意です。<a href="./01-architecture.html#additivity">additivityフラグ</a>として使われます。省略した場合は<code>null</code>が指定されたものとして扱います。
- </p>
-
- <p>たとえば、次のスクリプトはロガー名として"com.foo"、ログレベルとしてINFOを設定します。</p>
-
- <pre class="prettyprint source">logger("com.foo", INFO)</pre>
-
- <p>次のスクリプトは、ロガー名として"com.foo"、ログレベルとしてDEBUG、そしてアペンダーに"CONSOLE"を割り当てます。</p>
-
- <pre class="prettyprint source">logger("com.foo", DEBUG, ["CONSOLE"])</pre>
-
- <p>次のスクリプトは前のスクリプトとほとんど同じですが、additivityフラグにfalseを設定します。</p>
-
- <pre class="prettyprint source">logger("com.foo", DEBUG, ["CONSOLE"], false)</pre>
-
-
- <!-- ========================================================== -->
- <h3>• <span class="code">appender(String name, Class clazz, Closure closure = null)</span></h3>
-
- <p>appender()メソッドでは、第一引数にアペンダーの名前を指定します。第二引数は必須で、インスタンス化するアペンダーのクラスを指定します。第三引数には、そのほかの設定をするクロージャーを指定します。省略した場合はnullになります。</p>
-
- <p>ほとんどのアペンダーは、ちゃんと動作するためにプロパティを設定したりサブコンポーネントを注入しなければなりません。プロパティを設定するには '='演算子(代入)を使用します。サブコンポーネントを注入するには、プロパティ名をメソッド名のように記述して、引数にインスタンス化するクラスを指定します。このコーディング規約は、アペンダーのあらゆるサブコンポーネントについても同じように再帰的に適用されるものです。このアプローチは<em>logback.groovy</em>の中核を為すもので、覚えなければならない唯一の規約となるでしょう。</p>
-
- <p>例を見てみましょう。次のスクリプトは"FILE"という名前の<code>FileAppender</code>をインスタンス化して、<span class="option">file</span>プロパティに"testFile.log"を設定し、<span class="option">append</span>プロパティにfalseを設定しています。encoderには<code>PatternLayoutEncoder</code>を注入しています。encoderのpatternプロパティには" - %level %logger - %msg%n"を設定しています。そしてこのアペンダーをルートロガーに割り当てます。</p>
-
- <pre class="prettyprint source">appender("FILE", FileAppender) {
- file = "testFile.log"
- append = true
- encoder(PatternLayoutEncoder) {
- pattern = "%level %logger - %msg%n"
- }
-}
-
-root(DEBUG, ["FILE"])</pre>
-
- <p>
- </p>
-
-
- <!-- ========================================================== -->
- <h3>• <span class="code">timestamp(String datePattern, long timeReference = -1)</span></h3>
-
- <p><code>timestamp()</code>メソッドは、<code>datePattern</code>に指定された書式文字列で<code>timeReference</code>に指定されたlong値の時間を書式化した文字列を返します。第一引数の<code>datePattern</code>に指定する書式文字列は、<a href="https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a>で定義されている規則に従わなければなりません。第二引数の<code>timeReference</code>が省略された場合-1が指定されたものとして扱います。これは設定ファイルを解析しているときの現在日時を表す値です。状況によりますが、基準時間として<code>context.birthTime</code>を使うこともあるでしょう。
- </p>
-
- <p>次の例では、 <code>bySecond</code>変数に"yyyyMMdd'T'HHmmss"という書式で文字列化した現在日時を代入していますそして、"bySecond" 変数を<span class="option">file</span>プロパティの値として使っています。
- </p>
-
-<pre class="prettyprint source"><b>def bySecond = timestamp("yyyyMMdd'T'HHmmss")</b>
-
-appender("FILE", FileAppender) {
- <b>file = "log-${bySecond}.txt"</b>
- encoder(PatternLayoutEncoder) {
- pattern = "%logger{35} - %msg%n"
- }
-}
-root(DEBUG, ["FILE"])</pre>
-
- <!-- ========================================================== -->
- <h3>• <span class="code">conversionRule(String conversionWord, Class converterClass)</span></h3>
-
- <p><a href="./06-layouts.html#customConversionSpecifier">変換指定子</a>を自作しても、logbackに教えてあげなければ利用できません。このlogback.groovyでは、logbackが<code>%sample</code>という変換指定子に対してMySampleConverterを呼び出すようにしています。
- </p>
-
- <pre class="prettyprint source">
-import chapters.layouts.MySampleConverter
-
-conversionRule("sample", MySampleConverter)
-appender("STDOUT", ConsoleAppender) {
- encoder(PatternLayoutEncoder) {
- pattern = "%-4relative [%thread] %<b>sample</b> - %msg%n"
- }
-}
-root(DEBUG, ["STDOUT"])</pre>
-
- <!-- ========================================================== -->
- <h3>• <span class="code">scan(String scanPeriod = null)</span></h3>
-
- <p>scan()メソッドを使うと、logbackが定期的にlogback.groovyの変更を監視するようになります。logbackは変更を検出するたびに<em>logback.groovy</em>を再読み込みします。</p>
-
- <pre class="prettyprint source">scan()</pre>
-
- <p>デフォルトでは、一分ごとに設定ファイルの変更を監視します。監視周期を指定するには、"scanPeriod" 文字列引数を指定します。"scanPeriod" に指定する文字列には、時間単位としてミリ秒、秒、分または時間を含めることができます。例をみてください。</p>
-
- <pre class="prettyprint source">scan("30 seconds")</pre>
-
- <p>時間単位がない場合ミリ秒が指定されたものとして扱いますが、ほとんどの場合これは不適切な単位です。デフォルトの監視周期を変更する場合は、時間単位を指定することを忘れないでください。どのように変更を監視するのかについて詳しくは<a href="./03-configuration.html#autoScan">自動再読み込みのセクション</a>を参照してください。
- </p>
-
- <!-- ========================================================== -->
-
- <h3>• <span class="code">statusListener(Class listenerClass)</span></h3>
-
- <p><code>statusListener()</code>メソッドは、指定したリスナークラスをステータスリスナーとして追加します。例を見てください。</p>
-
- <pre class="prettyprint source">import chapters.layouts.MySampleConverter
-
-<b>// statusListener()メソッドの呼び出しはimport文の直後、他の式よりも前に置くことを強く推奨します</b>
-<b>statusListener(OnConsoleStatusListener)</b></pre>
-
- <p><a href="./03-configuration.html#statusListener">ステータスリスナー</a>については前の章で説明しました。</p>
-
- <h3>• <span class="code">jmxConfigurator(String name)</span></h3>
-
- <p><a href="./10-jmxConfig.html"><code>JMXConfigurator</code></a>のMBeanを登録します。MBean名としてデフォルトのオブジェクト名(<code>ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator</code>)を使うには引数を指定せずに呼び出してください。</p>
-
- <pre class="prettyprint source">jmxConfigurator()</pre>
-
- <p><code>Name</code>キーに"default"以外の値を指定するには、<code>jmxConfigurator()</code>メソッドの引数として指定するだけです。</p>
-
- <pre class="prettyprint source">jmxConfigurator('MyName')</pre>
-
- <p>オブジェクト名全体を指定したい場合は、正確なオブジェクト名文字列を引数に指定してください。</p>
-
- <pre class="prettyprint source">jmxConfigurator('myApp:type=LoggerManager')</pre>
-
- <p>このメソッドは、指定された文字列をオブジェクト名として使おうとしてから、それが有効なオブジェクト名ではなかったら、フォールバックとして"Name"キーの値にします。</p>
-
- <!-- ========================================================== -->
-
- <h2 class="doAnchor" name="internalDSL">内部DSL、すべてはGroovyの賜物だ!</h2>
-
- <p><em>logback.groovy</em>は内部DSLです。つまり、内容自体が実行可能なGroovyスクリプトなのです。したがって、logback.groovyの中ではGroovy言語に備わっているクラスimport、GString、変数定義、GString文字列中のMavenProject: ch.qos.logback:logback-site:1.1.9 @ C:\\home\\ceki\\logback\\logback-site\\pom.xml記法の評価、if-else文などのあらゆる機能を利用することができるのです。以降の説明では<em>logback.groovy</em>における典型的なGroovy言語の使用例を紹介します。
- </p>
-
-
- <h3 class="doAnchor" name="varedef">変数定義、そしてGString</h3>
-
- <p><em>logback.groovy</em>の中ならどこでも変数を定義することができますし、その変数をGString文字列の中で評価することができます。例を見てください。</p>
-
- <pre class="prettyprint source">// USER_HOME 変数にシステムプロパティの "user.home" の値を代入します
-<b>def USER_HOME = System.getProperty("user.home")</b>
-
-appender("FILE", FileAppender) {
- // USER_HOME 変数を使います
- <b>file = "${USER_HOME}/myApp.log"</b>
- encoder(PatternLayoutEncoder) {
- pattern = "%msg%n"
- }
-}
-root(DEBUG, ["FILE"])</pre>
-
-
- <h3 class="doAnchor" name="printing">コンソールへの出力</h3>
-
- <p>Groovyの<code>println()</code>メソッドを使ってコンソールに出力することができます。例を見てください。</p>
-
- <pre class="prettyprint source">def USER_HOME = System.getProperty("user.home");
-<b>println "USER_HOME=${USER_HOME}"</b>
-
-appender("FILE", FileAppender) {
- <b>println "Setting [file] property to [${USER_HOME}/myApp.log]"</b>
- file = "${USER_HOME}/myApp.log"
- encoder(PatternLayoutEncoder) {
- pattern = "%msg%n"
- }
-}
-root(DEBUG, ["FILE"])</pre>
-
-
- <h3 class="doAnchor" name="automaticallyExported">自動的に公開されるフィールド</h3>
-
- <h4 class="doAnchor" name="hostname">'hostname' 変数</h4>
-
- <p>'hostname' 変数にはスクリプトを実行しているホスト名が設定されています。このドキュメントの著者には正確な説明はできませんが、可視範囲のルールがあるため、'hostname'変数が利用できるのは最上位のスコープだけで、ネストされたスコープからは参照できません。次の例を見ればどういうことかわかるでしょう。
- </p>
-
- <pre class="prettyprint source">// will print "hostname is x" where x is the current host's name
-println "Hostname is ${hostname}"
-
-appender("STDOUT", ConsoleAppender) {
- <b>// will print "hostname is null"</b>
- <b>println "Hostname is ${hostname}" </b>
-}</pre>
-
- <p>すべてのスコープでhostname変数を使いたいなら、次のように別の変数に代入して参照しなければなりません。</p>
-
- <pre class="prettyprint source">// define HOSTNAME by assigning it hostname
-def HOSTNAME=hostname
-// will print "hostname is x" where x is the current host's name
-println "Hostname is ${HOSTNAME}"
-
-appender("STDOUT", ConsoleAppender) {
- // will print "hostname is x" where x is the current host's name
- println "Hostname is ${HOSTNAME}"
-}</pre>
-
-
- <h3 class="doAnchor" name="everythingIsContext">現在のコンテキストを参照するContextAwareが全ての土台になっている</h3>
-
- <p><em>logback.groovy</em>スクリプトは<a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/ContextAware.html">ContextAware</a>オブジェクト上で実行されます。したがって、<code>context</code>変数からいつでも現在のコンテキストにアクセスすることができます。それに、<code>addInfo()</code>メソッドや<code>addWarn()</code>メソッド、<code>addError()</code>メソッドで、<code>StatusManager</code>にステータスメッセージを伝えることができます。</p>
-
- <pre class="prettyprint source">// always a good idea to add an on console status listener
-statusListener(OnConsoleStatusListener)
-
-// set the context's name to wombat
-<b>context.name = "wombat"</b>
-// add a status message regarding context's name
-<b>addInfo("Context name has been set to ${context.name}")</b>
-
-def USER_HOME = System.getProperty("user.home");
-// add a status message regarding USER_HOME
-<b>addInfo("USER_HOME=${USER_HOME}")</b>
-
-appender("FILE", FileAppender) {
- // add a status message regarding the file property
- <b>addInfo("Setting [file] property to [${USER_HOME}/myApp.log]")</b>
- file = "${USER_HOME}/myApp.log"
- encoder(PatternLayoutEncoder) {
- pattern = "%msg%n"
- }
-}
-root(DEBUG, ["FILE"])</pre>
-
-
- <h3 class="doAnchor">条件付き設定</h3>
-
- <p>Groovyは本格的なプログラミング言語なので、条件分岐を使うと1つの<em>logback.groovy</em>をdevelopment、testing、productionといったいろいろな環境で使い回すことができます。</p>
-
- <p>次のスクリプトでは、ホスト名が本番環境のホスト名である pixie あるいは orion 以外の場合コンソールアペンダーが有効になるようにしています。ローリングファイルアペンダーの出力ディレクトリがホスト名に依存していることにも気をつけてください。</p>
-
- <pre class="prettyprint source">// always a good idea to add an on console status listener
-statusListener(OnConsoleStatusListener)
-
-def appenderList = ["ROLLING"]
-def WEBAPP_DIR = "."
-def consoleAppender = true;
-
-// does hostname match pixie or orion?
-if (hostname =~ /pixie|orion/) {
- WEBAPP_DIR = "/opt/myapp"
- consoleAppender = false
-} else {
- appenderList.add("CONSOLE")
-}
-
-if (consoleAppender) {
- appender("CONSOLE", ConsoleAppender) {
- encoder(PatternLayoutEncoder) {
- pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
- }
- }
-}
-
-appender("ROLLING", RollingFileAppender) {
- encoder(PatternLayoutEncoder) {
- Pattern = "%d %level %thread %mdc %logger - %m%n"
- }
- rollingPolicy(TimeBasedRollingPolicy) {
- FileNamePattern = "${WEBAPP_DIR}/log/translator-%d{yyyy-MM}.zip"
- }
-}
-
-root(INFO, appenderList)</pre>
-
-
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
- </div>
- </body>
-</html>
\ No newline at end of file
diff --git a/docs/manual/index.html b/docs/manual/index.html
index 3ee3d31..acd9bbd 100644
--- a/docs/manual/index.html
+++ b/docs/manual/index.html
@@ -25,7 +25,6 @@
<h2>The logback manual</h2>
- <a href="index_ja.html">和訳 (Japanese translation)</a>
<p>The complete logback manual documents the latest version of
logback framework. In over 150 pages and dozens of concrete
diff --git a/docs/manual/index_ja.html b/docs/manual/index_ja.html
deleted file mode 100644
index c0ed9df..0000000
--- a/docs/manual/index_ja.html
+++ /dev/null
@@ -1,115 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>Logbackマニュアル</title>
-
- <link rel="stylesheet" type="text/css" href="../css/common.css" />
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen" />
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print" />
-
- </head>
- <body dir="ltr">
- <script type="text/javascript">prefix='../';</script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h2>logback マニュアル</h2>
-
-
- <p>このマニュアルでは、logbackフレームワークの最新バージョンについて説明しています。百五十ページを超える説明、および、数十もの具体例によって、logback のフィーチャの基本的な使い方と応用的な使い方を説明します。大きく次のような内容が含まれています。</p>
-
-
- <div>
- <ul>
- <li><p>logbackの全体的なアーキテクチャ</p></li>
- <li><p>最高のプラクティスとアンチパターンについての議論</p></li>
- <li><p>XML形式のlogback設定</p></li>
- <li><p>アペンダー</p></li>
- <li><p>エンコーダー</p></li>
- <li><p>レイアウト</p></li>
- <li><p>フィルター</p></li>
- <li><p>診断コンテキスト(MDC)</p></li>
- <li><p>logbackの設定システム Joran の解説</p></li>
- </ul>
- </div>
-
-
- <p>このマニュアルは、logback の API をかなり詳細に説明したもので、フィーチャや設計の理論的な根拠も含まれます。執筆したのは logback プロジェクトの主要な貢献者である CekiGülcü と Sébastien Pennec です。
-このマニュアルの対象者としては、Javaによる開発の経験はあるけど logback を使ったことがない人から、logback について経験豊富な人までを想定しています。入門資料と多くの具体例を手がかりにすれば、例え未経験であってもすぐに慣れることができるはずです。
- </p>
-
-
-
- <div>
- <p>ここまでで特に疑問に思うことがなければ、早速ここから読み進めてください。</p>
-
- <ul>
- <li><p>
- <a href="introduction_ja.html"><b>第1章:はじめに</b></a>
- </p></li>
- <li><p>
- <a href="architecture_ja.html"><b>第2章:アーキテクチャ</b></a>
- </p></li>
- <li><p>
- <a href="configuration_ja.html"><b>第3章:設定</b></a>
- </p></li>
-
- <li><p>
- <a href="appenders_ja.html"><b>第4章:アペンダー</b></a>
- </p></li>
-
- <li><p><a href="encoders_ja.html"><b>第5章:エンコーダー</b></a></p>
- </li>
-
- <li><p>
- <a href="layouts_ja.html"><b>第6章:レイアウト</b></a>
- </p></li>
-
- <li><p>
- <a href="filters_ja.html"><b>第7章:フィルタ</b></a>
- </p></li>
-
- <li><p>
- <a href="mdc_ja.html"><b>第8章:診断コンテキスト(MDC)</b></a>
- </p></li>
-
- <li><p>
- <a href="loggingSeparation_ja.html"><b>第9章:ログの分離</b></a>
- </p></li>
-
- <li><p>
- <a href="jmxConfig_ja.html"><b>第10章:JMXコンフィギュレーター</b></a>
- </p></li>
-
- <li><p>
- <a href="onJoran_ja.html"><b>第11章:Joran</b></a>
- </p></li>
-
- <li><p><a href="groovy_ja.html"><b>第12章:Groovyによる設定</b></a></p></li>
-
- <li><p>
- <a href="migrationFromLog4j_ja.html"><b>第13章:log4jからの移行</b></a>
- </p></li>
-
- <li><p>
- <a href="receivers_ja.html"><b>第14章:レシーバー</b></a>
- </p></li>
-
- <li><p>
- <a href="usingSSL_ja.html"><b>第15章:SSLの使用</b></a>
- </p></li>
-
- </ul>
- </div>
-
- <script src="../templates/footer.js" type="text/javascript"></script>
- </div>
- </body>
-</html>
\ No newline at end of file
diff --git a/docs/manual/introduction.html b/docs/manual/introduction.html
index 5ad4057..7eea435 100644
--- a/docs/manual/introduction.html
+++ b/docs/manual/introduction.html
@@ -42,11 +42,8 @@
<script src="../templates/creative.js" type="text/javascript"></script>
-
<h2>What is logback?</h2>
- <a href="introduction_ja.html">和訳 (Japanese translation)</a>
-
<p>Logback is intended as a successor to the popular log4j
project. It was designed by Ceki Gülcü, log4j's
founder. It builds upon a decade of experience gained in
@@ -71,7 +68,7 @@
</p>
<p>The <em>logback-*.jar</em> files are part of the logback
- distribution whereas <em>slf4j-api-1.7.22.jar</em> ships
+ distribution whereas <em>slf4j-api-1.7.6.jar</em> ships
with <a href="http://www.slf4j.org">SLF4J</a>, a separate project.
</p>
diff --git a/docs/manual/introduction_ja.html b/docs/manual/introduction_ja.html
deleted file mode 100644
index dffc697..0000000
--- a/docs/manual/introduction_ja.html
+++ /dev/null
@@ -1,165 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第1章:はじめに</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
-
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第1章 はじめに</h1>
-
- <div class="quote">
- <p><em>やる気のもたらす効果には驚くべきものがある。例え簡単なシステムであろうとも、一つでも稼働しているシステムがあれば熱意は燃え上がる。新しいグラフィカルソフトウェアを使って、スクリーンに画像が表示されたなら、たとえそれが単純な四角形であったとしても、その効果は倍増する。システムを稼働させるまでのプロセス一つ一つにそういう瞬間があるものだ。チームが四ヶ月かけて何かを成し遂げたなら、きっとそれ以上に複雑なことが出来るほどに成長できることに気付かされたものだ。</em></p>
-
- <p>—FREDERICK P. BROOKS, JR., <em>The Mythical Man-Month</em></p>
- </div>
-
-
- <script src="../templates/creative.js" type="text/javascript"></script>
-
- <h2>logbackとは何か?</h2>
-
- <p>Logback は巷で大人気の log4j プロジェクトの後継プロジェクトです。log4j の創始者であるCekiGülcü によって設計されました。強固で頑健なロギングシステムの十年間に及ぶ経験に基いて設計、構築されています。おかげで、logback は既存のロギングシステムと比べてより高速で、より小さなフットプリントを持つようになりました。場合によってはその差は非常に大きなこともあります。同じくらい重要なのが、logback は他のロギングシステムには無い<a href="http://logback.qos.ch/reasonsToSwitch.html">固有の便利なフィーチャ</a>を提供していることです。
- </p>
-
- <h2>最初のステップ</h2>
-
- <script src="../templates/setup.js" type="text/javascript"></script>
-
- <a name="Requirements"></a>
- <h3>必要条件</h3>
-
- <p>logback-classic モジュールを動かす際は、クラスパス上に <em>slf4j-api.jar</em> と <em>logback-core.jar</em> と <em>logback-classic.jar</em> が配置されている必要があります。
- </p>
-
- <p><em>logback-*.jar</em> ファイルは logback の配布物に含まれていますが、 {0]slf4j-api-1.7.6.jar は別のプロジェクトである <a href="http://www.slf4j.org">SLF4J</a> の配布物です。
- </p>
-
- <p>さあ、logback を使ってみましょう。</p>
-
-<em>例1.1:ロギングの基本的なテンプレート( <a href="http://logback.qos.ch/xref/chapters/introduction/HelloWorld1.html">logback-examples/src/main/java/chapters/introduction/HelloWorld1.java</a> )</em>
-<pre class="prettyprint source">package chapters.introduction;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class HelloWorld1 {
-
- public static void main(String[] args) {
-
- Logger logger = LoggerFactory.getLogger("chapters.introduction.HelloWorld1");
- logger.debug("Hello world.");
-
- }
-}</pre>
-
- <p><code>HelloWorld1</code>クラスは <code>chapters.introduction</code> パッケージに定義されています。最初に SLF4J の API である <a href="http://slf4j.org/api/org/slf4j/Logger.html"><code>Logger</code></a> と <a href="http://slf4j.org/api/org/slf4j/LoggerFactory.html"><code>LoggerFactory</code></a> を <code>org.slf4j</code> パッケージからインポートしています。
- </p>
-
-
- <p>main()メソッドの最初の行では、<code>LoggerFactory</code>クラスの static メソッドである <code>getLogger</code> メソッドの返す<code>Logger</code> クラスのインスタンスを、<code>logger</code>変数に代入します。logger には "chapters.introduction.HelloWorld1" という名前が付けられています。次の処理では、引数として "Hello World" を渡して、logger の<code>debug</code>メソッドを呼び出しています。これを一言で表すと、main メソッドでは、"Hello World" というメッセージの DEBUG レベルのロギングがある、と言えます。
- </p>
-
- <p>上記の例では、logbackのクラスを一つも参照していないことに注意してください。ほとんどの場合、ロギングは本来の仕事ではないので、あなたのクラスでは SLF4J のクラスをインポートするだけでよいのです。このように、全てではないにしても、あなたのクラスの大半はSLF4J APIを使用するだけで、logbackの存在には気づかないでしょう。
- </p>
-
-
- <p>このサンプルアプリケーション(<em>chapters.introduction.HelloWorld1</em>)は次のコマンドで実行することができます。</p>
- <div class="source"><pre>java chapters.introduction.HelloWorld1</pre></div>
-
- <p><code>HelloWorld1</code>アプリケーションを実行すると、コンソールに何かが一行出力されます。logbackのデフォルトの設定ポリシーにより、デフォルトの設定ファイルが見つからない場合はルートロガーに<code>ConsoleAppender</code>を割り当てるようになっています。
- </p>
-
- <p class="source">20:49:07.962 [main] DEBUG chapters.introduction.HelloWorld1 - Hello world.</p>
-
- <p>logback は組み込みの状態管理システムによって、内部状態をレポートすることができます。<code>StatusManager</code>と呼ばれるコンポーネントを通じて、logback が有効になってから発生した重要なイベントの回数にアクセスすることができます。しばらくは、<code>StatusPrinter</code> クラスの<code>print()</code>メソッドによって logback の内部状態を出力することにします。
- </p>
-
-<em>例:ロガーの内部状態を出力する( <a href="http://logback.qos.ch/xref/chapters/introduction/HelloWorld2.html">logback-examples/src/main/java/chapters/introduction/HelloWorld2.java</a> )</em>
-<pre class="prettyprint source">package chapters.introduction;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-<b>import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.core.util.StatusPrinter;</b>
-
-public class HelloWorld2 {
-
- public static void main(String[] args) {
- Logger logger = LoggerFactory.getLogger("chapters.introduction.HelloWorld2");
- logger.debug("Hello world.");
-
- // print internal state
- <b>LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- StatusPrinter.print(lc);</b>
- }
-}</pre>
-
-
- <p><code>HelloWorld2</code>アプリケーションを実行すると次のように出力されます。</p>
-
-<div class="source longline"><pre>12:49:22.203 [main] DEBUG chapters.introduction.HelloWorld2 - Hello world.
-12:49:22,076 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
-12:49:22,078 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
-12:49:22,093 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.xml]
-12:49:22,093 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Setting up default configuration.
-</pre></div>
-
-
- <p>これは、logback が設定ファイルである <em>logback-test.xml</em> と <em>logback.xml</em> を見つけられなかったことを意味しています(詳しくは後述します)。そして、デフォルトポリシー(基本的な<code>ConsoleAppender</code>を使います)を使うように自分自身を設定しています。<code>Appender</code>とは、出力先として使用されるクラスのことです。既存のアペンダーには、コンソール、ファイル、Syslog、TCPソケット、JMSなどをいろいろな出力先のクラスが存在します。ユーザーは自分たちの状況に応じたアペンダーを簡単に作ることができます。
- </p>
-
- <p>異常が起きた場合、内部状態を自動的にコンソールに出力するようになっています。</p>
-
- <p>前の例はかなり単純なものでした。とはいえ、大きなアプリケーションで行われている実際のロギングもそんなに大きく変わるものではありません。一般的なロギング文の形式は変わらないでしょう。違うとしたら設定処理ですね。しかし、必要に応じたカスタマイズや設定をしたくなるでしょう。logbackを設定する方法については、以降の章で説明します。
- </p>
-
- <p>前述した例では、<code>StatusPrinter.print()</code>メソッドによって内部状態を出力するように命令していることに注意してください。logback の内部状態は、logback に起因する問題を調査するために非常に役立ちます。
- </p>
-
- <p>あなたのアプリケーションでロギングを有効にするための手順は次の三つです。
- </p>
-
- <ol>
- <li>logback の環境を準備します。やり方はさまざまです。詳細は後述します。</li>
-
- <li>ロギングをしたい全てのクラスで、<code>org.slf4j.LoggerFactory</code>の<code>getLogger()</code>メソッドによって<code>Logger</code>のインスタンスを取得しましょう。<code>getLogger()</code>メソッドにはクラス名やクラスオブジェクト自体を引数にしましょう。</li>
-
- <li>logger インスタンスのロギング用メソッドを呼び出しましょう。debug() info() warn() error() といったものがあります。そうすれば、アペンダーとして設定した出力先にログが出力されます。</li>
- </ol>
-
-
- <h2 class="doAnchor" name="building">logbackをビルドする</h2>
-
- <p>logback はビルドツールとして Maven を使用しています。<a href="http://maven.apache.org">Maven</a> はオープンソースのビルドツールで、広く利用されているものです。
- </p>
-
- <p>Maven をインストールしたら、logback の配布物を展開して、展開先のディレクトリに移動します。そして <code>mvn install</code> コマンドを実行すれば、全てのモジュールがビルドされます。Mavenは必要な外部ライブラリを自動的にダウンロードします。
- </p>
-
- <p>logback の配布物には完全なソースコードが含まれているので、編集して自分だけのバージョンのライブラリをビルドすることができます。あなたが修正したバージョンの logback は、LGPL ライセンス、もしくは、EPL ライセンスに従って再配布することもできます。
- </p>
-
- <p>IDE から logback をビルドする場合は<a href="http://logback.qos.ch/setup.html#ide">クラスパスの設定について説明したページ</a>を参照してください。</p>
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/manual/jmxConfig.html b/docs/manual/jmxConfig.html
index aeee141..86fee32 100644
--- a/docs/manual/jmxConfig.html
+++ b/docs/manual/jmxConfig.html
@@ -29,8 +29,6 @@
<div id="content">
<h1>Chapter 10: JMX Configurator</h1>
-
- <a href="jmxConfig_ja.html">和訳 (Japanese translation)</a>
<p>As its name indicates, <code>JMXConfigurator</code> allows
configuration of logback via JMX. In a nutshell, it lets you
diff --git a/docs/manual/jmxConfig_ja.html b/docs/manual/jmxConfig_ja.html
deleted file mode 100644
index 2b71a42..0000000
--- a/docs/manual/jmxConfig_ja.html
+++ /dev/null
@@ -1,290 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第10章 JMXコンフィギュレーター</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第10章 JMXコンフィギュレーター</h1>
-
- <p>名前のとおり、<code>JMXConfigurator</code>を使うとJMX経由でlogbackを設定することができます。つまり、デフォルトの設定ファイルで設定されたlogbackを、指定したパスやURLに配置した設定ファイルの内容で再設定したり、ロガーの一覧を取得したり、ロガーのレベルを変更することができるのです。
- </p>
-
- <h3>JMXコンフィギュレーターを使用する</h3>
-
-
- <p>サーバーを実行しているJVMがJDK1.6以降なら、コマンドラインから<code>jconsole</code>コマンドを実行するだけで、実行中のサーバーのMBeanServerにアクセスすることができます。古いJVMで実行している場合は<a href="./10-jmxConfig.html#jmxEnablingServer">サーバーでJMXを有効化する</a>のセクションを読んでおいてください。
- </p>
-
- <p>次のように設定ファイルに1行追加するだけで<code>JMXConfigurator</code>が有効になります。</p>
-
- <pre class="prettyprint source"><configuration>
- <b><jmxConfigurator /></b>
-
- <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
- <layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>%date [%thread] %-5level %logger{25} - %msg%n</Pattern>
- </layout>
- </appender>
-
- <root level="debug">
- <appender-ref ref="console" />
- </root>
-</configuration></pre>
-
- <p><em>jconsole</em>でサーバーに接続すれば、MBeans タブに表示される "ch.qos.logback.classic.jmx.Configurator" フォルダの下にいろいろなコマンドがぶら下がっているのが確認できます。スクリーンショットを見てください。</p>
-
- <h3 class="doAnchor" name="jmxConfigurator"><code>jconsole</code>で<code>JMXConfigurator</code>を表示している様子</h3>
-
- <img src="images/chapters/jmxConfigurator/jmxConfigurator.gif" alt="jmxConfigurator">
-
- <p>次のような操作を実行することができます。</p>
-
- <ul>
- <li>デフォルトの設定ファイルを使用してlogbackを再設定します。</li>
-
- <li>URLに配置された設定ファイルを使用して再設定します。</li>
- <li>ファイルパスに配置された設定ファイルを使用して再設定します。</li>
-
- <li>指定したロガーのレベルを設定します。nullを設定するには文字列"null"を指定します。</li>
- <li>指定したロガーのレベルを取得します。nullになることがあります。</li>
- <li>指定したロガーの<a href="./01-architecture.html#effectiveLevel">有効レベル</a>を取得します。</li>
- </ul>
-
- <p><code>JMXConfigurator</code>はAttributesとして存在しているロガーの一覧と、ステータスの一覧を公開します。</p>
-
- <p>ステータスの一覧は、logbackの内部状態を診断するのに役立ちます。</p>
-
- <img src="images/chapters/jmxConfigurator/statusList.gif" alt="statusList.gif">
-
- <h3 class="doAnchor" name="leak">メモリリークを避ける</h3>
-
- <p>アプリケーションがWebサーバーやアプリケーションサーバにデプロイされているときは、<code>JMXConfigurator</code>のインスタンスをJVMのMBeanサーバーに登録すると、システムクラスローダーの参照をアプリケーションが持つようになってしまいます。これはアプリケーションが停止したり再デプロイされたときにJMXConfiguratorがガベージコレクションされてしまうのを防ぐためですが、そのせいで深刻なメモリリークが生じてしまいます。</p>
-
- <p>したがって、スタンドアローンなJavaアプリケーションではないときは、必ず<code>JMXConfigurator</code>のインスタンスの登録をJVMのMBeanサーバーから解除しなければなりません。適切な<code>LoggerContetext</code>の<code>reset()</code>メソッドを呼べば、すべてのJMXConfiguratorのインスタンスは自動的に解除されるはずです。ロガーコンテキストを初期化するなら、<code>javax.servlet.ServletContextListener</code>の<code>contextDestroyed()</code>メソッドがちょうど良い場所です。サンプルコードを見てみましょう。</p>
-
- <pre class="prettyprint source">import javax.servlet.ServletContextEvent;
-import javax.servlet.ServletContextListener;
-
-import org.slf4j.LoggerFactory;
-import ch.qos.logback.classic.LoggerContext;
-
-public class MyContextListener implements ServletContextListener {
-
- public void contextDestroyed(ServletContextEvent sce) {
- <b>LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
- <b>lc.stop();</b>
- }
-
- public void contextInitialized(ServletContextEvent sce) {
- }
-} </pre>
-
-
- <!-- ============ Multiple web-applications ================== -->
-
-
- <h2 class="doAnchor" name="multiple">複数のWebアプリケーションで<code>JMXConfigurator</code>を使用する</h2>
-
- <p>複数のアプリケーションを同じサーバーにデプロイしている、<a href="./09-loggingSeparation.html#contextSelectors">コンテキストセレクタ</a>を上書きせずデフォルトのまま使っている、それぞれのアプリケーションの<em>WEB-INF/lib</em>フォルダに<em>logback-*.jar</em>と<em>slf4j-api.jar</em>を置いている、これらが全て当てはまるなら、それぞれのアプリケーションの<code>JMXConfigurator</code>のインスタンスは同じ名前("ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator")で登録されてしまうでしょう。言い換えると、何もしなければそれぞれのアプリケーションのロガーコンテキストに関連付けられた<code>JMXConfigurator</code>のインスタンスは衝突してしまうのです。
- </p>
-
- <p>衝突を避けるには、単に<a href="./03-configuration.html#contextName">アプリケーションのロガーコンテキストに名前を付ける</a>だけでよいのです。そうすれば、<code>JMXConfigurator</code>には自動的にその名前が設定されます。
- </p>
-
- <p>たとえば、それぞれ"コアラ"と"コウモリ"という名前のアプリケーションをデプロイしているものとします。そして、コアラのlogback.xmlには次のような設定がされているとしましょう。</p>
-
- <pre class="prettyprint source"><configuration>
- <b><contextName>Koala</contextName></b>
- <jmxConfigurator/>
- ...
-<configuration></pre>
-
- <p>また、コウモリのlogback.xmlには次のように設定がされていることにします。</p>
-
- <pre class="prettyprint source"><configuration>
- <b><contextName>Wombat</contextName></b>x
- <jmxConfigurator/>
- ...
-<configuration></pre>
-
- <p>そうすると、jconsoleのMBeanタブには、次のように二つの独立した<code>JMXConfigurator</code>のインスタンスが表示されるはずです。</p>
-
- <img src="images/chapters/jmxConfigurator/multiple.gif" alt="multiple.gif">
-
- <p>MBeanサーバーに登録されるJMXConfiguratorの名前は、<code>jmxConfigurator要素</code>の"objectName"属性で指定することができます。</p>
-
- <!-- ============ JMX enabling your server ================== -->
-
- <h3 class="doAnchor" name="jmxEnablingServer">JMXを有効化する</h3>
-
- <p>JDK1.6以降のJVMでサーバーを実行している場合はデフォルトでJMXが有効になっています。</p>
-
- <p>JDK1.6以前の古いJVMを使っている場合は、サーバーのJMX関連のドキュメントを確認することをおすすめします。たとえば<a href="http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html">Tomcat</a>や<a href="http://docs.codehaus.org/display/JETTY/JMX">Jetty</a>にはドキュメントがあります。それはさておき、このドキュメントではTomcatとJettyの設定方法を簡単に説明していきます。
- </p>
-
- <!-- ================ Configuring Jetty ================== -->
-
- <h4>JettyでJMXを有効にする(JDK 1.5およびJDK 1.6で動作確認済み)</h4>
-
- <p>以降の設定はJDK1.5とJDK1.6で動作確認しています。JDK1.6以降のJVMでは、デフォルトでJMXが有効になっています。以降の設定をしてもよいですが、特に何も変わりません。JDK1.5のJVMで実行するJettyでJMXを有効にするには、設定ファイル<em>$JETTY_HOME/etc/jetty.xml</em>にいくつか設定を追加する必要があります。追加するのは次の設定です。</p>
-
- <pre class="prettyprint source"><Call id="MBeanServer" class="java.lang.management.ManagementFactory"
- name="getPlatformMBeanServer"/>
-
-<Get id="Container" name="container">
- <Call name="addEventListener">
- <Arg>
- <New class="org.mortbay.management.MBeanContainer">
- <Arg><Ref id="MBeanServer"/></Arg>
- <Call name="start" />
- </New>
- </Arg>
- </Call>
-</Get> </pre>
-
- <p>Jettyの公開するMBeanに<code>jconsole</code>でアクセスしたいときは、Jettyを実行するJVMにシステムプロパティ"com.sun.management.jmxremote"を指定しておかなければなりません。
- </p>
-
- <p>スタンドアローン版のJettyなら次のように実行します。</p>
-
-
- <p class="source">java <b>-Dcom.sun.management.jmxremote</b> -jar start.jar [config files]</p>
-
- <p>MavenのプラグインからJettyを実行する場合は、システムプロパティ"com.sun.management.jmxremote"をシェル変数<code>MAVEN_OPTS</code>で指定しなければなりません。</p>
-
- <p class="source"><b>MAVEN_OPTS="-Dcom.sun.management.jmxremote</b>" mvn jetty:run</p>
-
- <p>そうすれば、<code>jconsole</code>でJettyの公開するMBeanとして<code>JMXConfigurator</code>にアクセスすることができます。</p>
-
- <img src="images/chapters/jmxConfigurator/jconsole15_jetty.gif" alt="jconsole15_jetty.gif">
-
- <p>接続したら、<a href="./10-jmxConfig.html#jmxConfigurator">前のスクリーンショット</a>のように<code>JMXConfigurator</code>にアクセスできるはずです。</p>
-
- <h4>JettyにMX4Jを入れる(JDK 1.5およびJDK 1.6で動作確認済み)</h4>
-
- <p>MX4JのHTTPインターフェイスを経由して<code>JMXConfigurator</code>にアクセスしたいときは、前に説明した設定ファイルに管理ポート番号の設定を追加します。<a href="http://mx4j.sourceforge.net/">MX4J</a>はすでにダウンロード済みであることにします。
- </p>
-
- <pre class="prettyprint source"><Call id="MBeanServer"
- class="java.lang.management.ManagementFactory"
- name="getPlatformMBeanServer"/>
-
-<Get id="Container" name="container">
- <Call name="addEventListener">
- <Arg>
- <New class="org.mortbay.management.MBeanContainer">
- <Arg><Ref id="MBeanServer"/></Arg>
- <b><Set name="managementPort">8082</Set></b>
- <Call name="start" />
- </New>
- </Arg>
- </Call>
-</Get>
- </pre>
-
- <p>なお、<em>mx4j-tools.jar</em>はJettyのクラスパス上に配置しておいてください。
- </p>
-
- <p>MavenのプラグインからJettyを実行する場合は、依存関係に<em>mx4j-tools</em>を追加してください。</p>
-
- <pre class="prettyprint source"><plugin>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>maven-jetty-plugin</artifactId>
- <configuration>
- <jettyConfig>path/to/jetty.xml</jettyConfig>
- ...
- </configuration>
- <b><dependencies>
- <dependency>
- <groupId>mx4j</groupId>
- <artifactId>mx4j-tools</artifactId>
- <version>3.0.1</version>
- </dependency>
- </dependencies></b>
-</plugin></pre>
-
- <p>この設定でJettyを起動すると、ブラウザで次のURLから<code>JMXConfigurator</code>にアクセスできるようになります。アクセスした後は "ch.qos.logback.classic" を探してください。</p>
-
- <p class="source"><a href="http://localhost:8082/">http://localhost:8082/</a></p>
-
- <p>MX4Jにアクセスしているところのスクリーンショットです。</p>
-
- <img src="images/chapters/jmxConfigurator/mx4j_jetty.gif" alt="mx4j_jetty.gif">
-
-
- <!-- ================ Tomcat ================== -->
-
- <h4>Tomcat用のJMXの設定(JDK 1.5およびJDK 1.6で動作確認済み)</h4>
-
- <p>JDK1.6以降のJVMを使用しているならJMXはデフォルトで有効になっているので以降の設定をする必要はありません。JDK1.5の場合は<em>$TOMCAT_HOME/bin/catalina.sh(Windowsの場合はcatalina.bat)</em>の適切な場所に次の設定を追加する必要があります。</p>
-
- <p class="source">CATALINA_OPTS="-Dcom.sun.management.jmxremote"</p>
-
- <p>そうすれば、<code>jconsole</code>を使ってTomcatの公開するMBeanとして<code>JMXConfigurator</code>にアクセスできるようになります。</p>
-
- <p class="source"></p>
-
- <img src="images/chapters/jmxConfigurator/jconsole15_tomcat.gif" alt="jconsole15_tomcat.gif">
-
- <p>接続したら、<a href="./10-jmxConfig.html#jmxConfigurator">前のスクリーンショット</a>のように<code>JMXConfigurator</code>にアクセスできるはずです。
-</p>
-
-
- <h4>TomcatにMX4Jを入れる(JDK 1.5およびJDK 1.6で動作確認済み)</h4>
-
- <p>MX4JのWebインターフェイスを使ってJMXのコンポーネントにアクセスしたくなるかもしれません。そうするために必要な設定方法を説明します。</p>
-
- <p><a href="http://mx4j.sourceforge.net/">MX4J</a>はすでにダウンロードしてあることにしましょう。<em>mx4j-tools.jar</em>を<em>$TOMCAT_HOME/bin</em>フォルダーにおいてください。それから、<em>$TOMCAT_HOME/bin/catalina.sh(Windowsの場合はcatalina.bat)</em>の適切な場所に次の設定を追加します。</p>
-
- <p class="source"><!-- at the beginning of the file -->
-CATALINA_OPTS="-Dcom.sun.management.jmxremote"
-
-<!-- in the "Add on extra jar files to CLASSPATH" section -->
-CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/mx4j-tools.jar</p>
-
- <p>最後に、<em>$TOMCAT_HOME/conf/server.xmlで新しい<code>Connector要素</code>を宣言します。</em></p>
-
-
- <pre class="prettyprint source"><Connector port="0"
- handler.list="mx"
- mx.enabled="true"
- mx.httpHost="localhost"
- mx.httpPort="8082"
- protocol="AJP/1.3" /></pre>
-
- <p>Tomcatを起動したら、ブラウザで次のURLからJMXConfiguratorにアクセスできるようになります。アクセスした後は "ch.qos.logback.classic" を探してください。</p>
-
- <p class="source"><a href="http://localhost:8082">http://localhost:8082/</a></p>
-
- <p>MX4Jにアクセスしているところのスクリーンショットです。
-</p>
-
- <img src="images/chapters/jmxConfigurator/mx4j_tomcat.gif" alt="mx4j_tomcat.gif">
-
-
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-
- </div>
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/manual/layouts.html b/docs/manual/layouts.html
index 32c44d8..7e78711 100644
--- a/docs/manual/layouts.html
+++ b/docs/manual/layouts.html
@@ -29,8 +29,6 @@
<div id="content">
<h1>Chapter 6: Layouts</h1>
-
- <a href="layouts_ja.html">和訳 (Japanese translation)</a>
<div class="quote">
<p>TCP implementations will follow a general principle of
@@ -162,7 +160,7 @@ public class MySampleLayout extends LayoutBase<ILoggingEvent> {
<code>MySampleLayout</code>. Here is the configuration file:</p>
<em>Example: Configuration of MySampleLayout
- (logback-examples/src/main/resources/chapters/layouts/sampleLayoutConfig.xml)</em>
+ (logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig.xml)</em>
<span class="asGroovy" onclick="return asGroovy('sampleLayoutConfig');">View as .groovy</span>
<pre id="sampleLayoutConfig" class="prettyprint source"><configuration>
@@ -543,7 +541,7 @@ WARN [main]: Message 2</p>
<p>Used to output the date of the logging event. The date
conversion word admits a pattern string as a parameter. The
pattern syntax is compatible with the format accepted by <a
- href="https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html"><code>java.text.SimpleDateFormat</code></a>.</p>
+ href="http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html"><code>java.text.SimpleDateFormat</code></a>.</p>
<p>You can specify the string <em>"ISO8601"</em> for the
ISO8601 date format. Note that the %date conversion word
@@ -626,9 +624,7 @@ WARN [main]: Message 2</p>
<tr >
<td class="word" name="caller">
<b>caller{depth}</b>
- <b>caller{depthStart..depthEnd}</b>
<b>caller{depth, evaluator-1, ... evaluator-n}</b>
- <b>caller{depthStart..depthEnd, evaluator-1, ... evaluator-n}</b>
</td>
<td>
@@ -660,16 +656,7 @@ Caller+1 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)</pre>
Caller+0 at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22)
Caller+1 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)
Caller+2 at mainPackage.ConfigTester.main(ConfigTester.java:38)</pre>
-
- <p>A range specifier can be added to the <em>caller</em> conversion specifier's
- options to configure the depth range of the information to be displayed.
- </p>
-
- <p>For example, <b>%caller{1..2}</b> would display the following excerpt:</p>
-
-<pre class="source white_bg">0 [main] DEBUG - logging statement
-Caller+0 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)</pre>
-
+
<p>This conversion word can also use evaluators to test
logging events against a given criterion before computing
caller data. For example, using <b>%caller{3,
@@ -1381,7 +1368,7 @@ Wrapped by: org.springframework.BeanCreationException: Error creating bean with
<em>
Example: Highlighting levels
- (logback-examples/src/main/resources/chapters/layouts/highlighted.xml)
+ (logback-examples/src/main/java/chapters/layouts/highlighted.xml)
</em>
<span class="asGroovy" onclick="return asGroovy('highlighted');">View as .groovy</span>
@@ -1458,7 +1445,7 @@ Wrapped by: org.springframework.BeanCreationException: Error creating bean with
<em>
Example: Sample usage of EventEvaluators
- (logback-examples/src/main/resources/chapters/layouts/callerEvaluatorConfig.xml)
+ (logback-examples/src/main/java/chapters/layouts/callerEvaluatorConfig.xml)
</em>
<span class="asGroovy" onclick="return asGroovy('callerEvaluatorConfig');">View as .groovy</span>
@@ -1636,7 +1623,7 @@ public class ExceptionEvaluatorExample {
<em>
Example: Sample usage of EventEvaluators
- (logback-examples/src/main/resources/chapters/layouts/exceptionEvaluatorConfig.xml)
+ (logback-examples/src/main/java/chapters/layouts/exceptionEvaluatorConfig.xml)
</em>
<pre class="prettyprint source"><configuration>
@@ -2083,14 +2070,6 @@ java.lang.Exception: display
</td>
</tr>
<tr>
- <td class="word" name="elapsedSeconds"><b>T / elapsedSeconds</b></td>
- <td>
- <p>
- The time taken to serve the request, in seconds.
- </p>
- </td>
- </tr>
- <tr>
<td class="word" name="dateAccess"><b>t / date</b></td>
<td>
<p>Outputs the date of the logging event. The date
@@ -2115,14 +2094,6 @@ java.lang.Exception: display
</td>
</tr>
<tr>
- <td class="word" name="queryString"><b>q / queryString</b></td>
- <td>
- <p>
- Request query string, prepended with a '?'.
- </p>
- </td>
- </tr>
- <tr>
<td class="word" name="requestURI"><b>U / requestURI</b></td>
<td>
<p>
@@ -2130,24 +2101,12 @@ java.lang.Exception: display
</p>
</td>
</tr>
- <tr>
- <td class="word" name="sessionID"><b>S / sessionID</b></td>
- <td>
- <p>Session ID.</p>
- </td>
- </tr>
<tr >
<td class="word" name="server"><b>v / server</b></td>
<td>
<p>Server name.</p>
</td>
</tr>
- <tr>
- <td class="word" name="threadName"><b>I / threadName</b></td>
- <td>
- <p>Name of the thread which processed the request.</p>
- </td>
- </tr>
<tr class="b">
<td class="word" name="localPort"><b>localPort</b></td>
<td>
diff --git a/docs/manual/layouts_ja.html b/docs/manual/layouts_ja.html
deleted file mode 100644
index eb26921..0000000
--- a/docs/manual/layouts_ja.html
+++ /dev/null
@@ -1,1645 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"></meta>
- <title>第6章 レイアウト</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第6章 レイアウト</h1>
-
- <div class="quote">
- <p>TCPの実装は頑健性の一般原則に従う。つまり、自分自身の行動は保守的に、他者から行われる行動については寛容さを持って受け入れるということだ。
- </p>
- <p>-JON POSTEL、RFC 793</p>
- </div>
-
- <script src="../templates/creative.js" type="text/javascript"></script>
- <script src="../templates/setup.js" type="text/javascript"></script>
-
- <h2 class="doAnchor">レイアウトとは何か</h2>
-
- <p>レイアウトといってもフロリダ州の大規模集合住宅とは何の関係もありません。レイアウトはlogbackのコンポーネントであり、受け取ったロギングイベントを文字列に変換する役割を担っています。<a href="http://logback.qos.ch/xref/ch/qos/logback/core/Layout.html"><code>Layout</code></a>インターフェイスの<code>format()</code>メソッドは、引数としてロギングイベントとみなされる(任意の型の)オブジェクトを受け取り、文字列を返します。<code>Layout</code>インターフェイスの概要を次に示します。
- </p>
-
- <pre class="prettyprint source">public interface Layout<E> extends ContextAware, LifeCycle {
-
- String doLayout(E event);
- String getFileHeader();
- String getPresentationHeader();
- String getFileFooter();
- String getPresentationFooter();
- String getContentType();
-}</pre>
-
- <p>このインターフェイスは簡潔ですが、あらゆる書式化のニーズを十分に満たしています。<em>Catch-22</em>に登場するテキサス育ちの開拓者であるジョセフ・ヘラーならこう叫んでいるところです。「レイアウトを実装しようにもたったの5つしかメソッドがない!!?ナンデ?!」
- </p>
-
- <h2>Logback-classic モジュール</h2>
-
- <p>logback-classic モジュールは<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/spi/ILoggingEvent.html">ch.qos.logback.classic.spi.ILoggingEvent</a></code>だけを扱うようになっています。この節を読み進めていけば理由が明らかになります。</p>
-
- <h2 class="doAnchor" name="writingYourOwnLayout">レイアウトを自作する</h2>
-
- <p>logback-classic モジュールで使うために、簡潔で十分な機能性のあるレイアウトを自作してみましょう。出力したいのは次のようなものです。アプリケーションが起動してから経過した時間、ロギングイベントのログレベル、ブラケットで囲んだ呼び出しスレッド名、ロガー名、ダッシュ(-のこと)とそれに続くロギングイベントのメッセージ、最後に改行文字も加えておきましょう。
- </p>
-
- <p>出力例は次のようになります。</p>
-
- <div class="source">10489 DEBUG [main] com.marsupial.Pouch - Hello world.</div>
-
- <p>テキサスの開拓者が実装したレイアウトのコードを見てましょう。</p>
- <p class="example">例:自作レイアウトのサンプル実装(<a href="http://logback.qos.ch/xref/chapters/layouts/MySampleLayout.html">logback-examples/src/main/java/chapters/layouts/MySampleLayout.java</a>)</p>
-
- <pre class="prettyprint source">package chapters.layouts;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.LayoutBase;
-
-public class MySampleLayout extends LayoutBase<ILoggingEvent> {
-
- public String doLayout(ILoggingEvent event) {
- StringBuffer sbuf = new StringBuffer(128);
- sbuf.append(event.getTimeStamp() - event.getLoggingContextVO.getBirthTime());
- sbuf.append(" ");
- sbuf.append(event.getLevel());
- sbuf.append(" [");
- sbuf.append(event.getThreadName());
- sbuf.append("] ");
- sbuf.append(event.getLoggerName();
- sbuf.append(" - ");
- sbuf.append(event.getFormattedMessage());
- sbuf.append(CoreConstants.LINE_SEP);
- return sbuf.toString();
- }
-}</pre>
-
- <p><code>MySampleLayout</code>は<a href="http://logback.qos.ch/xref/ch/qos/logback/core/LayoutBase.html"><code>LayoutBase</code></a>を継承しているのに気付きましたか。このクラスは全てのレイアウトのインスタンスに共通する内部状態を管理するものです。例えば、レイアウトが開始しているか、停止しているか、ヘッダーはあるか、フッターはあるか、コンテンツタイプはあるか、といったものです。おかげで、開発者は書式化の方法にだけ集中することができるのです。<code>LayoutBase</code>はジェネリッククラスです。上記のコードでは、<code>MySampleLayout</code>は<code>LayoutBase<ILoggingEvent></code>を継承しています。
- </p>
-
- <p><code>doLayout(ILoggingEvent event)</code>メソッド(<code>MySampleLayout</code>の実装する唯一のメソッドです)では、最初に空の<code>StringBuffer</code>を生成して、ロギングイベントのパラメータを付け足していきます。開拓者らしく、慎重に書式化したようです。ロギング要求で1つ以上のパラメータが渡されることを考えればこれは大事なことです。</p>
-
- <p><code>doLayout()</code>メソッドでは、StringBufferにいろいろな文字列を追加したあとで1つの文字列に変換して、その文字列を呼び出し元に返します。
- </p>
-
- <p>上記の<code>doLayout</code>メソッドでは、ロギングイベントに含まれる可能性のあるあらゆる例外を無視します。実際のレイアウトの実装では、ほぼ確実に例外の内容を出力したいはずです。
- </p>
-
- <h3 class="doAnchor" name="configuringYourOwnLayout">自作レイアウトの設定</h3>
-
- <p>自作レイアウトは、他のコンポーネントと同じように設定されます。前述したように<code>FileAppender</code>とその派生クラスにはエンコーダーが必要です。<code>FileAppender</code>のニーズを満たすため、<code>LayoutWrappingEncoder</code>に自作した<code>MySampleLayout</code>をラップしてみましょう。次のような設定になります。</p>
-
- <p class="example">例:MySampleLayoutの設定(<a href="http://logback.qos.ch/xref/chapters/layouts/sampleLayoutConfig.xml">logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('logback_Console');">Groovyで表示</span>
-<pre id="sampleLayoutConfig" class="prettyprint source"><configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <b><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"></b>
- <b><layout class="chapters.layouts.MySampleLayout" /></b>
- <b></encoder></b>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>サンプルアプリケーションの<code><a href="http://logback.qos.ch/xref/chapters/layouts/SampleLogging.html">chapters.layouts.SampleLogging</a></code>は、一つ目の引数で指定された設定ファイルを使ってlogbackを設定します。そして、デバッグメッセージとエラーメッセージを1つづつロギングします。</p>
-
- <p><em>logback-examples</em>ディレクトリに移動して、次のコマンドを実行してみましょう。
- </p>
-
- <p class="command">java chapters.layouts.SampleLogging src/main/java/chapters/layouts/sampleLayoutConfig.xml</p>
-
- <p>コンソールには次のように出力されます。</p>
-
-<div class="source"><pre>0 DEBUG [main] chapters.layouts.SampleLogging - Everything's going well
-0 ERROR [main] chapters.layouts.SampleLogging - maybe not quite...</pre></div>
-
- <p>簡単でしょう?エレア派の懐疑論者ピュロンは、それ自体が不確実であるということ以外に確実なことは無い、と主張しました。つまり、確かなことなど何もないというのです。彼はきっとこう質問するでしょう。「それでレイアウトのオプションについてはどうなっているの?」上記の自作レイアウトを少し変更したバージョンが<a href="http://logback.qos.ch/xref/chapters/layouts/MySampleLayout2.html"><code>MySampleLayout2.java</code></a>です。このマニュアル全体を通じて言えることですが、レイアウトでもlogbackの他のコンポーネントでも、単にセッターメソッドを設定するだけでプロパティを指定できるようになります。
- </p>
-
- <p><a href="http://logback.qos.ch/xref/chapters/layouts/MySampleLayout2.html"><code>MySampleLayout2</code></a>クラスには、2つのプロパティがあります。一つ目は、出力されるメッセージの先頭に追加する接頭辞です。二つ目は、ロギング要求を送信したスレッドの名前を表示するかどうかを選択する真偽値です。
- </p>
-
- <p><a href="http://logback.qos.ch/xref/chapters/layouts/MySampleLayout2.html"><code>MySampleLayout2</code></a>のコードを見てみましょう。</p>
-
- <pre class="prettyprint source">package chapters.layouts;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.LayoutBase;
-
-public class MySampleLayout2 extends LayoutBase<ILoggingEvent> {
-
- String prefix = null;
- boolean printThreadName = true;
-
- <b>public void setPrefix(String prefix) {
- this.prefix = prefix;
- }
-
- public void setPrintThreadName(boolean printThreadName) {
- this.printThreadName = printThreadName;
- }</b>
-
- public String doLayout(ILoggingEvent event) {
- StringBuffer sbuf = new StringBuffer(128);
- <b>if (prefix != null) {
- sbuf.append(prefix + ": ");
- }</b>
- sbuf.append(event.getTimeStamp() - event.getLoggerContextVO().getBirthTime());
- sbuf.append(" ");
- sbuf.append(event.getLevel());
- <b>if (printThreadName) {
- sbuf.append(" [");
- sbuf.append(event.getThreadName());
- sbuf.append("] ");
- } else {
- sbuf.append(" ");
- }</b>
- sbuf.append(event.getLoggerName());
- sbuf.append(" - ");
- sbuf.append(event.getFormattedMessage());
- sbuf.append(LINE_SEP);
- return sbuf.toString();
- }
-}</pre>
-
-
- <p>プロパティのセッターメソッドを追加すれば設定ファイルから指定できるようになります。<code>printThreadName</code>プロパティの型は真偽値(boolean)であって文字列(<code>String</code>)ではないので注意してください。logbackのコンポーネントの設定については、<a href="http://logback.qos.ch/manual/configuration.html">設定に関する章</a>で詳しく説明しています。<a href="http://logback.qos.ch/manual/onJoran.html">Joranの章</a>にはより詳細な説明があります。<code>MySampleLayout2</code>のために特別に誂えた設定ファイルは次のとおりです。
- </p>
-
-
- <span class="asGroovy" onclick="return asGroovy('MySampleLayout2');">Groovyとして表示</span>
- <pre id="MySampleLayout2" class="prettyprint source"><configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
- <layout class="chapters.layouts.MySampleLayout2">
- <b><prefix>MyPrefix</prefix></b>
- <b><printThreadName>false</printThreadName></b>
- </layout>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p></p>
-
-
- <h2 class="doAnchor" name="ClassicPatternLayout">PatternLayout</h2>
-
- <p>logback-classic の配布物には、<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/PatternLayout.html">PatternLayout</a></code>と呼ばれる柔軟性のあるレイアウトが含まれています。他のレイアウトと同じく、<code>PatternLayout</code>はロギングイベントを受け取って<code>文字列</code>を返します。<code>文字列</code>は、変換パターン文字列を調整してカスタマイズすることができます。
- </p>
-
- <p><code>PatternLayout</code>の変換パターン文字列はC言語の<code>printf()</code>関数と非常によく似たもので、文字列リテラルと<em>変換指定</em>と呼ばれる書式制御式で構成されています。変換パターン文字列には、どんな文字列リテラルでも入れることができます。変換指定はパーセント記号"%"で始まり、オプションの<em>書式修飾子</em>、<em>変換指定子</em>、括弧で囲まれたパラメータが続いたものです。変換指定子には変換したいデータフィールドを指定します。例えばロガー名、レベル、日付、スレッド名などです。書式修飾子には、フィールド幅、パディング、左揃えや右揃えを指定します。
- </p>
-
- <p>既に何度か述べたとおり、<code>FileAppender</code>とその派生クラスにはエンコーダーが必要です。結局、<code>FileAppender</code>やその派生クラスと<code>PatternLayout</code>を一緒に使うには、エンコーダーでラップしなければなりません。<code>FileAppender</code>と<code>PatternLayout</code>を組み合わせることがあまりにも一般的になってしまったことを考慮して、logback の配布物には<code>PatternLayoutEncoder</code>を含めるようになりました。これは単に<code>PatternLayout</code>をラップするだけのエンコーダーなので、エンコーダーであるにも関わらずPatternLayoutのように扱えるようになっています。プログラム的に<code>ConsoleAppender</code>と<code>PatternLayoutEncoder</code>を設定する例を示します。</p>
-
-
- <p class="example">例:PatternLayoutの使用例(<a href="http://logback.qos.ch/xref/chapters/layouts/PatternSample.html">logback-examples/src/main/java/chapters/layouts/PatternSample.java</a>)</p>
-
- <pre class="prettyprint source">package chapters.layouts;
-
-import org.slf4j.LoggerFactory;
-
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.ConsoleAppender;
-
-public class PatternSample {
-
- static public void main(String[] args) throws Exception {
- Logger rootLogger = (Logger)LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
- LoggerContext loggerContext = rootLogger.getLoggerContext();
- // we are not interested in auto-configuration
- loggerContext.reset();
-
- <b>PatternLayoutEncoder encoder = new PatternLayoutEncoder();</b>
- <b>encoder.setContext(loggerContext);</b>
- <b>encoder.setPattern("%-5level [%thread]: %message%n");</b>
- <b>encoder.start();</b>
-
- ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<ILoggingEvent>();
- appender.setContext(loggerContext);
- appender.setEncoder(encoder);
- appender.start();
-
- rootLogger.addAppender(appender);
-
- rootLogger.debug("Message 1");
- rootLogger.warn("Message 2");
- }
-}</pre>
-
- <p>この例では、変換パターン文字列として<b>"%-5level [%thread] %msg%n"</b>が設定されています。logbackに組み込みの変換指定子については後で簡単に説明します。<code>PatternSample</code>アプリケーションを実行してみましょう。</p>
-
- <p class="source">java java chapters.layouts.PatternSample</p>
-
- <p>コンソールにに次のように出力されます。</p>
-
- <p class="source">DEBUG [main]: Message 1
-WARN [main]: Message 2</p>
-
- <p>変換パターン文字列の<b>"%-5level [%thread] %msg%n"</b>には、文字列リテラルと変換指定子を明示的に区切る文字が無いことに気付きましたか。変換パターン文字列を解析する際、<code>PatternLayout</code>は文字列リテラル(空白文字、括弧、コロンなど)と変換指定を分離することができます。上記の例では、変換指定"%-5level"は、ロギングイベントのレベルを5文字の幅に左揃えすることを意味します。書式指定子については後で説明します。
- </p>
-
- <p><code>PatternLayout</code>は変換パターン文字列をグループ化するために括弧を使います。<b>つまり '('と ')'には特別な意味があるので、リテラル文字列として使うときはエスケープしなければならないということです。</b> 括弧の特殊な性質について詳しくは<a href="http://logback.qos.ch/manual/layouts.html#Parentheses">後で説明</a>します。
- </p>
-
- <p>前述のとおり、変換指定によっては括弧で囲んでオプションの引数を指定することができます。例えばこういう書き方です。<code>%logger{10}</code>"logger" が変換指定子で、10が引数です。オプションの指定の仕方について詳しくは<a href="http://logback.qos.ch/manual/layouts.html#cwOptions">後で説明</a>します。
- </p>
-
- <p>利用できる変換指定とオプションを表にまとめました。1つのセルに複数の変換指定子が登場する場合、それらは別名という意味です。
- </p>
-
- <table class="bodyTable properties striped" border="0">
- <tr>
- <th><a name="conversionWord" href="http://logback.qos.ch/manual/layouts.html#conversionWord">変換指定子</a></th>
- <th>効果</th>
- </tr>
-
- <tr>
- <td class="word" name="logger">
- <a name="logger" href="http://logback.qos.ch/manual/layouts.html#logger"><span class="anchor"></span></a>
- <b>c</b>{<em>length</em>} <br>
- <b>lo</b>{<em>length</em>} <br>
- <b>logger</b>{<em>length</em>} <br>
- </td>
-
- <td>ロギングイベントを生成する一番元になったロガーの名前を出力します。
-
- <p>この変換指定子に指定できるオプションは整数値だけです。ロガー名は省略アルゴリズムに従って、意味が通る程度に短縮されます。0を指定すると特別な振る舞いをします。ロガー名文字列の中で一番右端のドット(.)から右側だけを残すようになります。省略アルゴリズムの例を表にまとめました。
- </p>
-
- <table class="bodyTable dark" border="0" cellpadding="8">
- <tr>
- <th>変換指定</th>
- <th>ロガー名</th>
- <th>結果</th>
- </tr>
- <tr>
- <td>%logger</td>
- <td>mainPackage.sub.sample.Bar</td>
- <td>mainPackage.sub.sample.Bar</td>
- </tr>
-
- <tr>
- <td>%logger{0}</td>
- <td>mainPackage.sub.sample.Bar</td>
- <td>Bar</td>
- </tr>
-
- <tr>
- <td>%logger{5}</td>
- <td>mainPackage.sub.sample.Bar</td>
- <td>m.s.s.Bar</td>
- </tr>
-
- <tr>
- <td>%logger{10}</td>
- <td>mainPackage.sub.sample.Bar</td>
- <td>m.s.s.Bar</td>
- </tr>
-
- <tr>
- <td>%logger{15}</td>
- <td>mainPackage.sub.sample.Bar</td>
- <td>m.s.sample.Bar</td>
- </tr>
-
- <tr>
- <td>%logger{16}</td>
- <td>mainPackage.sub.sample.Bar</td>
- <td>m.sub.sample.Bar</td>
- </tr>
-
- <tr>
- <td>%logger{26}</td>
- <td>mainPackage.sub.sample.Bar</td>
- <td>mainPackage.sub.sample.Bar</td>
- </tr>
- </table>
-
- <p>オプションで指定した長さを越えるとしても、一番右側のドット(.)から後ろは省略されないので気をつけてください。それ以外の部分は最短で1文字になりますが、削除することはありません。</p>
-
- </td>
- </tr>
-
- <tr>
- <td class="word" name="class">
- <b>C</b>{<em>length</em>} <br>
- <b>class</b>{<em>length</em>} <br>
- </td>
-
- <td>
- <p>ロギング要求を生成した呼び出し元のクラスの完全名を出力します。</p>
-
- <p><em>%logger</em>と同じように、引数の整数値に合わせて名前を短縮します。0には特別な意味があり、パッケージ名を除いた単純クラス名を出力するようになります。デフォルトでは、完全クラス名が出力されます。
- </p>
-
- <p>送信側のクラス情報を生成するのはとても高速とは言えません。実行速度が問題にならない場合にだけ使うほうが良いでしょう。
- </p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="contextName">
- <b>contextName</b><br>
- <b>cn</b><br></td>
- <td>ロギングイベントを生成したロガーの割り当てられたロギングコンテキストの名前。</td>
- </tr>
- <tr>
- <td class="word" name="date">
- <b>d</b>{<em>pattern</em>} <br>
- <b>date</b>{<em>pattern</em>} <br>
- <b>d</b>{<em>pattern</em>, <em>timezone</em>} <br>
- <b>date</b>{<em>pattern</em>, <em>timezone</em>} <br>
- </td>
- <td>
- <p>ロギングイベントの日時を出力するために使います。引数として日時パターン文字列を指定することができます。日時パターン文字列は<a href="https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html"><code>java.text.SimpleDateFormat</code></a>と互換性があります。</p>
-
- <p>引数に<em>"ISO8601"</em>と指定すると ISO8601 の書式になります。日時パターン文字列が指定されなかった場合、デフォルトは<a href="http://en.wikipedia.org/wiki/ISO_8601">ISO8601書式</a>になるので注意してください。</p>
-
- <p>いくつかサンプルを見てください。ここでは日時が2006年10月20日(金曜日)であることを想定しています。これはこのマニュアルを書いた人が昼食から戻ってきた日時です。</p>
-
- <table class="bodyTable dark" cellpadding="8">
- <tr>
- <th>変換パターン</th>
- <th>結果</th>
- </tr>
- <tr>
- <td>%d</td>
- <td>2006-10-20 14:06:49,812</td>
- </tr>
- <tr>
- <td>%date</td>
- <td>2006-10-20 14:06:49,812</td>
- </tr>
- <tr>
- <td>%date{ISO8601}</td>
- <td>2006-10-20 14:06:49,812</td>
- </tr>
- <tr>
- <td>%date{HH:mm:ss.SSS}</td>
- <td>14:06:49.812</td>
- </tr>
- <tr>
- <td>%date{dd MMM yyyy;HH:mm:ss.SSS}</td>
- <td>20 oct. 2006;14:06:49.812 </td>
- </tr>
- </table>
-
- <p>二番目の引数にはタイムゾーンを指定します。たとえば、'%date{HH:mm:ss.SSS, Australia/Perth}' と指定すると、世界中で一番孤立しているオーストラリアのパースの時刻を出力するようになります。タイムゾーンが指定されなかった場合、JVMのタイムゾーンが使用されます。指定したタイムゾーンが未知のものであったりタイプミスだった場合、<a href="http://docs.oracle.com/javase/6/docs/api/java/util/TimeZone.html#getTimeZone(java.lang.String)">TimeZone.getTimeZone(String)</a>メソッドの仕様に基づいてGMTが指定されたものとして解釈します。
- </p>
-
- <p><span class="label">よくある間違い</span>は、カンマ(,)が引数の区切り文字として解釈されてしまうことです。<code>HH:mm:ss,SSS</code>というパターン文字列は<code>HM:mm:ss</code>というパターン文字列<code>SSS</code>というタイムゾーンが指定されたものとして解釈されてしまいます。日時パターン文字列にカンマ(,)を入れたければ、パターン文字列をクォートで囲んでください。たとえば次のようにします。%date{<b>"</b>HH:mm:ss,SSS<b>"</b>}.
- </p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="file">
- <b>F</b><br /><b>
-file</b>
- </td>
-
- <td>
- <p>ロギング要求を発行したクラスのソースコードファイル名を出力します。
- </p>
-
- <p>ファイル情報を生成するのはとても高速であるとは言えません。実行速度が問題にならない場合にだけ使うほうが良いでしょう。
- </p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="caller">
- <b>caller{depth}</b><br />
-<b>caller{depth, evaluator-1, ... evaluator-n}</b>
- </td>
-
- <td>
- <p>ロギングイベントを生成した呼び出し元の位置情報(スタックの深さ、ソースコードファイルの行番号)。
- </p>
-
- <p>位置情報の中身はJVM実装によって変わりますが、普通ならロギングイベントを生成したメソッドの定義されたクラスの完全名、ソースコードファイル名、行番号が含まれます。
- </p>
-
- <p>表示されるメソッド呼び出しの深さを指定するため、オプションとして整数値を指定できます。
- </p>
-
- <p>例えば、<b>%caller{2}</b>と書いたら次のように出力されます。</p>
-
-<pre class="source white_bg">0 [main] DEBUG - logging statement
-Caller+0 at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22)
-Caller+1 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)</pre>
-
- <p>そして<b>%caller{3}</b>と書いたら次のように出力されます。</p>
-
-<pre class="source white_bg">16 [main] DEBUG - logging statement
-Caller+0 at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22)
-Caller+1 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)
-Caller+2 at mainPackage.ConfigTester.main(ConfigTester.java:38)</pre>
-
- <p>ロギングイベントの送信元情報を計算するかどうかを判定するため、オプションとして評価器を指定できるようになっています。たとえば、<b>%caller{3,CALLER_DISPLAY_EVAL}</b>と指定すると評価器の<em>CALLER_DISPLAY_EVAL</em>が<b>真</b>を返す場合にだけ、3行分のスタックトレースを出力することになります。
- </p>
-
- <p>評価器の種類は後で紹介します。</p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="line">
- <b>L</b><br /><b>
-line</b>
- </td>
-
- <td><p>ロギング要求が生成されたソースコードファイル中の行番号を出力します。</p>
-
- <p>行番号を算出するのは決して高速とは言えません。実行速度が問題にならない場合にだけ使うほうが良いでしょう。
-
- </p>
- </td>
- </tr>
-
-
- <tr>
- <td class="word" name="message">
- <b>m</b><br /><b>
-msg</b><br /><b>
-message</b>
- </td>
- <td>
- <p>アプリケーションがロギングイベントに関連付けたメッセージを出力します。
- </p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="method">
- <b>M</b><br /><b>
-method</b>
- </td>
-
- <td>
- <p>ロギング要求が生成されたメソッド名を出力します。</p>
- <p>メソッド名を生成するのは決して高速とは言えません。実行速度が問題にならない場合にだけ使うほうが良いでしょう。
-</p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="newline">
- <b>n</b>
- </td>
-
- <td>
- <p>プラットフォーム依存の行区切り文字を出力します。</p>
- <p>この変換指定子を使っても、行区切り文字として可搬性の無い"\n" や"\r\n" を指定した場合と性能は変わりません。したがって、どんなときでも行区切り文字そのものではなく、この変換指定子を使うべきです。
- </p>
- </td>
-
- </tr>
-
- <tr>
- <td class="word" name="level">
- <b>p</b><br /><b>
-le</b><br /><b>
-level</b>
- </td>
- <td>ロギングイベントのレベルを出力します。</td>
- </tr>
-
- <tr>
-
- <td class="word" name="relative">
- <b>r</b><br /><b>
-relative</b>
- </td>
-
- <td>アプリケーションが開始してから、ロギングイベントを生成するまでの経過時間をミリ秒単位で出力します。
- </td>
- </tr>
-
-
- <tr>
- <td class="word" name="relative">
- <b>t</b><br /><b>
-thread</b>
- </td>
-
- <td>ロギングイベントを生成したスレッドの名前を出力します。
- </td>
-
- </tr>
-
- <tr>
- <td class="word" name="mdc">
- <b>X</b>{<em>key:-defaultVal</em>} <br>
- <b>mdc</b>{<em>key:-defaultVal</em>} <br>
- </td>
-
- <td>
-
- <p>ロギングイベントを生成したスレッドに関連付けられていたMDC(診断コンテキスト)の値を出力します。
- </p>
-
- <p><b>%mdc{uesrid}</b>のように<b>mdc</b>オプションにキーが指定されている場合、対応するMDCの値が出力されます。MDCの値がnullの場合、 <b>:-</b>演算子で指定したデフォルト値が出力されます。デフォルト値が無かったら空文字列が出力されます。
- </p>
-
- <p>キーが未指定のときは、MDCの内容がすべて出力されます。そのときの書式は"key1=val1,key2=val2"のようになります。
- </p>
-
- <p>詳しくは<a href="http://logback.qos.ch/manual/mdc.html">MDCの章</a>を参照してください。</p>
-
- </td>
- </tr>
- <tr>
- <td class="word" name="ex">
- <b>ex</b>{<em>depth</em>} <br>
- <b>exception</b>{<em>depth</em>} <br>
- <b>throwable</b>{<em>depth</em>} <br>
- <br>
- <b>ex</b>{depth, evaluator-1, ..., evaluator-n} <br>
- <b>exception</b>{depth, evaluator-1, ..., evaluator-n} <br>
- <b>throwable</b>{depth, evaluator-1, ..., evaluator-n}
- </td>
-
- <td>
- <p>ロギングイベントに例外オブジェクトが関連付けられていたら、その例外オブジェクトのスタックトレースを出力します。デフォルトでは完全なスタックトレースを出力します。
- </p>
-
- <p><em></em>throwable変換指定子に指定できるオプションは次のとおりです。</p>
- <ul>
- <li><em>short</em> :スタックトレースの一行目だけを出力します</li>
- <li><em>full</em> :完全なスタックトレースを出力します</li>
- <li>任意の整数:スタックトレースの先頭から数えて指定した行数を出力します</li>
- </ul>
-
- <p>いくつか例を見てみましょう。</p>
-
- <table class="bodyTable">
- <tr class="a">
- <th>変換指定</th>
- <th>結果</th>
- </tr>
- <tr class="b">
- <td>%ex</td>
- <td><pre>mainPackage.foo.bar.TestException: Houston we have a problem
- at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)
- at mainPackage.foo.bar.TestThrower.readyToLaunch(TestThrower.java:17)
- at mainPackage.ExceptionLauncher.main(ExceptionLauncher.java:38)</pre></td>
- </tr>
- <tr class="a">
- <td>%ex{short}</td>
- <td><pre>mainPackage.foo.bar.TestException: Houston we have a problem
- at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)</pre></td>
- </tr>
- <tr class="b">
- <td>%ex{full}</td>
- <td><pre>mainPackage.foo.bar.TestException: Houston we have a problem
- at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)
- at mainPackage.foo.bar.TestThrower.readyToLaunch(TestThrower.java:17)
- at mainPackage.ExceptionLauncher.main(ExceptionLauncher.java:38)</pre></td>
- </tr>
- <tr class="a">
- <td>%ex{2}</td>
- <td><pre>mainPackage.foo.bar.TestException: Houston we have a problem
- at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)
- at mainPackage.foo.bar.TestThrower.readyToLaunch(TestThrower.java:17)</pre></td>
- </tr>
- </table>
-
- <p>スタックトレースを出力するかどうかを判定するため、オプションとして評価器を指定できるようになっています。例えば、<b>%ex{full,EX_DISPLAY_EVAL}</b>と指定した場合、評価器<em>EX_DISPLAY_EVAL</em>が<b>偽</b>を返すときだけ例外オブジェクトの完全なスタックトレースが出力されます。評価器についてはこのドキュメントの後のほうで説明しています。
- </p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="xThrowable">
- <b>xEx</b>{<em>depth</em>} <br>
- <b>xException</b>{<em>depth</em>} <br>
- <b>xThrowable</b>{<em>depth</em>} <br>
- <br>
- <b>xEx</b>{depth, evaluator-1, ..., evaluator-n} <br>
- <b>xException</b>{depth, evaluator-1, ..., evaluator-n} <br>
- <b>xThrowable</b>{depth, evaluator-1, ..., evaluator-n}
- </td>
-
- <td>
- <p>クラスのパッケージングに関する情報が追加されていること以外は%throwableと同様です。</p>
-
- <p>変換パターン文字列に%xThrowableや他のthrowable関連の変換指定子を指定しなかった場合、<code>PatternLayout</code>は末尾に%xThrowableを自動的に追加します。スタックトレースの情報は非常に重要だからです。スタックトレースを出力したくなければ、%xThrowableの代わりに%nopexを指定すればよいです。%nopexの説明も参照してください。
- </p>
-
- <p>例外のスタックトレースの各行の終わりに、そのクラスが含まれるjarファイル名とMANIFEST.MFに書かれた"Implementation-Version"が追加されます。この画期的なテクニックを考案したのは<a href="http://macstrac.blogspot.com/2008/09/better-stack-traces-in-java-with-log4j.html">James Strachan</a>です。パッケージングの情報が不確かな場合、先頭にチルダ(~)が付きます。
- </p>
-
- <p>例を見てみましょう。</p>
-
- <p class="source small">java.lang.NullPointerException
- at com.xyz.Wombat(Wombat.java:57) <b><span class="red">~</span>[wombat-1.3.jar:1.3]</b>
- at com.xyz.Wombat(Wombat.java:76) ~[wombat-1.3.jar:1.3]
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.5.0_06]
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.5.0_06]
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.5.0_06]
- at java.lang.reflect.Method.invoke(Method.java:585) ~[na:1.5.0_06]
- at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59) [junit-4.4.jar:na]
- at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98) [junit-4.4.jar:na]
- ...etc </p>
-
- <p>logbackはパッケージング情報が正しく出力されるよう、適切な幅を確保します。どれだけクラスローダーの階層が複雑になっていても頑張ります。残念ながら正確性が担保できないときは先頭にチルダ(~)を付けます。従って、理屈の上では実際のパッケージング情報とは異なる内容を出力させることも可能です。ですから、前の例で Wombat クラスのパッケージング情報の先頭にはチルダ(~)があるので、本当は [wombat.jar:1.7] となるはずだったかもしれないのです。
- </p>
-
- <p><a href="http://jira.qos.ch/browse/LBCLASSIC-212">利用者からのフィードバックによると</a>、NetBeansはパッケージング情報を縮めてしまうそうです。Netbeansのユーザーは、変換パターン文字列の最後に"%ex"を追加して、スタックトレースにパッケージング情報が出てこないようにしたほうが良いでしょう。たとえば、"%d %logger - %m%n" という変換パターン文字列を使っているなら、"%d %logger - %m%n<b>%ex</b>" と書き換えればよいのです。</p>
- </td>
-
- </tr>
-
- <tr>
- <td class="word" name="nopex">
- <b>nopex</b> <br>
- <b>nopexception</b>
- </td>
-
- <td>
- <p>スタックトレースの情報を<em>扱うように見えます</em>が、実際は何も出力しません。つまり、うまく例外を無視できるのです。
- </p>
-
- <p>%nopex変換指定子を使うと、<code>PatternLayout</code>が内部的に実装している安全弁を無かったことにします。安全弁とは、変換パターン文字列に例外を扱う変換指定子が含まれていなかったらこっそり最後に%xThrowableを追加することです。
- </p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="marker">
- <b>marker</b>
- </td>
-
- <td>
- <p>ロギング要求に関連付けられたマーカーを出力します。</p>
-
- <p>マーカーに子マーカーがある場合、次のような書式で両方のマーカーを出力します。
- </p>
- <p>
- <em>parentName [ child1, child2 ]</em>
- </p>
- </td>
- </tr>
-
-
- <tr>
- <td class="word" name="property">
- <b>property{key}</b>
- </td>
-
- <td><p><em>キー</em>という名前のプロパティに設定された値を出力します。関連するドキュメントは<a href="http://logback.qos.ch/manual/configuration.html#variableSubstitution">変数の定義</a>と<a href="http://logback.qos.ch/manual/configuration.html#scopes">変数のスコープ</a>です。
-
- <em>キー</em>がロガーコンテキストのプロパティではなかったら、システムプロパティを探します。</p>
-
-
- <p><em>キー</em>に対するデフォルト値はありません。プロパティが見つからなかったら、"Property_HAS_NO_KEY"という文字列が値になります。エラーであることがすぐにわかりますね。</p>
-
- </td>
- </tr>
-
- <tr>
- <td class="word" name="replace">
- <b>replace(<em>p</em>){r, t}</b>
- </td>
-
- <td>
- <p>変換パターン文字列"p"について、正規表現'r'にマッチした部分を文字列't'で置き換えます。たとえば、"%replace(%msg){'\s',''}" とすると、ロギングイベントに設定されたメッセージに含まれるすべての空白文字を削除します。
- </p>
-
- <p>変換パターン文字列"p"はどれだけ複雑になってもいいですし、複数の変換指定を含めることもできます。たとえば、"%replace(%logger %msg)'\.','/'}" とすると、ロガー名とメッセージに含まれる全てのドット(.)をスラッシュ(/)で置き換えます。
- </p>
-
- </td>
- </tr>
-
-
- <tr>
- <td class="word" name="rootException">
- <b>rEx</b>{<em>depth</em>} <br>
- <b>rootException</b>{<em>depth</em>} <br>
- <br>
- <b>rEx</b>{depth, evaluator-1, ..., evaluator-n} <br>
- <b>rootException</b>{depth, evaluator-1, ..., evaluator-n}
- </td>
-
- <td>
- <p>ロギングイベントに例外オブジェクトが関連付けられていたら、その例外オブジェクトのスタックトレースを出力します。
-標準とは逆に、例外の発生元から順番にスタックトレースを出力します。こんな出力になります(サンプルなのでだいぶ削っています)。</p>
-
- <pre class="small">java.lang.NullPointerException
- at com.xyz.Wombat(Wombat.java:57) ~[wombat-1.3.jar:1.3]
- at com.xyz.Wombat(Wombat.java:76) ~[wombat-1.3.jar:1.3]
-Wrapped by: org.springframework.BeanCreationException: Error creating bean with name 'wombat':
- at org.springframework.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248) [spring-2.0.jar:2.0]
- at org.springframework.AbstractBeanFactory.getBean(AbstractBeanFactory.java:170) [spring-2.0.jar:2.0]
- at org.apache.catalina.StandardContext.listenerStart(StandardContext.java:3934) [tomcat-6.0.26.jar:6.0.26]
-</pre>
-
- <p>%rootExceptionには、%xExceptionと同じオプションを指定できます。それに、パッケージング情報も出力します。簡単に言うと、%rootException は %xException とほとんど変わりませんが、スタックトレースの出力順だけが逆になっているのです。
- </p>
-
- <p>%のrootExceptionの作者であるTomasz Nurkiewiczは、自身のブログエントリ<a href="http://nurkiewicz.blogspot.com/2011/09/logging-exceptions-root-cause-first.html">"Logging eceptions root cause first"</a>で解説しています。</p>
- </td>
- </tr>
-
- </table>
-
-
- <h4 class="doAnchor" name="percentIsSpecial">%文字の特別な意味</h4>
-
- <p>変換パターン文字列というコンテキストにおいて、%文字には特別な意味があります。文字列リテラルとして使用するにはバックスラッシュ(\)を前につけてエスケープしなければなりません。たとえば "%d %p \%%m%n" といったようにします。
- </p>
-
- <h4 class="doAnchor" name="restrictionsOnLiterals">変換指定子の直後の文字列リテラルの制限</h4>
-
- <p>ほとんどの場合文字列リテラルにはスペースや他の区切り文字が含まれるので、変換指定子と混同されることはありません。例えば、変換パターン文字列"%level [%thread] - %mmessage%n" には文字列リテラル <code>" ["</code>と<code>"] - "</code>が含まれています。しかし、Javaの識別子に使える文字リテラルが変換指定子の直後に現れると、logbackの文字列パターン解析器はその文字リテラルも変換指定子の一部だと勘違いしてしまいます。例えば、変換パターン文字列 "%date<b>%nHello</b>" は、%date と %nHello という二つの変換指定子として解釈されてしまいます。もちろん、%nHello は変換指定子に存在しないため、logback は %PARSER_ERROR[nHello] というエラーを出力するでしょう。%nのすぐ後に文字列リテラル "Hello" を出したければ、%nに空の引数リストを指定すればよいでしょう。たとえば、"%date<b>%n{}</b>Hello" とすれ [...]
-
- </p>
-
- <h2 class="doAnchor" name="formatModifiers">書式修飾子</h2>
-
- <p>デフォルトでは、関連する情報はそのまま出力されます。しかし、書式修飾子を使えばそれぞれのデータを出力する幅の最小値と最大値、それに文字揃えを変えることが出来ます。
- </p>
-
- <p>書式修飾子のオプションは%記号と修飾文字の間に入れます。
- </p>
-
- <p>最初に紹介する書式修飾子のオプションは<em>左揃え</em>です。これはただのマイナス(-)を指定します。次は<em>最小幅</em>です。整数値で出力する文字数を指定します。出力する文字列長が指定した文字数より小さい時は、最小幅を全てうめるまで右側か左側のどちらかをパディングします。デフォルトは右揃えなので左側にパディングしますが、左揃えにして右側にパディングさせることもできます。パディング文字は半角スペースです。出力する文字列長が指定した文字数より大きい時は、全て出力できるように幅を広げます。後ろを切り捨てることはありません。
- </p>
-
- <p>この振る舞いは最大幅を指定すれば変えられます。<em>最大幅</em>はドット(.)の後に整数値で指定します。出力する文字列長が指定した文字数より大きい時は、溢れた分だけ出力する文字列の<em>先頭</em>から削除されます。たとえば、最大幅を8にしたとき、出力する文字列長が10だったら、先頭の2文字が削除されることになります。C言語のprintf関数なら文字列の後ろのほうが削除されるので、逆の振る舞いをすることになります。
- </p>
-
- <p>ドット(.)に続けてマイナス文字(-)を指定すれば、後ろから削除することもできます。その場合、最大幅が8として、出力する文字列長が10だったら、末尾の2文字が削除されることになります。
- </p>
-
- <p>書式修飾子の例をいくつか見ていきましょう。
- </p>
-
- <table class="bodyTable" border="0" cellpadding="8">
- <tr>
- <th>書式修飾子</th>
- <th>左寄せ</th>
- <th>最小幅</th>
- <th>最大幅</th>
- <th>コメント</th>
- </tr>
- <tr class="a">
- <td align="center">%20logger</td>
- <td align="center">しない</td>
- <td align="center">20</td>
- <td align="center">なし</td>
- <td>ロガー名が20文字未満であれば半角スペースで左側にパディングします。
- </td>
- </tr>
- <tr class="b">
- <td align="center">%-20logger</td>
- <td align="center">する</td>
- <td align="center">20</td>
- <td align="center">なし</td>
- <td>ロガー名が20文字未満であれば半角スペースで右側にパディングします。
- </td>
- </tr>
- <tr class="a">
- <td align="center">%.30logger</td>
- <td align="center">指定できない</td>
- <td align="center">なし</td>
- <td align="center">30</td>
- <td>ロガー名が30文字を超える場合、先頭から切り捨てます。
- </td>
- </tr>
- <tr class="b">
- <td align="center">%20.30logger</td>
- <td align="center">しない</td>
- <td align="center">20</td>
- <td align="center">30</td>
- <td>ロガー名が20文字未満であれば半角スペースで左側にパディングします。ロガー名が30文字を超える場合、先頭から切り捨てます。
- </td>
- </tr>
- <tr class="a">
- <td align="center">%-20.30logger</td>
- <td align="center">する</td>
- <td align="center">20</td>
- <td align="center">30</td>
- <td>ロガー名が20文字未満であれば半角スペースで右側にパディングします。ロガー名が30文字を超える場合、<em>先頭</em>から切り捨てます。
- </td>
- </tr>
- <tr class="b">
- <td align="center">%.-30logger</td>
- <td align="center">指定できない</td>
- <td align="center">なし</td>
- <td align="center">30</td>
- <td>ロガー名が30文字を超える場合、<em>末尾</em>から切り捨てます。
- </td>
- </tr>
- </table>
-
- <p>書式修飾子による文字列の切り捨ての例を表にまとめました。角括弧"[]"は出力される文字列ではなく、出力幅を示しているだけなので注意してください。</p>
-
-
- <table class="bodyTable" border="0" cellpadding="8">
- <tr>
- <th>書式修飾子</th>
- <th>ロガー名</th>
- <th>結果</th>
- </tr>
- <tr class="b">
- <td align="center">[%20.20logger]</td>
- <td align="center">main.Name</td>
- <td align="center"><pre>[ main.Name]</pre></td>
- </tr>
- <tr class="a">
- <td align="center">[%-20.20logger]</td>
- <td align="center">main.Name</td>
- <td align="center"><pre>[main.Name ]</pre></td>
- </tr>
- <tr class="a">
- <td align="center">[%10.10logger]</td>
- <td align="center">main.foo.foo.bar.Name</td>
- <td align="center"><pre>[o.bar.Name]</pre></td>
- </tr>
- <tr class="b">
- <td align="center">[%10.-10logger]</td>
- <td align="center">main.foo.foo.bar.Name</td>
- <td align="center"><pre>[main.foo.f]</pre></td>
- </tr>
- </table>
-
- <h3 class="doAnchor" name="oneLetterLevel">レベルを1文字で出力する</h3>
-
- <p>ロギングレベルをTRACE、DEBUG、WARN、INFO、ERRORのような文字列として出力するのではなく、T、D、W、I、Eのように一文字だけ出力したい場合もあるでしょう。<a href="http://logback.qos.ch/manual/layouts.html#customConversionSpecifier">カスタムコンバーター</a>を実装してもできるでしょうし、書式修飾子を使うこともできます。書式修飾子を使うなら<code>"%.-1level"</code>とすればよいでしょう。
- </p>
-
- <h2 class="doAnchor" name="cwOptions">変換指定子のオプション</h2>
-
- <p>変換指定子にはオプションを指定することができます。オプションは必ず中括弧で囲むようにします。オプションで何ができるのか、すでに目にしてきたものがあります。たとえば、<em>%mdc{someKey}</em>のようにMDC変換指定子と組み合わせることができます。
- </p>
-
- <p>変換指定子のオプションは複数になるかもしれません。たとえば、評価器を使う変換指定子があります。すぐ後で説明しますが、こんな風に評価器の名前を複数並べることがあるかもしれません。</p>
-
- <pre class="prettyprint source"><pattern>%-4relative [%thread] %-5level - %msg%n \
- <b>%caller{2, DISP_CALLER_EVAL, OTHER_EVAL_NAME, THIRD_EVAL_NAME}</b></pattern></pre>
-
- <p>指定するオプションに括弧、スペース、カンマなどの特別な文字が含まれるときは、シングルクォートやダブルクォートで囲みます。たとえば、次のような変換パターン文字列になります。</p>
-
- <pre class="prettyprint source"><pattern>%-5level - %replace(%msg)<b>{'\d{14,16}', 'XXXX'}</b>%n</pattern></pre>
-
-
- <p>この例では、<code>replace</code>変換指定子にオプションとして<code>\d{14,16}</code>と<code>XXXX</code>を指定しています。これは、メッセージ中に14桁から16桁の数字文字列があったらそれをXXXXで置き換えるものです。クレジットカード番号をマスクするのに役立ちます。"\d"は一桁の数字を表す正規表現の省略形です。後ろに"{14,16}"をつけているので、一つ前の文字、つまり一桁の数字が14個から16個繰り返される場合にマッチすることになります。
- </p>
-
- <h2 class="doAnchor" name="Parentheses">括弧は特別扱い</h2>
-
- <p>logbackでは、パターン文字列の中の括弧は、トークンをグループ化するものとして扱います。それぞれのグループはそれ自体を1つのパターン文字列として扱うことができます。logback0.9.27から、<a href="http://logback.qos.ch/manual/layouts.html#replace">%replace</a>のような変換指定子を組み合わせて部分パターン文字列を作れるようになりました。
- </p>
-
- <p>こんなパターン文字列があるとします。</p>
-
- <p class="source"><b>%-30(</b>%d{HH:mm:ss.SSS} [%thread]<b>)</b> %-5level %logger{32} - %msg%n</p>
-
- <p>これは、部分パターン文字列"%d{HH:mm:ss.SSS} [%thread]" によって生成された出力をグループ化します。つまり、この部分パターン文字列によって生成された出力が30文字未満の文字列だった場合、右側にパディングされるのです。
- </p>
-
- <p>グループ化しなかった場合はこういう出力になります。</p>
-
- <p class="source">13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Classload hashcode is 13995234
-13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Initializing for ServletContext
-13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Trying platform Mbean server
-13:09:30 [pool-1-thread-1] INFO ch.qos.logback.demo.LoggingTask - Howdydy-diddly-ho - 0
-13:09:38 [btpool0-7] INFO c.q.l.demo.lottery.LotteryAction - Number: 50 was tried.
-13:09:40 [btpool0-7] INFO c.q.l.d.prime.NumberCruncherImpl - Beginning to factor.
-13:09:40 [btpool0-7] DEBUG c.q.l.d.prime.NumberCruncherImpl - Trying 2 as a factor.
-13:09:40 [btpool0-7] INFO c.q.l.d.prime.NumberCruncherImpl - Found factor 2
- </p>
-
- <p>"%-30()" でグループ化するとこうなります。</p>
-
- <p class="source">13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Classload hashcode is 13995234
-13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Initializing for ServletContext
-13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Trying platform Mbean server
-13:09:30 [pool-1-thread-1] INFO ch.qos.logback.demo.LoggingTask - Howdydy-diddly-ho - 0
-13:09:38 [btpool0-7] INFO c.q.l.demo.lottery.LotteryAction - Number: 50 was tried.
-13:09:40 [btpool0-7] INFO c.q.l.d.prime.NumberCruncherImpl - Beginning to factor.
-13:09:40 [btpool0-7] DEBUG c.q.l.d.prime.NumberCruncherImpl - Trying 2 as a factor.
-13:09:40 [btpool0-7] INFO c.q.l.d.prime.NumberCruncherImpl - Found factor 2
- </p>
-
-
- <p>後者のほうが読みやすいんじゃないでしょうか。</p>
-
- <p>括弧を文字列リテラルとして扱いたいときは、バックスラッシュ(\)でエスケープしなければなりません。こんな感じです。
-"<b>\(</b>%d{HH:mm:ss.SSS} [%thread]<b>\)</b>"
- </p>
-
- <h2 class="doAnchor" name="coloring">カラー化</h2>
-
- <p><a href="http://logback.qos.ch/manual/layouts.html#Parentheses">括弧</a>でグループ化した部分パターン文字列には色を指定することができます。logback1.0.5から<code>PatternLayout</code>で指定できるようになった色付け用の変換指定子は次のとおりです。
- <ul>
- <li>"%black"</li>
- <li>"%red"</li>
- <li>"%green"</li>
- <li>"%yellow"</li>
- <li>"%blue"</li>
- <li>"%magenta"</li>
- <li>"%cyan"</li>
- <li>"%white"</li>
- <li>"%gray"</li>
- <li>"%boldRed"</li>
- <li>"%boldGreen"</li>
- <li>"%boldYellow"</li>
- <li>"%boldBlue"</li>
- <li>"%boldMagenta"</li>
- <li>"%boldCyan"</li>
- <li>"%boldWhite"</li>
- <li>"%highlight"</li>
- </ul>
- これらの変換指定子にはオプションとして部分パターン文字列を指定することが想定されています。そしてその部分パターン文字列から生成された出力には色が付きます。
- </p>
-
- <p>色付けをわかりやすく説明する設定ファイルを次に示します。%cyan変換指定子には部分パターン文字列として"%logger{15}"を指定してあるのがわかりますか。こうすると、ロガー名は15文字に短縮されるだけでなく、文字色がシアンになります。%highlight変換指定子を使うと、部分パターン文字列の文字色が、ログレベルがERRORなら赤太字、ログレベルがWARNなら赤字、ログレベルがINFOなら青字、それ以外のログレベルならデフォルトの色になります。</p>
-
- <p class="example">例:ログレベルに応じた強調表示(<a href="http://logback.qos.ch/xref/chapters/layouts/highlighed.xml">logback-examples/src/main/java/chapters/layouts/highlighed.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('highlighted');">Groovyとして表示</span>
-
-
-<pre id="highlighted" class="prettyprint"><configuration debug="true">
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <!-- On Windows machines setting withJansi to true enables ANSI
- color code interpretation by the Jansi library. This requires
- org.fusesource.jansi:jansi:1.8 on the class path. Note that
- Unix-based operating systems such as Linux and Mac OS X
- support ANSI color codes by default. -->
- <b><withJansi>true</withJansi></b>
- <encoder>
- <pattern>[%thread] <b>%highlight(%-5level)</b> <b>%cyan(%logger{15})</b> - %msg %n</pattern>
- </encoder>
- </appender>
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>この設定ファイルを使うと次のように出力されます。</p>
-
-<pre class="source">[main] <span style="color:#611">WARN</span> <span style="color:#2bd">c.l.TrivialMain</span> - a warning message 0
-[main] DEBUG <span style="color:#2bd">c.l.TrivialMain</span> - hello world number1
-[main] DEBUG <span style="color:#2bd">c.l.TrivialMain</span> - hello world number2
-[main] <span style="color:#00f">INFO</span> <span style="color:#2bd">c.l.TrivialMain</span> - hello world number3
-[main] DEBUG <span style="color:#2bd">c.l.TrivialMain</span> - hello world number4
-[main] <span style="color:#611">WARN</span> <span style="color:#2bd">c.l.TrivialMain</span> - a warning message 5
-[main] <span style="color:#f00">ERROR</span> <span style="color:#2bd">c.l.TrivialMain</span> - Finish off with fireworks</pre>
-
- <p>色付け用変換指定子を使うとパターン文字列が複数行になってしまうこともあります。<a href="http://logback.qos.ch/manual/layouts.html#customConversionSpecifier">変換指定を自作する</a>では設定ファイルで使用できる変換指定子を登録する手順について議論しています。</p>
-
- <h2 class="doAnchor" name="Evaluators">評価器</h2>
-
- <p>前述したように、オプションをリストで指定できると、変換指定子に<a href="http://logback.qos.ch/xref/ch/qos/logback/core/boolex/EventEvaluator.html">EventEvaluator</a>に基づく動的な振る舞いを複数指定できる必要があるときは便利です。
- <code>EventEvaluator</code>の役割は、ロギングイベントが基準に合致するかどうかを判定することです。
- </p>
-
- <p>早速<code>EventEvaluator</code>の例を見てみましょう。次の設定ファイルは、ロギングイベントの日付、スレッド、レベル、メッセージと送信者情報をコンソールに出力するものです。ロギングイベントの送信者情報を抽出するのはとてもコストが高いので、特定のロガーが生成したロギング要求の場合だけに限定しています。さらに、メッセージに特定の文字列が含まれている場合だけにしています。ですので、特定のロギングイベントについてだけ、送信者情報の生成と出力を行うことになります。そうすれば、送信者情報のいらないケースではアプリケーションの性能ペナルティが発生しません。
- </p>
-
- <p>評価器と<em>具体的な評価式</em>については、<a href="http://logback.qos.ch/manual/filters.html#evalutatorFilter">フィルタの章の独立したセクション</a>で紹介しています。もし評価器を実戦投入しようとしているなら必ず読んでおいてください。この後で紹介する例では、明示的に書いていませんが<code>JaninoEventEvaluator</code>を使用しています。ですので実行するには<a href="http://docs.codehaus.org/display/JANINO/Home">Jainoライブラリ</a>が必要になります。設定方法をまとめたドキュメントの<a href="http://logback.qos.ch/setup.html#janino">該当するセクション</a>を読んでください。</p>
-
- <p class="example">例:EventEvaluatorsの使用例(<a href="http://logback.qos.ch/xref/chapters/callerEvaluatorConfig.xml">logback-examples/src/main/java/chapters/callerEvaluatorConfig.xml</a>)</p>
-<span class="asGroovy" onclick="return asGroovy('callerEvaluatorConfig');">Groovyとして表示</span>
-
-
- <pre id="callerEvaluatorConfig" class="prettyprint source"><configuration>
- <b><evaluator name="DISP_CALLER_EVAL">
- <expression>logger.contains("chapters.layouts") && \
- message.contains("who calls thee")</expression>
- </evaluator></b>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>
- %-4relative [%thread] %-5level - %msg%n<b>%caller{2, DISP_CALLER_EVAL}</b>
- </pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>この設定ファイル中の評価式は、ロガー名に"chapters.layouts" が含まれており、かつ、メッセージに"who clals thee" が含まれているロギングイベントにマッチするものです。XMLのエンコーディングルールに従うため、&文字は&のようにエスケープしなければなりません。</p>
-
- <p>この設定ファイルを使用するクラスを見てみましょう。</p>
-
- <p class="example">例:EventEvaluatorsの使用例(<a href="http://logback.qos.ch/xref/chapters/CallerEvaluatorExample.html">logback-examples/src/main/java/chapters/CallerEvaluatorExample.java</a>)</p>
- <pre class="prettyprint source">package <b>chapters.layouts</b>;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.core.joran.spi.JoranException;
-import ch.qos.logback.core.util.StatusPrinter;
-
-public class CallerEvaluatorExample {
-
- public static void main(String[] args) {
- Logger logger = LoggerFactory.getLogger(CallerEvaluatorExample.class);
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
-
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- // StatusPrinter will handle this
- }
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
-
- for (int i = 0; i < 5; i++) {
- if (i == 3) {
- logger.debug(<b>"who calls thee</b>?");
- } else {
- logger.debug("I know me " + i);
- }
- }
- }
-}</pre>
-
- <p>このアプリケーションは特別何もしません。forループでロギング要求を5回生成します。三回目だけ "who calls thee?" というメッセージを出力します。
- </p>
-
- <p>次のコマンドで実行します。</p>
-
- <p class="source">java chapters.layouts.CallerEvaluatorExample src/main/java/chapters/layouts/callerEvaluatorConfig.xml</p>
-
- <p>そうすると、コンソールに次のように出力されます。</p>
-
- <div class="source"><pre>0 [main] DEBUG - I know me 0
-0 [main] DEBUG - I know me 1
-0 [main] DEBUG - I know me 2
-0 [main] DEBUG - who calls thee?
-Caller+0 at chapters.layouts.CallerEvaluatorExample.main(CallerEvaluatorExample.java:28)
-0 [main] DEBUG - I know me 4</pre></div>
-
-
- <p>ロギング要求が生成されたら、そのロギングイベントが評価されます。三回目のロギングイベントだけが評価条件にマッチするので、送信者情報が出力されます。他のロギングイベントは評価基準とマッチしないので送信者情報が出力されていません。
- </p>
-
-
- <p>現実世界のシナリオに対応できるように評価式を変更することにしましょう。例えばロガー名とロギング要求のレベルを組み合わせることもできます。そうすれば、ロギング要求のレベルが<em>WARN</em>より高くて、かつ、アプリケーションの重要部品、例えばお金に絡むトランザクションを処理するモジュールで生成された場合にだけ送信者情報を出力する、といったことができるでしょう。
- </p>
-
- <p><b>重要:</b> <em>caller変換指定</em>によって送信者情報が出力されるのは、評価式が<b>true</b>と<em>評価された</em>ときだけです。</p>
-
- <p>別の状況を考えてみましょう。ロギング要求に例外オブジェクトが設定されていると、スタックトレースも出力されます。しかし、特定の例外オブジェクトのスタックトレースは出力したくないこともあります。
- </p>
-
- <p>次のコードでは、例外オブジェクトを指定したロギング要求を3つ生成しています。二つ目の例外オブジェクトは他のものと違ってメッセージに "do not display this" という文字列が含まれていますし、例外クラスが <code>chapters.layouts.TestException</code>になっています。このメッセージを指示とみなして、二つ目の例外オブジェクトのスタックトレースが出力されないようにしてみましょう。</p>
-
- <p class="example">例:ExceptionEventEvaluatorsの使用例(<a href="http://logback.qos.ch/xref/chapters/ExceptionEvaluatorExample.html">logback-examples/src/main/java/chapters/ExceptionEvaluatorExample.java</a>)</p>
-<pre class="prettyprint source">package chapters.layouts;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.core.joran.spi.JoranException;
-import ch.qos.logback.core.util.StatusPrinter;
-
-public class ExceptionEvaluatorExample {
-
- public static void main(String[] args) {
- Logger logger = LoggerFactory.getLogger(ExceptionEvaluatorExample.class);
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
-
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- lc.reset();
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- // StatusPrinter will handle this
- }
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
-
- for (int i = 0; i < 3; i++) {
- if (i == 1) {
- logger.debug("logging statement " + i, new TestException(
- "do not display this"));
- } else {
- logger.debug("logging statement " + i, new Exception("display"));
- }
- }
- }
-}</pre>
-
- <p>次の設定ファイルで指定した評価式は、<code>chapters.layouts.TextException</code>の例外オブジェクトが設定されたロギングイベントにマッチします。この例外型はスタックトレースの出力を抑止したい型そのものです。
- </p>
-
- <p class="example">例:ExceptionEventEvaluatorsの使用例(<a href="http://logback.qos.ch/xref/chapters/exceptionEvaluatorConfig.xml">logback-examples/src/main/java/chapters/exceptionEvaluatorConfig.xml</a>)</p>
- <pre class="prettyprint source"><configuration>
-
- <b><evaluator name="DISPLAY_EX_EVAL">
- <expression>throwable != null && throwable instanceof \
- chapters.layouts.TestException</expression>
- </evaluator></b>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%msg%n<b>%ex{full, DISPLAY_EX_EVAL}</b></pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>この設定は、<em>chapters.layouts.TestException</em>のインスタンスが設定されたロギング要求については、常にスタックトレースの出力を抑止します。
- </p>
-
- <p>実行してみましょう。</p>
-
- <p class="source">java chapters.layouts.ExceptionEvaluatorExample src/main/java/chapters/layouts/exceptionEvaluatorConfig.xml</p>
-
- <p>そうすると、次のような出力になります。</p>
-
-<p class="source">logging statement 0
-java.lang.Exception: display
- at chapters.layouts.ExceptionEvaluatorExample.main(ExceptionEvaluatorExample.java:43) [logback-examples-0.9.19.jar:na]
-logging statement 1
-logging statement 2
-java.lang.Exception: display
- at chapters.layouts.ExceptionEvaluatorExample.main(ExceptionEvaluatorExample.java:43) [logback-examples-0.9.19.jar:na]</p>
-
-
- <p>二つ目のロギング要求による出力にはスタックトレースが含まれていないことがわかりますか。うまく<code>TestException</code>のスタックトレースを出力しないようにできました。スタックトレースの各行の最後にある角括弧で囲まれた部分は<a href="http://logback.qos.ch/manual/layouts.html#xThrowable">パッケージング情報</a>です。</p>
-
- <p><b><em>%ex</em></b>変換指定があるので、<em>評価式</em>の結果が<b>false</b>になったときだけスタックトレースが出力されるようになっています。</p>
-
-
-
- <h2 class="doAnchor" name="customConversionSpecifier">変換指定子を自作する</h2>
-
- <p>ここまでに、<code>PatternLayout</code>に組み込みの変換指定子を見てきました。ですが、変換指定子を自作することもできるのです。</p>
-
- <p>カスタム変換指定子を作るには2つの手順を踏みます。
- </p>
-
- <h4>ステップ1</h4>
-
- <p>まず、<code>ClassicConverter</code>を継承したクラスを作ります。<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/pattern/ClassicConverter.html">ClassicConverter</a></code>の役割は、<code>ILoggingEvent</code>から情報を抽出して出力する文字列を生成することです。たとえば、 %logger変換指定子を実装した<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/pattern/LoggerConverter.html">LoggerConverter</a></code>は、<code>ILoggingEvent</code>から抽出したロガーの名前を文字列として返します。ロガー名の省略はこの手順で行います。</p>
-
- <p>アプリケーションが起動してからの経過時間をナノ秒単位で返すカスタム変換指定子の実装を見てみましょう。</p>
-
- <p class="example">例:自作コンバーターの例(<a href="http://logback.qos.ch/xref/chapters/MySampleConverter.html">logback-examples/src/main/java/chapters/MySampleConverter.java</a>)</p>
-<pre class="prettyprint source">public class MySampleConverter extends ClassicConverter {
-
- long start = System.nanoTime();
-
- <b>@Override</b>
- <b>public String convert(ILoggingEvent event) {</b>
- <b>long nowInNanos = System.nanoTime();</b>
- <b>return Long.toString(nowInNanos-start);</b>
- <b>}</b>
-}</pre>
-
- <p>この実装は非常に簡単です。<code>MySampleConverter</code>クラスは<code>ClassicConverter</code>を継承しており、<code>convert(ILoggingEvent)</code>メソッドはアプリケーションが起動してからの経過時間をナノ秒単位で計算して、それを文字列化しているだけです。
- </p>
-
- <h4>ステップ2</h4>
-
- <p>logback に自作した<code>Converter</code>のことを教えなければいけません。そのためには、設定ファイルで新しい変換指定子を宣言する必要があります。</p>
-
- <p class="example">例:自作コンバーターの設定例(<a href="http://logback.qos.ch/xref/chapters/mySampleConverterConfig.xml">logback-examples/src/main/java/chapters/mySampleConverterConfig.xml</a>)</p>
-<span class="asGroovy" onclick="return asGroovy('mySampleConverterConfig');">Groovyとして表示</span>
-<pre id="mySampleConverterConfig" class="prettyprint source"><configuration>
-
- <b><conversionRule conversionWord="nanos"
- converterClass="chapters.layouts.MySampleConverter" /></b>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern><b>%-6nanos</b> [%thread] - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>設定ファイルで宣言した新しい変換指定子は、<code>PatternLayout</code>に指定する変換パターン文字列の中で他の変換指定と同じように使うことが出来ます。</p>
-
- <p>実行してみましょう。</p>
-
- <div class="source">java chapters.layouts.SampleLogging src/main/java/chapters/layouts/mySampleConverterConfig.xml </div>
-
- <p>次のような出力になるはずです。</p>
-
- <pre class="source">4868695 [main] DEBUG - Everything's going well
-5758748 [main] ERROR - maybe not quite...</pre>
-
-
- <p>オプションの扱い方や、もっと複雑な振る舞いをさせるやり方を知りたければ、<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/pattern/MDCConverter.html"><code>MDCConverter</code></a>などの既存の<code>Converter</code>実装を見てみるとよいでしょう。独自の色付けをしたければ<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/pattern/color/HighlightingCompositeConverter.html"><code>HighlightingCompositeConverter</code></a>を参考にするとよいでしょう。
- </p>
-
-
-
- <h2 class="doAnchor" name="ClassicHTMLLayout">HTMLLayout</h2>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/html/HTMLLayout.html"><code>HTMLLayout</code></a>はHTML形式のログを出力します(logback-classicに含まれています)。<code>HTMLLayout</code>はHTMLのテーブルを出力します。それぞれの行がロギングイベントに対応しています。</p>
-
- <p>デフォルトのCSSを使った<code>HTMLLayout</code>の出力例を見てください。</p>
- <img src="images/chapters/layouts/htmlLayout0.gif" alt="HTMLレイアウトサンプル画像">
-
- <p>テーブルの列は変換パターン文字列で指定します。<a href="http://logback.qos.ch/manual/layouts.html#ClassicPatternLayout"><code>PatternLayout</code></a>のドキュメントに書かれた変換パターン文字列の説明を見てください。テーブルの形も内容も全て制御することができます。<code>PatternLayout</code>で使えるあらゆるコンバーターを使うことができます。
- </p>
-
- <p>自由に使えるとはいえ一つだけ例外的な制限があります。<code>PatternLayout</code>と<code>HTMLLayout</code>を使うときは、変換パターン文字列中で変換指定を半角スペースで区切ってはいけません。もっというと文字列リテラルを使わないようにしてください。変換パターン文字列中の変換指定はそれぞれがテーブルの列になるからです。同様に、変換指定を区切るつもりの文字列リテラルはそれぞれが列になってしまいます。下手をすると、横に超長いテーブルが出力されてしまうかもしれません。</p>
-
- <p><code>HTMLLayout</code>の使い方を説明する設定ファイルを見てください。
- </p>
-
- <p class="example">例:HTMLLayoutの設定例(<a href="http://logback.qos.ch/xref/chapters/htmlLayoutConfig1.xml">logback-examples/src/main/java/chapters/htmlLayoutConfig1.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('htmlLayoutConfig1');">Groovyとして表示</span>
-<pre id="htmlLayoutConfig1" class="prettyprint source"><configuration debug="true">
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
- <layout class="ch.qos.logback.classic.html.HTMLLayout">
- <b><pattern>%relative%thread%mdc%level%logger%msg</pattern></b>
- </layout>
- </encoder>
- <file>test.html</file>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration>
-</pre>
-
- <p><a href="http://logback.qos.ch/xref/chapters/layouts/TrivialMain.html">TrivialMain</a>アプリケーションは、いくつかログを出力してから最後に例外オブジェクトを指定したログを出力します。実行してみましょう。</p>
-
- <p class="source">java chapters.layouts.TrivialMain src/main/java/chapters/layouts/htmlLayoutConfig1.xml</p>
-
- <p>すると、カレントフォルダに<em>test.html</em>というファイルが作成されます。<em>test.html</em>をブラウザで見ると次のようになっているでしょう。</p>
- <img src="images/chapters/layouts/htmlLayout1.png" alt="HTMLレイアウトサンプル画像">
-
- <h3>スタックトレース</h3>
-
- <p>スタックトレースを出力するには<em>%ex変換指定</em>を指定します。そうすると専用の列が追加されます。ほとんどの場合スタックトレースの列は空なので、無駄に画面を専有することでしょう。さらに、スタックトレースを専用の列に出力したところで読みやすくはならないです。なお、スタックトレースを出力するには、<em>%ex変換指定</em>を指定する以外の方法があります。
- </p>
-
- <p>よりよい解決策は、自分で<code>IThrowableRenderer</code>インターフェイスを実装することです。実装したクラスは、例外オブジェクトに関係する情報を出力するため、<code>HTMLLayout</code>に割り当てることができます。デフォルトでは、<code>HTMLLayout</code>インスタンスに<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/html/DefaultThrowableRenderer.html">DefaultThrowableRenderer</a></code>が割り当てられています。これは例外オブジェクトのスタックトレースを<em>新しい行</em>に出力します。前の図を見るとわかりますが多少読みやすいです。
- </p>
-
- <p>それでも理由があって<em>%ex</em>を使いたいときは、設定ファイルに<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/html/NOPThrowableRenderer.html">NOPThrowableRenderer</a></code>を指定すればスタックトレースを別々の行に出力しないようにできます。あなたの望み通りに全てが上手くいくようなアイデアはありません。それでも、こうしたいという気持ちがあればきっと実現できます。
- </p>
-
- <h3>CSS</h3>
-
- <p><code>HTMLLayout</code>で生成したHTMLの見た目はCSSで調整することができます。特別な指定がなければ、<code>HTMLLayout</code>は組み込みのCSSを使います。しかし、外部のCSSを使うようにも指定できます。そのためには、<code>layout要素</code>に<code>cssBuilder要素</code>をネストさせればよいです。
- </p>
-
-<pre class="prettyprint source"><layout class="ch.qos.logback.classic.html.HTMLLayout">
- <pattern>%relative...%msg</pattern>
- <cssBuilder class="ch.qos.logback.classic.html.UrlCssBuilder">
- <!-- url where the css file is located -->
- <url>http://...</url>
- </cssBuilder>
-</layout></pre>
-
-
- <p><code>HTMLLayout</code>は<code>SMTPAppender</code>と組み合わせて使われることがあります。そうするとメールの内容がHTMLで綺麗に飾られたものになります。</p>
-
-
- <h2 class="doAnchor" name="log4jXMLLayout">Log4jのXMLLayout</h2>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/log4j/XMLLayout.html">XMLLayout</a> (logback-classicに含まれています)を使うとlog4j.dtdに準拠した書式で出力できるようになります。つまり、<a href="http://logging.apache.org/chainsaw/index.html">Chainsaw</a>や<a href="http://vigilog.sourceforge.net/">Vigilog</a>などの、<a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/XMLLayout.html">log4jのXML書式</a>を入力とするツールと相互運用できるのです。
- </p>
-
-
- <p>オリジナルのXMLLayoutはlog4j1.2.15で導入されたものです。logback-classic の XMLLayoutには<span class="option">locationInfo</span>と<span class="option">properties</span>という二つのプロパティが指定できます。<span class="option">locationInfo</span>プロパティにtrueを指定すると、ロギングイベントの位置情報(送信者情報)を含められるようになります。<span class="option">property</span>プロパティにtrueを指定すると、MDCの情報を含められるようになります。どちらのプロパティもデフォルトはfalseです。
- </p>
-
- <p>設定例を見てみましょう。</p>
-
- <p class="example">例:Log4jXMLLayoutの例(<a href="http://logback.qos.ch/xref/chapters/log4jXMLLayout.xml">logback-examples/src/main/java/chapters/log4jXMLLayout.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('log4jXMLLayout');">Groovyとして表示</span>
- <pre id="log4jXMLLayout" class="prettyprint source"><configuration>
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <file>test.xml</file>
- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
- <layout class="ch.qos.logback.classic.log4j.XMLLayout">
- <locationInfo>true</locationInfo>
- </layout>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration> </pre>
-
- <h1 class="doAnchor" name="logback-access">logback access モジュール</h1>
-
- <p>logback-access モジュールのほとんどのレイアウトは、logback-classic モジュールのレイアウトをそのまま移植しただけです。logback-classic モジュールと logback-access モジュールは用途が違うのですが、だいたい同じ機能を提供しています。</p>
-
- <h2>レイアウトを自作する</h2>
-
- <p>logback-access 用の<code>レイアウト</code>を自作するのは、logback-classic の<code>レイアウト</code>を自作するのとほとんど変わりありません。</p>
-
-
- <h3 class="doAnchor" name="AccessPatternLayout">PatternLayout</h3>
-
- <p>logback-access の<code><a href="http://logback.qos.ch/xref/ch/qos/logback/access/PatternLayout.html">PatternLayout</a></code>は、logback-classic とほとんど同じように設定することができます。ですが、HTTPリクエストやHTTPレスポンスにしか無い、ロギングに適した情報のための変換指定が追加されています。
- </p>
-
- <p>logback-accessの<code>PatternLayout</code>で使える変換指定を表にまとめました。</p>
-
- <table class="bodyTable striped" border="0" cellpadding="8">
- <tr>
- <th align="center">変換指定</th>
- <th align="center">効果</th>
- </tr>
- <tr>
- <td class="word" name="remoteIP">
- <b>a</b><br /><b>
-remoteIP</b>
- </td>
- <td>
- <p>リモートIPアドレス。</p>
- </td>
- </tr>
- <tr>
- <td class="word" name="localIP"><b>A</b><br /><b>
-localIP</b></td>
- <td>
- <p>ローカルIPアドレス。</p>
- </td>
- </tr>
- <tr>
- <td class="word" name="bytesSent"><b>b</b><br /><b>
-B</b><br /><b>
-bytesSent</b></td>
- <td>
- <p>レスポンスのコンテンツ長。
- </p>
- </td>
- </tr>
- <tr>
- <td class="word" name="clientHost"><b>h</b><br /><b>
-clientHost</b></td>
- <td>
- <p>リモートホスト名。
- </p>
- </td>
- </tr>
- <tr>
- <td class="word" name="protocol"><b>H</b><br /><b>
-protocol</b></td>
- <td>
- <p>リクエストプロトコル。</p>
- </td>
- </tr>
- <tr>
- <td class="word" name="remoteLogName"><b>l</b></td>
- <td>
- <p>リモートログ名。logback-accessではこのコンバーターの値は常に "-" です。
- </p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="reqParameter"><b>reqParameter{paramName}</b></td>
- <td>
- <p>リクエストパラメータ。</p>
- <p>この変換指定子は、オプションで指定されたリクエストパラメータを探します。</p>
- <p><b>%reqParameter{input_data}</b>とすると、リクエストパラメータのinput_dataの値を出力します。</p>
- </td>
- </tr>
- <tr>
- <td class="word" name="header"><b>i{header}</b><br /><b>
-header{header}</b></td>
- <td>
- <p>リクエストヘッダ。</p>
- <p>この変換指定子はオプションで指定されたリクエストヘッダを探します。</p>
- <p><b>%header{Referer}</b>とすると、リクエストヘッダのRefererの値を出力します。</p>
- <p>オプションを指定しなかったら、利用可能なヘッダを全て出力します。
- </p>
- </td>
- </tr>
- <tr>
- <td class="word" name="requestMethod"><b>m</b><br /><b>
-requestMethod</b></td>
- <td>
- <p>リクエストメソッド。</p>
- </td>
- </tr>
- <tr>
- <td class="word" name="requestURL"><b>r</b><br /><b>
-requestURL</b></td>
- <td>
- <p>要求されたURL。
- </p>
- </td>
- </tr>
- <tr>
- <td class="word" name="statusCode"><b>s</b><br /><b>
-statusCode</b></td>
- <td>
- <p>レスポンスのステータスコード。</p>
- </td>
- </tr>
- <tr>
- <td class="word" name="elapsedTime"><b>D</b><br /><b>
-elapsedTime</b></td>
- <td>
- <p>リクエストを処理するのにかかった時間。ミリ秒単位です。
- </p>
- </td>
- </tr>
- <tr>
- <td class="word" name="dateAccess"><b>t</b><br /><b>
-date</b></td>
- <td>
- <p>ロギングイベントの日時を出力します。オプションとして、<code>java.text.SimpleDateFormat</code>で使用できる日時パターン文字列を指定します。<em>ISO8601</em>も有効な値です。
- </p>
- <p>具体的には、<b>%t {HH:mm:ss,SSS} </b>や、<b>%t{dd MMM yyyy;HH:mm:ss,SSS}</b>などです。日時パターン文字列が指定されなかったら、共通ログ書式の日時パターン文字列である<b>T6{dd/MMM/yyyy:HH:mm:ss Z}</b>が指定されたものとして扱います。
- </p>
- </td>
- </tr>
- <tr>
- <td class="word" name="httpUser"><b>u</b><br /><b>
-user</b></td>
- <td>
- <p>リモートユーザー。
- </p>
- </td>
- </tr>
- <tr>
- <td class="word" name="requestURI"><b>U</b><br /><b>
-requestURI</b></td>
- <td>
- <p>要求されたURI。</p>
- </td>
- </tr>
- <tr>
- <td class="word" name="server"><b>v</b><br /><b>
-server</b></td>
- <td>
- <p>サーバー名。</p>
- </td>
- </tr>
- <tr class="b">
- <td class="word" name="localPort"><b>localPort</b></td>
- <td>
- <p>ローカルポート番号。</p>
- </td>
- </tr>
- <tr class="a">
- <td class="word" name="reqAttribute"><b>reqAttribute{attributeName}</b></td>
- <td>
- <p>リクエストの属性。</p>
- <p>この変換指定子はオプションで指定された属性を探します。
-</p>
- <p><b>%reqAttribute{SOME_ATTRIBUTE}</b>とすると、リクエスト属性SOME_ATTRIBUTEの値を出力します。</p>
- </td>
- </tr>
- <tr class="b">
- <td class="word" name="reqCookie"><b>reqCookie{cookie}</b></td>
- <td>
- <p>リクエストクッキー。</p>
- <p>この変換指定子はオプションで指定されたリクエストクッキーを探します。
-</p>
- <p><b>%cookie{COOKIE_NAME}</b>とすると、クッキーCOOKIE_NAMEの値を出力します。</p>
- </td>
- </tr>
- <tr class="a">
- <td class="word" name="responseHeader"><b>responseHeader{header}</b></td>
- <td>
- <p>レスポンスヘッダー。
- </p>
- <p>この変換指定子はオプションで指定されたレスポンスヘッダを探します。
-</p>
- <p><b>%responseHeader{Server}</b>とすると、レスポンスヘッダServerの値を出力します。</p>
- </td>
- </tr>
- <tr class="b">
- <td class="word" name="requestContent"><b>requestContent</b></td>
- <td>
- <p>この変換指定はリクエストの中身、つまり、リクエストの<code>InputStream</code>を出力します。実際は、<code><a href="http://logback.qos.ch/xref/ch/qos/logback/access/servlet/TeeFilter.html">TeeFilter</a></code>によって元の<code>HttpServletRequest</code>を<code>TeeHttpServletRequest</code>に置き換えます。だから、データを失わずに何度でもリクエストの<code>InputStream</code>にアクセスできるのです。
- </p>
- </td>
- </tr>
- <tr class="a">
- <td class="word" name="fullRequest"><b>fullRequest</b></td>
- <td>
- <p>リクエストに関連するヘッダ、コンテンツを全て出力します。
- </p>
- </td>
- </tr>
- <tr class="b">
- <td class="word" name="responseContent"><b>responseContent</b></td>
- <td>
- <p>レスポンスの中身、つまり、レsポンスの<code>InputStream</code>を出力します。実際は、<code>TeeFilter</code>によって元の<code>HttpServletResponse</code>を<code>TeeHttpServletResponse</code>に置き換えます。だから、データを失わずに何度でもレスポンスの<code>InputStream</code>にアクセスできるのです。
- </p>
- </td>
- </tr>
- <tr class="a">
- <td class="word" name="fullResponse"><b>fullResponse</b></td>
- <td>
- <p>レスポンスに関連するヘッダ、コンテンツを全て出力します。
- </p>
- </td>
- </tr>
- </table>
-
- <p>logback-accessの<code>PatternLayout</code>ではさらに3つのキーワードが利用できます。これはいわゆるショートカットです。</p>
-
- <table class="bodyTable">
- <tr>
- <th>キーワード</th>
- <th>等価な変換パターン文字列</th>
- </tr>
- <tr class="a">
- <td><em>common</em>
-<em>CLF</em></td>
- <td><em>%h %l %u [%t] "%r" %s %b</em></td>
- </tr>
- <tr class="b">
- <td><em>combined</em></td>
- <td><em>%h %l %u [%t] "%r" %s %b "%i{Referer}" "%i{User-Agent}"</em></td>
- </tr>
-
- </table>
-
-
- <p>キーワード<em>common</em>は変換文字列パターン<em>'%h %l %u [%t] "%r" %s %b'</em>と同じ意味になります。先頭から順番に、クライアントホスト、リモートログ名、ユーザー名、日時、リクエストURL、ステータスコード、レスポンスのコンテンツ長が出力されます。</p>
-
- <p>キーワード<em>combined</em>は変換文字列パターン<em>'%h %l %u [%t]
- "%r" %s %b "%i{Referer}" "%i{User-Agent}"'</em>のショートカットです。先頭は<em>common</em>キーワードの変換パターン文字列とほとんど代わりませんが、referer、user-agent というリクエストヘッダが追加されているのが違います。</p>
-
- <h3 class="doAnchor" name="AccessHTMLLayout">HTMLLayout</h3>
-
- <p>logback-accessモジュールの<a href="http://logback.qos.ch/xref/ch/qos/logback/access/html/HTMLLayout.html"><code>HTMLLayout</code></a>は、logback-classicモジュールの<a href="http://logback.qos.ch/manual/layouts.html#ClassicHTMLLayout"><code>HTMLLayout</code></a>とほとんど変わりません。
- </p>
-
- <p>デフォルトでは次の項目を含む表を作ります。</p>
-
- <ul>
- <li>リモートIP</li>
- <li>日付</li>
- <li>リクエストURL</li>
- <li>レスポンスのステータスコード</li>
- <li>コンテンツ長</li>
- </ul>
-
- <p>logack-accessの<code>HTMLLayout</code>による出力例を見てください。</p>
- <img src="images/chapters/layouts/htmlLayoutAccess.gif" alt="アクセスHTMLレイアウトサンプル画像">
-
- <p>実際に使うと上でもっと良くするにはどうしたらいいでしょうか?log4j.properties for logback <a href="http://logback.qos.ch/translator/">translator</a>は、logback-access の<code>RollingFileAppender</code>と<code>HTMLLayout</code>を使ってリアルタイム出力をするようになっています。</p>
-
-
- <p>Webアプリケーションの<a href="http://logback.qos.ch/translator/">translator</a>に対するユーザーからのリクエストに対して、都度新しいアクセスログが出力されます。<a href="http://logback.qos.ch/translator/logs/access.html">このリンク先</a>でそれを見ることが出来ます。</p>
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/manual/loggingSeparation.html b/docs/manual/loggingSeparation.html
index b7fe4a9..6054d1a 100644
--- a/docs/manual/loggingSeparation.html
+++ b/docs/manual/loggingSeparation.html
@@ -27,8 +27,6 @@
<div id="content">
<h1>Chapter 9: Logging separation</h1>
-
- <a href="loggingSeparation_ja.html">和訳 (Japanese translation)</a>
<div class="quote">
<p><em>It is not knowledge, but the act of learning, not
@@ -223,9 +221,9 @@
ContextJNDISelector</h3>
<p>First, place the logback jars (that is
- logback-classic-1.1.9.jar,
- logback-core-1.1.9.jar and
- slf4j-api-1.7.22.jar) in Tomcat's global (shared) class
+ logback-classic-1.1.2.jar,
+ logback-core-1.1.2.jar and
+ slf4j-api-1.7.6.jar) in Tomcat's global (shared) class
folder. In Tomcat 6.x, this directory is
<em>$TOMCAT_HOME/lib/</em>.
</p>
diff --git a/docs/manual/loggingSeparation_ja.html b/docs/manual/loggingSeparation_ja.html
deleted file mode 100644
index 68bed13..0000000
--- a/docs/manual/loggingSeparation_ja.html
+++ /dev/null
@@ -1,270 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第9章 ログの分離</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第9章 ログの分離</h1>
-
- <div class="quote">
- <p><em>知識ではなくそれを学ぼうとする行為、所持することではなく得ようとする行為、それこそが最上の娯楽なのです。私は課題を研究し尽くしてしまうと、誰にも見つからないようにそこから離れてしまいます。私という決して満足できない人間は、何かを成し遂げた後平和裏に過ごすのではなく、すぐに違うことを始めてしまう奇人なのです。1つの国を征服したそばから、次の国に手を出そうとする、世界を征服するというのはこういうことなんだという確信があります。</em></p>
-
- <p>-カール・フレデリッヒ・ガウス、1808年に記されたボヨイへの手紙</p>
-
- <p><em>薄い絹のような洋服であってもほとんどの湿疹は隠れてしまう。</em></p>
-
- <p>-アルベール・カミュ、 <em>秋</em></p>
-
- </div>
-
- <script src="../templates/creative.js" type="text/javascript"></script>
- <script src="../templates/setup.js" type="text/javascript"></script>
-
- <h2>問題:ログの分離</h2>
-
- <p>本章では、同じWebコンテナあるいはEJBコンテナ上で稼働する複数のアプリケーションで、ログを分離するにはどうすればいいのか検討します。文中で"application"という言葉を使う時は、WebアプリケーションかJ2EEアプリケーションのどちらかを表しています。分離されたログ環境では、それぞれのアプリケーションは独立したlogback環境になります。したがって、アプリケーションのlogbackの設定は、他の設定には影響しません。技術的な言葉で言うと、それぞれのWebアプリケーションは専用の独立した<code>LoggerContext</code>を使用します。logbackに話を戻します。<code>LoggerContext</code>に生成されたロガーオブジェクトは、メモリ上に残っている間はLoggerContextに割り当てられたままです。類似の問題として、アプリケーションのロギングとコンテナのロギングの分離、というものがあります。
- </p>
-
- <h2 class="doAnchor" name="easy">一番簡単でわかりやすい方法</h2>
-
- <p>コンテナが子孫優先クラスローディングをサポートしていることにしましょう。その場合 slf4j と logback の jar ファイルをアプリケーション自体に含めるようにすればログを分離することができます。Webアプリケーションなら<em>WEB-INF/lib</em>ディレクトリの下に置くだけで、アプリケーションごとのロギングを分離するには十分です。logbackがメモリにロードされるとき、<em>WEB-INF/classes</em>に置かれた<em>logback.xml</em>のコピーが選ばれます。
- </p>
-
- <p>コンテナがクラスローダーを別々にしてくれるので、Webアプリケーションは自分の<code>LoggerContext</code>に自分の<em>logback.xml</em>を選ばせることができます。</p>
-
- <p>朝飯前です。</p>
-
- <p>少し正確さにかけますね・・・SLF4Jとlogbackを全てのアプリケーションからアクセスできる場所に置かなければならないこともあるでしょう。共有ライブラリがSLF4Jを使っている場合などです。そうすると、全てのアプリケーションは同じlogback環境を共有することになってしまいます。他にも、全てのアプリケーションから参照できる場所にSLF4Jとlogbackを置かなければならないような状況はあるでしょう。そして、それはクラスローダー分離に基づくログの分離を不可能にしてしまいます。絶望しなくてもいいですよ。まだ希望は残されています。読み進めてください。
- </p>
-
- <h2 class="doAnchor" name="contextSelectors">コンテキストセレクタ</h2>
-
- <p>logbackにはメモリにロードされている単一のインスタンスによって複数のLoggerContextを扱う仕組みがあります。次のように書いたとしましょう。</p>
-
- <pre class="prettyprint source">Logger logger = LoggerFactory.getLogger("foo");</pre>
-
- <p><code>LoggerFactory</code>の<code>getLogger()</code>メソッドは、SLF4Jのバインディングに<code>ILoggerFactory</code>を問い合わせます。SLF4Jがlogbackにバインドされているときは、<code>ILoggerFactory</code>を返すというタスクが、<a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/selector/ContextSelector.html">ContextSelector</a>に委譲されるのです。<code>ContextSelector</code>は常に<code>LoggerContext</code>のインスタンスを返すので気をつけておきましょう。ContextSelectorは、<code>ILoggerFactory</code>インターフェイスを実装しています。言い換えると、コンテキストセレクタは独自の基準に従って<code>LoggerContext</c [...]
- </p>
-
- <p>デフォルトでは、logbackバインディングは<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/selector/DefaultContextSelector.html">DefaultContextSelector</a>を使います。これは、デフォルトのロガーコンテキストと呼ばれる常に同じ<code>LoggerContext</code>を返します。</p>
-
- <p>システムプロパティの<em>logback.ContextSelector</em>を使うと、別のコンテキストセレクタを指定することができます。コンテキストセレクタに<code>myPackage.myContextSelector</code>を指定したければ、次のように指定すればよいのです。</p>
-
- <p class="source">-Dlogback.ContextSelector=myPackage.myContextSelector</p>
-
- <p>コンテキストセレクタは、<code>ContextSelector</code>インターフェイスを実装しなければなりません。そして、<code>LoggerContext</code>を唯一の引数とするコンストラクタが必要です。
- </p>
-
-
- <h3 class="doAnchor" name="ContextJNDISelector">ContextJNDISelector</h3>
-
- <p>logback-classic の配布物には<code>ContextJNDISelector</code>というコンテキストセレクタが含まれています。これは JNDI を介して参照できるロガーコンテキストを選択できるようにするものです。これは J2EE の仕様にある JNDI のデータ分離に基づいています。したがって、同じ環境変数を使って、アプリケーションごとに異なる値を渡すことが出来るようになります。言い換えると、単独のLoggerFactoryを全てのアプリケーションで共有している状態でも、それぞれのアプリケーションによる<code>LoggerFactory.getLogger()</code>の呼び出しに対して、独立したロガーコンテキストに割り当てられたロガーを返すようになるのです。これでログを分離することができるでしょう。
- </p>
-
- <p><code>ContextJNDISelector</code>を有効化するには、システムプロパティの<em>logback.ContextSelector</em>に"JNDI"を指定します。</p>
-
- <p class="source">-Dlogback.ContextSelector=JNDI</p>
-
- <p><code>JNDI</code>という値は、<code>ch.qos.logback.classic.selector.ContextJNDISelector</code>の省略形です。</p>
-
- <h3 class="doAnchor" name="settingJNDIVariables">JNDI変数の設定</h3>
-
- <p>それぞれのアプリケーションが、専用のコンテキスト名を設定しなければなりません。Webアプリケーションの場合、JNDI環境変数は<em>web.xml</em>で指定します。アプリケーション名が "knobi" なら、web.xml に次のような設定を追加すればよいでしょう。</p>
-
- <pre class="prettyprint source"><env-entry>
- <env-entry-name>logback/context-name</env-entry-name>
- <env-entry-type>java.lang.String</env-entry-type>
- <env-entry-value>kenobi</env-entry-value>
-</env-entry></pre>
-
- <p><code>ContextJNDISelector</code>が有効になっているとしたら、kenobiアプリケーションのロガーは"kenobi"ロガーコンテキストに割り当てられたものになっているでしょう。また、"kenobi"ロガーコンテキストの設定ファイルは、<em>命名規約</em>にしたがって <em>logback-kenobi.xml</em>という名前になります。スレッドコンテキストクラスローダーの<em>リソース</em>から見つけて初期化に使われます。つまり、kenobiアプリケーションの<em>WEB-INF/classes</em>の下に<em>logback-kenobi.xml</em>を配置しておかなければなりません。
- </p>
-
- <p>"logback/configuration-resource" という JNDI 環境変数を使えば、命名規約に関わらず他の名前の設定ファイルを使うこともできます。例えば、kenobiアプリケーションで命名規約に従った<em>logback-kenobi.xml</em>ではなく<em>aFolder/my_config.xml</em>を使うとしたら、次のような設定をweb.xmlに追加することになります。</p>
-
-
- <pre class="prettyprint source"><env-entry>
- <env-entry-name>logback/configuration-resource</env-entry-name>
- <env-entry-type>java.lang.String</env-entry-type>
- <env-entry-value>aFolder/my_config.xml</env-entry-value>
-</env-entry></pre>
-
- <p><em>my_config.xml</em>は、<em>WEB-INF/classes/aFolder/</em>の下に置かなければなりません。設定ファイルは、現在のスレッドのコンテキストクラスローダーによってJavaのリソースと同じように探索されるということを覚えておいてください。
- </p>
-
-
- <h3 class="doAnchor" name="jndiTomcat">ContextJNDISelectorを使うためのTomcatの設定</h3>
-
- <p>まず、logback.jar(logback-classic-1.1.2.jar logback-core-1.1.1.jar slf4j-api-1.7.6.jar)をTomcatのグローバルな共有クラスフォルダ(shared)に置きましょう。Tomcat 6.x の場合は、<em>$TOMCAT_HOME/lib</em> の下に置いてください。
- </p>
-
- <p>そして、<em>$TOMCAT_HOME/bin/catalina.sh(Windows の場合は catalina.bat)</em>の適切な場所で、次のようにシステムプロパティの<em>logback.ContextSelector</em>を設定してください。</p>
-
- <p class="source">JAVA_OPTS="$JAVA_OPTS -Dlogback.ContextSelector=JNDI"</p>
-
-
- <h3 class="doAnchor" name="hotDeploy">ホットデプロイ</h3>
-
- <p>アプリケーションがリサイクルされるとき、あるいは、シャットダウンするとき、利用中の<code>LoggerContext</code>はクローズしましょう。確実にガベージコレクションされるためには欠かせません。声を大にしておすすめします。logbackの配布物には<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/selector/servlet/ContextDetachingSCL.html"><code>ContextDetachingSCL</code></a>という<code>ServletContextListener</code>が含まれています。これは古いアプリケーションのインスタンスに関連付けられている<code>ContextSelector</code>をデタッチするためだけに用意されたものです。<em>web.xml</em>に次のような設定を追加すれば有効になります。</p>
-
- <pre class="prettyprint source"><listener>
- <listener-class>ch.qos.logback.classic.selector.servlet.ContextDetachingSCL</listener-class>
-</listener></pre>
-
- <p>ほぼ全てのコンテナ実装は、web.xml に記載された順番でリスナーの<code>contextInitialized()</code>メソッドを呼び出します。ですが、<code>contextDestroyed()</code>メソッドの呼び出される順番は記載された順番の<span class="label notice">逆順</span>です。つまり、<em>web.xml</em>に複数の<code>ServletContextListener</code>を宣言している場合は、<code>ContextDetachingSCL</code>を<em>先頭</em>で宣言しなければならないということです。そうすれば、<code>contextDestroyed()</code>メソッドは<em>一番最後</em>に呼び出されるようになります。</p>
-
- <h3 class="doAnchor" name="betterPerf">パフォーマンスの改善</h3>
-
- <p><code>ContextJNDISelector</code>が有効になっていると、ロガーを取得するたびにJNDIの検索が行われるようになります。このことが、性能に悪影響を及ぼす可能性があります。特に静的変数ではない(インスタンス変数の)ロガーを使っている場合はその可能性は高まります。logbackの配布物には<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/selector/servlet/LoggerContextFilter.html">LoggerContextFilter</a>というサーブレットフィルターが含まれています。これはJNDIの検索にかかるコストを解消するために設計されたものです。web.xmlに次のような設定を追加すれば有効になります。
-</p>
-
- <pre class="prettyprint source"><filter>
- <filter-name>LoggerContextFilter</filter-name>
- <filter-class>ch.qos.logback.classic.selector.servlet.LoggerContextFilter</filter-class>
-</filter>
-<filter-mapping>
- <filter-name>LoggerContextFilter</filter-name>
- <url-pattern>/*</url-pattern>
-</filter-mapping></pre>
-
- <p>HTTPリクエストを受け付けたら、まず初めに<code>LoggerContextFilter</code>はアプリケーションに関連付けられたロガーコンテキストを取得して、<code>ThreadLocal</code>に保存します。<code>ContextJNDISelector</code>は、最初に<code>ThreadLocal</code>変数が設定されているかどうかをチェックします。設定されているときは、JNDIの検索をスキップします。HTTPリクエストの処理の最後に、<code>ThreadLocal</code>変数はnullにされるので気をつけてください。<code>LoggerContextFilter</code>を使うようにすると、ロギングの性能は大幅に改善します。
- </p>
-
- <p><code>ThreadLocal</code>の変数はnullになるので、アプリケーションがリサイクルされるときや停止するときのガベージコレクションでちゃんと回収されます。</p>
-
-
- <h2 class="doAnchor" name="tamingStaticRefs">共有ライブラリ内部の静的参照を飼いならす</h2>
-
- <p>全てのアプリケーションでSLF4Jとlogbackを共有しているとき、<code>ContextJNDISelector</code>を使うとうまくログを分離できます。<code>ContextJNDISelector</code>が有効なら、それぞれのアプリケーションの<code>LoggerFactory.getLogger()</code>メソッドの呼び出しは、アプリケーションに関連付けられたロガーコンテキストに割り当てられたロガーを返してくれます。</p>
-
- <p>静的変数としてロガーを参照するのが一般的なイディオムです。</p>
-
- <pre class="prettyprint source">public class Foo {
- <b>static</b> Logger logger = LoggerFactory.getLogger(Foo.class);
- ...
-}</pre>
-
- <p>静的変数でロガーを参照するのは、メモリとCPUのどちらにとっても効率的です。そのクラスの全てのインスタンスは、ただ一つの参照を使いまわせるからです。また、ロガーのインスタンスを取得するのは、クラスがメモリにロードされたときだけです。ロガー静的変数を持っているクラスが kenobi アプリケーションに含まれているなら、そのロガーのインスタンスは<code>ContextJNDISelector</code>から取得したkenobi用のロガーコンテキストに割り当てられることになります。同様に、別のアプリケーション yoda に含まれているクラスのロガーインスタンスは、やはり<code>ContextJNDISelector</code>から取得した yoda用のロガーコンテキストに割り当てられることになります。
- </p>
-
- <p>もし<em>kenobi</em>アプリケーションと<em>yoda</em>アプリケーションの両方で共有しているライブラリに含まれる<code>Mustafar</code>クラスだったら、ただし<code>Mustafar</code>クラスではインスタンス変数やローカル変数でロガーを参照していたらどうなるでしょうか。<code>LoggerFactory.getLogger()</code>メソッドは、それが呼ばれたアプリケーションに関連付けられたロガーコンテキストに割り当てられたロガーを返してくれるでしょう。しかし、<code>Mustafar</code>クラスが静的変数でロガーを参照していたらどうなるでしょう。その場合、最初にそのクラスを参照したアプリケーションに関連付けられたロガーコンテキストに割り当てられたロガーになってしまいます。つまり、<code>ContextJNDISelector</code>は、共有ライブラリのクラスが保持する静的変数のロガーについては、ログの分離ができないのです。このような状況は特に限定的なもので、長い間解決策 [...]
-
-
- <p>この問題を文句のつけようもないくらいに完全に解決するには、別の観点でロガーの内部事情に切り込まなければなりません。たとえば、ロガーは実際の仕事をするロガーを内包するものとして、ロガーに対するメッセージは内包するロガーに委譲するようにします。そして、内包されたロガーは適切なロガーコンテキストを参照するようにするのです。このアプローチは実装が大変だし、オーバーヘッドが非常に高くなってしまうでしょう。取りかかる気にはなれません。
- </p>
-
- <p>クラスの共有を止めて、アプリケーションの内部に移動してしまうのが、"共有クラスの静的ロガー"問題に対するお手軽な解決方法の1つであることは言うまでもありません。共有しないようにするのが不可能なら、<a href="http://logback.qos.ch/manual/appenders.html#SiftingAppender"><code>SiftingAppender</code></a>の魔法を使ってログの分離を実現するしかないでしょう。
- </p>
-
- <p>logbackの配布物には<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/sift/JNDIBasedContextDiscriminator.html">JNDIBasedContextDiscriminator</a>という弁別器が含まれています。これは<code>ContextJNDISelector</code>の返すロガーコンテキストの名前を返すものです。<code>SiftingAppender</code>と<code>JNDIBasedContextDiscriminator</code>を組み合わせると、アプリケーションごとに別々のアペンダーインスタンスを生成することができます。
- </p>
-
- <pre class="prettyprint source"><configuration>
-
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
-
- <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
- <discriminator class="ch.qos.logback.classic.sift.JNDIBasedContextDiscriminator">
- <defaultValue>unknown</defaultValue>
- </discriminator>
- <sift>
- <appender name="FILE-${contextName}" class="ch.qos.logback.core.FileAppender">
- <file><b>${contextName}.log</b></file>
- <encoder>
- <pattern>%-50(%level %logger{35}) cn=%contextName - %msg%n</pattern>
- </encoder>
- </appender>
- </sift>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SIFT" />
- </root>
-</configuration></pre>
-
-
- <p>kenobi と yoda というWebアプリケーションがあるとして、この設定ファイルを使うと yoda のログは <em>yoda.log</em>に、kenobi のログは<em>kenobi.log</em>に出力されるようになります。これは共有クラスの静的ロガーでも有効です。</p>
-
- <p><a href="http://github.com/ceki/logback-starwars">logback-starwars</a>プロジェクトを使えば、ここで説明したテクニックを実際に試してみることができます。
- </p>
-
-
- <p>上記のアプローチは、ログの分離問題を解決できますがかなり複雑です。適切な<code>ContextJNDISelector</code>の設定や、アペンダーを<code>SiftingAppender</code>でラップするこは、手傷を負った猛獣のように手が付けられません。
- </p>
-
- <p>それぞれのロギングコンテキストは、同じ設定ファイルでも、それぞれ別の設定ファイルでも設定できることを忘れないようにしましょう。選ぶのはあなたです。コンテキストごとに設定ファイルをメンテナンスするよりは、全て同じ設定ファイルを使うようにするほうが簡単です。アプリケーションごとに設定ファイルをメンテナンスするのは大変ですが、柔軟性はあります。</p>
-
- <p>これで終わりでしょうか?勝どきを上げて、気持ちよく我が家に帰れるのでしょうか?実はまだ続くんです。</p>
-
- <p><code>yoda</code>が<code>kenobi</code>より前に初期化されるとしましょう。<code>yoda</code>を初期化するため、<code>http://localhost:port/yoda/servlet</code>を参照して<code>YodaServlet</code>を呼び出します。このサーブレットは単に挨拶を返すだけです。ただし、ログを取得してから<code>Mustafar</code>の<code>foo()</code>メソッドを呼び出します。このメソッドは単純にログを取得するだけのものです。
- </p>
-
- <p><code>YodaServlet</code>が呼び出された後、<em>yoda.log</em>の内容は次のようになります。</p>
-
- <pre class="source">DEBUG ch.qos.starwars.yoda.YodaServlet cn=yoda - in doGet()
-DEBUG ch.qos.starwars.shared.Mustafar cn=yoda - in foo()</pre>
-
- <p>どちらのログも、"yoda"アプリケーションに関連付けられたロガーコンテキストによるものであることが分かりますか。ここからサーバーが停止するまで、<code>ch.qos.starwars.shared.Mustafar</code>のロガーは、"yoda"コンテキストに割り当てられたものになります。
- </p>
-
- <p><code>http://localhost:port/kenobi/servlet</code>にアクセスした後の<em>kenobi.log</em>の内容は次のようになります。</p>
-
- <pre class="source">DEBUG ch.qos.starwars.kenobi.KenobiServlet <b>cn=kenobi</b> - in doGet()
-DEBUG ch.qos.starwars.shared.Mustafar <b>cn=yoda</b> - in foo()</pre>
-
- <p>なんと、<code>ch.qos.starwars.shared.Mustafar</code>のロガーは<em>kenobi.log</em>に出力しているのに、"yoda"コンテキストに割り当てられているロガーのままです。つまり、別のロガーコンテキストに割り当てられたロガーが同じファイル(この場合は<em>kenobi.log</em>)に出力してしまうのです。それぞれのコンテキストが参照している<code>FileAppender</code>のインスタンスは、別々の<code>SiftingAppender</code>のインスタンスに内包されたもので、同じファイルにログを出力しています。ログの分離は思った通りに機能しているように見えますが、<span class="option">prudent</span>モードを有効化しない限り、FileAppender は同じファイルへのログの書き込みを安全に行うことができません。そうしないとファイルの内容が壊れてしまいます。</p>
-
- <p>prudent モードを有効にした設定ファイルを見てください。</p>
-
- <pre class="prettyprint source"><configuration>
-
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
-
- <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
- <discriminator class="ch.qos.logback.classic.sift.JNDIBasedContextDiscriminator">
- <defaultValue>unknown</defaultValue>
- </discriminator>
- <sift>
- <appender name="FILE-${contextName}" class="ch.qos.logback.core.FileAppender">
- <file>${contextName}.log</file>
- <b><prudent>true</prudent></b>
- <encoder>
- <pattern>%-50(%level %logger{35}) cn=%contextName - %msg%n</pattern>
- </encoder>
- </appender>
- </sift>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SIFT" />
- </root>
-</configuration></pre>
-
-
- <p>ここまでの議論を読み解いてきて、その上で logback-starwars プロジェクトを試してみたのなら、きっともうロギングのことが頭から離れなくなっていると思います。これ以上のことは<a href="http://www.qos.ch/shop/products/professionalSupport">専門家の助け</a>を借りるしかないでしょう。</p>
-
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-
- </body>
-</html>
\ No newline at end of file
diff --git a/docs/manual/mdc.html b/docs/manual/mdc.html
index 450548e..b7013e8 100644
--- a/docs/manual/mdc.html
+++ b/docs/manual/mdc.html
@@ -28,8 +28,6 @@
<h1>Chapter 8: Mapped Diagnostic Context</h1>
- <a href="mdc_ja.html">和訳 (Japanese translation)</a>
-
<div class="quote">
<p><em>Lock the doors.</em></p>
<p>—LEROY CAIN, Flight Director, Columbia Mission Control</p>
@@ -676,15 +674,6 @@ public class UserServletFilter implements Filter {
</tr>
<tr class="alt">
- <td><code>req.method</code></td>
- <td>
- as returned by <a
- href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletRequest.html#getMethod%28%29">getMethod()</a>
- method
- </td>
- </tr>
-
- <tr>
<td><code>req.requestURI</code></td>
<td>
as returned by <a
@@ -693,7 +682,7 @@ public class UserServletFilter implements Filter {
</td>
</tr>
- <tr class="alt">
+ <tr >
<td><code>req.requestURL</code></td>
<td>
as returned by <a
@@ -702,7 +691,7 @@ public class UserServletFilter implements Filter {
</td>
</tr>
- <tr>
+ <tr class="alt">
<td><code>req.queryString</code></td>
<td>
as returned by <a
@@ -710,7 +699,7 @@ public class UserServletFilter implements Filter {
</td>
</tr>
- <tr class="alt">
+ <tr>
<td><code>req.userAgent</code></td>
<td>value of the "User-Agent" header
</td>
diff --git a/docs/manual/mdc_ja.html b/docs/manual/mdc_ja.html
deleted file mode 100644
index edcfc4b..0000000
--- a/docs/manual/mdc_ja.html
+++ /dev/null
@@ -1,542 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第8章 診断コンテキスト</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第8章 診断コンテキスト</h1>
-
- <div class="quote">
- <p><em>ドアを閉めなさい</em></p>
- <p>—LEROY CAIN, Flight Director, Columbia Mission Control</p>
- </div>
-
- <script src="../templates/creative.js" type="text/javascript"></script>
-
- <p>logbackの設計目標の1つとして、複雑な分散アプリケーションの監査とデバッグに使うことがあります。現実世界のほとんどの分散型システムは、同時に複数のクライアントの相手をしなければなりません。こういうシステムの典型的なマルチスレッドの実装は、スレッドが別々のクライアントを処理するものです。それぞれのクライアントに対するログ出力を分離するために実際に行われているアプローチは、クライアントごとに新しいロガーを用意するという少々残念なものです。このやり方ではやたらめったらロガーを生成することになりますし、管理のためのオーバーヘッドも馬鹿になりません。
- </p>
-
- <script src="../templates/setup.js" type="text/javascript"></script>
-
-
- <p>もう少し軽めのやり方としては、リクエストを受け付けたクライアントの固有の情報をログに出力する方法があります。この方法は書籍「Patterns for Logging Diagnostic Messages in Pattern Languages of Program Design 3」(Addison-Wesley, 1997)でニール・ハリソンが紹介しています。logback が利用しているのはSLF4J API の診断コンテキスト(MDC)で、これはさっき紹介した技法を応用したものです。
- </p>
-
- <p>リクエストごとの固有の情報として、利用者はコンテキストの情報を<code>MDC</code>(Mapped Diagnostic Contextの略です)に設定します。MDCクラスの特筆すべき部分を紹介します。メソッドの完全な説明は<a href="http://www.slf4j.org/api/org/slf4j/MDC.html">MDCのjavadoc</a>を参照してください。
- </p>
-
-<pre class="prettyprint source">package org.slf4j;
-
-public class MDC {
- //Put a context value as identified by <em>key</em>
- //into the current thread's context map.
- <b>public static void put(String key, String val);</b>
-
- //Get the context identified by the <code>key</code> parameter.
- <b>public static String get(String key);</b>
-
- //Remove the context identified by the <code>key</code> parameter.
- <b>public static void remove(String key);</b>
-
- //Clear all entries in the MDC.
- <b>public static void clear();</b>
-}</pre>
-
- <p><code>MDC</code>クラスには静的メソッドしかありません。おかげで、開発者が<em>診断コンテキスト</em>に設定した情報は、logback のありとあらゆるコンポーネントから取得できるようになるのです。<code>MDC</code>はコンテキストの情報を<em>スレッドごとに</em>管理します。子スレッドは、親の診断コンテキストの<em>コピー</em>を自動的に継承します。普通なら、開発者はクライアントから受け付けた新しい要求の処理を始めるところで、クライアント識別子、IPアドレス、リクエストパラメーターなどの適切なコンテキスト情報を<code>MDC</code>に設定します。logback のコンポーネントがちゃんと設定されていれば、こういった情報は自動的にログ項目に含まれるようになります。
- </p>
-
- <p>logback-classic の MDC 実装は、値の書き込みが比較的穏やかに行われることを想定しているのでくれぐれも注意してください。</p>
-
- <p><code><a href="http://logback.qos.ch/xref/chapters/mdc/SimpleMDC.html">SimpleMDC</a></code>アプリケーションを使ってこの基本原則を説明しましょう。
- </p>
- <p class="example">例7.1:MDCの基本的な使い方(<a href="http://logback.qos.ch/xref/chapters/mdc/SimpleMDC.html">logback-examples/src/main/java/chapters/mdc/SimpleMDC.java</a>)</p>
-<pre class="prettyprint source">package chapters.mdc;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.MDC;
-
-import ch.qos.logback.classic.PatternLayout;
-import ch.qos.logback.core.ConsoleAppender;
-
-public class SimpleMDC {
- static public void main(String[] args) throws Exception {
-
- // You can put values in the MDC at any time. Before anything else
- // we put the first name
- MDC.put("first", "Dorothy");
-
- [ SNIP ]
-
- Logger logger = LoggerFactory.getLogger(SimpleMDC.class);
- // We now put the last name
- MDC.put("last", "Parker");
-
- // The most beautiful two words in the English language according
- // to Dorothy Parker:
- logger.info("Check enclosed.");
- logger.debug("The most beautiful two words in English.");
-
- MDC.put("first", "Richard");
- MDC.put("last", "Nixon");
- logger.info("I am not a crook.");
- logger.info("Attributed to the former US president. 17 Nov 1973.");
- }
-
- [ SNIP ]
-
-}</pre>
-
- <p>mainメソッドでは、まずキー<em>first</em>で値<em>Drothy</em>を<code>MDC</code>に設定します。<code>MDC</code>に指定するキーも値も利用者の自由です。同じキーで書き込むと前の値を上書きします。コード上ではlogbackの設定が行われているところです。</p>
-
- <p>簡潔にするため、logbackを<a href="http://github.com/qos-ch/logback/blob/master/logback-examples/src/main/java/chapters/mdc/simpleMDC.xml">simpleMDC.xml</a>で設定しているところは省略しました。設定ファイル中の該当する箇所は次のようになっています。
- </p>
-
- <pre class="prettyprint source"><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <layout>
- <Pattern><b>%X{first} %X{last}</b> - %m%n</Pattern>
- </layout>
-</appender></pre>
-
-
-
- <p><code>PatternLayout</code>の変換パターン文字列中の<em>%X変換指定子</em>の使い方を見てください。<em>%X変換指定子</em>二回登場しています。一つ目のキーには<em>first</em>、二つ目のキーには<em>last</em>を指定しています。<code>SimpleMDC.class</code>のロガーを取得した後で、MDCにキー<em>last</em>で値<em>Parker</em>を設定しています。それから、メッセージを変えて二回ロギング要求を発行しています。最後に、また別の値を<code>MDC</code>に設定してから、いくつかロギング要求を発行しています。SimpleMDCを実行すると次のような出力になります。</p>
-
-<div class="source"><pre>Dorothy Parker - Check enclosed.
-Dorothy Parker - The most beautiful two words in English.
-Richard Nixon - I am not a crook.
-Richard Nixon - Attributed to the former US president. 17 Nov 1973.</pre></div>
-
-
- <p><code>SimpleMDC</code>アプリケーションを見れば、logbackを適切に設定すると、<code>MDC</code>の値がどのようにレイアウトされて出力されるのかがわかります。また、<code>MDC</code>に設定された情報はロガーの呼び出し一度だけでなく、何度も利用できることがわかります。
- </p>
-
- <h3 class="doAnchor">応用</h3>
-
- <p>診断コンテキストが一番脚光を浴びるのはクライアント・サーバーアーキテクチャだ。一般的に、複数のクライアントはサーバ上の複数のスレッドで処理されます。しかし<code>MDC</code>クラスには静的メソッドしかないので、診断コンテキストはスレッドごとに管理するしかありません。つまり、サーバー上のスレッドそれぞれが<code>MDC</code>の分のコストを負うことになるのです。<code>MDC</code>の<code>put()</code>や<code>get()</code>ような操作は、<em>現在の</em>スレッドと子スレッドの<code>MDC</code>にしか影響しません。他のスレッドの<code>MDC</code>は影響を受けないのです。<code>MDC</code>の情報はスレッドごとに管理されているので、それぞれのスレッドは自分用の<code>MDC</code>を持っていることになります。したがって、開発者はスレッド安全性やスレッド間同期のことを考える必要はありません。<code>MDC</code>はそういったことを安全に [...]
- </p>
-
- <p>次の例は少し凝っています。クライアント・サーバ環境でどのように<code>MDC</code>を使うのか説明したものです。サーバーは例7.2の<code>NumberCrucher</code>インターフェイスを実装します。<code>The NumberCruncher</code>インターフェイスには、<code>factor()</code>というメソッドが1つあるだけです。クライアントは、RMIによってサーバアプリケーションの<code>factor()</code>メソッドを呼び出して、指定した整数の素因数を取得します。
- </p>
-
- <p class="example">例7.2:サービスインターフェイス(<a href="http://logback.qos.ch/xref/chapters/mdc/NumberCruncher.html">logback-examples/src/main/java/chapters/mdc/NumberCruncher.java</a>)</p>
-
-<pre class="prettyprint source">package chapters.mdc;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-/**
- * NumberCruncher factors positive integers.
- */
-public interface NumberCruncher extends Remote {
- /**
- * Factor a positive integer <code>number</code> and return its
- * <em>distinct</em> factor's as an integer array.
- * */
- int[] factor(int number) throws RemoteException;
-}</pre>
-
- <p>例7.3の<code>NumberCruncherServer</code>アプリケーションが<code>NumberCruncher</code>インターフェイスを実装しています。mainメソッドはlocalhost上でRMIレジストリを公開して、well-knownポートでリクエストを待ち受けます。
- </p>
-
- <p class="example">例7.3:サーバー実装(<a href="http://logback.qos.ch/xref/chapters/mdc/NumberCruncherServer.html">logback-examples/src/main/java/chapters/mdc/NumberCruncherServer.java</a>)</p>
-
-<pre class="prettyprint source">package chapters.mdc;
-
-import java.rmi.RemoteException;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.Vector;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.MDC;
-
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.core.joran.spi.JoranException;
-
-
-/**
- * A simple NumberCruncher implementation that logs its progress when
- * factoring numbers. The purpose of the whole exercise is to show the
- * use of mapped diagnostic contexts in order to distinguish the log
- * output from different client requests.
- * */
-public class NumberCruncherServer extends UnicastRemoteObject
- implements NumberCruncher {
-
- private static final long serialVersionUID = 1L;
-
- static Logger logger = LoggerFactory.getLogger(NumberCruncherServer.class);
-
- public NumberCruncherServer() throws RemoteException {
- }
-
- public int[] factor(int number) throws RemoteException {
- // The client's host is an important source of information.
- try {
- <b>MDC.put("client", NumberCruncherServer.getClientHost());</b>
- } catch (java.rmi.server.ServerNotActiveException e) {
- logger.warn("Caught unexpected ServerNotActiveException.", e);
- }
-
- // The information contained within the request is another source
- // of distinctive information. It might reveal the users name,
- // date of request, request ID etc. In servlet type environments,
- // useful information is contained in the HttpRequest or in the
- // HttpSession.
- <b>MDC.put("number", String.valueOf(number));</b>
-
- logger.info("Beginning to factor.");
-
- if (number <= 0) {
- throw new IllegalArgumentException(number +
- " is not a positive integer.");
- } else if (number == 1) {
- return new int[] { 1 };
- }
-
- Vector<Integer> factors = new Vector<Integer>();
- int n = number;
-
- for (int i = 2; (i <= n) && ((i * i) <= number); i++) {
- // It is bad practice to place log requests within tight loops.
- // It is done here to show interleaved log output from
- // different requests.
- logger.debug("Trying " + i + " as a factor.");
-
- if ((n % i) == 0) {
- logger.info("Found factor " + i);
- factors.addElement(new Integer(i));
-
- do {
- n /= i;
- } while ((n % i) == 0);
- }
-
- // Placing artificial delays in tight loops will also lead to
- // sub-optimal results. :-)
- delay(100);
- }
-
- if (n != 1) {
- logger.info("Found factor " + n);
- factors.addElement(new Integer(n));
- }
-
- int len = factors.size();
-
- int[] result = new int[len];
-
- for (int i = 0; i < len; i++) {
- result[i] = ((Integer) factors.elementAt(i)).intValue();
- }
-
- <b>// clean up
- MDC.remove("client");
- MDC.remove("number");</b>
-
- return result;
- }
-
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java chapters.mdc.NumberCruncherServer configFile\n" +
- " where configFile is a logback configuration file.");
- System.exit(1);
- }
-
- public static void delay(int millis) {
- try {
- Thread.sleep(millis);
- } catch (InterruptedException e) {
- }
- }
-
- public static void main(String[] args) {
- if (args.length != 1) {
- usage("Wrong number of arguments.");
- }
-
- String configFile = args[0];
-
- if (configFile.endsWith(".xml")) {
- try {
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- lc.reset();
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- je.printStackTrace();
- }
- }
-
- NumberCruncherServer ncs;
-
- try {
- ncs = new NumberCruncherServer();
- logger.info("Creating registry.");
-
- Registry registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
- registry.rebind("Factor", ncs);
- logger.info("NumberCruncherServer bound and ready.");
- } catch (Exception e) {
- logger.error("Could not bind NumberCruncherServer.", e);
-
- return;
- }
- }
-}</pre>
-
- <p>特に大事なのが<code>factor(int number)</code>メソッドの実装です。最初に、<code>MDC</code>へキー<em>client</em>でクライアントのホスト名を設定しています。そして、クライアントから渡された素因数分解する数をキー<em>number</em>で<code>MDC</code>に設定します。計算が終わったらクライアントに結果を返します。ですが、結果を返す前に、キー<em>client</em>とキー<em>number</em>で設定された値をクリアするため、<code>MDC.remove()</code>メソッドを呼んでいます。普通なら<code>put()</code>操作と<code>remove()</code>操作が同じ数だけ登場するべきです。そうしないと、<code>MDC</code>に特定のキーの値が残ってしまうからです。出来る限り<code>remove()</code>操作をfinallyブロックで実行するように仕込んでおくことをおすすめします。確実に実行されることを保証するためです。
- </p>
-
- <p>理屈っぽい説明が続きましたが、cruncer アプリケーションを実行する準備が整いました。次のコマンドを実行してサーバーを起動しましょう。</p>
-
-<div class="source"><pre>java chapters.mdc.NumberCruncherServer src/main/java/chapters/mdc/mdc1.xml</pre></div>
-
- <p><em>mdc1.xml</em>の内容は次のとおりです。</p>
-
- <p class="example">例7.4:設定ファイル(<a href="http://logback.qos.ch/xref/chapters/mdc/mdc1.xml">logback-examples/src/main/java/chapters/mdc/mdc1.xml</a>)</p>
-
-<pre class="prettyprint source"><configuration>
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <layout>
- <Pattern>%-4r [%thread] %-5level <b>C:%X{client} N:%X{number}</b> - %msg%n</Pattern>
- </layout>
- </appender>
-
- <root level="debug">
- <appender-ref ref="CONSOLE"/>
- </root>
-</configuration></pre>
-
- <p><span class="option">パターン·</span>オプションに<em>%X変換指定子</em>が使われているのを見てください。
- </p>
-
- <p>次のコマンドで<code>NumberCruncherClient</code>アプリケーションを実行しましょう。</p>
-
-<div class="source"><pre>java chapters.mdc.NumberCruncherClient <em>hostname</em></pre></div>
-
- <p><em>hostname</em>の部分には<code>NumberCruncherServer</code>を実行しているサーバのホスト名を指定します。</p>
-
- <p>複数のクライアントを実行して、最初に起動したクライアントがサーバに129を要求して、その後すぐに二つ目のクライアントから71を要求したときのサーバ側のコンソールには、次のように出力されています。</p>
-
-<div class="source"><pre>
-<b>70984 [RMI TCP Connection(4)-192.168.1.6] INFO C:orion N:129 - Beginning to factor.</b>
-70984 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 2 as a factor.
-71093 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 3 as a factor.
-71093 [RMI TCP Connection(4)-192.168.1.6] INFO C:orion N:129 - Found factor 3
-71187 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 4 as a factor.
-71297 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 5 as a factor.
-71390 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 6 as a factor.
-<b>71453 [RMI TCP Connection(5)-192.168.1.6] INFO C:orion N:71 - Beginning to factor.</b>
-71453 [RMI TCP Connection(5)-192.168.1.6] DEBUG C:orion N:71 - Trying 2 as a factor.
-71484 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 7 as a factor.
-71547 [RMI TCP Connection(5)-192.168.1.6] DEBUG C:orion N:71 - Trying 3 as a factor.
-71593 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 8 as a factor.
-71656 [RMI TCP Connection(5)-192.168.1.6] DEBUG C:orion N:71 - Trying 4 as a factor.
-71687 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 9 as a factor.
-71750 [RMI TCP Connection(5)-192.168.1.6] DEBUG C:orion N:71 - Trying 5 as a factor.
-71797 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 10 as a factor.
-71859 [RMI TCP Connection(5)-192.168.1.6] DEBUG C:orion N:71 - Trying 6 as a factor.
-71890 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 11 as a factor.
-71953 [RMI TCP Connection(5)-192.168.1.6] DEBUG C:orion N:71 - Trying 7 as a factor.
-72000 [RMI TCP Connection(4)-192.168.1.6] INFO C:orion N:129 - Found factor 43
-72062 [RMI TCP Connection(5)-192.168.1.6] DEBUG C:orion N:71 - Trying 8 as a factor.
-72156 [RMI TCP Connection(5)-192.168.1.6] INFO C:orion N:71 - Found factor 71</pre></div>
-
- <p>クライアントは<em>orion</em>というホスト名のマシンで実行されていることがわかります。サーバーがほぼ同時に別のスレッドでクライアントの要求を処理する場合でも、それぞれのクライアントからのリクエストによるログ出力は、<code>MDC</code>の出力を見れば分かるようになっています。たとえば、<em>number</em>として印付けられた素因数分解する数です。
- </p>
-
- <p>注意深い人なら、スレッド名を見るだけでもリクエストを区別できることが分かるでしょう。サーバ側の実装がスレッドを再利用するようになっていると混乱させられるかもしれません。そうなってしまったら、いつリクエストを受け付けて、いつ応答を返したのかを特定するのは難しいかもしれません。<code>MDC</code>を管理するのはアプリケーション開発者なので、そういった問題が起きることはありません。
- </p>
-
-
-
- <h3 class="doAnchor" name="autoMDC"><code>MDC</code>への自動的なアクセス</h3>
-
- <p>これまでに見てきたように、<code>MDC</code>があると複数のクライアントの相手をするとき便利です。ユーザー認証のあるWebアプリケーションなら、<code>MDC</code>にユーザー名を設定して、ログアウトするときにそれを削除するようにしておくのが、1つの簡単なソリューションになるでしょう。残念ながら、そのテクニックを使っていても常に確実な結果を得られるわけではありません。<code>MDC</code>がスレッド毎にデータを管理している限り、サーバがスレッドをリサイクするようになっていると、間違った情報が設定されていることがあるかもしれません。</p>
-
- <p>リクエストを処理するとき、いつでも<code>MDC</code>に正しい情報が設定されていることを確実にするためにできるのは、処理の始めにユーザー名を設定して、処理の終わりに削除することです。こういう場合サーブレット<code><a href="http://java.sun.com/javaee/5/docs/api/javax/servlet/Filter.html">Filter</a></code>を使うとよいでしょう。
- </p>
-
- <p>サーブレットフィルターの<code>doFilter()</code>メソッドで、リクエストに関連する情報(cookieも)を集めて、それを<code>MDC</code>に設定するのです。他のフィルターで行う後続処理やサーブレットからは、自動的に今設定したばかりのMDCの情報を参照することができます。最後にまたサーブレットフィルターが仕事をするとき、MDCに設定した内容を削除することができます。
- </p>
-
- <p>フィルターの実装例を見てみましょう。</p>
-
- <p class="example">例7.5:ユーザー名サーブレットフィルター(<a href="http://logback.qos.ch/xref/chapters/mdc/UserServletFilter.html">logback-examples/src/main/java/chapters/mdc/UserServletFilter.html</a>)</p>
-
-<pre class="prettyprint source">package chapters.mdc;
-
-import java.io.IOException;
-import java.security.Principal;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-
-import org.slf4j.MDC;
-
-public class UserServletFilter implements Filter {
-
- private final String USER_KEY = "username";
-
- public void destroy() {
- }
-
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
-
- boolean successfulRegistration = false;
-
- HttpServletRequest req = (HttpServletRequest) request;
- Principal principal = req.getUserPrincipal();
- // Please note that we could have also used a cookie to
- // retrieve the user name
-
- if (principal != null) {
- String username = principal.getName();
- successfulRegistration = registerUsername(username);
- }
-
- try {
- chain.doFilter(request, response);
- } finally {
- if (successfulRegistration) {
- MDC.remove(USER_KEY);
- }
- }
- }
-
- public void init(FilterConfig arg0) throws ServletException {
- }
-
-
- /**
- * Register the user in the MDC under USER_KEY.
- *
- * @param username
- * @return true id the user can be successfully registered
- */
- private boolean registerUsername(String username) {
- if (username != null && username.trim().length() > 0) {
- MDC.put(USER_KEY, username);
- return true;
- }
- return false;
- }
-}</pre>
-
- <p><code>doFilter()</code>メソッドが呼ばれたら、最初にリクエストオブジェクトから<code>java.security.Principal</code>オブジェクトを取得します。このオブジェクトからは、現在認証されているユーザーのユーザー名を取得することができます。ユーザー情報があったらそれを<code>MDC</code>に設定します。</p>
-
- <p>フィルターチェインが完了すると、フィルターでは<code>MDC</code>からユーザー情報を削除します。</p>
-
- <p>ここで紹介したやり方は、スレッドがリクエストを処理している間だけMDCに値を設定するものです。他のスレッドは影響を受けません。さらに、あらゆるスレッドが、任意の時点で正確なMDCデータを持つようになります。</p>
-
-
-
- <h3 class="doAnchor" name="managedThreads">MDCおよび管理スレッド</h3>
-
- <p>ワーカースレッドが自身を初期化するとき、どんなときでも診断コンテキストを継承するわけではありません。これは<code>java.util.concurrent.Executors</code>がスレッドを管理しているときに発生します。例えば、 <code>newCachedThreadPool</code>は<code>ThreadPoolExecutor</code>オブジェクトを作成しますが、他のスレッドプールを生成するコードでも、スレッドの生成は複雑なロジックになっています。
- </p>
-
- <p>そういう場合、元のスレッド(master)でタスクをエグゼキューターに渡す前に、<code>MDC.getCopyOfContextMap()</code>メソッドを呼ぶようにするとよいでしょう。タスクが実行されるとき、まず最初に<code>MDC.setContextMapValues()</code>メソッドを呼ぶようにするべきです。そうすると新しい<code>Executor</code>のスレッドに、元のMDCの値を関連付けることができます。
- </p>
-
- <h3 class="doAnchor" name="mis">MDCInsertingServletFilter</h3>
-
- <p>Webアプリケーションでは、受け付けたHTTPリクエストに関連するホスト名、リクエストURI、ユーザーエージェント文字列などがわかるようになっていると便利なのはよくご存知だと思います。<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/helpers/MDCInsertingServletFilter.html"><code>MDCInsertingServletFilter</code></a>はMDCに次のようなキーと値を設定します。
- </p>
-
- <table class="bodyTable">
- <tr>
- <th>キー</th>
- <th>値</th>
- </tr>
-
- <tr class="alt">
- <td><code>req.remoteHost</code></td>
- <td><a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/ServletRequest.html#getRemoteHost%28%29">getRemoteHost()</a>メソッドの返すホスト名</td>
- </tr>
-
- <tr>
- <td><code>req.xForwardedFor</code></td>
- <td><a href="http://en.wikipedia.org/wiki/X-Forwarded-For">"X-Forwarded-For"</a>ヘッダーの値</td>
- </tr>
-
- <tr class="alt">
- <td><code>req.requestURI</code></td>
- <td><a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletRequest.html#getRequestURI%28%29">getRequestURI()</a>メソッドの返すリクエストURI</td>
- </tr>
-
- <tr>
- <td><code>req.requestURL</code></td>
- <td><a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletRequest.html#getRequestURL%28%29">getRequestURL()</a>メソッドの返すリクエストURL</td>
- </tr>
-
- <tr class="alt">
- <td><code>req.queryString</code></td>
- <td><a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletRequest.html#getQueryString%28%29">getQueryString()</a>メソッドの返すクエリ文字列</td>
- </tr>
-
- <tr>
- <td><code>req.userAgent</code></td>
- <td>"User-Agent" ヘッダーの値</td>
- </tr>
-
- </table>
-
- <p><code>MDCInsertingServletFilter</code>を使用するには、Webアプリケーションの<em>web.xml</em>に次の設定を追加します。</p>
-
- <pre class="prettyprint source"><filter>
- <filter-name>MDCInsertingServletFilter</filter-name>
- <filter-class>
- ch.qos.logback.classic.helpers.MDCInsertingServletFilter
- </filter-class>
-</filter>
-<filter-mapping>
- <filter-name>MDCInsertingServletFilter</filter-name>
- <url-pattern>/*</url-pattern>
-</filter-mapping> </pre>
-
- <p><b>複数のフィルターを使用している場合、<code>MDCInsertingServletFilter</code>を他のフィルターより先に宣言するようにしてください。</b> たとえば、アプリケーションの主な処理がフィルター'F'で行われるとしたら、その前に<code>MDCInsertingServletFilter</code>を置かないと、MDCに設定される値を'F'から参照することはできません。
- </p>
-
- <p>フィルターを配置したら、上記のMDCのキーを%X変換指定子で使えるようになります。例えば、リモートホストとリクエストURIを一行に出したければ、次のような変換パターン文字列を指定すればよいでしょう。</p>
-
- <p class="source">%X{req.remoteHost} %X{req.requestURI}%n%d - %m%n</p>
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/manual/menu.js b/docs/manual/menu.js
index 7071c5a..972dcb7 100644
--- a/docs/manual/menu.js
+++ b/docs/manual/menu.js
@@ -15,17 +15,3 @@ document.write('<p class="menu"><a href="groovy.html"><b>Ch12: Groovy Configurat
document.write('<p class="menu"><a href="migrationFromLog4j.html"><b>Ch13: Migration from log4j</b></a></p>');
document.write('<p class="menu"><a href="receivers.html"><b>Ch14: Receivers</b></a></p>');
document.write('<p class="menu"><a href="usingSSL.html"><b>Ch15: Using SSL</b></a></p>');
-
-document.write('<p style="border: 1px solid #cccccc;"></p>');
-document.write('<p style="border: 1px solid #cccccc;"></p>');
-document.write('<p/>');
-document.write('<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>');
-//<!-- logback -->
-document.write('<ins class="adsbygoogle"');
-document.write(' style="display:block"');
-document.write(' data-ad-client="ca-pub-7471410671306824"');
-document.write(' data-ad-slot="6377851613"');
-document.write(' data-ad-format="auto"></ins>');
-document.write('<script>');
-document.write('(adsbygoogle = window.adsbygoogle || []).push({});');
-document.write('</script>');
\ No newline at end of file
diff --git a/docs/manual/menu_ja.js b/docs/manual/menu_ja.js
deleted file mode 100644
index 529072d..0000000
--- a/docs/manual/menu_ja.js
+++ /dev/null
@@ -1,16 +0,0 @@
-document.write('<p class="menu_header">目次</p>');
-document.write('<p class="menu"><a href="introduction_ja.html"><b>第1章 はじめに</b></a></p>');
-document.write('<p class="menu"><a href="architecture_ja.html"><b>第2章 アーキテクチャ</b></a></p>');
-document.write('<p class="menu"><a href="configuration_ja.html"><b>第3章 設定</b></a></p>');
-document.write('<p class="menu"><a href="appenders_ja.html"><b>第4章 アペンダー</b></a></p>');
-document.write('<p class="menu"><a href="encoders_ja.html"><b>第5章 エンコーダー</b></a></p></p>');
-document.write('<p class="menu"><a href="layouts_ja.html"><b>第6章 レイアウト</b></a></p>');
-document.write('<p class="menu"><a href="filters_ja.html"><b>第7章 フィルター</b></a></p>');
-document.write('<p class="menu"><a href="mdc_ja.html"><b>第8章 診断コンテキスト(MDC)</b></a></p>');
-document.write('<p class="menu"><a href="loggingSeparation_ja.html"><b>第9章 ログの分離</b></a></p>');
-document.write('<p class="menu"><a href="jmxConfig_ja.html"><b>第10章 JMXコンフィギュレーター</b></a></p>');
-document.write('<p class="menu"><a href="onJoran_ja.html"><b>第11章 Joran</b></a></p>');
-document.write('<p class="menu"><a href="groovy_ja.html"><b>第12章 Groovyによる設定</b></a></p>');
-document.write('<p class="menu"><a href="migrationFromLog4j_ja.html"><b>第13章 log4jから移行する</b></a></p>');
-document.write('<p class="menu"><a href="receivers_ja.html"><b>第14章 レシーバー</b></a></p>');
-document.write('<p class="menu"><a href="usingSSL_ja.html"><b>第15章 SSLを使用する</b></a></p>');
diff --git a/docs/manual/migrationFromLog4j.html b/docs/manual/migrationFromLog4j.html
index 4b05556..96fef84 100644
--- a/docs/manual/migrationFromLog4j.html
+++ b/docs/manual/migrationFromLog4j.html
@@ -28,8 +28,6 @@
<h1>Chapter 13: Migration from log4j</h1>
- <a href="migrationFromLog4j_ja.html">和訳 (Japanese translation)</a>
-
<div class="quote">
<p><em>The more things change, the more they remain the
same. </em></p>
diff --git a/docs/manual/migrationFromLog4j_ja.html b/docs/manual/migrationFromLog4j_ja.html
deleted file mode 100644
index 5226e0e..0000000
--- a/docs/manual/migrationFromLog4j_ja.html
+++ /dev/null
@@ -1,157 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第13章 log4jからの移行</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第13章 log4jからの移行</h1>
-
- <div class="quote">
- <p><em>多くのものが変化し、多くのものがそのままである。</em></p>
-
- <p>—ALPHONSE KARR, <em>Les Guêpes</em></p>
- </div>
-
- <p>本章ではカスタマイズされたlog4jのコンポーネントのアペンダーやレイアウトをlogback-classicに移行する方法について議論します。
- </p>
-
- <p>log4j のクライアントAPIとして<code>org.apache.log4j</code>パッケージの<code>Logger</code>や<code>Category</code>を使っているだけなら、SLF4Jの<a href="http://www.slf4j.org/migrator.html">SLF4J移行ツール</a>で自動的に移行することができます。<em>log4j.properties</em>から同じ内容のlogback.xmlを作るには、<a href="http://logback.qos.ch/translator/">log4j.properties トランスレーター</a>が使えます。
- </p>
-
- <p>広い観点から見ると、log4jとlogback-classicは密接に関連し合っています。ロガーやアペンダー、レイアウトといった基本的なコンポーネントはどちらのフレームワークにもありますし、目的も同じです。同様に、どちらのフレームワークにも一番重要な内部データ構造として<code>LoggingEvent</code>がありますが、実装まで完全に同じわけではありません。一番の違いは、logback-classic の<code>LoggingEvent</code>は<code>ILoggingEvent</code>インターフェイスを実装しているところです。log4jのコンポーネントをlogback-classicに移行するために必要な変更のほとんどは、<code>LoggingEvent</code>の実装の差異を埋めることに費やされます。差異があるといってもその範囲は限られているので安心してください。出来る限りの努力をしたにも関わらず移行がうまくいかなかったら、<a href="http://logback.qos.ch/mailinglist.ht [...]
- </p>
-
-
- <h3 class="doAnchor" name="log4jLayout">log4jのレイアウトを移行する</h3>
-
- <p>さあ移行してみましょう。対象はlog4j の単純なレイアウト<a href="http://logback.qos.ch/xref/chapters/migrationFromLog4j/TrivialLog4jLayout.html">TrivialLog4jLayout</a>ということにします。これはロギングイベントのメッセージを指定された書式で書式化した文字列を返すものです。コードを見てください。
- </p>
-
-
- <pre class="prettyprint source">package chapters.migrationFromLog4j;
-
-import org.apache.log4j.Layout;
-import org.apache.log4j.spi.LoggingEvent;
-
-public class TrivialLog4jLayout extends Layout {
-
- public void activateOptions() {
- // there are no options to activate
- }
-
- public String format(LoggingEvent loggingEvent) {
- return loggingEvent.getRenderedMessage();
- }
-
- public boolean ignoresThrowable() {
- return true;
- }
-}</pre>
-
- <p>logback-classicで等価なレイアウト<a href="http://logback.qos.ch/xref/chapters/migrationFromLog4j/TrivialLogbackLayout.html">TrivialLogbackLayout</a>は次のようになります。</p>
-
- <pre class="prettyprint source">package chapters.migrationFromLog4j;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.LayoutBase;
-
-public class TrivialLogbackLayout extends <b>LayoutBase<ILoggingEvent></b> {
-
- public String <b>doLayout</b>(ILoggingEvent loggingEvent) {
- return loggingEvent.getMessage();
- }
-} </pre>
-
- <p>ご覧のように、文字列を書式化するメソッドはlog4jでは<code>format()</code>でしたが、logback-classic では<code>doLayout()</code>なのです。また、logback-classic には<code>ignoresThrowable()</code>に相当するメソッドはありません。logback-classicのレイアウトは<code>LayoutBase<ILoggingEvent></code>を継承しなければならないので気をつけてください。
- </p>
-
- <p><code>activateOptions()</code>メソッドの効果については大いに議論の余地があります。log4jでは、log4j configurator(<code>PropertyConfigurator</code>あるいは<code>DOMConfiguration</code>) から、レイアウトの全てのオプションが設定された後に<code>activateOptions()</code>メソッドが呼ばれるようになっています。したがって、レイアウトには自分に指定されたオプションの整合性をチェックするタイミングが無いので、全て自分で賄わなければなりません。</p>
-
-
- <p>logback-classic では、レイアウトは<a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/LifeCycle.html">LifeCycle</a>インターフェイスを実装しなければなりません。このインターフェイスには<code>start()</code>メソッドがあります。この<code>start()</code>メソッドは、log4jの<code>activateOptions()</code>メソッドとほぼ同様の役割を果たします。
- </p>
-
- <h3 class="doAnchor" name="log4jAppender">log4jのアペンダーを移行する</h3>
-
- <p>アペンダーの移行は、レイアウトの移行とほとんど同じです。単純なアペンダー<a href="http://logback.qos.ch/xref/chapters/migrationFromLog4j/TrivialLog4jAppender.html">TrivialLog4jAppender</a>を移行することを考えてみましょう。このアペンダーはレイアウトの返す文字列をコンソールに出力するだけのものです。</p>
-
- <pre class="prettyprint source">package chapters.migrationFromLog4j;
-
-import org.apache.log4j.AppenderSkeleton;
-import org.apache.log4j.spi.LoggingEvent;
-
-
-public class TrivialLog4jAppender extends AppenderSkeleton {
-
- protected void append(LoggingEvent loggingevent) {
- String s = this.layout.format(loggingevent);
- System.out.println(s);
- }
-
- public void close() {
- // nothing to do
- }
-
- public boolean requiresLayout() {
- return true;
- }
-}</pre>
-
- <p>logback-classicで等価なアペンダー<a href="http://logback.qos.ch/xref/chapters/migrationFromLog4j/TrivialLogbackAppender.html">TrivialLogbackAppender</a>は次のようになります。</p>
-
-
- <pre class="prettyprint source">package chapters.migrationFromLog4j;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.AppenderBase;
-
-public class TrivialLogbackAppender extends AppenderBase<ILoggingEvent> {
-
- @Override
- public void start() {
- if (this.layout == null) {
- addError("No layout set for the appender named [" + name + "].");
- return;
- }
- super.start();
- }
-
- @Override
- protected void append(ILoggingEvent loggingevent) {
- // note that AppenderBase.doAppend will invoke this method only if
- // this appender was successfully started.
-
- String s = this.layout.doLayout(loggingevent);
- System.out.println(s);
- }
-}</pre>
-
-
- <p>コードを比べてみると分かるのですが、<code>append()</code>メソッドはそのままです。logbackでは<code>requiresLayout()</code>メソッドを使用しないので、これは削除できます。logbackの<code>stop()</code>メソッドは、log4jの<code>close()</code>メソッドと同じ意味です。logback-classicの<code>AppenderBase</code>には何もしない<code>stop()</code>メソッドの実装があるので、今回のように単純なアペンダーならそれで十分でしょう。
- </p>
-
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/manual/onJoran.html b/docs/manual/onJoran.html
index 4805cb8..3231b48 100644
--- a/docs/manual/onJoran.html
+++ b/docs/manual/onJoran.html
@@ -28,8 +28,6 @@
<h1>Chapter 11: Joran</h1>
- <a href="onJoran_ja.html">和訳 (Japanese translation)</a>
-
<div class="quote">
<p><em>The answer, my friend, is blowin' in the wind, The answer
is blowin' in the wind.</em></p>
@@ -67,7 +65,7 @@
<p>To install Joran, simply <a
href="../download.html">download</a> logback and add
- <em>logback-core-1.1.9.jar</em> to your
+ <em>logback-core-1.1.2.jar</em> to your
classpath.</p>
<h2 class="doAnchor">Historical perspective</h2>
@@ -186,10 +184,9 @@
<pre class="prettyprint source">package ch.qos.logback.core.joran.action;
import org.xml.sax.Attributes;
-import org.xml.sax.Locator;
-import ch.qos.logback.core.joran.spi.InterpretationContext;
+import ch.qos.logback.core.joran.spi.ExecutionContext;
-public abstract class Action extends ContextAwareBase {
+public abstract class Action {
/**
* Called when the parser encounters an element matching a
* {@link ch.qos.logback.core.joran.spi.Pattern Pattern}.
diff --git a/docs/manual/onJoran_ja.html b/docs/manual/onJoran_ja.html
deleted file mode 100644
index 6712fff..0000000
--- a/docs/manual/onJoran_ja.html
+++ /dev/null
@@ -1,433 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第11章 Joran</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第11章 Joran</h1>
-
- <div class="quote">
- <p><em>答えは風に吹かれている。答えは風に吹かれている。</em></p>
-
- <p>—BOB DYLAN, <em>The Freewheelin' Bob Dylan</em></p>
- </div>
-
- <p>Joranとは、ジュネーブ湖で一年中吹きすさんでいる冷たい北西風のことです。ジュネーブ湖は西ヨーロッパの中央からやや右側にある湖で、ヨーロッパにいくつもある他の湖と比べるとずっと狭い湖です。しかし、平均水深は153メートルと非常に深く、西ヨーロッパ最大の淡水湖として知られています。
- </p>
-
-
- <p>これまでの章で説明したように、logbackはJoran設定フレームワークの成熟した、柔軟で、強力な機能を頼りにしています。logbackのモジュールが提供する機能の大部分は、Joran無しでは実現できません。この章では、Joranの設計の根幹部分と、顕著な特徴に焦点を当てていきます。
- </p>
-
- <p>Joranはロギングとは完全に無関係な、汎用設定システムです。この点を明らかにするため、logback-coreモジュールにはロガーに関わる要素が一切存在しないことに触れておかなければなりません。また、本章に登場するほとんどの例に、ロガーもアペンダーもレイアウトも出てこないこともそれを後押ししています。
- </p>
-
- <p>この章で使っている例は<em>LOGBACK_HOME/logback-examples/src/main/java/chapters/onJoran</em>に配置されています。
- </p>
-
- <p>Joranのインストールは簡単です。<a href="http://logback.qos.ch/download.html">logbackをダウンロード</a>して、クラスパスに<em>logback-core-1.1.2.jar</em>を追加するだけです。</p>
-
- <h2 class="doAnchor">歴史的な観点</h2>
-
- <p>リフレクションは、宣言的にソフトウェアシステムを設定できるようにしてくれる、Java言語の強力な機能です。たとえば、EJBの重要なプロパティの多くは<em>ejb.xml</em>で設定します。EJBがJavaで実装されているとしても、それらのプロパティのほとんどが<em>ejb.xml</em>で指定されるのです。同じように、logbackの設定もXML形式の設定ファイルで指定します。JDK1.5から導入されたアノテーションは、以前ならXMLで設定されていたものを置き換えるためにEJB3.0で多用されています。Joranもアノテーションは利用しますが、ほんの少しだけです。EJBに比べてlogbackの設定には動的な要素が多いので、Joranでアノテーションを活用できる範囲が限られてしまうのです。
- </p>
-
- <p>logbackの前身のlog4jでは、<code>DOMConfigurator</code>(log4j1.2.x以降に含まれています)がXML形式の設定ファイルをパースするために使われていました。<code>DOMConfigurator</code>は、設定ファイルの構造を変えるたびに、コードを微調整しなければならない作りになっていました。修正したコードは、再コンパイルして再デプロイしなければなりません。同じくらい重要なのが、<code>DOMConfigurator</code>のコードは、たくさんのまばらなif/else文を含む子要素をループするような作りになっていたことです。たいして役に立ちませんでしたし、冗長であちこちに重複があるコードでした。このとき、<a href="http://jakarta.apache.org/commons/digester/">Apace commons-digester</a>ではパターンマッチ規則に基づいたXMLのパースができていました。digesterは、パース時に指定したパターンにマッチしたら、こちらも [...]
- </p>
-
- <p>私たちは<code>DOMConfigurator</code>の経験を武器にしてlogbackで使うための設定フレームワーク<code>Joran</code>の開発を始めました。Joranはcommons-digesterに強く影響を受けています。にもかかわらず、使っている用語が若干異なります。たとえば、commons-digester だとルールとパターンは一緒に使うものでした。Digesterの<code>addRule(String pattern, Rule rule)</code>メソッドがいい例です。私たちは、ルールがルールによって構成されている(再帰的という意味ではなく別の意味で)と、不必要な混乱を招くことに気づきました。そこで、Joranではルールがパターンとアクションで構成されるものとしました。アクションとは、対応するパターンがマッチしたときに行われる操作です。パターンとアクションの関係が、Joranの中核を為していると言ってもおかしくありません。それが顕著にあらわれているのが、単純なパターンを使って非常に複雑な要件を満たすことができ [...]
- </p>
-
- <h3 class="doAnchor" name="saxOrDom">SAXかDOMか</h3>
-
- <p>SAXのAPIはイベントベースのアーキテクチャなので、SAXをベースにしたツールで前方参照を扱うのは決して簡単なことではありません。前方参照とは、現在の要素よりも後で定義される要素を参照することです。同様に循環参照も手強い相手です。一般的な話ですが、DOM APIなら全要素を検索対象にできるし、前方の要素にジャンプすることもできるのです。
- </p>
-
- <p>こういった柔軟性についてのあれこれを鑑みて、Joranでは当初DOM APIを使ってパースしていました。試行錯誤の後、パターンとアクションの形式で表現されたルールを解釈する上で、DOMツリーをパースしてる途中で離れた要素にジャンプできても意味が無いことが明らかになりました。<em>Joranに必要だったのは、XMLドキュメントの要素を、深さ優先で逐次的に走査していくことだけだったのです。</em>
- </p>
-
- <p>また、SAX APIには要素の位置を取得するものがあったので、Joranは問題のあった行番号と列番号を表示できるようにもなりました。位置情報があれば、パースエラーの起きている場所を簡単に特定することができます。
- </p>
-
- <h3>対象外事項</h3>
-
- <p>高度な可変性を求められていることもあり、JoranのAPIは数千要素にもなる巨大なXMLドキュメントを扱うようには設計されていません。
- </p>
-
-
- <h3 class="doAnchor" name="pattern">パターン</h3>
-
- <p>Joranのパターンとは基本的に文字列です。<em>正確なパターン</em>と<em>ワイルドカードパターン</em>の2種類があります。パターン"a/b" は、最上位要素<code>a</code>にネストされた要素<code>b</code>にマッチします。他の要素にはマッチしないことから、これは<em>正確なパターン</em>だと言えます。</p>
-
- <p>ワイルドカードは、接尾辞または接頭辞をマッチさせるときに使われます。たとえばパターン"*/a" は接尾辞が"a"であるものすべてにマッチします。つまり、XMLドキュメント中で要素<code>a</code>をネストしているあらゆる要素がマッチするのです。パターン"a/*"は接頭辞が"a"なので、要素<code>a</code>がネストしているあらゆる要素がマッチすることになります。
- </p>
-
- <h3 class="doAnchor" name="action">アクション</h3>
-
- <p>前に述べたように、Joranはパターンに関連付けられたルールをパースします。アクションは、<a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/action/Action.html"><code>Action</code></a>クラスを継承したもので、次のような抽象メソッドで肉付けします。他のメソッドは簡潔にするために省略されています。
- </p>
-
-
- <pre class="prettyprint source">package ch.qos.logback.core.joran.action;
-
-import org.xml.sax.Attributes;
-import ch.qos.logback.core.joran.spi.ExecutionContext;
-
-public abstract class Action {
- /**
- * Called when the parser encounters an element matching a
- * {@link ch.qos.logback.core.joran.spi.Pattern Pattern}.
- */
- public abstract void begin(InterpretationContext ic, String name,
- Attributes attributes) throws ActionException;
-
- /**
- * Called to pass the body (as text) contained within an element.
- */
- public void body(InterpretationContext ic, String body)
- throws ActionException {
- // NOP
- }
-
- /*
- * Called when the parser encounters an endElement event matching a
- * {@link ch.qos.logback.core.joran.spi.Pattern Pattern}.
- */
- public abstract void end(InterpretationContext ic, String name)
- throws ActionException;
-}</pre>
-
- <p>ごらんのように、アクションは<code>begin()</code>メソッドと<code>end()</code>メソッドを実装しなければなりません。<code>body()</code>メソッドを実装するかどうかは選択可能ですが。<code>Action</code>クラスは空実装を提供しているからです。</p>
-
-
- <h3 class="doAnchor" name="ruleStore">RuleStore</h3>
-
- <p>前述のように、パターンマッチと関連するアクションの実行がJoranの中心的な考え方です。ルールはパターンとアクションを関連付けるものです。そして<a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/spi/RuleStore.html">RuleStore</a>に保存されます。
- </p>
-
- <p>前述したとり、JoranはSAX APIを使っています。SAX APIとは、XMLドキュメントのそれぞれの要素についてstart/body/endというイベントを生成しながらパースを進めていくものです。Joranコンフィギュレーターは、イベントを受け付けると<em>今のパターン</em>に対応したアクションをルールストアから探してきます。たとえば、最上位要素<em>A</em>にネストされた要素<em>B</em>のstart/body/endイベントなら、今のパターンとは"A/B"になります。今のパターンとは、JoranがSAXイベントを受け付けながら自動的に調整するデータ構造なのです。</p>
-
- <p>今のパターンにいくつかのルールがマッチするときは、正確なマッチが接尾辞マッチより優先されます。そして接尾辞マッチは接頭辞マッチより優先されます。実装の詳細については<a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/spi/SimpleRuleStore.html">SimpleRuleStoreの</a>を参照してください。
- </p>
-
-
- <h3 class="doAnchor" name="interpretationContext">解釈コンテキスト</h3>
-
- <p>いろいろなアクションが協調して動作させるため、beginメソッドとendメソッドの一つ目の引数に解釈コンテキストが渡されます。解釈コンテキストには、オブジェクトスタック、オブジェクトマップ、エラーリスト、アクションを呼び出したJoranインタプリタへの参照が含まれています。解釈コンテキストの完全なフィールドが知りたければ<a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/spi/InterpretationContext.html"><code>InterpretationContext</code></a>を見てください。
- </p>
-
- <p>アクションは、共通のオブジェクトスタックに対するフェッチ、プッシュ、ポップといった操作や、共通のオブジェクトマップに対してキーと共にオブジェクトをプットしたりフェッチしたりすることで、他のアクションと共同作業をすることができます。また、解釈コンテキストの<code>StatusManager</code>にエラーを追加することで、問題が起きたことを報告することができます。
- </p>
-
- <h3 class="doAnchor" name="helloWorld">こんにちは</h3>
-
- <p>最初に、Joranを使うために必要最低限の構成を見てもらいます。<code><a href="http://logback.qos.ch/xref/chapters/onJoran/helloWorld/HelloWorldAction.html">HelloWorldAction</a></code>は、<code>begin()</code>でコンソールに"Hello World"と出力するだけの小さなアクションです。XMLファイルはコンフィギュレーターでパースします。この章の説明用に、非常に小さくて単純な<a href="http://logback.qos.ch/xref/chapters/onJoran/SimpleConfigurator.html"><code>SimpleConfigurator</code></a>というコンフィギュレーターを用意しました。<a href="http://logback.qos.ch/xref/chapters/onJoran/helloWorld/HelloWorld.html"><code>HelloWo [...]
-
- <ul>
- <li>ルールマップと<code>Context</code>を用意します</li>
- <li><code>HelloWorldAction</code>と<em>hello-world</em>パターンを関連付けて、パースルールを用意します</li>
- <li><code>SimpleConfigutator</code>を用意して、ルールマップを渡します</li>
- <li>XMLファイルを引数として、コンフィギュレーターの<code>doConfigure()</code>メソッドを呼び出します</li>
- <li>最後に、もしあれば解釈コンテキストに蓄積されたステータスメッセージを出力します</li>
- </ul>
-
- <p><em>hello.xml</em>には何もネストしていない1つのhello-world要素があります。<em>logback-examples/src/main/java/chapters/onJoran/helloWorld/</em>フォルダを参照してください。
- </p>
-
- <p><em>hello.xml</em>ファイルを指定してHelloWorldアプリケーションを実行すると、コンソールに"Hello World"と出力します。</p>
-
- <p class="command">java chapters.onJoran.helloWorld.HelloWorld src/main/java/chapters/onJoran/helloWorld/hello.xml</p>
-
- <p>ルールストアに新しいルールを追加したり、XMLドキュメントを変更してみたり、新しいアクションを追加するなど、いろいろと試してみたくなったでしょう?
- </p>
-
- <!-- ====================================================== -->
-
- <h3 class="doAnchor" name="calculator">アクションの協調</h3>
-
- <p>共通のオブジェクトスタックを通じて協調して簡単な計算をするアクションが、<em>logback-examples/src/main/java/joran/calculator/</em>ディレクトリに入っています。
- </p>
-
- <p><em>calculator1.xml</em>を見ると、<code>literal要素</code>をネストした<code>computation要素</code>があるので見てみましょう。
- </p>
-
- <p class="example">例10:Calculatorの設定例(<a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/calculator1.xml">logback-examples/src/main/java/chapters/onJoran/calculator/calculator1.xml</a>)</p>
-
- <pre class="prettyprint source"><computation name="total">
- <literal value="3"/>
-</computation></pre>
-
- <p><code><a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/Calculator1.html">Calculator1</a></code>アプリケーションでは、さまざまな解析ルール(パターンとアクション)を宣言しています。これらはXMLドキュメントの内容に基づき、協調して結果を算出するものです。
- </p>
-
- <p><em>calculator1.xml</em>を指定して<code>Calculator1</code>を実行してみましょう。</p>
-
- <p class="command">java chapters.onJoran.calculator.Calculator1 src/main/java/chapters/onJoran/calculator/calculator1.xml</p>
-
- <p>次のように出力されます。</p>
-
- <p class="console">The computation named [total] resulted in the value 3</p>
-
-
- <p>上記の<em>calculator1.xml</em>は次のように解釈されます。</p>
-
- <ul>
- <li>computation要素のstartイベントが、"/computation" パターンとみなされます。<code><a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/Calculator1.html">Calculator1</a></code>アプリケーションは"/computation"パターンと<a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/ComputationAction1.html"><code>ComputationAction1</code></a>を関連付けています。ですので、<code>ComputationAction1</code>のインスタンスの<code>begin()</code>メソッドが実行されます。
- </li>
-
- <li><p>literal要素のstartイベントが、"/computation/literal" パターンとみなされます。"/computation/literal" パターンは<code><a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/LiteralAction.html">LiteralAction</a></code>と関連付けられています。ですので、<code>LiteralAction</code>のインスタンスの<code>begin()</code>メソッドが実行されます。</p>
- </li>
-
- <li><p>また、literal要素のendイベントより、<code>LiteralAction</code>のインスタンスの<code>end()</code>メソッドを実行されます。</p>
- </li>
-
-
- <li><p>同様に、computation要素のendイベントより、<code>ComputationAction1</code>のインスタンスの<code>end()</code>メソッドが実行されます。
- </p>
- </li>
- </ul>
-
- <p>ここで注目して欲しいのは、アクションがどのように協調しているのかということです。<code>LiteralAction</code>は設定ファイルからリテラル値を読み取り、<code>InterpretationContext</code>の保持しているオブジェクトスタックに登録します。オブジェクトスタックに登録された値は、他のアクションから読み書きすることができるようになります。ここでは、 <code>ComputationAction1</code>の<code>end()</code>メソッドが、オブジェクトスタックから値をポップして、出力しています。
- </p>
-
- <!-- TO BE CONTINUED -->
-
- <p>次に<em>calculator2.xml</em>を見てみましょう。前の例よりも少し複雑で、面白いことをしています。</p>
-
- <p class="example">例10:Calculatorの設定例(<a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/calculator2.xml">logback-examples/src/main/java/chapters/onJoran/calculator/calculator2.xml</a>)</p>
-
- <pre class="prettyprint source"><computation name="toto">
- <literal value="7"/>
- <literal value="3"/>
- <add/>
- <literal value="3"/>
- <multiply/>
-</computation></pre>
-
-
- <p>前の例と同じく、literal要素に対応する<code><a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/LiteralAction.html">LiteralAction</a></code>は、解釈コンテキストのオブジェクトスタックに整数値を登録します。ここ(<em>calculator2.xml</em>)ではまず7と3が登録されています。add要素には<a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/AddAction.html"><code>AddAction</code></a>が関連付けられています。これはオブジェクトスタックから二回整数値をポップして、それらを加算した結果をオブジェクトスタックにプッシュするものです。次のliteral要素に対応するLiteralActionは、オブジェクトスタックの一番上に整数値3をプッシュします。multiply要素には<a href="http://lo [...]
-
- <p class="command">java chapters.onJoran.calculator.Calculator1 src/main/java/chapters/onJoran/calculator/calculator2.xml </p>
-
- <p>そうすると、次のように出力されます。</p>
-
- <p class="console">The computation named [toto] resulted in the value 30 </p>
-
-
- <!--
-
-
- <p>Finally, a <em>calculator3.xml</em> is also provided, to
- demonstrate the possibility elements that contain instances of the
- same element. Here's the content of <em>calculator3.xml</em>:</p>
-
- <em>Example 10.<span class="autoEx"/>: Calculator configuration file
- (logback-examples/src/main/java/chapters/onJoran/calculator/calculator3.xml)</em>
-
-<pre class="prettyprint source"><computation name="toto">
- <computation>
- <literal value="7"/>
- <literal value="3"/>
- <add/>
- </computation>
-
- <literal value="3"/>
- <multiply/>
-</computation></pre>
-
- <p>Much like the use of parentheses in an algebrical equation, the
- presence of a <code>computation</code> element nested in another is
- managed by the <a
- href="../xref/chapters/onJoran/calculator/ComputationAction2.html">
- <code>ComputationAction2</code></a> class using an internal
- stack. The well-formedness of XML will guarantee that a value saved
- by one <code>begin()</code> will be consumed only by the matching
- <code>end()</code> method.</p>
- -->
-
- <h3 class="doAnchor" name="implicit">暗黙的なアクション</h3>
-
- <p>ここまでに紹介してきたルールの定義は明示的なアクションと呼ばれます。現在のxml要素に対応するパターンとアクションのペアを、ルールストアから1つだけ取り出すことができるからです。しかし、高度な拡張性を備えたシステムにおいて、コンポーネントの種類は膨大な数になります。それゆえに、すべてのパターンに明示的なアクションを関連付けるのはとても面倒なことになるのです。
- </p>
-
- <p>そうは言っても、高度な拡張性を備えたシステムなら、ルールに付随するコンポーネントそれぞれに結びついたルールを、循環して見つけることができます。そのようにルールを発見できるとすると、logbackの設定ファイルをパースする時点では未知のコンポーネントが含まれるコンポーネントを扱うことができるようになります。たとえば、Apacne Ant では、<code>addFile</code>や<code>addClassPath</code>といったコンポーネントを発見するメソッドを使うことで、設定ファイルをパースする時点では未知のタグを含んだタスクを扱えるようになっています。Antはタスクの処理中に未知のタグを発見すると、タグ名に基づいたクラスのオブジェクトを生成し、タスクの実装クラスに宣言されているaddXメソッドを呼び出して、親のオブジェクトに登録します。
- </p>
-
- <p>Joranは暗黙的なアクションとして同じような機能を実現しています。現在のパターンが明示的なアクションにマッチしなかった時のために、暗黙的なアクションの一覧を保持するようになっています。しかし、暗黙的なアクションを適用することが必ずしも適切ではない場合があります。そこで、Joranは暗黙的なアクションを実行する前に、現在の状況が妥当であるかどうかを確認するようになっています。Joranからの確認に対して、これから実行されようとするアクションが肯定を返すときだけ、アクションを呼び出します。この例外対応によって、複数の暗黙的なアクションを備えつつ、適切なアクションが無ければ何もしないことの両方のケースに対応できるのです。
- </p>
-
- <p>暗黙的なアクションの作成例が<em>logback-examples/src/main/java/chapters/onJoran/implicit</em>にあります。
- </p>
-
- <p><a href="http://logback.qos.ch/xref/chapters/onJoran/implicit/PrintMe.html"><code>PrintMe</code></a>アプリケーションでは、"/*/foo" パターンと<a href="http://logback.qos.ch/xref/chapters/onJoran/implicit/NOPAction.html"><code>NOPAction</code></a>アクションを関連付けています。このパターンは任意のfoo要素にマッチします。<code>NOPAction</code>の<code>begin()</code>メソッドと<code>end()</code>メソッドは、名前のとおり空っぽです。<code>PrintMe</code>アプリケーションは、暗黙的なアクションの一覧に<a href="http://logback.qos.ch/xref/chapters/onJoran/implicit/PrintMeImplicitAction.html">Pri [...]
- </p>
-
- <p>暗黙的なアクションがどのように振る舞うのか、<em>implicit1.xml</em>で試してみましょう。</p>
-
- <p class="example">例10: 暗黙的なルールの使い方(<a href="http://logback.qos.ch/xref/chapters/onJoran/implicit/implicit1.xml">logback-examples/src/main/java/chapters/onJoran/implicit/implicit1.xml</a>)</p>
-
- <pre class="prettyprint source"><foo>
- <xyz printme="true">
- <abc printme="true"/>
- </xyz>
-
- <xyz/>
-
- <foo printme="true"/>
-
-</foo></pre>
-
- <p>実行してみましょう。</p>
-
- <p class="command">java chapters.onJoran.implicit.PrintMe src/main/java/chapters/onJoran/implicit/implicit1.xml</p>
- <p>次のように出力されます。</p>
-
- <p class="console">Element [xyz] asked to be printed.
-Element [abc] asked to be printed.
-20:33:43,750 |-ERROR in c.q.l.c.joran.spi.Interpreter@<b>10:9</b> - no applicable action for [xyz], current pattern is [[foo][xyz]]</p>
-
- <p><code>NOPAction</code>が"*/foo"パターンに関連付けられているので、foo要素について<code>NOPAction</code>の<code>begin()</code>メソッドと<code>end()</code>メソッドが実行されているはずです。そのため、foo要素については<code>PrintMeImplicitAction</code>は呼び出されないのです。他の明示的なアクションがマッチしない要素について、<code>PrintMeImplicitAction{\0}の<code>isApplicable()</code></code>メソッドが呼び出されます。isApplicable()メソッドは、<span class="attr">printme属性</span>にtrueが指定されている場合にだけtrueを返します。したがって、最初のxyz要素とabc要素についてはtrueを返します。10行目の二つ目のxyz要素には適用可能なアクションがないので、内部エラーメッセージが出力されます。エラーメッセージは<code> [...]
- </p>
-
- <h3 class="doAnchor" name="iaPractice">暗黙的なアクションの実装</h3>
-
- <p>logback-classic モジュールと logback-access モジュールのそれぞれの Joran コンフィギュレーターには、暗黙的なアクションが2つだけ含まれています。<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/action/NestedBasicPropertyIA.html">NestedBasicPropertyIA</a></code>と<a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.html"><code>NestedComplexPropertyIA</code></a>です。</p>
-
- <p><code>NestedBasicPropertyIA</code>は、プリミティブ型あるいはそのラッパークラス、列挙型、"valueOf" 規約に則った任意のクラスのプロパティに適用可能なアクションです。このアクションが適用可能なプロパティは<em>基本型</em>あるいは<em>単純型</em>と呼ばれています。"valueOf" 規約に則るというのは、<code>java.lang.String</code>を引数とする静的メソッド<code>valueOf()</code>によってインスタンス化できる、ということです。<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/Level.html"><code>Level</code></a>や<a href="http://logback.qos.ch/xref/ch/qos/logback/core/util/Duration.html"><code>Duration</code></a>、<a href="http://logback.q [...]
- </p>
-
- <p><code>NestedComplexPropertyIA</code>は、<code>NestedBasicPropertyIA</code>が適用できない場合に、<em>かつ</em>、オブジェクトスタックの一番上のオブジェクトに、現在の要素名に対応するセッターあるいはアダーメソッドがある場合に適用可能なアクションです。このアクションが適用可能なプロパティは、更に他のコンポーネントを内包することがあるので注意しましょう。このアクションが適用可能なプロパティは<em>複雑型</em>と呼ばれています。<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.html">NestedComplexPropertyIA</a></code>が複雑型のプロパティを見つけると、ネストされたコンポーネントに対応する適切なクラスをインスタンス化して、親のコンポーネント(オブジェクトスタックの一番上のオブジェクト)に設定します。<sp [...]
-
- <ol>
- <li>親のオブジェクトのプロパティのクラスを決定する内部的なルールに基づいて決められたクラス名</li>
- <li>セッターメソッドの@DefaultClassアノテーションに指定あされ</li>
-
- <li>セッターメソッドの引数が公開コンストラクタを持つ具象クラスならそのクラス名</li>
- </ol>
-
- <h4 class="doAnchor" name="defaultClassMapping">デフォルトのクラスマッピング</h4>
-
- <p>logback-classic では、親のクラスとプロパティ名に対応するデフォルトのクラスを規定した内部的なルールがあります。表にまとめました。</p>
-
- <table class="bodyTable">
- <tr>
- <th>親クラス</th>
- <th>プロパティ名</th>
- <th>ネストするコンポーネントのデフォルトクラス</th>
- </tr>
-
- <tr>
- <td>ch.qos.logback.core.AppenderBase</td>
- <td>encoder</td>
- <td>ch.qos.logback.classic.encoder.PatternLayoutEncoder</td>
- </tr>
-
- <tr class="alt">
- <td>ch.qos.logback.core.UnsynchronizedAppenderBase</td>
- <td>encoder</td>
- <td>ch.qos.logback.classic.encoder.PatternLayoutEncoder</td>
- </tr>
-
- <tr>
- <td>ch.qos.logback.core.AppenderBase</td>
- <td>layout</td>
- <td>ch.qos.logback.classic.PatternLayout</td>
- </tr>
-
- <tr class="alt">
- <td>ch.qos.logback.core.UnsynchronizedAppenderBase</td>
- <td>layout</td>
- <td>ch.qos.logback.classic.PatternLayout</td>
- </tr>
-
- <tr>
- <td>ch.qos.logback.core.filter.EvaluatorFilter</td>
- <td>evaluator</td>
- <td>ch.qos.logback.classic.boolex.JaninoEventEvaluator</td>
- </tr>
- </table>
-
- <p>これらは将来的に変更されるかもしれません。最新のルールについては、logback-classic モジュールの<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/joran/JoranConfigurator.html">JoranConfigurator</a>の<code>addDefaultNestedComponentRegistryRules()</code>メソッドを参照してください。
- </p>
-
- <p>logback-accessモジュールのルールも似たようなものです。ネストするコンポーネントのデフォルトクラスについては、パッケージ名を ch.qos.logback.classic から ch.qos.logback.access に読み替えてください。最新のルールについては、logback-access モジュールの<a href="http://logback.qos.ch/xref/ch/qos/logback/access/joran/JoranConfigurator.html">JoranConfigurator</a>の<code>addDefaultNestedComponentRegistryRules()</code>メソッドを参照してください。
-
- </p>
-
- <h4 class="doAnchor">コレクション型のプロパティ</h4>
-
-
- <p>logbackの暗黙的なアクションは、単独の基本型プロパティ、複雑型プロパティに加えて、コレクション型のプロパティにも対応しています。ただし、セッターメソッドの代わりに、アダーメソッドを用意する必要があります。</p>
-
- <h3 class="doAnchor" name="newRule">その場で新しいルールを定義する</h3>
-
- <p>Joranには、XMLドキュメントを解釈している途中でも、Joranコンフィギュレーターに新しいルールを教えるためのアクションが含まれています。サンプルコードが<em>logback-examples/src/main/java/chapters/onJoran/newRule</em>ディレクトリにあります。<code><a href="http://logback.qos.ch/xref/chapters/onJoran/newRule/NewRuleCalculator.html">NewRuleCalculator</a></code>アプリケーションは、二つのルールを定義しています。1つは最上位要素を処理するためのもので、二つ目は動的に新しいルールを定義するためのものです。<code>NewRuleCalculator</code>の関連するコードをピックアップしました。
- </p>
-
- <pre class="prettyprint source">ruleMap.put(new Pattern("*/computation"), new ComputationAction1());
-<b>ruleStore.addRule(new Pattern("/computation/newRule"), new NewRuleAction());</b></pre>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/action/NewRuleAction.html"><code>NewRuleAction</code></a>はlogback-coreの一部で、他のアクションと同じように動作します。パーサーが<em>newRule要素</em>を見つけるたびに、このアクションの<code>begin()</code>メソッドと<code>end()</code>メソッドが呼び出されます。<code>begin()</code>メソッドは、 <em>pattern属性</em>と<em>actionClass属性</em>を探します。その後、対応するアクションクラスをインスタンス化し、Joranのルールストアにパターンとアクションの関連付けを新しいルールとして追加します。</p>
-
-
- <p>XMLドキュメント中では次のように新しいルールを宣言します。</p>
-
- <pre class="prettyprint source"><newRule pattern="*/computation/literal"
- actionClass="chapters.onJoran.calculator.LiteralAction"/></pre>
-
- <p>newRule宣言を使って、<code>NewRuleCalculator</code>に<code>Calculator1</code>のような振る舞いをさせることができます。</p>
-
- <p class="example">例10: 動的にルールを定義する設定例(<a href="http://logback.qos.ch/xref/chapters/onJoran/newrule/newRule.xml">logback-examples/src/main/java/chapters/onJoran/newrule/newRule.xml</a>)</p>
-
- <pre class="prettyprint source"><computation name="toto">
- <newRule pattern="*/computation/literal"
- actionClass="chapters.onJoran.calculator.LiteralAction"/>
- <newRule pattern="*/computation/add"
- actionClass="chapters.onJoran.calculator.AddAction"/>
- <newRule pattern="*/computation/multiply"
- actionClass="chapters.onJoran.calculator.MultiplyAction"/>
-
- <computation>
- <literal value="7"/>
- <literal value="3"/>
- <add/>
- </computation>
-
- <literal value="3"/>
- <multiply/>
-</computation></pre>
-
-
- <p class="command">実行してみましょう。
-java chapters.onJoran.newRule.NewRuleCalculator src/main/java/chapters/onJoran/newRule/newRule.xml</p>
-
- <p>次のように出力されます。</p>
-
- <p class="console">The computation named [toto] resulted in the value 30</p>
-
- <p>これは<a href="./10-onJoran.html#calculator">元のCalculator1</a>の出力とまったく同じです。</p>
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/manual/receivers.html b/docs/manual/receivers.html
index 11425ca..205b104 100644
--- a/docs/manual/receivers.html
+++ b/docs/manual/receivers.html
@@ -28,8 +28,6 @@
<h1>Chapter 14: Receivers</h1>
- <a href="receivers_ja.html">和訳 (Japanese translation)</a>
-
<div class="quote">
<p><em>You cannot swim for new horizons until you have courage
@@ -185,7 +183,7 @@
to the local console appender.</p>
<p class="example">Example: Basic ServerSocketReceiver Configuration
- (logback-examples/src/main/resources/chapters/receivers/socket/receiver1.xml)</p>
+ (logback-examples/src/main/java/chapters/receivers/socket/receiver1.xml)</p>
<span class="asGroovy" onclick="return asGroovy('receiver1');">View as .groovy</span>
<pre id="receiver1" class="prettyprint source"><configuration debug="true">
@@ -245,7 +243,7 @@
that acts in the server role.</p>
<p class="example">Example: Basic SSLServerSocketReceiver Configuration
- (logback-examples/src/main/resources/chapters/receivers/socket/receiver2.xml)</p>
+ (logback-examples/src/main/java/chapters/receivers/socket/receiver2.xml)</p>
<span class="asGroovy" onclick="return asGroovy('receiver2');">View as .groovy</span>
<pre id="receiver2" class="prettyprint source"><configuration debug="true">
@@ -385,7 +383,7 @@
appender acts as a server.</p>
<p class="example">Example: Basic SocketReceiver Configuration
- (logback-examples/src/main/resources/chapters/receivers/socket/receiver3.xml)</p>
+ (logback-examples/src/main/java/chapters/receivers/socket/receiver3.xml)</p>
<span class="asGroovy" onclick="return asGroovy('receiver3');">View as .groovy</span>
<pre id="receiver3" class="prettyprint source"><configuration debug="true">
@@ -427,14 +425,10 @@
succeeds or until the logger context is shut down. The delay
interval between attempts is configurable using the
<span class="prop">reconnectionDelay</span> property as shown in the
- example configuration.
- </p>
-
- <p class="source">java -Dhost=localhost -Dport=6000 \
+ example configuration.<p class="source">java -Dhost=localhost -Dport=6000 \
chapters.receivers.socket.ReceiverExample \
src/main/java/chapters/receivers/socket/receiver3.xml</p>
-
<p>We can provide a remote appender to which our example receiver
can connect, using the same appender example used previously. The
example loads a logback configuration containing a
@@ -463,7 +457,7 @@
</p>
<p class="example">Example: Basic SSLSocketReceiver Configuration
- (logback-examples/src/main/resources/chapters/receivers/socket/receiver4.xml)</p>
+ (logback-examples/src/main/java/chapters/receivers/socket/receiver4.xml)</p>
<span class="asGroovy" onclick="return asGroovy('receiver4');">View as .groovy</span>
<pre id="receiver4" class="prettyprint source"><configuration debug="true">
diff --git a/docs/manual/receivers_ja.html b/docs/manual/receivers_ja.html
deleted file mode 100644
index b6d2138..0000000
--- a/docs/manual/receivers_ja.html
+++ /dev/null
@@ -1,343 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第14章 レシーバー</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第14章 レシーバー</h1>
-
- <div class="quote">
-
- <p><em>岸が見えなくなることを恐れない勇気が無ければ、地平線の向こうまで泳ぎ着くことはできない。</em></p>
-
- <p>—WILLIAM FAULKNER</p>
- </div>
-
-
- <script type="text/javascript" src="../templates/creative.js"></script>
- <script type="text/javascript" src="../templates/setup.js"></script>
-
- <h2 class="doAnchor" name="whatIsAReceiver">レシーバーとは何か?</h2>
-
- <p><em>レシーバー</em>とは、リモートアペンダーからロギングイベントを受信し、ローカルポリシーに基づいてログに記録するlogbackのコンポーネントです。ソケットベースのアペンダーとレシーバーを組み合わせることで、分散アプリケーションのロギングイベントをネットワーク越しに配信する高度なトポロジーを実現することができます。</p>
-
- <p>レシーバーは<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/ReceiverBase.html">ch.qos.logback.classic.net.ReceiverBase</a></code>クラスを継承しています。おかげで<a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/LifeCycle.html">LifeCycle</a>に参加できるし、レシーバー自体が<a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/ContextAware.html">ContextAware</a>になります。</p>
-
- <p>歴史的な経緯により、logback によるネットワーク越しのロギングイベントの配信は<code>SocketAppender</code>と<code>SimpleSocketServer</code>によって実現されてきました。アペンダーはクライアントとして動作します。サーバーアプリケーションへのネットワーク接続を確立し、ロギングイベントを配信するのです。レシーバーコンポーネントと対応するアペンダーを使うことで、より優れた柔軟性を実現することができます。</p>
-
- <p>レシーバーコンポーネントは他のlogbackのコンポーネントと同様に<em>logback.xml</em>で設定します。つまり、<a href="./11-onJoran.html">Joran</a>の全ての機能を利用することができるのです。さらに、複数のレシーバーコンポーネントを設定するだけで、<em>あらゆる</em>アプリケーションのリモートアペンダーからロギングイベントを受け付けることができます。</p>
-
- <p>アペンダーとレシーバー間のネットワーク接続の確立はどちら側からでも始めることができます。レシーバーはサーバーとして振る舞うことができます。つまり、クライアントたるリモートアペンダーからの接続を待ち受けることができます。レシーバーはクライアントとして振る舞うこともできます。サーバーとして振る舞うリモートアペンダーに対してネットワーク接続を確立することができるのです。アペンダーとレシーバーのそれぞれの役割とは無関係に、<em>ロギングイベントは常にアペンダーからレシーバーに送信されます</em>。</p>
-
- <p>レシーバーからアペンダーに接続できることは、特定の状況においてとても有用です。</p>
- <ul>
- <li>セキュリティ上の観点から、中央ロギングサーバーはファイアーウォールの後ろ側に配置されることが多いです。つまり、外部からの接続が許されないのです。レシーバーコンポーネントがクライアントとして振る舞うことで、中央ロギングサーバー(ファイアーウォールの内側)から対象のアプリケーション(ファイアーウォールの外側)に接続することができます。
- </li>
- <li>IDEのプラグインなどの開発者ツールに最適です。また、実行中のアプリケーションが生成するロギングイベントのストリームへのアクセスを、企業統制の仕組みによって管理するのにも適しています。伝統的に、logbackでこのような状況に対応する(たとえばlogback Beagleなど)には、宛先のアプリケーション(たとえばIDEで実行される開発者ツール)がサーバーの役割を担う必要がありました。管理が大変になることは明らかです。特に、開発者のワークステーションで実行しているツールならなおさらです。モバイルPCが一般的になってきているのも悩みの種になります。今では、それらのツールはクライアントとしてのレシーバーコンポーネントを実装すればよくなりました。手元でロギングイベントをフィルタしたり、警告を上げたり、内容を確認するには、リモートアペンダーに接続すればよいのです。
- </li>
- </ul>
-
- <p>logbackの設定には、サーバーあるいはクライアントのいずれかの役割を担うレシーバーコンポーネントを混在させることができます。数少ない制限として、サーバーとして振る舞うレシーバーコンポーネントはそれぞれ固有のポート番号で接続を待ち受けなければならないということと、クライアントとして振る舞うレシーバーコンポーネントはそれぞれただ1つのリモートアペンダーにしか接続してはならないということがあります。</p>
-
- <h2 class="doAnchor" name="receiverServerComponents">サーバーとして振る舞うレシーバー</h2>
-
- <p>サーバーとして振る舞うレシーバーはリモートアペンダーからの接続を待ち受けます。これはスタンドアローンの<code>SimpleSocketServer</code>アプリケーションと同じ機能です。ただし、レシーバーコンポーネントなら、<em>logback.xml</em>に設定するだけで、logback-classicモジュールを使っている<em>あらゆる{</em>\1}アプリケーションからロギングイベントを受信することができます。</p>
-
- <p>
- <img border="1" src="images/chapters/receivers/serverSocketReceiver.png">
- </p>
-
- <p>logbackの配布物には二つのレシーバーコンポーネントが含まれています。<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/server/ServerSocketReceiver.html">ServerSocketReceiver</a></code>とそのSSL対応の<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/server/SSLServerSocketReceiver.html"><code>SSLServerSocketReceiver</code></a>です。どちらも<code>SocketAppender</code>(あるいは<code>SSLSocketAppender</code>)からの接続を待ち受けるように設計されています。</p>
-
- <p><code>ServerSocketReceiver</code>の設定可能なプロパティは次のとおりです。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="serverSocketReceiver">address</span></td>
- <td><code>String</code></td>
- <td>レシーバーが待ち受けるローカルネットワークインターフェイスのネットワークアドレス。このプロパティが指定されない場合、レシーバーは全てのネットワークインターフェイスで待ち受けるようになります。</td>
- </tr>
- <tr>
- <td><span class="prop" container="serverSocketReceiver">port</span></td>
- <td><code>int</code></td>
- <td>レシーバーが待ち受けるTCPのポート番号。このプロパティが指定されない場合、デフォルト値が使用されます。</td>
- </tr>
- <tr>
- <td><span class="prop" container="serverSocketReceiver">ssl</span></td>
- <td><code>SSLConfiguration</code></td>
- <td><code>SSLServerSocketReceiver</code>でのみサポートされているプロパティです。このプロパティには<a href="./15-usingSSL.html">SSLを使用する</a>で説明されているSSLの設定を指定します。</td>
- </tr>
- </table>
-
- <h3 class="doAnchor" name="usingServerSocketReceiver">ServerSocketReceiverの使い方</h3>
-
- <p>次の設定は、最小限のアペンダーとロガーの設定とともに<code>ServerSocketReceiver</code>を使用するものです。リモートアペンダーから受信したロギングイベントは、ルートロガーに渡されて、ローカルのコンソールアペンダーに配信されます。</p>
-
- <p class="example">例:基本的なServerSocketReceiverの設定(<a href="http://logback.qos.ch/xref/chapters/receivers/socket/receiver1.xml">logback-examples/src/main/java/chapters/receivers/socket/receiver1.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('receiver1');">Groovyとして表示</span>
- <pre id="receiver1" class="prettyprint source"><configuration debug="true">
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-
- <receiver class="ch.qos.logback.classic.net.server.ServerSocketReceiver">
- <port>${port}</port>
- </receiver>
-
-</configuration></pre>
-
- <p>レシーバーコンポーネントの<em>class属性</em>に指定した値によって、レシーバーのサブタイプを指定します。ここでは<code>ServerSocketReceiver</code>を指定しています。</p>
-
- <p>例として、<code>SimpleSocketServer</code>と非常によく似た機能を持ったサーバーアプリケーションを用意しました。logbackの設定ファイルへのパスをコマンドライン引数から受け取って、指定された設定ファイルを読み込みます。この例のアプリケーションは大した仕事をするわけではありませんが、<code>ServerSocketReceiver</code> (あるいは<code>SSLServerSocketReceiver</code>)は<em>どんな</em>アプリケーションからでも利用できることを覚えておきましょう。
- </p>
-
- <p>コマンドをプロンプトで<em>logback-examplesディレクトリ</em>に移動して、次のコマンドを実行しましょう。</p>
-
- <p class="source">java -Dport=6000 <a href="http://logback.qos.ch/xref/chapters/receivers/socket/ReceiverExample.html">chapters.receivers.socket.ReceiverExample</a> \
- src/main/java/chapters/receivers/socket/receiver1.xml</p>
-
- <p>クライアントアプリケーションで<code>SocketAppender</code>を設定して、実行中のレシーバーに接続することができます。サンプルのクライアントアプリケーションは、上記のレシーバーに接続する設定ファイルを読み込むだけのものです。クライアントアプリケーションはユーザー入力を待ちます。ユーザー入力はそのままレシーバーに中継されます。クライアントアプリケーションは次のように実行します。</p>
-
- <p class="source">java -Dhost=localhost -Dport=6000 \
- <a href="http://logback.qos.ch/xref/chapters/receivers/socket/AppenderExample.html">chapters.receivers.socket.AppenderExample </a>\
- src/main/java/chapters/receivers/socket/appender1.xml</p>
-
- <h3 class="doAnchor" name="usingSSLServerSocketReceiver">SSLServerSocketReceiverの使い方</h3>
-
- <p>次の設定は、前の設定とは違ってSSLに対応したレシーバーを使うものです。</p>
-
- <p class="example">例:基本的なSSLServerSocketReceiverの設定(<a href="http://logback.qos.ch/xref/chapters/receivers/socket/receiver2.xml">logback-examples/src/main/java/chapters/receivers/socket/receiver2.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('receiver2');">Groovyとして表示</span>
- <pre id="receiver2" class="prettyprint source"><configuration debug="true">
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-
- <receiver class="ch.qos.logback.classic.net.server.SSLServerSocketReceiver">
- <port>${port}</port>
- <ssl>
- <keyStore>
- <location>${keystore}</location>
- <password>${password}</password>
- </keyStore>
- </ssl>
- </receiver>
-
-</configuration></pre>
-
- <p>前の<code>ServerSocketReceiver</code>を使った設定とこちらの設定で根本的に違うのは、レシーバーの<em>class属性</em>に<code>SSLServerSocketReceiver</code>が指定されていることと、<span class="prop">ssl</span>プロパティがネストされていることです。sslプロパティにはレシーバーの秘密鍵と証明書が配置されたキーストアの場所とパスワードを、変数で指定しています。sslプロパティの設定内容について詳しくは<a href="./15-usingSSL.html">SSLを使用する</a>を参照してください。</p>
-
- <p>いくつか引数を追加して次のようにサーバーアプリケーションを実行します。</p>
-
- <p class="source">java -Dport=6001 \
- -Dkeystore=file:src/main/java/chapters/appenders/socket/ssl/keystore.jks \
- -Dpassword=changeit \
- chapters.receivers.socket.ReceiverExample \
- src/main/java/chapters/receivers/socket/receiver2.xml</p>
-
- <p>コマンドラインで指定したプロパティ<em>keystore</em>には、キーストアのfileから始まるURLを指定します。<a href="./15-usingSSL.html">SSLを使用する</a>でも説明していますが、クラスパス上のリソースを指定することもできます。</p>
-
- <p>このレシーバーには、クライアントアプリケーションから<code>SSLSocketAppender</code>で接続することができます。SSL対応のアペンダーを使う設定ファイルを、前の例で使用したクライアントアプリケーションから使うことができます。次のように実行します。</p>
-
- <p class="source">java -Dhost=localhost -Dport=6001 \
- -Dtruststore=file:src/main/java/chapters/appenders/socket/ssl/truststore.jks \
- -Dpassword=changeit \
- chapters.receivers.socket.AppenderExample \
- src/main/java/chapters/receivers/socket/appender2.xml</p>
-
- <p>この例では自己署名したX.509証明書を使用していますが、これを使っていいのはテストや実験的な用途だけです。<strong>本番環境では、SSL対応のアペンダーのために適切なX.509証明書を使うようにしてください</strong> 。詳細は<a href="./15-usingSSL.html">SSLを使用する</a>を参照してください。</p>
-
- <h2 class="doAnchor" name="receiverClientComponents">クライアントとして振る舞うレシーバー
-</h2>
-
- <p>クライアントとして振る舞うように設定したレシーバーは、リモートアペンダーに接続します。リモートアペンダーは<code>ServerSocketAppender</code>などのサーバ型でなければなりません。</p>
-
- <p>
- <img border="1" src="images/chapters/receivers/socketReceiver.png">
- </p>
-
- <p>logackの配布物にはクライアントとして振る舞うレシーバーコンポーネントが2つ含まれています。<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/SocketReceiver.html">SocketReceiver</a></code>とそのSSL対応版の<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/SSLSocketReceiver.html"><code>SSLSocketReceiver</code></a>です。どちらのレシーバーもリモートアペンダー(<code>ServerSocketAppender</code>あるいは<code>SSLServerSocketAppender</code>)に対して接続を確立するようになっています。</p>
-
- <p><code>SocketReceiver</code>の派生クラスで設定可能なプロパティは次のとおりです。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="SocketReceiver">remoteHost</span></td>
- <td><code>String</code></td>
- <td>リモートアペンダーのホスト名またはIPアドレス。</td>
- </tr>
- <tr>
- <td><span class="prop" container="SocketReceiver">port</span></td>
- <td><code>int</code></td>
- <td>リモートアペンダーの待ち受けポート番号。</td>
- </tr>
- <tr>
- <td><span class="prop" container="socket">reconnectionDelay</span></td>
- <td><code>int</code></td>
- <td>接続異常が発生した後で、再接続をする前に待機する時間を表す正の整数値。単位はミリ秒。デフォルト値は30000(30秒)です。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="SocketReceiver">ssl</span></td>
- <td><code>SSLConfiguration</code></td>
- <td><code>SSLSocketReceiver</code>でのみ設定可能なプロパティ。<a href="./15-usingSSL.html">SSLを使用する</a>で説明しているとおり、SSLの設定を指定します。</td>
- </tr>
- </table>
-
- <h3 class="doAnchor" name="usingSocketReceiver">SocketReceiverの使い方</h3>
-
- <p><code>SocketReceiver</code>の設定は<code>ServerSocketReceiver</code>の設定と非常によく似ています。これらの差は、サーバーとクライアントという真逆の役割に起因するものです。<code>SocketReceiver</code>はクライアントで、リモートアペンダはサーバーとして動作します。</p>
-
- <p class="example">例:基本的なSocketReceiverの設定(<a href="http://logback.qos.ch/xref/chapters/receivers/socket/receiver3.xml">logback-examples/src/main/java/chapters/receivers/socket/receiver3.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('receiver3');">Groovyとして表示</span>
- <pre id="receiver3" class="prettyprint source"><configuration debug="true">
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%date %-5level [%thread] %logger - %message%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-
- <receiver class="ch.qos.logback.classic.net.SocketReceiver">
- <remoteHost>${host}</remoteHost>
- <port>${port}</port>
- <reconnectionDelay>10000</reconnectionDelay>
- </receiver>
-
-</configuration></pre>
-
- <p>この設定だと、logbackは<em>host</em>変数で指定されたホストの、<em>port</em>変数で指定されたポート番号で実行中の<code>ServerSocketAppender</code>へ接続します。リモートアペンダーから受け取ったロギングイベントは、手元でコンソールアペンダーに渡されます。
- </p>
-
- <p>コマンドプロンプトで<em>logback-examples</em>ディレクトリに移動して、次のコマンドを実行してみましょう。</p>
-
-
-
- <p>サンプルアプリケーションは上記の設定ファイルを読み込んだあと、リモートアペンダーからのロギングイベントを待ち受けます。リモートアペンダーが落ちているときは、定期的に<em>接続を拒否された</em>メッセージが出力されます。再接続が成功するか、アプリケーションが停止するまで、レシーバーは定期的にリモートアペンダーへの再接続を繰り返します。設定例にあるとおり、再接続の間隔は<span class="prop">reconnectionDelay</span>プロパティで指定することができます。<p class="source">java -Dhost=localhost -Dport=6000 \
- chapters.receivers.socket.ReceiverExample \
- src/main/java/chapters/receivers/socket/receiver3.xml</p>
-
- <p>この例のレシーバーは、前のアプリケーションのアペンダーにそのまま接続できます。アペンダー用のサンプルアプリケーションは、<code>ServerSocketAppender</code>を使った設定ファイルを読み込んでから、ユーザー入力を待ちます。ユーザー入力はアペンダーに接続してきたレシーバーに配信されます。アペンダー用のサンプルアプリケーションを実行してみましょう。</p>
-
- <p class="source">java -Dport=6000 \
- chapters.receivers.socket.AppenderExample \
- src/main/java/chapters/receivers/socket/appender3.xml</p>
-
- <p>レシーバーが接続する前に入力したメッセージは破棄されます。わかりやすいですね。</p>
-
- <h3 class="doAnchor" name="usingSSLSocketReceiver">SocketSSLReceiverの使い方</h3>
-
-
- <p><code>SSLSocketReceiver</code>の設定は<code>SocketReceiver</code>の設定とほとんど変わりません。根本的に違うのは、レシーバーのclass属性の指定と、<span class="prop">ssl</span>プロパティがネストされていることです。基本的な設定を見てみましょう。</p>
-
- <p class="example">例:基本的なSSLSocketReceiverの設定(<a href="http://logback.qos.ch/xref/chapters/receivers/socket/receiver4.xml">logback-examples/src/main/java/chapters/receivers/socket/receiver4.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('receiver4');">Groovyとして表示</span>
- <pre id="receiver4" class="prettyprint source"><configuration debug="true">
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%date %-5level [%thread] %logger - %message%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-
- <receiver class="ch.qos.logback.classic.net.SSLSocketReceiver">
- <remoteHost>${host}</remoteHost>
- <port>${port}</port>
- <reconnectionDelay>10000</reconnectionDelay>
- <ssl>
- <trustStore>
- <location>${truststore}</location>
- <password>${password}</password>
- </trustStore>
- </ssl>
- </receiver>
-
-</configuration></pre>
-
- <p><em>class</em>属性に<code>SSLSocketReceiver</code>を指定していること、そして、リモートアペンダーが信頼できるかどうかを検証するために使用するトラストストアの場所とパスワードを指定しているところが重要なところです。sslプロパティの設定内容について詳しくは<a href="./15-usingSSL.html">SSLを使用する</a>を参照してください。
-
- </p>
-
- <p>この設定をつかってレシーバーのサンプルアプリケーションを実行しましょう。</p>
-
- <p class="source">java -Dhost=localhost -Dport=6001 \
- -Dtruststore=file:src/main/java/chapters/appenders/socket/ssl/truststore.jks \
- -Dpassword=changeit \
- chapters.receivers.socket.ReceiverExample \
- src/main/java/chapters/receivers/socket/receiver4.xml</p>
-
- <p>アプリケーションが開始すると、レシーバーは設定ファイルで指定されたリモートアペンダーに接続しようとします。まだアペンダーが実行されていないときは、定期的に"接続を拒否されました"というメッセージがログに出力されrます。レシーバーは<span class="prop">reconnectionDelay</span>プロパティで指定した時間間隔で、アペンダーに接続できるまで、再接続を繰り返します。
- </p>
-
- <p>レシーバーが接続するアペンダーのためのサンプルアプリケーションを実行しましょう。アプリケーションが開始すると、アプリケーションはユーザー入力を待ち受けます。<code>SSLServerSocketAppender</code>はレシーバーからの接続を待ち受けつつ、接続されているレシーバーにユーザー入力をメッセージとして発生したロギングイベントを配信します。アペンダーのサンプルアプリケーションを実行しましょう。</p>
-
- <p class="source">java -Dport=6001 \
- -Dkeystore=file:src/main/java/chapters/appenders/socket/ssl/keystore.jks \
- -Dpassword=changeit \
- chapters.receivers.socket.AppenderExample \
- src/main/java/chapters/receivers/socket/appender4.xml</p>
-
- <p>レシーバーが接続していない状態で何か入力しても、そのメッセージは単純に破棄されるだけです。</p>
-
- <p>繰り返しになりますが、この例では自己署名したX.509証明書を使用していますが、これはあくまでもテストだからです。<strong>本番環境においては、SSL対応のlogbackコンポーネントが自身の身元を証明するため、適切なX.509証明書を取得しなければなりません</strong>。詳しくは<a href="./15-usingSSL.html">SSLを使用する</a>を参照してください。
-</p>
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-
- </p></div>
- </body>
-</html>
\ No newline at end of file
diff --git a/docs/manual/usingSSL.html b/docs/manual/usingSSL.html
index 77b7fd3..b6dd8eb 100644
--- a/docs/manual/usingSSL.html
+++ b/docs/manual/usingSSL.html
@@ -25,11 +25,7 @@
<script src="menu.js" type="text/javascript"></script>
</div>
<div id="content">
-
<h1>Chapter 15: Using SSL</h1>
-
-
- <a href="usingSSL_ja.html">和訳 (Japanese translation)</a>
<div class="quote">
@@ -653,14 +649,14 @@
<th>Description</th>
</tr>
<tr>
- <td><a name="parameters.excludedCipherSuites"></a>
- <span class="prop" container="parameters">excludedCipherSuites</span></td>
+ <td><a name="parameters.excludedCipherSpecs"></a>
+ <span class="prop" container="parameters">excludedCipherSpecs</span></td>
<td><code>String</code></td>
<td>
- <p>Specifies a comma-separated list of SSL cipher suite names or
+ <p>Specifies a comma-separated list of SSL cipher spec names or
patterns to disable during session negotiation. This property is
used to filter the cipher suites supported by the SSL engine,
- such that any cipher suite matched by this property is disabled.
+ such that any cipher spec matched by this property is disabled.
</p>
<p>Each field in the comma-separated list specified for this
property may be a simple string or a regular expression.
@@ -668,16 +664,16 @@
<p>See the <a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">
Standard Names</a> specification in the
<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">
- JSSE Reference Guide</a> for a list of cipher suite names.
+ JSSE Reference Guide</a> for a list of cipher spec names.
</p>
</td>
</tr>
<tr>
- <td><a name="parameters.includedCipherSuites"></a>
- <span class="prop" container="parameters">includedCipherSuites</span></td>
+ <td><a name="parameters.includedCipherSpecs"></a>
+ <span class="prop" container="parameters">includedCipherSpecs</span></td>
<td><code>String</code></td>
<td>
- <p>Specifies a comma-separated list of SSL cipher suite names or
+ <p>Specifies a comma-separated list of SSL cipher spec names or
patterns to enable during session negotiation. This property is
used to filter the cipher suites supported by the SSL engine,
such that only those cipher suites matched by this property are
@@ -689,7 +685,7 @@
<p>See the <a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">
Standard Names</a> specification in the
<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">
- JSSE Reference Guide</a> for a list of cipher suite names.
+ JSSE Reference Guide</a> for a list of cipher spec names.
</p>
</td>
</tr>
@@ -1261,8 +1257,8 @@ Trust this certificate? [no]: <Enter "yes">
<h3>Client and Server Cannot Agree on a Cipher Suite</h3>
<p>NOTE: <strong>This problem usually occurs only when you are
explicitly
- <a href="#parameters.excludedCipherSuites">excluding</a> or
- <a href="#parameters.includedCipherSuites">including</a> SSL
+ <a href="#parameters.excludedCipherSuites">excluding</a> or
+ <a href="#parameters.includedCipherSuites">including</a> SSL
cipher suites in your configuration</strong>.
</p>
diff --git a/docs/manual/usingSSL_ja.html b/docs/manual/usingSSL_ja.html
deleted file mode 100644
index 77a1002..0000000
--- a/docs/manual/usingSSL_ja.html
+++ /dev/null
@@ -1,811 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第15章 SSLを使用する</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
- <h1>第15章 SSLを使用する</h1>
-
- <div class="quote">
-
- <p><em>建築物と創造物の間には越えられない壁があります。それは、建築物は作られた後でしか愛されることができないのに、創造物は存在する前から愛されていることです。</em></p>
- <p>—CHARLES DICKENS</p>
- </div>
-
- <script type="text/javascript" src="../templates/creative.js"></script>
-
- <p>logbackはソケットベースのアペンダーから遠隔のレシーバーにログを配信するために、Secure Socket Layer(SSL)を使用することが出来ます。SSLに対応したアペンダーとレシーバーを使うと、シリアライズされたロギングイベントはセキュアなチャネルで配信されます。
- </p>
-
- <h2 class="doAnchor">SSLとそれを使うコンポーネントの役割</h2>
-
- <p>アペンダーやレシーバーはサーバーとしても振る舞うし、クライアントとしても振る舞うことができます。これはネットワーク接続を始める方向によるものです。サーバーとして振る舞うとき、logbackのコンポーネントは外部のクライアントコンポーネントからの接続を待ち受けます。逆に、クライアントとして振る舞うコンポーネントは、外部のサーバーコンポーネントに接続し始めます。たとえば、<em>クライアント</em>として振る舞うアペンダーは、<em>サーバー</em>として振る舞うレシーバーに接続するのです。あるいは、<em>クライアント</em>として振る舞うレシーバーが、 <em>サーバー</em>として振る舞うアペンダーに接続します。</p>
-
- <p>コンポーネントの役割は、基本的にコンポーネントタイプによって決まります。たとえば、 <code>SSLServerSocketAppender</code>はサーバーとして振る舞うアペンダーコンポーネントですし、<code>SSLSocketAppender</code>はクライアントとして振る舞うアペンダーコンポーネントです。このように、開発者もアプリケーション管理者も、思った通りの方向でネットワーク接続を始められるようにlogbackのコンポーネントを設定することができます。</p>
-
- <p>SSLのコンテキストにおいて接続を開始する方向は非常に重要です。なぜなら、サーバーコンポーネントは接続してくるクライアントに対してX.509証明書を使って自分のことを証明しなければならないからです。クライアントコンポーネントはサーバーに接続するとき、信頼できるかどうかをサーバーの証明書で検証します。開発者やアプリケーション管理者はlogbackのコンポーネントの役割をきちんと理解しておかなければなりません。つまり、サーバーならキーストア(サーバーのX.509証明書を配置します)を適切に構成し、クライアントならトラストストア(信頼できるサーバーかどうかを検証するときに使用する自己署名ルート証明書を配置します)を適切に構成しなければなりません。</p>
-
- <p>SSLが<em>相互認証</em>するように設定されている場合、サーバーコンポーネントとクライアントコンポーネントの両方が、それぞれのピアから信頼性を検証された正当なX.509証明書を持っていなければなりません。相互認証はサーバーコンポーネントで設定するものなので、開発者もアプリケーション管理者も、コンポーネントがちゃんとサーバーとして振る舞っていることをきちんと把握しておかなければなりません。</p>
-
- <p>本章では、サーバーとして振る舞うアペンダーやレシーバーのことを、単に<em>サーバーコンポーネント</em>あるいは<em>サーバー</em>と呼ぶことにします。そして、クライアントとして振る舞うコンポーネントは<em>クライアントコンポーネント</em>あるいは<em>クライアント</em>と呼ぶことにします。
-
- <h2 class="doAnchor">SSLとX.509証明書</h2>
-
- <p>SSLに対応したlogbackコンポーネントを使うには、SSLサーバーとして動作するコンポーネントが自分のことを証明するのに、X.509証明書(秘密鍵とそれに対応する証明書、および、CAの証明書チェーン)が必要になります。相互認証を使いたいときは、SSLクライアントとして動作するコンポーネントの証明書も必要です。
- </p>
- <p>民間の証明機関(CA)だけでなく、独自のCAで発行した証明書を使うことができるのですが、自己署名した証明書を使うこともできます。必要事項は次のとおりです。</p>
- <ol>
- <li>(自己署名証明書を使わない場合)サーバーコンポーネントに、サーバーの秘密鍵を含むキーストア、対応する証明書、およびCAの証明書チェーンを指定しなければなりません。
- </li>
- <li>クライアントコンポーネントに、信頼されたルートCA証明書(複数可)または、サーバの自己署名ルート証明書を含むトラストストアを指定しなければなりません。
- </li>
- </ol>
-
- <h2 class="doAnchor">SSL用のlogbackコンポーネントの設定</h2>
- <p>logbackがSSL対応するのに使っているJava Secure Sockets Extension(JSSE)とJava 暗号化アーキテクチャ(JCA)には設定可能な項目がたくさんあります。また、プラグイン可能なフレームワークなので、組み込みのSSLとプラットフォーム固有の暗号化機能は差し替え可能になっています。SSLに対応したlogbackのコンポーネントでは、SSLエンジンと暗号化プロバイダーに設定できることは全て設定できるようになっています。ですので、利用者によって固有のセキュリティ要件を満たすことができます。
- </p>
-
- <h3>JSSEのシステムプロパティを使った基本的なSSLの設定</h3>
- <p>SSLに対応したlogbackのコンポーネントでは、SSLの設定可能なプロパティのほとんどについて妥当な初期値が用意されています。したがって、ほとんどの場合いくつかJSEEのシステムプロパティを指定するだけで済むでしょう。
- </p>
-
- <p>このセクションの残りの部分では、ほとんどの環境で必要になる特定のJSSEプロパティについて説明します。システムプロパティを使ってJSSEをカスタマイズする方法の詳細については、
-<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#InstallationAndCustomization">JSSEのカスタマイズ</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>を参照してください。
- </p>
-
- <p>サーバーとして振る舞うSSL対応のlogbackアペンダーやレシーバー(<code>SSLServerSocketReceiver</code>や<code>SSLServerSocketAppender</code>や<code>SimpleSSLSocketServer</code>)を使うときは、JSSEのシステムプロパティで秘密鍵と証明書を含むキーストアの場所と種類とパスワードを指定しなければなりません。
- </p>
-
- <h4><a name="basicConfig.keyStore"></a>サーバー側でキーストアを指定するためのシステムプロパティ</h4>
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><code>javax.net.ssl.keyStore</code></td>
- <td>サーバーコンポーネントの秘密鍵と証明書を含むファイルの、ファイルシステム上のパスを指定します。</td>
- </tr>
- <tr>
- <td><code>javax.net.ssl.keyStoreType</code></td>
- <td>キーストアの種類を指定します。このプロパティが指定されていない場合、プラットフォームのデフォルト(JKS)になります。
- </td>
- </tr>
- <tr>
- <td><code>javax.net.ssl.keyStorePassword</code></td>
- <td>キーストアにアクセスするためのパスワードを指定します。
- </td>
- </tr>
- </table>
-
- <p><a href="./15-usingSSL.html#Examples">こちらの例</a>で、SSL対応のサーバーコンポーネントを実行する際にシステムプロパティを指定する方法を確認してください。
- </p>
-
- <p>サーバーコンポーネントが民間の証明機関(CA)で署名された証明書を使うときは、<strong>おそらくクライアントコンポーネントでSSLの設定をする必要はありません。</strong>サーバー側では、JVMのシステムプロパティとしてキーストアを指定するだけでよいです。
- </p>
-
- <p>自己署名したサーバー証明書か、Javaのデフォルトのトラストストアに含まれないルート証明書(社内用の証明局など)で署名したサーバー証明書を使うときは、JSEEシステムプロパティでトラストストアの場所、種類、パスワードを指定するか、サーバー証明書を署名した信頼できるルート証明書を指定しなければなりません。<strong>SSL対応のクライアントコンポーネントを利用するアプリケーションごとに、これらのシステムプロパティを設定しなければなりません</strong> 。
- </p>
-
- <h4><a name="basicConfig.trustStore"></a>クライアント側でトラストストアを指定するためのシステムプロパティ</h4>
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><code>javax.net.ssl.trustStore</code></td>
- <td>サーバーコンポーネントの証明書か、サーバー証明書に署名した認証局(CA)の信頼できるルート証明書のファイルシステム上のパスを指定します。</td>
- </tr>
- <tr>
- <td><code>javax.net.ssl.trustStoreType</code></td>
- <td>トラストストアの種類を指定します。このプロパティが指定されていない場合、プラットフォームのデフォルト(JKS)になります。
- </td>
- </tr>
- <tr>
- <td><code>javax.net.ssl.trustStorePassword</code></td>
- <td>トラストストアにアクセスするためのパスワードを指定します。
- </td>
- </tr>
- </table>
-
- <p><a href="./15-usingSSL.html#Examples">こちらの例</a>で、SSL対応のクライアントコンポーネントを実行する際にシステムプロパティを指定する方法を確認してください。
- </p>
-
- <h3 class="doAnchor"><a name="SSLConfiguration"></a>高度なSSLの設定</h3>
- <p>JSSEシステムプロパティによる基本的なSSLの設定だけでは足りないことがあります。Webアプリケーションで<code>SSLServerSocketReceiver</code>を使用しているとき、WebクライアントがWebサーバーを識別するための証明書と、ロギングクライアントがロギングサーバーを識別するための証明書では別のものを使いたいはずです。ロギングサーバーには、認証、および、認可されたリモートロガーだけが接続できるよう、SSLのクライアントを認証したいこともあるでしょう。あるいは、内部ネットワークではSSLプロトコルと暗号スイートを使わなければならない、というポリシーを強制する組織があるかもしれません。これらのいずれかのニーズを満たすためには、logbackの高度なSSL設定オプションを確かめておいたほういいでしょう。</p>
- <p>logbackのコンポーネントでSSLを設定するときは、<code>ssl</code>プロパティに指定します。
- </p>
- <p><code>SSLServerSocketReceiver</code>を使うときは、keystoreプロパティでサーバーの証明書を含んだキーストアを指定します。
- </p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-ssl-serverKeyStore');">Groovyとして表示</span>
- <pre id="logback-ssl-serverKeyStore" class="prettyprint source"><configuration>
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="CONSOLE" />
- </root>
-
- <receiver class="ch.qos.logback.classic.net.server.SSLServerSocketReceiver">
- <ssl>
- <keyStore>
- <location>classpath:/logging-server-keystore.jks</location>
- <password>changeit</password>
- </keyStore>
- </ssl>
- </receiver>
-
-</configuration></pre>
-
- <p>ここでは、キーストアの場所にアプリケーションのクラスパスのルートに配置された<em>logging-server-keystore.jks</em>が指定されています。もちろん、fileから始まるURLを指定することもできます。
- </p>
- <p>アプリケーションで<code>SSLSocketAppender</code>を使いたいけど、アプリケーション自体の(JSEEの)デフォルトのトラストストアを変更したくないときは、<code>javax.net.ssl.trustStore</code>プロパティを使うことができます。
- </p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-ssl-clientTrustStore');">Groovyとして表示</span>
- <pre id="logback-ssl-clientTrustStore" class="prettyprint source"><configuration>
- <appender name="SOCKET" class="ch.qos.logback.classic.net.SSLSocketAppender">
- <ssl>
- <trustStore>
- <location>classpath:/logging-server-truststore.jks</location>
- <password>changeit</password>
- </trustStore>
- </ssl>
- </appender>
-
- <root level="debug">
- <appender-ref ref="SOCKET" />
- </root>
-
-</configuration></pre>
-
- <p>ここでは、トラストストアの場所にアプリケーションのクラスパスのルートに配置された<em>logging-server-truststore.jks</em>が指定されています。
-もちろん、fileから始まるURLを指定することもできます。
-
- </p>
-
- <h4>SSLプロパティ</h4>
-
- <p>JSSEは設定可能なオプションを大量に公開しています。logbackのSSL対応では公開された設定のほとんどを設定ファイル中で指定できるようになっています。XML形式の設定ファイルでは、SSLの各種設定をssl要素で設定します。ssl要素に対応しているのは<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/SSLConfiguration.html">SSLConfiguration</a></code>クラスです。
- </p>
-
- <p>SSLに対応したコンポーネントを設定するには、デフォルト値では困る時にこれらのプロパティを設定するだけでよいです。なんでもかんでも設定してしまうと、こんがらがってしまって問題を解析するのがとてもむずかしくなってしまいます。
- </p>
-
- <p>SSLの設定におけるトップレベルのプロパティは次のとおりです。これらのプロパティの多くについて、さらに下位のプロパティが存在します。トップレベルなプロパティの一覧表の後に説明します。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>Type</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="ssl">keyManagerFactory</span></td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/KeyManagerFactoryFactoryBean.html">
- <code>KeyManagerFactoryFactoryBean</code></a>
- </td>
- <td><code><a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/net/ssl/KeyManagerFactory.html">KeyManagerFactory</a></code>の設定を指定します。このプロパティが設定されていない場合は、JVMのデフォルトのファクトリが使われます。<a href="./15-usingSSL.html#KeyManagerFactoryFactoryBean">キーマネージャファクトリの設定</a>を参照してください。
- </td>
- </tr>
- <tr>
- <td><a name="ssl.keyStore"></a><span class="prop" container="ssl">keyStore</span></td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/KeyStoreFactoryBean.html">
- <code>KeyStoreFactoryBean</code></a>
- </td>
- <td>
- <p><code><a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/security/KeyStore.html">KeyStore</a></code>の設定を指定します。キーストアには、少なくとも1つのX.509証明書(秘密鍵と対応する証明書、あるいはCA証明書チェーン)が含まれていなければなりません。この証明書がSSLのリモートピアに提示されます。
- </p>
- <p>SSLクライアント(<code>SSLSocketAppender</code>など)の設定に<span class="prop" container="ssl">keyStore</span>プロパティが必要になるのは、リモートピアへの接続にクライアント認証が必要な場合だけです。
- </p>
- <p>SSLサーバー(<code>SimpleSSLSocketServer</code>など)の<span class="prop" container="ssl">keyStore</span>プロパティには、サーバー証明書を格納したキーストアを指定します。このプロパティが設定されていない場合は、JSSEのシステムプロパティ<code>javax.net.ssl.keyStore</code>に、サーバーのキーストアの場所を指定しておかなければなりません。詳細は<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#InstallationAndCustomization">JSSEのカスタマイズ</a>を参照してください。
- </p>
- <p><a href="./15-usingSSL.html#KeyStoreFactoryBean">キーストアの設定</a>については後述します。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="ssl">parameters</span></td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/SSLParametersConfiguration.html">
- <code>SSLParametersConfiguration</code></a></td>
- <td>SSLセッションのネゴシエーションで使用するいろいろなパラメータを指定します。<a href="./15-usingSSL.html#SSLParametersConfiguration">SSLパラメータの設定</a>については後述します。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="ssl">protocol</span></td>
- <td><code>String</code></td>
- <td><code><a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/net/ssl/SSLContext.html">SSLContext</a></code>を作成するために使用するSSLプロトコルを指定します。<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>に記載された<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">標準名</a>を指定してください。このプロパティが設定されていない場合は、JVMのデフォルトのプロトコル名が使用されます。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="ssl">provider</span></td>
- <td><code>String</code></td>
- <td><code><a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/net/ssl/SSLContext.html">SSLContext</a></code>を作成するために使用するJSSEプロバイダー名を指定します。このプロパティが設定されていない場合は、JVMのデフォルトのJSSEプロバイダ名が使用されます。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="ssl">secureRandom</span></td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/SecureRandomFactoryBean.html">
- <code>SecureRandomFactoryBean</code></a>
- </td>
- <td><code><a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/security/SecureRandom.html">SecureRandom</a></code>(安全な乱数生成器)の設定を指定します。このプロパティが設定されていない場合は、JVMのデフォルトの乱数生成器が使用されます。<a href="./15-usingSSL.html#SecureRandomFactoryBean">安全な乱数生成器の設定</a>については後述します。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="ssl">trustManagerFactory</span></td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/TrustManagerFactoryFactoryBean.html">
- <code>TrustManagerFactoryFactoryBean</code></a>
- </td>
- <td><code><a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/net/ssl/TrustManagerFactory.html">TrustManagerFactory</a></code>の設定を指定します。このプロパティが設定されていない場合は、JVMのデフォルトのファクトリーを使用します。<a href="./15-usingSSL.html#TrustManagerFactoryFactoryBean">トラストマネージャファクトリー</a>については後述します。
- </td>
- </tr>
- <tr>
- <td><a name="ssl.trustStore"></a><span class="prop" container="ssl">trustStore</span></td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/KeyStoreFactoryBean.html">
- <code>KeyStoreFactoryBean</code></a>
- </td>
- <td>
- <p>SSLのリモートピアの同一性を検証するために使う<code><a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/security/KeyStore.html">KeyStore</a></code>の設定を指定します。キーストアには少なくとも1つ以上の<em>トラストアンカー</em>が含まれていなければなりません。"信頼できる"と印の付けられた自己署名証明書のことです。一般的に、トラストストアには自己署名CA証明書が含まれています。
- </p>
- <p>このプロパティで指定したトラストストアは、JSSEの<code>java.net.ssl.trustStore</code>システムプロパティで指定された全てのトラストストアを上書きします。詳細は<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#InstallationAndCustomization">JSSEのカスタマイズ</a>を参照してください。
-
- </p>
- </td>
- </tr>
- </table>
-
- <h4 class="doAnchor"><a name="KeyStoreFactoryBean"></a>キーストアの設定</h4>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/KeyStoreFactoryBean.html">KeyStoreFactoryBean</a></code>は、X.509証明書を格納した<a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/security/KeyStore.html"><code>KeyStore</code></a>を作成するために必要な設定を提供します。このファクトリーBeanのプロパティは、<a href="./15-usingSSL.html#SSLConfiguration">SSLの設定</a>で紹介した<a href="./15-usingSSL.html#ssl.keyStore"><span class="prop" container="ssl">keyStore</span></a>および<a href="./15-usingSSL.html#ssl.tr [...]
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="keyStore">location</span></td>
- <td><code>String</code></td>
- <td>キーストアの場所をURLで指定します。ファイルシステム上のキーストアを指定するときは、<code>file:</code>形式のURLを指定します。<code>classpath:</code>形式のURLを指定すれば、クラスパス上のリソースを指定することもできます。URLスキームがないときは、<code>classpath:</code>が指定されたものとして扱います。</td>
- </tr>
- <tr>
- <td><span class="prop" container="keyStore">password</span></td>
- <td><code>String</code></td>
- <td>キーストアにアクセスするためのパスワードを指定します。</td>
- </tr>
- <tr>
- <td><span class="prop" container="keyStore">provider</span></td>
- <td><code>String</code></td>
- <td><code>KeyStore</code>を作成するために使用するJCAプロバイダー名を指定します。このプロパティが設定されていない場合は、JVMのデフォルトのキーストアプロバイダーが使用されます。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="keyStore">type</span></td>
- <td><code>String</code></td>
- <td><code>KeyStore</code>の種類を指定します。指定できるのは、<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html">Java暗号化アーキテクチャ</a>に記載された仕様である<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html#AppA">標準名</a>です。このプロパティが設定されていない場合は、JVMのデフォルトが使用されます。
- </td>
- </tr>
- </table>
-
- <h4><a name="KeyManagerFactoryFactoryBean"></a>キーマネージャファクトリーの設定</h4>
-
- <p><a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/net/ssl/KeyManagerFactory.html"><code>KeyManagerFactory</code></a>を作成するために必要な設定は、<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/KeyManagerFactoryFactoryBean.html">KeyManagerFactoryFactoryBean</a></code>によって提供されます。普通はキーマネージャーファクトリーの明示的な設定は不要です。ほぼ全ての場合にJVMのデフォルトのファクトリーで十分だからです。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="keyManagerFactory">algorithm</span></td>
- <td><code>String</code></td>
- <td><code>KeyManagerFactory</code>が使うアルゴリズム名を指定します。指定できるのは、<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>に記載された<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">標準名</a>だけです。このプロパティが設定されていない場合は、JVMのデフォルトのアルゴリズムが使用されます。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="keyManagerFactory">provider</span></td>
- <td><code>String</code></td>
- <td><code>SecureRandom</code>生成器を生成するのに使われるJCAプロバイダー名を指定します。このプロパティが設定されていない場合は、JVMのデフォルトのJSSEプロバイダーが使用されます。
- </td>
- </tr>
- </table>
-
- <h4 class="doAnchor"><a name="SecureRandomFactoryBean"></a>安全な乱数生成器の設定</h4>
-
- <p><a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/security/SecureRandom.html"><code>SecureRandom</code></a>生成器を作成するために必要な設定は、<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/SecureRandomFactoryBean.html">SecureRandomFactoryBean</a></code>によって提供されます。JVMのデフォルトの乱数生成器で十分なことがほとんどなので、普通は明示的に設定する必要がありません。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="secureRandom">algorithm</span></td>
- <td><code>String</code></td>
- <td><code>安全な乱数生成器</code>のアルゴリズム名を指定します。指定できるのは<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html">Java暗号化アーキテクチャの</a>に記載された<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html#AppA">標準名</a>だけです。このプロパティが設定されていない場合は、JVMのデフォルトの乱数生成アルゴリズムが使用されます。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="secureRandom">provider</span></td>
- <td><code>String</code></td>
- <td><code>安全な乱数生成器</code>を生成するために使われるJCAプロバイダー名を指定します。このプロパティが設定されていない場合は、JVMのデフォルトのJSSEプロバイダ名が使用されます。
- </td>
- </tr>
- </table>
-
- <h4><a name="SSLParametersConfiguration"></a> SSLパラメータの設定</h4>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/SSLParametersConfiguration.html">SSLParametersConfiguration</a></code>を使って、SSLプロトコル、暗号スイート、およびクライアント認証オプションをカスタマイズすることができます。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><a name="parameters.excludedCipherSpecs"></a>
- <span class="prop" container="parameters">excludedCipherSpecs</span></td>
- <td><code>String</code></td>
- <td>
- <p>セッションネゴシエーションをする際に除外するSSL暗号方式名をカンマ区切りリストで指定します。このプロパティに指定する値は、SSLエンジンがサポートしている暗号方式を限定するために使用されます。マッチした暗号方式はすべて無効になります。
- </p>
- <p>カンマ区切りリストのそれぞれの項目には単純な文字列あるいは正規表現を指定することができます。
- </p>
- <p>指定できるのは、<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">標準名</a>にあるものだけです。
- </p>
- </td>
- </tr>
- <tr>
- <td><a name="parameters.includedCipherSpecs"></a>
- <span class="prop" container="parameters">includedCipherSpecs</span></td>
- <td><code>String</code></td>
- <td>
- <p>セッションネゴシエーションをする際に使用するSSL暗号方式名をカンマ区切りリストで指定します。
-このプロパティに指定する値は、SSLエンジンがサポートしている暗号方式を特定するために使用されます。マッチした暗号方式はすべて有効になります。
- </p>
- <p>カンマ区切りリストのそれぞれの項目には単純な文字列あるいは正規表現を指定することができます。
- </p>
- <p>指定できるのは、<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">標準名</a>にあるものだけです。
-
- </p>
- </td>
- </tr>
- <tr>
- <td><a name="parameters.excludedProtocols"></a>
- <span class="prop" container="parameters">excludedProtocols</span></td>
- <td><code>String</code></td>
- <td>
- <p>セッションネゴシエーションをする際に除外するSSLプロトコル名をカンマ区切りリストで指定します。このプロパティに指定する値は、SSLエンジンがサポートしているSSLプロトコルを限定するために使用されます。マッチしたSSLプロトコルはすべて無効になります。
- </p>
- <p>カンマ区切りリストのそれぞれの項目には単純な文字列あるいは正規表現を指定することができます。
- </p>
- <p>指定できるのは、<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">標準名</a>にあるものだけです。
- </p>
- </td>
- </tr>
- <tr>
- <td><a name="parameters.includedProtocols"></a>
- <span class="prop" container="parameters">includedProtocols</span></td>
- <td><code>String</code></td>
- <td>
- <p>セッションネゴシエーションをする際に使用するSSLプロトコル名をカンマ区切りリストで指定します。
-このプロパティに指定する値は、SSLエンジンがサポートしているSSLプロトコルを特定するために使用されます。マッチしたSSLプロトコルはすべて有効になります。
-
- </p>
- <p>カンマ区切りリストのそれぞれの項目には単純な文字列あるいは正規表現を指定することができます。
-
- </p>
- <p>指定できるのは、<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">標準名</a>にあるものだけです。
- </p>
- </td>
- </tr>
- <tr>
- <td><a name="parameters.needClientAuth"></a>
- <span class="prop" container="parameters">needClientAuth</span></td>
- <td><code>boolean</code></td>
- <td>サーバー側でクライアント認証が<em>必要</em>なときは、このプロパティに<code>true</code>を指定します。クライアントコンポーネント(<code>SSLSocketAppender</code>など)の場合はこのプロパティは無視されます。
- </td>
- </tr>
- <tr>
- <td><a name="parameters.wantClientAuth"></a>
- <span class="prop" container="parameters">wantClientAuth</span></td>
- <td><code>boolean</code></td>
- <td>サーバー側でクライアント認証が<em>必要</em>なときは、このプロパティに<code>true</code>を指定します。
-クライアントコンポーネント(<code>SSLSocketAppender</code>など)の場合はこのプロパティは無視されます。
-
- </td>
- </tr>
- </table>
-
- <h4><a name="TrustManagerFactoryFactoryBean"></a>トラストマネージャファクトリーの設定</h4>
-
- <p><a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/net/ssl/TrustManagerFactory.html"><code>TrustManagerFactory</code></a>を作成するために必要な設定は、<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/TrustManagerFactoryFactoryBean.html">TrustManagerFactoryFactoryBean</a></code>が提供します。JVMのデフォルトのファクトリーで十分なことがほとんどなので、普通は明示的に設定する必要がありません。
-
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="trustManagerFactory">algorithm</span></td>
- <td><code>String</code></td>
- <td><code>TrustManagerFactory</code>のアルゴリズム名を指定します。指定できるのは、<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">標準名</a>にあるものだけです。このプロパティが設定されていない場合は、JVMのデフォルトのキーマネージャのアルゴリズムが使用されます。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="trustManagerFactory">provider</span></td>
- <td><code>String</code></td>
- <td><code>安全な乱数生成器</code>を生成するために使われるJCAプロバイダー名を指定します。このプロパティが設定されていない場合は、JVMのデフォルトのJSSEプロバイダが使用されます。
- </td>
- </tr>
- </table>
-
- <h2 class="doAnchor"><a name="Examples"></a>例</h2>
-
- <h3>JSSEシステムプロパティを使用する</h3>
- <p>JSSEシステムプロパティは、サーバーのX.509証明書を含むキーストアの場所とパスワードを指定するために使われます。また、クライアントコンポーネントが信頼できるサーバーかどうかを検証するために使用する、自己署名ルートCA証明書を含むトラストストアの場所とパスワードを指定します。</p>
-
- <h4>サーバーのキーストアを指定する</h4>
- <p>サーバーコンポーネントを実行する場合、サーバーの証明書を含むキーストアの場所とパスワードを指定しなければなりません。そのために、JSSEシステムプロパティを使用することができます。logbackの配布物に含まれる<code>SimpleSSLSocketServer</code>を実行してみましょう。</p>
-
- <p class="source">java -DkeyStore=/etc/logback-server-keystore.jks \
- -DkeyStorePassword=changeit -DkeyStoreType=JKS \
- ch.qos.logback.net.SimpleSSLSocketServer 6000 /etc/logback-server-config.xml</p>
-
- <p>JSSEシステムプロパティの<em>keyStore</em>に、サーバーのキーストアへのパスを指定するのを忘れないようにしてください。そのパスを<em>logback.xml</em>で指定するときはURLで指定します。</p>
-
- <p>この例ではlogbackの配布物に含まれているスタンドアローンのサーバーアプリケーションを実行しました。どんなアプリケーションでも、logbackのサーバーコンポーネントを使う場合は同じようにシステムプロパティを指定できます。
-
- <h4>クライアントのトラストストアを指定する</h4>
-
- <p>クライアントコンポーネントを使用する場合、信頼できるサーバーかどうかを検証するために使用する、ルートCA証明書を含むトラストストアの場所とパスワードを指定しなければなりません。そのためにJSSEシステムプロパティを使用することができます。logbackのSSL対応のクライアントコンポーネントを複数使用する<code>com.example.MyLoggingApplication</code>を実行してみましょう。</p>
-
- <p class="source">java -DtrustStore=/etc/logback-client-truststore.jks \
- -DtrustStorePassword=changeit -DtrustStoreType=JKS \
- com.example.MyLoggingApplication</p>
-
- <p>JSSEシステムプロパティの<em>trustStore</em>に、トラストストアへのパスを指定するのを忘れないようにしてください。そのパスを<em>logback.xml</em>で指定するときはURLで指定します。</p>
-
- <h3>サーバーコンポーネントの自己署名証明書を生成して利用する</h3>
- <p>自己署名証明書を生成するには、Javaランタイム環境(JRE)に同梱されている<em>keytoolユーティリティ</em>を使用します。以下の手順では、サーバーコンポーネントの自己署名X.509証明書をキーストアに配置してから、クライアントコンポーネントの使用するトラストストアを作成します。
- </p>
-
- <h4>サーバコンポーネントの証明書の生成</h4>
- <p>次のコマンドを実行すると、<em>server.keystore</em>というファイル名の自己署名クライアント証明書を生成します。</p>
- <pre class="source">keytool -genkey -alias server -dname "CN=my-logging-server" \
- -keyalg RSA -validity 365 -keystore server.keystore
-Enter keystore password: <Enter password of your choosing>
-Re-enter new password: <Re-enter same password>
-Enter key password for <my-logging-server>
- (RETURN if same as keystore password): <Press RETURN>
-</pre>
-
- <p><em>dname</em>に指定した<em>my-logging-server</em>は、正当なものであればどんなものでも構いません。サーバーを実行するホストの完全修飾ドメイン名にするとよいでしょう。<em>validity</em>には証明書の有効期限が切れるまでの日数を指定します。</p>
-
- <p>本番環境の設定で重要になるのが、サーバー証明書を配置するキーストアにとても強力なパスワードを指定することです。このパスワードによって、サーバーの秘密鍵にアクセスできるのが限られた関係者だけであることを保証します。後の手順でこのパスワードが必要になるので、サーバーの設定をするときに心の中にメモしておいてください。
- </p>
-
- <h4>クライアントコンポーネント用のトラストストアの作成</h4>
- <p>クライアントコンポーネントの設定に使用するため、前の手順で作成したサーバーの証明書をキーストアからエクスポートして、トラストストアにインポートしましょう。次のコマンドを実行すると、証明書をエクスポートして<em>server.truststore</em>というファイル名のトラストストアにインポートします。</p>
-
- <pre class="source">keytool -export -rfc -alias server -keystore server.keystore \
- -file server.crt
-Enter keystore password: <Enter password you chose for in previous step>
-
-keytool -import -alias server -file server.crt -keystore server.truststore
-Enter keystore password: <Enter password of your choosing>
-Re-enter new password: <Re-enter same password>
-Owner: CN=my-logging-server
-Issuer: CN=my-logging-server
-Serial number: 6e7eea40
-Valid from: Sun Mar 31 07:57:29 EDT 2013 until: Mon Mar 31 07:57:29 EDT 2014
-
- ...
-
-Trust this certificate? [no]: <Enter "yes">
-</pre>
-
- <p>最初のコマンドは、キーストアからエクスポートしたサーバー証明書(サーバーの秘密鍵ではありません)を<em>server.crt</em>というファイル名で保存します。二つ目のコマンドは、サーバー証明書を含んだ<em>server.truststore</em>という新しいトラストストアを作成します。
- </p>
-
- <p>本番環境の設定で重要になるのが、トラストストアにとても強力な、そして、サーバーのキーストアに使用したパスワードとは異なるパスワードを設定することです。ここで指定したパスワードは、クライアントのアペンダーの設定に必要になるので心の中にメモしておいてください。
- </p>
-
- <h4>サーバコンポーネントの設定</h4>
- <p><em>server.keystore</em>をアプリケーションアーカイブの内部に取り込まなければならないかもしれません。キーストアはアプリケーションのクラスパスリソースとして扱うこともできますし、単にサーバーを実行するホストのファイルシステム上に配置することもできます。設定ファイルからキーストアの場所を指定するときは、<code>classpath:</code>から始まるURLか、<code>file:</code>から始まるURLのいずれかを指定します。設定ファイルを見てみましょう。</p>
-
- <p class="example">例:サーバーコンポーネントの設定</p>
- <pre class="prettyprint source"><configuration debug="true">
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-
- <server class="ch.qos.logback.classic.net.server.SSLServerSocketReceiver">
- <ssl>
- <keyStore>
- <location>classpath:server.keystore</location>
- <password>${server.keystore.password}</password>
- </keyStore>
- </ssl>
- </server>
-</configuration></pre>
-
- <p>この例では、キーストアがアプリケーションのクラスパスのルートに配置されていることを前提としています。</p>
-
- <p>また、キーストアのパスワードには<em>server.keystore.password</em>という変数を指定しています。こうしておけば、どの設定ファイルにもパスワードを書いておかなくてもよくなります。たとえば、アプリケーションが起動した後、ロギングシステムを設定する前にコンソールでパスワード入力を促すプロンプトを出すようにして、システムプロパティ<em>server.keystore.password</em>をプログラム的に設定すればよいのです。
- </p>
-
- <h4>クライアントコンポーネントの設定</h4>
- <p>クライアントとして振る舞うSSL対応のコンポーネントを使用するアプリケーションそれぞれについて、<em>server.truststore</em>をアプリケーションアーカイブの内部に取り込まなければならないかもしれません。トラストストアはアプリケーションのクラスパスリソースとして扱うこともできますし、単にクライアントを実行するホストのファイルシステム上に配置することもできます。
-設定ファイルからトラストストアの場所を指定するときは、<code>classpath:</code>から始まるURLか、<code>file:</code>から始まるURLのいずれかを指定します。
-アペンダーの設定を見てみましょう。</p>
-
- <p class="example">例:アペンダーの設定</p>
-
- <pre class="prettyprint source"><configuration debug="true">
- <appender name="SOCKET" class="ch.qos.logback.classic.net.SSLSocketAppender">
- <remoteHost>${host}</remoteHost>
- <ssl>
- <trustStore>
- <location>classpath:server.truststore</location>
- <password>${server.truststore.password}</password>
- </trustStore>
- </ssl>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SOCKET" />
- </root>
-</configuration></pre>
-
- <p>この例では、トラストストアがアプリケーションのクラスパスのルートに配置されていることを前提としています。</p>
-
- <p>また、トラストストアのパスワードには<em>server.truststore.password</em>という変数を指定しています。
-こうしておけば、どの設定ファイルにもパスワードを書いておかなくてもよくなります。
-たとえば、アプリケーションが起動した後、ロギングシステムを設定する前にコンソールでパスワード入力を促すプロンプトを出すようにして、システムプロパティ<em>server.truststore.password</em>をプログラム的に設定すればよいのです。
-
- </p>
-
- <h2>SSLの設定を監査する</h2>
- <p>安全な通信が必要とされる環境では、SSLを使うコンポーネントがローカルセキュリティポリシーを満たしていることを検証するため、設定内容を監査しなければならない。logbackでは、自身を初期化している間に行われるSSLの設定について詳細なロギング情報を提供することでこれに対応しています。設定中で<code>debug</code>プロパティを使うことで、監査ログを有効化することができます。</p>
-
- <pre class="prettyprint source"><configuration debug="true">
-
- ...
-
-</configuration></pre>
-
- <p>debugプロパティを有効にすると、ロギングシステムの初期化中に行われるSSLの設定に関するあらゆる情報が得られるようになります。SSL設定の監査ログとして出力されるのは次のようなものです。</p>
-
- <p class="example">例:SSL設定の監査ログ</p>
-
- <pre>06:46:31,941 |-INFO in SSLServerSocketReceiver at 4ef18d37 - SSL protocol 'SSL' provider 'SunJSSE version 1.6'
-06:46:31,967 |-INFO in SSLServerSocketReceiver at 4ef18d37 - key store of type 'JKS' provider 'SUN version 1.6': file:src/main/java/chapters/appenders/socket/ssl/keystore.jks
-06:46:31,967 |-INFO in SSLServerSocketReceiver at 4ef18d37 - key manager algorithm 'SunX509' provider 'SunJSSE version 1.6'
-06:46:31,973 |-INFO in SSLServerSocketReceiver at 4ef18d37 - secure random algorithm 'SHA1PRNG' provider 'SUN version 1.6'
-06:46:32,755 |-INFO in SSLParametersConfiguration at 4a6f19d5 - enabled protocol: SSLv2Hello
-06:46:32,755 |-INFO in SSLParametersConfiguration at 4a6f19d5 - enabled protocol: SSLv3
-06:46:32,755 |-INFO in SSLParametersConfiguration at 4a6f19d5 - enabled protocol: TLSv1
-06:46:32,756 |-INFO in SSLParametersConfiguration at 4a6f19d5 - enabled cipher suite: SSL_RSA_WITH_RC4_128_MD5
-06:46:32,756 |-INFO in SSLParametersConfiguration at 4a6f19d5 - enabled cipher suite: SSL_RSA_WITH_RC4_128_SHA
-06:46:32,756 |-INFO in SSLParametersConfiguration at 4a6f19d5 - enabled cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
-</pre>
-
- <p>ここで示した出力は大幅にカットしてありますが、一般的には次のようなものが含まれています。
- <ul>
- <li>完全なプロトコルのリスト</li>
- <li>プロバイダー</li>
- <li>アルゴリズム</li>
- <li>暗号スイート</li>
- <li>キーストアやトラストストアの場所</li>
- </ul>
- </p>
-
- <p>この監査ログに取り扱いに注意の必要な情報が含まれることはありませんが、セキュリティのベストプラクティスとしては、本番環境の設定の妥当性が確認されたなら、監査ログは無効化するべきです。<code>debug</code>プロパティを消すか、<code>false</code>を指定すれば監査ログは無効化されます。
- </p>
-
- <h2>SSLの設定誤りを解決する</h2>
- <p>SSLの設定が間違っていると、普通ならクライアントとサーバーのコンポーネントの間でセッションを確立できなくなります。これは、クライアントがサーバーに接続しようとしてそれができなかったときにそれぞれで例外をスローすることによって明らかになります。
- </p>
- <p>例外メッセージの内容は、見ているログによって異なります。それは、セッションネゴシエーション中に報告されるエラーの原因は、主にプロトコルの制限によるものだからです。したがって、セッションネゴシエーションの問題を解決するには、クライアントとサーバーの両方のログを調査しなければなりません。
- </p>
-
- <h3>サーバの証明書が使用できません</h3>
- <p>サーバーの証明書が使用できない時、サーバコンポーネントを起動すると次のような例外メッセージがログに出力されます。</p>
-
- <p><em>javax.net.ssl.SSLException: No available certificate or
- key corresponds to the SSL cipher suites which are enabled</em>
- </p>
-
- <p>ほとんどの場合、サーバーの秘密鍵に対応する証明書を含むキーストアの場所を設定し忘れていることが原因です。
- </p>
-
- <h4>ソリューション</h4>
- <p>システムプロパティの<a href="./15-usingSSL.html#basicConfig.keyStore">キーストア</a>か、サーバーコンポーネントの<span class="prop">ssl</span>の設定で<span class="prop"><a href="./15-usingSSL.html#ssl.keyStore">keyStore</a></span>プロパティに、サーバ証明書を含むキーストアの場所を指定してください。あと、キーストアのパスワードも指定してください。
- </p>
-
- <h3>クライアントはサーバーを信頼できません</h3>
- <p>クライアントがサーバに接続しようとするとき、次のような例外メッセージがログに現れます。</p>
-
- <p><em>javax.net.ssl.SSLHandshakeException:
- sun.security.validator.ValidatorException:
- PKIX path building failed</em>
- </p>
- <p>これは、クライアントがサーバーの提示した証明書を信頼できないと判断した場合に発生します。よくある原因としては、サーバーが自己署名サーバー証明書(あるいは内部の認証局で署名したサーバー証明書)を使っている上で、クライアントの使用するトラストストアにサーバーの自己署名証明書が含まれていない(あるいはサーバー証明書に署名したCAの信頼できるルート証明書が含まれていない)ことです。
- </p>
- <p>サーバー証明書が失効している場合も同じような現象が発生します。サーバー側のログを見ることが出来るなら、クライアントが接続しようとするたびに次のような例外メッセージが現れているのがわかると思います。</p>
-
- <p><em>javax.net.ssl.SSLHandshakeException: Received fatal alert: ...</em>
- </p>
-
- <p>例外メッセージの後半部分には、クライアントがサーバー証明書を拒否した理由を表すコードが現れます。
- </p>
- <table class="bodyTable striped">
- <tr>
- <th>コード</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><code>certificate_unknown</code></td>
- <td>クライアントのトラストストアが正しく設定されていないことを示しています。
- </td>
- </tr>
- <tr>
- <td><code>certificate_expired</code></td>
- <td>サーバー証明書が失効しているので更新が必要なことを示しています。
- </td>
- </tr>
- <tr>
- <td><code>certificate_revoked</code></td>
- <td>サーバー証明書に署名した認証局(CA)が、そのサーバー証明書を無効にしたことを示しています。サーバー証明書を更新しなければなりません。
- </td>
- </tr>
- </table>
-
- <h4>ソリューション</h4>
- <p>サーバー側のログに<code>certificate_unknown</code>が現れているときは、システムプロパティ<a href="./15-usingSSL.html#basicConfig.trustStore">トラストストア</a>か、アペンダーの<span class="prop">ssl</span>設定に<a href="./15-usingSSL.html#ssl.trustStore">trustStore</a>プロパティを指定してください。サーバーの自己署名証明書か、証明書に署名したCAのルート証明書を格納した<span class="prop">トラストストア</span>の場所と、アクセスするためのパスワードを指定しなければなりません。
- </p>
-
- <p>サーバー側のログに<code>certificate_expired</code>か<code>certificate_revoked</code>が現れているときは、新しいサーバー証明書が必要です。サーバーの設定で指定したキーストアの場所に、新しいサーバー証明書と対応する秘密鍵を配置してください。自己署名サーバー証明書を使っているときは、クライアントのアペンダーの設定に指定されているトラストストアにも新しい証明書を配置しなければなりません。
- </p>
-
- <h3>サーバーはクライアントを信頼できません
-</h3>
- <p>注: <strong>この問題が生じるのは、サーバーがクライアント証明書を要求するように明示的に設定している場合だけです(<a href="./15-usingSSL.html#parameters.needClientAuth"><span class="prop">needClientAuth</span></a>か<a href="./15-usingSSL.html#parameters.wantClientAuth"><span class="prop">wantClientAuth</span></a>プロパティを指定したときです)。</strong>
- </p>
-
- <p>クライアントがサーバに接続しようとするとき、次のような例外メッセージがログに現れます。
-</p>
-
- <p><em>javax.net.ssl.SSLHandshakeException: Received fatal
- alert: ...</em>
- </p>
-
- <p>例外メッセージの後半部分には、サーバーがクライアントの証明書を拒否した理由を表すコードが現れます。
-
- </p>
- <table class="bodyTable striped">
- <tr>
- <th>コード</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><code>certificate_unknown</code></td>
- <td>サーバのトラストストアが正しく設定されていないことを示しています。
- </td>
- </tr>
- <tr>
- <td><code>certificate_expired</code></td>
- <td>クライアントの証明書が失効しているので更新が必要なことを示しています。
-
- </td>
- </tr>
- <tr>
- <td><code>certificate_revoked</code></td>
- <td>クライアントの証明書に署名した認証局(CA)が、その証明書を無効にしたことを示しています。証明書を更新しなければなりません。
-
- </td>
- </tr>
- </table>
-
- <h4>ソリューション</h4>
- <p>クライアント側のログに<code>bad_certificate</code>が現れているときは、システムプロパティ<a href="./15-usingSSL.html#basicConfig.trustStore">トラストストア</a>かサーバーコンポーネントの<span class="prop">ssl</span>設定の<span class="prop"><a href="./15-usingSSL.html#ssl.trustStore">trustStore</a></span>プロパティに、トラストストアの場所とパスワードを指定しなければなりません。トラストストアにはクライアントの自己署名証明書か、証明書に署名したCAのルート証明書が含まれていなければなりません。
- </p>
-
- <p>サーバー側のログに<code>certifacte_expired</code>あるいは<code>certificate_revoked</code>が現れているときは、新しい証明書が必要です。クライアントの設定で指定したキーストアの場所に、新しい証明書と対応する秘密鍵を配置してください。自己署名証明書を使っているときは、サーバーの設定に指定されているトラストストアにも新しい証明書を配置しなければなりません。
-
- </p>
-
- <h3>クライアントとサーバー間でSSLプロトコルを合意できません</h3>
- <p>注: <strong>この問題が生じるのは、明示的にSSLプロトコルを<a href="./15-usingSSL.html#parameters.excludedProtocols">除外</a>したり<a href="./15-usingSSL.html#parameters.includedProtocols">指定</a>している場合だけです</strong> 。
- </p>
-
- <p>クライアントがサーバに接続しようとするとき、次のような例外メッセージがログに現れます。</p>
-
- <p><em>javax.net.ssl.SSLHandshakeException: Received fatal
- alert: handshake_failure</em>
- </p>
-
- <p>サーバーのログに現れるメッセージのほうがわかりやすいです。</p>
-
- <p><em>javax.net.ssl.SSLHandshakeException: SSLv2Hello is disabled</em>
- </p>
-
- <p>一方のピアで除外したプロトコルが、もう一方のピアでは除外されていない場合に発生します。</p>
-
- <h4>ソリューション</h4>
- <p>サーバーとクライアントの両方で、<a href="./15-usingSSL.html#parameters.excludedProtocols"><span class="prop">excludedProtocols</span></a>と<a href="./15-usingSSL.html#parameters.includedProtocols"><span class="prop">includedProtocols</span></a>に指定した値を確認してください。
- </p>
-
- <h3>クライアントとサーバー間で暗号スイートを合意できません
-</h3>
- <p>注: <strong>この問題が生じるのは、明示的に暗号スイートを<a href="./15-usingSSL.html#parameters.excludedCipherSuites">除外</a>したり<a href="./15-usingSSL.html#parameters.includedCipherSuites">指定</a>している場合だけです</strong> 。
- </p>
-
- <p>クライアントがサーバに接続しようとするとき、次のような例外メッセージがログに現れます。
-</p>
-
- <p><em>javax.net.ssl.SSLHandshakeException: Received fatal
- alert: handshake_failure</em>
- </p>
-
- <p>サーバーのログに現れるメッセージのほうがわかりやすいです。
-</p>
-
- <p><em>javax.net.ssl.SSLHandshakeException: no cipher suites in common</em>
- </p>
-
- <p>クライアントとサーバーそれぞれの暗号スイート一覧について、1つも一致するものが無い場合に発生します。</p>
-
- <h4>ソリューション</h4>
- <p>サーバーとクライアントの両方で、<a href="./15-usingSSL.html#parameters.excludedCipherSuites"><span class="prop">excludedCipherSuites</span></a>と<a href="./15-usingSSL.html#parameters.includedCipherSuites"><span class="prop">includedCipherSuites</span></a>に指定した値を確認してください。
-
- </p>
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-
- </p></p></div>
- </body>
-</html>
\ No newline at end of file
diff --git a/docs/news.html b/docs/news.html
index c903a8b..39170b1 100644
--- a/docs/news.html
+++ b/docs/news.html
@@ -19,9 +19,6 @@
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="templates/right.js" type="text/javascript"></script>
- </div>
<div id="content">
<h2>Logback News</h2>
@@ -30,426 +27,7 @@
the <a href="http://www.qos.ch/mailman/listinfo/announce">QOS.ch
announce</a> mailing list.</p>
-
- <hr width="80%" align="center" />
-
- <h3>January 20th, 2017, Release of version 1.1.9</h3>
-
-
- <p>Logback's internal executor service had a thread pool size of 2
- which could be used up rather quickly, e.g. configuration scanning
- in addition to an active <code>ServerSocketAppender</code>. When
- both threads where permanently in use, compression could not
- proceed. To alleviate this problem, the thread pool size has been
- increased to 8. See issue <a
- href="https://jira.qos.ch/browse/LOGBACK-1238">LOGBACK-1238</a>
- for more details.
- </p>
-
- <p>Fixed issue with <code>FileAppender</code> instances embedded
- within <code>SiftingAppender</code> reporting filename collisions
- after reaching timeout and subsequently restarted. This problem
- was reported in <a
- href="https://jira.qos.ch/browse/LOGBACK-1167">LOGBACK-1167</a> by
- Michael Edgar.
- </p>
-
- <p>Fixed <code>SizeAndTimeBasedFNATP</code> deprecation warning
- emitted even the replacement,
- i.e. <code>SizeAndTimeBasedRollingPolicy</code>, is in use. See <a
- href="http://jira.qos.ch/browse/LOGBACK-1236">LOGBACK-1236</a>. This
- issue was reported by Claudius Nicolae.
- </p>
-
- <p>Added proper implementation for
- <code>LobackValve.getScheduledExecutorService()</code> method. The
- missing implementation manifested itself in the form of an
- <code>UnsupportedOperationException</code> thrown by
- LogbackValve. This problem is further described in <a
- href="http://jira.qos.ch/browse/LOGBACK-1181">LOGBACK-1181</a>
- reported by Andreas von Roepenack.
- </p>
-
- <hr width="80%" align="center" />
-
- <h3>December 9th, 2016, Release of version 1.1.8</h3>
-
- <p>Removed the two period safeguard, aka untouchable periods, for
- archive removal beyond the size specified by <span
- class="option">totalSizeCap</span> in
- <code>TimeBasedRollingPolicy</code>. It turns out the safegaurd is
- not required and is unexpected as attested by <a
- href="http://jira.qos.ch/browse/LOGBACK-1166">LOGBACK-1166</a>.
- </p>
-
- <p>Fixed issue with Joran incorrectly reporting "Unexpected
- aggregationType AS_BASIC_PROPERTY_COLLECTION". This issue was
- raised in <a
- href="http://jira.qos.ch/browse/LOGBACK-1158">LOGBACK-1158</a> by
- Christian Hübner.
- </p>
-
- <p>Gaffer (logback's groovy configurator) now supports the
- <code>valueOf</code> convention. This issue was raised in <a
- href="http://jira.qos.ch/browse/LOGBACK-1232">LOGBACK-1232</a> by
- Frans Orsel.
- </p>
-
- <p>The <code>org.slf4j.impl.StaticLoggerBinder</code> class
- shipping in logback-classic no longer catches
- <code>Throwable</code> but <code>Exception</code>. This change was
- requested in <a
- href="http://jira.qos.ch/browse/LOGBACK-1159">LOGBACK-1159</a> by
- David J. M. Karlsen.
- </p>
-
- <p><code>BeanDescriptionFactory</code> no longer outputs a
- superflous warning message in case the class contains bridge
- methods. This fixes <a
- href="http://jira.qos.ch/browse/LOGBACK-1164">LOGBACK-1164</a>
- reported by Phil Clay.
- </p>
-
- <!--
- <p>Added logback-bom module for use as a Maven "Bill of Materials"
- <em>pom</em> file. This was requested in <a
- href="http://jira.qos.ch/browse/LOGBACK-1157">LOGBACK-1157</a>
- Joerg Sesterhenn.</p>
- -->
-
- <hr width="80%" align="center" />
-
- <h3>March 29th, 2016, Release of version 1.1.7</h3>
-
- <p>Logback is now <a href="
- http://docs.oracle.com/javase/8/docs/technotes/guides/compactprofiles/compactprofiles.html">compact3
- profile</a> compatible. This improvement was requested in <a
- href="http://jira.qos.ch/browse/LOGBACK-1071">LOGBACK-1071</a> by
- Axel Fontaine with Max Urech providing the relevant pull-request.
- </p>
-
- <p>Fixed <code>ConcurrentModificationException</code> being thrown
- when the <code>reset()</code> method is invoked on the
- <code>LoggerContext</code> instance. This issue was reported in <a
- href="http://jira.qos.ch/browse/LOGBACK-397">LOGBACK-397</a> by
- Szczepan Faber with Ross Sargant providing the relevant test case.
- </p>
-
- <p><code>TimeBasedRollingPolicy</code> now supports the <a
- href="manual/appenders.html#tbrpTotalSizeCap"><span
- class="option">totalSizeCap</span></a> property which allows the
- user to limit the total size of archived logs.
- </p>
-
- <p><a
- href="manual/appenders.html#SizeAndTimeBasedRollingPolicy"><code>SizeAndTimeBasedRollingPolicy</code></a>
- offers the same functionality as
- <code>SizeAndTimeBasedFNATP</code> did previously but with a
- simpler configuration structure.
- </p>
-
- <p>Archive removal by <code>RollingFileAppender</code> is now
- performed asynchronously.</p>
-
- <p>Unnecessary and incompatible %i token in <span
- class="option">fileNamePattern</span> option with
- <code>RollingFileAppender/TimeBasedRollingPolicy</code> is now
- detected and the user alerted to the misconfiguration
- problem. This fixes <a
- href="http://jira.qos.ch/browse/LOGBACK-1143">LOGBACK-1143</a>.
- </p>
-
-
- <p>Joran can now handle logger names ending with a $, i.e. the
- first character in variable substitution. This issue was raised in
- <a href="http://jira.qos.ch/browse/LOGBACK-1149">LOGBACK-1149</a>
- by by Stevo Slavic.
- </p>
-
-
-
- <hr width="80%" align="center" />
-
- <h3>February 29th, 2016, Release of version 1.1.6</h3>
-
- <p><code>LogbackValve</code> (in logback-access) now attempts to
- load the configuration file as a resource if it cannot be found on
- the filesystem (<a
- href="http://jira.qos.ch/browse/LOGBACK-1069">LOGBACK-1069</a>). This
- is helpful in scenarios where applications are using an embedded
- Tomcat server.</p>
-
- <p><code>JMXConfigurator.reloadDefaultConfiguration()</code>
- method now tolerates programmatic configuration without a
- URL. This change was provided by Vedran Pavic in <a
- href="https://github.com/qos-ch/logback/pull/302">PR 302</a>.
- </p>
-
- <p><code>RollingFileAppender</code> will output an error message
- if the date time pattern in the %d token within the <span
- class="option">fileNamePattern</span> is not collision free. This
- fixes <a
- href="http://jira.qos.ch/browse/LOGBACK-1137">LOGBACK-1137</a>. In
- a similar vein, every instance of <code>FileAppender</code> will
- now detect if it shares the same <span class="option">File</span>
- option value as given for an appender defined earlier. In
- addition, <code>RollingFileAppender</code> instances now check for
- colliding <span class="option">FileNamePattern</span> values.</p>
-
- <p>Fixed <code>NullPointerException</code> thrown by
- <code>RollingFileAppender</code> if the name of the rollover
- target path did not contain a parent. This issue was reported in
- <a href="http://jira.qos.ch/browse/LOGBACK-1054">LOGBACK-1054</a>
- by Paulius Matulionis. Analysis of the problem and the relevant PR
- was provided by Ferenc Palkovics.</p>
-
- <p><code>BasicConfigurator.configure</code> method call executes
- significatly faster. Improved documentation for configuration
- using JDK 1.6 service-provider facility. These changes are in
- response to <a
- href="http://jira.qos.ch/browse/LOGBACK-1141">LOGBACK-1141</a>
- requesting faster logback start-up time.
- </p>
-
-
- <p>Fixed issue with variable substitution with the value ending in
- a colon. This problem was reported in <a
- href="http://jira.qos.ch/browse/LOGBACK-1140">LOGBACK-1140</a> by
- Eric Cook.</p>
-
- <hr width="80%" align="center" />
-
- <h3>February 13th, 2016, Release of version 1.1.5</h3>
-
- <div class="breaking">
- <h4>MDC values are no longer inherited by child threads.</h4>
- </div>
-
- <p>Child threads no longer inherit MDC values. In previous
- versions of logback as well as log4j 1.x, MDC values were
- inherited by child threads. Several users have argued convincingly
- that MDC inheritance by child threads was unhelpful and even
- dangerous. This change fixes <a
- href="http://jira.qos.ch/browse/LOGBACK-422">LOGBACK-422</a> and <a
- href="http://jira.qos.ch/browse/LOGBACK-624">LOGBACK-624</a>
- </p>
-
- <p>When the <code>FileNamePattern</code> string for
- <code>RollingFileAppender/SizeAndTimeBasedFNATP</code> lacks a %i
- token, then compression for the second archive in the same period
- cannot occur as the target file already exists. Under those
- circumstances, logback leaves behind .tmp files as reported in <a
- href="http://jira.qos.ch/browse/LOGBACK-992">LOGBACK-992</a>, <a
- href="http://jira.qos.ch/browse/LOGBACK-173">LOGBACK-173</a> and
- <a
- href="http://jira.qos.ch/browse/LOGBACK-920">LOGBACK-920</a>. In
- this release, this particular condition is detected by
- <code>RollingFileAppender</code> which will not start but alert
- the user instead.
- </p>
-
- <p>AsyncAppender is now configurable to never block. This feature
- was requested by Jeff Wartes in <a
- href="http://jira.qos.ch/browse/LOGBACK-898">LOGBACK-898</a> with
- Jeff Wartes and Gareth Davis providing the relevant patch.
- </p>
-
-
- <hr width="80%" align="center" />
-
- <h3>February 11th, 2016, Release of version 1.1.4</h3>
-
- <div class="breaking">
- <h4>Logback 1.1.4 requires SLF4J version 1.7.16 or later.</h4>
- </div>
-
- <p>Added event replay support as introduced in SLF4J version
- 1.7.15. In most circumstances, logack-classic should run fine with
- earlier versions of slf4j-api, including all versions in the 1.6.x
- and 1.7.x series. However, with a version of slf4j-api.jar earlier
- than 1.7.15 in the classpath, attempting introspection of a
- <code>Logger</code> instance will result in a
- <code>NoClassDefFoundError</code> similar to that shown below.
- </p>
-
- <pre class="prettyprint source">Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/event/LoggingEvent
- at java.lang.Class.getDeclaredMethods0(Native Method)
- at java.lang.Class.privateGetDeclaredMethods(Class.java:2451)
- at java.lang.Class.privateGetPublicMethods(Class.java:2571)
- at java.lang.Class.getMethods(Class.java:1429)
- at java.beans.Introspector.getPublicDeclaredMethods(Introspector.java:1261)
- at java.beans.Introspector.getTargetMethodInfo(Introspector.java:1122)
- at java.beans.Introspector.getBeanInfo(Introspector.java:414)
- at java.beans.Introspector.getBeanInfo(Introspector.java:161)
- </pre>
-
- <p>
- </p>
-
- <div class="breaking">
- <h4>Packaging data (as output in stack traces) is now disabled
- by default.
- </h4>
- </div>
-
- <p>In case an application throws exceptions frequently, then
- computing packaging data can be very costly and will cause the
- application to run slower. Making bad worse. To alleviate this
- problem, packaging data is no longer computed by default. It has
- to be <a href="manual/configuration.html#packagingData">enabled
- explicitly</a>. In the absence of explicit instructions, i.e the
- user has not specified a converter handling exceptions,
- <code>PatternLayout</code> in logback-classic will follow the
- settings defining for the logging environment. If packaging data
- is disabled, then it add %ex as a suffix in the pattern, and if
- packaging data is enabled then %xEx will be added. These changes
- fix <a
- href="http://jira.qos.ch/browse/LOGBACK-730">LOGBACK-730</a> and
- <a href="http://jira.qos.ch/browse/LOGBACK-966">LOGBACK-966</a>.
- </p>
-
-
- <p>Fixed a bug in
- <code>TimeBasedFileNamingAndTriggeringPolicyBase</code> causing
- time-based rolling policies to always rollover according to the
- local system time and ignore the time zone passed in the file name
- pattern. The issue was reported by Lukasz Sanek who also provided
- the the relevant fix. </p>
-
- <p><code>AsyncAppenderBase</code> now restores the current
- thread's interrupt flag when catching an
- <code>InterruptedException</code>. The issue
- (<a href="http://jira.qos.ch/browse/LOGBACK-910">LOGBACK-910</a>) was
- raised by Henrik Nordvik who also provided the relevant fix.</p>
-
<hr width="80%" align="center" />
-
- <h3>24th of March 2015, Release of version 1.1.3</h3>
-
-
- <div class="breaking">
- <h4>As of version 1.1.3, all logback modules require JDK 1.6
- instead of previously JDK 1.5. This change was put to
- consultation on the logback mailing lists with no objections
- raised.</h4>
- </div>
-
-
- <p>Fixed <code>FileAppender</code>'s prudent mode so that it properly recovers
- from IO Errors
- (<a href="http://jira.qos.ch/browse/LOGBACK-1046">LOGBACK-1046</a>) </p>
-
- <p>Irrelevant or internal stack trace lines can now be omitted. Pull request
- provided by Tomasz Nurkiewicz
- (<a href="http://jira.qos.ch/browse/LOGBACK-540">LOGBACK-540</a>).</p>
-
- <p><code>AccessEvent</code> now creates a copy of request attributes when
- its <code>prepareForDeferredProcessing()</code> method is called. This makes
- attributes visible even if an appender uses a background thread to process
- events.
- (<a href="http://jira.qos.ch/browse/LOGBACK-1033">LOGBACK-1033</a>)</p>
-
- <p>All threads opened by <code>ch.qos.logback.core.util.ExecutorServiceUtil#THREAD_FACTORY</code>
- are now daemons, which fixes an application hang on shutdown when <code>LoggerContext#stop()</code>
- is not called (<a href="http://jira.qos.ch/browse/LOGBACK-929">LOGBACK-929</a>).
- Note that daemon threads are abruptly terminated by the JVM, which may cause
- undesirable results, such as corrupted files written by the <code>FileAppender</code>.
- It is still highly recommended for the application to call <code>LoggerContext#stop()</code>
- (e.g., in a shutdown hook) to gracefully shutdown appenders.</p>
-
- <p>Fixed an issue with <code>RollingFileAppender</code> where the first
- rollover file could be unintentionally deleted, depending on the specified
- filename pattern
- (<a href="http://jira.qos.ch/browse/LOGBACK-894">LOGBACK-894</a>).</p>
-
- <p>Fixed an issue with <code>TeeHttpServletResponse</code>
- where the system default encoding would be used instead of the
- response encoding when constructing a new writer
- (<a href="http://jira.qos.ch/browse/LOGBACK-1023">LOGBACK-1023</a>).</p>
-
- <p>Fixed <code>ConfigurationDelegate.groovy</code> to allow any appender
- that implements <code>AppenderAttachable</code>, which supports third-party
- appenders, such as <b>reactor-logback's</b> <code>AsyncAppender</code>
- (<a href="http://jira.qos.ch/browse/LOGBACK-1008">LOGBACK-1008</a>)</p>
-
- <p>Added support for specifying the callstack depth range in the
- <code>PatternLayout</code>. For example, <code>%caller{1..2}</code>
- displays the first two calls in the callstack.</p>
-
- <p>Added HTTP request method to <code>MDCInsertingServletFilter</code>.</p>
-
- <p>Fixed time-zone dependent code in <code>RollingCalendarTest</code>.
- (<a href="http://jira.qos.ch/browse/LOGBACK-116">LOGBACK-116</a>)
- </p>
-
- <p>Simplified connection logic of SocketApender to reduce multi-threading
- overhead and unnecessary instantiation of <code>SocketConnector</code>
- objects.</p>
-
- <p>Fixed race condition in <code>SMTPAppenderBase</code> causing missing or
- duplicate emails.
- (<a href="http://jira.qos.ch/browse/LOGBACK-909">LOGBACK-909</a>)
- </p>
-
- <p>Fixed an issue with <code>FileAppender</code> in prudent mode, where
- an interrupt could prevent further access to the file
- (<a href="http://jira.qos.ch/browse/LOGBACK-875">LOGBACK-875</a>).</p>
-
- <p>Fixed <code>IllegalStateException</code> when multiple threads
- write files to same directory
- (<a href="http://jira.qos.ch/browse/LOGBACK-128">LOGBACK-128</a>).</p>
-
- <p>Changed queue consumption strategy in <code>AbstractSocketAppender</code>
- from "take" to "peek/remove" in order to avoid losing an event on each socket
- connection break. Zero is now a deprecated queue size. A queue size of one
- should be taken instead to indicate synchronous processing.
- (<a href="http://jira.qos.ch/browse/LOGBACK-977">LOGBACK-977</a>)
- </p>
-
- <p><code>RequestLogImpl</code> now has an overridable <code>configure</code>
- method to allow extending implementations to configure it via methods
- other than the <code>logback-access.xml</code> file.</p>
-
- <p>Fixed a bug in <code>AccessEvent</code> which could cause any
- <code>AsyncAppender</code> based appender to corrupt the request
- headers, request parameters, or response headers, before logging.</p>
-
- <p>SQL scripts to setup your logback database are now provided as
- JAR resources
- (<a href="http://jira.qos.ch/browse/LOGBACK-948">LOGBACK-948</a>).
- </p>
-
- <p>Threads created internally by logback are now named
- <i>logback-n</i>, where <i>n</i> is an integer. For the
- first thread <i>n</i> is set to 1, for each successive thread
- <i>n</i> is incremented by 1.</p>
-
- <p>Added max runtime parameter to <code>AsyncAppender</code> to allow
- the appender to flush events, up to a maximum delay, during a stop
- of the LoggerContext. This can be used to ensure that all queued
- events are flushed.</p>
-
- <p>Added new configuration element <code>shutdownHook</code> to allow the
- user to specify a ShutdownHook implementation that will stop the Logback
- context upon JVM exit.
- </p>
-
- <p><code>BasicStatusManager</code> now prevents adding more than
- one instance of <code>OnConsoleStatusListener</code> as a status
- listener. This fixes <a
- href="http://jira.qos.ch/browse/LOGBACK-976">LOGBACK-976</a>.
- </p>
-
- <p><code>TimeBasedRollingPolicy</code> now accepts a time zone in
- its <code>%d</code> conversion pattern. (<a
- href="http://jira.qos.ch/browse/LOGBACK-611">LOGBACK-611</a>)
- </p>
-
- <p>It is now possible to configure the character encoding used by
- <code>SyslogAppender</code> to encode messages using the
- <code>setCharset()</code> method. This fixes <a
- href="http://jira.qos.ch/browse/LOGBACK-732">LOGBACK-732</a>
- </p>
<h3>2nd of April, 2014 - Release of version 1.1.2</h3>
@@ -466,7 +44,7 @@
</p>
<p>Fixed <code>NullPointerException</code> when substituting blank variables
- (<a href="http://jira.qos.ch/browse/LOGBACK-959">LOGBACK-959</a>)</p>
+ (<a href="http://jira.qos.ch/browse/LOGBACK-959">LOGBACK-959</a>)
<p>Fixed <code>NullPointerException</code> that occurs when stopping a
<code>SyslogAppender</code> that did not properly initialize, e.g.,
@@ -481,12 +59,7 @@
<p>In case of missing included files, IncludeAction no longer
prints a stack trace but prints a warning instead. (<a
- href="http://jira.qos.ch/browse/LOGBACK-954">LOGBACK-954</a>)</p>
-
- <p>Fixed character escaping in XMLLayout
- (<a href="http://jira.qos.ch/browse/LOGBACK-728">LOGBACK-728</a>)
- and HTMLLayout
- (<a href="http://jira.qos.ch/browse/LOGBACK-440">LOGBACK-440</a>).</p>
+ href="http://jira.qos.ch/browse/LOGBACK-954">LOGBACK-954</a>)
<hr width="80%" align="center" />
diff --git a/docs/project-reports.html b/docs/project-reports.html
index a13f2d3..e2615eb 100644
--- a/docs/project-reports.html
+++ b/docs/project-reports.html
@@ -1,16 +1,16 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<!-- Generated by Apache Maven Doxia Site Renderer 1.6 at 2017-01-20 -->
+<!-- Generated by Apache Maven Doxia at Apr 2, 2014 -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <title>Logback-Parent – Generated Reports</title>
+ <title>Generated Reports</title>
<style type="text/css" media="all">
@import url("./css/maven-base.css");
@import url("./css/maven-theme.css");
@import url("./css/site.css");
</style>
<link rel="stylesheet" href="./css/print.css" type="text/css" media="print" />
- <meta name="Date-Revision-yyyymmdd" content="20170120" />
+ <meta name="Date-Revision-yyyymmdd" content="20140402" />
<meta http-equiv="Content-Language" content="en" />
</head>
@@ -25,14 +25,14 @@
</div>
<div id="breadcrumbs">
-
+
<div class="xleft">
- <span id="publishDate">Last Published: 2017-01-20</span>
- | <span id="projectVersion">Version: 1.1.9</span>
+ <span id="publishDate">Last Published: 2014-04-02</span>
+ | <span id="projectVersion">Version: 1.1.2</span>
</div>
<div class="xright"> <a href="./" title="Logback-Parent">Logback-Parent</a>
-
+
</div>
<div class="clear">
<hr/>
@@ -41,7 +41,7 @@
<div id="leftColumn">
<div id="navcolumn">
-
+
<h5>Modules</h5>
<ul>
<li class="none">
@@ -84,32 +84,12 @@
<img class="poweredBy" alt="Built by Maven" src="./images/logos/maven-feather.png" />
</a>
-
+
</div>
</div>
<div id="bodyColumn">
<div id="contentBox">
- <div class="section">
-<h2><a name="Generated_Reports"></a>Generated Reports</h2>
-<p>This document provides an overview of the various reports that are automatically generated by <a class="externalLink" href="http://maven.apache.org">Maven</a> . Each report is briefly described below.</p>
-<div class="section">
-<h3><a name="Overview"></a>Overview</h3>
-<table border="0" class="bodyTable">
-<tr class="a">
-<th>Document</th>
-<th>Description</th></tr>
-<tr class="b">
-<td><a href="xref/index.html">Source Xref</a></td>
-<td>HTML based, cross-reference version of Java source code.</td></tr>
-<tr class="a">
-<td><a href="xref-test/index.html">Test Source Xref</a></td>
-<td>HTML based, cross-reference version of Java test source code.</td></tr>
-<tr class="b">
-<td><a href="apidocs/index.html">JavaDocs</a></td>
-<td>JavaDoc API documentation.</td></tr>
-<tr class="a">
-<td><a href="testapidocs/index.html">Test JavaDocs</a></td>
-<td>Test JavaDoc API documentation.</td></tr></table></div></div>
+ <div class="section"><h2>Generated Reports<a name="Generated_Reports"></a></h2><p>This document provides an overview of the various reports that are automatically generated by <a class="externalLink" href="http://maven.apache.org">Maven</a> . Each report is briefly described below.</p><div class="section"><h3>Overview<a name="Overview"></a></h3><table border="0" class="bodyTable"><tr class="a"><th>Document</th><th>Description</th></tr><tr class="b"><td><a href="xref/index.html">S [...]
</div>
</div>
<div class="clear">
@@ -117,10 +97,10 @@
</div>
<div id="footer">
<div class="xright">
- Copyright © 2005–2017
+ Copyright © 2005-2014
<a href="http://www.qos.ch">QOS.ch</a>.
- All rights reserved.
-
+ All Rights Reserved.
+
</div>
<div class="clear">
<hr/>
diff --git a/docs/reasonsToSwitch.html b/docs/reasonsToSwitch.html
index 146abc6..c6f150a 100644
--- a/docs/reasonsToSwitch.html
+++ b/docs/reasonsToSwitch.html
@@ -19,10 +19,6 @@
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="templates/right.js" type="text/javascript"></script>
- </div>
-
<div id="content">
<h2>Reasons to prefer logback over log4j</h2>
diff --git a/docs/setup.html b/docs/setup.html
index 7c30960..ba83c28 100644
--- a/docs/setup.html
+++ b/docs/setup.html
@@ -31,31 +31,31 @@
</p>
<ul>
- <li>logback-core-1.1.9.jar</li>
- <li>logback-classic-1.1.9.jar</li>
- <li>logback-examples-1.1.9.jar</li>
- <li>slf4j-api-1.7.22.jar</li>
+ <li>logback-core-1.1.2.jar</li>
+ <li>logback-classic-1.1.2.jar</li>
+ <li>logback-examples-1.1.2.jar</li>
+ <li>slf4j-api-1.7.6.jar</li>
</ul>
<p>The <em>logback-*.jar</em> files are part of the logback
- distribution whereas <em>slf4j-api-1.7.22.jar</em> ships
+ distribution whereas <em>slf4j-api-1.7.6.jar</em> ships
with <a href="http://www.slf4j.org">SLF4J</a>, a separate project.
</p>
+
<h3 class="doAnchor" name="commandLine">Running from the command
line</h3>
- <p>You can launch the first sample application,
- <em>chapters.introduction.HelloWord1</em> with the following
- command. This assumes that your current directory is
+ <p>Assuming your current directory is
<em>$LOGBACK_HOME/logback-examples</em>, where
<em>$LOGBACK_HOME</em> stands for the directory where you
- installed logback:
+ installed logback, you can launch the first sample application,
+ <em>chapters.introduction.HelloWord1</em> with the following command:
</p>
- <p class="source">java -cp lib/slf4j-api-1.7.22.jar;../logback-core-1.1.9.jar;\
- ../logback-classic-1.1.9.jar;logback-examples-1.1.9.jar\
+ <p class="source">java -cp lib/slf4j-api-1.7.6.jar;../logback-core-1.1.2.jar;\
+ ../logback-classic-1.1.2.jar;logback-examples-1.1.2.jar\
chapters.introduction.HelloWorld1</p>
<p>It is more convenient to set the CLASSPATH environment variable
@@ -78,76 +78,6 @@
<em>$LOGBACK_HOME/logback-examples</em> directory.
</p>
-
- <h2 class="doAnchor" name="mavenBuild">Maven dependency
- declaration</h2>
-
- <p>To use logback-classic in your Maven project, declare the
- following dependency in your project's <em>pom</em> file.</p>
-
- <pre class="prettyprint source"><dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <version>1.1.9</version>
-</dependency></pre>
-
- <p><span class="label notice">TRANSITIVITY</span> Note that in
- addition to <em>logback-classic.jar</em>, the above declaration
- will automatically pull-in <em>slf4j-api.jar</em> and
- <em>logback-core.jar</em> into your project by virtue of Maven's
- transitivity rules.</p>
-
-
- <p>To include logback-access in your Maven project, declare the following
- dependency in your project's <em>pom</em> file.</p>
-
- <pre class="prettyprint source"><dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-access</artifactId>
- <version>1.1.9</version>
-</dependency></pre>
-
- <h4>Maven "Bill of materials" (useful for large teams)</h4>
-
- <p>To facilitate the synchronization of logback and slf4j modules,
- we provide a "Bill of materials" pom file. It can be imported in
- the <code>dependencyManagement</code> section of your parent
- <code>pom</code> file, as shown below.
- </p>
-
- <pre class="prettyprint source"><dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-bom</artifactId>
- <version>1.1.9</version>
- <type>pom</type>
- <scope>import</scope>
- <dependency>
- ...
- </dependencies>
-</dependencyManagement></pre>
-
- <p>Importing logback-bom as shown above allows you to declare the
- version for logback/slf4j modules in one step and keep them in
- sync. This can be convenient particularly in larger software
- teams.</p>
-
- <p>Note that you still need to declare a dependency on
- logback-classic (or logback-access). However, you no longer will
- have to specify the version.</p>
-
- <p>After logback-bom is imported, the previous dependency declaration
- becomes:</p>
-
- <pre class="prettyprint source"><dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <!-- Look mom, no version! -->
-</dependency></pre>
-
- <h2 class="doAnchor" name="optionalDeps">Optional dependencies</h2>
-
<h3 class="doAnchor" name="SMTP"><code>SMTPAppender</code> requires
JavaMail API</h3>
@@ -175,7 +105,7 @@
runtime</h3>
<p><code>GEventEvaluator</code> depends on the Groovy runtime. It
- was tested with Groovy version 2.4.0. Similarly, as the
+ was tested with Groovy version 2.0.7. Similarly, as the
name indicates <a href="manual/groovy.html">groovy
configuration</a> files require the groovy runtime to be present on
your class path.
@@ -189,7 +119,7 @@
<pre class="prettyprint source"><dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
- <version>2.4.0</version>
+ <version>2.0.7</version>
</dependency></pre>
@@ -213,12 +143,12 @@
convenience.
</p>
- <pre class="prettyprint source"><!-- The org.codehaus.janino:commons-compiler:2.7.8 dependency -->
+ <pre class="prettyprint source"><!-- The org.codehaus.janino:commons-compiler:2.6.1 dependency -->
<!-- will be automatically pulled in by Maven's transitivity rules -->
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
- <version>2.7.8</version>
+ <version>2.6.1</version>
</dependency></pre>
@@ -226,7 +156,7 @@
- <h2 class="doAnchor" name="ide">Building with an IDE</h2>
+ <h3 class="doAnchor" name="ide">Building with an IDE</h3>
<p>If you wish to contribute to the project or just hack for fun,
you will probably want to import logback as a project into your
@@ -260,15 +190,20 @@
<h3 class="doAnchor" name="eclipse">Building with Eclipse</h3>
<p>Building logback under Eclipse is a little trickier. Here are
- instructions for building logback under Eclipse using the maven
- eclipse:eclipse plugin.
+ instructions for building logback under Eclipse in 61 easy steps.
</p>
-
- <p>The procedure outlines below assumes that M2Eclipse is not
- active. If you have <code>m2eclipse</code> installed, you can
- disable it by removing the Maven Nature for a given project. In
- later versions of Eclipse, m2eclipse is installed by default.
+ <p>The author does not wish to unduly disparage
+ <code>m2eclipse</code>. However, as of this writing, that is
+ October 2011, it appears that the key to building logback under
+ Eclipse is to avoid using <code>m2eclipse</code>. If you have
+ <code>m2eclipse</code> installed, you can disable it by removing
+ the Maven Nature for a given project. In later versions of Eclipse,
+ m2eclipse is installed bu default. As of logback version 1.0.7, the
+ <em>pom.xml</em> file for logback-core now deactivates m2eclipse as
+ explained in <a
+ href="http://wiki.eclipse.org/M2E_plugin_execution_not_covered#ignore_plugin_goal">M2E
+ plugin wiki</a>.
</p>
<p>And without further ado here are the steps:
@@ -289,10 +224,13 @@
<p>You first need to determine the update site appropriate
for your version of Eclipse. The list of available update
sites is available from <a
- href="https://github.com/groovy/groovy-eclipse/wiki">Groovy
- Eclipse Wiki</a>.
+ href="http://groovy.codehaus.org/Eclipse+Plugin">Groovy
+ project documentation</a>.
+ </p>
+ <p>For example, for Eclipse 4.2 (Juno) the URL of the
+ update site is
+ "http://dist.springsource.org/release/GRECLIPSE/e4.2/".
</p>
-
</li>
<li>In Eclipse, select Help → Intall new Software →
@@ -311,7 +249,11 @@
where $LOGBACK_HOME stands for the location where you cloned the
logback project from github </li>
-
+ <li>In case they exist, remove <em>.settings</em>,
+ <em>.classpath</em>, <em>.project</em> folders (again if any)
+ under $LOGBACK_HOME and its sub-folders. Somehow, this step seems
+ to be crucial.</li>
+
<li>From the command line, run <code>mvn eclipse:eclipse</code>
in $LOGBACK_HOME</li>
@@ -319,52 +261,27 @@
General→ Existing Projects into Workspace, select
$LOGBACK_HOME folder for the import
</li>
-
- <!--
- <li>In Eclipse, remove the
- "**/EvaluatorTemplate.groovy" inclusion pattern from
- the
- logback-classic/src/main/groovy build path (logback-classic→
- project properties → Java Build Path) as shown next:
-
- <p><img src="images/setup/remove_evaluator_template.jpg"/> </p>
-
- </li>
- -->
-
- <!--
- <li>In Eclipse, remove the
+
+ <li>In Eclipse, remove the
logback-classic/target/generated-sources/groovy-stubs/main
directory from the list of source folders (logback-classic→
- project properties → Java Build Path) as shown next.
-
- <p><img src="images/setup/remove_gen_src.jpg"/> </p>
-
+ project properties → Java Build Path)
</li>
- -->
<li>In Eclipse, clean all projects in Eclipse (Project →
Clean)
</li>
- <li>In Eclipse, select logback-classic project and check that it has
- "Groovy" nature. If not add it by right clicking on logback-classic project →
- Groovy → Convert Groovy to Project.
+ <li>In Eclipse, select logback-classic project and convert it to
+ "Groovy project" (right click on logback-classic project →
+ Configure → Convert Groovy to Project)
</li>
</ol>
<p>The above listed procedure has been last tested by the author
- using Eclipse Luna on February 25th, 2016.</p>
-
-
- <p><span class="label notice">Call for volunteers</span> Given that many
- users prefer M2Eclipse for building projects under Eclipse IDE, we
- are looking for volunteers to help work out the steps for building
- logback with M2Eclipse.
- </p>
-
+ using Eclipse Juno on April 4th 2013.</p>
<script src="templates/footer.js" type="text/javascript"></script>
</div>
diff --git a/docs/templates/creative.js b/docs/templates/creative.js
index d9badf7..78b2b40 100644
--- a/docs/templates/creative.js
+++ b/docs/templates/creative.js
@@ -5,7 +5,7 @@ document.write(' <td> ');
document.write(' <p class="author">');
document.write(' Authors: Ceki Gülcü, Sébastien Pennec, Carl Harris');
document.write(' <br/>');
-document.write(' Copyright © 2000-2016, QOS.ch</p>');
+document.write(' Copyright © 2000-2012, QOS.ch</p>');
document.write(' </td>');
document.write(' <td>');
document.write(' <a rel="license"');
diff --git a/docs/templates/footer.js b/docs/templates/footer.js
index 73f766f..0f4685b 100644
--- a/docs/templates/footer.js
+++ b/docs/templates/footer.js
@@ -3,7 +3,7 @@ document.write('<table class="footer" border="0">')
document.write('<tr>')
-document.write('<td valign="top">Copyright © 2017 <a href="http://www.qos.ch/">QOS.ch</a></td>')
+document.write('<td valign="top">Copyright © 2013 <a href="http://www.qos.ch/">QOS.ch</a></td>')
document.write(' <td rowspan="2">');
document.write(' <a href="http://twitter.com/qos_ch">');
diff --git a/docs/templates/left.js b/docs/templates/left.js
index 5a0c278..cf769dd 100644
--- a/docs/templates/left.js
+++ b/docs/templates/left.js
@@ -26,16 +26,6 @@ document.write('<p class="menu"><a href="http://logback.qos.ch/translator/asGroo
document.write('</p>');
document.write('</div>');
-document.write('<p> </p>');
+document.write('<p/>');
-document.write('<div class="pub">');
-document.write(' <a href="http://twitter.com/qos_ch" style="">');
-document.write(' <img alt="Follow @qos_ch" src="images/follow_us.png" />');
-document.write(' </a>');
-document.write('</div>');
-
-document.write('<p> </p>');
-document.write('<div class="pub"><img src="https://travis-ci.org/qos-ch/logback.svg?branch=master"/></div>');
-
-
-//document.write('<div class="jobadd"><p><a href="'+prefix +'job.html">Your career<br/>@QOS.ch</a></p></div>');
\ No newline at end of file
+document.write('<div class="jobadd"><p><a href="'+prefix +'job.html">Your career<br/>@QOS.ch</a></p></div>');
\ No newline at end of file
diff --git a/docs/templates/right.js b/docs/templates/right.js
index c8d4a0d..493ae09 100644
--- a/docs/templates/right.js
+++ b/docs/templates/right.js
@@ -1,11 +1,19 @@
-document.write(' <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>');
-// <!-- SLF4J -->
-document.write(' <ins class="adsbygoogle"');
-document.write(' style="display:block"');
-document.write(' data-ad-client="ca-pub-7471410671306824"');
-document.write(' data-ad-slot="6377851613"');
-document.write(' data-ad-format="auto"></ins>');
-document.write(' <script>');
-document.write(' (adsbygoogle = window.adsbygoogle || []).push({});');
-document.write(' </script>;');
+//document.write('<p class="menu"><a href="'+prefix+'10reasons.ppt">10 reasons for migrating</a>')
+document.write('<p class="menu_header">New and noteworthy</p>')
+
+document.write('<p class="menu"><a href="http://stubbisms.wordpress.com/2008/07/15/some-serious-logging-niceness-logback-with-eclipse-plugin/">Logging niceness</a>')
+
+document.write('<p class="menu"><a href="http://wimpi.coalevo.net/2008/04/logger-name-based-filtering-in-logback.html">Filtering by logger name</a>')
+
+document.write('<p class="menu"><a href="http://out-println.blogspot.com/2007/09/slf4j-and-logback.html">SLF4J and Logback</a>')
+
+
+document.write('<p class="menu"><a href="http://wizardforge.org/pc?action=showVersion&id=72">Configuration Wizard</a>')
+
+document.write('<p class="menu"><a href="http://xhab.blogspot.com/2007/03/new-logging-experience.html">A new logging experience!</a>')
+
+document.write('<p class="menu"><a href="http://javablog.smilehouse.com/blog/default/Java/2007/02/02/Writing-rotated-and-compressed-access-logs-with-logback">Writing rotated and compressed access logs</a>')
+
+
+document.write('</p>')
diff --git a/docs/volunteer.html b/docs/volunteer.html
index e1b4612..5a5fd36 100644
--- a/docs/volunteer.html
+++ b/docs/volunteer.html
@@ -17,10 +17,6 @@
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="templates/right.js" type="text/javascript"></script>
- </div>
-
<div id="content">
diff --git a/logback-access/pom.xml b/logback-access/pom.xml
index 8b82c18..12639e1 100644
--- a/logback-access/pom.xml
+++ b/logback-access/pom.xml
@@ -1,13 +1,13 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-parent</artifactId>
- <version>1.1.9</version>
+ <version>1.1.2</version>
</parent>
<artifactId>logback-access</artifactId>
@@ -15,47 +15,68 @@
<name>Logback Access Module</name>
<description>logback-access module</description>
+ <url>http://logback.qos.ch</url>
+
+ <licenses>
+ <license>
+ <name>Eclipse Public License - v 1.0</name>
+ <url>http://www.eclipse.org/legal/epl-v10.html</url>
+ </license>
+
+ <license>
+ <name>GNU Lesser General Public License</name>
+ <url>http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</url>
+ </license>
+ </licenses>
+
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<scope>compile</scope>
</dependency>
+
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
+
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-coyote</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
+
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
+
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
+
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
@@ -66,9 +87,11 @@
<build>
<plugins>
+
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
+ <version>${maven-surefire-plugin.version}</version>
<configuration>
<forkMode>once</forkMode>
<!--<parallel>classes</parallel>-->
@@ -81,9 +104,11 @@
</excludes>
</configuration>
</plugin>
+
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
+ <version>${maven-jar-plugin.version}</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF
@@ -131,18 +156,21 @@
org.eclipse.jetty.*;version="${jetty.version}";resolution:=optional,
*
</Import-Package>
- <Bundle-RequiredExecutionEnvironment>JavaSE-1.6
+ <Bundle-RequiredExecutionEnvironment>J2SE-1.5
</Bundle-RequiredExecutionEnvironment>
</instructions>
</configuration>
</plugin>
+
</plugins>
</build>
+
<profiles>
<profile>
<!-- Integration tests require the host-orion profile -->
<id>host-orion</id>
+
<dependencies>
<dependency>
<groupId>mysql</groupId>
@@ -150,11 +178,13 @@
<version>5.0.8</version>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>8.2-507.jdbc3</version>
</dependency>
+
<!-- locally installed artifact -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
@@ -170,7 +200,10 @@
<scope>test</scope>
</dependency>
</dependencies>
+
</profile>
+
</profiles>
+
</project>
\ No newline at end of file
diff --git a/logback-access/src/main/java/ch/qos/logback/access/AccessConstants.java b/logback-access/src/main/java/ch/qos/logback/access/AccessConstants.java
index 927ce25..8b82174 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/AccessConstants.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/AccessConstants.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,19 +14,19 @@
package ch.qos.logback.access;
public class AccessConstants {
+
+ public static final String LOGBACK_STATUS_MANAGER_KEY = "LOGBACK_STATUS_MANAGER";
+ public static final String LB_INPUT_BUFFER = "LB_INPUT_BUFFER";
+ public static final String LB_OUTPUT_BUFFER = "LB_OUTPUT_BUFFER";
+
+ public static final String X_WWW_FORM_URLECODED = "application/x-www-form-urlencoded";
+
+ public static final String IMAGE_CONTENT_TYPE = "image/";
+ public static final String IMAGE_JPEG = "image/jpeg";
+ public static final String IMAGE_GIF = "image/gif";
+ public static final String IMAGE_PNG = "image/png";
- public static final String LOGBACK_STATUS_MANAGER_KEY = "LOGBACK_STATUS_MANAGER";
- public static final String LB_INPUT_BUFFER = "LB_INPUT_BUFFER";
- public static final String LB_OUTPUT_BUFFER = "LB_OUTPUT_BUFFER";
-
- public static final String X_WWW_FORM_URLECODED = "application/x-www-form-urlencoded";
-
- public static final String IMAGE_CONTENT_TYPE = "image/";
- public static final String IMAGE_JPEG = "image/jpeg";
- public static final String IMAGE_GIF = "image/gif";
- public static final String IMAGE_PNG = "image/png";
-
- public static final String TEE_FILTER_INCLUDES_PARAM = "includes";
- public static final String TEE_FILTER_EXCLUDES_PARAM = "excludes";
+ public static final String TEE_FILTER_INCLUDES_PARAM = "includes";
+ public static final String TEE_FILTER_EXCLUDES_PARAM = "excludes";
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java b/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java
index 25d713f..3a58f4d 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,7 +15,6 @@ package ch.qos.logback.access;
import ch.qos.logback.access.pattern.ContentLengthConverter;
import ch.qos.logback.access.pattern.DateConverter;
-import ch.qos.logback.access.pattern.ElapsedSecondsConverter;
import ch.qos.logback.access.pattern.ElapsedTimeConverter;
import ch.qos.logback.access.pattern.EnsureLineSeparation;
import ch.qos.logback.access.pattern.FullRequestConverter;
@@ -24,7 +23,6 @@ import ch.qos.logback.access.pattern.LineSeparatorConverter;
import ch.qos.logback.access.pattern.LocalIPAddressConverter;
import ch.qos.logback.access.pattern.LocalPortConverter;
import ch.qos.logback.access.pattern.NAConverter;
-import ch.qos.logback.access.pattern.QueryStringConverter;
import ch.qos.logback.access.pattern.RemoteHostConverter;
import ch.qos.logback.access.pattern.RemoteIPAddressConverter;
import ch.qos.logback.access.pattern.RemoteUserConverter;
@@ -40,9 +38,7 @@ import ch.qos.logback.access.pattern.RequestURLConverter;
import ch.qos.logback.access.pattern.ResponseContentConverter;
import ch.qos.logback.access.pattern.ResponseHeaderConverter;
import ch.qos.logback.access.pattern.ServerNameConverter;
-import ch.qos.logback.access.pattern.SessionIDConverter;
import ch.qos.logback.access.pattern.StatusCodeConverter;
-import ch.qos.logback.access.pattern.ThreadNameConverter;
import ch.qos.logback.access.spi.IAccessEvent;
import ch.qos.logback.core.pattern.PatternLayoutBase;
import ch.qos.logback.core.pattern.color.*;
@@ -68,150 +64,152 @@ import java.util.Map;
*/
public class PatternLayout extends PatternLayoutBase<IAccessEvent> {
- public static final Map<String, String> defaultConverterMap = new HashMap<String, String>();
- public static final String HEADER_PREFIX = "#logback.access pattern: ";
+ public static final Map<String, String> defaultConverterMap = new HashMap<String, String>();
+ public static final String HEADER_PREFIX = "#logback.access pattern: ";
- public static final String CLF_PATTERN = "%h %l %u [%t] \"%r\" %s %b";
- public static final String CLF_PATTERN_NAME = "common";
- public static final String CLF_PATTERN_NAME_2 = "clf";
- public static final String COMBINED_PATTERN = "%h %l %u [%t] \"%r\" %s %b \"%i{Referer}\" \"%i{User-Agent}\"";
- public static final String COMBINED_PATTERN_NAME = "combined";
+ public static final String CLF_PATTERN = "%h %l %u [%t] \"%r\" %s %b";
+ public static final String CLF_PATTERN_NAME = "common";
+ public static final String CLF_PATTERN_NAME_2 = "clf";
+ public static final String COMBINED_PATTERN = "%h %l %u [%t] \"%r\" %s %b \"%i{Referer}\" \"%i{User-Agent}\"";
+ public static final String COMBINED_PATTERN_NAME = "combined";
- static {
- defaultConverterMap.putAll(Parser.DEFAULT_COMPOSITE_CONVERTER_MAP);
+ static {
+ defaultConverterMap.putAll(Parser.DEFAULT_COMPOSITE_CONVERTER_MAP);
- defaultConverterMap.put("a", RemoteIPAddressConverter.class.getName());
- defaultConverterMap.put("remoteIP", RemoteIPAddressConverter.class.getName());
+ defaultConverterMap.put("a", RemoteIPAddressConverter.class.getName());
+ defaultConverterMap.put("remoteIP", RemoteIPAddressConverter.class
+ .getName());
- defaultConverterMap.put("A", LocalIPAddressConverter.class.getName());
- defaultConverterMap.put("localIP", LocalIPAddressConverter.class.getName());
+ defaultConverterMap.put("A", LocalIPAddressConverter.class.getName());
+ defaultConverterMap.put("localIP", LocalIPAddressConverter.class.getName());
- defaultConverterMap.put("b", ContentLengthConverter.class.getName());
- defaultConverterMap.put("B", ContentLengthConverter.class.getName());
- defaultConverterMap.put("bytesSent", ContentLengthConverter.class.getName());
+ defaultConverterMap.put("b", ContentLengthConverter.class.getName());
+ defaultConverterMap.put("B", ContentLengthConverter.class.getName());
+ defaultConverterMap
+ .put("bytesSent", ContentLengthConverter.class.getName());
- defaultConverterMap.put("h", RemoteHostConverter.class.getName());
- defaultConverterMap.put("clientHost", RemoteHostConverter.class.getName());
+ defaultConverterMap.put("h", RemoteHostConverter.class.getName());
+ defaultConverterMap.put("clientHost", RemoteHostConverter.class.getName());
- defaultConverterMap.put("H", RequestProtocolConverter.class.getName());
- defaultConverterMap.put("protocol", RequestProtocolConverter.class.getName());
+ defaultConverterMap.put("H", RequestProtocolConverter.class.getName());
+ defaultConverterMap.put("protocol", RequestProtocolConverter.class
+ .getName());
- defaultConverterMap.put("i", RequestHeaderConverter.class.getName());
- defaultConverterMap.put("header", RequestHeaderConverter.class.getName());
+ defaultConverterMap.put("i", RequestHeaderConverter.class.getName());
+ defaultConverterMap.put("header", RequestHeaderConverter.class.getName());
- defaultConverterMap.put("I", ThreadNameConverter.class.getName());
- defaultConverterMap.put("threadName", ThreadNameConverter.class.getName());
-
- defaultConverterMap.put("l", NAConverter.class.getName());
+ defaultConverterMap.put("l", NAConverter.class.getName());
- defaultConverterMap.put("m", RequestMethodConverter.class.getName());
- defaultConverterMap.put("requestMethod", RequestMethodConverter.class.getName());
+ defaultConverterMap.put("m", RequestMethodConverter.class.getName());
+ defaultConverterMap.put("requestMethod", RequestMethodConverter.class
+ .getName());
- defaultConverterMap.put("q", QueryStringConverter.class.getName());
- defaultConverterMap.put("queryString", QueryStringConverter.class.getName());
-
- defaultConverterMap.put("r", RequestURLConverter.class.getName());
- defaultConverterMap.put("requestURL", RequestURLConverter.class.getName());
+ defaultConverterMap.put("r", RequestURLConverter.class.getName());
+ defaultConverterMap.put("requestURL", RequestURLConverter.class.getName());
- defaultConverterMap.put("s", StatusCodeConverter.class.getName());
- defaultConverterMap.put("statusCode", StatusCodeConverter.class.getName());
+ defaultConverterMap.put("s", StatusCodeConverter.class.getName());
+ defaultConverterMap.put("statusCode", StatusCodeConverter.class.getName());
- defaultConverterMap.put("S", SessionIDConverter.class.getName());
- defaultConverterMap.put("sessionID", SessionIDConverter.class.getName());
-
- defaultConverterMap.put("t", DateConverter.class.getName());
- defaultConverterMap.put("date", DateConverter.class.getName());
+ defaultConverterMap.put("t", DateConverter.class.getName());
+ defaultConverterMap.put("date", DateConverter.class.getName());
- defaultConverterMap.put("u", RemoteUserConverter.class.getName());
- defaultConverterMap.put("user", RemoteUserConverter.class.getName());
+ defaultConverterMap.put("u", RemoteUserConverter.class.getName());
+ defaultConverterMap.put("user", RemoteUserConverter.class.getName());
- defaultConverterMap.put("U", RequestURIConverter.class.getName());
- defaultConverterMap.put("requestURI", RequestURIConverter.class.getName());
+ defaultConverterMap.put("U", RequestURIConverter.class.getName());
+ defaultConverterMap.put("requestURI", RequestURIConverter.class.getName());
- defaultConverterMap.put("v", ServerNameConverter.class.getName());
- defaultConverterMap.put("server", ServerNameConverter.class.getName());
+ defaultConverterMap.put("v", ServerNameConverter.class.getName());
+ defaultConverterMap.put("server", ServerNameConverter.class.getName());
- defaultConverterMap.put("localPort", LocalPortConverter.class.getName());
+ defaultConverterMap.put("localPort", LocalPortConverter.class.getName());
- defaultConverterMap.put("requestAttribute", RequestAttributeConverter.class.getName());
- defaultConverterMap.put("reqAttribute", RequestAttributeConverter.class.getName());
+ defaultConverterMap.put("requestAttribute", RequestAttributeConverter.class
+ .getName());
+ defaultConverterMap.put("reqAttribute", RequestAttributeConverter.class
+ .getName());
- defaultConverterMap.put("reqCookie", RequestCookieConverter.class.getName());
- defaultConverterMap.put("requestCookie", RequestCookieConverter.class.getName());
+ defaultConverterMap
+ .put("reqCookie", RequestCookieConverter.class.getName());
+ defaultConverterMap
+ .put("requestCookie", RequestCookieConverter.class.getName());
- defaultConverterMap.put("responseHeader", ResponseHeaderConverter.class.getName());
- defaultConverterMap.put("requestParameter", RequestParameterConverter.class.getName());
- defaultConverterMap.put("reqParameter", RequestParameterConverter.class.getName());
+ defaultConverterMap.put("responseHeader", ResponseHeaderConverter.class
+ .getName());
- defaultConverterMap.put("requestContent", RequestContentConverter.class.getName());
- defaultConverterMap.put("responseContent", ResponseContentConverter.class.getName());
+ defaultConverterMap.put("requestParameter", RequestParameterConverter.class
+ .getName());
+ defaultConverterMap.put("reqParameter", RequestParameterConverter.class
+ .getName());
- defaultConverterMap.put("fullRequest", FullRequestConverter.class.getName());
- defaultConverterMap.put("fullResponse", FullResponseConverter.class.getName());
+ defaultConverterMap.put("requestContent", RequestContentConverter.class.getName());
- defaultConverterMap.put("elapsedTime", ElapsedTimeConverter.class.getName());
- defaultConverterMap.put("D", ElapsedTimeConverter.class.getName());
+ defaultConverterMap.put("responseContent", ResponseContentConverter.class.getName());
- defaultConverterMap.put("elapsedSeconds", ElapsedSecondsConverter.class.getName());
- defaultConverterMap.put("T", ElapsedSecondsConverter.class.getName());
-
- defaultConverterMap.put("n", LineSeparatorConverter.class.getName());
+ defaultConverterMap.put("fullRequest", FullRequestConverter.class.getName());
+ defaultConverterMap.put("fullResponse", FullResponseConverter.class.getName());
- defaultConverterMap.put("black", BlackCompositeConverter.class.getName());
- defaultConverterMap.put("red", RedCompositeConverter.class.getName());
- defaultConverterMap.put("green", GreenCompositeConverter.class.getName());
- defaultConverterMap.put("yellow", YellowCompositeConverter.class.getName());
- defaultConverterMap.put("blue", BlueCompositeConverter.class.getName());
- defaultConverterMap.put("magenta", MagentaCompositeConverter.class.getName());
- defaultConverterMap.put("cyan", CyanCompositeConverter.class.getName());
- defaultConverterMap.put("white", WhiteCompositeConverter.class.getName());
- defaultConverterMap.put("gray", GrayCompositeConverter.class.getName());
- defaultConverterMap.put("boldRed", BoldRedCompositeConverter.class.getName());
- defaultConverterMap.put("boldGreen", BoldGreenCompositeConverter.class.getName());
- defaultConverterMap.put("boldYellow", BoldYellowCompositeConverter.class.getName());
- defaultConverterMap.put("boldBlue", BoldBlueCompositeConverter.class.getName());
- defaultConverterMap.put("boldMagenta", BoldMagentaCompositeConverter.class.getName());
- defaultConverterMap.put("boldCyan", BoldCyanCompositeConverter.class.getName());
- defaultConverterMap.put("boldWhite", BoldWhiteCompositeConverter.class.getName());
- }
+ defaultConverterMap.put("elapsedTime", ElapsedTimeConverter.class.getName());
+ defaultConverterMap.put("D", ElapsedTimeConverter.class.getName());
- public PatternLayout() {
- // set a default value for pattern
- setPattern(CLF_PATTERN);
- // by default postCompileProcessor the is an EnsureLineSeparation instance
- this.postCompileProcessor = new EnsureLineSeparation();
- }
+ defaultConverterMap.put("n", LineSeparatorConverter.class.getName());
- /**
- * Returns the default converter map for this instance.
- */
- @Override
- public Map<String, String> getDefaultConverterMap() {
- return defaultConverterMap;
- }
+ defaultConverterMap.put("black", BlackCompositeConverter.class.getName());
+ defaultConverterMap.put("red", RedCompositeConverter.class.getName());
+ defaultConverterMap.put("green", GreenCompositeConverter.class.getName());
+ defaultConverterMap.put("yellow", YellowCompositeConverter.class.getName());
+ defaultConverterMap.put("blue", BlueCompositeConverter.class.getName());
+ defaultConverterMap.put("magenta", MagentaCompositeConverter.class.getName());
+ defaultConverterMap.put("cyan", CyanCompositeConverter.class.getName());
+ defaultConverterMap.put("white", WhiteCompositeConverter.class.getName());
+ defaultConverterMap.put("gray", GrayCompositeConverter.class.getName());
+ defaultConverterMap.put("boldRed", BoldRedCompositeConverter.class.getName());
+ defaultConverterMap.put("boldGreen", BoldGreenCompositeConverter.class.getName());
+ defaultConverterMap.put("boldYellow", BoldYellowCompositeConverter.class.getName());
+ defaultConverterMap.put("boldBlue", BoldBlueCompositeConverter.class.getName());
+ defaultConverterMap.put("boldMagenta", BoldMagentaCompositeConverter.class.getName());
+ defaultConverterMap.put("boldCyan", BoldCyanCompositeConverter.class.getName());
+ defaultConverterMap.put("boldWhite", BoldWhiteCompositeConverter.class.getName());
+ }
- @Override
- public String doLayout(IAccessEvent event) {
- if (!isStarted()) {
- return null;
- }
- return writeLoopOnConverters(event);
- }
- @Override
- public void start() {
- if (getPattern().equalsIgnoreCase(CLF_PATTERN_NAME) || getPattern().equalsIgnoreCase(CLF_PATTERN_NAME_2)) {
- setPattern(CLF_PATTERN);
- } else if (getPattern().equalsIgnoreCase(COMBINED_PATTERN_NAME)) {
- setPattern(COMBINED_PATTERN);
- }
- super.start();
- }
+ public PatternLayout() {
+ // set a default value for pattern
+ setPattern(CLF_PATTERN);
+ // by default postCompileProcessor the is an EnsureLineSeparation instance
+ this.postCompileProcessor = new EnsureLineSeparation();
+ }
- @Override
- protected String getPresentationHeaderPrefix() {
- return HEADER_PREFIX;
+ /**
+ * Returns the default converter map for this instance.
+ */
+ public Map<String, String> getDefaultConverterMap() {
+ return defaultConverterMap;
+ }
+
+ public String doLayout(IAccessEvent event) {
+ if (!isStarted()) {
+ return null;
+ }
+ return writeLoopOnConverters(event);
+ }
+
+ @Override
+ public void start() {
+ if (getPattern().equalsIgnoreCase(CLF_PATTERN_NAME)
+ || getPattern().equalsIgnoreCase(CLF_PATTERN_NAME_2)) {
+ setPattern(CLF_PATTERN);
+ } else if (getPattern().equalsIgnoreCase(COMBINED_PATTERN_NAME)) {
+ setPattern(COMBINED_PATTERN);
}
+ super.start();
+ }
+
+
+ @Override
+ protected String getPresentationHeaderPrefix() {
+ return HEADER_PREFIX;
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/PatternLayoutEncoder.java b/logback-access/src/main/java/ch/qos/logback/access/PatternLayoutEncoder.java
index 87aba19..f49270b 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/PatternLayoutEncoder.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/PatternLayoutEncoder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,16 +16,17 @@ package ch.qos.logback.access;
import ch.qos.logback.access.spi.IAccessEvent;
import ch.qos.logback.core.pattern.PatternLayoutEncoderBase;
-public class PatternLayoutEncoder extends PatternLayoutEncoderBase<IAccessEvent> {
- @Override
- public void start() {
- PatternLayout patternLayout = new PatternLayout();
- patternLayout.setContext(context);
- patternLayout.setPattern(getPattern());
- patternLayout.start();
- this.layout = patternLayout;
- super.start();
- }
+public class PatternLayoutEncoder extends PatternLayoutEncoderBase<IAccessEvent> {
+ @Override
+ public void start() {
+ PatternLayout patternLayout = new PatternLayout();
+ patternLayout.setContext(context);
+ patternLayout.setPattern(getPattern());
+ patternLayout.start();
+ this.layout = patternLayout;
+ super.start();
+ }
+
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/ViewStatusMessagesServlet.java b/logback-access/src/main/java/ch/qos/logback/access/ViewStatusMessagesServlet.java
index a9f86f3..d43ce1e 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/ViewStatusMessagesServlet.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/ViewStatusMessagesServlet.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,28 +22,30 @@ import ch.qos.logback.core.status.ViewStatusMessagesServletBase;
public class ViewStatusMessagesServlet extends ViewStatusMessagesServletBase {
- private static final long serialVersionUID = 443878494348593337L;
-
- @Override
- protected StatusManager getStatusManager(HttpServletRequest req, HttpServletResponse resp) {
-
- ServletContext sc = getServletContext();
- return (StatusManager) sc.getAttribute(AccessConstants.LOGBACK_STATUS_MANAGER_KEY);
-
- // if (result != null) {
- // System.out.println("from ServletContext");
- // return result;
- // } else {
- // HttpSession httpSession = req.getSession(true);
- //
- // System.out.println("from httpSession");
- // return (StatusManager) httpSession
- // .getAttribute(AccessConstants.LOGBACK_STATUS_MANAGER_KEY);
- // }
- }
-
- @Override
- protected String getPageTitle(HttpServletRequest req, HttpServletResponse resp) {
- return "<h2>Status messages for logback-access</h2>\r\n";
- }
+ private static final long serialVersionUID = 443878494348593337L;
+
+ @Override
+ protected StatusManager getStatusManager(HttpServletRequest req,
+ HttpServletResponse resp) {
+
+ ServletContext sc = getServletContext();
+ return (StatusManager) sc
+ .getAttribute(AccessConstants.LOGBACK_STATUS_MANAGER_KEY);
+
+// if (result != null) {
+// System.out.println("from ServletContext");
+// return result;
+// } else {
+// HttpSession httpSession = req.getSession(true);
+//
+// System.out.println("from httpSession");
+// return (StatusManager) httpSession
+// .getAttribute(AccessConstants.LOGBACK_STATUS_MANAGER_KEY);
+// }
+ }
+
+ @Override
+ protected String getPageTitle(HttpServletRequest req, HttpServletResponse resp) {
+ return "<h2>Status messages for logback-access</h2>\r\n";
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/boolex/JaninoEventEvaluator.java b/logback-access/src/main/java/ch/qos/logback/access/boolex/JaninoEventEvaluator.java
index dc14ed3..7ac0a75 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/boolex/JaninoEventEvaluator.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/boolex/JaninoEventEvaluator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,62 +23,59 @@ import ch.qos.logback.core.boolex.Matcher;
public class JaninoEventEvaluator extends JaninoEventEvaluatorBase<IAccessEvent> {
- public final static List<String> DEFAULT_PARAM_NAME_LIST = new ArrayList<String>();
- public final static List<Class> DEFAULT_PARAM_TYPE_LIST = new ArrayList<Class>();
+ public final static List<String> DEFAULT_PARAM_NAME_LIST = new ArrayList<String>();
+ public final static List<Class> DEFAULT_PARAM_TYPE_LIST = new ArrayList<Class>();
- static {
- DEFAULT_PARAM_NAME_LIST.add("event");
- DEFAULT_PARAM_TYPE_LIST.add(IAccessEvent.class);
- }
+ static {
+ DEFAULT_PARAM_NAME_LIST.add("event");
+ DEFAULT_PARAM_TYPE_LIST.add(IAccessEvent.class);
+ }
- @Override
- protected String getDecoratedExpression() {
- String expression = getExpression();
- if (!expression.contains("return")) {
- expression = "return " + expression + ";";
- addInfo("Adding [return] prefix and a semicolon suffix. Expression becomes [" + expression + "]");
- addInfo("See also " + CoreConstants.CODES_URL + "#block");
- }
- return expression;
- }
- @Override
- protected String[] getParameterNames() {
- List<String> fullNameList = new ArrayList<String>();
- fullNameList.addAll(DEFAULT_PARAM_NAME_LIST);
+ protected String getDecoratedExpression() {
+ String expression = getExpression();
+ if (!expression.contains("return")) {
+ expression = "return " + expression + ";";
+ addInfo("Adding [return] prefix and a semicolon suffix. Expression becomes [" + expression + "]");
+ addInfo("See also " + CoreConstants.CODES_URL + "#block");
+ }
+ return expression;
+ }
- for (int i = 0; i < matcherList.size(); i++) {
- Matcher m = (Matcher) matcherList.get(i);
- fullNameList.add(m.getName());
- }
+ protected String[] getParameterNames() {
+ List<String> fullNameList = new ArrayList<String>();
+ fullNameList.addAll(DEFAULT_PARAM_NAME_LIST);
- return (String[]) fullNameList.toArray(CoreConstants.EMPTY_STRING_ARRAY);
+ for (int i = 0; i < matcherList.size(); i++) {
+ Matcher m = (Matcher) matcherList.get(i);
+ fullNameList.add(m.getName());
}
- @Override
- protected Class[] getParameterTypes() {
- List<Class> fullTypeList = new ArrayList<Class>();
- fullTypeList.addAll(DEFAULT_PARAM_TYPE_LIST);
- for (int i = 0; i < matcherList.size(); i++) {
- fullTypeList.add(Matcher.class);
- }
- return (Class[]) fullTypeList.toArray(CoreConstants.EMPTY_CLASS_ARRAY);
- }
+ return (String[]) fullNameList.toArray(CoreConstants.EMPTY_STRING_ARRAY);
+ }
- @Override
- protected Object[] getParameterValues(IAccessEvent accessEvent) {
- final int matcherListSize = matcherList.size();
+ protected Class[] getParameterTypes() {
+ List<Class> fullTypeList = new ArrayList<Class>();
+ fullTypeList.addAll(DEFAULT_PARAM_TYPE_LIST);
+ for (int i = 0; i < matcherList.size(); i++) {
+ fullTypeList.add(Matcher.class);
+ }
+ return (Class[]) fullTypeList.toArray(CoreConstants.EMPTY_CLASS_ARRAY);
+ }
- int i = 0;
- Object[] values = new Object[DEFAULT_PARAM_NAME_LIST.size() + matcherListSize];
+ protected Object[] getParameterValues(IAccessEvent accessEvent) {
+ final int matcherListSize = matcherList.size();
- values[i++] = accessEvent;
+ int i = 0;
+ Object[] values = new Object[DEFAULT_PARAM_NAME_LIST.size() + matcherListSize];
- for (int j = 0; j < matcherListSize; j++) {
- values[i++] = matcherList.get(j);
- }
+ values[i++] = accessEvent;
- return values;
+ for (int j = 0; j < matcherListSize; j++) {
+ values[i++] = matcherList.get(j);
}
+ return values;
+ }
+
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/db/DBAppender.java b/logback-access/src/main/java/ch/qos/logback/access/db/DBAppender.java
index 211b2a6..2383566 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/db/DBAppender.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/db/DBAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -34,107 +34,113 @@ import ch.qos.logback.core.db.DBAppenderBase;
* @author Sébastien Pennec
*/
public class DBAppender extends DBAppenderBase<IAccessEvent> {
- protected static final String insertSQL;
- protected final String insertHeaderSQL = "INSERT INTO access_event_header (event_id, header_key, header_value) VALUES (?, ?, ?)";
- protected static final Method GET_GENERATED_KEYS_METHOD;
-
- private boolean insertHeaders = false;
-
- static {
- StringBuilder sql = new StringBuilder();
- sql.append("INSERT INTO access_event (");
- sql.append("timestmp, ");
- sql.append("requestURI, ");
- sql.append("requestURL, ");
- sql.append("remoteHost, ");
- sql.append("remoteUser, ");
- sql.append("remoteAddr, ");
- sql.append("protocol, ");
- sql.append("method, ");
- sql.append("serverName, ");
- sql.append("postContent) ");
- sql.append(" VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?, ?)");
- insertSQL = sql.toString();
-
- Method getGeneratedKeysMethod;
- try {
- getGeneratedKeysMethod = PreparedStatement.class.getMethod("getGeneratedKeys", (Class[]) null);
- } catch (Exception ex) {
- getGeneratedKeysMethod = null;
- }
- GET_GENERATED_KEYS_METHOD = getGeneratedKeysMethod;
+ protected static final String insertSQL;
+ protected final String insertHeaderSQL = "INSERT INTO access_event_header (event_id, header_key, header_value) VALUES (?, ?, ?)";
+ protected static final Method GET_GENERATED_KEYS_METHOD;
+
+ private boolean insertHeaders = false;
+
+ static {
+ StringBuilder sql = new StringBuilder();
+ sql.append("INSERT INTO access_event (");
+ sql.append("timestmp, ");
+ sql.append("requestURI, ");
+ sql.append("requestURL, ");
+ sql.append("remoteHost, ");
+ sql.append("remoteUser, ");
+ sql.append("remoteAddr, ");
+ sql.append("protocol, ");
+ sql.append("method, ");
+ sql.append("serverName, ");
+ sql.append("postContent) ");
+ sql.append(" VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?, ?)");
+ insertSQL = sql.toString();
+
+ Method getGeneratedKeysMethod;
+ try {
+ getGeneratedKeysMethod = PreparedStatement.class.getMethod(
+ "getGeneratedKeys", (Class[]) null);
+ } catch (Exception ex) {
+ getGeneratedKeysMethod = null;
}
-
- @Override
- protected void subAppend(IAccessEvent event, Connection connection, PreparedStatement insertStatement) throws Throwable {
-
- addAccessEvent(insertStatement, event);
-
- int updateCount = insertStatement.executeUpdate();
- if (updateCount != 1) {
- addWarn("Failed to insert access event");
- }
- }
-
- @Override
- protected void secondarySubAppend(IAccessEvent event, Connection connection, long eventId) throws Throwable {
- if (insertHeaders) {
- addRequestHeaders(event, connection, eventId);
- }
+ GET_GENERATED_KEYS_METHOD = getGeneratedKeysMethod;
+ }
+
+ @Override
+ protected void subAppend(IAccessEvent event, Connection connection,
+ PreparedStatement insertStatement) throws Throwable {
+
+ addAccessEvent(insertStatement, event);
+
+ int updateCount = insertStatement.executeUpdate();
+ if (updateCount != 1) {
+ addWarn("Failed to insert access event");
}
-
- void addAccessEvent(PreparedStatement stmt, IAccessEvent event) throws SQLException {
- stmt.setLong(1, event.getTimeStamp());
- stmt.setString(2, event.getRequestURI());
- stmt.setString(3, event.getRequestURL());
- stmt.setString(4, event.getRemoteHost());
- stmt.setString(5, event.getRemoteUser());
- stmt.setString(6, event.getRemoteAddr());
- stmt.setString(7, event.getProtocol());
- stmt.setString(8, event.getMethod());
- stmt.setString(9, event.getServerName());
- stmt.setString(10, event.getRequestContent());
+ }
+
+ protected void secondarySubAppend(IAccessEvent event, Connection connection,
+ long eventId) throws Throwable {
+ if (insertHeaders) {
+ addRequestHeaders(event, connection, eventId);
}
-
- void addRequestHeaders(IAccessEvent event, Connection connection, long eventId) throws SQLException {
- Enumeration names = event.getRequestHeaderNames();
- if (names.hasMoreElements()) {
- PreparedStatement insertHeaderStatement = connection.prepareStatement(insertHeaderSQL);
-
- while (names.hasMoreElements()) {
- String key = (String) names.nextElement();
- String value = (String) event.getRequestHeader(key);
-
- insertHeaderStatement.setLong(1, eventId);
- insertHeaderStatement.setString(2, key);
- insertHeaderStatement.setString(3, value);
-
- if (cnxSupportsBatchUpdates) {
- insertHeaderStatement.addBatch();
- } else {
- insertHeaderStatement.execute();
- }
- }
-
- if (cnxSupportsBatchUpdates) {
- insertHeaderStatement.executeBatch();
- }
-
- insertHeaderStatement.close();
+ }
+
+ void addAccessEvent(PreparedStatement stmt, IAccessEvent event)
+ throws SQLException {
+ stmt.setLong(1, event.getTimeStamp());
+ stmt.setString(2, event.getRequestURI());
+ stmt.setString(3, event.getRequestURL());
+ stmt.setString(4, event.getRemoteHost());
+ stmt.setString(5, event.getRemoteUser());
+ stmt.setString(6, event.getRemoteAddr());
+ stmt.setString(7, event.getProtocol());
+ stmt.setString(8, event.getMethod());
+ stmt.setString(9, event.getServerName());
+ stmt.setString(10, event.getRequestContent());
+ }
+
+ void addRequestHeaders(IAccessEvent event,
+ Connection connection, long eventId) throws SQLException {
+ Enumeration names = event.getRequestHeaderNames();
+ if (names.hasMoreElements()) {
+ PreparedStatement insertHeaderStatement = connection
+ .prepareStatement(insertHeaderSQL);
+
+
+ while (names.hasMoreElements()) {
+ String key = (String) names.nextElement();
+ String value = (String) event.getRequestHeader(key);
+
+ insertHeaderStatement.setLong(1, eventId);
+ insertHeaderStatement.setString(2, key);
+ insertHeaderStatement.setString(3, value);
+
+ if (cnxSupportsBatchUpdates) {
+ insertHeaderStatement.addBatch();
+ } else {
+ insertHeaderStatement.execute();
}
- }
+ }
- @Override
- protected Method getGeneratedKeysMethod() {
- return GET_GENERATED_KEYS_METHOD;
- }
-
- @Override
- protected String getInsertSQL() {
- return insertSQL;
- }
+ if (cnxSupportsBatchUpdates) {
+ insertHeaderStatement.executeBatch();
+ }
- public void setInsertHeaders(boolean insertHeaders) {
- this.insertHeaders = insertHeaders;
+ insertHeaderStatement.close();
}
+ }
+
+ @Override
+ protected Method getGeneratedKeysMethod() {
+ return GET_GENERATED_KEYS_METHOD;
+ }
+
+ @Override
+ protected String getInsertSQL() {
+ return insertSQL;
+ }
+
+ public void setInsertHeaders(boolean insertHeaders) {
+ this.insertHeaders = insertHeaders;
+ }
}
diff --git a/logback-access/src/main/resources/ch/qos/logback/access/db/script/db2.sql b/logback-access/src/main/java/ch/qos/logback/access/db/script/db2.sql
similarity index 100%
rename from logback-access/src/main/resources/ch/qos/logback/access/db/script/db2.sql
rename to logback-access/src/main/java/ch/qos/logback/access/db/script/db2.sql
diff --git a/logback-access/src/main/resources/ch/qos/logback/access/db/script/db2l.sql b/logback-access/src/main/java/ch/qos/logback/access/db/script/db2l.sql
similarity index 100%
rename from logback-access/src/main/resources/ch/qos/logback/access/db/script/db2l.sql
rename to logback-access/src/main/java/ch/qos/logback/access/db/script/db2l.sql
diff --git a/logback-access/src/main/resources/ch/qos/logback/access/db/script/hsqldb.sql b/logback-access/src/main/java/ch/qos/logback/access/db/script/hsqldb.sql
similarity index 100%
rename from logback-access/src/main/resources/ch/qos/logback/access/db/script/hsqldb.sql
rename to logback-access/src/main/java/ch/qos/logback/access/db/script/hsqldb.sql
diff --git a/logback-access/src/main/resources/ch/qos/logback/access/db/script/msSQLServer.sql b/logback-access/src/main/java/ch/qos/logback/access/db/script/msSQLServer.sql
similarity index 100%
rename from logback-access/src/main/resources/ch/qos/logback/access/db/script/msSQLServer.sql
rename to logback-access/src/main/java/ch/qos/logback/access/db/script/msSQLServer.sql
diff --git a/logback-access/src/main/resources/ch/qos/logback/access/db/script/mysql.sql b/logback-access/src/main/java/ch/qos/logback/access/db/script/mysql.sql
similarity index 100%
rename from logback-access/src/main/resources/ch/qos/logback/access/db/script/mysql.sql
rename to logback-access/src/main/java/ch/qos/logback/access/db/script/mysql.sql
diff --git a/logback-access/src/main/resources/ch/qos/logback/access/db/script/oracle.sql b/logback-access/src/main/java/ch/qos/logback/access/db/script/oracle.sql
similarity index 100%
rename from logback-access/src/main/resources/ch/qos/logback/access/db/script/oracle.sql
rename to logback-access/src/main/java/ch/qos/logback/access/db/script/oracle.sql
diff --git a/logback-access/src/main/resources/ch/qos/logback/access/db/script/postgresql.sql b/logback-access/src/main/java/ch/qos/logback/access/db/script/postgresql.sql
similarity index 100%
rename from logback-access/src/main/resources/ch/qos/logback/access/db/script/postgresql.sql
rename to logback-access/src/main/java/ch/qos/logback/access/db/script/postgresql.sql
diff --git a/logback-access/src/main/java/ch/qos/logback/access/filter/CountingFilter.java b/logback-access/src/main/java/ch/qos/logback/access/filter/CountingFilter.java
index c53bde4..6ae1a46 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/filter/CountingFilter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/filter/CountingFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -11,7 +11,7 @@
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
-package ch.qos.logback.access.filter;
+ package ch.qos.logback.access.filter;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;
@@ -23,60 +23,61 @@ import java.lang.management.ManagementFactory;
public class CountingFilter extends Filter {
- long total = 0;
- final StatisticalViewImpl accessStatsImpl;
+ long total = 0;
+ final StatisticalViewImpl accessStatsImpl;
+
+ String domain = "ch.qos.logback.access";
+
+ public CountingFilter() {
+ accessStatsImpl = new StatisticalViewImpl(this);
+ }
+
+ @Override
+ public FilterReply decide(Object event) {
+ total++;
+ accessStatsImpl.update();
+ return FilterReply.NEUTRAL;
+ }
- String domain = "ch.qos.logback.access";
-
- public CountingFilter() {
- accessStatsImpl = new StatisticalViewImpl(this);
- }
-
- @Override
- public FilterReply decide(Object event) {
- total++;
- accessStatsImpl.update();
- return FilterReply.NEUTRAL;
+ public long getTotal() {
+ return total;
+ }
+
+
+ @Override
+ public void start() {
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ try {
+ ObjectName on = new ObjectName(domain+":Name="+getName());
+ StandardMBean mbean = new StandardMBean(accessStatsImpl, StatisticalView.class);
+ if (mbs.isRegistered(on)) {
+ mbs.unregisterMBean(on);
+ }
+ mbs.registerMBean(mbean, on);
+ super.start();
+ } catch (Exception e) {
+ addError("Failed to create mbean", e);
}
-
- public long getTotal() {
- return total;
- }
-
- @Override
- public void start() {
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- try {
- ObjectName on = new ObjectName(domain + ":Name=" + getName());
- StandardMBean mbean = new StandardMBean(accessStatsImpl, StatisticalView.class);
- if (mbs.isRegistered(on)) {
- mbs.unregisterMBean(on);
- }
- mbs.registerMBean(mbean, on);
- super.start();
- } catch (Exception e) {
- addError("Failed to create mbean", e);
- }
+ }
+
+ @Override
+ public void stop() {
+ super.stop();
+ try {
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ ObjectName on = new ObjectName("totp:Filter=1");
+ mbs.unregisterMBean(on);
+ } catch(Exception e) {
+ addError("Failed to unregister mbean", e);
}
+ }
- @Override
- public void stop() {
- super.stop();
- try {
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- ObjectName on = new ObjectName("totp:Filter=1");
- mbs.unregisterMBean(on);
- } catch (Exception e) {
- addError("Failed to unregister mbean", e);
- }
- }
-
- public String getDomain() {
- return domain;
- }
-
- public void setDomain(String domain) {
- this.domain = domain;
- }
+ public String getDomain() {
+ return domain;
+ }
+ public void setDomain(String domain) {
+ this.domain = domain;
+ }
+
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/filter/PeriodicStats.java b/logback-access/src/main/java/ch/qos/logback/access/filter/PeriodicStats.java
index 7055f77..6b7e6e1 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/filter/PeriodicStats.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/filter/PeriodicStats.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,52 +13,53 @@
*/
package ch.qos.logback.access.filter;
-abstract public class PeriodicStats {
-
- private long nextPeriodBegins = 0;
- private long lastTotal = 0;
- private long lastCount = 0;
-
- private double average;
- private int n;
-
- PeriodicStats() {
- this(System.currentTimeMillis());
- }
-
- PeriodicStats(long now) {
- nextPeriodBegins = computeStartOfNextPeriod(now);
- }
- void update(long now, long total) {
- if (now > nextPeriodBegins) {
- lastCount = total - lastTotal;
- lastTotal = total;
- average = (average * n + lastCount) / (++n);
- nextPeriodBegins = computeStartOfNextPeriod(now);
- }
- }
-
- public double getAverage() {
- return average;
- }
-
- public long getLastCount() {
- return lastCount;
- }
+abstract public class PeriodicStats {
+
+ private long nextPeriodBegins = 0;
+ private long lastTotal = 0;
+ private long lastCount = 0;
- void reset(long now) {
- nextPeriodBegins = computeStartOfNextPeriod(now);
- lastTotal = 0;
- lastCount = 0;
- average = 0.0;
- n = 0;
+ private double average;
+ private int n;
+
+ PeriodicStats() {
+ this(System.currentTimeMillis());
+ }
+
+ PeriodicStats(long now) {
+ nextPeriodBegins = computeStartOfNextPeriod(now);
+ }
+
+ void update(long now, long total) {
+ if (now > nextPeriodBegins) {
+ lastCount = total - lastTotal;
+ lastTotal = total;
+ average = (average * n + lastCount) / (++n);
+ nextPeriodBegins = computeStartOfNextPeriod(now);
}
+ }
- void reset() {
- reset(System.currentTimeMillis());
- }
+ public double getAverage() {
+ return average;
+ }
- abstract long computeStartOfNextPeriod(long now);
+ public long getLastCount() {
+ return lastCount;
+ }
+
+ void reset(long now) {
+ nextPeriodBegins = computeStartOfNextPeriod(now);
+ lastTotal = 0;
+ lastCount = 0;
+ average = 0.0;
+ n = 0;
+ }
+
+ void reset() {
+ reset(System.currentTimeMillis());
+ }
+
+ abstract long computeStartOfNextPeriod(long now);
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/filter/StatisticalView.java b/logback-access/src/main/java/ch/qos/logback/access/filter/StatisticalView.java
index 3901779..efe21d0 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/filter/StatisticalView.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/filter/StatisticalView.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,26 +15,25 @@ package ch.qos.logback.access.filter;
public interface StatisticalView {
- long getTotal();
-
- long getLastMinuteCount();
-
- double getMinuteAverage();
-
- long getLastHoursCount();
-
- double getHourlyAverage();
-
- long getLastDaysCount();
-
- double getDailyAverage();
-
- long getLastWeeksCount();
-
- double getWeeklyAverage();
-
- long getLastMonthsCount();
-
- double getMonthlyAverage();
-
+
+ long getTotal();
+
+ long getLastMinuteCount();
+ double getMinuteAverage();
+
+
+ long getLastHoursCount();
+ double getHourlyAverage();
+
+
+ long getLastDaysCount();
+ double getDailyAverage();
+
+
+ long getLastWeeksCount();
+ double getWeeklyAverage();
+
+ long getLastMonthsCount();
+ double getMonthlyAverage();
+
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/filter/StatisticalViewImpl.java b/logback-access/src/main/java/ch/qos/logback/access/filter/StatisticalViewImpl.java
index d0dad45..4217a12 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/filter/StatisticalViewImpl.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/filter/StatisticalViewImpl.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,114 +17,100 @@ import ch.qos.logback.core.spi.LifeCycle;
public class StatisticalViewImpl implements StatisticalView, LifeCycle {
- final CountingFilter countingFilter;
- boolean started;
-
- StatsByMinute statsByMinute = new StatsByMinute();
- StatsByHour statsByHour = new StatsByHour();
- StatsByDay statsByDay = new StatsByDay();
- StatsByWeek statsByWeek = new StatsByWeek();
- StatsByMonth statsByMonth = new StatsByMonth();
-
- StatisticalViewImpl(CountingFilter countingFilter) {
- this.countingFilter = countingFilter;
- }
-
- @Override
- public double getDailyAverage() {
- return statsByDay.getAverage();
- }
-
- @Override
- public long getLastDaysCount() {
- return statsByDay.getLastCount();
- }
-
- @Override
- public double getMonthlyAverage() {
- return statsByMonth.getAverage();
- }
-
- @Override
- public long getLastMonthsCount() {
- return statsByMonth.getLastCount();
- }
-
- @Override
- public long getTotal() {
- return countingFilter.getTotal();
- }
-
- @Override
- public double getWeeklyAverage() {
- return statsByWeek.getAverage();
- }
-
- @Override
- public long getLastWeeksCount() {
- return statsByWeek.getLastCount();
- }
-
- void update(long now) {
- long total = getTotal();
- statsByMinute.update(now, total);
- statsByHour.update(now, total);
- statsByDay.update(now, total);
- statsByWeek.update(now, total);
- statsByMonth.update(now, total);
-
- }
-
- void update() {
- long now = System.currentTimeMillis();
- update(now);
- }
-
- @Override
- public void start() {
- System.out.println("StatisticalViewImpl start called");
- started = true;
- long now = System.currentTimeMillis();
- statsByMinute = new StatsByMinute(now);
- statsByHour = new StatsByHour(now);
- statsByDay = new StatsByDay(now);
- statsByWeek = new StatsByWeek(now);
- statsByMonth = new StatsByMonth(now);
- }
-
- @Override
- public boolean isStarted() {
- return started;
- }
-
- @Override
- public void stop() {
- started = false;
- statsByMinute.reset();
- statsByHour.reset();
- statsByDay.reset();
- statsByWeek.reset();
- statsByMonth.reset();
- }
-
- @Override
- public long getLastMinuteCount() {
- return statsByMinute.getLastCount();
- }
-
- @Override
- public double getMinuteAverage() {
- return statsByMinute.getAverage();
- }
-
- @Override
- public double getHourlyAverage() {
- return statsByHour.getAverage();
- }
-
- @Override
- public long getLastHoursCount() {
- return statsByHour.getLastCount();
- }
+ final CountingFilter countingFilter;
+ boolean started;
+
+ StatsByMinute statsByMinute = new StatsByMinute();
+ StatsByHour statsByHour = new StatsByHour();
+ StatsByDay statsByDay = new StatsByDay();
+ StatsByWeek statsByWeek = new StatsByWeek();
+ StatsByMonth statsByMonth = new StatsByMonth();
+
+ StatisticalViewImpl(CountingFilter countingFilter) {
+ this.countingFilter = countingFilter;
+ }
+
+ public double getDailyAverage() {
+ return statsByDay.getAverage();
+ }
+
+ public long getLastDaysCount() {
+ return statsByDay.getLastCount();
+ }
+
+ public double getMonthlyAverage() {
+ return statsByMonth.getAverage();
+ }
+
+ public long getLastMonthsCount() {
+ return statsByMonth.getLastCount();
+ }
+
+ public long getTotal() {
+ return countingFilter.getTotal();
+ }
+
+ public double getWeeklyAverage() {
+ return statsByWeek.getAverage();
+ }
+
+ public long getLastWeeksCount() {
+ return statsByWeek.getLastCount();
+ }
+
+ void update(long now) {
+ long total = getTotal();
+ statsByMinute.update(now, total);
+ statsByHour.update(now, total);
+ statsByDay.update(now, total);
+ statsByWeek.update(now, total);
+ statsByMonth.update(now, total);
+
+ }
+
+ void update() {
+ long now = System.currentTimeMillis();
+ update(now);
+ }
+
+ public void start() {
+ System.out.println("StatisticalViewImpl start called");
+ started = true;
+ long now = System.currentTimeMillis();
+ statsByMinute = new StatsByMinute(now);
+ statsByHour = new StatsByHour(now);
+ statsByDay = new StatsByDay(now);
+ statsByWeek = new StatsByWeek(now);
+ statsByMonth = new StatsByMonth(now);
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public void stop() {
+ started = false;
+ statsByMinute.reset();
+ statsByHour.reset();
+ statsByDay.reset();
+ statsByWeek.reset();
+ statsByMonth.reset();
+ }
+
+ public long getLastMinuteCount() {
+ return statsByMinute.getLastCount();
+ }
+
+ public double getMinuteAverage() {
+ return statsByMinute.getAverage();
+ }
+
+ public double getHourlyAverage() {
+ return statsByHour.getAverage();
+ }
+
+ public long getLastHoursCount() {
+ return statsByHour.getLastCount();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByDay.java b/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByDay.java
index 131928b..65a4ab0 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByDay.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByDay.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,17 +17,17 @@ import ch.qos.logback.core.util.TimeUtil;
public class StatsByDay extends PeriodicStats {
- StatsByDay() {
- super();
- }
+ StatsByDay() {
+ super();
+ }
- StatsByDay(long now) {
- super(now);
- }
+ StatsByDay(long now) {
+ super(now);
+ }
- @Override
- long computeStartOfNextPeriod(long now) {
- return TimeUtil.computeStartOfNextDay(now);
- }
+ @Override
+ long computeStartOfNextPeriod(long now) {
+ return TimeUtil.computeStartOfNextDay(now);
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByHour.java b/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByHour.java
index 28fcb8d..f38af02 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByHour.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByHour.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,17 +17,17 @@ import ch.qos.logback.core.util.TimeUtil;
public class StatsByHour extends PeriodicStats {
- StatsByHour() {
- super();
- }
+ StatsByHour() {
+ super();
+ }
- StatsByHour(long now) {
- super(now);
- }
+ StatsByHour(long now) {
+ super(now);
+ }
- @Override
- long computeStartOfNextPeriod(long now) {
- return TimeUtil.computeStartOfNextHour(now);
- }
+ @Override
+ long computeStartOfNextPeriod(long now) {
+ return TimeUtil.computeStartOfNextHour(now);
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByMinute.java b/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByMinute.java
index 441de6e..c7d0d61 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByMinute.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByMinute.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,17 +17,17 @@ import ch.qos.logback.core.util.TimeUtil;
public class StatsByMinute extends PeriodicStats {
- StatsByMinute() {
- super();
- }
+ StatsByMinute() {
+ super();
+ }
- StatsByMinute(long now) {
- super(now);
- }
+ StatsByMinute(long now) {
+ super(now);
+ }
- @Override
- long computeStartOfNextPeriod(long now) {
- return TimeUtil.computeStartOfNextMinute(now);
- }
+ @Override
+ long computeStartOfNextPeriod(long now) {
+ return TimeUtil.computeStartOfNextMinute(now);
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByMonth.java b/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByMonth.java
index bc045f0..009e9c3 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByMonth.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByMonth.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,17 +17,17 @@ import ch.qos.logback.core.util.TimeUtil;
public class StatsByMonth extends PeriodicStats {
- StatsByMonth() {
- super();
- }
-
- StatsByMonth(long now) {
- super(now);
- }
-
- @Override
- long computeStartOfNextPeriod(long now) {
- return TimeUtil.computeStartOfNextMonth(now);
- }
-
+ StatsByMonth() {
+ super();
+ }
+
+ StatsByMonth(long now) {
+ super(now);
+ }
+
+ @Override
+ long computeStartOfNextPeriod(long now) {
+ return TimeUtil.computeStartOfNextMonth(now);
+ }
+
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByWeek.java b/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByWeek.java
index 94f5fc2..2ecf8cb 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByWeek.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/filter/StatsByWeek.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,17 +17,16 @@ import ch.qos.logback.core.util.TimeUtil;
public class StatsByWeek extends PeriodicStats {
- StatsByWeek() {
- super();
- }
-
- StatsByWeek(long now) {
- super(now);
- }
-
- @Override
- long computeStartOfNextPeriod(long now) {
- return TimeUtil.computeStartOfNextWeek(now);
- }
-
+ StatsByWeek() {
+ super();
+ }
+
+ StatsByWeek(long now) {
+ super(now);
+ }
+ @Override
+ long computeStartOfNextPeriod(long now) {
+ return TimeUtil.computeStartOfNextWeek(now);
+ }
+
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/html/DefaultCssBuilder.java b/logback-access/src/main/java/ch/qos/logback/access/html/DefaultCssBuilder.java
index 1fecfd6..5dc00af 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/html/DefaultCssBuilder.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/html/DefaultCssBuilder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,54 +25,56 @@ import ch.qos.logback.core.html.CssBuilder;
*/
public class DefaultCssBuilder implements CssBuilder {
- @Override
- public void addCss(StringBuilder sbuf) {
- sbuf.append("<style type=\"text/css\">");
- sbuf.append("table{ ");
- sbuf.append("margin-left: 2em; ");
- sbuf.append("margin-right: 2em; ");
- sbuf.append("border-left: 2px solid #AAA; ");
- sbuf.append("}");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("TR.even { ");
- sbuf.append("background: #FFFFFF; ");
- sbuf.append("}");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("TR.odd { ");
- sbuf.append("background: #EAEAEA; ");
- sbuf.append("}");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("TD {");
- sbuf.append("padding-right: 1ex; ");
- sbuf.append("padding-left: 1ex; ");
- sbuf.append("border-right: 2px solid #AAA;");
- sbuf.append("}");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("TD.Time, TD.Date { ");
- sbuf.append("text-align: right; ");
- sbuf.append("font-family: courier, monospace; ");
- sbuf.append("font-size: smaller; ");
- sbuf.append("}");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("TD.RemoteHost, TD.RequestProtocol, TD.RequestHeader, TD.RequestURL, TD.RemoteUser, TD.RequestURI, TD.ServerName {");
- sbuf.append("text-align: left; ");
- sbuf.append("}");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("TD.RequestAttribute, TD.RequestCookie, TD.ResponseHeader, TD.RequestParameter {");
- sbuf.append("text-align: left; ");
- sbuf.append("}");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("TD.RemoteIPAddress, TD.LocalIPAddress, TD.ContentLength, TD.StatusCode, TD.LocalPort {");
- sbuf.append("text-align: right; ");
- sbuf.append("}");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("TR.header { ");
- sbuf.append("background: #596ED5; ");
- sbuf.append("color: #FFF; ");
- sbuf.append("font-weight: bold; ");
- sbuf.append("font-size: larger; ");
- sbuf.append("}");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("</style>");
- }
+ public void addCss(StringBuilder sbuf) {
+ sbuf.append("<style type=\"text/css\">");
+ sbuf.append("table{ ");
+ sbuf.append("margin-left: 2em; ");
+ sbuf.append("margin-right: 2em; ");
+ sbuf.append("border-left: 2px solid #AAA; ");
+ sbuf.append("}");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append("TR.even { ");
+ sbuf.append("background: #FFFFFF; ");
+ sbuf.append("}");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append("TR.odd { ");
+ sbuf.append("background: #EAEAEA; ");
+ sbuf.append("}");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append("TD {");
+ sbuf.append("padding-right: 1ex; ");
+ sbuf.append("padding-left: 1ex; ");
+ sbuf.append("border-right: 2px solid #AAA;");
+ sbuf.append("}");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append("TD.Time, TD.Date { ");
+ sbuf.append("text-align: right; ");
+ sbuf.append("font-family: courier, monospace; ");
+ sbuf.append("font-size: smaller; ");
+ sbuf.append("}");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf
+ .append("TD.RemoteHost, TD.RequestProtocol, TD.RequestHeader, TD.RequestURL, TD.RemoteUser, TD.RequestURI, TD.ServerName {");
+ sbuf.append("text-align: left; ");
+ sbuf.append("}");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf
+ .append("TD.RequestAttribute, TD.RequestCookie, TD.ResponseHeader, TD.RequestParameter {");
+ sbuf.append("text-align: left; ");
+ sbuf.append("}");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf
+ .append("TD.RemoteIPAddress, TD.LocalIPAddress, TD.ContentLength, TD.StatusCode, TD.LocalPort {");
+ sbuf.append("text-align: right; ");
+ sbuf.append("}");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append("TR.header { ");
+ sbuf.append("background: #596ED5; ");
+ sbuf.append("color: #FFF; ");
+ sbuf.append("font-weight: bold; ");
+ sbuf.append("font-size: larger; ");
+ sbuf.append("}");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append("</style>");
+ }
}
\ No newline at end of file
diff --git a/logback-access/src/main/java/ch/qos/logback/access/html/HTMLLayout.java b/logback-access/src/main/java/ch/qos/logback/access/html/HTMLLayout.java
index 4b35dde..057dbd2 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/html/HTMLLayout.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/html/HTMLLayout.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -39,61 +39,61 @@ import ch.qos.logback.core.pattern.Converter;
*/
public class HTMLLayout extends HTMLLayoutBase<IAccessEvent> {
- /**
- * Default pattern string for log output.
- */
- static final String DEFAULT_CONVERSION_PATTERN = "%h%l%u%t%r%s%b";
+ /**
+ * Default pattern string for log output.
+ */
+ static final String DEFAULT_CONVERSION_PATTERN = "%h%l%u%t%r%s%b";
- /**
- * Constructs a PatternLayout using the DEFAULT_LAYOUT_PATTERN.
- *
- */
- public HTMLLayout() {
- pattern = DEFAULT_CONVERSION_PATTERN;
- cssBuilder = new DefaultCssBuilder();
- }
-
- @Override
- protected Map<String, String> getDefaultConverterMap() {
- return PatternLayout.defaultConverterMap;
- }
-
- @Override
- public String doLayout(IAccessEvent event) {
- StringBuilder buf = new StringBuilder();
- startNewTableIfLimitReached(buf);
+ /**
+ * Constructs a PatternLayout using the DEFAULT_LAYOUT_PATTERN.
+ *
+ */
+ public HTMLLayout() {
+ pattern = DEFAULT_CONVERSION_PATTERN;
+ cssBuilder = new DefaultCssBuilder();
+ }
+
+ @Override
+ protected Map<String, String> getDefaultConverterMap() {
+ return PatternLayout.defaultConverterMap;
+ }
- boolean odd = true;
- if (((counter++) & 1) == 0) {
- odd = false;
- }
+ public String doLayout(IAccessEvent event) {
+ StringBuilder buf = new StringBuilder();
+ startNewTableIfLimitReached(buf);
- buf.append(LINE_SEPARATOR);
- buf.append("<tr class=\"");
- if (odd) {
- buf.append(" odd\">");
- } else {
- buf.append(" even\">");
- }
- buf.append(LINE_SEPARATOR);
-
- Converter<IAccessEvent> c = head;
- while (c != null) {
- appendEventToBuffer(buf, c, event);
- c = c.getNext();
- }
- buf.append("</tr>");
- buf.append(LINE_SEPARATOR);
+ boolean odd = true;
+ if (((counter++) & 1) == 0) {
+ odd = false;
+ }
- return buf.toString();
+ buf.append(LINE_SEPARATOR);
+ buf.append("<tr class=\"");
+ if (odd) {
+ buf.append(" odd\">");
+ } else {
+ buf.append(" even\">");
}
+ buf.append(LINE_SEPARATOR);
- private void appendEventToBuffer(StringBuilder buf, Converter<IAccessEvent> c, IAccessEvent event) {
- buf.append("<td class=\"");
- buf.append(computeConverterName(c));
- buf.append("\">");
- c.write(buf, event);
- buf.append("</td>");
- buf.append(LINE_SEPARATOR);
+ Converter<IAccessEvent> c = head;
+ while (c != null) {
+ appendEventToBuffer(buf, c, event);
+ c = c.getNext();
}
+ buf.append("</tr>");
+ buf.append(LINE_SEPARATOR);
+
+ return buf.toString();
+ }
+
+ private void appendEventToBuffer(StringBuilder buf, Converter<IAccessEvent> c,
+ IAccessEvent event) {
+ buf.append("<td class=\"");
+ buf.append(computeConverterName(c));
+ buf.append("\">");
+ c.write(buf, event);
+ buf.append("</td>");
+ buf.append(LINE_SEPARATOR);
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/html/UrlCssBuilder.java b/logback-access/src/main/java/ch/qos/logback/access/html/UrlCssBuilder.java
index b43ebbe..05aa000 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/html/UrlCssBuilder.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/html/UrlCssBuilder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,6 +15,7 @@ package ch.qos.logback.access.html;
import ch.qos.logback.core.html.CssBuilder;
+
/**
* This class helps the HTMLLayout build the CSS link.
* It either provides the HTMLLayout with a default css file,
@@ -24,20 +25,19 @@ import ch.qos.logback.core.html.CssBuilder;
*/
public class UrlCssBuilder implements CssBuilder {
- String url = "http://logback.qos.ch/css/access.css";
-
- public String getUrl() {
- return url;
- }
-
- public void setUrl(String url) {
- this.url = url;
- }
-
- @Override
- public void addCss(StringBuilder sbuf) {
- sbuf.append("<link REL=StyleSheet HREF=\"");
- sbuf.append(url);
- sbuf.append("\" TITLE=\"Basic\" />");
- }
+ String url = "http://logback.qos.ch/css/access.css";
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public void addCss(StringBuilder sbuf) {
+ sbuf.append("<link REL=StyleSheet HREF=\"");
+ sbuf.append(url);
+ sbuf.append("\" TITLE=\"Basic\" />");
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java b/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java
index 1ef51de..6889706 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,7 +14,6 @@
package ch.qos.logback.access.jetty;
import ch.qos.logback.access.spi.ServerAdapter;
-
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
@@ -31,40 +30,36 @@ import java.util.Map;
*/
public class JettyServerAdapter implements ServerAdapter {
- Request request;
- Response response;
+ Request request;
+ Response response;
- public JettyServerAdapter(Request jettyRequest, Response jettyResponse) {
- this.request = jettyRequest;
- this.response = jettyResponse;
- }
+ public JettyServerAdapter(Request jettyRequest, Response jettyResponse) {
+ this.request = jettyRequest;
+ this.response = jettyResponse;
+ }
- @Override
- public long getContentLength() {
- return response.getContentCount();
- }
+ public long getContentLength() {
+ return response.getContentCount();
+ }
- @Override
- public int getStatusCode() {
- return response.getStatus();
- }
+ public int getStatusCode() {
+ return response.getStatus();
+ }
- @Override
- public long getRequestTimestamp() {
- return request.getTimeStamp();
- }
+ public long getRequestTimestamp() {
+ return request.getTimeStamp();
+ }
- @Override
- public Map<String, String> buildResponseHeaderMap() {
- Map<String, String> responseHeaderMap = new HashMap<String, String>();
- HttpFields httpFields = response.getHttpFields();
- Enumeration e = httpFields.getFieldNames();
- while (e.hasMoreElements()) {
- String key = (String) e.nextElement();
- String value = response.getHeader(key);
- responseHeaderMap.put(key, value);
- }
- return responseHeaderMap;
+ public Map<String, String> buildResponseHeaderMap() {
+ Map<String, String> responseHeaderMap = new HashMap<String, String>();
+ HttpFields httpFields = response.getHttpFields();
+ Enumeration e = httpFields.getFieldNames();
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+ String value = response.getHeader(key);
+ responseHeaderMap.put(key, value);
}
+ return responseHeaderMap;
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java b/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java
index 19b75f7..656f8f1 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,6 +14,8 @@
package ch.qos.logback.access.jetty;
import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URI;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
@@ -22,18 +24,17 @@ import java.util.List;
import ch.qos.logback.core.status.InfoStatus;
import ch.qos.logback.core.util.FileUtil;
import ch.qos.logback.core.util.StatusPrinter;
-
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.RequestLog;
import org.eclipse.jetty.server.Response;
+
import ch.qos.logback.access.joran.JoranConfigurator;
import ch.qos.logback.access.spi.AccessEvent;
import ch.qos.logback.access.spi.IAccessEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.CoreConstants;
-import ch.qos.logback.core.boolex.EventEvaluator;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.spi.AppenderAttachable;
@@ -42,6 +43,7 @@ import ch.qos.logback.core.spi.FilterAttachable;
import ch.qos.logback.core.spi.FilterAttachableImpl;
import ch.qos.logback.core.spi.FilterReply;
import ch.qos.logback.core.status.ErrorStatus;
+import ch.qos.logback.core.status.WarnStatus;
import ch.qos.logback.core.util.OptionHelper;
/**
@@ -112,212 +114,191 @@ import ch.qos.logback.core.util.OptionHelper;
* @author Ceki Gülcü
* @author Sébastien Pennec
*/
-public class RequestLogImpl extends ContextBase implements RequestLog, AppenderAttachable<IAccessEvent>, FilterAttachable<IAccessEvent> {
-
- public final static String DEFAULT_CONFIG_FILE = "etc" + File.separatorChar + "logback-access.xml";
-
- AppenderAttachableImpl<IAccessEvent> aai = new AppenderAttachableImpl<IAccessEvent>();
- FilterAttachableImpl<IAccessEvent> fai = new FilterAttachableImpl<IAccessEvent>();
- String fileName;
- String resource;
- boolean started = false;
- boolean quiet = false;
-
- public RequestLogImpl() {
- putObject(CoreConstants.EVALUATOR_MAP, new HashMap<String, EventEvaluator<?>>());
- }
-
- @Override
- public void log(Request jettyRequest, Response jettyResponse) {
- JettyServerAdapter adapter = new JettyServerAdapter(jettyRequest, jettyResponse);
- IAccessEvent accessEvent = new AccessEvent(jettyRequest, jettyResponse, adapter);
- if (getFilterChainDecision(accessEvent) == FilterReply.DENY) {
- return;
- }
- aai.appendLoopOnAppenders(accessEvent);
- }
-
- private void addInfo(String msg) {
- getStatusManager().add(new InfoStatus(msg, this));
- }
-
- private void addError(String msg) {
- getStatusManager().add(new ErrorStatus(msg, this));
- }
-
- @Override
- public void start() {
- configure();
- if (!isQuiet()) {
- StatusPrinter.print(getStatusManager());
- }
- started = true;
- }
-
- protected void configure() {
- URL configURL = getConfigurationFileURL();
- if (configURL != null) {
- runJoranOnFile(configURL);
- } else {
- addError("Could not find configuration file for logback-access");
- }
- }
-
- protected URL getConfigurationFileURL() {
- if (fileName != null) {
- addInfo("Will use configuration file [" + fileName + "]");
- File file = new File(fileName);
- if (!file.exists())
- return null;
- return FileUtil.fileToURL(file);
- }
- if (resource != null) {
- addInfo("Will use configuration resource [" + resource + "]");
- return this.getClass().getResource(resource);
- }
-
- String jettyHomeProperty = OptionHelper.getSystemProperty("jetty.home");
- String defaultConfigFile = DEFAULT_CONFIG_FILE;
- if (!OptionHelper.isEmpty(jettyHomeProperty)) {
- defaultConfigFile = jettyHomeProperty + File.separatorChar + DEFAULT_CONFIG_FILE;
- } else {
- addInfo("[jetty.home] system property not set.");
- }
- File file = new File(defaultConfigFile);
- addInfo("Assuming default configuration file [" + defaultConfigFile + "]");
- if (!file.exists())
- return null;
- return FileUtil.fileToURL(file);
- }
-
- private void runJoranOnFile(URL configURL) {
- try {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(this);
- jc.doConfigure(configURL);
- if (getName() == null) {
- setName("LogbackRequestLog");
- }
- } catch (JoranException e) {
- // errors have been registered as status messages
- }
- }
-
- @Override
- public void stop() {
- aai.detachAndStopAllAppenders();
- started = false;
- }
-
- @Override
- public boolean isRunning() {
- return started;
- }
-
- public void setFileName(String fileName) {
- this.fileName = fileName;
- }
-
- public void setResource(String resource) {
- this.resource = resource;
- }
-
- @Override
- public boolean isStarted() {
- return started;
- }
-
- @Override
- public boolean isStarting() {
- return false;
- }
-
- @Override
- public boolean isStopping() {
- return false;
- }
+public class RequestLogImpl extends ContextBase implements RequestLog,
+ AppenderAttachable<IAccessEvent>, FilterAttachable<IAccessEvent> {
+
+ public final static String DEFAULT_CONFIG_FILE = "etc" + File.separatorChar
+ + "logback-access.xml";
+
+ AppenderAttachableImpl<IAccessEvent> aai = new AppenderAttachableImpl<IAccessEvent>();
+ FilterAttachableImpl<IAccessEvent> fai = new FilterAttachableImpl<IAccessEvent>();
+ String fileName;
+ String resource;
+ boolean started = false;
+ boolean quiet = false;
+
+ public RequestLogImpl() {
+ putObject(CoreConstants.EVALUATOR_MAP, new HashMap());
+ }
+
+ public void log(Request jettyRequest, Response jettyResponse) {
+ JettyServerAdapter adapter = new JettyServerAdapter(jettyRequest,
+ jettyResponse);
+ IAccessEvent accessEvent = new AccessEvent(jettyRequest, jettyResponse,
+ adapter);
+ if (getFilterChainDecision(accessEvent) == FilterReply.DENY) {
+ return;
+ }
+ aai.appendLoopOnAppenders(accessEvent);
+ }
+
+ private void addInfo(String msg) {
+ getStatusManager().add(new InfoStatus(msg, this));
+ }
+
+ private void addError(String msg) {
+ getStatusManager().add(new ErrorStatus(msg, this));
+ }
+
+ public void start() {
+ URL configURL = getConfigurationFileURL();
+ if (configURL != null) {
+ runJoranOnFile(configURL);
+ } else {
+ addError("Could not find configuration file for logback-access");
+ }
+ if (!isQuiet()) {
+ StatusPrinter.print(getStatusManager());
+ }
+ started = true;
+ }
+
+ URL getConfigurationFileURL() {
+ if (fileName != null) {
+ addInfo("Will use configuration file [" + fileName + "]");
+ File file = new File(fileName);
+ if (!file.exists())
+ return null;
+ return FileUtil.fileToURL(file);
+ }
+ if (resource != null) {
+ addInfo("Will use configuration resource [" + resource + "]");
+ return this.getClass().getResource(resource);
+ }
+
+ String jettyHomeProperty = OptionHelper.getSystemProperty("jetty.home");
+ String defaultConfigFile = DEFAULT_CONFIG_FILE;
+ if (!OptionHelper.isEmpty(jettyHomeProperty)) {
+ defaultConfigFile = jettyHomeProperty + File.separatorChar + DEFAULT_CONFIG_FILE;
+ } else {
+ addInfo("[jetty.home] system property not set.");
+ }
+ File file = new File(defaultConfigFile);
+ addInfo("Assuming default configuration file ["+defaultConfigFile+"]");
+ if (!file.exists())
+ return null;
+ return FileUtil.fileToURL(file);
+ }
+
+ private void runJoranOnFile(URL configURL) {
+ try {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(this);
+ jc.doConfigure(configURL);
+ if (getName() == null) {
+ setName("LogbackRequestLog");
+ }
+ } catch (JoranException e) {
+ // errors have been registered as status messages
+ }
+ }
+
+ public void stop() {
+ aai.detachAndStopAllAppenders();
+ started = false;
+ }
+
+ public boolean isRunning() {
+ return started;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public void setResource(String resource) {
+ this.resource = resource;
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public boolean isStarting() {
+ return false;
+ }
+
+ public boolean isStopping() {
+ return false;
+ }
+
+ public boolean isStopped() {
+ return !started;
+ }
+
+ public boolean isFailed() {
+ return false;
+ }
+
+ public boolean isQuiet() {
+ return quiet;
+ }
+
+ public void setQuiet(boolean quiet) {
+ this.quiet = quiet;
+ }
+
+ public void addAppender(Appender<IAccessEvent> newAppender) {
+ aai.addAppender(newAppender);
+ }
+
+ public Iterator<Appender<IAccessEvent>> iteratorForAppenders() {
+ return aai.iteratorForAppenders();
+ }
+
+ public Appender<IAccessEvent> getAppender(String name) {
+ return aai.getAppender(name);
+ }
+
+ public boolean isAttached(Appender<IAccessEvent> appender) {
+ return aai.isAttached(appender);
+ }
+
+ public void detachAndStopAllAppenders() {
+ aai.detachAndStopAllAppenders();
+
+ }
+
+ public boolean detachAppender(Appender<IAccessEvent> appender) {
+ return aai.detachAppender(appender);
+ }
+
+ public boolean detachAppender(String name) {
+ return aai.detachAppender(name);
+ }
+
+ public void addFilter(Filter<IAccessEvent> newFilter) {
+ fai.addFilter(newFilter);
+ }
+
+ public void clearAllFilters() {
+ fai.clearAllFilters();
+ }
+
+ public List<Filter<IAccessEvent>> getCopyOfAttachedFiltersList() {
+ return fai.getCopyOfAttachedFiltersList();
+ }
+
+ public FilterReply getFilterChainDecision(IAccessEvent event) {
+ return fai.getFilterChainDecision(event);
+ }
+
+ public void addLifeCycleListener(Listener listener) {
+ // we'll implement this when asked
+ }
- @Override
- public boolean isStopped() {
- return !started;
- }
-
- @Override
- public boolean isFailed() {
- return false;
- }
-
- public boolean isQuiet() {
- return quiet;
- }
-
- public void setQuiet(boolean quiet) {
- this.quiet = quiet;
- }
-
- @Override
- public void addAppender(Appender<IAccessEvent> newAppender) {
- aai.addAppender(newAppender);
- }
-
- @Override
- public Iterator<Appender<IAccessEvent>> iteratorForAppenders() {
- return aai.iteratorForAppenders();
- }
-
- @Override
- public Appender<IAccessEvent> getAppender(String name) {
- return aai.getAppender(name);
- }
-
- @Override
- public boolean isAttached(Appender<IAccessEvent> appender) {
- return aai.isAttached(appender);
- }
-
- @Override
- public void detachAndStopAllAppenders() {
- aai.detachAndStopAllAppenders();
- }
-
- @Override
- public boolean detachAppender(Appender<IAccessEvent> appender) {
- return aai.detachAppender(appender);
- }
-
- @Override
- public boolean detachAppender(String name) {
- return aai.detachAppender(name);
- }
-
- @Override
- public void addFilter(Filter<IAccessEvent> newFilter) {
- fai.addFilter(newFilter);
- }
-
- @Override
- public void clearAllFilters() {
- fai.clearAllFilters();
- }
-
- @Override
- public List<Filter<IAccessEvent>> getCopyOfAttachedFiltersList() {
- return fai.getCopyOfAttachedFiltersList();
- }
-
- @Override
- public FilterReply getFilterChainDecision(IAccessEvent event) {
- return fai.getFilterChainDecision(event);
- }
-
- @Override
- public void addLifeCycleListener(Listener listener) {
- // we'll implement this when asked
- }
-
- @Override
- public void removeLifeCycleListener(Listener listener) {
- // we'll implement this when asked
- }
+ public void removeLifeCycleListener(Listener listener) {
+ // we'll implement this when asked
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogRegistry.java b/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogRegistry.java
index 5ad1fd8..9491abd 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogRegistry.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogRegistry.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,15 +18,15 @@ import java.util.Map;
// this class is currently not used
public class RequestLogRegistry {
-
- private static Map<String, RequestLogImpl> requestLogRegistry = new HashMap<String, RequestLogImpl>();
-
- public static void register(RequestLogImpl requestLogImpl) {
- requestLogRegistry.put(requestLogImpl.getName(), requestLogImpl);
- }
-
- public static RequestLogImpl get(String key) {
- return requestLogRegistry.get(key);
- }
+
+ private static Map<String, RequestLogImpl> requestLogRegistry = new HashMap<String, RequestLogImpl>();
+
+ public static void register(RequestLogImpl requestLogImpl) {
+ requestLogRegistry.put(requestLogImpl.getName(), requestLogImpl);
+ }
+
+ public static RequestLogImpl get(String key) {
+ return requestLogRegistry.get(key);
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/joran/JoranConfigurator.java b/logback-access/src/main/java/ch/qos/logback/access/joran/JoranConfigurator.java
index df84e40..1538797 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/joran/JoranConfigurator.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/joran/JoranConfigurator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.access.joran;
+
import ch.qos.logback.access.PatternLayout;
import ch.qos.logback.access.PatternLayoutEncoder;
import ch.qos.logback.access.boolex.JaninoEventEvaluator;
@@ -34,6 +35,8 @@ import ch.qos.logback.core.joran.spi.ElementSelector;
import ch.qos.logback.core.joran.spi.RuleStore;
import ch.qos.logback.core.net.ssl.SSLNestedComponentRegistryRules;
+
+
/**
* This JoranConfiguratorclass adds rules specific to logback-access.
*
@@ -41,36 +44,38 @@ import ch.qos.logback.core.net.ssl.SSLNestedComponentRegistryRules;
*/
public class JoranConfigurator extends JoranConfiguratorBase {
- @Override
- public void addInstanceRules(RuleStore rs) {
- super.addInstanceRules(rs);
-
- rs.addRule(new ElementSelector("configuration"), new ConfigurationAction());
- rs.addRule(new ElementSelector("configuration/appender-ref"), new AppenderRefAction());
-
- rs.addRule(new ElementSelector("configuration/appender/sift"), new SiftAction());
- rs.addRule(new ElementSelector("configuration/appender/sift/*"), new NOPAction());
-
- rs.addRule(new ElementSelector("configuration/evaluator"), new EvaluatorAction());
+ @Override
+ public void addInstanceRules(RuleStore rs) {
+ super.addInstanceRules(rs);
+
+ rs.addRule(new ElementSelector("configuration"), new ConfigurationAction());
+ rs.addRule(new ElementSelector("configuration/appender-ref"), new AppenderRefAction());
+
+ rs.addRule(new ElementSelector("configuration/appender/sift"), new SiftAction());
+ rs.addRule(new ElementSelector("configuration/appender/sift/*"), new NOPAction());
+
+ rs.addRule(new ElementSelector("configuration/evaluator"), new EvaluatorAction());
- // add if-then-else support
- rs.addRule(new ElementSelector("*/if"), new IfAction());
- rs.addRule(new ElementSelector("*/if/then"), new ThenAction());
- rs.addRule(new ElementSelector("*/if/then/*"), new NOPAction());
- rs.addRule(new ElementSelector("*/if/else"), new ElseAction());
- rs.addRule(new ElementSelector("*/if/else/*"), new NOPAction());
+ // add if-then-else support
+ rs.addRule(new ElementSelector("*/if"), new IfAction());
+ rs.addRule(new ElementSelector("*/if/then"), new ThenAction());
+ rs.addRule(new ElementSelector("*/if/then/*"), new NOPAction());
+ rs.addRule(new ElementSelector("*/if/else"), new ElseAction());
+ rs.addRule(new ElementSelector("*/if/else/*"), new NOPAction());
- rs.addRule(new ElementSelector("configuration/include"), new IncludeAction());
- }
+ rs.addRule(new ElementSelector("configuration/include"), new IncludeAction());
+ }
- @Override
- protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
- registry.add(AppenderBase.class, "layout", PatternLayout.class);
- registry.add(EvaluatorFilter.class, "evaluator", JaninoEventEvaluator.class);
+ @Override
+ protected void addDefaultNestedComponentRegistryRules(
+ DefaultNestedComponentRegistry registry) {
+ registry.add(AppenderBase.class, "layout", PatternLayout.class);
+ registry
+ .add(EvaluatorFilter.class, "evaluator", JaninoEventEvaluator.class);
- registry.add(AppenderBase.class, "encoder", PatternLayoutEncoder.class);
- registry.add(UnsynchronizedAppenderBase.class, "encoder", PatternLayoutEncoder.class);
- SSLNestedComponentRegistryRules.addDefaultNestedComponentRegistryRules(registry);
- }
+ registry.add(AppenderBase.class, "encoder", PatternLayoutEncoder.class);
+ registry.add(UnsynchronizedAppenderBase.class, "encoder", PatternLayoutEncoder.class);
+ SSLNestedComponentRegistryRules.addDefaultNestedComponentRegistryRules(registry);
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/joran/action/ConfigurationAction.java b/logback-access/src/main/java/ch/qos/logback/access/joran/action/ConfigurationAction.java
index ad4a396..f9383a2 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/joran/action/ConfigurationAction.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/joran/action/ConfigurationAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,44 +15,42 @@ package ch.qos.logback.access.joran.action;
import ch.qos.logback.core.status.OnConsoleStatusListener;
import ch.qos.logback.core.util.OptionHelper;
-import ch.qos.logback.core.util.StatusListenerConfigHelper;
-
import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.util.ContextUtil;
+import ch.qos.logback.core.util.StatusPrinter;
+
public class ConfigurationAction extends Action {
- static final String INTERNAL_DEBUG_ATTR = "debug";
- static final String DEBUG_SYSTEM_PROPERTY_KEY = "logback-access.debug";
-
- @Override
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
-
- // See LBCLASSIC-225 (the system property is looked up first. Thus, it overrides
- // the equivalent property in the config file. This reversal of scope priority is justified
- // by the use case: the admin trying to chase rogue config file
- String debugAttrib = System.getProperty(DEBUG_SYSTEM_PROPERTY_KEY);
- if (debugAttrib == null) {
- debugAttrib = attributes.getValue(INTERNAL_DEBUG_ATTR);
- }
-
- if (OptionHelper.isEmpty(debugAttrib) || debugAttrib.equals("false") || debugAttrib.equals("null")) {
- addInfo(INTERNAL_DEBUG_ATTR + " attribute not set");
- } else {
- StatusListenerConfigHelper.addOnConsoleListenerInstance(context, new OnConsoleStatusListener());
- }
-
- new ContextUtil(context).addHostNameAsProperty();
-
- // the context is appender attachable, so it is pushed on top of the stack
- ec.pushObject(getContext());
+ static final String INTERNAL_DEBUG_ATTR = "debug";
+ static final String DEBUG_SYSTEM_PROPERTY_KEY = "logback-access.debug";
+
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+
+ // See LBCLASSIC-225 (the system property is looked up first. Thus, it overrides
+ // the equivalent property in the config file. This reversal of scope priority is justified
+ // by the use case: the admin trying to chase rogue config file
+ String debugAttrib = System.getProperty(DEBUG_SYSTEM_PROPERTY_KEY);
+ if (debugAttrib == null) {
+ debugAttrib = attributes.getValue(INTERNAL_DEBUG_ATTR);
}
- @Override
- public void end(InterpretationContext ec, String name) {
- addInfo("End of configuration.");
- ec.popObject();
+ if (OptionHelper.isEmpty(debugAttrib) || debugAttrib.equals("false") || debugAttrib.equals("null")) {
+ addInfo(INTERNAL_DEBUG_ATTR + " attribute not set");
+ } else {
+ OnConsoleStatusListener.addNewInstanceToContext(context);
}
+
+ new ContextUtil(context).addHostNameAsProperty();
+
+ // the context is appender attachable, so it is pushed on top of the stack
+ ec.pushObject(getContext());
+ }
+
+ public void end(InterpretationContext ec, String name) {
+ addInfo("End of configuration.");
+ ec.popObject();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/joran/action/EvaluatorAction.java b/logback-access/src/main/java/ch/qos/logback/access/joran/action/EvaluatorAction.java
index b3cf2f1..471e4c5 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/joran/action/EvaluatorAction.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/joran/action/EvaluatorAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,10 +16,10 @@ package ch.qos.logback.access.joran.action;
import ch.qos.logback.access.boolex.JaninoEventEvaluator;
import ch.qos.logback.core.joran.action.AbstractEventEvaluatorAction;
+
public class EvaluatorAction extends AbstractEventEvaluatorAction {
- @Override
- protected String defaultClassName() {
- return JaninoEventEvaluator.class.getName();
- }
+ protected String defaultClassName() {
+ return JaninoEventEvaluator.class.getName();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/net/AccessEventPreSerializationTransformer.java b/logback-access/src/main/java/ch/qos/logback/access/net/AccessEventPreSerializationTransformer.java
index 40bf2c3..066bfe3 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/net/AccessEventPreSerializationTransformer.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/net/AccessEventPreSerializationTransformer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,15 +19,15 @@ import ch.qos.logback.access.spi.AccessEvent;
import ch.qos.logback.access.spi.IAccessEvent;
import ch.qos.logback.core.spi.PreSerializationTransformer;
-public class AccessEventPreSerializationTransformer implements PreSerializationTransformer<IAccessEvent> {
+public class AccessEventPreSerializationTransformer implements
+ PreSerializationTransformer<IAccessEvent> {
- @Override
- public Serializable transform(IAccessEvent event) {
- if (event instanceof AccessEvent) {
- return (AccessEvent) event;
- } else {
- throw new IllegalArgumentException("Unsupported type " + event.getClass().getName());
- }
+ public Serializable transform(IAccessEvent event) {
+ if (event instanceof AccessEvent) {
+ return (AccessEvent)event;
+ } else {
+ throw new IllegalArgumentException("Unsupported type "+event.getClass().getName());
}
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/net/SMTPAppender.java b/logback-access/src/main/java/ch/qos/logback/access/net/SMTPAppender.java
index 1558110..11e2c9e 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/net/SMTPAppender.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/net/SMTPAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -33,64 +33,61 @@ import ch.qos.logback.core.net.SMTPAppenderBase;
*/
public class SMTPAppender extends SMTPAppenderBase<IAccessEvent> {
- static final String DEFAULT_SUBJECT_PATTERN = "%m";
+ static final String DEFAULT_SUBJECT_PATTERN = "%m";
- /**
- * The default constructor will instantiate the appender with a
- * {@link EventEvaluator} that will trigger on events with level
- * ERROR or higher.
- */
- public SMTPAppender() {
- }
+ /**
+ * The default constructor will instantiate the appender with a
+ * {@link EventEvaluator} that will trigger on events with level
+ * ERROR or higher.
+ */
+ public SMTPAppender() {
+ }
- /**
- * Use <code>evaluator</code> passed as parameter as the {@link
- * EventEvaluator} for this SMTPAppender.
- */
- public SMTPAppender(EventEvaluator<IAccessEvent> evaluator) {
- this.eventEvaluator = evaluator;
- }
+ /**
+ * Use <code>evaluator</code> passed as parameter as the {@link
+ * EventEvaluator} for this SMTPAppender.
+ */
+ public SMTPAppender(EventEvaluator<IAccessEvent> evaluator) {
+ this.eventEvaluator = evaluator;
+ }
- /**
- * Perform SMTPAppender specific appending actions, mainly adding the event to
- * the appropriate cyclic buffer.
- */
- @Override
- protected void subAppend(CyclicBuffer<IAccessEvent> cb, IAccessEvent event) {
- cb.add(event);
- }
+ /**
+ * Perform SMTPAppender specific appending actions, mainly adding the event to
+ * the appropriate cyclic buffer.
+ */
+ protected void subAppend(CyclicBuffer<IAccessEvent> cb, IAccessEvent event) {
+ cb.add(event);
+ }
- @Override
- protected void fillBuffer(CyclicBuffer<IAccessEvent> cb, StringBuffer sbuf) {
- int len = cb.length();
- for (int i = 0; i < len; i++) {
- // sbuf.append(MimeUtility.encodeText(layout.format(cb.getOrCreate())));
- IAccessEvent event = cb.get();
- sbuf.append(layout.doLayout(event));
- }
+ @Override
+ protected void fillBuffer(CyclicBuffer<IAccessEvent> cb, StringBuffer sbuf) {
+ int len = cb.length();
+ for (int i = 0; i < len; i++) {
+ // sbuf.append(MimeUtility.encodeText(layout.format(cb.getOrCreate())));
+ IAccessEvent event = cb.get();
+ sbuf.append(layout.doLayout(event));
}
+ }
- @Override
- protected Layout<IAccessEvent> makeSubjectLayout(String subjectStr) {
- if (subjectStr == null) {
- subjectStr = DEFAULT_SUBJECT_PATTERN;
- }
- PatternLayout pl = new PatternLayout();
- pl.setPattern(subjectStr);
- pl.start();
- return pl;
+ @Override
+ protected Layout<IAccessEvent> makeSubjectLayout(String subjectStr) {
+ if(subjectStr == null) {
+ subjectStr = DEFAULT_SUBJECT_PATTERN;
}
+ PatternLayout pl = new PatternLayout();
+ pl.setPattern(subjectStr);
+ pl.start();
+ return pl;
+ }
- @Override
- protected PatternLayout makeNewToPatternLayout(String toPattern) {
- PatternLayout pl = new PatternLayout();
- pl.setPattern(toPattern);
- return pl;
- }
+ protected PatternLayout makeNewToPatternLayout(String toPattern) {
+ PatternLayout pl = new PatternLayout();
+ pl.setPattern(toPattern);
+ return pl;
+ }
- @Override
- protected boolean eventMarksEndOfLife(IAccessEvent eventObject) {
- return false;
- }
+ protected boolean eventMarksEndOfLife(IAccessEvent eventObject) {
+ return false;
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/net/SSLSocketAppender.java b/logback-access/src/main/java/ch/qos/logback/access/net/SSLSocketAppender.java
index defd231..0595dca 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/net/SSLSocketAppender.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/net/SSLSocketAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,8 @@
*/
package ch.qos.logback.access.net;
+import java.net.InetAddress;
+
import ch.qos.logback.access.spi.IAccessEvent;
import ch.qos.logback.core.net.AbstractSSLSocketAppender;
import ch.qos.logback.core.spi.PreSerializationTransformer;
@@ -27,18 +29,19 @@ import ch.qos.logback.core.spi.PreSerializationTransformer;
*/
public class SSLSocketAppender extends AbstractSSLSocketAppender<IAccessEvent> {
- private final PreSerializationTransformer<IAccessEvent> pst = new AccessEventPreSerializationTransformer();
-
- public SSLSocketAppender() {
- }
+ private final PreSerializationTransformer<IAccessEvent> pst =
+ new AccessEventPreSerializationTransformer();
- @Override
- protected void postProcessEvent(IAccessEvent event) {
- event.prepareForDeferredProcessing();
- }
+ public SSLSocketAppender() {
+ }
- public PreSerializationTransformer<IAccessEvent> getPST() {
- return pst;
- }
+ @Override
+ protected void postProcessEvent(IAccessEvent event) {
+ event.prepareForDeferredProcessing();
+ }
+ public PreSerializationTransformer<IAccessEvent> getPST() {
+ return pst;
+ }
+
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/net/SimpleSocketServer.java b/logback-access/src/main/java/ch/qos/logback/access/net/SimpleSocketServer.java
index fdabf94..d485778 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/net/SimpleSocketServer.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/net/SimpleSocketServer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -45,56 +45,57 @@ import ch.qos.logback.core.util.StatusPrinter;
*/
public class SimpleSocketServer {
- static int port;
+ static int port;
+
+ private static AccessContext basicContext;
- private static AccessContext basicContext;
+ public static void main(String argv[]) throws Exception {
+ if (argv.length == 2) {
+ init(argv[0], argv[1]);
+ } else {
+ usage("Wrong number of arguments.");
+ }
- public static void main(String argv[]) throws Exception {
- if (argv.length == 2) {
- init(argv[0], argv[1]);
- } else {
- usage("Wrong number of arguments.");
- }
+ runServer();
+ }
- runServer();
+ static void runServer() {
+ try {
+ System.out.println("Listening on port " + port);
+ ServerSocket serverSocket = new ServerSocket(port);
+ while (true) {
+ System.out.println("Waiting to accept a new client.");
+ Socket socket = serverSocket.accept();
+ System.out.println("Connected to client at " + socket.getInetAddress());
+ System.out.println("Starting new socket node.");
+ new Thread(new SocketNode(socket, basicContext)).start();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
}
+ }
- static void runServer() {
- try {
- System.out.println("Listening on port " + port);
- ServerSocket serverSocket = new ServerSocket(port);
- while (true) {
- System.out.println("Waiting to accept a new client.");
- Socket socket = serverSocket.accept();
- System.out.println("Connected to client at " + socket.getInetAddress());
- System.out.println("Starting new socket node.");
- new Thread(new SocketNode(socket, basicContext)).start();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + SimpleSocketServer.class.getName()
+ + " port configFile");
+ System.exit(1);
+ }
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + SimpleSocketServer.class.getName() + " port configFile");
- System.exit(1);
+ static void init(String portStr, String configFile) throws JoranException {
+ try {
+ port = Integer.parseInt(portStr);
+ } catch (java.lang.NumberFormatException e) {
+ e.printStackTrace();
+ usage("Could not interpret port number [" + portStr + "].");
}
- static void init(String portStr, String configFile) throws JoranException {
- try {
- port = Integer.parseInt(portStr);
- } catch (java.lang.NumberFormatException e) {
- e.printStackTrace();
- usage("Could not interpret port number [" + portStr + "].");
- }
-
- basicContext = new AccessContext();
- if (configFile.endsWith(".xml")) {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(basicContext);
- configurator.doConfigure(configFile);
- StatusPrinter.print(basicContext);
- }
+ basicContext = new AccessContext();
+ if (configFile.endsWith(".xml")) {
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(basicContext);
+ configurator.doConfigure(configFile);
+ StatusPrinter.print(basicContext);
}
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/net/SocketAppender.java b/logback-access/src/main/java/ch/qos/logback/access/net/SocketAppender.java
index b139ad1..6376eb0 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/net/SocketAppender.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/net/SocketAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,6 +14,8 @@
// Contributors: Dan MacDonald <dan at redknee.com>
package ch.qos.logback.access.net;
+import java.net.InetAddress;
+
import ch.qos.logback.access.spi.IAccessEvent;
import ch.qos.logback.core.net.AbstractSocketAppender;
import ch.qos.logback.core.spi.PreSerializationTransformer;
@@ -31,18 +33,18 @@ import ch.qos.logback.core.spi.PreSerializationTransformer;
*/
public class SocketAppender extends AbstractSocketAppender<IAccessEvent> {
+
+ PreSerializationTransformer<IAccessEvent> pst = new AccessEventPreSerializationTransformer();
+
+ public SocketAppender() {
+ }
- PreSerializationTransformer<IAccessEvent> pst = new AccessEventPreSerializationTransformer();
-
- public SocketAppender() {
- }
-
- @Override
- protected void postProcessEvent(IAccessEvent event) {
- event.prepareForDeferredProcessing();
- }
+ @Override
+ protected void postProcessEvent(IAccessEvent event) {
+ event.prepareForDeferredProcessing();
+ }
- public PreSerializationTransformer<IAccessEvent> getPST() {
- return pst;
- }
+ public PreSerializationTransformer<IAccessEvent> getPST() {
+ return pst;
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/net/SocketNode.java b/logback-access/src/main/java/ch/qos/logback/access/net/SocketNode.java
index e164774..32c6654 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/net/SocketNode.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/net/SocketNode.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -40,50 +40,50 @@ import ch.qos.logback.core.spi.FilterReply;
*/
public class SocketNode implements Runnable {
- Socket socket;
- AccessContext context;
- ObjectInputStream ois;
+ Socket socket;
+ AccessContext context;
+ ObjectInputStream ois;
- public SocketNode(Socket socket, AccessContext context) {
- this.socket = socket;
- this.context = context;
- try {
- ois = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
- } catch (Exception e) {
- System.out.println("Could not open ObjectInputStream to " + socket + e);
- }
+ public SocketNode(Socket socket, AccessContext context) {
+ this.socket = socket;
+ this.context = context;
+ try {
+ ois = new ObjectInputStream(new BufferedInputStream(socket
+ .getInputStream()));
+ } catch (Exception e) {
+ System.out.println("Could not open ObjectInputStream to " + socket + e);
}
+ }
- @Override
- public void run() {
- IAccessEvent event;
+ public void run() {
+ IAccessEvent event;
- try {
- while (true) {
- // read an event from the wire
- event = (IAccessEvent) ois.readObject();
- // check that the event should be logged
- if (context.getFilterChainDecision(event) == FilterReply.DENY) {
- break;
- }
- // send it to the appenders
- context.callAppenders(event);
- }
- } catch (java.io.EOFException e) {
- System.out.println("Caught java.io.EOFException closing connection.");
- } catch (java.net.SocketException e) {
- System.out.println("Caught java.net.SocketException closing connection.");
- } catch (IOException e) {
- System.out.println("Caught java.io.IOException: " + e);
- System.out.println("Closing connection.");
- } catch (Exception e) {
- System.out.println("Unexpected exception. Closing connection." + e);
+ try {
+ while (true) {
+ // read an event from the wire
+ event = (IAccessEvent) ois.readObject();
+ //check that the event should be logged
+ if (context.getFilterChainDecision(event) == FilterReply.DENY) {
+ break;
}
+ //send it to the appenders
+ context.callAppenders(event);
+ }
+ } catch (java.io.EOFException e) {
+ System.out.println("Caught java.io.EOFException closing connection.");
+ } catch (java.net.SocketException e) {
+ System.out.println("Caught java.net.SocketException closing connection.");
+ } catch (IOException e) {
+ System.out.println("Caught java.io.IOException: " + e);
+ System.out.println("Closing connection.");
+ } catch (Exception e) {
+ System.out.println("Unexpected exception. Closing connection." + e);
+ }
- try {
- ois.close();
- } catch (Exception e) {
- System.out.println("Could not close connection." + e);
- }
+ try {
+ ois.close();
+ } catch (Exception e) {
+ System.out.println("Could not close connection." + e);
}
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/net/URLEvaluator.java b/logback-access/src/main/java/ch/qos/logback/access/net/URLEvaluator.java
index 352341a..ddc5b7b 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/net/URLEvaluator.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/net/URLEvaluator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,52 +24,46 @@ import ch.qos.logback.core.spi.LifeCycle;
public class URLEvaluator extends ContextAwareBase implements EventEvaluator, LifeCycle {
- boolean started;
- String name;
- private List<String> URLList = new ArrayList<String>();
+ boolean started;
+ String name;
+ private List<String> URLList = new ArrayList<String>();
- public void addURL(String url) {
- URLList.add(url);
- }
+ public void addURL(String url) {
+ URLList.add(url);
+ }
- @Override
- public void start() {
- if (URLList.size() == 0) {
- addWarn("No URL was given to URLEvaluator");
- } else {
- started = true;
- }
+ public void start() {
+ if (URLList.size() == 0) {
+ addWarn("No URL was given to URLEvaluator");
+ } else {
+ started = true;
}
-
- @Override
- public boolean evaluate(Object eventObject) throws NullPointerException, EvaluationException {
- IAccessEvent event = (IAccessEvent) eventObject;
- String url = event.getRequestURL();
- for (String expected : URLList) {
- if (url.contains(expected)) {
- return true;
- }
- }
- return false;
+ }
+
+ public boolean evaluate(Object eventObject) throws NullPointerException, EvaluationException {
+ IAccessEvent event = (IAccessEvent)eventObject;
+ String url = event.getRequestURL();
+ for(String expected:URLList) {
+ if (url.contains(expected)) {
+ return true;
+ }
}
+ return false;
+ }
- @Override
- public String getName() {
- return name;
- }
+ public String getName() {
+ return name;
+ }
- @Override
- public void setName(String name) {
- this.name = name;
- }
+ public void setName(String name) {
+ this.name = name;
+ }
- @Override
- public boolean isStarted() {
- return started;
- }
+ public boolean isStarted() {
+ return started;
+ }
- @Override
- public void stop() {
- started = false;
- }
+ public void stop() {
+ started = false;
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/net/server/SSLServerSocketAppender.java b/logback-access/src/main/java/ch/qos/logback/access/net/server/SSLServerSocketAppender.java
index 5d3722e..70bbbfd 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/net/server/SSLServerSocketAppender.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/net/server/SSLServerSocketAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,18 +25,20 @@ import ch.qos.logback.core.spi.PreSerializationTransformer;
*
* @author Carl Harris
*/
-public class SSLServerSocketAppender extends SSLServerSocketAppenderBase<IAccessEvent> {
+public class SSLServerSocketAppender
+ extends SSLServerSocketAppenderBase<IAccessEvent> {
- private static final PreSerializationTransformer<IAccessEvent> pst = new AccessEventPreSerializationTransformer();
+ private static final PreSerializationTransformer<IAccessEvent> pst =
+ new AccessEventPreSerializationTransformer();
- @Override
- protected void postProcessEvent(IAccessEvent event) {
- event.prepareForDeferredProcessing();
- }
+ @Override
+ protected void postProcessEvent(IAccessEvent event) {
+ event.prepareForDeferredProcessing();
+ }
- @Override
- protected PreSerializationTransformer<IAccessEvent> getPST() {
- return pst;
- }
+ @Override
+ protected PreSerializationTransformer<IAccessEvent> getPST() {
+ return pst;
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/net/server/ServerSocketAppender.java b/logback-access/src/main/java/ch/qos/logback/access/net/server/ServerSocketAppender.java
index 7a02177..c003001 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/net/server/ServerSocketAppender.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/net/server/ServerSocketAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,18 +25,20 @@ import ch.qos.logback.core.spi.PreSerializationTransformer;
*
* @author Carl Harris
*/
-public class ServerSocketAppender extends AbstractServerSocketAppender<IAccessEvent> {
+public class ServerSocketAppender
+ extends AbstractServerSocketAppender<IAccessEvent> {
- private static final PreSerializationTransformer<IAccessEvent> pst = new AccessEventPreSerializationTransformer();
+ private static final PreSerializationTransformer<IAccessEvent> pst =
+ new AccessEventPreSerializationTransformer();
- @Override
- protected void postProcessEvent(IAccessEvent event) {
- event.prepareForDeferredProcessing();
- }
+ @Override
+ protected void postProcessEvent(IAccessEvent event) {
+ event.prepareForDeferredProcessing();
+ }
- @Override
- protected PreSerializationTransformer<IAccessEvent> getPST() {
- return pst;
- }
+ @Override
+ protected PreSerializationTransformer<IAccessEvent> getPST() {
+ return pst;
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/AccessConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/AccessConverter.java
index 52750f7..d12f4b7 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/AccessConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/AccessConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,56 +20,48 @@ import ch.qos.logback.core.spi.ContextAware;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.status.Status;
-abstract public class AccessConverter extends DynamicConverter<IAccessEvent> implements ContextAware {
-
- public final static char SPACE_CHAR = ' ';
- public final static char QUESTION_CHAR = '?';
-
- ContextAwareBase cab = new ContextAwareBase();
- @Override
- public void setContext(Context context) {
- cab.setContext(context);
- }
-
- @Override
- public Context getContext() {
- return cab.getContext();
- }
+abstract public class AccessConverter extends DynamicConverter<IAccessEvent> implements ContextAware {
- @Override
- public void addStatus(Status status) {
- cab.addStatus(status);
- }
+ public final static char SPACE_CHAR = ' ';
+ public final static char QUESTION_CHAR = '?';
+
+ ContextAwareBase cab = new ContextAwareBase();
+
+ public void setContext(Context context) {
+ cab.setContext(context);
+ }
- @Override
- public void addInfo(String msg) {
- cab.addInfo(msg);
- }
+ public Context getContext() {
+ return cab.getContext();
+ }
+
+ public void addStatus(Status status) {
+ cab.addStatus(status);
+ }
- @Override
- public void addInfo(String msg, Throwable ex) {
- cab.addInfo(msg, ex);
- }
+ public void addInfo(String msg) {
+ cab.addInfo(msg);
+ }
- @Override
- public void addWarn(String msg) {
- cab.addWarn(msg);
- }
+ public void addInfo(String msg, Throwable ex) {
+ cab.addInfo(msg, ex);
+ }
- @Override
- public void addWarn(String msg, Throwable ex) {
- cab.addWarn(msg, ex);
- }
+ public void addWarn(String msg) {
+ cab.addWarn(msg);
+ }
- @Override
- public void addError(String msg) {
- cab.addError(msg);
- }
+ public void addWarn(String msg, Throwable ex) {
+ cab.addWarn(msg, ex);
+ }
- @Override
- public void addError(String msg, Throwable ex) {
- cab.addError(msg, ex);
- }
+ public void addError(String msg) {
+ cab.addError(msg);
+ }
+ public void addError(String msg, Throwable ex) {
+ cab.addError(msg, ex);
+ }
+
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/ContentLengthConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/ContentLengthConverter.java
index 95a3763..d8c2e80 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/ContentLengthConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/ContentLengthConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,14 +17,13 @@ import ch.qos.logback.access.spi.IAccessEvent;
public class ContentLengthConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent accessEvent) {
- long len = accessEvent.getContentLength();
- if (len == IAccessEvent.SENTINEL) {
- return IAccessEvent.NA;
- } else {
- return Long.toString(len);
- }
- }
+ public String convert(IAccessEvent accessEvent) {
+ long len = accessEvent.getContentLength();
+ if(len == IAccessEvent.SENTINEL) {
+ return IAccessEvent.NA;
+ } else {
+ return Long.toString(len);
+ }
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/DateConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/DateConverter.java
index 22a0cff..eacb63d 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/DateConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/DateConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,43 +20,44 @@ import ch.qos.logback.access.spi.IAccessEvent;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.util.CachingDateFormatter;
-public class DateConverter extends AccessConverter {
-
- CachingDateFormatter cachingDateFormatter = null;
-
- @Override
- public void start() {
-
- String datePattern = getFirstOption();
- if (datePattern == null) {
- datePattern = CoreConstants.CLF_DATE_PATTERN;
- }
-
- if (datePattern.equals(CoreConstants.ISO8601_STR)) {
- datePattern = CoreConstants.ISO8601_PATTERN;
- }
- try {
- cachingDateFormatter = new CachingDateFormatter(datePattern);
- // maximumCacheValidity = CachedDateFormat.getMaximumCacheValidity(pattern);
- } catch (IllegalArgumentException e) {
- addWarn("Could not instantiate SimpleDateFormat with pattern " + datePattern, e);
- addWarn("Defaulting to " + CoreConstants.CLF_DATE_PATTERN);
- cachingDateFormatter = new CachingDateFormatter(CoreConstants.CLF_DATE_PATTERN);
- }
+public class DateConverter extends AccessConverter {
- List optionList = getOptionList();
- // if the option list contains a TZ option, then set it.
- if (optionList != null && optionList.size() > 1) {
- TimeZone tz = TimeZone.getTimeZone((String) optionList.get(1));
- cachingDateFormatter.setTimeZone(tz);
- }
+ CachingDateFormatter cachingDateFormatter = null;
+
+ public void start() {
+
+ String datePattern = getFirstOption();
+ if(datePattern == null) {
+ datePattern = CoreConstants.CLF_DATE_PATTERN;
}
-
- @Override
- public String convert(IAccessEvent accessEvent) {
- long timestamp = accessEvent.getTimeStamp();
- return cachingDateFormatter.format(timestamp);
+
+ if (datePattern.equals(CoreConstants.ISO8601_STR)) {
+ datePattern = CoreConstants.ISO8601_PATTERN;
+ }
+
+ try {
+ cachingDateFormatter = new CachingDateFormatter(datePattern);
+ //maximumCacheValidity = CachedDateFormat.getMaximumCacheValidity(pattern);
+ } catch (IllegalArgumentException e) {
+ addWarn("Could not instantiate SimpleDateFormat with pattern " + datePattern, e);
+ addWarn("Defaulting to " + CoreConstants.CLF_DATE_PATTERN);
+ cachingDateFormatter = new CachingDateFormatter(CoreConstants.CLF_DATE_PATTERN);
}
+
+ List optionList = getOptionList();
+
+ // if the option list contains a TZ option, then set it.
+ if (optionList != null && optionList.size() > 1) {
+ TimeZone tz = TimeZone.getTimeZone((String) optionList.get(1));
+ cachingDateFormatter.setTimeZone(tz);
+ }
+ }
+
+
+ public String convert(IAccessEvent accessEvent) {
+ long timestamp = accessEvent.getTimeStamp();
+ return cachingDateFormatter.format(timestamp);
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/ElapsedSecondsConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/ElapsedSecondsConverter.java
deleted file mode 100644
index ea80147..0000000
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/ElapsedSecondsConverter.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.access.pattern;
-
-import ch.qos.logback.access.spi.IAccessEvent;
-
-public class ElapsedSecondsConverter extends AccessConverter {
-
- public String convert(IAccessEvent accessEvent) {
- return Long.toString(accessEvent.getElapsedSeconds());
- }
-
-}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/ElapsedTimeConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/ElapsedTimeConverter.java
index 66c13ea..54a7569 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/ElapsedTimeConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/ElapsedTimeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,9 +17,8 @@ import ch.qos.logback.access.spi.IAccessEvent;
public class ElapsedTimeConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent accessEvent) {
- return Long.toString(accessEvent.getElapsedTime());
- }
+ public String convert(IAccessEvent accessEvent) {
+ return Long.toString(accessEvent.getElapsedTime());
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/EnsureLineSeparation.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/EnsureLineSeparation.java
index c9a83db..25c9ad2 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/EnsureLineSeparation.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/EnsureLineSeparation.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,27 +14,25 @@
package ch.qos.logback.access.pattern;
import ch.qos.logback.access.spi.IAccessEvent;
-import ch.qos.logback.core.Context;
import ch.qos.logback.core.pattern.Converter;
import ch.qos.logback.core.pattern.ConverterUtil;
import ch.qos.logback.core.pattern.PostCompileProcessor;
public class EnsureLineSeparation implements PostCompileProcessor<IAccessEvent> {
- /**
- * Add a line separator converter so that access event appears on a separate
- * line.
- */
- @Override
- public void process(Context context, Converter<IAccessEvent> head) {
- if (head == null)
- throw new IllegalArgumentException("Empty converter chain");
+ /**
+ * Add a line separator converter so that access event appears on a separate
+ * line.
+ */
+ public void process(Converter<IAccessEvent> head) {
+ if(head == null)
+ throw new IllegalArgumentException("Empty converter chain");
- // if head != null, then tail != null as well
- Converter<IAccessEvent> tail = ConverterUtil.findTail(head);
- Converter<IAccessEvent> newLineConverter = new LineSeparatorConverter();
- if (!(tail instanceof LineSeparatorConverter)) {
- tail.setNext(newLineConverter);
- }
+ // if head != null, then tail != null as well
+ Converter<IAccessEvent> tail = ConverterUtil.findTail(head);
+ Converter<IAccessEvent> newLineConverter = new LineSeparatorConverter();
+ if (!(tail instanceof LineSeparatorConverter)) {
+ tail.setNext(newLineConverter);
}
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/FullRequestConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/FullRequestConverter.java
index 72ad8b1..10c443f 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/FullRequestConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/FullRequestConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,23 +29,23 @@ import ch.qos.logback.core.CoreConstants;
*/
public class FullRequestConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent ae) {
- StringBuilder buf = new StringBuilder();
- buf.append(ae.getRequestURL());
- buf.append(CoreConstants.LINE_SEPARATOR);
-
- Enumeration headerNames = ae.getRequestHeaderNames();
- while (headerNames.hasMoreElements()) {
- String name = (String) headerNames.nextElement();
- buf.append(name);
- buf.append(": ");
- buf.append(ae.getRequestHeader(name));
- buf.append(CoreConstants.LINE_SEPARATOR);
- }
- buf.append(CoreConstants.LINE_SEPARATOR);
- buf.append(ae.getRequestContent());
- return buf.toString();
+ @Override
+ public String convert(IAccessEvent ae) {
+ StringBuilder buf = new StringBuilder();
+ buf.append(ae.getRequestURL());
+ buf.append(CoreConstants.LINE_SEPARATOR);
+
+ Enumeration headerNames = ae.getRequestHeaderNames();
+ while(headerNames.hasMoreElements()) {
+ String name = (String) headerNames.nextElement();
+ buf.append(name);
+ buf.append(": ");
+ buf.append(ae.getRequestHeader(name));
+ buf.append(CoreConstants.LINE_SEPARATOR);
}
+ buf.append(CoreConstants.LINE_SEPARATOR);
+ buf.append(ae.getRequestContent());
+ return buf.toString();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/FullResponseConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/FullResponseConverter.java
index 19f8cb6..c5c7dc2 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/FullResponseConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/FullResponseConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,112 +20,72 @@ import ch.qos.logback.core.CoreConstants;
public class FullResponseConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent ae) {
- StringBuilder buf = new StringBuilder();
-
- buf.append("HTTP/1.1 ");
- int statusCode = ae.getStatusCode();
- buf.append(statusCode);
- buf.append(" ");
- buf.append(getStatusCodeDescription(statusCode));
- buf.append(CoreConstants.LINE_SEPARATOR);
-
- List<String> hnList = ae.getResponseHeaderNameList();
- for (String headerName : hnList) {
- buf.append(headerName);
- buf.append(": ");
- buf.append(ae.getResponseHeader(headerName));
- buf.append(CoreConstants.LINE_SEPARATOR);
- }
- buf.append(CoreConstants.LINE_SEPARATOR);
- buf.append(ae.getResponseContent());
- buf.append(CoreConstants.LINE_SEPARATOR);
- return buf.toString();
+ @Override
+ public String convert(IAccessEvent ae) {
+ StringBuilder buf = new StringBuilder();
+
+ buf.append("HTTP/1.1 ");
+ int statusCode = ae.getStatusCode();
+ buf.append(statusCode);
+ buf.append(" ");
+ buf.append(getStatusCodeDescription(statusCode));
+ buf.append(CoreConstants.LINE_SEPARATOR);
+
+ List<String> hnList = ae.getResponseHeaderNameList();
+ for(String headerName: hnList) {
+ buf.append(headerName);
+ buf.append(": ");
+ buf.append(ae.getResponseHeader(headerName));
+ buf.append(CoreConstants.LINE_SEPARATOR);
}
+ buf.append(CoreConstants.LINE_SEPARATOR);
+ buf.append(ae.getResponseContent());
+ buf.append(CoreConstants.LINE_SEPARATOR);
+ return buf.toString();
+ }
- static String getStatusCodeDescription(int sc) {
- switch (sc) {
- case 200:
- return "OK";
- case 201:
- return "Created";
- case 202:
- return "Accepted";
- case 203:
- return "Non-Authoritative Information";
- case 204:
- return "No Content";
- case 205:
- return "Reset Content";
- case 206:
- return "Partial Content";
- case 300:
- return "Multiple Choices";
- case 301:
- return "Moved Permanently";
- case 302:
- return "Found";
- case 303:
- return "See Other";
- case 304:
- return "Not Modified";
- case 305:
- return "Use Proxy";
- case 306:
- return "(Unused)";
- case 307:
- return "Temporary Redirect";
- case 400:
- return "Bad Request";
- case 401:
- return "Unauthorized";
- case 402:
- return "Payment Required";
- case 403:
- return "Forbidden";
- case 404:
- return "Not Found";
- case 405:
- return "Method Not Allowed";
- case 406:
- return "Not Acceptable";
- case 407:
- return "Proxy Authentication Required";
- case 408:
- return "Request Timeout";
- case 409:
- return "Conflict";
- case 410:
- return "Gone";
- case 411:
- return "Length Required";
- case 412:
- return "Precondition Failed";
- case 413:
- return "Request Entity Too Large";
- case 414:
- return "Request-URI Too Long";
- case 415:
- return "Unsupported Media Type";
- case 416:
- return "Requested Range Not Satisfiable";
- case 417:
- return "Expectation Failed";
- case 500:
- return "Internal Server Error";
- case 501:
- return "Not Implemented";
- case 502:
- return "Bad Gateway";
- case 503:
- return "Service Unavailable";
- case 504:
- return "Gateway Timeout";
- case 505:
- return "HTTP Version Not Supported";
- default:
- return "NA";
- }
+ static String getStatusCodeDescription(int sc) {
+ switch(sc) {
+ case 200: return "OK";
+ case 201: return "Created";
+ case 202: return "Accepted";
+ case 203: return "Non-Authoritative Information";
+ case 204: return "No Content";
+ case 205: return "Reset Content";
+ case 206: return "Partial Content";
+ case 300: return "Multiple Choices";
+ case 301: return "Moved Permanently";
+ case 302: return "Found";
+ case 303: return "See Other";
+ case 304: return "Not Modified";
+ case 305: return "Use Proxy";
+ case 306: return "(Unused)";
+ case 307: return "Temporary Redirect";
+ case 400: return "Bad Request";
+ case 401: return "Unauthorized";
+ case 402: return "Payment Required";
+ case 403: return "Forbidden";
+ case 404: return "Not Found";
+ case 405: return "Method Not Allowed";
+ case 406: return "Not Acceptable";
+ case 407: return "Proxy Authentication Required";
+ case 408: return "Request Timeout";
+ case 409: return "Conflict";
+ case 410: return "Gone";
+ case 411: return "Length Required";
+ case 412: return "Precondition Failed";
+ case 413: return "Request Entity Too Large";
+ case 414: return "Request-URI Too Long";
+ case 415: return "Unsupported Media Type";
+ case 416: return "Requested Range Not Satisfiable";
+ case 417: return "Expectation Failed";
+ case 500: return "Internal Server Error";
+ case 501: return "Not Implemented";
+ case 502: return "Bad Gateway";
+ case 503: return "Service Unavailable";
+ case 504: return "Gateway Timeout";
+ case 505: return "HTTP Version Not Supported";
+ default: return "NA";
}
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/LineSeparatorConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/LineSeparatorConverter.java
index b3250d6..63974dd 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/LineSeparatorConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/LineSeparatorConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,10 +16,10 @@ package ch.qos.logback.access.pattern;
import ch.qos.logback.access.spi.IAccessEvent;
import ch.qos.logback.core.CoreConstants;
+
public class LineSeparatorConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent event) {
- return CoreConstants.LINE_SEPARATOR;
- }
+ public String convert(IAccessEvent event) {
+ return CoreConstants.LINE_SEPARATOR;
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/LocalIPAddressConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/LocalIPAddressConverter.java
index e1183ad..ba26284 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/LocalIPAddressConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/LocalIPAddressConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,19 +20,18 @@ import ch.qos.logback.access.spi.IAccessEvent;
public class LocalIPAddressConverter extends AccessConverter {
- String localIPAddressStr;
+ String localIPAddressStr;
- public LocalIPAddressConverter() {
- try {
- localIPAddressStr = InetAddress.getLocalHost().getHostAddress();
- } catch (UnknownHostException uhe) {
- localIPAddressStr = "127.0.0.1";
- }
+ public LocalIPAddressConverter() {
+ try {
+ localIPAddressStr = InetAddress.getLocalHost().getHostAddress();
+ } catch (UnknownHostException uhe) {
+ localIPAddressStr = "127.0.0.1";
}
+ }
- @Override
- public String convert(IAccessEvent accessEvent) {
- return localIPAddressStr;
- }
+ public String convert(IAccessEvent accessEvent) {
+ return localIPAddressStr;
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/LocalPortConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/LocalPortConverter.java
index 3d5611a..cc0b516 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/LocalPortConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/LocalPortConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,8 +17,8 @@ import ch.qos.logback.access.spi.IAccessEvent;
public class LocalPortConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent accessEvent) {
- return Integer.toString(accessEvent.getLocalPort());
- }
+
+ public String convert(IAccessEvent accessEvent) {
+ return Integer.toString(accessEvent.getLocalPort());
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/NAConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/NAConverter.java
index a8c4c83..1d6923c 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/NAConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/NAConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,10 +22,9 @@ import ch.qos.logback.access.spi.IAccessEvent;
* @author Ceki Gülcü
*/
public class NAConverter extends AccessConverter {
-
- @Override
- public String convert(IAccessEvent accessEvent) {
- return IAccessEvent.NA;
- }
+
+ public String convert(IAccessEvent accessEvent) {
+ return IAccessEvent.NA;
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/QueryStringConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/QueryStringConverter.java
deleted file mode 100644
index 1cfd4bc..0000000
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/QueryStringConverter.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.access.pattern;
-
-import ch.qos.logback.access.spi.IAccessEvent;
-
-public class QueryStringConverter extends AccessConverter {
-
- public String convert(IAccessEvent accessEvent) {
- return accessEvent.getQueryString();
- }
-}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/RemoteHostConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/RemoteHostConverter.java
index 464bf50..381dbcc 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/RemoteHostConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/RemoteHostConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,9 +17,9 @@ import ch.qos.logback.access.spi.IAccessEvent;
public class RemoteHostConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent accessEvent) {
- return accessEvent.getRemoteHost();
- }
+
+ public String convert(IAccessEvent accessEvent) {
+ return accessEvent.getRemoteHost();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/RemoteIPAddressConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/RemoteIPAddressConverter.java
index 3476314..eb25007 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/RemoteIPAddressConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/RemoteIPAddressConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,9 +17,8 @@ import ch.qos.logback.access.spi.IAccessEvent;
public class RemoteIPAddressConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent accessEvent) {
- return accessEvent.getRemoteAddr();
- }
+ public String convert(IAccessEvent accessEvent) {
+ return accessEvent.getRemoteAddr();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/RemoteUserConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/RemoteUserConverter.java
index 30ef04c..28f5013 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/RemoteUserConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/RemoteUserConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,15 +17,15 @@ import ch.qos.logback.access.spi.IAccessEvent;
public class RemoteUserConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent accessEvent) {
-
- String user = accessEvent.getRemoteUser();
- if (user == null) {
- return IAccessEvent.NA;
- } else {
- return user;
- }
+
+ public String convert(IAccessEvent accessEvent) {
+
+ String user = accessEvent.getRemoteUser();
+ if(user == null) {
+ return IAccessEvent.NA;
+ } else {
+ return user;
}
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestAttributeConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestAttributeConverter.java
index abb2df2..1624883 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestAttributeConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestAttributeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,27 +16,26 @@ package ch.qos.logback.access.pattern;
import ch.qos.logback.access.spi.IAccessEvent;
import ch.qos.logback.core.util.OptionHelper;
+
public class RequestAttributeConverter extends AccessConverter {
- String key;
+ String key;
- @Override
- public void start() {
- key = getFirstOption();
- if (OptionHelper.isEmpty(key)) {
- addWarn("Missing key for the request attribute");
- } else {
- super.start();
- }
+ public void start() {
+ key = getFirstOption();
+ if (OptionHelper.isEmpty(key)) {
+ addWarn("Missing key for the request attribute");
+ } else {
+ super.start();
}
+ }
- @Override
- public String convert(IAccessEvent accessEvent) {
- if (!isStarted()) {
- return "INACTIVE_REQUEST_ATTRIB_CONV";
- }
-
- return accessEvent.getAttribute(key);
+ public String convert(IAccessEvent accessEvent) {
+ if (!isStarted()) {
+ return "INACTIVE_REQUEST_ATTRIB_CONV";
}
+ return accessEvent.getAttribute(key);
+ }
+
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestContentConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestContentConverter.java
index 7e7c120..258eb64 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestContentConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestContentConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,9 +26,9 @@ import ch.qos.logback.access.spi.IAccessEvent;
*/
public class RequestContentConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent accessEvent) {
- return accessEvent.getRequestContent();
- }
+ @Override
+ public String convert(IAccessEvent accessEvent) {
+ return accessEvent.getRequestContent();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestCookieConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestCookieConverter.java
index 45bf91b..0cb855e 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestCookieConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestCookieConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,26 +16,25 @@ package ch.qos.logback.access.pattern;
import ch.qos.logback.access.spi.IAccessEvent;
import ch.qos.logback.core.util.OptionHelper;
+
public class RequestCookieConverter extends AccessConverter {
- String key;
+ String key;
- @Override
- public void start() {
- key = getFirstOption();
- if (OptionHelper.isEmpty(key)) {
- addWarn("Missing key for the requested header");
- } else {
- super.start();
- }
+ public void start() {
+ key = getFirstOption();
+ if (OptionHelper.isEmpty(key)) {
+ addWarn("Missing key for the requested header");
+ } else {
+ super.start();
}
+ }
- @Override
- public String convert(IAccessEvent accessEvent) {
- if (!isStarted()) {
- return "INACTIVE_COOKIE_CONVERTER";
- }
-
- return accessEvent.getCookie(key);
+ public String convert(IAccessEvent accessEvent) {
+ if (!isStarted()) {
+ return "INACTIVE_COOKIE_CONVERTER";
}
+
+ return accessEvent.getCookie(key);
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestHeaderConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestHeaderConverter.java
index e3742f1..840e319 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestHeaderConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestHeaderConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,31 +16,30 @@ package ch.qos.logback.access.pattern;
import ch.qos.logback.access.spi.IAccessEvent;
import ch.qos.logback.core.util.OptionHelper;
-public class RequestHeaderConverter extends AccessConverter {
- String key;
+public class RequestHeaderConverter extends AccessConverter {
- @Override
- public void start() {
- key = getFirstOption();
- if (OptionHelper.isEmpty(key)) {
- addWarn("Missing key for the requested header. Defaulting to all keys.");
- key = null;
- }
- super.start();
- }
+ String key;
- @Override
- public String convert(IAccessEvent accessEvent) {
- if (!isStarted()) {
- return "INACTIVE_HEADER_CONV";
- }
+ public void start() {
+ key = getFirstOption();
+ if (OptionHelper.isEmpty(key)) {
+ addWarn("Missing key for the requested header. Defaulting to all keys.");
+ key = null;
+ }
+ super.start();
+ }
- if (key != null) {
- return accessEvent.getRequestHeader(key);
- } else {
- return accessEvent.getRequestHeaderMap().toString();
- }
+ public String convert(IAccessEvent accessEvent) {
+ if(!isStarted()) {
+ return "INACTIVE_HEADER_CONV";
+ }
+
+ if(key != null) {
+ return accessEvent.getRequestHeader(key);
+ } else {
+ return accessEvent.getRequestHeaderMap().toString();
}
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestMethodConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestMethodConverter.java
index 283293a..de8f163 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestMethodConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestMethodConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,8 +17,8 @@ import ch.qos.logback.access.spi.IAccessEvent;
public class RequestMethodConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent accessEvent) {
- return accessEvent.getMethod();
- }
+
+ public String convert(IAccessEvent accessEvent) {
+ return accessEvent.getMethod();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestParameterConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestParameterConverter.java
index 17c6271..9cc8458 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestParameterConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestParameterConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,32 +20,30 @@ import ch.qos.logback.core.util.OptionHelper;
public class RequestParameterConverter extends AccessConverter {
- String key;
+ String key;
- @Override
- public void start() {
- key = getFirstOption();
- if (OptionHelper.isEmpty(key)) {
- addWarn("Missing key for the request parameter");
- } else {
- super.start();
- }
+ public void start() {
+ key = getFirstOption();
+ if (OptionHelper.isEmpty(key)) {
+ addWarn("Missing key for the request parameter");
+ } else {
+ super.start();
}
+ }
- @Override
- public String convert(IAccessEvent accessEvent) {
- if (!isStarted()) {
- return "INACTIVE_REQUEST_PARAM_CONV";
- }
-
- String[] paramArray = accessEvent.getRequestParameter(key);
- if (paramArray.length == 1) {
- return paramArray[0];
- } else {
- // for an array string {"a", "b"} named 'sa', Array.toString(sa) returns the string
- // "[a, b]".
- return Arrays.toString(paramArray);
- }
+ public String convert(IAccessEvent accessEvent) {
+ if (!isStarted()) {
+ return "INACTIVE_REQUEST_PARAM_CONV";
}
+ String[] paramArray = accessEvent.getRequestParameter(key);
+ if (paramArray.length == 1) {
+ return paramArray[0];
+ } else {
+ // for an array string {"a", "b"} named 'sa', Array.toString(sa) returns the string
+ // "[a, b]".
+ return Arrays.toString(paramArray);
+ }
+ }
+
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestProtocolConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestProtocolConverter.java
index 52110a4..12ddb52 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestProtocolConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestProtocolConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,8 +17,8 @@ import ch.qos.logback.access.spi.IAccessEvent;
public class RequestProtocolConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent accessEvent) {
- return accessEvent.getProtocol();
- }
+
+ public String convert(IAccessEvent accessEvent) {
+ return accessEvent.getProtocol();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestURIConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestURIConverter.java
index 5036ce8..dc67cb2 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestURIConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestURIConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,9 +22,8 @@ import ch.qos.logback.access.spi.IAccessEvent;
*/
public class RequestURIConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent accessEvent) {
- return accessEvent.getRequestURI();
- }
+ public String convert(IAccessEvent accessEvent) {
+ return accessEvent.getRequestURI();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestURLConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestURLConverter.java
index 0b2b90d..da60908 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestURLConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/RequestURLConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,8 +22,7 @@ import ch.qos.logback.access.spi.IAccessEvent;
*/
public class RequestURLConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent accessEvent) {
- return accessEvent.getRequestURL();
- }
+ public String convert(IAccessEvent accessEvent) {
+ return accessEvent.getRequestURL();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/ResponseContentConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/ResponseContentConverter.java
index f6a935e..55ee5c8 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/ResponseContentConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/ResponseContentConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,9 +26,9 @@ import ch.qos.logback.access.spi.IAccessEvent;
*/
public class ResponseContentConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent accessEvent) {
- return accessEvent.getResponseContent();
- }
+ @Override
+ public String convert(IAccessEvent accessEvent) {
+ return accessEvent.getResponseContent();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/ResponseHeaderConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/ResponseHeaderConverter.java
index 83e762d..d018063 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/ResponseHeaderConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/ResponseHeaderConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,37 +16,36 @@ package ch.qos.logback.access.pattern;
import ch.qos.logback.access.spi.IAccessEvent;
import ch.qos.logback.core.util.OptionHelper;
+
public class ResponseHeaderConverter extends AccessConverter {
- String key;
+ String key;
- @Override
- public void start() {
- key = getFirstOption();
- if (OptionHelper.isEmpty(key)) {
- addWarn("Missing key for the response header");
- } else {
- super.start();
- }
+ public void start() {
+ key = getFirstOption();
+ if (OptionHelper.isEmpty(key)) {
+ addWarn("Missing key for the response header");
+ } else {
+ super.start();
}
+ }
- @Override
- public String convert(IAccessEvent accessEvent) {
- if (!isStarted()) {
- return "INACTIVE_REPONSE_HEADER_CONV";
- }
-
- return accessEvent.getResponseHeader(key);
- // return null;
-
- // HttpServletResponse response = accessEvent.getHttpResponse();
- //
- // Object value = null; // = response.getHeader(key);
- // if (value == null) {
- // return AccessConverter.NA;
- // } else {
- // return value.toString();
- // }
+ public String convert(IAccessEvent accessEvent) {
+ if(!isStarted()) {
+ return "INACTIVE_REPONSE_HEADER_CONV";
}
+
+ return accessEvent.getResponseHeader(key);
+ //return null;
+
+// HttpServletResponse response = accessEvent.getHttpResponse();
+//
+// Object value = null; // = response.getHeader(key);
+// if (value == null) {
+// return AccessConverter.NA;
+// } else {
+// return value.toString();
+// }
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/ServerNameConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/ServerNameConverter.java
index 97e79b3..1c27c23 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/ServerNameConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/ServerNameConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,8 +17,7 @@ import ch.qos.logback.access.spi.IAccessEvent;
public class ServerNameConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent accessEvent) {
- return accessEvent.getServerName();
- }
+ public String convert(IAccessEvent accessEvent) {
+ return accessEvent.getServerName();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/SessionIDConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/SessionIDConverter.java
deleted file mode 100644
index d6d6bd7..0000000
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/SessionIDConverter.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.access.pattern;
-
-import ch.qos.logback.access.spi.IAccessEvent;
-
-public class SessionIDConverter extends AccessConverter {
-
- public String convert(IAccessEvent accessEvent) {
- return accessEvent.getSessionID();
- }
-}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/StatusCodeConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/StatusCodeConverter.java
index 34e04a2..1f65264 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/StatusCodeConverter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/pattern/StatusCodeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,9 +17,8 @@ import ch.qos.logback.access.spi.IAccessEvent;
public class StatusCodeConverter extends AccessConverter {
- @Override
- public String convert(IAccessEvent accessEvent) {
- return Integer.toString(accessEvent.getStatusCode());
- }
+ public String convert(IAccessEvent accessEvent) {
+ return Integer.toString(accessEvent.getStatusCode());
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/pattern/ThreadNameConverter.java b/logback-access/src/main/java/ch/qos/logback/access/pattern/ThreadNameConverter.java
deleted file mode 100644
index 9a9c498..0000000
--- a/logback-access/src/main/java/ch/qos/logback/access/pattern/ThreadNameConverter.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.access.pattern;
-
-import ch.qos.logback.access.spi.IAccessEvent;
-
-public class ThreadNameConverter extends AccessConverter {
-
- public String convert(IAccessEvent accessEvent) {
- return accessEvent.getThreadName();
- }
-
-}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeFilter.java b/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeFilter.java
index 45512aa..24e3af9 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeFilter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -32,31 +32,34 @@ import static ch.qos.logback.access.AccessConstants.LB_OUTPUT_BUFFER;
import static ch.qos.logback.access.AccessConstants.TEE_FILTER_INCLUDES_PARAM;
import static ch.qos.logback.access.AccessConstants.TEE_FILTER_EXCLUDES_PARAM;
+
public class TeeFilter implements Filter {
boolean active;
- @Override
public void destroy() {
// NOP
}
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
+ public void doFilter(ServletRequest request, ServletResponse response,
+ FilterChain filterChain) throws IOException, ServletException {
if (active && request instanceof HttpServletRequest) {
try {
- TeeHttpServletRequest teeRequest = new TeeHttpServletRequest((HttpServletRequest) request);
- TeeHttpServletResponse teeResponse = new TeeHttpServletResponse((HttpServletResponse) response);
+ TeeHttpServletRequest teeRequest = new TeeHttpServletRequest(
+ (HttpServletRequest) request);
+ TeeHttpServletResponse teeResponse = new TeeHttpServletResponse(
+ (HttpServletResponse) response);
- // System.out.println("BEFORE TeeFilter. filterChain.doFilter()");
+ //System.out.println("BEFORE TeeFilter. filterChain.doFilter()");
filterChain.doFilter(teeRequest, teeResponse);
- // System.out.println("AFTER TeeFilter. filterChain.doFilter()");
+ //System.out.println("AFTER TeeFilter. filterChain.doFilter()");
teeResponse.finish();
// let the output contents be available for later use by
// logback-access-logging
- teeRequest.setAttribute(LB_OUTPUT_BUFFER, teeResponse.getOutputBuffer());
+ teeRequest.setAttribute(LB_OUTPUT_BUFFER, teeResponse
+ .getOutputBuffer());
} catch (IOException e) {
e.printStackTrace();
throw e;
@@ -70,7 +73,6 @@ public class TeeFilter implements Filter {
}
- @Override
public void init(FilterConfig filterConfig) throws ServletException {
String includeListAsStr = filterConfig.getInitParameter(TEE_FILTER_INCLUDES_PARAM);
String excludeListAsStr = filterConfig.getInitParameter(TEE_FILTER_EXCLUDES_PARAM);
@@ -103,6 +105,7 @@ public class TeeFilter implements Filter {
return nameList;
}
+
static String getLocalhostName() {
String hostname = "127.0.0.1";
@@ -122,15 +125,14 @@ public class TeeFilter implements Filter {
return inIncludesList && (!inExcludesList);
}
+
static boolean mathesIncludesList(String hostname, List<String> includeList) {
- if (includeList.isEmpty())
- return true;
+ if (includeList.isEmpty()) return true;
return includeList.contains(hostname);
}
static boolean mathesExcludesList(String hostname, List<String> excludesList) {
- if (excludesList.isEmpty())
- return false;
+ if (excludesList.isEmpty()) return false;
return excludesList.contains(hostname);
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletRequest.java b/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletRequest.java
index 23cd26d..3d734a9 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletRequest.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletRequest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,7 +22,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import static ch.qos.logback.access.AccessConstants.LB_INPUT_BUFFER;
-
/**
* As the "tee" program on Unix, duplicate the request's input stream.
*
@@ -30,54 +29,54 @@ import static ch.qos.logback.access.AccessConstants.LB_INPUT_BUFFER;
*/
class TeeHttpServletRequest extends HttpServletRequestWrapper {
- private TeeServletInputStream inStream;
- private BufferedReader reader;
- boolean postedParametersMode = false;
-
- TeeHttpServletRequest(HttpServletRequest request) {
- super(request);
- // we can't access the input stream and access the request parameters
- // at the same time
- if (Util.isFormUrlEncoded(request)) {
- postedParametersMode = true;
- } else {
- inStream = new TeeServletInputStream(request);
- // add the contents of the input buffer as an attribute of the request
- request.setAttribute(LB_INPUT_BUFFER, inStream.getInputBuffer());
- reader = new BufferedReader(new InputStreamReader(inStream));
- }
+ private TeeServletInputStream inStream;
+ private BufferedReader reader;
+ boolean postedParametersMode = false;
+ TeeHttpServletRequest(HttpServletRequest request) {
+ super(request);
+ // we can't access the input stream and access the request parameters
+ // at the same time
+ if (Util.isFormUrlEncoded(request)) {
+ postedParametersMode = true;
+ } else {
+ inStream = new TeeServletInputStream(request);
+ // add the contents of the input buffer as an attribute of the request
+ request.setAttribute(LB_INPUT_BUFFER, inStream.getInputBuffer());
+ reader = new BufferedReader(new InputStreamReader(inStream));
}
- byte[] getInputBuffer() {
- if (postedParametersMode) {
- throw new IllegalStateException("Call disallowed in postedParametersMode");
- }
- return inStream.getInputBuffer();
+ }
+
+ byte[] getInputBuffer() {
+ if (postedParametersMode) {
+ throw new IllegalStateException("Call disallowed in postedParametersMode");
}
+ return inStream.getInputBuffer();
+ }
- @Override
- public ServletInputStream getInputStream() throws IOException {
- if (!postedParametersMode) {
- return inStream;
- } else {
- return super.getInputStream();
- }
+ @Override
+ public ServletInputStream getInputStream() throws IOException {
+ if (!postedParametersMode) {
+ return inStream;
+ } else {
+ return super.getInputStream();
}
+ }
- //
+ //
- @Override
- public BufferedReader getReader() throws IOException {
- if (!postedParametersMode) {
- return reader;
- } else {
- return super.getReader();
- }
+ @Override
+ public BufferedReader getReader() throws IOException {
+ if (!postedParametersMode) {
+ return reader;
+ } else {
+ return super.getReader();
}
+ }
- public boolean isPostedParametersMode() {
- return postedParametersMode;
- }
+ public boolean isPostedParametersMode() {
+ return postedParametersMode;
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletResponse.java b/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletResponse.java
index 6244fe9..8c62c5e 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletResponse.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletResponse.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,52 +23,53 @@ import javax.servlet.http.HttpServletResponseWrapper;
public class TeeHttpServletResponse extends HttpServletResponseWrapper {
- TeeServletOutputStream teeServletOutputStream;
- PrintWriter teeWriter;
+ TeeServletOutputStream teeServletOutputStream;
+ PrintWriter teeWriter;
- public TeeHttpServletResponse(HttpServletResponse httpServletResponse) {
- super(httpServletResponse);
- }
+ public TeeHttpServletResponse(HttpServletResponse httpServletResponse) {
+ super(httpServletResponse);
+ }
- @Override
- public ServletOutputStream getOutputStream() throws IOException {
- if (teeServletOutputStream == null) {
- teeServletOutputStream = new TeeServletOutputStream(this.getResponse());
- }
- return teeServletOutputStream;
+ @Override
+ public ServletOutputStream getOutputStream() throws IOException {
+ if (teeServletOutputStream == null) {
+ teeServletOutputStream = new TeeServletOutputStream(this.getResponse());
}
+ return teeServletOutputStream;
+ }
- @Override
- public PrintWriter getWriter() throws IOException {
- if (this.teeWriter == null) {
- this.teeWriter = new PrintWriter(new OutputStreamWriter(getOutputStream(), this.getResponse().getCharacterEncoding()), true);
- }
- return this.teeWriter;
+ @Override
+ public PrintWriter getWriter() throws IOException {
+ if (this.teeWriter == null) {
+ this.teeWriter = new PrintWriter(new OutputStreamWriter(getOutputStream()),
+ true);
}
+ return this.teeWriter;
+ }
- @Override
- public void flushBuffer() {
- if (this.teeWriter != null) {
- this.teeWriter.flush();
- }
+ @Override
+ public void flushBuffer() {
+ if (this.teeWriter != null) {
+ this.teeWriter.flush();
}
+ }
- byte[] getOutputBuffer() {
- // teeServletOutputStream can be null if the getOutputStream method is never
- // called.
- if (teeServletOutputStream != null) {
- return teeServletOutputStream.getOutputStreamAsByteArray();
- } else {
- return null;
- }
+ byte[] getOutputBuffer() {
+ // teeServletOutputStream can be null if the getOutputStream method is never
+ // called.
+ if (teeServletOutputStream != null) {
+ return teeServletOutputStream.getOutputStreamAsByteArray();
+ } else {
+ return null;
}
+ }
- void finish() throws IOException {
- if (this.teeWriter != null) {
- this.teeWriter.close();
- }
- if (this.teeServletOutputStream != null) {
- this.teeServletOutputStream.close();
- }
+ void finish() throws IOException {
+ if (this.teeWriter != null) {
+ this.teeWriter.close();
+ }
+ if (this.teeServletOutputStream != null) {
+ this.teeServletOutputStream.close();
}
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletInputStream.java b/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletInputStream.java
index 6fc2a62..60efd95 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletInputStream.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletInputStream.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,52 +23,53 @@ import javax.servlet.http.HttpServletRequest;
class TeeServletInputStream extends ServletInputStream {
- InputStream in;
- byte[] inputBuffer;
+ InputStream in;
+ byte[] inputBuffer;
- TeeServletInputStream(HttpServletRequest request) {
- duplicateInputStream(request);
- }
+ TeeServletInputStream(HttpServletRequest request) {
+ duplicateInputStream(request);
+ }
- @Override
- public int read() throws IOException {
- return in.read();
- }
+ @Override
+ public int read() throws IOException {
+ return in.read();
+ }
- private void duplicateInputStream(HttpServletRequest request) {
- ServletInputStream originalSIS = null;
- try {
- originalSIS = request.getInputStream();
- inputBuffer = consumeBufferAndReturnAsByteArray(originalSIS);
- this.in = new ByteArrayInputStream(inputBuffer);
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- closeStrean(originalSIS);
- }
+ private void duplicateInputStream(HttpServletRequest request) {
+ ServletInputStream originalSIS = null;
+ try {
+ originalSIS = request.getInputStream();
+ inputBuffer = consumeBufferAndReturnAsByteArray(originalSIS);
+ this.in = new ByteArrayInputStream(inputBuffer);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ closeStrean(originalSIS);
}
+ }
- byte[] consumeBufferAndReturnAsByteArray(InputStream is) throws IOException {
- int len = 1024;
- byte[] temp = new byte[len];
- int c = -1;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- while ((c = is.read(temp, 0, len)) != -1) {
- baos.write(temp, 0, c);
- }
- return baos.toByteArray();
+ byte[] consumeBufferAndReturnAsByteArray(InputStream is) throws IOException {
+ int len = 1024;
+ byte[] temp = new byte[len];
+ int c = -1;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ while ((c = is.read(temp, 0, len)) != -1) {
+ baos.write(temp, 0, c);
}
+ return baos.toByteArray();
+ }
- void closeStrean(ServletInputStream is) {
- if (is != null) {
- try {
- is.close();
- } catch (IOException e) {
- }
- }
- }
- byte[] getInputBuffer() {
- return inputBuffer;
+ void closeStrean(ServletInputStream is) {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ }
}
+ }
+
+ byte[] getInputBuffer() {
+ return inputBuffer;
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletOutputStream.java b/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletOutputStream.java
index 7861bd4..5e782b1 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletOutputStream.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletOutputStream.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,65 +21,68 @@ import javax.servlet.ServletResponse;
public class TeeServletOutputStream extends ServletOutputStream {
- final ServletOutputStream underlyingStream;
- final ByteArrayOutputStream baosCopy;
+ final ServletOutputStream underlyingStream;
+ final ByteArrayOutputStream baosCopy;
- TeeServletOutputStream(ServletResponse httpServletResponse) throws IOException {
- // System.out.println("TeeServletOutputStream.constructor() called");
- this.underlyingStream = httpServletResponse.getOutputStream();
- baosCopy = new ByteArrayOutputStream();
- }
+ TeeServletOutputStream(ServletResponse httpServletResponse)
+ throws IOException {
+ // System.out.println("TeeServletOutputStream.constructor() called");
+ this.underlyingStream = httpServletResponse.getOutputStream();
+ baosCopy = new ByteArrayOutputStream();
+ }
- byte[] getOutputStreamAsByteArray() {
- return baosCopy.toByteArray();
- }
+ byte[] getOutputStreamAsByteArray() {
+ return baosCopy.toByteArray();
+ }
- @Override
- public void write(int val) throws IOException {
- if (underlyingStream != null) {
- underlyingStream.write(val);
- baosCopy.write(val);
- }
+ @Override
+ public void write(int val) throws IOException {
+ if (underlyingStream != null) {
+ underlyingStream.write(val);
+ baosCopy.write(val);
}
+ }
- @Override
- public void write(byte[] byteArray) throws IOException {
- if (underlyingStream == null) {
- return;
- }
- // System.out.println("WRITE TeeServletOutputStream.write(byte[]) called");
- write(byteArray, 0, byteArray.length);
+ @Override
+ public void write(byte[] byteArray) throws IOException {
+ if (underlyingStream == null) {
+ return;
}
+ // System.out.println("WRITE TeeServletOutputStream.write(byte[]) called");
+ write(byteArray, 0, byteArray.length);
+ }
- @Override
- public void write(byte byteArray[], int offset, int length) throws IOException {
- if (underlyingStream == null) {
- return;
- }
- // System.out.println("WRITE TeeServletOutputStream.write(byte[], int, int)
- // called");
- // System.out.println(new String(byteArray, offset, length));
- underlyingStream.write(byteArray, offset, length);
- baosCopy.write(byteArray, offset, length);
+ @Override
+ public void write(byte byteArray[], int offset, int length)
+ throws IOException {
+ if (underlyingStream == null) {
+ return;
}
+ // System.out.println("WRITE TeeServletOutputStream.write(byte[], int, int)
+ // called");
+ // System.out.println(new String(byteArray, offset, length));
+ underlyingStream.write(byteArray, offset, length);
+ baosCopy.write(byteArray, offset, length);
+ }
- @Override
- public void close() throws IOException {
- // System.out.println("CLOSE TeeServletOutputStream.close() called");
+ @Override
+ public void close() throws IOException {
+ // System.out.println("CLOSE TeeServletOutputStream.close() called");
+
+ // If the servlet accessing the stream is using a writer instead of
+ // an OutputStream, it will probably call os.close() before calling
+ // writer.close. Thus, the underlying output stream will be called
+ // before the data sent to the writer could be flushed.
+ }
- // If the servlet accessing the stream is using a writer instead of
- // an OutputStream, it will probably call os.close() before calling
- // writer.close. Thus, the underlying output stream will be called
- // before the data sent to the writer could be flushed.
- }
- @Override
- public void flush() throws IOException {
- if (underlyingStream == null) {
- return;
- }
- // System.out.println("FLUSH TeeServletOutputStream.flush() called");
- underlyingStream.flush();
- baosCopy.flush();
+ @Override
+ public void flush() throws IOException {
+ if (underlyingStream == null) {
+ return;
}
+ // System.out.println("FLUSH TeeServletOutputStream.flush() called");
+ underlyingStream.flush();
+ baosCopy.flush();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/servlet/Util.java b/logback-access/src/main/java/ch/qos/logback/access/servlet/Util.java
index b298182..cb840c5 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/servlet/Util.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/servlet/Util.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,24 +20,26 @@ import javax.servlet.http.HttpServletResponse;
public class Util {
- public static boolean isFormUrlEncoded(HttpServletRequest request) {
+ public static boolean isFormUrlEncoded(HttpServletRequest request) {
- String contentTypeStr = request.getContentType();
- if ("POST".equalsIgnoreCase(request.getMethod()) && contentTypeStr != null && contentTypeStr.startsWith(AccessConstants.X_WWW_FORM_URLECODED)) {
- return true;
- } else {
- return false;
- }
+ String contentTypeStr = request.getContentType();
+ if ("POST".equalsIgnoreCase(request.getMethod())
+ && contentTypeStr != null
+ && contentTypeStr.startsWith(AccessConstants.X_WWW_FORM_URLECODED)) {
+ return true;
+ } else {
+ return false;
}
+ }
- public static boolean isImageResponse(HttpServletResponse response) {
+ public static boolean isImageResponse(HttpServletResponse response) {
- String responseType = response.getContentType();
+ String responseType = response.getContentType();
- if (responseType != null && responseType.startsWith(AccessConstants.IMAGE_CONTENT_TYPE)) {
- return true;
- } else {
- return false;
- }
+ if (responseType != null && responseType.startsWith(AccessConstants.IMAGE_CONTENT_TYPE)) {
+ return true;
+ } else {
+ return false;
}
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/sift/AccessEventDiscriminator.java b/logback-access/src/main/java/ch/qos/logback/access/sift/AccessEventDiscriminator.java
index c102efb..2b50f52 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/sift/AccessEventDiscriminator.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/sift/AccessEventDiscriminator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,160 +31,160 @@ import ch.qos.logback.core.sift.AbstractDiscriminator;
*/
public class AccessEventDiscriminator extends AbstractDiscriminator<IAccessEvent> {
- /**
- * At present time the followed fields can be designated: COOKIE,
- * REQUEST_ATTRIBUTE, SESSION_ATTRIBUTE, REMOTE_ADDRESS,
- * LOCAL_PORT,REQUEST_URI
- *
- * <p> The first three fields require an additional key. For the
- * SESSION_ATTRIBUTE field, the additional key named "id" has special meaning
- * as it is mapped to the session id of the current http request.
- */
- public enum FieldName {
- COOKIE, REQUEST_ATTRIBUTE, SESSION_ATTRIBUTE, REMOTE_ADDRESS, LOCAL_PORT, REQUEST_URI
+ /**
+ * At present time the followed fields can be designated: COOKIE,
+ * REQUEST_ATTRIBUTE, SESSION_ATTRIBUTE, REMOTE_ADDRESS,
+ * LOCAL_PORT,REQUEST_URI
+ *
+ * <p> The first three fields require an additional key. For the
+ * SESSION_ATTRIBUTE field, the additional key named "id" has special meaning
+ * as it is mapped to the session id of the current http request.
+ */
+ public enum FieldName {
+ COOKIE, REQUEST_ATTRIBUTE, SESSION_ATTRIBUTE, REMOTE_ADDRESS, LOCAL_PORT, REQUEST_URI
+ }
+
+ String defaultValue;
+ String key;
+ FieldName fieldName;
+ String additionalKey;
+
+ public String getDiscriminatingValue(IAccessEvent acccessEvent) {
+ String rawValue = getRawDiscriminatingValue(acccessEvent);
+ if (rawValue == null || rawValue.length() == 0) {
+ return defaultValue;
+ } else {
+ return rawValue;
}
-
- String defaultValue;
- String key;
- FieldName fieldName;
- String additionalKey;
-
- @Override
- public String getDiscriminatingValue(IAccessEvent acccessEvent) {
- String rawValue = getRawDiscriminatingValue(acccessEvent);
- if (rawValue == null || rawValue.length() == 0) {
- return defaultValue;
- } else {
- return rawValue;
- }
+ }
+
+ public String getRawDiscriminatingValue(IAccessEvent acccessEvent) {
+ switch (fieldName) {
+ case COOKIE:
+ // tested
+ return acccessEvent.getCookie(additionalKey);
+ case LOCAL_PORT:
+ return String.valueOf(acccessEvent.getLocalPort());
+ case REQUEST_ATTRIBUTE:
+ // tested
+ return getRequestAttribute(acccessEvent);
+ case SESSION_ATTRIBUTE:
+ return getSessionAttribute(acccessEvent);
+ case REMOTE_ADDRESS:
+ return acccessEvent.getRemoteAddr();
+ case REQUEST_URI:
+ // tested
+ return getRequestURI(acccessEvent);
+ default:
+ return null;
}
-
- public String getRawDiscriminatingValue(IAccessEvent acccessEvent) {
- switch (fieldName) {
- case COOKIE:
- // tested
- return acccessEvent.getCookie(additionalKey);
- case LOCAL_PORT:
- return String.valueOf(acccessEvent.getLocalPort());
- case REQUEST_ATTRIBUTE:
- // tested
- return getRequestAttribute(acccessEvent);
- case SESSION_ATTRIBUTE:
- return getSessionAttribute(acccessEvent);
- case REMOTE_ADDRESS:
- return acccessEvent.getRemoteAddr();
- case REQUEST_URI:
- // tested
- return getRequestURI(acccessEvent);
- default:
- return null;
- }
+ }
+
+ private String getRequestAttribute(IAccessEvent acccessEvent) {
+ String attr = acccessEvent.getAttribute(additionalKey);
+ if (IAccessEvent.NA.equals(attr)) {
+ return null;
+ } else {
+ return attr;
}
-
- private String getRequestAttribute(IAccessEvent acccessEvent) {
- String attr = acccessEvent.getAttribute(additionalKey);
- if (IAccessEvent.NA.equals(attr)) {
- return null;
- } else {
- return attr;
- }
+ }
+
+ private String getRequestURI(IAccessEvent acccessEvent) {
+ String uri = acccessEvent.getRequestURI();
+ if (uri != null && uri.length() >= 1 && uri.charAt(0) == '/') {
+ return uri.substring(1);
+ } else {
+ return uri;
}
-
- private String getRequestURI(IAccessEvent acccessEvent) {
- String uri = acccessEvent.getRequestURI();
- if (uri != null && uri.length() >= 1 && uri.charAt(0) == '/') {
- return uri.substring(1);
+ }
+
+ private String getSessionAttribute(IAccessEvent acccessEvent) {
+ HttpServletRequest req = acccessEvent.getRequest();
+ if (req != null) {
+ HttpSession session = req.getSession(false);
+ if (session != null) {
+ if ("id".equalsIgnoreCase(additionalKey)) {
+ return session.getId();
} else {
- return uri;
- }
- }
-
- private String getSessionAttribute(IAccessEvent acccessEvent) {
- HttpServletRequest req = acccessEvent.getRequest();
- if (req != null) {
- HttpSession session = req.getSession(false);
- if (session != null) {
- if ("id".equalsIgnoreCase(additionalKey)) {
- return session.getId();
- } else {
- Object v = session.getAttribute(additionalKey);
- if (v != null) {
- return v.toString();
- }
- }
- }
- }
- return null;
- }
-
- @Override
- public void start() {
-
- int errorCount = 0;
-
- if (defaultValue == null) {
- addError("\"DefaultValue\" property must be set.");
- }
- if (fieldName == null) {
- addError("\"FieldName\" property must be set.");
- errorCount++;
- }
-
- switch (fieldName) {
- case SESSION_ATTRIBUTE:
- case REQUEST_ATTRIBUTE:
- case COOKIE:
- if (additionalKey == null) {
- addError("\"OptionalKey\" property is mandatory for field name " + fieldName.toString());
- errorCount++;
- }
- }
-
- if (errorCount == 0) {
- started = true;
+ Object v = session.getAttribute(additionalKey);
+ if (v != null) {
+ return v.toString();
+ }
}
+ }
}
+ return null;
+ }
- public void setFieldName(FieldName fieldName) {
- this.fieldName = fieldName;
- }
-
- public FieldName getFieldName() {
- return fieldName;
- }
+ @Override
+ public void start() {
- public String getAdditionalKey() {
- return additionalKey;
- }
+ int errorCount = 0;
- public void setAdditionalKey(String additionalKey) {
- this.additionalKey = additionalKey;
+ if (defaultValue == null) {
+ addError("\"DefaultValue\" property must be set.");
}
-
- /**
- * @see #setDefaultValue(String)
- * @return
- */
- public String getDefaultValue() {
- return defaultValue;
- }
-
- /**
- * The default value returned by this discriminator in case it cannot compute
- * the discriminating value from the access event.
- *
- * @param defaultValue
- */
- public void setDefaultValue(String defaultValue) {
- this.defaultValue = defaultValue;
+ if (fieldName == null) {
+ addError("\"FieldName\" property must be set.");
+ errorCount++;
}
- public String getKey() {
- return key;
+ switch (fieldName) {
+ case SESSION_ATTRIBUTE:
+ case REQUEST_ATTRIBUTE:
+ case COOKIE:
+ if (additionalKey == null) {
+ addError("\"OptionalKey\" property is mandatory for field name "
+ + fieldName.toString());
+ errorCount++;
+ }
}
- public void setKey(String key) {
- this.key = key;
+ if (errorCount == 0) {
+ started = true;
}
+ }
+
+ public void setFieldName(FieldName fieldName) {
+ this.fieldName = fieldName;
+ }
+
+ public FieldName getFieldName() {
+ return fieldName;
+ }
+
+ public String getAdditionalKey() {
+ return additionalKey;
+ }
+
+ public void setAdditionalKey(String additionalKey) {
+ this.additionalKey = additionalKey;
+ }
+
+ /**
+ * @see #setDefaultValue(String)
+ * @return
+ */
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ /**
+ * The default value returned by this discriminator in case it cannot compute
+ * the discriminating value from the access event.
+ *
+ * @param defaultValue
+ */
+ public void setDefaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/sift/AppenderFactoryUsingJoran.java b/logback-access/src/main/java/ch/qos/logback/access/sift/AppenderFactoryUsingJoran.java
index 77d25ff..0bd2ad5 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/sift/AppenderFactoryUsingJoran.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/sift/AppenderFactoryUsingJoran.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,13 +23,13 @@ import ch.qos.logback.core.sift.SiftingJoranConfiguratorBase;
public class AppenderFactoryUsingJoran extends AbstractAppenderFactoryUsingJoran<IAccessEvent> {
- AppenderFactoryUsingJoran(List<SaxEvent> eventList, String key, Map<String, String> parentPropertyMap) {
- super(eventList, key, parentPropertyMap);
- }
+ AppenderFactoryUsingJoran(List<SaxEvent> eventList, String key, Map<String, String> parentPropertyMap) {
+ super(eventList, key, parentPropertyMap);
+ }
- @Override
- public SiftingJoranConfiguratorBase<IAccessEvent> getSiftingJoranConfigurator(String keyValue) {
- return new SiftingJoranConfigurator(key, keyValue, parentPropertyMap);
- }
+ public SiftingJoranConfiguratorBase<IAccessEvent> getSiftingJoranConfigurator(
+ String keyValue) {
+ return new SiftingJoranConfigurator(key, keyValue, parentPropertyMap);
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/sift/SiftAction.java b/logback-access/src/main/java/ch/qos/logback/access/sift/SiftAction.java
index a91a688..36f292c 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/sift/SiftAction.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/sift/SiftAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,34 +25,37 @@ import ch.qos.logback.core.joran.event.SaxEvent;
import ch.qos.logback.core.joran.spi.ActionException;
import ch.qos.logback.core.joran.spi.InterpretationContext;
-public class SiftAction extends Action implements InPlayListener {
- List<SaxEvent> seList;
-
- @Override
- public void begin(InterpretationContext ic, String name, Attributes attributes) throws ActionException {
- seList = new ArrayList<SaxEvent>();
- ic.addInPlayListener(this);
+public class SiftAction extends Action implements InPlayListener {
+ List<SaxEvent> seList;
+
+ @Override
+ public void begin(InterpretationContext ic, String name, Attributes attributes)
+ throws ActionException {
+ seList = new ArrayList<SaxEvent>();
+ ic.addInPlayListener(this);
+ }
+
+ @Override
+ public void end(InterpretationContext ic, String name) throws ActionException {
+ ic.removeInPlayListener(this);
+ Object o = ic.peekObject();
+ if (o instanceof SiftingAppender) {
+ SiftingAppender siftingAppender = (SiftingAppender) o;
+ Map<String, String> propertyMap = ic.getCopyOfPropertyMap();
+ AppenderFactoryUsingJoran appenderFactory = new AppenderFactoryUsingJoran(seList, siftingAppender.getDiscriminatorKey(), propertyMap);
+ siftingAppender.setAppenderFactory(appenderFactory);
}
+ }
- @Override
- public void end(InterpretationContext ic, String name) throws ActionException {
- ic.removeInPlayListener(this);
- Object o = ic.peekObject();
- if (o instanceof SiftingAppender) {
- SiftingAppender siftingAppender = (SiftingAppender) o;
- Map<String, String> propertyMap = ic.getCopyOfPropertyMap();
- AppenderFactoryUsingJoran appenderFactory = new AppenderFactoryUsingJoran(seList, siftingAppender.getDiscriminatorKey(), propertyMap);
- siftingAppender.setAppenderFactory(appenderFactory);
- }
- }
+ public void inPlay(SaxEvent event) {
+ seList.add(event);
+ }
- @Override
- public void inPlay(SaxEvent event) {
- seList.add(event);
- }
+ public List<SaxEvent> getSeList() {
+ return seList;
+ }
+
+
- public List<SaxEvent> getSeList() {
- return seList;
- }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java b/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java
index c80f3a4..f3f8998 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,24 +30,24 @@ import ch.qos.logback.core.sift.SiftingAppenderBase;
*/
public class SiftingAppender extends SiftingAppenderBase<IAccessEvent> {
- @Override
- public void start() {
- super.start();
- }
+ @Override
+ public void start() {
+ super.start();
+ }
- @Override
- protected long getTimestamp(IAccessEvent event) {
- return event.getTimeStamp();
- }
+ @Override
+ protected long getTimestamp(IAccessEvent event) {
+ return event.getTimeStamp();
+ }
- @Override
- protected boolean eventMarksEndOfLife(IAccessEvent event) {
- return false;
- }
+ @Override
+ protected boolean eventMarksEndOfLife(IAccessEvent event) {
+ return false;
+ }
- @Override
- @DefaultClass(AccessEventDiscriminator.class)
- public void setDiscriminator(Discriminator<IAccessEvent> discriminator) {
- super.setDiscriminator(discriminator);
- }
+ @Override
+ @DefaultClass(AccessEventDiscriminator.class)
+ public void setDiscriminator(Discriminator<IAccessEvent> discriminator) {
+ super.setDiscriminator(discriminator);
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingJoranConfigurator.java b/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingJoranConfigurator.java
index 04ad7b2..65ae986 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingJoranConfigurator.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingJoranConfigurator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,44 +26,48 @@ import ch.qos.logback.core.joran.spi.ElementSelector;
import ch.qos.logback.core.joran.spi.RuleStore;
import ch.qos.logback.core.sift.SiftingJoranConfiguratorBase;
-public class SiftingJoranConfigurator extends SiftingJoranConfiguratorBase<IAccessEvent> {
+public class SiftingJoranConfigurator extends
+ SiftingJoranConfiguratorBase<IAccessEvent> {
- SiftingJoranConfigurator(String key, String value, Map<String, String> parentPropertyMap) {
- super(key, value, parentPropertyMap);
- }
- @Override
- protected ElementPath initialElementPath() {
- return new ElementPath("configuration");
- }
- @Override
- protected void addInstanceRules(RuleStore rs) {
- rs.addRule(new ElementSelector("configuration/appender"), new AppenderAction<IAccessEvent>());
- }
+ SiftingJoranConfigurator(String key, String value, Map<String, String> parentPropertyMap) {
+ super(key, value, parentPropertyMap);
+ }
- @Override
- protected void buildInterpreter() {
- super.buildInterpreter();
- Map<String, Object> omap = interpreter.getInterpretationContext().getObjectMap();
- omap.put(ActionConst.APPENDER_BAG, new HashMap<String, Appender<IAccessEvent>>());
- //omap.put(ActionConst.FILTER_CHAIN_BAG, new HashMap());
- Map<String, String> propertiesMap = new HashMap<String, String>();
- propertiesMap.putAll(parentPropertyMap);
- propertiesMap.put(key, value);
- interpreter.setInterpretationContextPropertiesMap(propertiesMap);
- }
+ @Override
+ protected ElementPath initialElementPath() {
+ return new ElementPath("configuration");
+ }
+
+ @Override
+ protected void addInstanceRules(RuleStore rs) {
+ rs.addRule(new ElementSelector("configuration/appender"), new AppenderAction());
+ }
+
+ @Override
+ protected void buildInterpreter() {
+ super.buildInterpreter();
+ Map<String, Object> omap = interpreter.getInterpretationContext()
+ .getObjectMap();
+ omap.put(ActionConst.APPENDER_BAG, new HashMap());
+ omap.put(ActionConst.FILTER_CHAIN_BAG, new HashMap());
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.putAll(parentPropertyMap);
+ propertiesMap.put(key, value);
+ interpreter.setInterpretationContextPropertiesMap(propertiesMap);
+ }
- @SuppressWarnings("unchecked")
- @Override
- public Appender<IAccessEvent> getAppender() {
- Map<String, Object> omap = interpreter.getInterpretationContext().getObjectMap();
- HashMap<String, Appender<?>> appenderMap = (HashMap<String, Appender<?>>) omap.get(ActionConst.APPENDER_BAG);
- oneAndOnlyOneCheck(appenderMap);
- Collection<Appender<?>> values = appenderMap.values();
- if (values.size() == 0) {
- return null;
- }
- return (Appender<IAccessEvent>) values.iterator().next();
+ @SuppressWarnings("unchecked")
+ public Appender<IAccessEvent> getAppender() {
+ Map<String, Object> omap = interpreter.getInterpretationContext()
+ .getObjectMap();
+ HashMap appenderMap = (HashMap) omap.get(ActionConst.APPENDER_BAG);
+ oneAndOnlyOneCheck(appenderMap);
+ Collection values = appenderMap.values();
+ if(values.size() == 0) {
+ return null;
}
+ return (Appender<IAccessEvent>) values.iterator().next();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/spi/AccessContext.java b/logback-access/src/main/java/ch/qos/logback/access/spi/AccessContext.java
index 12329b1..c22e258 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/spi/AccessContext.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/spi/AccessContext.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,67 +31,57 @@ import ch.qos.logback.core.spi.FilterReply;
*
* @author Sébastien Pennec
*/
-public class AccessContext extends ContextBase implements AppenderAttachable<IAccessEvent>, FilterAttachable<IAccessEvent> {
-
- AppenderAttachableImpl<IAccessEvent> aai = new AppenderAttachableImpl<IAccessEvent>();
- FilterAttachableImpl<IAccessEvent> fai = new FilterAttachableImpl<IAccessEvent>();
-
- public void callAppenders(IAccessEvent event) {
- aai.appendLoopOnAppenders(event);
- }
-
- @Override
- public void addAppender(Appender<IAccessEvent> newAppender) {
- aai.addAppender(newAppender);
- }
-
- @Override
- public void detachAndStopAllAppenders() {
- aai.detachAndStopAllAppenders();
- }
-
- @Override
- public boolean detachAppender(Appender<IAccessEvent> appender) {
- return aai.detachAppender(appender);
- }
-
- @Override
- public boolean detachAppender(String name) {
- return aai.detachAppender(name);
- }
-
- @Override
- public Appender<IAccessEvent> getAppender(String name) {
- return aai.getAppender(name);
- }
-
- @Override
- public boolean isAttached(Appender<IAccessEvent> appender) {
- return aai.isAttached(appender);
- }
-
- @Override
- public Iterator<Appender<IAccessEvent>> iteratorForAppenders() {
- return aai.iteratorForAppenders();
- }
-
- @Override
- public void addFilter(Filter<IAccessEvent> newFilter) {
- fai.addFilter(newFilter);
- }
-
- @Override
- public void clearAllFilters() {
- fai.clearAllFilters();
- }
-
- @Override
- public List<Filter<IAccessEvent>> getCopyOfAttachedFiltersList() {
- return fai.getCopyOfAttachedFiltersList();
- }
-
- @Override
- public FilterReply getFilterChainDecision(IAccessEvent event) {
- return fai.getFilterChainDecision(event);
- }
+public class AccessContext extends ContextBase implements
+ AppenderAttachable<IAccessEvent>, FilterAttachable<IAccessEvent> {
+
+ AppenderAttachableImpl<IAccessEvent> aai = new AppenderAttachableImpl<IAccessEvent>();
+ FilterAttachableImpl<IAccessEvent> fai = new FilterAttachableImpl<IAccessEvent>();
+
+ public void callAppenders(IAccessEvent event) {
+ aai.appendLoopOnAppenders(event);
+ }
+
+ public void addAppender(Appender<IAccessEvent> newAppender) {
+ aai.addAppender(newAppender);
+ }
+
+ public void detachAndStopAllAppenders() {
+ aai.detachAndStopAllAppenders();
+ }
+
+ public boolean detachAppender(Appender<IAccessEvent> appender) {
+ return aai.detachAppender(appender);
+ }
+
+ public boolean detachAppender(String name) {
+ return aai.detachAppender(name);
+ }
+
+ public Appender<IAccessEvent> getAppender(String name) {
+ return aai.getAppender(name);
+ }
+
+ public boolean isAttached(Appender<IAccessEvent> appender) {
+ return aai.isAttached(appender);
+ }
+
+ public Iterator<Appender<IAccessEvent>> iteratorForAppenders() {
+ return aai.iteratorForAppenders();
+ }
+
+ public void addFilter(Filter<IAccessEvent> newFilter) {
+ fai.addFilter(newFilter);
+ }
+
+ public void clearAllFilters() {
+ fai.clearAllFilters();
+ }
+
+ public List<Filter<IAccessEvent>> getCopyOfAttachedFiltersList() {
+ return fai.getCopyOfAttachedFiltersList();
+ }
+
+ public FilterReply getFilterChainDecision(IAccessEvent event) {
+ return fai.getFilterChainDecision(event);
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java b/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java
index 9fac863..53d7bfa 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,8 +20,6 @@ import ch.qos.logback.access.servlet.Util;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
@@ -44,556 +42,463 @@ import java.util.Vector;
*/
public class AccessEvent implements Serializable, IAccessEvent {
- private static final long serialVersionUID = 866718993618836343L;
-
- private static final String EMPTY = "";
-
- private transient final HttpServletRequest httpRequest;
- private transient final HttpServletResponse httpResponse;
-
- String queryString;
- String requestURI;
- String requestURL;
- String remoteHost;
- String remoteUser;
- String remoteAddr;
- String threadName;
- String protocol;
- String method;
- String serverName;
- String requestContent;
- String responseContent;
- String sessionID;
- long elapsedTime;
-
- Map<String, String> requestHeaderMap;
- Map<String, String[]> requestParameterMap;
- Map<String, String> responseHeaderMap;
- Map<String, Object> attributeMap;
-
- long contentLength = SENTINEL;
- int statusCode = SENTINEL;
- int localPort = SENTINEL;
-
- transient ServerAdapter serverAdapter;
-
- /**
- * The number of milliseconds elapsed from 1/1/1970 until logging event was
- * created.
- */
- private long timeStamp = 0;
-
- public AccessEvent(HttpServletRequest httpRequest, HttpServletResponse httpResponse, ServerAdapter adapter) {
- this.httpRequest = httpRequest;
- this.httpResponse = httpResponse;
- this.timeStamp = System.currentTimeMillis();
- this.serverAdapter = adapter;
- this.elapsedTime = calculateElapsedTime();
- }
-
- /**
- * Returns the underlying HttpServletRequest. After serialization the returned
- * value will be null.
- *
- * @return
- */
- @Override
- public HttpServletRequest getRequest() {
- return httpRequest;
- }
-
- /**
- * Returns the underlying HttpServletResponse. After serialization the returned
- * value will be null.
- *
- * @return
- */
- @Override
- public HttpServletResponse getResponse() {
- return httpResponse;
- }
-
- @Override
- public long getTimeStamp() {
- return timeStamp;
- }
-
- public void setTimeStamp(long timeStamp) {
- if (this.timeStamp != 0) {
- throw new IllegalStateException("timeStamp has been already set for this event.");
- } else {
- this.timeStamp = timeStamp;
- }
- }
-
- /**
- * @param threadName The threadName to set.
- */
- public void setThreadName(String threadName) {
- this.threadName = threadName;
- }
-
- @Override
- public String getThreadName() {
- return threadName == null ? NA : threadName;
- }
-
- @Override
- public String getRequestURI() {
- if (requestURI == null) {
- if (httpRequest != null) {
- requestURI = httpRequest.getRequestURI();
- } else {
- requestURI = NA;
- }
- }
- return requestURI;
- }
-
- @Override
- public String getQueryString() {
- if (queryString == null) {
- if (httpRequest != null) {
- StringBuilder buf = new StringBuilder();
- final String qStr = httpRequest.getQueryString();
- if (qStr != null) {
- buf.append(AccessConverter.QUESTION_CHAR);
- buf.append(qStr);
- }
- queryString = buf.toString();
- } else {
- queryString = NA;
- }
- }
- return queryString;
- }
-
- /**
- * The first line of the request.
- */
- @Override
- public String getRequestURL() {
- if (requestURL == null) {
- if (httpRequest != null) {
- StringBuilder buf = new StringBuilder();
- buf.append(httpRequest.getMethod());
- buf.append(AccessConverter.SPACE_CHAR);
- buf.append(httpRequest.getRequestURI());
- buf.append(getQueryString());
- buf.append(AccessConverter.SPACE_CHAR);
- buf.append(httpRequest.getProtocol());
- requestURL = buf.toString();
- } else {
- requestURL = NA;
- }
- }
- return requestURL;
- }
-
- @Override
- public String getRemoteHost() {
- if (remoteHost == null) {
- if (httpRequest != null) {
- // the underlying implementation of HttpServletRequest will
- // determine if remote lookup will be performed
- remoteHost = httpRequest.getRemoteHost();
- } else {
- remoteHost = NA;
- }
- }
- return remoteHost;
- }
-
- @Override
- public String getRemoteUser() {
- if (remoteUser == null) {
- if (httpRequest != null) {
- remoteUser = httpRequest.getRemoteUser();
- } else {
- remoteUser = NA;
- }
- }
- return remoteUser;
- }
-
- @Override
- public String getProtocol() {
- if (protocol == null) {
- if (httpRequest != null) {
- protocol = httpRequest.getProtocol();
- } else {
- protocol = NA;
- }
- }
- return protocol;
- }
-
- @Override
- public String getMethod() {
- if (method == null) {
- if (httpRequest != null) {
- method = httpRequest.getMethod();
- } else {
- method = NA;
- }
- }
- return method;
- }
-
- @Override
- public String getSessionID() {
- if (sessionID == null) {
- if (httpRequest != null) {
- final HttpSession session = httpRequest.getSession();
- if (session != null) {
- sessionID = session.getId();
- }
- } else {
- sessionID = NA;
- }
- }
- return sessionID;
- }
-
- @Override
- public String getServerName() {
- if (serverName == null) {
- if (httpRequest != null) {
- serverName = httpRequest.getServerName();
- } else {
- serverName = NA;
- }
- }
- return serverName;
- }
-
- @Override
- public String getRemoteAddr() {
- if (remoteAddr == null) {
- if (httpRequest != null) {
- remoteAddr = httpRequest.getRemoteAddr();
- } else {
- remoteAddr = NA;
- }
- }
- return remoteAddr;
- }
-
- @Override
- public String getRequestHeader(String key) {
- String result = null;
- key = key.toLowerCase();
- if (requestHeaderMap == null) {
- if (httpRequest != null) {
- buildRequestHeaderMap();
- result = requestHeaderMap.get(key);
- }
- } else {
- result = requestHeaderMap.get(key);
- }
-
- if (result != null) {
- return result;
- } else {
- return NA;
- }
- }
-
- @Override
- public Enumeration<String> getRequestHeaderNames() {
- // post-serialization
- if (httpRequest == null) {
- Vector<String> list = new Vector<String>(getRequestHeaderMap().keySet());
- return list.elements();
- }
- return httpRequest.getHeaderNames();
- }
-
- @Override
- public Map<String, String> getRequestHeaderMap() {
- if (requestHeaderMap == null) {
- buildRequestHeaderMap();
- }
- return requestHeaderMap;
- }
-
- public void buildRequestHeaderMap() {
- // according to RFC 2616 header names are case insensitive
- // latest versions of Tomcat return header names in lower-case
- requestHeaderMap = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
- Enumeration<String> e = httpRequest.getHeaderNames();
- if (e == null) {
- return;
- }
- while (e.hasMoreElements()) {
- String key = e.nextElement();
- requestHeaderMap.put(key, httpRequest.getHeader(key));
- }
- }
-
- public void buildRequestParameterMap() {
- requestParameterMap = new HashMap<String, String[]>();
- Enumeration<String> e = httpRequest.getParameterNames();
- if (e == null) {
- return;
- }
- while (e.hasMoreElements()) {
- String key = e.nextElement();
- requestParameterMap.put(key, httpRequest.getParameterValues(key));
- }
- }
-
- @Override
- public Map<String, String[]> getRequestParameterMap() {
- if (requestParameterMap == null) {
- buildRequestParameterMap();
- }
- return requestParameterMap;
- }
-
- @Override
- public String getAttribute(String key) {
- Object value = null;
- if (attributeMap != null) {
- // Event was prepared for deferred processing so we have a copy of attribute map and must use that copy
- value = attributeMap.get(key);
- } else if (httpRequest != null) {
- // We have original request so take attribute from it
- value = httpRequest.getAttribute(key);
- }
- return value != null ? value.toString() : NA;
- }
-
- private void copyAttributeMap() {
-
- if (httpRequest == null) {
- return;
- }
-
- attributeMap = new HashMap<String, Object>();
-
- Enumeration<String> names = httpRequest.getAttributeNames();
- while (names.hasMoreElements()) {
- String name = names.nextElement();
-
- Object value = httpRequest.getAttribute(name);
- if (shouldCopyAttribute(name, value)) {
- attributeMap.put(name, value);
- }
- }
- }
-
- private boolean shouldCopyAttribute(String name, Object value) {
- if (AccessConstants.LB_INPUT_BUFFER.equals(name) || AccessConstants.LB_OUTPUT_BUFFER.equals(name)) {
- // Do not copy attributes used by logback internally - these are available via other getters anyway
- return false;
- } else if (value == null) {
- // No reasons to copy nulls - Map.get() will return null for missing keys and the list of attribute
- // names is not available through IAccessEvent
- return false;
- } else {
- // Only copy what is serializable
- return value instanceof Serializable;
- }
- }
-
- @Override
- public String[] getRequestParameter(String key) {
- if (httpRequest != null) {
- String[] value = httpRequest.getParameterValues(key);
- if (value == null) {
- return new String[] { NA };
- } else {
- return value;
- }
- } else {
- return new String[] { NA };
- }
- }
-
- @Override
- public String getCookie(String key) {
-
- if (httpRequest != null) {
- Cookie[] cookieArray = httpRequest.getCookies();
- if (cookieArray == null) {
- return NA;
- }
-
- for (Cookie cookie : cookieArray) {
- if (key.equals(cookie.getName())) {
- return cookie.getValue();
- }
- }
- }
+ private static final long serialVersionUID = 866718993618836343L;
+
+ private static final String EMPTY = "";
+
+ private transient final HttpServletRequest httpRequest;
+ private transient final HttpServletResponse httpResponse;
+
+ String requestURI;
+ String requestURL;
+ String remoteHost;
+ String remoteUser;
+ String remoteAddr;
+ String protocol;
+ String method;
+ String serverName;
+ String requestContent;
+ String responseContent;
+ long elapsedTime;
+
+ Map<String, String> requestHeaderMap;
+ Map<String, String[]> requestParameterMap;
+ Map<String, String> responseHeaderMap;
+
+ long contentLength = SENTINEL;
+ int statusCode = SENTINEL;
+ int localPort = SENTINEL;
+
+ transient ServerAdapter serverAdapter;
+
+ /**
+ * The number of milliseconds elapsed from 1/1/1970 until logging event was
+ * created.
+ */
+ private long timeStamp = 0;
+
+ public AccessEvent(HttpServletRequest httpRequest,
+ HttpServletResponse httpResponse, ServerAdapter adapter) {
+ this.httpRequest = httpRequest;
+ this.httpResponse = httpResponse;
+ this.timeStamp = System.currentTimeMillis();
+ this.serverAdapter = adapter;
+ this.elapsedTime = calculateElapsedTime();
+ }
+
+ /**
+ * Returns the underlying HttpServletRequest. After serialization the returned
+ * value will be null.
+ *
+ * @return
+ */
+ public HttpServletRequest getRequest() {
+ return httpRequest;
+ }
+
+ /**
+ * Returns the underlying HttpServletResponse. After serialization the returned
+ * value will be null.
+ *
+ * @return
+ */
+ public HttpServletResponse getResponse() {
+ return httpResponse;
+ }
+
+ public long getTimeStamp() {
+ return timeStamp;
+ }
+
+ public void setTimeStamp(long timeStamp) {
+ if (this.timeStamp != 0) {
+ throw new IllegalStateException(
+ "timeStamp has been already set for this event.");
+ } else {
+ this.timeStamp = timeStamp;
+ }
+ }
+
+ public String getRequestURI() {
+ if (requestURI == null) {
+ if (httpRequest != null) {
+ requestURI = httpRequest.getRequestURI();
+ } else {
+ requestURI = NA;
+ }
+ }
+ return requestURI;
+ }
+
+ /**
+ * The first line of the request.
+ */
+ public String getRequestURL() {
+ if (requestURL == null) {
+ if (httpRequest != null) {
+ StringBuilder buf = new StringBuilder();
+ buf.append(httpRequest.getMethod());
+ buf.append(AccessConverter.SPACE_CHAR);
+ buf.append(httpRequest.getRequestURI());
+ final String qStr = httpRequest.getQueryString();
+ if (qStr != null) {
+ buf.append(AccessConverter.QUESTION_CHAR);
+ buf.append(qStr);
+ }
+ buf.append(AccessConverter.SPACE_CHAR);
+ buf.append(httpRequest.getProtocol());
+ requestURL = buf.toString();
+ } else {
+ requestURL = NA;
+ }
+ }
+ return requestURL;
+ }
+
+ public String getRemoteHost() {
+ if (remoteHost == null) {
+ if (httpRequest != null) {
+ // the underlying implementation of HttpServletRequest will
+ // determine if remote lookup will be performed
+ remoteHost = httpRequest.getRemoteHost();
+ } else {
+ remoteHost = NA;
+ }
+ }
+ return remoteHost;
+ }
+
+ public String getRemoteUser() {
+ if (remoteUser == null) {
+ if (httpRequest != null) {
+ remoteUser = httpRequest.getRemoteUser();
+ } else {
+ remoteUser = NA;
+ }
+ }
+ return remoteUser;
+ }
+
+ public String getProtocol() {
+ if (protocol == null) {
+ if (httpRequest != null) {
+ protocol = httpRequest.getProtocol();
+ } else {
+ protocol = NA;
+ }
+ }
+ return protocol;
+ }
+
+ public String getMethod() {
+ if (method == null) {
+ if (httpRequest != null) {
+ method = httpRequest.getMethod();
+ } else {
+ method = NA;
+ }
+ }
+ return method;
+ }
+
+ public String getServerName() {
+ if (serverName == null) {
+ if (httpRequest != null) {
+ serverName = httpRequest.getServerName();
+ } else {
+ serverName = NA;
+ }
+ }
+ return serverName;
+ }
+
+ public String getRemoteAddr() {
+ if (remoteAddr == null) {
+ if (httpRequest != null) {
+ remoteAddr = httpRequest.getRemoteAddr();
+ } else {
+ remoteAddr = NA;
+ }
+ }
+ return remoteAddr;
+ }
+
+ public String getRequestHeader(String key) {
+ String result = null;
+ key = key.toLowerCase();
+ if (requestHeaderMap == null) {
+ if (httpRequest != null) {
+ buildRequestHeaderMap();
+ result = requestHeaderMap.get(key);
+ }
+ } else {
+ result = requestHeaderMap.get(key);
+ }
+
+ if (result != null) {
+ return result;
+ } else {
+ return NA;
+ }
+ }
+
+ public Enumeration getRequestHeaderNames() {
+ // post-serialization
+ if (httpRequest == null) {
+ Vector<String> list = new Vector<String>(getRequestHeaderMap().keySet());
+ return list.elements();
+ }
+ return httpRequest.getHeaderNames();
+ }
+
+ public Map<String, String> getRequestHeaderMap() {
+ if (requestHeaderMap == null) {
+ buildRequestHeaderMap();
+ }
+ return requestHeaderMap;
+ }
+
+ public void buildRequestHeaderMap() {
+ // according to RFC 2616 header names are case insensitive
+ // latest versions of Tomcat return header names in lower-case
+ requestHeaderMap = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+ Enumeration e = httpRequest.getHeaderNames();
+ if (e == null) {
+ return;
+ }
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+ requestHeaderMap.put(key, httpRequest.getHeader(key));
+ }
+ }
+
+ public void buildRequestParameterMap() {
+ requestParameterMap = new HashMap<String, String[]>();
+ Enumeration e = httpRequest.getParameterNames();
+ if (e == null) {
+ return;
+ }
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+ requestParameterMap.put(key, httpRequest.getParameterValues(key));
+ }
+ }
+
+ public Map<String, String[]> getRequestParameterMap() {
+ if (requestParameterMap == null) {
+ buildRequestParameterMap();
+ }
+ return requestParameterMap;
+ }
+
+ /**
+ * Attributes are not serialized
+ *
+ * @param key
+ */
+ public String getAttribute(String key) {
+ if (httpRequest != null) {
+ Object value = httpRequest.getAttribute(key);
+ if (value == null) {
return NA;
- }
-
- @Override
- public long getContentLength() {
- if (contentLength == SENTINEL) {
- if (httpResponse != null) {
- contentLength = serverAdapter.getContentLength();
- return contentLength;
- }
- }
- return contentLength;
- }
-
- public int getStatusCode() {
- if (statusCode == SENTINEL) {
- if (httpResponse != null) {
- statusCode = serverAdapter.getStatusCode();
- }
- }
- return statusCode;
- }
-
- public long getElapsedSeconds() {
- return elapsedTime < 0 ? elapsedTime : elapsedTime / 1000;
- }
-
- public long getElapsedTime() {
- return elapsedTime;
- }
-
- private long calculateElapsedTime() {
- if (serverAdapter.getRequestTimestamp() < 0) {
- return -1;
- }
- return getTimeStamp() - serverAdapter.getRequestTimestamp();
- }
-
- public String getRequestContent() {
- if (requestContent != null) {
- return requestContent;
- }
+ } else {
+ return value.toString();
+ }
+ } else {
+ return NA;
+ }
+ }
+
+ public String[] getRequestParameter(String key) {
+ if (httpRequest != null) {
+ String[] value = httpRequest.getParameterValues(key);
+ if (value == null) {
+ return new String[]{ NA };
+ } else {
+ return value;
+ }
+ } else {
+ return new String[]{ NA };
+ }
+ }
+
+ public String getCookie(String key) {
+
+ if (httpRequest != null) {
+ Cookie[] cookieArray = httpRequest.getCookies();
+ if (cookieArray == null) {
+ return NA;
+ }
- if (Util.isFormUrlEncoded(httpRequest)) {
- StringBuilder buf = new StringBuilder();
-
- Enumeration<String> pramEnumeration = httpRequest.getParameterNames();
-
- // example: id=1234&user=cgu
- // number=1233&x=1
- int count = 0;
- try {
- while (pramEnumeration.hasMoreElements()) {
-
- String key = pramEnumeration.nextElement();
- if (count++ != 0) {
- buf.append("&");
- }
- buf.append(key);
- buf.append("=");
- String val = httpRequest.getParameter(key);
- if (val != null) {
- buf.append(val);
- } else {
- buf.append("");
- }
- }
- } catch (Exception e) {
- // FIXME Why is try/catch required?
- e.printStackTrace();
- }
- requestContent = buf.toString();
- } else {
- // retrieve the byte array placed by TeeFilter
- byte[] inputBuffer = (byte[]) httpRequest.getAttribute(AccessConstants.LB_INPUT_BUFFER);
-
- if (inputBuffer != null) {
- requestContent = new String(inputBuffer);
- }
-
- if (requestContent == null || requestContent.length() == 0) {
- requestContent = EMPTY;
- }
+ for (Cookie cookie : cookieArray) {
+ if (key.equals(cookie.getName())) {
+ return cookie.getValue();
}
-
- return requestContent;
+ }
}
+ return NA;
+ }
- public String getResponseContent() {
- if (responseContent != null) {
- return responseContent;
- }
-
- if (Util.isImageResponse(httpResponse)) {
- responseContent = "[IMAGE CONTENTS SUPPRESSED]";
- } else {
-
- // retreive the byte array previously placed by TeeFilter
- byte[] outputBuffer = (byte[]) httpRequest.getAttribute(AccessConstants.LB_OUTPUT_BUFFER);
-
- if (outputBuffer != null) {
- responseContent = new String(outputBuffer);
- }
- if (responseContent == null || responseContent.length() == 0) {
- responseContent = EMPTY;
- }
- }
-
- return responseContent;
+ public long getContentLength() {
+ if (contentLength == SENTINEL) {
+ if (httpResponse != null) {
+ contentLength = serverAdapter.getContentLength();
+ return contentLength;
+ }
}
-
- public int getLocalPort() {
- if (localPort == SENTINEL) {
- if (httpRequest != null) {
- localPort = httpRequest.getLocalPort();
- }
-
- }
- return localPort;
+ return contentLength;
+ }
+
+ public int getStatusCode() {
+ if (statusCode == SENTINEL) {
+ if (httpResponse != null) {
+ statusCode = serverAdapter.getStatusCode();
+ }
}
+ return statusCode;
+ }
- public ServerAdapter getServerAdapter() {
- return serverAdapter;
- }
+ public long getElapsedTime() {
+ return elapsedTime;
+ }
- public String getResponseHeader(String key) {
- buildResponseHeaderMap();
- return responseHeaderMap.get(key);
+ private long calculateElapsedTime() {
+ if (serverAdapter.getRequestTimestamp() < 0) {
+ return -1;
}
+ return getTimeStamp() - serverAdapter.getRequestTimestamp();
+ }
- void buildResponseHeaderMap() {
- if (responseHeaderMap == null) {
- responseHeaderMap = serverAdapter.buildResponseHeaderMap();
- }
+ public String getRequestContent() {
+ if (requestContent != null) {
+ return requestContent;
}
- public Map<String, String> getResponseHeaderMap() {
- buildResponseHeaderMap();
- return responseHeaderMap;
- }
+ if (Util.isFormUrlEncoded(httpRequest)) {
+ StringBuilder buf = new StringBuilder();
- public List<String> getResponseHeaderNameList() {
- buildResponseHeaderMap();
- return new ArrayList<String>(responseHeaderMap.keySet());
- }
+ Enumeration pramEnumeration = httpRequest.getParameterNames();
- public void prepareForDeferredProcessing() {
- getRequestHeaderMap();
- getRequestParameterMap();
- getResponseHeaderMap();
- getLocalPort();
- getMethod();
- getProtocol();
- getRemoteAddr();
- getRemoteHost();
- getRemoteUser();
- getRequestURI();
- getRequestURL();
- getServerName();
- getTimeStamp();
- getElapsedTime();
-
- getStatusCode();
- getContentLength();
- getRequestContent();
- getResponseContent();
-
- copyAttributeMap();
- }
+ // example: id=1234&user=cgu
+ // number=1233&x=1
+ int count = 0;
+ try {
+ while (pramEnumeration.hasMoreElements()) {
+
+ String key = (String) pramEnumeration.nextElement();
+ if (count++ != 0) {
+ buf.append("&");
+ }
+ buf.append(key);
+ buf.append("=");
+ String val = httpRequest.getParameter(key);
+ if (val != null) {
+ buf.append(val);
+ } else {
+ buf.append("");
+ }
+ }
+ } catch (Exception e) {
+ // FIXME Why is try/catch required?
+ e.printStackTrace();
+ }
+ requestContent = buf.toString();
+ } else {
+ // retrieve the byte array placed by TeeFilter
+ byte[] inputBuffer = (byte[]) httpRequest
+ .getAttribute(AccessConstants.LB_INPUT_BUFFER);
+
+ if (inputBuffer != null) {
+ requestContent = new String(inputBuffer);
+ }
+
+ if (requestContent == null || requestContent.length() == 0) {
+ requestContent = EMPTY;
+ }
+ }
+
+ return requestContent;
+ }
+
+ public String getResponseContent() {
+ if (responseContent != null) {
+ return responseContent;
+ }
+
+ if (Util.isImageResponse(httpResponse)) {
+ responseContent = "[IMAGE CONTENTS SUPPRESSED]";
+ } else {
+
+ // retreive the byte array previously placed by TeeFilter
+ byte[] outputBuffer = (byte[]) httpRequest
+ .getAttribute(AccessConstants.LB_OUTPUT_BUFFER);
+
+ if (outputBuffer != null) {
+ responseContent = new String(outputBuffer);
+ }
+ if (responseContent == null || responseContent.length() == 0) {
+ responseContent = EMPTY;
+ }
+ }
+
+ return responseContent;
+ }
+
+ public int getLocalPort() {
+ if (localPort == SENTINEL) {
+ if (httpRequest != null) {
+ localPort = httpRequest.getLocalPort();
+ }
+
+ }
+ return localPort;
+ }
+
+ public ServerAdapter getServerAdapter() {
+ return serverAdapter;
+ }
+
+ public String getResponseHeader(String key) {
+ buildResponseHeaderMap();
+ return responseHeaderMap.get(key);
+ }
+
+ void buildResponseHeaderMap() {
+ if (responseHeaderMap == null) {
+ responseHeaderMap = serverAdapter.buildResponseHeaderMap();
+ }
+ }
+
+ public Map<String, String> getResponseHeaderMap() {
+ buildResponseHeaderMap();
+ return responseHeaderMap;
+ }
+
+ public List<String> getResponseHeaderNameList() {
+ buildResponseHeaderMap();
+ return new ArrayList<String>(responseHeaderMap.keySet());
+ }
+
+ public void prepareForDeferredProcessing() {
+ buildRequestHeaderMap();
+ buildRequestParameterMap();
+ buildResponseHeaderMap();
+ getLocalPort();
+ getMethod();
+ getProtocol();
+ getRemoteAddr();
+ getRemoteHost();
+ getRemoteUser();
+ getRequestURI();
+ getRequestURL();
+ getServerName();
+ getTimeStamp();
+ getElapsedTime();
+
+ getStatusCode();
+ getContentLength();
+ getRequestContent();
+ getResponseContent();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/spi/IAccessEvent.java b/logback-access/src/main/java/ch/qos/logback/access/spi/IAccessEvent.java
index ec86fd1..c79e7ad 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/spi/IAccessEvent.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/spi/IAccessEvent.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -35,96 +35,89 @@ import java.util.Map;
*/
public interface IAccessEvent extends DeferredProcessingAware {
- String NA = "-";
- int SENTINEL = -1;
+ String NA = "-";
+ int SENTINEL = -1;
- /**
- * Returns the underlying HttpServletRequest. After serialization the returned
- * value will be null.
- *
- * @return
- */
- HttpServletRequest getRequest();
+ /**
+ * Returns the underlying HttpServletRequest. After serialization the returned
+ * value will be null.
+ *
+ * @return
+ */
+ HttpServletRequest getRequest();
- /**
- * Returns the underlying HttpServletResponse. After serialization the returned
- * value will be null.
- *
- * @return
- */
- HttpServletResponse getResponse();
+ /**
+ * Returns the underlying HttpServletResponse. After serialization the returned
+ * value will be null.
+ *
+ * @return
+ */
+ HttpServletResponse getResponse();
- /**
- * The number of milliseconds elapsed from 1/1/1970 until logging event was
- * created.
- */
- long getTimeStamp();
+ /**
+ * The number of milliseconds elapsed from 1/1/1970 until logging event was
+ * created.
+ */
+ long getTimeStamp();
- /**
- * The time elapsed between receiving the request and logging it in milliseconds.
- */
- long getElapsedTime();
+ /**
+ * The time elapsed between receiving the request and logging it.
+ */
+ long getElapsedTime();
- /**
- * The number of seconds elapsed between receiving the request and logging it.
- */
- long getElapsedSeconds();
+ String getRequestURI();
- String getRequestURI();
+ /**
+ * The first line of the request.
+ */
+ String getRequestURL();
- /**
- * The first line of the request.
- */
- String getRequestURL();
+ String getRemoteHost();
- String getRemoteHost();
+ String getRemoteUser();
- String getRemoteUser();
+ String getProtocol();
- String getProtocol();
+ String getMethod();
- String getMethod();
+ String getServerName();
- String getServerName();
+ String getRemoteAddr();
- String getSessionID();
+ String getRequestHeader(String key);
- void setThreadName(String threadName);
- String getThreadName();
-
- String getQueryString();
-
- String getRemoteAddr();
+ Enumeration getRequestHeaderNames();
- String getRequestHeader(String key);
+ Map<String, String> getRequestHeaderMap();
- Enumeration getRequestHeaderNames();
+ Map<String, String[]> getRequestParameterMap();
- Map<String, String> getRequestHeaderMap();
+ /**
+ * Attributes are not serialized
+ *
+ * @param key
+ */
+ String getAttribute(String key);
- Map<String, String[]> getRequestParameterMap();
+ String[] getRequestParameter(String key);
- String getAttribute(String key);
+ String getCookie(String key);
- String[] getRequestParameter(String key);
+ long getContentLength();
- String getCookie(String key);
+ int getStatusCode();
- long getContentLength();
+ String getRequestContent();
- int getStatusCode();
+ String getResponseContent();
- String getRequestContent();
+ int getLocalPort();
- String getResponseContent();
+ ServerAdapter getServerAdapter();
- int getLocalPort();
+ String getResponseHeader(String key);
- ServerAdapter getServerAdapter();
+ Map<String, String> getResponseHeaderMap();
- String getResponseHeader(String key);
-
- Map<String, String> getResponseHeaderMap();
-
- List<String> getResponseHeaderNameList();
+ List<String> getResponseHeaderNameList();
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/spi/ServerAdapter.java b/logback-access/src/main/java/ch/qos/logback/access/spi/ServerAdapter.java
index 792f8af..3fd900c 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/spi/ServerAdapter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/spi/ServerAdapter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,11 +24,8 @@ import java.util.Map;
*/
public interface ServerAdapter {
- long getRequestTimestamp();
-
- long getContentLength();
-
- int getStatusCode();
-
- Map<String, String> buildResponseHeaderMap();
+ long getRequestTimestamp();
+ long getContentLength();
+ int getStatusCode();
+ Map<String, String> buildResponseHeaderMap();
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/spi/Util.java b/logback-access/src/main/java/ch/qos/logback/access/spi/Util.java
index ffb8722..0456cc4 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/spi/Util.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/spi/Util.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,18 +18,18 @@ import java.io.IOException;
import java.io.InputStream;
public class Util {
- static final int BUF_SIZE = 128;
-
- public static String readToString(InputStream in) throws IOException {
- if (in == null) {
- return null;
- }
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] buf = new byte[BUF_SIZE];
- int n = 0;
- while ((n = in.read(buf, 0, BUF_SIZE)) != -1) {
- baos.write(buf, 0, n);
- }
- return baos.toString();
+ static final int BUF_SIZE= 128;
+
+ public static String readToString(InputStream in) throws IOException {
+ if(in == null) {
+ return null;
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buf = new byte[BUF_SIZE];
+ int n = 0;
+ while( (n = in.read(buf, 0, BUF_SIZE)) != -1) {
+ baos.write(buf, 0, n);
}
+ return baos.toString();
+ }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/tomcat/LogbackValve.java b/logback-access/src/main/java/ch/qos/logback/access/tomcat/LogbackValve.java
index 49ee9ca..4bfc1fd 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/tomcat/LogbackValve.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/tomcat/LogbackValve.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,15 +15,11 @@ package ch.qos.logback.access.tomcat;
import java.io.File;
import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
@@ -45,7 +41,6 @@ import ch.qos.logback.core.BasicStatusManager;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.LifeCycleManager;
-import ch.qos.logback.core.boolex.EventEvaluator;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.spi.AppenderAttachable;
@@ -55,17 +50,12 @@ import ch.qos.logback.core.spi.FilterAttachableImpl;
import ch.qos.logback.core.spi.FilterReply;
import ch.qos.logback.core.spi.LifeCycle;
import ch.qos.logback.core.spi.LogbackLock;
-import ch.qos.logback.core.status.ErrorStatus;
import ch.qos.logback.core.status.InfoStatus;
-import ch.qos.logback.core.status.OnConsoleStatusListener;
-import ch.qos.logback.core.status.Status;
import ch.qos.logback.core.status.StatusManager;
import ch.qos.logback.core.status.WarnStatus;
import ch.qos.logback.core.util.ExecutorServiceUtil;
-import ch.qos.logback.core.util.Loader;
import ch.qos.logback.core.util.OptionHelper;
-import ch.qos.logback.core.util.StatusListenerConfigHelper;
-
+import ch.qos.logback.core.util.StatusPrinter;
//import org.apache.catalina.Lifecycle;
/**
@@ -80,380 +70,266 @@ import ch.qos.logback.core.util.StatusListenerConfigHelper;
* @author Ceki Gülcü
* @author Sébastien Pennec
*/
-public class LogbackValve extends ValveBase implements Lifecycle, Context, AppenderAttachable<IAccessEvent>, FilterAttachable<IAccessEvent> {
-
- public final static String DEFAULT_FILENAME = "logback-access.xml";
- public final static String DEFAULT_CONFIG_FILE = "conf" + File.separatorChar + DEFAULT_FILENAME;
- final static String CATALINA_BASE_KEY = "catalina.base";
- final static String CATALINA_HOME_KEY = "catalina.home";
-
- private final LifeCycleManager lifeCycleManager = new LifeCycleManager();
-
- private long birthTime = System.currentTimeMillis();
- LogbackLock configurationLock = new LogbackLock();
-
- // Attributes from ContextBase:
- private String name;
- StatusManager sm = new BasicStatusManager();
- // TODO propertyMap should be observable so that we can be notified
- // when it changes so that a new instance of propertyMap can be
- // serialized. For the time being, we ignore this shortcoming.
- Map<String, String> propertyMap = new HashMap<String, String>();
- Map<String, Object> objectMap = new HashMap<String, Object>();
- private FilterAttachableImpl<IAccessEvent> fai = new FilterAttachableImpl<IAccessEvent>();
-
- AppenderAttachableImpl<IAccessEvent> aai = new AppenderAttachableImpl<IAccessEvent>();
- String filenameOption;
- boolean quiet;
- boolean started;
- boolean alreadySetLogbackStatusManager = false;
-
- private ScheduledExecutorService scheduledExecutorService;
-
- public LogbackValve() {
- putObject(CoreConstants.EVALUATOR_MAP, new HashMap<String, EventEvaluator<?>>());
- }
-
- public boolean isStarted() {
- return started;
- }
-
- @Override
- public void startInternal() throws LifecycleException {
- scheduledExecutorService = ExecutorServiceUtil.newScheduledExecutorService();
-
- String filename;
-
- if (filenameOption != null) {
- filename = filenameOption;
- } else {
- addInfo("filename property not set. Assuming [" + DEFAULT_CONFIG_FILE + "]");
- filename = DEFAULT_CONFIG_FILE;
+public class LogbackValve extends ValveBase implements Lifecycle, Context,
+ AppenderAttachable<IAccessEvent>, FilterAttachable<IAccessEvent> {
+
+ public final static String DEFAULT_CONFIG_FILE = "conf" + File.separatorChar
+ + "logback-access.xml";
+
+ private final LifeCycleManager lifeCycleManager = new LifeCycleManager();
+
+ private long birthTime = System.currentTimeMillis();
+ LogbackLock configurationLock = new LogbackLock();
+
+ // Attributes from ContextBase:
+ private String name;
+ StatusManager sm = new BasicStatusManager();
+ // TODO propertyMap should be observable so that we can be notified
+ // when it changes so that a new instance of propertyMap can be
+ // serialized. For the time being, we ignore this shortcoming.
+ Map<String, String> propertyMap = new HashMap<String, String>();
+ Map<String, Object> objectMap = new HashMap<String, Object>();
+ private FilterAttachableImpl<IAccessEvent> fai = new FilterAttachableImpl<IAccessEvent>();
+
+ AppenderAttachableImpl<IAccessEvent> aai = new AppenderAttachableImpl<IAccessEvent>();
+ String filename;
+ boolean quiet;
+ boolean started;
+ boolean alreadySetLogbackStatusManager = false;
+
+ private ExecutorService executorService;
+
+ public LogbackValve() {
+ putObject(CoreConstants.EVALUATOR_MAP, new HashMap());
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public void startInternal() throws LifecycleException {
+ executorService = ExecutorServiceUtil.newExecutorService();
+ if (filename == null) {
+ String tomcatBaseProperty = OptionHelper
+ .getSystemProperty("catalina.base");
+
+ filename = tomcatBaseProperty + File.separatorChar + DEFAULT_CONFIG_FILE;
+
+ File baseConfigFile = new File(filename);
+ if (!baseConfigFile.exists()) {
+
+ String tomcatHomeProperty = OptionHelper
+ .getSystemProperty("catalina.home");
+
+ filename = tomcatHomeProperty + File.separatorChar
+ + DEFAULT_CONFIG_FILE;
+ }
+
+ getStatusManager().add(
+ new InfoStatus("filename property not set. Assuming [" + filename
+ + "]", this));
+ }
+ File configFile = new File(filename);
+
+ if (configFile.exists()) {
+ try {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(this);
+ jc.doConfigure(filename);
+ } catch (JoranException e) {
+ // TODO can we do better than printing a stack trace on syserr?
+ e.printStackTrace();
+ }
+ } else {
+ getStatusManager().add(
+ new WarnStatus("[" + filename + "] does not exist", this));
+ }
+
+ if (!quiet) {
+ StatusPrinter.print(getStatusManager());
+ }
+
+ started = true;
+ setState(LifecycleState.STARTING);
+ }
+
+ public String getFilename() {
+ return filename;
+ }
+
+ public void setFilename(String filename) {
+ this.filename = filename;
+ }
+
+ public boolean isQuiet() {
+ return quiet;
+ }
+
+ public void setQuiet(boolean quiet) {
+ this.quiet = quiet;
+ }
+
+ public void invoke(Request request, Response response) throws IOException,
+ ServletException {
+
+ try {
+
+ if (!alreadySetLogbackStatusManager) {
+ alreadySetLogbackStatusManager = true;
+ org.apache.catalina.Context tomcatContext = request.getContext();
+ if (tomcatContext != null) {
+ ServletContext sc = tomcatContext.getServletContext();
+ if (sc != null) {
+ sc.setAttribute(AccessConstants.LOGBACK_STATUS_MANAGER_KEY,
+ getStatusManager());
+ }
}
+ }
- // String catalinaBase = OptionHelper.getSystemProperty(CATALINA_BASE_KEY);
- // String catalinaHome = OptionHelper.getSystemProperty(CATALINA_BASE_KEY);
+ getNext().invoke(request, response);
- File configFile = searchForConfigFileTomcatProperty(filename, CATALINA_BASE_KEY);
- if (configFile == null) {
- configFile = searchForConfigFileTomcatProperty(filename, CATALINA_HOME_KEY);
- }
+ TomcatServerAdapter adapter = new TomcatServerAdapter(request, response);
+ IAccessEvent accessEvent = new AccessEvent(request, response, adapter);
- URL resourceURL;
- if (configFile != null)
- resourceURL = fileToUrl(configFile);
- else
- resourceURL = searchAsResource(filename);
+ if (getFilterChainDecision(accessEvent) == FilterReply.DENY) {
+ return;
+ }
- if (resourceURL != null) {
- configureAsResource(resourceURL);
- } else {
- addWarn("Failed to find valid logback-access configuration file.");
- }
-
- if (!quiet) {
- StatusListenerConfigHelper.addOnConsoleListenerInstance(this, new OnConsoleStatusListener());
- }
-
- started = true;
- setState(LifecycleState.STARTING);
+ // TODO better exception handling
+ aai.appendLoopOnAppenders(accessEvent);
+ } finally {
+ request.removeAttribute(AccessConstants.LOGBACK_STATUS_MANAGER_KEY);
}
+ }
- private URL fileToUrl(File configFile) {
- try {
- return configFile.toURI().toURL();
- } catch (MalformedURLException e) {
- throw new IllegalStateException("File to URL conversion failed", e);
- }
+ protected void stopInternal() throws LifecycleException {
+ started = false;
+ setState(LifecycleState.STOPPING);
+ lifeCycleManager.reset();
+ if (executorService != null) {
+ ExecutorServiceUtil.shutdown(executorService);
+ executorService = null;
}
+ }
- private URL searchAsResource(String filename) {
- URL result = Loader.getResource(filename, getClass().getClassLoader());
- if (result != null)
- addInfo("Found [" + filename + "] as a resource.");
- else
- addInfo("Could NOT find [" + filename + "] as a resource.");
- return result;
- }
+ public void addAppender(Appender<IAccessEvent> newAppender) {
+ aai.addAppender(newAppender);
+ }
- private File searchForConfigFileTomcatProperty(String filename, String propertyKey) {
- String propertyValue = OptionHelper.getSystemProperty(propertyKey);
- String candidatePath = propertyValue + File.separatorChar + filename;
- if (propertyValue == null) {
- addInfo("System property \"" + propertyKey + "\" is not set. Skipping configuration file search with ${" + propertyKey + "} path prefix.");
- return null;
- }
- File candidateFile = new File(candidatePath);
- if (candidateFile.exists()) {
- addInfo("Found configuration file [" + candidatePath + "] using property \"" + propertyKey + "\"");
- return candidateFile;
- } else {
- addInfo("Could NOT configuration file [" + candidatePath + "] using property \"" + propertyKey + "\"");
- return null;
- }
- }
+ public Iterator<Appender<IAccessEvent>> iteratorForAppenders() {
+ return aai.iteratorForAppenders();
+ }
- public void addStatus(Status status) {
- StatusManager sm = getStatusManager();
- if (sm != null) {
- sm.add(status);
- }
- }
+ public Appender<IAccessEvent> getAppender(String name) {
+ return aai.getAppender(name);
+ }
- public void addInfo(String msg) {
- addStatus(new InfoStatus(msg, this));
- }
+ public boolean isAttached(Appender<IAccessEvent> appender) {
+ return aai.isAttached(appender);
+ }
- public void addWarn(String msg) {
- addStatus(new WarnStatus(msg, this));
- }
+ public void detachAndStopAllAppenders() {
+ aai.detachAndStopAllAppenders();
- public void addError(String msg, Throwable t) {
- addStatus(new ErrorStatus(msg, this, t));
- }
+ }
- private void configureAsResource(URL resourceURL) {
- try {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(this);
- jc.doConfigure(resourceURL);
- addInfo("Done configuring");
- } catch (JoranException e) {
- addError("Failed to configure LogbackValve", e);
- }
- }
+ public boolean detachAppender(Appender<IAccessEvent> appender) {
+ return aai.detachAppender(appender);
+ }
- public String getFilename() {
- return filenameOption;
- }
+ public boolean detachAppender(String name) {
+ return aai.detachAppender(name);
+ }
- public void setFilename(String filename) {
- this.filenameOption = filename;
- }
+ public String getInfo() {
+ return "Logback's implementation of ValveBase";
+ }
- public boolean isQuiet() {
- return quiet;
- }
+ // Methods from ContextBase:
+ public StatusManager getStatusManager() {
+ return sm;
+ }
- public void setQuiet(boolean quiet) {
- this.quiet = quiet;
- }
+ public Map<String, String> getPropertyMap() {
+ return propertyMap;
+ }
- @Override
- public void invoke(Request request, Response response) throws IOException, ServletException {
- try {
- if (!alreadySetLogbackStatusManager) {
- alreadySetLogbackStatusManager = true;
- org.apache.catalina.Context tomcatContext = request.getContext();
- if (tomcatContext != null) {
- ServletContext sc = tomcatContext.getServletContext();
- if (sc != null) {
- sc.setAttribute(AccessConstants.LOGBACK_STATUS_MANAGER_KEY, getStatusManager());
- }
- }
- }
-
- getNext().invoke(request, response);
-
- TomcatServerAdapter adapter = new TomcatServerAdapter(request, response);
- IAccessEvent accessEvent = new AccessEvent(request, response, adapter);
-
- addThreadName(accessEvent);
-
- if (getFilterChainDecision(accessEvent) == FilterReply.DENY) {
- return;
- }
-
- // TODO better exception handling
- aai.appendLoopOnAppenders(accessEvent);
- } finally {
- request.removeAttribute(AccessConstants.LOGBACK_STATUS_MANAGER_KEY);
- }
- }
+ public void putProperty(String key, String val) {
+ this.propertyMap.put(key, val);
+ }
- private void addThreadName(IAccessEvent accessEvent) {
- try {
- final String threadName = Thread.currentThread().getName();
- if (threadName != null) {
- accessEvent.setThreadName(threadName);
- }
- } catch (Exception ignored) {
- }
- }
+ public String getProperty(String key) {
+ return (String) this.propertyMap.get(key);
+ }
- @Override
- protected void stopInternal() throws LifecycleException {
- started = false;
- setState(LifecycleState.STOPPING);
- lifeCycleManager.reset();
- if (scheduledExecutorService != null) {
- ExecutorServiceUtil.shutdown(scheduledExecutorService);
- scheduledExecutorService = null;
- }
- }
+ public Map<String, String> getCopyOfPropertyMap() {
+ return new HashMap<String, String>(this.propertyMap);
+ }
- @Override
- public void addAppender(Appender<IAccessEvent> newAppender) {
- aai.addAppender(newAppender);
- }
+ public Object getObject(String key) {
+ return objectMap.get(key);
+ }
- @Override
- public Iterator<Appender<IAccessEvent>> iteratorForAppenders() {
- return aai.iteratorForAppenders();
- }
+ public void putObject(String key, Object value) {
+ objectMap.put(key, value);
+ }
- @Override
- public Appender<IAccessEvent> getAppender(String name) {
- return aai.getAppender(name);
- }
+ public void addFilter(Filter<IAccessEvent> newFilter) {
+ fai.addFilter(newFilter);
+ }
- @Override
- public boolean isAttached(Appender<IAccessEvent> appender) {
- return aai.isAttached(appender);
- }
+ public void clearAllFilters() {
+ fai.clearAllFilters();
+ }
- @Override
- public void detachAndStopAllAppenders() {
- aai.detachAndStopAllAppenders();
+ public List<Filter<IAccessEvent>> getCopyOfAttachedFiltersList() {
+ return fai.getCopyOfAttachedFiltersList();
+ }
- }
+ public FilterReply getFilterChainDecision(IAccessEvent event) {
+ return fai.getFilterChainDecision(event);
+ }
- @Override
- public boolean detachAppender(Appender<IAccessEvent> appender) {
- return aai.detachAppender(appender);
- }
+ public ExecutorService getExecutorService() {
+ return executorService;
+ }
- @Override
- public boolean detachAppender(String name) {
- return aai.detachAppender(name);
- }
+ public String getName() {
+ return name;
+ }
- @Override
- public String getInfo() {
- return "Logback's implementation of ValveBase";
+ public void setName(String name) {
+ if (this.name != null) {
+ throw new IllegalStateException(
+ "LogbackValve has been already given a name");
}
+ this.name = name;
+ }
- // Methods from ContextBase:
- @Override
- public StatusManager getStatusManager() {
- return sm;
- }
-
- public Map<String, String> getPropertyMap() {
- return propertyMap;
- }
-
- @Override
- public void putProperty(String key, String val) {
- this.propertyMap.put(key, val);
- }
-
- @Override
- public String getProperty(String key) {
- return (String) this.propertyMap.get(key);
- }
-
- @Override
- public Map<String, String> getCopyOfPropertyMap() {
- return new HashMap<String, String>(this.propertyMap);
- }
-
- @Override
- public Object getObject(String key) {
- return objectMap.get(key);
- }
-
- @Override
- public void putObject(String key, Object value) {
- objectMap.put(key, value);
- }
-
- @Override
- public void addFilter(Filter<IAccessEvent> newFilter) {
- fai.addFilter(newFilter);
- }
-
- @Override
- public void clearAllFilters() {
- fai.clearAllFilters();
- }
-
- @Override
- public List<Filter<IAccessEvent>> getCopyOfAttachedFiltersList() {
- return fai.getCopyOfAttachedFiltersList();
- }
-
- @Override
- public FilterReply getFilterChainDecision(IAccessEvent event) {
- return fai.getFilterChainDecision(event);
- }
-
- @Override
- public ExecutorService getExecutorService() {
- return getScheduledExecutorService();
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public void setName(String name) {
- if (this.name != null) {
- throw new IllegalStateException("LogbackValve has been already given a name");
- }
- this.name = name;
- }
-
- @Override
- public long getBirthTime() {
- return birthTime;
- }
+ public long getBirthTime() {
+ return birthTime;
+ }
- @Override
- public Object getConfigurationLock() {
- return configurationLock;
- }
-
- @Override
- public void register(LifeCycle component) {
- lifeCycleManager.register(component);
- }
+ public Object getConfigurationLock() {
+ return configurationLock;
+ }
- // ====== Methods from catalina Lifecycle =====
-
- @Override
- public void addLifecycleListener(LifecycleListener arg0) {
- // dummy NOP implementation
- }
+ public void register(LifeCycle component) {
+ lifeCycleManager.register(component);
+ }
- @Override
- public LifecycleListener[] findLifecycleListeners() {
- return new LifecycleListener[0];
- }
+ // ====== Methods from catalina Lifecycle =====
- @Override
- public void removeLifecycleListener(LifecycleListener arg0) {
- // dummy NOP implementation
- }
+ public void addLifecycleListener(LifecycleListener arg0) {
+ // dummy NOP implementation
+ }
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder(this.getClass().getName());
- sb.append('[');
- sb.append(getName());
- sb.append(']');
- return sb.toString();
- }
+ public LifecycleListener[] findLifecycleListeners() {
+ return new LifecycleListener[0];
+ }
- @Override
- public ScheduledExecutorService getScheduledExecutorService() {
- return scheduledExecutorService;
- }
+ public void removeLifecycleListener(LifecycleListener arg0) {
+ // dummy NOP implementation
+ }
- @Override
- public void addScheduledFuture(ScheduledFuture<?> scheduledFuture) {
- throw new UnsupportedOperationException();
- }
}
diff --git a/logback-access/src/main/java/ch/qos/logback/access/tomcat/TomcatServerAdapter.java b/logback-access/src/main/java/ch/qos/logback/access/tomcat/TomcatServerAdapter.java
index 0b046e9..b5f300d 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/tomcat/TomcatServerAdapter.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/tomcat/TomcatServerAdapter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,7 +14,6 @@
package ch.qos.logback.access.tomcat;
import ch.qos.logback.access.spi.ServerAdapter;
-
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
@@ -28,36 +27,32 @@ import java.util.Map;
*/
public class TomcatServerAdapter implements ServerAdapter {
- Request request;
- Response response;
+ Request request;
+ Response response;
- public TomcatServerAdapter(Request tomcatRequest, Response tomcatResponse) {
- this.request = tomcatRequest;
- this.response = tomcatResponse;
- }
+ public TomcatServerAdapter(Request tomcatRequest, Response tomcatResponse) {
+ this.request = tomcatRequest;
+ this.response = tomcatResponse;
+ }
- @Override
- public long getContentLength() {
- return response.getContentLength();
- }
+ public long getContentLength() {
+ return response.getContentLength();
+ }
- @Override
- public int getStatusCode() {
- return response.getStatus();
- }
+ public int getStatusCode() {
+ return response.getStatus();
+ }
- @Override
- public long getRequestTimestamp() {
- return request.getCoyoteRequest().getStartTime();
- }
+ public long getRequestTimestamp() {
+ return request.getCoyoteRequest().getStartTime();
+ }
- @Override
- public Map<String, String> buildResponseHeaderMap() {
- Map<String, String> responseHeaderMap = new HashMap<String, String>();
- for (String key : response.getHeaderNames()) {
- String value = response.getHeader(key);
- responseHeaderMap.put(key, value);
- }
- return responseHeaderMap;
+ public Map<String, String> buildResponseHeaderMap() {
+ Map<String, String> responseHeaderMap = new HashMap<String, String>();
+ for (String key : response.getHeaderNames()) {
+ String value = response.getHeader(key);
+ responseHeaderMap.put(key, value);
}
+ return responseHeaderMap;
+ }
}
diff --git a/logback-access/src/test/input/joran/tomcat/logback-access.xml b/logback-access/src/test/input/joran/tomcat/logback-access.xml
deleted file mode 100644
index 3cbd745..0000000
--- a/logback-access/src/test/input/joran/tomcat/logback-access.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<configuration>
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%h %l %u %user %date "%r" %s %b</pattern>
- </encoder>
- </appender>
-
- <appender-ref ref="STDOUT" />
-</configuration>
\ No newline at end of file
diff --git a/logback-access/src/test/java/ch/qos/logback/access/AccessTestConstants.java b/logback-access/src/test/java/ch/qos/logback/access/AccessTestConstants.java
deleted file mode 100644
index ffb8a38..0000000
--- a/logback-access/src/test/java/ch/qos/logback/access/AccessTestConstants.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.access;
-
-public class AccessTestConstants {
-
- public static final String TEST_DIR_PREFIX = "src/test/";
- final static public String INPUT_PREFIX = "src/test/input/";
- final static public String JORAN_INPUT_PREFIX = INPUT_PREFIX + "joran/";
-}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/AllAccessTest.java b/logback-access/src/test/java/ch/qos/logback/access/AllAccessTest.java
index d9cd88c..e78cfe4 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/AllAccessTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/AllAccessTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,10 +18,16 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ ch.qos.logback.access.spi.PackageTest.class, ch.qos.logback.access.boolex.PackageTest.class, ch.qos.logback.access.net.PackageTest.class,
- ch.qos.logback.access.db.PackageTest.class, ch.qos.logback.access.pattern.PackageTest.class, ch.qos.logback.access.joran.PackageTest.class,
- ch.qos.logback.access.jetty.PackageTest.class, ch.qos.logback.access.filter.PackageTest.class, ch.qos.logback.access.servlet.PackageTest.class,
- ch.qos.logback.access.sift.PackageTest.class })
+ at SuiteClasses({ch.qos.logback.access.spi.PackageTest.class,
+ ch.qos.logback.access.boolex.PackageTest.class,
+ ch.qos.logback.access.net.PackageTest.class,
+ ch.qos.logback.access.db.PackageTest.class,
+ ch.qos.logback.access.pattern.PackageTest.class,
+ ch.qos.logback.access.joran.PackageTest.class,
+ ch.qos.logback.access.jetty.PackageTest.class,
+ ch.qos.logback.access.filter.PackageTest.class,
+ ch.qos.logback.access.servlet.PackageTest.class,
+ ch.qos.logback.access.sift.PackageTest.class})
public class AllAccessTest {
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/TeztConstants.java b/logback-access/src/test/java/ch/qos/logback/access/TeztConstants.java
new file mode 100644
index 0000000..880efa9
--- /dev/null
+++ b/logback-access/src/test/java/ch/qos/logback/access/TeztConstants.java
@@ -0,0 +1,19 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.access;
+
+public class TeztConstants {
+
+ public static final String TEST_DIR_PREFIX = "src/test/";
+}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/boolex/JaninoEventEvaluatorTest.java b/logback-access/src/test/java/ch/qos/logback/access/boolex/JaninoEventEvaluatorTest.java
index f84a425..f1c2127 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/boolex/JaninoEventEvaluatorTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/boolex/JaninoEventEvaluatorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.access.boolex;
+
import ch.qos.logback.access.dummy.DummyRequest;
import ch.qos.logback.access.dummy.DummyResponse;
import ch.qos.logback.access.dummy.DummyServerAdapter;
@@ -29,48 +30,50 @@ import static org.junit.Assert.fail;
public class JaninoEventEvaluatorTest {
- final String expectedURL1 = "testUrl1";
- final String expectedURL2 = "testUrl2";
- Context context = new ContextBase();
- JaninoEventEvaluator evaluator;
- DummyRequest request;
- DummyResponse response;
- DummyServerAdapter serverAdapter;
+ final String expectedURL1 = "testUrl1";
+ final String expectedURL2 = "testUrl2";
+ Context context = new ContextBase();
+ JaninoEventEvaluator evaluator;
+ DummyRequest request;
+ DummyResponse response;
+ DummyServerAdapter serverAdapter;
+
+ @Before
+ public void setUp() throws Exception {
+ evaluator = new JaninoEventEvaluator();
+ evaluator.setContext(context);
+ request = new DummyRequest();
+ response = new DummyResponse();
+ serverAdapter = new DummyServerAdapter(request, response);
+ }
- @Before
- public void setUp() throws Exception {
- evaluator = new JaninoEventEvaluator();
- evaluator.setContext(context);
- request = new DummyRequest();
- response = new DummyResponse();
- serverAdapter = new DummyServerAdapter(request, response);
- }
- @Test
- public void smoke() throws EvaluationException {
- evaluator.setExpression("event.getProtocol().equals(\"testProtocol\")");
- evaluator.start();
- IAccessEvent ae = new AccessEvent(request, response, serverAdapter);
- assertTrue(evaluator.evaluate(ae));
- }
+ @Test
+ public void smoke() throws EvaluationException {
+ evaluator.setExpression("event.getProtocol().equals(\"testProtocol\")");
+ evaluator.start();
+ IAccessEvent ae = new AccessEvent(request, response, serverAdapter);
+ assertTrue( evaluator.evaluate(ae));
+ }
- @Test
- public void block() throws EvaluationException {
- evaluator.setExpression("String protocol = event.getProtocol();" + "return protocol.equals(\"testProtocol\");");
- evaluator.start();
- IAccessEvent ae = new AccessEvent(request, response, serverAdapter);
- assertTrue(evaluator.evaluate(ae));
- }
+ @Test
+ public void block() throws EvaluationException {
+ evaluator.setExpression("String protocol = event.getProtocol();" +
+ "return protocol.equals(\"testProtocol\");");
+ evaluator.start();
+ IAccessEvent ae = new AccessEvent(request, response, serverAdapter);
+ assertTrue(evaluator.evaluate(ae));
+ }
- @Test
- public void invalidExpression() throws EvaluationException {
- evaluator.setExpression("return true");
- evaluator.start();
- IAccessEvent ae = new AccessEvent(request, response, serverAdapter);
- try {
- evaluator.evaluate(ae);
- fail("Was expecting an exception");
- } catch (IllegalStateException e) {
- }
- }
+ @Test
+ public void invalidExpression() throws EvaluationException {
+ evaluator.setExpression("return true");
+ evaluator.start();
+ IAccessEvent ae = new AccessEvent(request, response, serverAdapter);
+ try {
+ evaluator.evaluate(ae);
+ fail("Was expecting an exception");
+ } catch (IllegalStateException e) {
+ }
+ }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/boolex/PackageTest.java b/logback-access/src/test/java/ch/qos/logback/access/boolex/PackageTest.java
index 44dabfc..465ec57 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/boolex/PackageTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/boolex/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,6 +19,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ JaninoEventEvaluatorTest.class })
+ at SuiteClasses({JaninoEventEvaluatorTest.class})
public class PackageTest extends TestCase {
}
\ No newline at end of file
diff --git a/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderHSQLTest.java b/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderHSQLTest.java
index c6ffc83..8d38892 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderHSQLTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderHSQLTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -38,184 +38,187 @@ import ch.qos.logback.core.db.DriverManagerConnectionSource;
import ch.qos.logback.core.util.StatusPrinter;
public class DBAppenderHSQLTest {
- static DBAppenderHSQLTestFixture DB_APPENDER_HSQL_TEST_FIXTURE;
-
- AccessContext context;
- DBAppender appender;
- DriverManagerConnectionSource connectionSource;
-
- int existingEventTableRowCount;
- Statement stmt;
-
- @BeforeClass
- static public void fixtureSetUp() throws SQLException {
- DB_APPENDER_HSQL_TEST_FIXTURE = new DBAppenderHSQLTestFixture();
- DB_APPENDER_HSQL_TEST_FIXTURE.setUp();
+ static DBAppenderHSQLTestFixture DB_APPENDER_HSQL_TEST_FIXTURE;
+
+
+ AccessContext context;
+ DBAppender appender;
+ DriverManagerConnectionSource connectionSource;
+
+ int existingEventTableRowCount;
+ Statement stmt;
+
+ @BeforeClass
+ static public void fixtureSetUp() throws SQLException {
+ DB_APPENDER_HSQL_TEST_FIXTURE = new DBAppenderHSQLTestFixture();
+ DB_APPENDER_HSQL_TEST_FIXTURE.setUp();
+ }
+
+ @AfterClass
+ static public void fixtureTearDown() throws SQLException {
+ DB_APPENDER_HSQL_TEST_FIXTURE.tearDown();
+ }
+
+ @Before
+ public void setUp() throws SQLException {
+ context = new AccessContext();
+ context.setName("default");
+ appender = new DBAppender();
+ appender.setName("DB");
+ appender.setContext(context);
+ connectionSource = new DriverManagerConnectionSource();
+ connectionSource.setContext(context);
+ connectionSource.setDriverClass(DBAppenderHSQLTestFixture.DRIVER_CLASS);
+ connectionSource.setUrl(DB_APPENDER_HSQL_TEST_FIXTURE.url);
+ connectionSource.setUser(DB_APPENDER_HSQL_TEST_FIXTURE.user);
+ connectionSource.setPassword(DB_APPENDER_HSQL_TEST_FIXTURE.password);
+ connectionSource.start();
+ appender.setConnectionSource(connectionSource);
+
+ stmt = connectionSource.getConnection().createStatement();
+ existingEventTableRowCount = existingEventTableRowCount(stmt);
+ }
+
+ @After
+ public void tearDown() throws SQLException {
+ context = null;
+ appender = null;
+ connectionSource = null;
+ stmt.close();
+ }
+
+ int existingEventTableRowCount(Statement stmt) throws SQLException {
+ ResultSet rs = stmt.executeQuery("SELECT count(*) FROM access_event");
+ int result = -1;
+ if (rs.next()) {
+ result = rs.getInt(1);
}
-
- @AfterClass
- static public void fixtureTearDown() throws SQLException {
- DB_APPENDER_HSQL_TEST_FIXTURE.tearDown();
+ rs.close();
+ return result;
+ }
+
+ private void setInsertHeadersAndStart(boolean insert) {
+ appender.setInsertHeaders(insert);
+ appender.start();
+ }
+
+
+ @Test
+ public void testAppendAccessEvent() throws SQLException {
+ setInsertHeadersAndStart(false);
+
+ IAccessEvent event = createAccessEvent();
+ appender.append(event);
+
+ Statement stmt = connectionSource.getConnection().createStatement();
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM access_event where EVENT_ID = " + existingEventTableRowCount);
+ if (rs.next()) {
+ assertEquals(event.getTimeStamp(), rs.getLong(1));
+ assertEquals(event.getRequestURI(), rs.getString(2));
+ assertEquals(event.getRequestURL(), rs.getString(3));
+ assertEquals(event.getRemoteHost(), rs.getString(4));
+ assertEquals(event.getRemoteUser(), rs.getString(5));
+ assertEquals(event.getRemoteAddr(), rs.getString(6));
+ assertEquals(event.getProtocol(), rs.getString(7));
+ assertEquals(event.getMethod(), rs.getString(8));
+ assertEquals(event.getServerName(), rs.getString(9));
+ assertEquals(event.getRequestContent(), rs.getString(10));
+ } else {
+ fail("No row was inserted in the database");
}
-
- @Before
- public void setUp() throws SQLException {
- context = new AccessContext();
- context.setName("default");
- appender = new DBAppender();
- appender.setName("DB");
- appender.setContext(context);
- connectionSource = new DriverManagerConnectionSource();
- connectionSource.setContext(context);
- connectionSource.setDriverClass(DBAppenderHSQLTestFixture.DRIVER_CLASS);
- connectionSource.setUrl(DB_APPENDER_HSQL_TEST_FIXTURE.url);
- connectionSource.setUser(DB_APPENDER_HSQL_TEST_FIXTURE.user);
- connectionSource.setPassword(DB_APPENDER_HSQL_TEST_FIXTURE.password);
- connectionSource.start();
- appender.setConnectionSource(connectionSource);
-
- stmt = connectionSource.getConnection().createStatement();
- existingEventTableRowCount = existingEventTableRowCount(stmt);
+ rs.close();
+ stmt.close();
+ }
+
+
+ @Test
+ public void testCheckNoHeadersAreInserted() throws Exception {
+ setInsertHeadersAndStart(false);
+
+ IAccessEvent event = createAccessEvent();
+ appender.append(event);
+ StatusPrinter.print(context.getStatusManager());
+
+ //Check that no headers were inserted
+ Statement stmt = connectionSource.getConnection().createStatement();
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM access_event_header where EVENT_ID = " + existingEventTableRowCount);
+
+ assertFalse(rs.next());
+ rs.close();
+ stmt.close();
+ }
+
+ @Test
+ public void testAppendHeaders() throws SQLException {
+ setInsertHeadersAndStart(true);
+
+ IAccessEvent event = createAccessEvent();
+ appender.append(event);
+
+ Statement stmt = connectionSource.getConnection().createStatement();
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM access_event_header");
+ String key;
+ String value;
+ if (!rs.next()) {
+ fail("There should be results to this query");
+ } else {
+ key = rs.getString(2);
+ value = rs.getString(3);
+ assertNotNull(key);
+ assertNotNull(value);
+ assertEquals(event.getRequestHeader(key), value);
+ rs.next();
+ key = rs.getString(2);
+ value = rs.getString(3);
+ assertNotNull(key);
+ assertNotNull(value);
+ assertEquals(event.getRequestHeader(key), value);
}
-
- @After
- public void tearDown() throws SQLException {
- context = null;
- appender = null;
- connectionSource = null;
- stmt.close();
+ if (rs.next()) {
+ fail("There should be no more rows available");
}
- int existingEventTableRowCount(Statement stmt) throws SQLException {
- ResultSet rs = stmt.executeQuery("SELECT count(*) FROM access_event");
- int result = -1;
- if (rs.next()) {
- result = rs.getInt(1);
- }
- rs.close();
- return result;
+ rs.close();
+ stmt.close();
+ }
+
+ @Test
+ public void testAppendMultipleEvents() throws SQLException {
+ setInsertHeadersAndStart(false);
+ String uri = "testAppendMultipleEvents";
+ for (int i = 0; i < 10; i++) {
+ IAccessEvent event = createAccessEvent(uri);
+ appender.append(event);
}
- private void setInsertHeadersAndStart(boolean insert) {
- appender.setInsertHeaders(insert);
- appender.start();
- }
+ StatusPrinter.print(context);
- @Test
- public void testAppendAccessEvent() throws SQLException {
- setInsertHeadersAndStart(false);
-
- IAccessEvent event = createAccessEvent();
- appender.append(event);
-
- Statement stmt = connectionSource.getConnection().createStatement();
- ResultSet rs = null;
- rs = stmt.executeQuery("SELECT * FROM access_event where EVENT_ID = " + existingEventTableRowCount);
- if (rs.next()) {
- assertEquals(event.getTimeStamp(), rs.getLong(1));
- assertEquals(event.getRequestURI(), rs.getString(2));
- assertEquals(event.getRequestURL(), rs.getString(3));
- assertEquals(event.getRemoteHost(), rs.getString(4));
- assertEquals(event.getRemoteUser(), rs.getString(5));
- assertEquals(event.getRemoteAddr(), rs.getString(6));
- assertEquals(event.getProtocol(), rs.getString(7));
- assertEquals(event.getMethod(), rs.getString(8));
- assertEquals(event.getServerName(), rs.getString(9));
- assertEquals(event.getRequestContent(), rs.getString(10));
- } else {
- fail("No row was inserted in the database");
- }
- rs.close();
- stmt.close();
+ Statement stmt = connectionSource.getConnection().createStatement();
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM access_event where requestURI='" + uri + "'");
+ int count = 0;
+ while (rs.next()) {
+ count++;
}
+ assertEquals(10, count);
- @Test
- public void testCheckNoHeadersAreInserted() throws Exception {
- setInsertHeadersAndStart(false);
+ rs.close();
+ stmt.close();
+ }
- IAccessEvent event = createAccessEvent();
- appender.append(event);
- StatusPrinter.print(context.getStatusManager());
+ private IAccessEvent createAccessEvent() {
+ return createAccessEvent("");
+ }
- // Check that no headers were inserted
- Statement stmt = connectionSource.getConnection().createStatement();
- ResultSet rs = null;
- rs = stmt.executeQuery("SELECT * FROM access_event_header where EVENT_ID = " + existingEventTableRowCount);
-
- assertFalse(rs.next());
- rs.close();
- stmt.close();
- }
+ private IAccessEvent createAccessEvent(String uri) {
+ DummyRequest request = new DummyRequest();
+ request.setRequestUri(uri);
+ DummyResponse response = new DummyResponse();
+ DummyServerAdapter adapter = new DummyServerAdapter(request, response);
- @Test
- public void testAppendHeaders() throws SQLException {
- setInsertHeadersAndStart(true);
-
- IAccessEvent event = createAccessEvent();
- appender.append(event);
-
- Statement stmt = connectionSource.getConnection().createStatement();
- ResultSet rs = null;
- rs = stmt.executeQuery("SELECT * FROM access_event_header");
- String key;
- String value;
- if (!rs.next()) {
- fail("There should be results to this query");
- } else {
- key = rs.getString(2);
- value = rs.getString(3);
- assertNotNull(key);
- assertNotNull(value);
- assertEquals(event.getRequestHeader(key), value);
- rs.next();
- key = rs.getString(2);
- value = rs.getString(3);
- assertNotNull(key);
- assertNotNull(value);
- assertEquals(event.getRequestHeader(key), value);
- }
- if (rs.next()) {
- fail("There should be no more rows available");
- }
-
- rs.close();
- stmt.close();
- }
-
- @Test
- public void testAppendMultipleEvents() throws SQLException {
- setInsertHeadersAndStart(false);
- String uri = "testAppendMultipleEvents";
- for (int i = 0; i < 10; i++) {
- IAccessEvent event = createAccessEvent(uri);
- appender.append(event);
- }
-
- StatusPrinter.print(context);
-
- Statement stmt = connectionSource.getConnection().createStatement();
- ResultSet rs = null;
- rs = stmt.executeQuery("SELECT * FROM access_event where requestURI='" + uri + "'");
- int count = 0;
- while (rs.next()) {
- count++;
- }
- assertEquals(10, count);
-
- rs.close();
- stmt.close();
- }
-
- private IAccessEvent createAccessEvent() {
- return createAccessEvent("");
- }
-
- private IAccessEvent createAccessEvent(String uri) {
- DummyRequest request = new DummyRequest();
- request.setRequestUri(uri);
- DummyResponse response = new DummyResponse();
- DummyServerAdapter adapter = new DummyServerAdapter(request, response);
-
- return new AccessEvent(request, response, adapter);
- }
+ return new AccessEvent(request, response, adapter);
+ }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderHSQLTestFixture.java b/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderHSQLTestFixture.java
index 202a2de..38bfb1a 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderHSQLTestFixture.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderHSQLTestFixture.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,106 +22,107 @@ import org.hsqldb.Server;
public class DBAppenderHSQLTestFixture {
- public static final String DRIVER_CLASS = "org.hsqldb.jdbcDriver";
- String serverProps;
- String url;
- String user = "sa";
- String password = "";
- Server server;
- boolean isNetwork = true;
-
- void setUp() throws SQLException {
- if (isNetwork) {
- if (url == null) {
- url = "jdbc:hsqldb:hsql://localhost/test";
- }
-
- server = new Server();
-
- server.setDatabaseName(0, "test");
- server.setDatabasePath(0, "mem:test;sql.enforce_strict_size=true");
- server.setLogWriter(null);
- server.setErrWriter(null);
- server.setTrace(false);
- server.setSilent(true);
- server.start();
- } else {
- if (url == null) {
- url = "jdbc:hsqldb:file:test;sql.enforce_strict_size=true";
- }
- }
-
- try {
- Class.forName(DRIVER_CLASS);
- } catch (Exception e) {
- e.printStackTrace();
- System.out.println(this + ".setUp() error: " + e.getMessage());
- }
- Thread.yield();
-
- createTables();
+ public static final String DRIVER_CLASS = "org.hsqldb.jdbcDriver";
+ String serverProps;
+ String url;
+ String user = "sa";
+ String password = "";
+ Server server;
+ boolean isNetwork = true;
+
+
+ void setUp() throws SQLException {
+ if (isNetwork) {
+ if (url == null) {
+ url = "jdbc:hsqldb:hsql://localhost/test";
+ }
+
+ server = new Server();
+
+ server.setDatabaseName(0, "test");
+ server.setDatabasePath(0, "mem:test;sql.enforce_strict_size=true");
+ server.setLogWriter(null);
+ server.setErrWriter(null);
+ server.setTrace(false);
+ server.setSilent(true);
+ server.start();
+ } else {
+ if (url == null) {
+ url = "jdbc:hsqldb:file:test;sql.enforce_strict_size=true";
+ }
}
- void tearDown() throws SQLException {
- dropTables();
- if (isNetwork) {
- server.stop();
- server = null;
- }
+ try {
+ Class.forName(DRIVER_CLASS);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println(this + ".setUp() error: " + e.getMessage());
}
-
- Connection newConnection() throws SQLException {
- return DriverManager.getConnection(url, user, password);
+ Thread.yield();
+
+ createTables();
+ }
+
+ void tearDown() throws SQLException {
+ dropTables();
+ if (isNetwork) {
+ server.stop();
+ server = null;
}
-
- private void createTables() throws SQLException {
- Connection conn = newConnection();
- StringBuilder buf = new StringBuilder();
- buf.append("CREATE TABLE access_event (");
- buf.append("timestmp BIGINT NOT NULL,");
- buf.append("requestURI VARCHAR(254),");
- buf.append("requestURL VARCHAR(254),");
- buf.append("remoteHost VARCHAR(254),");
- buf.append("remoteUser VARCHAR(254),");
- buf.append("remoteAddr VARCHAR(254),");
- buf.append("protocol VARCHAR(254),");
- buf.append("method VARCHAR(254),");
- buf.append("serverName VARCHAR(254),");
- buf.append("postContent VARCHAR(254),");
- buf.append("event_id INT NOT NULL IDENTITY);");
- query(conn, buf.toString());
-
- buf = new StringBuilder();
- buf.append("CREATE TABLE access_event_header (");
- buf.append("event_id INT NOT NULL,");
- buf.append("header_key VARCHAR(254) NOT NULL,");
- buf.append("header_value LONGVARCHAR,");
- buf.append("PRIMARY KEY(event_id, header_key),");
- buf.append("FOREIGN KEY (event_id) REFERENCES access_event(event_id));");
- query(conn, buf.toString());
+ }
+
+ Connection newConnection() throws SQLException {
+ return DriverManager.getConnection(url, user, password);
+ }
+
+ private void createTables() throws SQLException {
+ Connection conn = newConnection();
+ StringBuilder buf = new StringBuilder();
+ buf.append("CREATE TABLE access_event (");
+ buf.append("timestmp BIGINT NOT NULL,");
+ buf.append("requestURI VARCHAR(254),");
+ buf.append("requestURL VARCHAR(254),");
+ buf.append("remoteHost VARCHAR(254),");
+ buf.append("remoteUser VARCHAR(254),");
+ buf.append("remoteAddr VARCHAR(254),");
+ buf.append("protocol VARCHAR(254),");
+ buf.append("method VARCHAR(254),");
+ buf.append("serverName VARCHAR(254),");
+ buf.append("postContent VARCHAR(254),");
+ buf.append("event_id INT NOT NULL IDENTITY);");
+ query(conn, buf.toString());
+
+ buf = new StringBuilder();
+ buf.append("CREATE TABLE access_event_header (");
+ buf.append("event_id INT NOT NULL,");
+ buf.append("header_key VARCHAR(254) NOT NULL,");
+ buf.append("header_value LONGVARCHAR,");
+ buf.append("PRIMARY KEY(event_id, header_key),");
+ buf.append("FOREIGN KEY (event_id) REFERENCES access_event(event_id));");
+ query(conn, buf.toString());
+ }
+
+ private void dropTables() throws SQLException {
+ Connection conn = newConnection();
+
+ StringBuilder buf = new StringBuilder();
+ buf.append("DROP TABLE access_event_header IF EXISTS;");
+ query(conn, buf.toString());
+
+ buf = new StringBuilder();
+ buf.append("DROP TABLE access_event IF EXISTS;");
+ query(conn, buf.toString());
+ }
+
+ private void query(Connection conn, String expression) throws SQLException {
+ Statement st = null;
+ st = conn.createStatement();
+
+ int i = st.executeUpdate(expression);
+ if (i == -1) {
+ System.out.println("db error : " + expression);
}
- private void dropTables() throws SQLException {
- Connection conn = newConnection();
-
- StringBuilder buf = new StringBuilder();
- buf.append("DROP TABLE access_event_header IF EXISTS;");
- query(conn, buf.toString());
-
- buf = new StringBuilder();
- buf.append("DROP TABLE access_event IF EXISTS;");
- query(conn, buf.toString());
- }
-
- private void query(Connection conn, String expression) throws SQLException {
- Statement st = null;
- st = conn.createStatement();
-
- int i = st.executeUpdate(expression);
- if (i == -1) {
- System.out.println("db error : " + expression);
- }
-
- st.close();
- }
+ st.close();
+ }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderIntegrationTest.java b/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderIntegrationTest.java
index 9f6895a..61ab69e 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderIntegrationTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderIntegrationTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -38,101 +38,101 @@ import ch.qos.logback.core.util.StatusPrinter;
public class DBAppenderIntegrationTest {
- static String LOCAL_HOST_NAME = EnvUtilForTests.getLocalHostName();
- static String[] CONFORMING_HOST_LIST = new String[] { "Orion" };
+ static String LOCAL_HOST_NAME = EnvUtilForTests.getLocalHostName();
+ static String[] CONFORMING_HOST_LIST = new String[] { "Orion" };
- int diff = new Random(System.nanoTime()).nextInt(10000);
- AccessContext context = new AccessContext();
- StatusChecker statusChecker = new StatusChecker(context);
+ int diff = new Random(System.nanoTime()).nextInt(10000);
+ AccessContext context = new AccessContext();
+ StatusChecker statusChecker = new StatusChecker(context);
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ }
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- }
-
- @AfterClass
- public static void tearDownAfterClass() throws Exception {
- }
-
- @Before
- public void setUp() throws Exception {
- }
-
- @After
- public void tearDown() throws Exception {
-
- }
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ }
- public void doTest(String configFile) throws JoranException {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(context);
- configurator.doConfigure(configFile);
+ @Before
+ public void setUp() throws Exception {
+ }
- Appender<IAccessEvent> appender = context.getAppender("DB");
+ @After
+ public void tearDown() throws Exception {
- for (int i = 0; i < 10; i++) {
- IAccessEvent event = DummyAccessEventBuilder.buildNewAccessEvent();
- appender.doAppend(event);
- }
+ }
- StatusPrinter.print(context);
-
- // check that there were no errors
- assertEquals(Status.INFO, statusChecker.getHighestLevel(0));
+ public void doTest(String configFile) throws JoranException {
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(context);
+ configurator.doConfigure(configFile);
+ Appender<IAccessEvent> appender = context.getAppender("DB");
+
+ for (int i = 0; i < 10; i++) {
+ IAccessEvent event = DummyAccessEventBuilder.buildNewAccessEvent();
+ appender.doAppend(event);
}
-
- static boolean isConformingHostAndJDK16OrHigher() {
- if (!EnvUtil.isJDK6OrHigher()) {
- return false;
- }
- return EnvUtilForTests.isLocalHostNameInList(CONFORMING_HOST_LIST);
+
+ StatusPrinter.print(context);
+
+ // check that there were no errors
+ assertEquals(Status.INFO, statusChecker.getHighestLevel(0));
+
+ }
+
+ static boolean isConformingHostAndJDK16OrHigher() {
+ if(!EnvUtil.isJDK6OrHigher()) {
+ return false;
}
-
- @Test
- public void sqlserver() throws Exception {
- // perform test only on conforming hosts
- if (!isConformingHostAndJDK16OrHigher()) {
- return;
- }
- doTest("src/test/input/integration/db/sqlserver-with-driver.xml");
+ return EnvUtilForTests.isLocalHostNameInList(CONFORMING_HOST_LIST);
+ }
+
+ @Test
+ public void sqlserver() throws Exception {
+ // perform test only on conforming hosts
+ if (!isConformingHostAndJDK16OrHigher()) {
+ return;
}
-
- @Test
- @Ignore
- public void oracle10g() throws Exception {
- // perform test only on conforming hosts
- if (!isConformingHostAndJDK16OrHigher()) {
- return;
- }
- doTest("src/test/input/integration/db/oracle10g-with-driver.xml");
+ doTest("src/test/input/integration/db/sqlserver-with-driver.xml");
+ }
+
+ @Test
+ @Ignore
+ public void oracle10g() throws Exception {
+ // perform test only on conforming hosts
+ if (!isConformingHostAndJDK16OrHigher()) {
+ return;
}
-
- @Test
- @Ignore
- public void oracle11g() throws Exception {
- // perform test only on conforming hosts
- if (!isConformingHostAndJDK16OrHigher()) {
- return;
- }
- doTest("src/test/input/integration/db/oracle11g-with-driver.xml");
+ doTest("src/test/input/integration/db/oracle10g-with-driver.xml");
+ }
+
+ @Test
+ @Ignore
+ public void oracle11g() throws Exception {
+ // perform test only on conforming hosts
+ if (!isConformingHostAndJDK16OrHigher()) {
+ return;
}
-
- @Test
- public void mysql() throws Exception {
- // perform test only on conforming hosts
- if (!isConformingHostAndJDK16OrHigher()) {
- return;
- }
- doTest("src/test/input/integration/db/mysql-with-driver.xml");
+ doTest("src/test/input/integration/db/oracle11g-with-driver.xml");
+ }
+
+ @Test
+ public void mysql() throws Exception {
+ // perform test only on conforming hosts
+ if (!isConformingHostAndJDK16OrHigher()) {
+ return;
}
-
- @Test
- public void postgres() throws Exception {
- // perform test only on conforming hosts
- if (!isConformingHostAndJDK16OrHigher()) {
- return;
- }
- doTest("src/test/input/integration/db/postgresql-with-driver.xml");
+ doTest("src/test/input/integration/db/mysql-with-driver.xml");
+ }
+
+ @Test
+ public void postgres() throws Exception {
+ // perform test only on conforming hosts
+ if (!isConformingHostAndJDK16OrHigher()) {
+ return;
}
-
+ doTest("src/test/input/integration/db/postgresql-with-driver.xml");
+ }
+
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/db/PackageTest.java b/logback-access/src/test/java/ch/qos/logback/access/db/PackageTest.java
index 7e3ad4b..46f0d1b 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/db/PackageTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/db/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,7 +17,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
- at Suite.SuiteClasses({ DBAppenderHSQLTest.class, DBAppenderIntegrationTest.class })
-public class PackageTest {
+ at Suite.SuiteClasses({DBAppenderHSQLTest.class, DBAppenderIntegrationTest.class})
+public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyAccessEventBuilder.java b/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyAccessEventBuilder.java
index d782e12..05d9963 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyAccessEventBuilder.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyAccessEventBuilder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,12 +18,13 @@ import ch.qos.logback.access.spi.IAccessEvent;
public class DummyAccessEventBuilder {
- static public IAccessEvent buildNewAccessEvent() {
- DummyRequest request = new DummyRequest();
- DummyResponse response = new DummyResponse();
- DummyServerAdapter adapter = new DummyServerAdapter(request, response);
-
- return new AccessEvent(request, response, adapter);
- }
-
+
+ static public IAccessEvent buildNewAccessEvent() {
+ DummyRequest request = new DummyRequest();
+ DummyResponse response = new DummyResponse();
+ DummyServerAdapter adapter = new DummyServerAdapter(request, response);
+
+ return new AccessEvent(request, response, adapter);
+ }
+
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyRequest.java b/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyRequest.java
index c873bcc..4674f64 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyRequest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyRequest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,308 +13,307 @@
*/
package ch.qos.logback.access.dummy;
-import ch.qos.logback.access.AccessConstants;
-
-import javax.servlet.*;
-import javax.servlet.http.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.*;
-public class DummyRequest implements HttpServletRequest {
-
- public final static String DUMMY_CONTENT_STRING = "request contents";
- public final static byte[] DUMMY_CONTENT_BYTES = DUMMY_CONTENT_STRING.getBytes();
-
- public static final Map<String, Object> DUMMY_DEFAULT_ATTR_MAP = new HashMap<String, Object>();
-
- public static final String DUMMY_RESPONSE_CONTENT_STRING = "response contents";
- public static final byte[] DUMMY_RESPONSE_CONTENT_BYTES = DUMMY_RESPONSE_CONTENT_STRING.getBytes();
-
- Hashtable<String, String> headerNames;
- String uri;
- Map<String, Object> attributes;
-
- static {
- DUMMY_DEFAULT_ATTR_MAP.put("testKey", "testKey");
- DUMMY_DEFAULT_ATTR_MAP.put(AccessConstants.LB_INPUT_BUFFER, DUMMY_CONTENT_BYTES);
- DUMMY_DEFAULT_ATTR_MAP.put(AccessConstants.LB_OUTPUT_BUFFER, DUMMY_RESPONSE_CONTENT_BYTES);
- }
-
- public DummyRequest() {
- headerNames = new Hashtable<String, String>();
- headerNames.put("headerName1", "headerValue1");
- headerNames.put("headerName2", "headerValue2");
-
- attributes = new HashMap<String, Object>(DUMMY_DEFAULT_ATTR_MAP);
- }
-
- public String getAuthType() {
- return null;
- }
-
- public String getContextPath() {
- return null;
- }
-
- public Cookie[] getCookies() {
- Cookie cookie = new Cookie("testName", "testCookie");
- return new Cookie[] { cookie };
- }
-
- public long getDateHeader(String arg0) {
- return 0;
- }
-
- public String getHeader(String key) {
- return headerNames.get(key);
- }
-
- public Enumeration getHeaderNames() {
- return headerNames.keys();
- }
-
- public Enumeration getHeaders(String arg0) {
- return null;
- }
-
- public int getIntHeader(String arg0) {
- return 0;
- }
-
- public String getMethod() {
- return "testMethod";
- }
-
- public String getPathInfo() {
- return null;
- }
-
- public String getPathTranslated() {
- return null;
- }
-
- public String getQueryString() {
- return null;
- }
-
- public String getRemoteUser() {
- return "testUser";
- }
-
- public String getRequestURI() {
- return uri;
- }
-
- public StringBuffer getRequestURL() {
- return new StringBuffer(uri);
- }
-
- public String getRequestedSessionId() {
- return null;
- }
-
- public String getServletPath() {
- return null;
- }
-
- public HttpSession getSession() {
- return null;
- }
-
- public HttpSession getSession(boolean arg0) {
- return null;
- }
-
- public Principal getUserPrincipal() {
- return null;
- }
-
- public boolean isRequestedSessionIdFromCookie() {
- return false;
- }
-
- public boolean isRequestedSessionIdFromURL() {
- return false;
- }
-
- public boolean isRequestedSessionIdFromUrl() {
- return false;
- }
-
- public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
- return false; // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void login(String username, String password) throws ServletException {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void logout() throws ServletException {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public Collection<Part> getParts() throws IOException, IllegalStateException, ServletException {
- return null; // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public Part getPart(String name) throws IOException, IllegalStateException, ServletException {
- return null; // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public boolean isRequestedSessionIdValid() {
- return false;
- }
-
- public boolean isUserInRole(String arg0) {
- return false;
- }
-
- public Object getAttribute(String key) {
- return attributes.get(key);
- }
-
- public Enumeration getAttributeNames() {
- return Collections.enumeration(attributes.keySet());
- }
-
- public String getCharacterEncoding() {
- return null;
- }
-
- public int getContentLength() {
- return 0;
- }
-
- public String getContentType() {
- return null;
- }
-
- public ServletInputStream getInputStream() throws IOException {
- return null;
- }
-
- public String getLocalAddr() {
- return null;
- }
+import javax.servlet.*;
+import javax.servlet.http.*;
- public String getLocalName() {
- return null;
- }
+import ch.qos.logback.access.AccessConstants;
- public int getLocalPort() {
- return 11;
- }
+public class DummyRequest implements HttpServletRequest {
- public ServletContext getServletContext() {
- return null; // To change body of implemented methods use File | Settings | File Templates.
- }
+ public final static String DUMMY_CONTENT_STRING = "request contents";
+ public final static byte[] DUMMY_CONTENT_BYTES = DUMMY_CONTENT_STRING.getBytes();
+
+
+ public static final String DUMMY_RESPONSE_CONTENT_STRING = "response contents";
+ public static final byte[] DUMMY_RESPONSE_CONTENT_BYTES =DUMMY_RESPONSE_CONTENT_STRING.getBytes();
+
+ Hashtable<String, String> headerNames;
+ String uri;
- public AsyncContext startAsync() {
- return null; // To change body of implemented methods use File | Settings | File Templates.
- }
+ public DummyRequest() {
+ headerNames = new Hashtable<String, String>();
+ headerNames.put("headerName1", "headerValue1");
+ headerNames.put("headerName2", "headerValue2");
+ }
+
+ public String getAuthType() {
+ return null;
+ }
+
+ public String getContextPath() {
+ return null;
+ }
+
+ public Cookie[] getCookies() {
+ Cookie cookie = new Cookie("testName", "testCookie");
+ return new Cookie[] { cookie };
+ }
- public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) {
- return null; // To change body of implemented methods use File | Settings | File Templates.
- }
+ public long getDateHeader(String arg0) {
+ return 0;
+ }
- public boolean isAsyncStarted() {
- return false; // To change body of implemented methods use File | Settings | File Templates.
- }
+ public String getHeader(String key) {
+ return headerNames.get(key);
+ }
- public boolean isAsyncSupported() {
- return false; // To change body of implemented methods use File | Settings | File Templates.
- }
+ public Enumeration getHeaderNames() {
+ return headerNames.keys();
+ }
+
+ public Enumeration getHeaders(String arg0) {
+ return null;
+ }
+
+ public int getIntHeader(String arg0) {
+ return 0;
+ }
+
+ public String getMethod() {
+ return "testMethod";
+ }
+
+ public String getPathInfo() {
+ return null;
+ }
+
+ public String getPathTranslated() {
+ return null;
+ }
+
+ public String getQueryString() {
+ return null;
+ }
+
+ public String getRemoteUser() {
+ return "testUser";
+ }
+
+ public String getRequestURI() {
+ return uri;
+ }
+
+ public StringBuffer getRequestURL() {
+ return new StringBuffer(uri);
+ }
+
+ public String getRequestedSessionId() {
+ return null;
+ }
+
+ public String getServletPath() {
+ return null;
+ }
+
+ public HttpSession getSession() {
+ return null;
+ }
+
+ public HttpSession getSession(boolean arg0) {
+ return null;
+ }
+
+ public Principal getUserPrincipal() {
+ return null;
+ }
+
+ public boolean isRequestedSessionIdFromCookie() {
+ return false;
+ }
+
+ public boolean isRequestedSessionIdFromURL() {
+ return false;
+ }
+
+ public boolean isRequestedSessionIdFromUrl() {
+ return false;
+ }
+
+ public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void login(String username, String password) throws ServletException {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void logout() throws ServletException {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public Collection<Part> getParts() throws IOException, IllegalStateException, ServletException {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public Part getPart(String name) throws IOException, IllegalStateException, ServletException {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
- public AsyncContext getAsyncContext() {
- return null; // To change body of implemented methods use File | Settings | File Templates.
- }
+ public boolean isRequestedSessionIdValid() {
+ return false;
+ }
- public DispatcherType getDispatcherType() {
- return null; // To change body of implemented methods use File | Settings | File Templates.
- }
+ public boolean isUserInRole(String arg0) {
+ return false;
+ }
- public Locale getLocale() {
- return null;
- }
+ public Object getAttribute(String key) {
+ if (key.equals("testKey")) {
+ return "testKey";
+ } else if (AccessConstants.LB_INPUT_BUFFER.equals(key)) {
+ return DUMMY_CONTENT_BYTES;
+ } else if (AccessConstants.LB_OUTPUT_BUFFER.equals(key)) {
+ return DUMMY_RESPONSE_CONTENT_BYTES;
+ } else {
+ return null;
+ }
+ }
- public Enumeration getLocales() {
- return null;
- }
+ public Enumeration getAttributeNames() {
+ return null;
+ }
- public String getParameter(String arg0) {
- return null;
- }
+ public String getCharacterEncoding() {
+ return null;
+ }
- public Map getParameterMap() {
- return null;
- }
+ public int getContentLength() {
+ return 0;
+ }
- public Enumeration getParameterNames() {
- return null;
- }
+ public String getContentType() {
+ return null;
+ }
- public String[] getParameterValues(String arg0) {
- return null;
- }
+ public ServletInputStream getInputStream() throws IOException {
+ return null;
+ }
- public String getProtocol() {
- return "testProtocol";
- }
+ public String getLocalAddr() {
+ return null;
+ }
- public BufferedReader getReader() throws IOException {
- return null;
- }
+ public String getLocalName() {
+ return null;
+ }
- public String getRealPath(String arg0) {
- return null;
- }
+ public int getLocalPort() {
+ return 11;
+ }
- public String getRemoteAddr() {
- return "testRemoteAddress";
- }
+ public ServletContext getServletContext() {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
- public String getRemoteHost() {
- return "testHost";
- }
+ public AsyncContext startAsync() {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean isAsyncStarted() {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean isAsyncSupported() {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public AsyncContext getAsyncContext() {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public DispatcherType getDispatcherType() {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public Locale getLocale() {
+ return null;
+ }
+
+ public Enumeration getLocales() {
+ return null;
+ }
+
+ public String getParameter(String arg0) {
+ return null;
+ }
+
+ public Map getParameterMap() {
+ return null;
+ }
+
+ public Enumeration getParameterNames() {
+ return null;
+ }
+
+ public String[] getParameterValues(String arg0) {
+ return null;
+ }
+
+ public String getProtocol() {
+ return "testProtocol";
+ }
+
+ public BufferedReader getReader() throws IOException {
+ return null;
+ }
+
+ public String getRealPath(String arg0) {
+ return null;
+ }
- public int getRemotePort() {
- return 0;
- }
+ public String getRemoteAddr() {
+ return "testRemoteAddress";
+ }
- public RequestDispatcher getRequestDispatcher(String arg0) {
- return null;
- }
+ public String getRemoteHost() {
+ return "testHost";
+ }
- public String getScheme() {
- return null;
- }
+ public int getRemotePort() {
+ return 0;
+ }
- public String getServerName() {
- return "testServerName";
- }
+ public RequestDispatcher getRequestDispatcher(String arg0) {
+ return null;
+ }
- public int getServerPort() {
- return 0;
- }
+ public String getScheme() {
+ return null;
+ }
- public boolean isSecure() {
- return false;
- }
+ public String getServerName() {
+ return "testServerName";
+ }
- public void removeAttribute(String arg0) {
- }
+ public int getServerPort() {
+ return 0;
+ }
- public void setAttribute(String name, Object value) {
- attributes.put(name, value);
- }
+ public boolean isSecure() {
+ return false;
+ }
- public void setCharacterEncoding(String arg0) throws UnsupportedEncodingException {
- }
+ public void removeAttribute(String arg0) {
+ }
- public void setRequestUri(String uri) {
- this.uri = uri;
- }
+ public void setAttribute(String arg0, Object arg1) {
+ }
+
+ public void setCharacterEncoding(String arg0)
+ throws UnsupportedEncodingException {
+ }
+
+ public void setRequestUri(String uri) {
+ this.uri = uri;
+ }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyResponse.java b/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyResponse.java
index abcd354..8331db0 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyResponse.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyResponse.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,161 +23,154 @@ import javax.servlet.http.HttpServletResponse;
public class DummyResponse implements HttpServletResponse {
- public static final int DUMMY_DEFAULT_STATUS = 200;
- public static final int DUMMY_DEFAULT_CONTENT_COUNT = 1000;
- public static final Map<String, String> DUMMY_DEFAULT_HDEADER_MAP = new HashMap<String, String>();;
+ public static final int DUMMY_DEFAULT_STATUS = 200;
+ public static final int DUMMY_DEFAULT_CONTENT_COUNT = 1000;
+ public static final Map<String, String> DUMMY_DEFAULT_HDEADER_MAP = new HashMap<String, String>();
+ ;
- static {
- DUMMY_DEFAULT_HDEADER_MAP.put("headerName1", "headerValue1");
- DUMMY_DEFAULT_HDEADER_MAP.put("headerName2", "headerValue2");
- }
+ static {
+ DUMMY_DEFAULT_HDEADER_MAP.put("headerName1", "headerValue1");
+ DUMMY_DEFAULT_HDEADER_MAP.put("headerName2", "headerValue2");
+ }
- int status = DUMMY_DEFAULT_STATUS;
- public Map<String, String> headerMap;
+ int status = DUMMY_DEFAULT_STATUS;
+ public Map<String, String> headerMap;
- String characterEncoding = null;
- ServletOutputStream outputStream = null;
+ public DummyResponse() {
+ headerMap = DUMMY_DEFAULT_HDEADER_MAP;
+ }
- public DummyResponse() {
- headerMap = DUMMY_DEFAULT_HDEADER_MAP;
- }
+ public void addCookie(Cookie arg0) {
+ }
- public void addCookie(Cookie arg0) {
- }
+ public void addDateHeader(String arg0, long arg1) {
+ }
- public void addDateHeader(String arg0, long arg1) {
- }
+ public void addHeader(String arg0, String arg1) {
+ }
- public void addHeader(String arg0, String arg1) {
- }
+ public void addIntHeader(String arg0, int arg1) {
+ }
- public void addIntHeader(String arg0, int arg1) {
- }
+ public boolean containsHeader(String arg0) {
+ return false;
+ }
- public boolean containsHeader(String arg0) {
- return false;
- }
+ public String encodeRedirectURL(String arg0) {
+ return null;
+ }
- public String encodeRedirectURL(String arg0) {
- return null;
- }
+ public String encodeRedirectUrl(String arg0) {
+ return null;
+ }
- public String encodeRedirectUrl(String arg0) {
- return null;
- }
+ public String encodeURL(String arg0) {
+ return null;
+ }
- public String encodeURL(String arg0) {
- return null;
- }
+ public String encodeUrl(String arg0) {
+ return null;
+ }
- public String encodeUrl(String arg0) {
- return null;
- }
+ public void sendError(int arg0) throws IOException {
+ }
- public void sendError(int arg0) throws IOException {
- }
+ public void sendError(int arg0, String arg1) throws IOException {
+ }
- public void sendError(int arg0, String arg1) throws IOException {
- }
+ public void sendRedirect(String arg0) throws IOException {
+ }
- public void sendRedirect(String arg0) throws IOException {
- }
+ public void setDateHeader(String arg0, long arg1) {
+ }
- public void setDateHeader(String arg0, long arg1) {
- }
+ public void setHeader(String arg0, String arg1) {
+ }
- public void setHeader(String arg0, String arg1) {
- }
+ public void setIntHeader(String arg0, int arg1) {
+ }
- public void setIntHeader(String arg0, int arg1) {
- }
+ public void setStatus(int arg0, String arg1) {
+ }
- public void setStatus(int arg0, String arg1) {
- }
+ public void flushBuffer() throws IOException {
+ }
- public void flushBuffer() throws IOException {
- }
+ public int getBufferSize() {
+ return 0;
+ }
- public int getBufferSize() {
- return 0;
- }
+ public String getCharacterEncoding() {
+ return null;
+ }
- public String getCharacterEncoding() {
- return characterEncoding;
- }
+ public String getContentType() {
+ return null;
+ }
- public String getContentType() {
- return null;
- }
+ public Locale getLocale() {
+ return null;
+ }
- public Locale getLocale() {
- return null;
- }
+ public ServletOutputStream getOutputStream() throws IOException {
+ return null;
+ }
- public ServletOutputStream getOutputStream() throws IOException {
- return outputStream;
- }
+ public PrintWriter getWriter() throws IOException {
+ return null;
+ }
- public void setOutputStream(ServletOutputStream outputStream) {
- this.outputStream = outputStream;
- }
+ public boolean isCommitted() {
+ return false;
+ }
- public PrintWriter getWriter() throws IOException {
- return null;
- }
+ public void reset() {
+ }
- public boolean isCommitted() {
- return false;
- }
+ public void resetBuffer() {
+ }
- public void reset() {
- }
+ public void setBufferSize(int arg0) {
+ }
- public void resetBuffer() {
- }
+ public void setCharacterEncoding(String arg0) {
+ }
- public void setBufferSize(int arg0) {
- }
+ public void setContentLength(int arg0) {
+ }
- public void setCharacterEncoding(String characterEncoding) {
- this.characterEncoding = characterEncoding;
- }
+ public void setContentType(String arg0) {
+ }
- public void setContentLength(int arg0) {
- }
+ public void setLocale(Locale arg0) {
+ }
- public void setContentType(String arg0) {
- }
+ public String getHeader(String key) {
+ return headerMap.get(key);
+ }
- public void setLocale(Locale arg0) {
- }
+ public Collection<String> getHeaders(String name) {
+ String val = headerMap.get(name);
+ List list = new ArrayList();
+ if (val != null)
+ list.add(val);
+ return list;
+ }
- public String getHeader(String key) {
- return headerMap.get(key);
- }
+ public Collection<String> getHeaderNames() {
+ return headerMap.keySet();
+ }
- public Collection<String> getHeaders(String name) {
- String val = headerMap.get(name);
- List list = new ArrayList();
- if (val != null)
- list.add(val);
- return list;
- }
+ public long getContentCount() {
+ return DUMMY_DEFAULT_CONTENT_COUNT;
+ }
- public Collection<String> getHeaderNames() {
- return headerMap.keySet();
- }
+ public int getStatus() {
+ return status;
+ }
- public long getContentCount() {
- return DUMMY_DEFAULT_CONTENT_COUNT;
- }
-
- public int getStatus() {
- return status;
- }
-
- public void setStatus(int status) {
- this.status = status;
- }
+ public void setStatus(int status) {
+ this.status = status;
+ }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyServerAdapter.java b/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyServerAdapter.java
index 429e658..2bae5f8 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyServerAdapter.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyServerAdapter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,28 +19,28 @@ import java.util.Map;
public class DummyServerAdapter implements ServerAdapter {
- DummyRequest request;
- DummyResponse response;
+ DummyRequest request;
+ DummyResponse response;
- public DummyServerAdapter(DummyRequest dummyRequest, DummyResponse dummyResponse) {
- this.request = dummyRequest;
- this.response = dummyResponse;
- }
+ public DummyServerAdapter(DummyRequest dummyRequest, DummyResponse dummyResponse) {
+ this.request = dummyRequest;
+ this.response = dummyResponse;
+ }
- public long getContentLength() {
- return response.getContentCount();
- }
+ public long getContentLength() {
+ return response.getContentCount();
+ }
- public int getStatusCode() {
- return response.getStatus();
- }
+ public int getStatusCode() {
+ return response.getStatus();
+ }
- public long getRequestTimestamp() {
- return -1;
- }
+ public long getRequestTimestamp() {
+ return -1;
+ }
- public Map<String, String> buildResponseHeaderMap() {
- return response.headerMap;
- }
+ public Map<String, String> buildResponseHeaderMap() {
+ return response.headerMap;
+ }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyServletOutputStream.java b/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyServletOutputStream.java
deleted file mode 100644
index 76b9117..0000000
--- a/logback-access/src/test/java/ch/qos/logback/access/dummy/DummyServletOutputStream.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.access.dummy;
-
-import javax.servlet.ServletOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-public class DummyServletOutputStream extends ServletOutputStream {
-
- private final OutputStream targetStream;
-
- public DummyServletOutputStream(OutputStream targetStream) {
- this.targetStream = targetStream;
- }
-
- @Override
- public void write(int b) throws IOException {
- this.targetStream.write(b);
- }
-
- public void flush() throws IOException {
- super.flush();
- this.targetStream.flush();
- }
-
- public void close() throws IOException {
- super.close();
- this.targetStream.close();
- }
-}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/filter/PackageTest.java b/logback-access/src/test/java/ch/qos/logback/access/filter/PackageTest.java
index b6f0220..7160e7f 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/filter/PackageTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/filter/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,6 +20,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ StatsByDayTest.class })
+ at SuiteClasses({StatsByDayTest.class})
public class PackageTest extends TestCase {
}
\ No newline at end of file
diff --git a/logback-access/src/test/java/ch/qos/logback/access/filter/StatsByDayTest.java b/logback-access/src/test/java/ch/qos/logback/access/filter/StatsByDayTest.java
index 83e1754..06c038d 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/filter/StatsByDayTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/filter/StatsByDayTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,56 +21,56 @@ import ch.qos.logback.core.util.TimeUtil;
public class StatsByDayTest {
- @Test
- public void testBasic() {
- // Tue Nov 21 18:05:36 CET 2006
- long now = 1164128736369L;
- StatsByDay statsByDay = new StatsByDay(now);
-
- int total = 0;
- // test fresh start
- statsByDay.update(now, 0);
- assertEquals(0, statsByDay.getLastCount());
- assertEquals(0, statsByDay.getAverage(), 0.01);
-
- total++;
- statsByDay.update(now, total);
- assertEquals(0, statsByDay.getLastCount());
- assertEquals(0.0, statsByDay.getAverage(), 0.01);
-
- long nextDay0 = TimeUtil.computeStartOfNextDay(now);
- nextDay0 += 99;
-
- // there should be one event the next day, avg should also be 1
- statsByDay.update(nextDay0, total);
- assertEquals(1.0, statsByDay.getLastCount(), 0.01);
- assertEquals(1.0, statsByDay.getAverage(), 0.01);
-
- total += 2;
-
- statsByDay.update(nextDay0, total);
- assertEquals(1, statsByDay.getLastCount());
- assertEquals(1.0, statsByDay.getAverage(), 0.01);
-
- long nextDay1 = TimeUtil.computeStartOfNextDay(nextDay0) + 6747;
- statsByDay.update(nextDay1, total);
- assertEquals(2, statsByDay.getLastCount());
- assertEquals(1.5, statsByDay.getAverage(), 0.01);
-
- nextDay1 += 4444;
- total += 4;
-
- statsByDay.update(nextDay1, total);
- // values should remain unchanged
- assertEquals(2, statsByDay.getLastCount());
- assertEquals(1.5, statsByDay.getAverage(), 0.01);
-
- long nextDay2 = TimeUtil.computeStartOfNextDay(nextDay1) + 11177;
-
- statsByDay.update(nextDay2, total);
- // values should remain unchanged
- assertEquals(4, statsByDay.getLastCount());
- assertEquals(7.0 / 3, statsByDay.getAverage(), 0.01);
- }
+ @Test
+ public void testBasic() {
+ // Tue Nov 21 18:05:36 CET 2006
+ long now = 1164128736369L;
+ StatsByDay statsByDay = new StatsByDay(now);
+
+ int total = 0;
+ // test fresh start
+ statsByDay.update(now, 0);
+ assertEquals(0, statsByDay.getLastCount());
+ assertEquals(0, statsByDay.getAverage(), 0.01);
+
+ total++;
+ statsByDay.update(now, total);
+ assertEquals(0, statsByDay.getLastCount());
+ assertEquals(0.0, statsByDay.getAverage(), 0.01);
+
+ long nextDay0 = TimeUtil.computeStartOfNextDay(now);
+ nextDay0 += 99;
+
+ // there should be one event the next day, avg should also be 1
+ statsByDay.update(nextDay0, total);
+ assertEquals(1.0, statsByDay.getLastCount(), 0.01);
+ assertEquals(1.0, statsByDay.getAverage(), 0.01);
+
+ total += 2;
+
+ statsByDay.update(nextDay0, total);
+ assertEquals(1, statsByDay.getLastCount());
+ assertEquals(1.0, statsByDay.getAverage(), 0.01);
+
+ long nextDay1 = TimeUtil.computeStartOfNextDay(nextDay0) + 6747;
+ statsByDay.update(nextDay1, total);
+ assertEquals(2, statsByDay.getLastCount());
+ assertEquals(1.5, statsByDay.getAverage(), 0.01);
+
+ nextDay1 += 4444;
+ total += 4;
+
+ statsByDay.update(nextDay1, total);
+ // values should remain unchanged
+ assertEquals(2, statsByDay.getLastCount());
+ assertEquals(1.5, statsByDay.getAverage(), 0.01);
+
+ long nextDay2 = TimeUtil.computeStartOfNextDay(nextDay1) + 11177;
+
+ statsByDay.update(nextDay2, total);
+ // values should remain unchanged
+ assertEquals(4, statsByDay.getLastCount());
+ assertEquals(7.0 / 3, statsByDay.getAverage(), 0.01);
+ }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java b/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java
index da2531e..0172850 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,14 +14,12 @@
package ch.qos.logback.access.jetty;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
-import java.util.concurrent.TimeUnit;
import ch.qos.logback.access.spi.IAccessEvent;
import org.junit.AfterClass;
@@ -34,87 +32,97 @@ import ch.qos.logback.core.testUtil.RandomUtil;
public class JettyBasicTest {
- static RequestLogImpl REQUEST_LOG_IMPL;
- static JettyFixtureWithListAndConsoleAppenders JETTY_FIXTURE;
-
- private static final int TIMEOUT = 5;
- static int RANDOM_SERVER_PORT = RandomUtil.getRandomServerPort();
-
- @BeforeClass
- static public void startServer() throws Exception {
- REQUEST_LOG_IMPL = new RequestLogImpl();
- JETTY_FIXTURE = new JettyFixtureWithListAndConsoleAppenders(REQUEST_LOG_IMPL, RANDOM_SERVER_PORT);
- JETTY_FIXTURE.start();
- }
-
- @AfterClass
- static public void stopServer() throws Exception {
- if (JETTY_FIXTURE != null) {
- JETTY_FIXTURE.stop();
- }
+ static RequestLogImpl REQYEST_LOG_IMPL;
+ static JettyFixtureWithListAndConsoleAppenders JETTY_FIXTURE;
+
+ static int RANDOM_SERVER_PORT = RandomUtil.getRandomServerPort();
+
+ @BeforeClass
+ static public void startServer() throws Exception {
+ REQYEST_LOG_IMPL = new RequestLogImpl();
+ JETTY_FIXTURE = new JettyFixtureWithListAndConsoleAppenders(REQYEST_LOG_IMPL, RANDOM_SERVER_PORT);
+ JETTY_FIXTURE.start();
+ }
+
+ @AfterClass
+ static public void stopServer() throws Exception {
+ if (JETTY_FIXTURE != null) {
+ JETTY_FIXTURE.stop();
}
+ }
- @Test
- public void getRequest() throws Exception {
- URL url = new URL("http://localhost:" + RANDOM_SERVER_PORT + "/");
- HttpURLConnection connection = (HttpURLConnection) url.openConnection();
- connection.setDoInput(true);
-
- String result = Util.readToString(connection.getInputStream());
+ @Test
+ public void getRequest() throws Exception {
+ URL url = new URL("http://localhost:" + RANDOM_SERVER_PORT + "/");
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setDoInput(true);
- assertEquals("hello world", result);
+ String result = Util.readToString(connection.getInputStream());
- NotifyingListAppender listAppender = (NotifyingListAppender) REQUEST_LOG_IMPL.getAppender("list");
- listAppender.list.clear();
- }
+ assertEquals("hello world", result);
- @Test
- public void eventGoesToAppenders() throws Exception {
- URL url = new URL(JETTY_FIXTURE.getUrl());
- HttpURLConnection connection = (HttpURLConnection) url.openConnection();
- connection.setDoInput(true);
+ NotifyingListAppender listAppender = (NotifyingListAppender) REQYEST_LOG_IMPL
+ .getAppender("list");
+ listAppender.list.clear();
+ }
- String result = Util.readToString(connection.getInputStream());
+ @Test
+ public void eventGoesToAppenders() throws Exception {
+ URL url = new URL(JETTY_FIXTURE.getUrl());
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setDoInput(true);
- assertEquals("hello world", result);
+ String result = Util.readToString(connection.getInputStream());
- NotifyingListAppender listAppender = (NotifyingListAppender) REQUEST_LOG_IMPL.getAppender("list");
- IAccessEvent event = listAppender.list.poll(TIMEOUT, TimeUnit.SECONDS);
- assertNotNull("No events received", event);
+ assertEquals("hello world", result);
- assertEquals("127.0.0.1", event.getRemoteHost());
- assertEquals("localhost", event.getServerName());
- listAppender.list.clear();
+ NotifyingListAppender listAppender = (NotifyingListAppender) REQYEST_LOG_IMPL
+ .getAppender("list");
+ synchronized (listAppender) {
+ listAppender.wait(100);
}
- @Test
- public void postContentConverter() throws Exception {
- URL url = new URL(JETTY_FIXTURE.getUrl());
- String msg = "test message";
-
- HttpURLConnection connection = (HttpURLConnection) url.openConnection();
- // this line is necessary to make the stream aware of when the message is
- // over.
- connection.setFixedLengthStreamingMode(msg.getBytes().length);
- ((HttpURLConnection) connection).setRequestMethod("POST");
- connection.setDoOutput(true);
- connection.setDoInput(true);
- connection.setUseCaches(false);
- connection.setRequestProperty("Content-Type", "text/plain");
-
- PrintWriter output = new PrintWriter(new OutputStreamWriter(connection.getOutputStream()));
- output.print(msg);
- output.flush();
- output.close();
-
- // StatusPrinter.print(requestLogImpl.getStatusManager());
-
- NotifyingListAppender listAppender = (NotifyingListAppender) REQUEST_LOG_IMPL.getAppender("list");
+ assertTrue(listAppender.list.size() > 0);
+ IAccessEvent event = listAppender.list.get(0);
+ assertEquals("127.0.0.1", event.getRemoteHost());
+ assertEquals("localhost", event.getServerName());
+ listAppender.list.clear();
+ }
+
+ @Test
+ public void postContentConverter() throws Exception {
+ URL url = new URL(JETTY_FIXTURE.getUrl());
+ String msg = "test message";
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ // this line is necessary to make the stream aware of when the message is
+ // over.
+ connection.setFixedLengthStreamingMode(msg.getBytes().length);
+ ((HttpURLConnection) connection).setRequestMethod("POST");
+ connection.setDoOutput(true);
+ connection.setDoInput(true);
+ connection.setUseCaches(false);
+ connection.setRequestProperty("Content-Type", "text/plain");
+
+ PrintWriter output = new PrintWriter(new OutputStreamWriter(connection
+ .getOutputStream()));
+ output.print(msg);
+ output.flush();
+ output.close();
+
+ // StatusPrinter.print(requestLogImpl.getStatusManager());
+
+ NotifyingListAppender listAppender = (NotifyingListAppender) REQYEST_LOG_IMPL
+ .getAppender("list");
+
+ synchronized (listAppender) {
+ listAppender.wait(100);
+ }
- IAccessEvent event = listAppender.list.poll(TIMEOUT, TimeUnit.SECONDS);
- assertNotNull("No events received", event);
+ @SuppressWarnings("unused")
+ IAccessEvent event = listAppender.list.get(0);
- // we should test the contents of the requests
- // assertEquals(msg, event.getRequestContent());
- }
+ // we should test the contents of the requests
+ // assertEquals(msg, event.getRequestContent());
+ }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyFixtureBase.java b/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyFixtureBase.java
index 4e309b4..eeb269b 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyFixtureBase.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyFixtureBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,69 +30,72 @@ import java.io.IOException;
import java.io.OutputStream;
public class JettyFixtureBase {
- final protected RequestLogImpl requestLogImpl;
- protected Handler handler = new BasicHandler();
- private final int port;
- Server server;
- protected String url;
-
- public JettyFixtureBase(RequestLogImpl impl, int port) {
- requestLogImpl = impl;
- this.port = port;
- url = "http://localhost:" + port + "/";
- }
-
- public String getName() {
- return "Jetty Test Setup";
- }
-
- public String getUrl() {
- return url;
- }
-
- public void start() throws Exception {
- server = new Server();
- Connector connector = new SelectChannelConnector();
- connector.setPort(port);
- server.setConnectors(new Connector[] { connector });
-
- RequestLogHandler requestLogHandler = new RequestLogHandler();
- configureRequestLogImpl();
- requestLogHandler.setRequestLog(requestLogImpl);
-
- HandlerList handlers = new HandlerList();
- handlers.addHandler(requestLogHandler);
- handlers.addHandler(getRequestHandler());
-
- server.setHandler(handlers);
- server.start();
- }
-
- public void stop() throws Exception {
- server.stop();
- server = null;
- }
-
- protected void configureRequestLogImpl() {
- requestLogImpl.start();
- }
+ final protected RequestLogImpl requestLogImpl;
+ protected Handler handler = new BasicHandler();
+ private final int port;
+ Server server;
+ protected String url;
+
+ public JettyFixtureBase(RequestLogImpl impl, int port) {
+ requestLogImpl = impl;
+ this.port = port;
+ url = "http://localhost:" + port + "/";
+ }
+
+ public String getName() {
+ return "Jetty Test Setup";
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void start() throws Exception {
+ server = new Server();
+ Connector connector = new SelectChannelConnector();
+ connector.setPort(port);
+ server.setConnectors(new Connector[]{connector});
+
+ RequestLogHandler requestLogHandler = new RequestLogHandler();
+ configureRequestLogImpl();
+ requestLogHandler.setRequestLog(requestLogImpl);
+
+ HandlerList handlers = new HandlerList();
+ handlers.addHandler(requestLogHandler);
+ handlers.addHandler(getRequestHandler());
+
+ server.setHandler(handlers);
+ server.start();
+ }
+
+ public void stop() throws Exception {
+ server.stop();
+ server = null;
+ }
+
+ protected void configureRequestLogImpl() {
+ requestLogImpl.start();
+ }
+
+ protected Handler getRequestHandler() {
+ return handler;
+ }
+
+
+ class BasicHandler extends AbstractHandler {
+ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+ OutputStream out = response.getOutputStream();
+ ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer();
+ writer.write("hello world");
+ writer.flush();
+ response.setContentLength(writer.size());
+ writer.writeTo(out);
+ out.flush();
+
+ baseRequest.setHandled(true);
- protected Handler getRequestHandler() {
- return handler;
}
+ }
+}
- class BasicHandler extends AbstractHandler {
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
- OutputStream out = response.getOutputStream();
- ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer();
- writer.write("hello world");
- writer.flush();
- response.setContentLength(writer.size());
- writer.writeTo(out);
- out.flush();
-
- baseRequest.setHandled(true);
- }
- }
-}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyFixtureWithListAndConsoleAppenders.java b/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyFixtureWithListAndConsoleAppenders.java
index d5653c6..bf04d51 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyFixtureWithListAndConsoleAppenders.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyFixtureWithListAndConsoleAppenders.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,39 +20,40 @@ import ch.qos.logback.core.ConsoleAppender;
public class JettyFixtureWithListAndConsoleAppenders extends JettyFixtureBase {
- public JettyFixtureWithListAndConsoleAppenders(RequestLogImpl impl, int port) {
- super(impl, port);
- url = "http://localhost:" + port + "/";
- }
-
- public void start() throws Exception {
- super.start();
- Thread.yield();
- }
-
- public void stop() throws Exception {
- super.stop();
- Thread.sleep(500);
- }
-
- @Override
- protected void configureRequestLogImpl() {
- NotifyingListAppender appender = new NotifyingListAppender();
- appender.setContext(requestLogImpl);
- appender.setName("list");
- appender.start();
-
- ConsoleAppender<IAccessEvent> console = new ConsoleAppender<IAccessEvent>();
- console.setContext(requestLogImpl);
- console.setName("console");
- PatternLayoutEncoder layout = new PatternLayoutEncoder();
- layout.setContext(requestLogImpl);
- layout.setPattern("%date %server %clientHost");
- console.setEncoder(layout);
- layout.start();
- console.start();
-
- requestLogImpl.addAppender(appender);
- requestLogImpl.addAppender(console);
- }
+ public JettyFixtureWithListAndConsoleAppenders(RequestLogImpl impl, int port) {
+ super(impl, port);
+ url = "http://localhost:" + port + "/";
+ }
+
+ public void start() throws Exception {
+ super.start();
+ Thread.yield();
+ }
+
+ public void stop() throws Exception {
+ super.stop();
+ Thread.sleep(500);
+ }
+
+ @Override
+ protected void configureRequestLogImpl() {
+ NotifyingListAppender appender = new NotifyingListAppender();
+ appender.setContext(requestLogImpl);
+ appender.setName("list");
+ appender.start();
+
+ ConsoleAppender<IAccessEvent> console = new ConsoleAppender<IAccessEvent>();
+ console.setContext(requestLogImpl);
+ console.setName("console");
+ PatternLayoutEncoder layout = new PatternLayoutEncoder();
+ layout.setContext(requestLogImpl);
+ layout.setPattern("%date %server %clientHost");
+ console.setEncoder(layout);
+ layout.start();
+ console.start();
+
+ requestLogImpl.addAppender(appender);
+ requestLogImpl.addAppender(console);
+ }
}
+
diff --git a/logback-access/src/test/java/ch/qos/logback/access/jetty/PackageTest.java b/logback-access/src/test/java/ch/qos/logback/access/jetty/PackageTest.java
index 75a3b73..3d3aebd 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/jetty/PackageTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/jetty/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,7 +18,7 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ JettyBasicTest.class })
-public class PackageTest {
+ at SuiteClasses({JettyBasicTest.class})
+public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-access/src/test/java/ch/qos/logback/access/joran/ConditionalTest.java b/logback-access/src/test/java/ch/qos/logback/access/joran/ConditionalTest.java
index a4f33dc..2d7dee1 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/joran/ConditionalTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/joran/ConditionalTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,7 +13,7 @@
*/
package ch.qos.logback.access.joran;
-import ch.qos.logback.access.AccessTestConstants;
+import ch.qos.logback.access.TeztConstants;
import ch.qos.logback.access.spi.AccessContext;
import ch.qos.logback.core.ConsoleAppender;
import ch.qos.logback.core.joran.spi.JoranException;
@@ -33,61 +33,63 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class ConditionalTest {
- AccessContext context = new AccessContext();
- StatusChecker checker = new StatusChecker(context);
+ AccessContext context = new AccessContext();
+ StatusChecker checker = new StatusChecker(context);
- int diff = RandomUtil.getPositiveInt();
- String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "/";
+ int diff = RandomUtil.getPositiveInt();
+ String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "/";
- @Before
- public void setUp() {
- InetAddress localhost = null;
- try {
- localhost = InetAddress.getLocalHost();
- context.putProperty("aHost", localhost.getHostName());
- } catch (UnknownHostException e) {
- e.printStackTrace();
- }
+ @Before
+ public void setUp() {
+ InetAddress localhost = null;
+ try {
+ localhost = InetAddress.getLocalHost();
+ context.putProperty("aHost", localhost.getHostName());
+ } catch (UnknownHostException e) {
+ e.printStackTrace();
}
+ }
- void configure(String file) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(context);
- jc.doConfigure(file);
- }
+ void configure(String file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(context);
+ jc.doConfigure(file);
+ }
- @Test
- public void conditionalConsoleApp_IF_THEN_True() throws JoranException, UnknownHostException {
- configure(AccessTestConstants.TEST_DIR_PREFIX + "input/joran/conditional/conditionalConsole.xml");
- ConsoleAppender consoleAppender = (ConsoleAppender) context.getAppender("CON");
- assertNotNull(consoleAppender);
- assertTrue(checker.isErrorFree(0));
- }
+ @Test
+ public void conditionalConsoleApp_IF_THEN_True() throws JoranException, UnknownHostException {
+ configure(TeztConstants.TEST_DIR_PREFIX + "input/joran/conditional/conditionalConsole.xml");
+ ConsoleAppender consoleAppender = (ConsoleAppender) context.getAppender("CON");
+ assertNotNull(consoleAppender);
+ assertTrue(checker.isErrorFree(0));
+ }
- @Test
- public void conditionalConsoleApp_IF_THEN_False() throws JoranException, IOException, InterruptedException {
- context.putProperty("aHost", null);
- configure(AccessTestConstants.TEST_DIR_PREFIX + "input/joran/conditional/conditionalConsole.xml");
+ @Test
+ public void conditionalConsoleApp_IF_THEN_False() throws JoranException,
+ IOException, InterruptedException {
+ context.putProperty("aHost", null);
+ configure(TeztConstants.TEST_DIR_PREFIX + "input/joran/conditional/conditionalConsole.xml");
- ConsoleAppender consoleAppender = (ConsoleAppender) context.getAppender("CON");
- assertNull(consoleAppender);
+ ConsoleAppender consoleAppender = (ConsoleAppender) context.getAppender("CON");
+ assertNull(consoleAppender);
- StatusChecker checker = new StatusChecker(context);
- assertTrue(checker.isErrorFree(0));
- }
+ StatusChecker checker = new StatusChecker(context);
+ assertTrue(checker.isErrorFree(0));
+ }
- @Test
- public void conditionalConsoleApp_ELSE() throws JoranException, IOException, InterruptedException {
- configure(AccessTestConstants.TEST_DIR_PREFIX + "input/joran/conditional/conditionalConsole_ELSE.xml");
- ConsoleAppender consoleAppender = (ConsoleAppender) context.getAppender("CON");
- assertNull(consoleAppender);
+ @Test
+ public void conditionalConsoleApp_ELSE() throws JoranException,
+ IOException, InterruptedException {
+ configure(TeztConstants.TEST_DIR_PREFIX + "input/joran/conditional/conditionalConsole_ELSE.xml");
+ ConsoleAppender consoleAppender = (ConsoleAppender) context.getAppender("CON");
+ assertNull(consoleAppender);
- ListAppender listAppender = (ListAppender) context.getAppender("LIST");
- assertNotNull(listAppender);
- assertTrue(checker.isErrorFree(0));
- }
+ ListAppender listAppender = (ListAppender) context.getAppender("LIST");
+ assertNotNull(listAppender);
+ assertTrue(checker.isErrorFree(0));
+ }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/joran/JoranConfiguratorTest.java b/logback-access/src/test/java/ch/qos/logback/access/joran/JoranConfiguratorTest.java
index d06f231..de5d00a 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/joran/JoranConfiguratorTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/joran/JoranConfiguratorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,7 +22,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import ch.qos.logback.access.AccessTestConstants;
+import ch.qos.logback.access.TeztConstants;
import ch.qos.logback.access.dummy.DummyAccessEventBuilder;
import ch.qos.logback.access.spi.AccessContext;
import ch.qos.logback.core.joran.spi.JoranException;
@@ -31,45 +31,47 @@ import ch.qos.logback.core.testUtil.StringListAppender;
public class JoranConfiguratorTest {
- AccessContext context = new AccessContext();
+ AccessContext context = new AccessContext();
- @Before
- public void setUp() throws Exception {
- }
+ @Before
+ public void setUp() throws Exception {
+ }
- @After
- public void tearDown() throws Exception {
- }
+ @After
+ public void tearDown() throws Exception {
+ }
- void configure(String file) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(context);
- jc.doConfigure(file);
- }
+ void configure(String file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(context);
+ jc.doConfigure(file);
+ }
- @Test
- public void smoke() throws Exception {
- configure(AccessTestConstants.TEST_DIR_PREFIX + "input/joran/smoke.xml");
+ @Test
+ public void smoke() throws Exception {
+ configure(TeztConstants.TEST_DIR_PREFIX + "input/joran/smoke.xml");
- ListAppender<IAccessEvent> listAppender = (ListAppender<IAccessEvent>) context.getAppender("LIST");
- IAccessEvent event = DummyAccessEventBuilder.buildNewAccessEvent();
- listAppender.doAppend(event);
+ ListAppender<IAccessEvent> listAppender = (ListAppender<IAccessEvent>) context
+ .getAppender("LIST");
+ IAccessEvent event = DummyAccessEventBuilder.buildNewAccessEvent();
+ listAppender.doAppend(event);
- assertEquals(1, listAppender.list.size());
+ assertEquals(1, listAppender.list.size());
- assertEquals(1, listAppender.list.size());
- IAccessEvent ae = listAppender.list.get(0);
- assertNotNull(ae);
- }
+ assertEquals(1, listAppender.list.size());
+ IAccessEvent ae = listAppender.list.get(0);
+ assertNotNull(ae);
+ }
- @Test
- public void defaultLayout() throws Exception {
- configure(AccessTestConstants.TEST_DIR_PREFIX + "input/joran/defaultLayout.xml");
- StringListAppender<IAccessEvent> listAppender = (StringListAppender<IAccessEvent>) context.getAppender("STR_LIST");
- IAccessEvent event = DummyAccessEventBuilder.buildNewAccessEvent();
- listAppender.doAppend(event);
- assertEquals(1, listAppender.strList.size());
- // the result contains a line separator at the end
- assertTrue(listAppender.strList.get(0).startsWith("testMethod"));
- }
+ @Test
+ public void defaultLayout() throws Exception {
+ configure(TeztConstants.TEST_DIR_PREFIX + "input/joran/defaultLayout.xml");
+ StringListAppender<IAccessEvent> listAppender = (StringListAppender<IAccessEvent>) context
+ .getAppender("STR_LIST");
+ IAccessEvent event = DummyAccessEventBuilder.buildNewAccessEvent();
+ listAppender.doAppend(event);
+ assertEquals(1, listAppender.strList.size());
+ // the result contains a line separator at the end
+ assertTrue(listAppender.strList.get(0).startsWith("testMethod"));
+ }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/joran/PackageTest.java b/logback-access/src/test/java/ch/qos/logback/access/joran/PackageTest.java
index d8731ba..229e44e 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/joran/PackageTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/joran/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,9 +17,9 @@ import org.junit.runner.RunWith;
import org.junit.runners.Suite;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
@RunWith(Suite.class)
- at Suite.SuiteClasses({ JoranConfiguratorTest.class, ConditionalTest.class })
+ at Suite.SuiteClasses({JoranConfiguratorTest.class, ConditionalTest.class})
public class PackageTest {
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/net/NOPOutputStream.java b/logback-access/src/test/java/ch/qos/logback/access/net/NOPOutputStream.java
index 314c2f7..7f956d2 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/net/NOPOutputStream.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/net/NOPOutputStream.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,10 +18,10 @@ import java.io.OutputStream;
public class NOPOutputStream extends OutputStream {
- @Override
- public void write(int b) throws IOException {
- // do nothing
+ @Override
+ public void write(int b) throws IOException {
+ // do nothing
- }
+ }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/net/PackageTest.java b/logback-access/src/test/java/ch/qos/logback/access/net/PackageTest.java
index c18c74d..fa85904 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/net/PackageTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/net/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,6 +20,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ URLEvaluatorTest.class })
+ at SuiteClasses({URLEvaluatorTest.class})
public class PackageTest extends TestCase {
}
\ No newline at end of file
diff --git a/logback-access/src/test/java/ch/qos/logback/access/net/SerializationPerfTest.java b/logback-access/src/test/java/ch/qos/logback/access/net/SerializationPerfTest.java
index 00cbb28..f9f8c2e 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/net/SerializationPerfTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/net/SerializationPerfTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,83 +22,87 @@ import ch.qos.logback.access.dummy.DummyAccessEventBuilder;
public class SerializationPerfTest extends TestCase {
- ObjectOutputStream oos;
+ ObjectOutputStream oos;
+
+ int loopNumber = 10000;
+ int resetFrequency = 100;
+ int pauseFrequency = 10;
+ long pauseLengthInMillis = 20;
+
- int loopNumber = 10000;
- int resetFrequency = 100;
- int pauseFrequency = 10;
- long pauseLengthInMillis = 20;
+ public void setUp() throws Exception {
+ super.setUp();
+ oos = new ObjectOutputStream(new NOPOutputStream());
- public void setUp() throws Exception {
- super.setUp();
- oos = new ObjectOutputStream(new NOPOutputStream());
+ }
- }
+ public void tearDown() throws Exception {
+ super.tearDown();
+ oos.close();
+ oos = null;
+ }
+
+ public void test1() throws Exception {
+ // first run for just in time compiler
+ int resetCounter = 0;
+ int pauseCounter = 0;
+ for (int i = 0; i < loopNumber; i++) {
+ try {
+ IAccessEvent ae = DummyAccessEventBuilder.buildNewAccessEvent();
+ //average time for the next method: 5000 nanos
+ ae.prepareForDeferredProcessing();
+ oos.writeObject(ae);
+ oos.flush();
+ if (++resetCounter >= resetFrequency) {
+ oos.reset();
+ resetCounter = 0;
+ }
+ if (++pauseCounter >= pauseFrequency) {
+ Thread.sleep(pauseLengthInMillis);
+ pauseCounter = 0;
+ }
- public void tearDown() throws Exception {
- super.tearDown();
- oos.close();
- oos = null;
+ } catch (IOException ex) {
+ fail(ex.getMessage());
+ }
}
-
- public void test1() throws Exception {
- // first run for just in time compiler
- int resetCounter = 0;
- int pauseCounter = 0;
- for (int i = 0; i < loopNumber; i++) {
- try {
- IAccessEvent ae = DummyAccessEventBuilder.buildNewAccessEvent();
- // average time for the next method: 5000 nanos
- ae.prepareForDeferredProcessing();
- oos.writeObject(ae);
- oos.flush();
- if (++resetCounter >= resetFrequency) {
- oos.reset();
- resetCounter = 0;
- }
- if (++pauseCounter >= pauseFrequency) {
- Thread.sleep(pauseLengthInMillis);
- pauseCounter = 0;
- }
-
- } catch (IOException ex) {
- fail(ex.getMessage());
- }
+
+ // second run
+ Long t1;
+ Long t2;
+ Long total = 0L;
+ resetCounter = 0;
+ pauseCounter = 0;
+ // System.out.println("Beginning mesured run");
+ for (int i = 0; i < loopNumber; i++) {
+ try {
+ IAccessEvent ae = DummyAccessEventBuilder.buildNewAccessEvent();
+ t1 = System.nanoTime();
+ //average length of the next method: 4000 nanos
+ ae.prepareForDeferredProcessing();
+ oos.writeObject(ae);
+ oos.flush();
+ t2 = System.nanoTime();
+ total += (t2 - t1);
+ if (++resetCounter >= resetFrequency) {
+ oos.reset();
+ resetCounter = 0;
}
-
- // second run
- Long t1;
- Long t2;
- Long total = 0L;
- resetCounter = 0;
- pauseCounter = 0;
- // System.out.println("Beginning mesured run");
- for (int i = 0; i < loopNumber; i++) {
- try {
- IAccessEvent ae = DummyAccessEventBuilder.buildNewAccessEvent();
- t1 = System.nanoTime();
- // average length of the next method: 4000 nanos
- ae.prepareForDeferredProcessing();
- oos.writeObject(ae);
- oos.flush();
- t2 = System.nanoTime();
- total += (t2 - t1);
- if (++resetCounter >= resetFrequency) {
- oos.reset();
- resetCounter = 0;
- }
- if (++pauseCounter >= pauseFrequency) {
- Thread.sleep(pauseLengthInMillis);
- pauseCounter = 0;
- }
- } catch (IOException ex) {
- fail(ex.getMessage());
- }
+ if (++pauseCounter >= pauseFrequency) {
+ Thread.sleep(pauseLengthInMillis);
+ pauseCounter = 0;
}
-
- total /= (1000);// nanos -> micros
- System.out.println("Loop done : average time = " + total / loopNumber + " microsecs after " + loopNumber + " writes.");
- // average time: 26-30 microsec = 0.030 millis
+ } catch (IOException ex) {
+ fail(ex.getMessage());
+ }
}
+
+ total /= (1000);//nanos -> micros
+ System.out.println("Loop done : average time = " + total / loopNumber
+ + " microsecs after " + loopNumber + " writes.");
+ //average time: 26-30 microsec = 0.030 millis
+ }
+
+
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/net/URLEvaluatorTest.java b/logback-access/src/test/java/ch/qos/logback/access/net/URLEvaluatorTest.java
index a7878bf..0ed1450 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/net/URLEvaluatorTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/net/URLEvaluatorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,56 +28,56 @@ import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.boolex.EvaluationException;
-public class URLEvaluatorTest {
+public class URLEvaluatorTest {
- final String expectedURL1 = "testUrl1";
- final String expectedURL2 = "testUrl2";
- Context context = new ContextBase();
- URLEvaluator evaluator;
- DummyRequest request;
- DummyResponse response;
- DummyServerAdapter serverAdapter;
-
- @Before
- public void setUp() throws Exception {
- evaluator = new URLEvaluator();
- evaluator.setContext(context);
- evaluator.addURL(expectedURL1);
- evaluator.start();
- request = new DummyRequest();
- response = new DummyResponse();
- serverAdapter = new DummyServerAdapter(request, response);
- }
-
- @After
- public void tearDown() throws Exception {
- evaluator.stop();
- evaluator = null;
- request = null;
- response = null;
- serverAdapter = null;
- context = null;
- }
-
- @Test
- public void testExpectFalse() throws EvaluationException {
- request.setRequestUri("test");
- IAccessEvent ae = new AccessEvent(request, response, serverAdapter);
- assertFalse(evaluator.evaluate(ae));
- }
-
- @Test
- public void testExpectTrue() throws EvaluationException {
- request.setRequestUri(expectedURL1);
- IAccessEvent ae = new AccessEvent(request, response, serverAdapter);
- assertTrue(evaluator.evaluate(ae));
- }
-
- @Test
- public void testExpectTrueMultiple() throws EvaluationException {
- evaluator.addURL(expectedURL2);
- request.setRequestUri(expectedURL2);
- IAccessEvent ae = new AccessEvent(request, response, serverAdapter);
- assertTrue(evaluator.evaluate(ae));
- }
+ final String expectedURL1 = "testUrl1";
+ final String expectedURL2 = "testUrl2";
+ Context context = new ContextBase();
+ URLEvaluator evaluator;
+ DummyRequest request;
+ DummyResponse response;
+ DummyServerAdapter serverAdapter;
+
+ @Before
+ public void setUp() throws Exception {
+ evaluator = new URLEvaluator();
+ evaluator.setContext(context);
+ evaluator.addURL(expectedURL1);
+ evaluator.start();
+ request = new DummyRequest();
+ response = new DummyResponse();
+ serverAdapter = new DummyServerAdapter(request, response);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ evaluator.stop();
+ evaluator = null;
+ request = null;
+ response = null;
+ serverAdapter = null;
+ context = null;
+ }
+
+ @Test
+ public void testExpectFalse() throws EvaluationException {
+ request.setRequestUri("test");
+ IAccessEvent ae = new AccessEvent(request, response, serverAdapter);
+ assertFalse(evaluator.evaluate(ae));
+ }
+
+ @Test
+ public void testExpectTrue() throws EvaluationException {
+ request.setRequestUri(expectedURL1);
+ IAccessEvent ae = new AccessEvent(request, response, serverAdapter);
+ assertTrue(evaluator.evaluate(ae));
+ }
+
+ @Test
+ public void testExpectTrueMultiple() throws EvaluationException {
+ evaluator.addURL(expectedURL2);
+ request.setRequestUri(expectedURL2);
+ IAccessEvent ae = new AccessEvent(request, response, serverAdapter);
+ assertTrue(evaluator.evaluate(ae));
+ }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/pattern/ConverterTest.java b/logback-access/src/test/java/ch/qos/logback/access/pattern/ConverterTest.java
index 682dd45..9cf6992 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/pattern/ConverterTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/pattern/ConverterTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,170 +30,171 @@ import ch.qos.logback.access.dummy.DummyResponse;
import ch.qos.logback.access.dummy.DummyServerAdapter;
import ch.qos.logback.access.spi.AccessEvent;
-public class ConverterTest {
-
- IAccessEvent event;
- DummyRequest request;
- DummyResponse response;
-
- @Before
- public void setUp() throws Exception {
- request = new DummyRequest();
- response = new DummyResponse();
- event = createEvent();
- }
-
- @After
- public void tearDown() throws Exception {
- event = null;
- request = null;
- response = null;
- }
-
- @Test
- public void testContentLengthConverter() {
- ContentLengthConverter converter = new ContentLengthConverter();
- converter.start();
- String result = converter.convert(event);
- assertEquals(Long.toString(event.getServerAdapter().getContentLength()), result);
- }
-
- @Test
- public void testDateConverter() {
- DateConverter converter = new DateConverter();
- converter.start();
- String result = converter.convert(event);
- assertEquals(converter.cachingDateFormatter.format(event.getTimeStamp()), result);
- }
-
- public void testLineLocalPortConverter() {
- LocalPortConverter converter = new LocalPortConverter();
- converter.start();
- String result = converter.convert(event);
- assertEquals(Integer.toString(request.getLocalPort()), result);
- }
-
- @Test
- public void testRemoteHostConverter() {
- RemoteHostConverter converter = new RemoteHostConverter();
- converter.start();
- String result = converter.convert(event);
- assertEquals(request.getRemoteHost(), result);
- }
-
- @Test
- public void testRemoteIPAddressConverter() {
- RemoteIPAddressConverter converter = new RemoteIPAddressConverter();
- converter.start();
- String result = converter.convert(event);
- assertEquals(request.getRemoteAddr(), result);
- }
-
- @Test
- public void testRemoteUserConverter() {
- RemoteUserConverter converter = new RemoteUserConverter();
- converter.start();
- String result = converter.convert(event);
- assertEquals(request.getRemoteUser(), result);
- }
-
- @Test
- public void testRequestAttributeConverter() {
- RequestAttributeConverter converter = new RequestAttributeConverter();
- List<String> optionList = new ArrayList<String>();
- optionList.add("testKey");
- converter.setOptionList(optionList);
- converter.start();
- String result = converter.convert(event);
- assertEquals(request.getAttribute("testKey"), result);
- }
-
- @Test
- public void testRequestCookieConverter() {
- RequestCookieConverter converter = new RequestCookieConverter();
- List<String> optionList = new ArrayList<String>();
- optionList.add("testName");
- converter.setOptionList(optionList);
- converter.start();
- String result = converter.convert(event);
- Cookie cookie = request.getCookies()[0];
- assertEquals(cookie.getValue(), result);
- }
-
- @Test
- public void testRequestHeaderConverter() {
- RequestHeaderConverter converter = new RequestHeaderConverter();
- List<String> optionList = new ArrayList<String>();
- optionList.add("headerName1");
- converter.setOptionList(optionList);
- converter.start();
- String result = converter.convert(event);
- assertEquals(request.getHeader("headerName1"), result);
- }
-
- @Test
- public void testRequestMethodConverter() {
- RequestMethodConverter converter = new RequestMethodConverter();
- converter.start();
- String result = converter.convert(event);
- assertEquals(request.getMethod(), result);
- }
-
- @Test
- public void testRequestProtocolConverter() {
- RequestProtocolConverter converter = new RequestProtocolConverter();
- converter.start();
- String result = converter.convert(event);
- assertEquals(request.getProtocol(), result);
- }
-
- @Test
- public void testRequestURIConverter() {
- RequestURIConverter converter = new RequestURIConverter();
- converter.start();
- String result = converter.convert(event);
- assertEquals(request.getRequestURI(), result);
- }
-
- @Test
- public void testRequestURLConverter() {
- RequestURLConverter converter = new RequestURLConverter();
- converter.start();
- String result = converter.convert(event);
- String expected = request.getMethod() + " " + request.getRequestURI() + " " + request.getProtocol();
- assertEquals(expected, result);
- }
-
- @Test
- public void testResponseHeaderConverter() {
- ResponseHeaderConverter converter = new ResponseHeaderConverter();
- List<String> optionList = new ArrayList<String>();
- optionList.add("headerName1");
- converter.setOptionList(optionList);
- converter.start();
- String result = converter.convert(event);
- assertEquals(request.getHeader("headerName1"), result);
- }
-
- @Test
- public void testServerNameConverter() {
- ServerNameConverter converter = new ServerNameConverter();
- converter.start();
- String result = converter.convert(event);
- assertEquals(request.getServerName(), result);
- }
-
- @Test
- public void testStatusCodeConverter() {
- StatusCodeConverter converter = new StatusCodeConverter();
- converter.start();
- String result = converter.convert(event);
- assertEquals(Integer.toString(event.getServerAdapter().getStatusCode()), result);
- }
-
- private IAccessEvent createEvent() {
- DummyServerAdapter dummyAdapter = new DummyServerAdapter(request, response);
- return new AccessEvent(request, response, dummyAdapter);
- }
+public class ConverterTest {
+
+ IAccessEvent event;
+ DummyRequest request;
+ DummyResponse response;
+
+ @Before
+ public void setUp() throws Exception {
+ request = new DummyRequest();
+ response = new DummyResponse();
+ event = createEvent();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ event = null;
+ request = null;
+ response = null;
+ }
+
+ @Test
+ public void testContentLengthConverter() {
+ ContentLengthConverter converter = new ContentLengthConverter();
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(Long.toString(event.getServerAdapter().getContentLength()), result);
+ }
+
+ @Test
+ public void testDateConverter() {
+ DateConverter converter = new DateConverter();
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(converter.cachingDateFormatter.format(event.getTimeStamp()), result);
+ }
+
+ public void testLineLocalPortConverter() {
+ LocalPortConverter converter = new LocalPortConverter();
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(Integer.toString(request.getLocalPort()), result);
+ }
+
+ @Test
+ public void testRemoteHostConverter() {
+ RemoteHostConverter converter = new RemoteHostConverter();
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(request.getRemoteHost(), result);
+ }
+
+ @Test
+ public void testRemoteIPAddressConverter() {
+ RemoteIPAddressConverter converter = new RemoteIPAddressConverter();
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(request.getRemoteAddr(), result);
+ }
+
+ @Test
+ public void testRemoteUserConverter() {
+ RemoteUserConverter converter = new RemoteUserConverter();
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(request.getRemoteUser(), result);
+ }
+
+ @Test
+ public void testRequestAttributeConverter() {
+ RequestAttributeConverter converter = new RequestAttributeConverter();
+ List<String> optionList = new ArrayList<String>();
+ optionList.add("testKey");
+ converter.setOptionList(optionList);
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(request.getAttribute("testKey"), result);
+ }
+
+ @Test
+ public void testRequestCookieConverter() {
+ RequestCookieConverter converter = new RequestCookieConverter();
+ List<String> optionList = new ArrayList<String>();
+ optionList.add("testName");
+ converter.setOptionList(optionList);
+ converter.start();
+ String result = converter.convert(event);
+ Cookie cookie = request.getCookies()[0];
+ assertEquals(cookie.getValue(), result);
+ }
+
+ @Test
+ public void testRequestHeaderConverter() {
+ RequestHeaderConverter converter = new RequestHeaderConverter();
+ List<String> optionList = new ArrayList<String>();
+ optionList.add("headerName1");
+ converter.setOptionList(optionList);
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(request.getHeader("headerName1"), result);
+ }
+
+ @Test
+ public void testRequestMethodConverter() {
+ RequestMethodConverter converter = new RequestMethodConverter();
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(request.getMethod(), result);
+ }
+
+ @Test
+ public void testRequestProtocolConverter() {
+ RequestProtocolConverter converter = new RequestProtocolConverter();
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(request.getProtocol(), result);
+ }
+
+ @Test
+ public void testRequestURIConverter() {
+ RequestURIConverter converter = new RequestURIConverter();
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(request.getRequestURI(), result);
+ }
+
+ @Test
+ public void testRequestURLConverter() {
+ RequestURLConverter converter = new RequestURLConverter();
+ converter.start();
+ String result = converter.convert(event);
+ String expected = request.getMethod() + " " + request.getRequestURI() + " "
+ + request.getProtocol();
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void testResponseHeaderConverter() {
+ ResponseHeaderConverter converter = new ResponseHeaderConverter();
+ List<String> optionList = new ArrayList<String>();
+ optionList.add("headerName1");
+ converter.setOptionList(optionList);
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(request.getHeader("headerName1"), result);
+ }
+
+ @Test
+ public void testServerNameConverter() {
+ ServerNameConverter converter = new ServerNameConverter();
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(request.getServerName(), result);
+ }
+
+ @Test
+ public void testStatusCodeConverter() {
+ StatusCodeConverter converter = new StatusCodeConverter();
+ converter.start();
+ String result = converter.convert(event);
+ assertEquals(Integer.toString(event.getServerAdapter().getStatusCode()), result);
+ }
+
+ private IAccessEvent createEvent() {
+ DummyServerAdapter dummyAdapter = new DummyServerAdapter(request, response);
+ return new AccessEvent(request, response, dummyAdapter);
+ }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/pattern/PackageTest.java b/logback-access/src/test/java/ch/qos/logback/access/pattern/PackageTest.java
index 7468267..71bff21 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/pattern/PackageTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/pattern/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,7 +18,8 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ ConverterTest.class })
-public class PackageTest {
+ at SuiteClasses({ConverterTest.class})
+public class PackageTest {
+
}
\ No newline at end of file
diff --git a/logback-access/src/test/java/ch/qos/logback/access/servlet/PackageTest.java b/logback-access/src/test/java/ch/qos/logback/access/servlet/PackageTest.java
index f63e37a..4c8acbd 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/servlet/PackageTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/servlet/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,6 +19,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ TeeFilterTest.class })
+ at SuiteClasses({TeeFilterTest.class})
public class PackageTest extends TestCase {
}
\ No newline at end of file
diff --git a/logback-access/src/test/java/ch/qos/logback/access/servlet/TeeFilterTest.java b/logback-access/src/test/java/ch/qos/logback/access/servlet/TeeFilterTest.java
index aa6316a..8bcac42 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/servlet/TeeFilterTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/servlet/TeeFilterTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,12 +23,13 @@ import static org.junit.Assert.assertEquals;
public class TeeFilterTest {
+
@Test
public void extractNameList() {
- assertEquals(Arrays.asList(new String[] { "a" }), TeeFilter.extractNameList("a"));
- assertEquals(Arrays.asList(new String[] { "a", "b" }), TeeFilter.extractNameList("a, b"));
- assertEquals(Arrays.asList(new String[] { "a", "b" }), TeeFilter.extractNameList("a; b"));
- assertEquals(Arrays.asList(new String[] { "a", "b", "c" }), TeeFilter.extractNameList("a; b, c"));
+ assertEquals(Arrays.asList(new String[]{"a"}), TeeFilter.extractNameList("a"));
+ assertEquals(Arrays.asList(new String[]{"a", "b"}), TeeFilter.extractNameList("a, b"));
+ assertEquals(Arrays.asList(new String[]{"a", "b"}), TeeFilter.extractNameList("a; b"));
+ assertEquals(Arrays.asList(new String[]{"a", "b", "c"}), TeeFilter.extractNameList("a; b, c"));
}
@Test
@@ -45,6 +46,7 @@ public class TeeFilterTest {
assertFalse(TeeFilter.computeActivation("a", "b, c", null));
}
+
@Test
public void withExcludesOnly() {
assertFalse(TeeFilter.computeActivation("a", null, "a"));
@@ -53,6 +55,7 @@ public class TeeFilterTest {
assertTrue(TeeFilter.computeActivation("a", null, "b, c"));
}
+
@Test
public void withIncludesAndExcludes() {
assertFalse(TeeFilter.computeActivation("a", "a", "a"));
diff --git a/logback-access/src/test/java/ch/qos/logback/access/servlet/TeeHttpServletResponseTest.java b/logback-access/src/test/java/ch/qos/logback/access/servlet/TeeHttpServletResponseTest.java
deleted file mode 100644
index fb8e958..0000000
--- a/logback-access/src/test/java/ch/qos/logback/access/servlet/TeeHttpServletResponseTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.access.servlet;
-
-import ch.qos.logback.access.dummy.DummyResponse;
-import ch.qos.logback.access.dummy.DummyServletOutputStream;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.Collection;
-
-import static org.junit.Assert.assertArrayEquals;
-
- at RunWith(Parameterized.class)
-public class TeeHttpServletResponseTest {
-
- String characterEncoding;
- String testString;
- byte[] expectedBytes;
-
- public TeeHttpServletResponseTest(String characterEncoding, String testString, byte[] expectedBytes) {
- this.characterEncoding = characterEncoding;
- this.testString = testString;
- this.expectedBytes = expectedBytes;
- }
-
- @Parameterized.Parameters
- public static Collection<?> inputValues() {
- return Arrays.asList(new Object[][] {
- { "utf-8", "Gülcü", new byte[] { (byte) 0x47, (byte) 0xC3, (byte) 0xBC, (byte) 0x6C, (byte) 0x63, (byte) 0xC3, (byte) 0xBC } },
- { "iso-8859-1", "Gülcü", new byte[] { (byte) 0x47, (byte) 0xFC, (byte) 0x6C, (byte) 0x63, (byte) 0xFC } } });
- }
-
- @Test
- public void testWriterEncoding() throws IOException {
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-
- DummyResponse dummyResponse = new DummyResponse();
- dummyResponse.setCharacterEncoding(characterEncoding);
- dummyResponse.setOutputStream(new DummyServletOutputStream(byteArrayOutputStream));
-
- TeeHttpServletResponse teeServletResponse = new TeeHttpServletResponse(dummyResponse);
-
- PrintWriter writer = teeServletResponse.getWriter();
- writer.write(testString);
- writer.flush();
-
- assertArrayEquals(expectedBytes, byteArrayOutputStream.toByteArray());
- }
-
-}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/sift/PackageTest.java b/logback-access/src/test/java/ch/qos/logback/access/sift/PackageTest.java
index 3a91138..99e6af0 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/sift/PackageTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/sift/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,7 +18,7 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ SiftingAppenderTest.class })
-public class PackageTest {
+ at SuiteClasses({SiftingAppenderTest.class})
+public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-access/src/test/java/ch/qos/logback/access/sift/SiftingAppenderTest.java b/logback-access/src/test/java/ch/qos/logback/access/sift/SiftingAppenderTest.java
index fccb77b..31fd02e 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/sift/SiftingAppenderTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/sift/SiftingAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -33,59 +33,61 @@ import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.util.StatusPrinter;
public class SiftingAppenderTest {
- static final String PREFIX = "src/test/input/jetty/";
- static int RANDOM_SERVER_PORT = RandomUtil.getRandomServerPort();
+ static final String PREFIX = "src/test/input/jetty/";
+ static int RANDOM_SERVER_PORT = RandomUtil.getRandomServerPort();
- JettyFixtureBase jettyFixture;
- RequestLogImpl rli = new RequestLogImpl();
+ JettyFixtureBase jettyFixture;
+ RequestLogImpl rli = new RequestLogImpl();
- @Before
- public void startServer() throws Exception {
- jettyFixture = new JettyFixtureBase(rli, RANDOM_SERVER_PORT);
- }
+ @Before
+ public void startServer() throws Exception {
+ jettyFixture = new JettyFixtureBase(rli, RANDOM_SERVER_PORT);
+ }
- @After
- public void stopServer() throws Exception {
- if (jettyFixture != null) {
- jettyFixture.stop();
- }
+ @After
+ public void stopServer() throws Exception {
+ if (jettyFixture != null) {
+ jettyFixture.stop();
}
+ }
- @Test
- public void invokingDifferentPathShouldBeSiftedAccordingly() throws Exception {
- rli.setFileName(PREFIX + "sifting.xml");
- jettyFixture.start();
- invokeServer("/");
- invokeServer("/x");
- invokeServer("/x");
- invokeServer("/y");
+ @Test
+ public void invokingDifferentPathShouldBeSiftedAccordingly() throws Exception {
+ rli.setFileName(PREFIX + "sifting.xml");
+ jettyFixture.start();
+ invokeServer("/");
+ invokeServer("/x");
+ invokeServer("/x");
+ invokeServer("/y");
- StatusPrinter.print(rli);
- SiftingAppender siftingAppender = (SiftingAppender) rli.getAppender("SIFTING");
- Set<String> keySet = siftingAppender.getAppenderTracker().allKeys();
- assertEquals(3, keySet.size());
+ StatusPrinter.print(rli);
+ SiftingAppender siftingAppender = (SiftingAppender) rli
+ .getAppender("SIFTING");
+ Set<String> keySet = siftingAppender.getAppenderTracker().allKeys();
+ assertEquals(3, keySet.size());
- Set<String> witnessSet = new LinkedHashSet<String>();
- witnessSet.add("NA");
- witnessSet.add("x");
- witnessSet.add("y");
- assertEquals(witnessSet, keySet);
+ Set<String> witnessSet = new LinkedHashSet<String>();
+ witnessSet.add("NA");
+ witnessSet.add("x");
+ witnessSet.add("y");
+ assertEquals(witnessSet, keySet);
- check(siftingAppender, "NA", 1);
- check(siftingAppender, "x", 2);
- check(siftingAppender, "y", 1);
- }
+ check(siftingAppender, "NA", 1);
+ check(siftingAppender, "x", 2);
+ check(siftingAppender, "y", 1);
+ }
- private void check(SiftingAppender siftingAppender, String key, int expectedCount) {
- ListAppender<IAccessEvent> listAppender = (ListAppender<IAccessEvent>) siftingAppender.getAppenderTracker().find(key);
- assertEquals(expectedCount, listAppender.list.size());
- }
+ private void check(SiftingAppender siftingAppender, String key, int expectedCount) {
+ ListAppender<IAccessEvent> listAppender = (ListAppender<IAccessEvent>) siftingAppender
+ .getAppenderTracker().find(key);
+ assertEquals(expectedCount, listAppender.list.size());
+ }
- void invokeServer(String uri) throws Exception {
- URL url = new URL("http://localhost:" + RANDOM_SERVER_PORT + uri);
- HttpURLConnection connection = (HttpURLConnection) url.openConnection();
- connection.setDoInput(true);
- Util.readToString(connection.getInputStream());
- Thread.sleep(10);
- }
+ void invokeServer(String uri) throws Exception {
+ URL url = new URL("http://localhost:" + RANDOM_SERVER_PORT + uri);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setDoInput(true);
+ Util.readToString(connection.getInputStream());
+ Thread.sleep(10);
+ }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/spi/AccessEventSerializationTest.java b/logback-access/src/test/java/ch/qos/logback/access/spi/AccessEventSerializationTest.java
index 817b152..be4d257 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/spi/AccessEventSerializationTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/spi/AccessEventSerializationTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,73 +13,64 @@
*/
package ch.qos.logback.access.spi;
-import ch.qos.logback.access.dummy.DummyAccessEventBuilder;
-import ch.qos.logback.access.dummy.DummyRequest;
-import ch.qos.logback.access.dummy.DummyResponse;
-import ch.qos.logback.access.dummy.DummyServerAdapter;
-import org.junit.Test;
-
-import java.io.*;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-public class AccessEventSerializationTest {
-
- private Object buildSerializedAccessEvent() throws IOException, ClassNotFoundException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- IAccessEvent ae = DummyAccessEventBuilder.buildNewAccessEvent();
- // average time for the next method: 5000 nanos
- ae.prepareForDeferredProcessing();
- oos.writeObject(ae);
- oos.flush();
-
- ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
- ObjectInputStream ois = new ObjectInputStream(bais);
-
- return ois.readObject();
- }
-
- @Test
- public void testSerialization() throws IOException, ClassNotFoundException {
- Object o = buildSerializedAccessEvent();
- assertNotNull(o);
- IAccessEvent aeBack = (IAccessEvent) o;
-
- assertEquals(DummyResponse.DUMMY_DEFAULT_HDEADER_MAP, aeBack.getResponseHeaderMap());
- assertEquals(DummyResponse.DUMMY_DEFAULT_HDEADER_MAP.get("x"), aeBack.getResponseHeader("x"));
- assertEquals(DummyResponse.DUMMY_DEFAULT_HDEADER_MAP.get("headerName1"), aeBack.getResponseHeader("headerName1"));
- assertEquals(DummyResponse.DUMMY_DEFAULT_HDEADER_MAP.size(), aeBack.getResponseHeaderNameList().size());
- assertEquals(DummyResponse.DUMMY_DEFAULT_CONTENT_COUNT, aeBack.getContentLength());
- assertEquals(DummyResponse.DUMMY_DEFAULT_STATUS, aeBack.getStatusCode());
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
- assertEquals(DummyRequest.DUMMY_CONTENT_STRING, aeBack.getRequestContent());
-
- assertEquals(DummyRequest.DUMMY_RESPONSE_CONTENT_STRING, aeBack.getResponseContent());
-
- assertEquals(DummyRequest.DUMMY_DEFAULT_ATTR_MAP.get("testKey"), aeBack.getAttribute("testKey"));
- }
-
- // Web containers may (and will) recycle requests objects. So we must make sure that after
- // we prepared an event for deferred processing it won't be using data from the original
- // HttpRequest object which may at that time represent another request
- @Test
- public void testAttributesAreNotTakenFromRecycledRequestWhenProcessingDeferred() {
-
- DummyRequest request = new DummyRequest();
- DummyResponse response = new DummyResponse();
- DummyServerAdapter adapter = new DummyServerAdapter(request, response);
-
- IAccessEvent event = new AccessEvent(request, response, adapter);
-
- request.setAttribute("testKey", "ORIGINAL");
+import org.junit.Test;
- event.prepareForDeferredProcessing();
+import ch.qos.logback.access.dummy.DummyAccessEventBuilder;
+import ch.qos.logback.access.dummy.DummyRequest;
+import ch.qos.logback.access.dummy.DummyResponse;
- request.setAttribute("testKey", "NEW");
+public class AccessEventSerializationTest {
+
+ private Object buildSerializedAccessEvent() throws IOException,
+ ClassNotFoundException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ IAccessEvent ae = DummyAccessEventBuilder.buildNewAccessEvent();
+ // average time for the next method: 5000 nanos
+ ae.prepareForDeferredProcessing();
+ oos.writeObject(ae);
+ oos.flush();
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(bais);
+
+ return ois.readObject();
+ }
+
+ @Test
+ public void testSerialization() throws IOException, ClassNotFoundException {
+ Object o = buildSerializedAccessEvent();
+ assertNotNull(o);
+ IAccessEvent aeBack = (IAccessEvent) o;
+
+
+ assertEquals(DummyResponse.DUMMY_DEFAULT_HDEADER_MAP, aeBack
+ .getResponseHeaderMap());
+ assertEquals(DummyResponse.DUMMY_DEFAULT_HDEADER_MAP.get("x"), aeBack
+ .getResponseHeader("x"));
+ assertEquals(DummyResponse.DUMMY_DEFAULT_HDEADER_MAP.get("headerName1"),
+ aeBack.getResponseHeader("headerName1"));
+ assertEquals(DummyResponse.DUMMY_DEFAULT_HDEADER_MAP.size(), aeBack
+ .getResponseHeaderNameList().size());
+ assertEquals(DummyResponse.DUMMY_DEFAULT_CONTENT_COUNT, aeBack
+ .getContentLength());
+ assertEquals(DummyResponse.DUMMY_DEFAULT_STATUS, aeBack.getStatusCode());
+
+ assertEquals(DummyRequest.DUMMY_CONTENT_STRING, aeBack
+ .getRequestContent());
+
+ assertEquals(DummyRequest.DUMMY_RESPONSE_CONTENT_STRING, aeBack
+ .getResponseContent());
+
+ }
- // Event should capture the original value
- assertEquals("ORIGINAL", event.getAttribute("testKey"));
- }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/spi/PackageTest.java b/logback-access/src/test/java/ch/qos/logback/access/spi/PackageTest.java
index d7962f7..f9ea0d8 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/spi/PackageTest.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/spi/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,6 +20,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ AccessEventSerializationTest.class })
+ at SuiteClasses({AccessEventSerializationTest.class})
public class PackageTest extends TestCase {
}
\ No newline at end of file
diff --git a/logback-access/src/test/java/ch/qos/logback/access/testUtil/NotifyingListAppender.java b/logback-access/src/test/java/ch/qos/logback/access/testUtil/NotifyingListAppender.java
index 6c998c7..e296995 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/testUtil/NotifyingListAppender.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/testUtil/NotifyingListAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,16 +13,20 @@
*/
package ch.qos.logback.access.testUtil;
-import java.util.concurrent.LinkedBlockingQueue;
+import java.util.ArrayList;
+import java.util.List;
import ch.qos.logback.access.spi.IAccessEvent;
import ch.qos.logback.core.AppenderBase;
public class NotifyingListAppender extends AppenderBase<IAccessEvent> {
- public final LinkedBlockingQueue<IAccessEvent> list = new LinkedBlockingQueue<IAccessEvent>();
-
- protected void append(IAccessEvent e) {
- list.add(e);
+ public List<IAccessEvent> list = new ArrayList<IAccessEvent>();
+
+ protected void append(IAccessEvent e) {
+ list.add(e);
+ synchronized (this) {
+ this.notify();
}
+ }
}
diff --git a/logback-access/src/test/java/ch/qos/logback/access/tomcat/LogbackValveTest.java b/logback-access/src/test/java/ch/qos/logback/access/tomcat/LogbackValveTest.java
deleted file mode 100644
index ce16c4b..0000000
--- a/logback-access/src/test/java/ch/qos/logback/access/tomcat/LogbackValveTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.access.tomcat;
-
-import static org.junit.Assert.*;
-
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.core.ContainerBase;
-import org.junit.After;
-import org.junit.Test;
-
-import ch.qos.logback.access.AccessTestConstants;
-import ch.qos.logback.core.status.Status;
-import ch.qos.logback.core.status.StatusChecker;
-
-public class LogbackValveTest {
-
- LogbackValve valve = new LogbackValve();
- StatusChecker checker = new StatusChecker(valve);
-
- @After
- public void tearDown() {
- System.clearProperty(LogbackValve.CATALINA_BASE_KEY);
- System.clearProperty(LogbackValve.CATALINA_HOME_KEY);
- }
-
- @Test
- public void nonExistingConfigFileShouldResultInWarning() throws LifecycleException {
- final String resourceName = "logback-test2-config.xml";
- setupValve(resourceName);
- valve.start();
- checker.assertContainsMatch(Status.WARN, "Failed to find valid");
- }
-
- @Test
- public void fileUnderCatalinaBaseShouldBeFound() throws LifecycleException {
- System.setProperty(LogbackValve.CATALINA_BASE_KEY, AccessTestConstants.JORAN_INPUT_PREFIX + "tomcat/");
- final String fileName = "logback-access.xml";
- setupValve(fileName);
- valve.start();
- checker.assertContainsMatch("Found configuration file");
- checker.assertContainsMatch("Done configuring");
- checker.assertIsErrorFree();
- }
-
- @Test
- public void fileUnderCatalinaHomeShouldBeFound() throws LifecycleException {
- System.setProperty(LogbackValve.CATALINA_HOME_KEY, AccessTestConstants.JORAN_INPUT_PREFIX + "tomcat/");
- final String fileName = "logback-access.xml";
- setupValve(fileName);
- valve.start();
- checker.assertContainsMatch("Found configuration file");
- checker.assertContainsMatch("Done configuring");
- checker.assertIsErrorFree();
- }
-
- @Test
- public void resourceShouldBeFound() throws LifecycleException {
- final String fileName = "logback-asResource.xml";
- setupValve(fileName);
- valve.start();
- checker.assertContainsMatch("Found ." + fileName + ". as a resource.");
- checker.assertContainsMatch("Done configuring");
- checker.assertIsErrorFree();
- }
-
- @Test
- public void executorServiceShouldBeNotNull() throws LifecycleException {
- final String fileName = "logback-asResource.xml";
- setupValve(fileName);
- valve.start();
- assertNotNull(valve.getScheduledExecutorService());
-
- }
-
- private void setupValve(final String resourceName) {
- valve.setFilename(resourceName);
- valve.setName("test");
- valve.setContainer(new ContainerBase() {
- @Override
- protected String getObjectNameKeyProperties() {
- return "getObjectNameKeyProperties-test";
- }
- });
- }
-}
\ No newline at end of file
diff --git a/logback-access/src/test/resources/logback-asResource.xml b/logback-access/src/test/resources/logback-asResource.xml
deleted file mode 100644
index 3cbd745..0000000
--- a/logback-access/src/test/resources/logback-asResource.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<configuration>
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%h %l %u %user %date "%r" %s %b</pattern>
- </encoder>
- </appender>
-
- <appender-ref ref="STDOUT" />
-</configuration>
\ No newline at end of file
diff --git a/logback-classic/osgi-build.xml b/logback-classic/osgi-build.xml
index 5c5d912..091cd45 100644
--- a/logback-classic/osgi-build.xml
+++ b/logback-classic/osgi-build.xml
@@ -11,23 +11,14 @@
define the currentVersion property on the command line, e.g.:
ant -DcurrentVersion=1.5.4-SNAPSHOT
-
- See test results in target/unit-reports
-->
<!-- We skip the test if the maven.test.skip system property is set
to true. See also http://jira.qos.ch/browse/LBCLASSIC-191 -->
-<!--
- <property name="slf4j.version" value="1.7.20"/>
- <property name="org.slf4j:slf4j-api:jar" value="c:/Users/ceki/.m2/repository/org/slf4j/slf4j-api/1.7.20/slf4j-api-1.7.20.jar"/>
-
- <property name="org.apache.felix:org.apache.felix.main:jar" value="c:/Users/ceki/.m2/repository/org/apache/felix/org.apache.felix.main/2.0.2/org.apache.felix.main-2.0.2.jar" />
--->
-
<echo message="compile classpath: ${currentVersion}" />
- <echo message="slfj4: ${org.slf4j:slf4j-api:jar}" />
- <echo message="felix: ${org.apache.felix:org.apache.felix.main:jar}" />
+ <echo message="slfj4: ${org.slf4j:slf4j-api:jar}" />
+ <echo message="felix ${org.apache.felix:org.apache.felix.main:jar}" />
@@ -36,7 +27,7 @@
<echo message="===============================" />
- <echo message="basedir:${basedir}" />
+ <echo message="basedir: ${basedir}" />
<echo message="===============================" />
<path id="basicCP">
@@ -51,23 +42,18 @@
</path >
<target name="copySLF4J_JAR">
- <echo>Making lib/ folder in case it does not already exist.</echo>
- <mkdir dir="lib/"/>
<echo>Copying ${org.slf4j:slf4j-api:jar} to lib/</echo>
- <!-- sneak in a clean up procedure of the ../logback-examples/lib/ folder-->
- <delete quiet="true">
+ <delete>
<fileset dir="../logback-examples/lib/" includes="slf4j-*SNAPSHOT.jar" />
</delete>
<copy file="${org.slf4j:slf4j-api:jar}" todir="lib/" />
</target>
<target name="init" depends="copySLF4J_JAR">
- <echo message="in init"/>
<mkdir dir="target/unit-reports" />
</target>
<target name="createIBundle" unless="maven.test.skip">
- <echo message="Making folder ${bundlesDir}"/>
<mkdir dir="${bundlesDir}"/>
<jar destFile="${iBundleJar}"
manifest="src/IBUNDLE-META-INF/MANIFEST.MF"
@@ -96,7 +82,7 @@
<!-- for some reason if mvn is invoked from the parent directory, junit gets
- invoked from the parent dir, which messes up theseg tests. Hence, the
+ invoked from the parent dir, which messes up theses tests. Hence, the
fork="yes" dir="${basedir}" -->
<target name="logback" unless="maven.test.skip">
diff --git a/logback-classic/pom.xml b/logback-classic/pom.xml
index 60d9570..dbeebbb 100644
--- a/logback-classic/pom.xml
+++ b/logback-classic/pom.xml
@@ -1,13 +1,13 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-parent</artifactId>
- <version>1.1.9</version>
+ <version>1.1.2</version>
</parent>
<artifactId>logback-classic</artifactId>
@@ -15,24 +15,40 @@
<name>Logback Classic Module</name>
<description>logback-classic module</description>
+ <url>http://logback.qos.ch</url>
+
+ <licenses>
+ <license>
+ <name>Eclipse Public License - v 1.0</name>
+ <url>http://www.eclipse.org/legal/epl-v10.html</url>
+ </license>
+
+ <license>
+ <name>GNU Lesser General Public License</name>
+ <url>http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</url>
+ </license>
+ </licenses>
+
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<scope>compile</scope>
</dependency>
+
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
- <version>${slf4j.version}</version>
<scope>compile</scope>
</dependency>
+
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-ext</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
@@ -40,100 +56,110 @@
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
- <!-- Must be after log4j-over-slf4j:
- * we want to use the classes from log4j-over-slf4j (so it must come first);
- * we want to use log4j.dtd from log4j. -->
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.17</version>
- <scope>test</scope>
- </dependency>
+
+
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
+ <version>5.1.9</version>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
+
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
+
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
+
+
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>integration</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_1.1_spec</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
+
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
+
<dependency>
<groupId>com.icegreen</groupId>
<artifactId>greenmail</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>org.subethamail</groupId>
<artifactId>subethasmtp</artifactId>
@@ -146,73 +172,61 @@
</exclusion>
</exclusions>
</dependency>
+
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.main</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
+
</dependencies>
+
<build>
+
<resources>
<resource>
<directory>src/main/groovy</directory>
<includes>
<include>**/EvaluatorTemplate.groovy</include>
- <include>**/*.groovy</include>
</includes>
</resource>
- <resource>
- <directory>src/main/resources</directory>
- </resource>
</resources>
+
<plugins>
-
<plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <compilerId>groovy-eclipse-compiler</compilerId>
- </configuration>
+ <groupId>org.codehaus.gmaven</groupId>
+ <artifactId>gmaven-plugin</artifactId>
+ <version>1.4</version>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
- <artifactId>groovy-eclipse-compiler</artifactId>
- <version>2.9.1-01</version>
- </dependency>
- <!-- for 2.8.0-01 and later you must have an explicit dependency on groovy-eclipse-batch -->
- <dependency>
- <groupId>org.codehaus.groovy</groupId>
- <artifactId>groovy-eclipse-batch</artifactId>
- <version>2.3.7-01</version>
+ <artifactId>groovy-all</artifactId>
+ <version>${groovy.version}</version>
</dependency>
</dependencies>
- </plugin>
+ <executions>
+ <execution>
+ <configuration>
+ <providerSelection>1.8</providerSelection>
+ </configuration>
+ <goals>
+ <goal>generateStubs</goal>
+ <goal>compile</goal>
+ <goal>generateTestStubs</goal>
+ <goal>testCompile</goal>
+ </goals>
+ </execution>
+ </executions>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-eclipse-plugin</artifactId>
- <version>2.8</version>
- <configuration>
- <additionalProjectnatures>
- <projectnature>org.eclipse.jdt.groovy.core.groovyNature</projectnature>
- </additionalProjectnatures>
- <!-- Source includes is necessary to allow groovy files in the java
- folder, else eclipse will throw a filtering exception -->
- <sourceIncludes>
- <sourceInclude>**/*.groovy</sourceInclude>
- </sourceIncludes>
- <!-- Download sources will make maven download and attach source files
- where available -->
- <downloadSources>true</downloadSources>
- <downloadJavadocs>true</downloadJavadocs>
- </configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
+ <version>${maven-jar-plugin.version}</version>
<configuration>
<archive>
<manifestFile>
@@ -232,10 +246,10 @@
</executions>
</plugin>
+
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
- <version>1.7</version>
+ <version>1.4</version>
<dependencies>
<dependency>
<groupId>org.apache.ant</groupId>
@@ -247,6 +261,7 @@
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
+
</dependencies>
<executions>
@@ -254,12 +269,12 @@
<id>ant-osgi-test</id>
<phase>package</phase>
<configuration>
- <target>
+ <tasks>
<property name="currentVersion" value="${project.version}"/>
<property name="slf4j.version" value="${slf4j.version}"/>
<property name="basedir" value="${basedir}"/>
<ant antfile="${basedir}/osgi-build.xml"/>
- </target>
+ </tasks>
</configuration>
<goals>
<goal>run</goal>
@@ -270,10 +285,10 @@
<id>ant-integration-test</id>
<phase>package</phase>
<configuration>
- <target>
+ <tasks>
<property name="slf4j.version" value="${slf4j.version}"/>
<ant antfile="${basedir}/integration.xml"/>
- </target>
+ </tasks>
</configuration>
<goals>
<goal>run</goal>
@@ -285,11 +300,11 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
+ <version>${maven-surefire-plugin.version}</version>
<configuration>
<!-- once, never, pertest, always -->
- <!--<forkMode>once</forkMode>-->
- <forkCount>1C</forkCount>
- <reuseForks>false</reuseForks>
+ <forkMode>once</forkMode>
+ <!--<parallel>classes</parallel>-->
<reportFormat>plain</reportFormat>
<trimStackTrace>false</trimStackTrace>
<excludes>
@@ -304,10 +319,10 @@
</configuration>
</plugin>
+
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>2.5.3</version>
<extensions>true</extensions>
<executions>
<execution>
@@ -325,12 +340,12 @@
file packages as classes are created via IOC (xml
config files). They won't be found by Bnd's analysis
of java code. -->
+
<Import-Package>
sun.reflect;resolution:=optional,
javax.*;resolution:=optional,
org.xml.*;resolution:=optional,
org.slf4j,
- org.slf4j.event,
ch.qos.logback.core.rolling,
ch.qos.logback.core.rolling.helper,
ch.qos.logback.core.util,
@@ -339,15 +354,13 @@
groovy.lang.*;resolution:=optional,
*
</Import-Package>
- <Bundle-RequiredExecutionEnvironment>JavaSE-1.6</Bundle-RequiredExecutionEnvironment>
+
+ <Bundle-RequiredExecutionEnvironment>J2SE-1.5</Bundle-RequiredExecutionEnvironment>
</instructions>
</configuration>
</plugin>
+
</plugins>
- <pluginManagement>
- <plugins>
- </plugins>
- </pluginManagement>
</build>
<profiles>
@@ -371,6 +384,7 @@
<scope>test</scope>
</dependency>
</dependencies>
+
</profile>
<profile>
diff --git a/logback-classic/src/IBUNDLE-META-INF/MANIFEST.MF b/logback-classic/src/IBUNDLE-META-INF/MANIFEST.MF
index 9adbbbf..875866d 100644
--- a/logback-classic/src/IBUNDLE-META-INF/MANIFEST.MF
+++ b/logback-classic/src/IBUNDLE-META-INF/MANIFEST.MF
@@ -12,11 +12,4 @@ Bundle-SymbolicName: iBundle
Bundle-Name: abundle
Bundle-RequiredExecutionEnvironment: J2SE-1.3
Export-Package: apack
-Import-Package: org.osgi.framework,
- org.slf4j;version=1.7,
- org.slf4j.event;
- ch.qos.logback.core,
- ch.qos.logback.core.joran.spi,
- ch.qos.logback.core.util,
- ch.qos.logback.classic,
- ch.qos.logback.classic.joran
+Import-Package: org.osgi.framework, org.slf4j;version=1.6, ch.qos.logback.core, ch.qos.logback.core.joran.spi, ch.qos.logback.core.util, ch.qos.logback.classic, ch.qos.logback.classic.joran
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/boolex/EvaluatorTemplate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/boolex/EvaluatorTemplate.groovy
index d611b08..beaec4b 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/boolex/EvaluatorTemplate.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/boolex/EvaluatorTemplate.groovy
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy
index 07fd075..5f24a53 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -12,37 +12,18 @@
* as published by the Free Software Foundation.
*/
package ch.qos.logback.classic.gaffer
-import java.util.List;
-import java.util.Map;
-
import ch.qos.logback.core.Appender
-import ch.qos.logback.core.spi.AppenderAttachable;
-
/**
* @author Ceki Gücü
*/
class AppenderDelegate extends ComponentDelegate {
- Map<String, Appender<?>> appendersByName = [:]
-
AppenderDelegate(Appender appender) {
super(appender)
}
- AppenderDelegate(Appender appender, List<Appender<?>> appenders) {
- super(appender)
- appendersByName = appenders.collectEntries { [(it.name) : it]}
- }
-
String getLabel() {
- "appender"
+ "appender"
}
- void appenderRef(String name){
- if (!AppenderAttachable.class.isAssignableFrom(component.class)) {
- def errorMessage= component.class.name + ' does not implement ' + AppenderAttachable.class.name + '.'
- throw new IllegalArgumentException(errorMessage)
- }
- component.addAppender(appendersByName[name])
- }
}
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/AsyncAppenderDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/AsyncAppenderDelegate.groovy
new file mode 100644
index 0000000..cccb0ff
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/AsyncAppenderDelegate.groovy
@@ -0,0 +1,30 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.gaffer
+
+import ch.qos.logback.core.Appender
+
+class AsyncAppenderDelegate extends AppenderDelegate {
+
+ Map<String, Appender<?>> appendersByName = [:]
+
+ AsyncAppenderDelegate(Appender appender, List<Appender<?>> appenders) {
+ super(appender)
+ appendersByName = appenders.collectEntries { [(it.name) : it]}
+ }
+
+ void appenderRef(String name){
+ component.addAppender(appendersByName[name])
+ }
+}
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy
index 0832d6b..6cefd21 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -36,16 +36,15 @@ class ComponentDelegate extends ContextAwareBase {
String getLabelFistLetterInUpperCase() { getLabel()[0].toUpperCase() + getLabel().substring(1) }
void methodMissing(String name, def args) {
- NestingType nestingType = PropertyUtil.nestingType(component, name, null);
+ NestingType nestingType = PropertyUtil.nestingType(component, name);
if (nestingType == NestingType.NA) {
- addError("${getLabelFistLetterInUpperCase()} ${getComponentName()} of type [${component.getClass().canonicalName}] has no appplicable [${name}] property.")
+ addError("${getLabelFistLetterInUpperCase()} ${getComponentName()} of type [${component.getClass().canonicalName}] has no appplicable [${name}] property ")
return;
}
String subComponentName
Class clazz
Closure closure
-
(subComponentName, clazz, closure) = analyzeArgs(args)
if (clazz != null) {
Object subComponent = clazz.newInstance()
@@ -87,7 +86,7 @@ class ComponentDelegate extends ContextAwareBase {
}
void propertyMissing(String name, def value) {
- NestingType nestingType = PropertyUtil.nestingType(component, name, value);
+ NestingType nestingType = PropertyUtil.nestingType(component, name);
if (nestingType == NestingType.NA) {
addError("${getLabelFistLetterInUpperCase()} ${getComponentName()} of type [${component.getClass().canonicalName}] has no appplicable [${name}] property ")
return;
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationContributor.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationContributor.groovy
index a5f193d..97776c9 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationContributor.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationContributor.groovy
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy
index 17b66bd..78cf705 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,7 +19,6 @@ import ch.qos.logback.classic.Logger
import ch.qos.logback.classic.LoggerContext
import ch.qos.logback.classic.jmx.JMXConfigurator
import ch.qos.logback.classic.jmx.MBeanUtil
-import ch.qos.logback.classic.joran.ReconfigureOnChangeTask;
import ch.qos.logback.classic.net.ReceiverBase
import ch.qos.logback.classic.turbo.ReconfigureOnChangeFilter
import ch.qos.logback.classic.turbo.TurboFilter
@@ -34,11 +33,7 @@ import ch.qos.logback.core.spi.ContextAware
import javax.management.MalformedObjectNameException
import javax.management.ObjectName
-
import java.lang.management.ManagementFactory
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
/**
* @author Ceki Gücü
@@ -46,166 +41,169 @@ import java.util.concurrent.TimeUnit;
public class ConfigurationDelegate extends ContextAwareBase {
- List<Appender> appenderList = [];
+ List<Appender> appenderList = [];
- Object getDeclaredOrigin() {
- return this;
- }
+ Object getDeclaredOrigin() {
+ return this;
+ }
- void scan(String scanPeriodStr = null) {
- if (scanPeriodStr) {
- ReconfigureOnChangeTask rocTask = new ReconfigureOnChangeTask();
- rocTask.setContext(context);
- context.putObject(CoreConstants.RECONFIGURE_ON_CHANGE_TASK, rocTask);
- try {
- Duration duration = Duration.valueOf(scanPeriodStr);
- ScheduledExecutorService scheduledExecutorService = context.getScheduledExecutorService();
- ScheduledFuture<?> scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(rocTask, duration.getMilliseconds(), duration.getMilliseconds(), TimeUnit.MILLISECONDS);
- context.addScheduledFuture(scheduledFuture);
- addInfo("Setting ReconfigureOnChangeTask scanning period to " + duration);
- } catch (NumberFormatException nfe) {
- addError("Error while converting [" + scanPeriodStr + "] to long", nfe);
- }
- }
- }
- void statusListener(Class listenerClass) {
- StatusListener statusListener = listenerClass.newInstance()
- context.statusManager.add(statusListener)
- if(statusListener instanceof ContextAware) {
- ((ContextAware) statusListener).setContext(context);
- }
- if(statusListener instanceof LifeCycle) {
- ((LifeCycle) statusListener).start();
- }
- addInfo("Added status listener of type [${listenerClass.canonicalName}]");
+
+ void scan(String scanPeriodStr = null) {
+ ReconfigureOnChangeFilter rocf = new ReconfigureOnChangeFilter();
+ rocf.setContext(context);
+ if (scanPeriodStr) {
+ try {
+ Duration duration = Duration.valueOf(scanPeriodStr);
+ rocf.setRefreshPeriod(duration.getMilliseconds());
+ addInfo("Setting ReconfigureOnChangeFilter scanning period to "
+ + duration);
+ } catch (NumberFormatException nfe) {
+ addError("Error while converting [" + scanAttrib + "] to long", nfe);
+ }
+ }
+ rocf.start();
+ addInfo("Adding ReconfigureOnChangeFilter as a turbo filter");
+ context.addTurboFilter(rocf);
+ }
+
+ void statusListener(Class listenerClass) {
+ StatusListener statusListener = listenerClass.newInstance()
+ context.statusManager.add(statusListener)
+ if(statusListener instanceof ContextAware) {
+ ((ContextAware) statusListener).setContext(context);
}
+ if(statusListener instanceof LifeCycle) {
+ ((LifeCycle) statusListener).start();
+ }
+ addInfo("Added status listener of type [${listenerClass.canonicalName}]");
+ }
- void conversionRule(String conversionWord, Class converterClass) {
- String converterClassName = converterClass.getName();
+ void conversionRule(String conversionWord, Class converterClass) {
+ String converterClassName = converterClass.getName();
- Map<String, String> ruleRegistry = (Map) context.getObject(CoreConstants.PATTERN_RULE_REGISTRY);
- if (ruleRegistry == null) {
- ruleRegistry = new HashMap<String, String>();
- context.putObject(CoreConstants.PATTERN_RULE_REGISTRY, ruleRegistry);
- }
- // put the new rule into the rule registry
- addInfo("registering conversion word " + conversionWord + " with class [" + converterClassName + "]");
- ruleRegistry.put(conversionWord, converterClassName);
+ Map<String, String> ruleRegistry = (Map) context.getObject(CoreConstants.PATTERN_RULE_REGISTRY);
+ if (ruleRegistry == null) {
+ ruleRegistry = new HashMap<String, String>();
+ context.putObject(CoreConstants.PATTERN_RULE_REGISTRY, ruleRegistry);
}
-
- void root(Level level, List<String> appenderNames = []) {
- if (level == null) {
- addError("Root logger cannot be set to level null");
- } else {
- logger(org.slf4j.Logger.ROOT_LOGGER_NAME, level, appenderNames);
- }
+ // put the new rule into the rule registry
+ addInfo("registering conversion word " + conversionWord + " with class [" + converterClassName + "]");
+ ruleRegistry.put(conversionWord, converterClassName);
+ }
+
+ void root(Level level, List<String> appenderNames = []) {
+ if (level == null) {
+ addError("Root logger cannot be set to level null");
+ } else {
+ logger(org.slf4j.Logger.ROOT_LOGGER_NAME, level, appenderNames);
}
-
- void logger(String name, Level level, List<String> appenderNames = [], Boolean additivity = null) {
- if (name) {
- Logger logger = ((LoggerContext) context).getLogger(name);
- addInfo("Setting level of logger [${name}] to " + level);
- logger.level = level;
-
- for (aName in appenderNames) {
- Appender appender = appenderList.find { it -> it.name == aName };
- if (appender != null) {
- addInfo("Attaching appender named [${aName}] to " + logger);
- logger.addAppender(appender);
- } else {
- addError("Failed to find appender named [${aName}]");
- }
- }
-
- if (additivity != null) {
- logger.additive = additivity;
- }
+ }
+
+ void logger(String name, Level level, List<String> appenderNames = [], Boolean additivity = null) {
+ if (name) {
+ Logger logger = ((LoggerContext) context).getLogger(name);
+ addInfo("Setting level of logger [${name}] to " + level);
+ logger.level = level;
+
+ for (aName in appenderNames) {
+ Appender appender = appenderList.find { it -> it.name == aName };
+ if (appender != null) {
+ addInfo("Attaching appender named [${aName}] to " + logger);
+ logger.addAppender(appender);
} else {
- addInfo("No name attribute for logger");
+ addError("Failed to find appender named [${aName}]");
}
- }
+ }
- void appender(String name, Class clazz, Closure closure = null) {
- addInfo("About to instantiate appender of type [" + clazz.name + "]");
- Appender appender = clazz.newInstance();
- addInfo("Naming appender as [" + name + "]");
- appender.name = name
- appender.context = context
- appenderList.add(appender)
- if (closure != null) {
- AppenderDelegate ad = new AppenderDelegate(appender, appenderList)
- copyContributions(ad, appender)
- ad.context = context;
- closure.delegate = ad;
- closure.resolveStrategy = Closure.DELEGATE_FIRST
- closure();
- }
- try {
- appender.start()
- } catch (RuntimeException e) {
- addError("Failed to start apppender named [" + name + "]", e)
- }
+ if (additivity != null) {
+ logger.additive = additivity;
+ }
+ } else {
+ addInfo("No name attribute for logger");
}
-
- void receiver(String name, Class aClass, Closure closure = null) {
- addInfo("About to instantiate receiver of type [" + clazz.name + "]");
- ReceiverBase receiver = aClass.newInstance();
- receiver.context = context;
- if(closure != null) {
- ComponentDelegate componentDelegate = new ComponentDelegate(receiver);
- componentDelegate.context = context;
- closure.delegate = componentDelegate;
- closure.resolveStrategy = Closure.DELEGATE_FIRST
- closure();
- }
- try {
- receiver.start()
- } catch (RuntimeException e) {
- addError("Failed to start receiver of type [" + aClass.getName() + "]", e)
- }
+ }
+
+ void appender(String name, Class clazz, Closure closure = null) {
+ addInfo("About to instantiate appender of type [" + clazz.name + "]");
+ Appender appender = clazz.newInstance();
+ addInfo("Naming appender as [" + name + "]");
+ appender.name = name
+ appender.context = context
+ appenderList.add(appender)
+ if (closure != null) {
+ AppenderDelegate ad = clazz.name == 'ch.qos.logback.classic.AsyncAppender' ? new AsyncAppenderDelegate(appender, appenderList) : new AppenderDelegate(appender);
+ copyContributions(ad, appender)
+ ad.context = context;
+ closure.delegate = ad;
+ closure.resolveStrategy = Closure.DELEGATE_FIRST
+ closure();
}
-
- private void copyContributions(AppenderDelegate appenderDelegate, Appender appender) {
- if (appender instanceof ConfigurationContributor) {
- ConfigurationContributor cc = (ConfigurationContributor) appender;
- cc.getMappings().each() { oldName, newName ->
- appenderDelegate.metaClass."${newName}" = appender.&"$oldName"
- }
- }
+ try {
+ appender.start()
+ } catch (RuntimeException e) {
+ addError("Failed to start apppender named [" + name + "]", e)
}
-
- void turboFilter(Class clazz, Closure closure = null) {
- addInfo("About to instantiate turboFilter of type [" + clazz.name + "]");
- TurboFilter turboFilter = clazz.newInstance();
- turboFilter.context = context
-
- if (closure != null) {
- ComponentDelegate componentDelegate = new ComponentDelegate(turboFilter);
- componentDelegate.context = context;
- closure.delegate = componentDelegate;
- closure.resolveStrategy = Closure.DELEGATE_FIRST
- closure();
- }
- turboFilter.start();
- addInfo("Adding aforementioned turbo filter to context");
- context.addTurboFilter(turboFilter)
+ }
+
+ void receiver(String name, Class aClass, Closure closure = null) {
+ addInfo("About to instantiate receiver of type [" + clazz.name + "]");
+ ReceiverBase receiver = aClass.newInstance();
+ receiver.context = context;
+ if(closure != null) {
+ ComponentDelegate componentDelegate = new ComponentDelegate(receiver);
+ componentDelegate.context = context;
+ closure.delegate = componentDelegate;
+ closure.resolveStrategy = Closure.DELEGATE_FIRST
+ closure();
}
-
- String timestamp(String datePattern, long timeReference = -1) {
- long now = -1;
-
- if (timeReference == -1) {
- addInfo("Using current interpretation time, i.e. now, as time reference.");
- now = System.currentTimeMillis()
- } else {
- now = timeReference
- addInfo("Using " + now + " as time reference.");
- }
- CachingDateFormatter sdf = new CachingDateFormatter(datePattern);
- sdf.format(now)
+ try {
+ receiver.start()
+ } catch (RuntimeException e) {
+ addError("Failed to start receiver of type [" + aClass.getName() + "]", e)
+ }
+ }
+
+ private void copyContributions(AppenderDelegate appenderDelegate, Appender appender) {
+ if (appender instanceof ConfigurationContributor) {
+ ConfigurationContributor cc = (ConfigurationContributor) appender;
+ cc.getMappings().each() { oldName, newName ->
+ appenderDelegate.metaClass."${newName}" = appender.&"$oldName"
+ }
+ }
+ }
+
+ void turboFilter(Class clazz, Closure closure = null) {
+ addInfo("About to instantiate turboFilter of type [" + clazz.name + "]");
+ TurboFilter turboFilter = clazz.newInstance();
+ turboFilter.context = context
+
+ if (closure != null) {
+ ComponentDelegate componentDelegate = new ComponentDelegate(turboFilter);
+ componentDelegate.context = context;
+ closure.delegate = componentDelegate;
+ closure.resolveStrategy = Closure.DELEGATE_FIRST
+ closure();
}
+ turboFilter.start();
+ addInfo("Adding aforementioned turbo filter to context");
+ context.addTurboFilter(turboFilter)
+ }
+
+ String timestamp(String datePattern, long timeReference = -1) {
+ long now = -1;
+
+ if (timeReference == -1) {
+ addInfo("Using current interpretation time, i.e. now, as time reference.");
+ now = System.currentTimeMillis()
+ } else {
+ now = timeReference
+ addInfo("Using " + now + " as time reference.");
+ }
+ CachingDateFormatter sdf = new CachingDateFormatter(datePattern);
+ sdf.format(now)
+ }
/**
* Creates and registers a {@link JMXConfigurator} with the platform MBean Server.
@@ -214,35 +212,35 @@ public class ConfigurationDelegate extends ContextAwareBase {
*
* @param name custom context name or full ObjectName string representation (defaults to null)
*/
- void jmxConfigurator(String name = null) {
- def objectName = null
- def contextName = context.name
- if (name != null) {
- // check if this is a valid ObjectName
- try {
- objectName = new ObjectName(name)
- } catch (MalformedObjectNameException e) {
- contextName = name
- }
- }
- if (objectName == null) {
- def objectNameAsStr = MBeanUtil.getObjectNameFor(contextName, JMXConfigurator.class)
- objectName = MBeanUtil.string2ObjectName(context, this, objectNameAsStr)
- if (objectName == null) {
- addError("Failed to construct ObjectName for [${objectNameAsStr}]")
- return
- }
- }
+ void jmxConfigurator(String name = null) {
+ def objectName = null
+ def contextName = context.name
+ if (name != null) {
+ // check if this is a valid ObjectName
+ try {
+ objectName = new ObjectName(name)
+ } catch (MalformedObjectNameException e) {
+ contextName = name
+ }
+ }
+ if (objectName == null) {
+ def objectNameAsStr = MBeanUtil.getObjectNameFor(contextName, JMXConfigurator.class)
+ objectName = MBeanUtil.string2ObjectName(context, this, objectNameAsStr)
+ if (objectName == null) {
+ addError("Failed to construct ObjectName for [${objectNameAsStr}]")
+ return
+ }
+ }
- def platformMBeanServer = ManagementFactory.platformMBeanServer
- if (!MBeanUtil.isRegistered(platformMBeanServer, objectName)) {
- JMXConfigurator jmxConfigurator = new JMXConfigurator((LoggerContext) context, platformMBeanServer, objectName)
- try {
- platformMBeanServer.registerMBean(jmxConfigurator, objectName)
- } catch (all) {
- addError("Failed to create mbean", all)
- }
- }
+ def platformMBeanServer = ManagementFactory.platformMBeanServer
+ if (!MBeanUtil.isRegistered(platformMBeanServer, objectName)) {
+ JMXConfigurator jmxConfigurator = new JMXConfigurator((LoggerContext) context, platformMBeanServer, objectName)
+ try {
+ platformMBeanServer.registerMBean(jmxConfigurator, objectName)
+ } catch (all) {
+ addError("Failed to create mbean", all)
+ }
}
+ }
}
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/GafferConfigurator.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/GafferConfigurator.groovy
index f1c1fb2..391f0ff 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/GafferConfigurator.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/GafferConfigurator.groovy
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/NestedType.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/NestedType.groovy
index 462fcc8..58176ad 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/NestedType.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/NestedType.groovy
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,6 @@ package ch.qos.logback.classic.gaffer
*/
enum NestingType {
- NA, SINGLE, SINGLE_WITH_VALUE_OF_CONVENTION, AS_COLLECTION;
+ NA, SINGLE, AS_COLLECTION;
}
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/PropertyUtil.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/PropertyUtil.groovy
index cf9efe4..3f6ebdb 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/PropertyUtil.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/PropertyUtil.groovy
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,83 +14,59 @@
package ch.qos.logback.classic.gaffer
import java.lang.reflect.Method
-
-import com.sun.org.apache.xpath.internal.axes.SubContextList;
-
-import ch.qos.logback.core.joran.util.StringToObjectConverter;
-import ch.qos.logback.core.joran.util.beans.BeanUtil
+import java.beans.Introspector
/**
* @author Ceki Gücü
*/
class PropertyUtil {
- static boolean hasAdderMethod(Object obj, String name) {
- String addMethod = "add${upperCaseFirstLetter(name)}";
- return obj.metaClass.respondsTo(obj, addMethod);
- }
-
-
- static NestingType nestingType(Object obj, String name, Object value) {
- def decapitalizedName = BeanUtil.toLowerCamelCase(name);
- MetaProperty metaProperty = obj.hasProperty(decapitalizedName);
+ static boolean hasAdderMethod(Object obj, String name) {
+ String addMethod = "add${upperCaseFirstLetter(name)}";
+ return obj.metaClass.respondsTo(obj, addMethod);
+ }
- if(metaProperty != null) {
- boolean VALUE_IS_A_STRING = value instanceof String;
-
- if(VALUE_IS_A_STRING && StringToObjectConverter.followsTheValueOfConvention(metaProperty.getType())) {
- return NestingType.SINGLE_WITH_VALUE_OF_CONVENTION;
- } else {
- return NestingType.SINGLE;
- }
- }
- if (hasAdderMethod(obj, name)) {
- return NestingType.AS_COLLECTION;
- }
- return NestingType.NA;
+ static NestingType nestingType(Object obj, String name) {
+ def decapitalizedName = Introspector.decapitalize(name)
+ if (obj.hasProperty(decapitalizedName)) {
+ return NestingType.SINGLE;
}
-
- static Object convertByValueMethod(Object component, String name, String value) {
- def decapitalizedName = BeanUtil.toLowerCamelCase(name);
- MetaProperty metaProperty = component.hasProperty(decapitalizedName);
- Method valueOfMethod = StringToObjectConverter.getValueOfMethod(metaProperty.getType());
- return valueOfMethod.invoke(null, value);
+ if (hasAdderMethod(obj, name)) {
+ return NestingType.AS_COLLECTION;
}
-
- static void attach(NestingType nestingType, Object component, Object subComponent, String name) {
- switch (nestingType) {
- case NestingType.SINGLE_WITH_VALUE_OF_CONVENTION:
- name = BeanUtil.toLowerCamelCase(name);
- Object value = convertByValueMethod(component, name, subComponent);
- component."${name}" = value;
- break;
- case NestingType.SINGLE:
- name = BeanUtil.toLowerCamelCase(name);
- component."${name}" = subComponent;
- break;
+ return NestingType.NA;
+ }
- case NestingType.AS_COLLECTION:
- String firstUpperName = PropertyUtil.upperCaseFirstLetter(name)
- component."add${firstUpperName}"(subComponent);
- break;
- }
+ static void attach(NestingType nestingType, Object component, Object subComponent, String name) {
+ switch (nestingType) {
+ case NestingType.SINGLE:
+ name = Introspector.decapitalize(name)
+ component."${name}" = subComponent;
+ break;
+ case NestingType.AS_COLLECTION:
+ String firstUpperName = PropertyUtil.upperCaseFirstLetter(name)
+ component."add${firstUpperName}"(subComponent);
+ break;
}
+ }
- static String transformFirstLetter(String s, Closure closure) {
- if (s == null || s.length() == 0)
- return s;
+ static String transformFirstLetter(String s, Closure closure) {
+ if (s == null || s.length() == 0)
+ return s;
- String firstLetter = new String(s.getAt(0));
+ String firstLetter = new String(s.getAt(0));
- String modifiedFistLetter = closure(firstLetter);
+ String modifiedFistLetter = closure(firstLetter);
- if (s.length() == 1)
- return modifiedFistLetter
- else
- return modifiedFistLetter + s.substring(1);
- }
+ if (s.length() == 1)
+ return modifiedFistLetter
+ else
+ return modifiedFistLetter + s.substring(1);
+
+ }
+
+ static String upperCaseFirstLetter(String s) {
+ return transformFirstLetter(s, {String it -> it.toUpperCase()})
+ }
- static String upperCaseFirstLetter(String s) {
- return transformFirstLetter(s, {String it -> it.toUpperCase()})
- }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/AsyncAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/AsyncAppender.java
index bedcf0c..075bed3 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/AsyncAppender.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/AsyncAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,30 +27,32 @@ import ch.qos.logback.core.AsyncAppenderBase;
*/
public class AsyncAppender extends AsyncAppenderBase<ILoggingEvent> {
- boolean includeCallerData = false;
-
- /**
- * Events of level TRACE, DEBUG and INFO are deemed to be discardable.
- * @param event
- * @return true if the event is of level TRACE, DEBUG or INFO false otherwise.
- */
- protected boolean isDiscardable(ILoggingEvent event) {
- Level level = event.getLevel();
- return level.toInt() <= Level.INFO_INT;
- }
-
- protected void preprocess(ILoggingEvent eventObject) {
- eventObject.prepareForDeferredProcessing();
- if (includeCallerData)
- eventObject.getCallerData();
- }
-
- public boolean isIncludeCallerData() {
- return includeCallerData;
- }
-
- public void setIncludeCallerData(boolean includeCallerData) {
- this.includeCallerData = includeCallerData;
- }
+
+ boolean includeCallerData = false;
+
+
+ /**
+ * Events of level TRACE, DEBUG and INFO are deemed to be discardable.
+ * @param event
+ * @return true if the event is of level TRACE, DEBUG or INFO false otherwise.
+ */
+ protected boolean isDiscardable(ILoggingEvent event) {
+ Level level = event.getLevel();
+ return level.toInt() <= Level.INFO_INT;
+ }
+
+ protected void preprocess(ILoggingEvent eventObject) {
+ eventObject.prepareForDeferredProcessing();
+ if(includeCallerData)
+ eventObject.getCallerData();
+ }
+
+ public boolean isIncludeCallerData() {
+ return includeCallerData;
+ }
+
+ public void setIncludeCallerData(boolean includeCallerData) {
+ this.includeCallerData = includeCallerData;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java b/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java
index e0dac11..d5df37e 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,48 +13,50 @@
*/
package ch.qos.logback.classic;
-import ch.qos.logback.classic.layout.TTLLLayout;
-import ch.qos.logback.classic.spi.Configurator;
+import org.slf4j.LoggerFactory;
+
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.ConsoleAppender;
-import ch.qos.logback.core.encoder.LayoutWrappingEncoder;
-import ch.qos.logback.core.spi.ContextAwareBase;
+import ch.qos.logback.core.status.InfoStatus;
+import ch.qos.logback.core.status.StatusManager;
/**
* BasicConfigurator configures logback-classic by attaching a
* {@link ConsoleAppender} to the root logger. The console appender's layout
- * is set to a {@link ch.qos.logback.classic.layout.TTLLLayout TTLLLayout}.
+ * is set to a {@link PatternLayout} with the pattern
+ * "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n".
*
- * @author Ceki Gülcü
+ * @author Ceki Gulcu
*/
-public class BasicConfigurator extends ContextAwareBase implements Configurator {
+public class BasicConfigurator {
- public BasicConfigurator() {
+ final static BasicConfigurator hiddenSingleton = new BasicConfigurator();
+
+ private BasicConfigurator() {
+ }
+
+ public static void configure(LoggerContext lc) {
+ StatusManager sm = lc.getStatusManager();
+ if(sm != null) {
+ sm.add(new InfoStatus("Setting up default configuration.", lc));
}
+ ConsoleAppender<ILoggingEvent> ca = new ConsoleAppender<ILoggingEvent>();
+ 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();
- public void configure(LoggerContext lc) {
- addInfo("Setting up default configuration.");
-
- ConsoleAppender<ILoggingEvent> ca = new ConsoleAppender<ILoggingEvent>();
- ca.setContext(lc);
- ca.setName("console");
- LayoutWrappingEncoder<ILoggingEvent> encoder = new LayoutWrappingEncoder<ILoggingEvent>();
- encoder.setContext(lc);
-
-
- // same as
- // PatternLayout layout = new PatternLayout();
- // layout.setPattern("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");
- TTLLLayout layout = new TTLLLayout();
-
- layout.setContext(lc);
- layout.start();
- encoder.setLayout(layout);
-
- ca.setEncoder(encoder);
- ca.start();
-
- Logger rootLogger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- rootLogger.addAppender(ca);
- }
+ ca.setEncoder(pl);
+ ca.start();
+ Logger rootLogger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+ rootLogger.addAppender(ca);
+ }
+
+ public static void configureDefaultContext() {
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ configure(lc);
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/ClassicConstants.java b/logback-classic/src/main/java/ch/qos/logback/classic/ClassicConstants.java
index 2638bac..e28fe0e 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/ClassicConstants.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/ClassicConstants.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,35 +17,34 @@ import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
public class ClassicConstants {
- public static final String USER_MDC_KEY = "user";
-
- public static final String LOGBACK_CONTEXT_SELECTOR = "logback.ContextSelector";
- public static final String JNDI_CONFIGURATION_RESOURCE = "java:comp/env/logback/configuration-resource";
- public static final String JNDI_CONTEXT_NAME = "java:comp/env/logback/context-name";
-
- /**
- * The maximum number of package separators (dots) that abbreviation
- * algorithms can handle. Class or logger names with more separators will have
- * their first MAX_DOTS parts shortened.
- *
- */
- public static final int MAX_DOTS = 16;
-
- /**
- * The default stack data depth computed during caller data extraction.
- */
- public static final int DEFAULT_MAX_CALLEDER_DATA_DEPTH = 8;
-
- public static final String REQUEST_REMOTE_HOST_MDC_KEY = "req.remoteHost";
- public static final String REQUEST_USER_AGENT_MDC_KEY = "req.userAgent";
- public static final String REQUEST_REQUEST_URI = "req.requestURI";
- public static final String REQUEST_QUERY_STRING = "req.queryString";
- public static final String REQUEST_REQUEST_URL = "req.requestURL";
- public static final String REQUEST_METHOD = "req.method";
- public static final String REQUEST_X_FORWARDED_FOR = "req.xForwardedFor";
-
- public static final String GAFFER_CONFIGURATOR_FQCN = "ch.qos.logback.classic.gaffer.GafferConfigurator";
-
- public static final String FINALIZE_SESSION = "FINALIZE_SESSION";
- public static final Marker FINALIZE_SESSION_MARKER = MarkerFactory.getMarker(FINALIZE_SESSION);
+ public static final String USER_MDC_KEY = "user";
+
+ public static final String LOGBACK_CONTEXT_SELECTOR = "logback.ContextSelector";
+ public static final String JNDI_CONFIGURATION_RESOURCE = "java:comp/env/logback/configuration-resource";
+ public static final String JNDI_CONTEXT_NAME = "java:comp/env/logback/context-name";
+
+ /**
+ * The maximum number of package separators (dots) that abbreviation
+ * algorithms can handle. Class or logger names with more separators will have
+ * their first MAX_DOTS parts shortened.
+ *
+ */
+ public static final int MAX_DOTS = 16;
+
+ /**
+ * The default stack data depth computed during caller data extraction.
+ */
+ public static final int DEFAULT_MAX_CALLEDER_DATA_DEPTH = 8;
+
+ public static final String REQUEST_REMOTE_HOST_MDC_KEY = "req.remoteHost";
+ public static final String REQUEST_USER_AGENT_MDC_KEY = "req.userAgent";
+ public static final String REQUEST_REQUEST_URI = "req.requestURI";
+ public static final String REQUEST_QUERY_STRING = "req.queryString";
+ public static final String REQUEST_REQUEST_URL = "req.requestURL";
+ public static final String REQUEST_X_FORWARDED_FOR = "req.xForwardedFor";
+
+ public static final String GAFFER_CONFIGURATOR_FQCN = "ch.qos.logback.classic.gaffer.GafferConfigurator";
+
+ public static final String FINALIZE_SESSION = "FINALIZE_SESSION";
+ public static final Marker FINALIZE_SESSION_MARKER = MarkerFactory.getMarker(FINALIZE_SESSION);
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/Level.java b/logback-classic/src/main/java/ch/qos/logback/classic/Level.java
index 1f27679..bd2ec82 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/Level.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/Level.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,272 +24,275 @@ import org.slf4j.spi.LocationAwareLogger;
*/
public final class Level implements java.io.Serializable {
- private static final long serialVersionUID = -814092767334282137L;
+ private static final long serialVersionUID = -814092767334282137L;
- public static final int OFF_INT = Integer.MAX_VALUE;
- public static final int ERROR_INT = 40000;
- public static final int WARN_INT = 30000;
- public static final int INFO_INT = 20000;
- public static final int DEBUG_INT = 10000;
- public static final int TRACE_INT = 5000;
- public static final int ALL_INT = Integer.MIN_VALUE;
+ public static final int OFF_INT = Integer.MAX_VALUE;
+ public static final int ERROR_INT = 40000;
+ public static final int WARN_INT = 30000;
+ public static final int INFO_INT = 20000;
+ public static final int DEBUG_INT = 10000;
+ public static final int TRACE_INT = 5000;
+ public static final int ALL_INT = Integer.MIN_VALUE;
- public static final Integer OFF_INTEGER = OFF_INT;
- public static final Integer ERROR_INTEGER = ERROR_INT;
- public static final Integer WARN_INTEGER = WARN_INT;
- public static final Integer INFO_INTEGER = INFO_INT;
- public static final Integer DEBUG_INTEGER = DEBUG_INT;
- public static final Integer TRACE_INTEGER = TRACE_INT;
- public static final Integer ALL_INTEGER = ALL_INT;
+ public static final Integer OFF_INTEGER = OFF_INT;
+ public static final Integer ERROR_INTEGER = ERROR_INT;
+ public static final Integer WARN_INTEGER = WARN_INT;
+ public static final Integer INFO_INTEGER = INFO_INT;
+ public static final Integer DEBUG_INTEGER = DEBUG_INT;
+ public static final Integer TRACE_INTEGER = TRACE_INT;
+ public static final Integer ALL_INTEGER = ALL_INT;
- /**
- * The <code>OFF</code> is used to turn off logging.
- */
- public static final Level OFF = new Level(OFF_INT, "OFF");
+ /**
+ * The <code>OFF</code> is used to turn off logging.
+ */
+ public static final Level OFF = new Level(OFF_INT, "OFF");
- /**
- * The <code>ERROR</code> level designates error events which may or not
- * be fatal to the application.
- */
- public static final Level ERROR = new Level(ERROR_INT, "ERROR");
+ /**
+ * The <code>ERROR</code> level designates error events which may or not
+ * be fatal to the application.
+ */
+ public static final Level ERROR = new Level(ERROR_INT, "ERROR");
- /**
- * The <code>WARN</code> level designates potentially harmful situations.
- */
- public static final Level WARN = new Level(WARN_INT, "WARN");
+ /**
+ * The <code>WARN</code> level designates potentially harmful situations.
+ */
+ public static final Level WARN = new Level(WARN_INT, "WARN");
- /**
- * The <code>INFO</code> level designates informational messages
- * highlighting overall progress of the application.
- */
- public static final Level INFO = new Level(INFO_INT, "INFO");
+ /**
+ * The <code>INFO</code> level designates informational messages
+ * highlighting overall progress of the application.
+ */
+ public static final Level INFO = new Level(INFO_INT, "INFO");
- /**
- * The <code>DEBUG</code> level designates informational events of lower
- * importance.
- */
- public static final Level DEBUG = new Level(DEBUG_INT, "DEBUG");
+ /**
+ * The <code>DEBUG</code> level designates informational events of lower
+ * importance.
+ */
+ public static final Level DEBUG = new Level(DEBUG_INT, "DEBUG");
- /**
- * The <code>TRACE</code> level designates informational events of very low
- * importance.
- */
- public static final Level TRACE = new Level(TRACE_INT, "TRACE");
+ /**
+ * The <code>TRACE</code> level designates informational events of very low
+ * importance.
+ */
+ public static final Level TRACE = new Level(TRACE_INT, "TRACE");
- /**
- * The <code>ALL</code> is used to turn on all logging.
- */
- public static final Level ALL = new Level(ALL_INT, "ALL");
+ /**
+ * The <code>ALL</code> is used to turn on all logging.
+ */
+ public static final Level ALL = new Level(ALL_INT, "ALL");
- public final int levelInt;
- public final String levelStr;
+ public final int levelInt;
+ public final String levelStr;
- /**
- * Instantiate a Level object.
- */
- private Level(int levelInt, String levelStr) {
- this.levelInt = levelInt;
- this.levelStr = levelStr;
- }
+ /**
+ * Instantiate a Level object.
+ */
+ private Level(int levelInt, String levelStr) {
+ this.levelInt = levelInt;
+ this.levelStr = levelStr;
+ }
- /**
- * Returns the string representation of this Level.
- */
- public String toString() {
- return levelStr;
- }
+ /**
+ * Returns the string representation of this Level.
+ */
+ public String toString() {
+ return levelStr;
+ }
- /**
- * Returns the integer representation of this Level.
- */
- public int toInt() {
- return levelInt;
- }
+ /**
+ * Returns the integer representation of this Level.
+ */
+ public int toInt() {
+ return levelInt;
+ }
- /**
- * Convert a Level to an Integer object.
- *
- * @return This level's Integer mapping.
- */
- public Integer toInteger() {
- switch (levelInt) {
- case ALL_INT:
- return ALL_INTEGER;
- case TRACE_INT:
- return TRACE_INTEGER;
- case DEBUG_INT:
- return DEBUG_INTEGER;
- case INFO_INT:
- return INFO_INTEGER;
- case WARN_INT:
- return WARN_INTEGER;
- case ERROR_INT:
- return ERROR_INTEGER;
- case OFF_INT:
- return OFF_INTEGER;
- default:
- throw new IllegalStateException("Level " + levelStr + ", " + levelInt + " is unknown.");
- }
+ /**
+ * Convert a Level to an Integer object.
+ *
+ * @return This level's Integer mapping.
+ */
+ public Integer toInteger() {
+ switch (levelInt) {
+ case ALL_INT:
+ return ALL_INTEGER;
+ case TRACE_INT:
+ return TRACE_INTEGER;
+ case DEBUG_INT:
+ return DEBUG_INTEGER;
+ case INFO_INT:
+ return INFO_INTEGER;
+ case WARN_INT:
+ return WARN_INTEGER;
+ case ERROR_INT:
+ return ERROR_INTEGER;
+ case OFF_INT:
+ return OFF_INTEGER;
+ default:
+ throw new IllegalStateException("Level " + levelStr + ", " + levelInt
+ + " is unknown.");
}
+ }
- /**
- * Returns <code>true</code> if this Level has a higher or equal Level than
- * the Level passed as argument, <code>false</code> otherwise.
- */
- public boolean isGreaterOrEqual(Level r) {
- return levelInt >= r.levelInt;
- }
+ /**
+ * Returns <code>true</code> if this Level has a higher or equal Level than
+ * the Level passed as argument, <code>false</code> otherwise.
+ */
+ public boolean isGreaterOrEqual(Level r) {
+ return levelInt >= r.levelInt;
+ }
- /**
- * Convert the string passed as argument to a Level. If the conversion fails,
- * then this method returns {@link #DEBUG}.
- */
- public static Level toLevel(String sArg) {
- return toLevel(sArg, Level.DEBUG);
- }
+ /**
+ * Convert the string passed as argument to a Level. If the conversion fails,
+ * then this method returns {@link #DEBUG}.
+ */
+ public static Level toLevel(String sArg) {
+ return toLevel(sArg, Level.DEBUG);
+ }
- /**
- * This method exists in order to comply with Joran's valueOf convention.
- *
- * @param sArg
- * @return
- */
- public static Level valueOf(String sArg) {
- return toLevel(sArg, Level.DEBUG);
- }
- /**
- * Convert an integer passed as argument to a Level. If the conversion fails,
- * then this method returns {@link #DEBUG}.
- */
- public static Level toLevel(int val) {
- return toLevel(val, Level.DEBUG);
- }
+ /**
+ * This method exists in order to comply with Joran's valueOf convention.
+ *
+ * @param sArg
+ * @return
+ */
+ public static Level valueOf(String sArg) {
+ return toLevel(sArg, Level.DEBUG);
+ }
- /**
- * Convert an integer passed as argument to a Level. If the conversion fails,
- * then this method returns the specified default.
- */
- public static Level toLevel(int val, Level defaultLevel) {
- switch (val) {
- case ALL_INT:
- return ALL;
- case TRACE_INT:
- return TRACE;
- case DEBUG_INT:
- return DEBUG;
- case INFO_INT:
- return INFO;
- case WARN_INT:
- return WARN;
- case ERROR_INT:
- return ERROR;
- case OFF_INT:
- return OFF;
- default:
- return defaultLevel;
- }
- }
- /**
- * Convert the string passed as argument to a Level. If the conversion fails,
- * then this method returns the value of <code>defaultLevel</code>.
- */
- public static Level toLevel(String sArg, Level defaultLevel) {
- if (sArg == null) {
- return defaultLevel;
- }
+ /**
+ * Convert an integer passed as argument to a Level. If the conversion fails,
+ * then this method returns {@link #DEBUG}.
+ */
+ public static Level toLevel(int val) {
+ return toLevel(val, Level.DEBUG);
+ }
- if (sArg.equalsIgnoreCase("ALL")) {
- return Level.ALL;
- }
- if (sArg.equalsIgnoreCase("TRACE")) {
- return Level.TRACE;
- }
- if (sArg.equalsIgnoreCase("DEBUG")) {
- return Level.DEBUG;
- }
- if (sArg.equalsIgnoreCase("INFO")) {
- return Level.INFO;
- }
- if (sArg.equalsIgnoreCase("WARN")) {
- return Level.WARN;
- }
- if (sArg.equalsIgnoreCase("ERROR")) {
- return Level.ERROR;
- }
- if (sArg.equalsIgnoreCase("OFF")) {
- return Level.OFF;
- }
+ /**
+ * Convert an integer passed as argument to a Level. If the conversion fails,
+ * then this method returns the specified default.
+ */
+ public static Level toLevel(int val, Level defaultLevel) {
+ switch (val) {
+ case ALL_INT:
+ return ALL;
+ case TRACE_INT:
+ return TRACE;
+ case DEBUG_INT:
+ return DEBUG;
+ case INFO_INT:
+ return INFO;
+ case WARN_INT:
+ return WARN;
+ case ERROR_INT:
+ return ERROR;
+ case OFF_INT:
+ return OFF;
+ default:
return defaultLevel;
}
+ }
- /**
- * Return the flyweight instance of the level received through serizalization,
- * i.e. 'this'.
- *
- * @return The appropriate flyweight instance
- */
- private Object readResolve() {
- return toLevel(this.levelInt);
+ /**
+ * Convert the string passed as argument to a Level. If the conversion fails,
+ * then this method returns the value of <code>defaultLevel</code>.
+ */
+ public static Level toLevel(String sArg, Level defaultLevel) {
+ if (sArg == null) {
+ return defaultLevel;
}
- /**
- * Convert one of the integer values defined in {@link LocationAwareLogger}
- * interface to an instance of this class, i.e. a Level.
- *
- * @param levelInt An integer value representing a level as defined in LocationAwareLogger
- * @return an instance of this class, i.e. a Level.
- * @since 1.0.1
- */
- public static Level fromLocationAwareLoggerInteger(int levelInt) {
- Level level;
- switch (levelInt) {
- case LocationAwareLogger.TRACE_INT:
- level = TRACE;
- break;
- case LocationAwareLogger.DEBUG_INT:
- level = DEBUG;
- break;
- case LocationAwareLogger.INFO_INT:
- level = INFO;
- break;
- case LocationAwareLogger.WARN_INT:
- level = WARN;
- break;
- case LocationAwareLogger.ERROR_INT:
- level = ERROR;
- break;
- default:
- throw new IllegalArgumentException(levelInt + " not a valid level value");
- }
- return level;
+ if (sArg.equalsIgnoreCase("ALL")) {
+ return Level.ALL;
+ }
+ if (sArg.equalsIgnoreCase("TRACE")) {
+ return Level.TRACE;
+ }
+ if (sArg.equalsIgnoreCase("DEBUG")) {
+ return Level.DEBUG;
+ }
+ if (sArg.equalsIgnoreCase("INFO")) {
+ return Level.INFO;
+ }
+ if (sArg.equalsIgnoreCase("WARN")) {
+ return Level.WARN;
+ }
+ if (sArg.equalsIgnoreCase("ERROR")) {
+ return Level.ERROR;
+ }
+ if (sArg.equalsIgnoreCase("OFF")) {
+ return Level.OFF;
+ }
+ return defaultLevel;
+ }
+
+ /**
+ * Return the flyweight instance of the level received through serizalization,
+ * i.e. 'this'.
+ *
+ * @return The appropriate flyweight instance
+ */
+ private Object readResolve() {
+ return toLevel(this.levelInt);
+ }
+
+ /**
+ * Convert one of the integer values defined in {@link LocationAwareLogger}
+ * interface to an instance of this class, i.e. a Level.
+ *
+ * @param levelInt An integer value representing a level as defined in LocationAwareLogger
+ * @return an instance of this class, i.e. a Level.
+ * @since 1.0.1
+ */
+ public static Level fromLocationAwareLoggerInteger(int levelInt) {
+ Level level;
+ switch (levelInt) {
+ case LocationAwareLogger.TRACE_INT:
+ level = TRACE;
+ break;
+ case LocationAwareLogger.DEBUG_INT:
+ level = DEBUG;
+ break;
+ case LocationAwareLogger.INFO_INT:
+ level = INFO;
+ break;
+ case LocationAwareLogger.WARN_INT:
+ level = WARN;
+ break;
+ case LocationAwareLogger.ERROR_INT:
+ level = ERROR;
+ break;
+ default:
+ throw new IllegalArgumentException(levelInt + " not a valid level value");
}
+ return level;
+ }
- /**
- * Convert this level instance to an integer value defined in the
- * {@link LocationAwareLogger} interface.
- *
- * @param level The level to convert to LocationAwareLogger integer
- * @return int An integer corresponding to this level as defined in LocationAwareLogger
- * @since 1.0.1
- */
- public static int toLocationAwareLoggerInteger(Level level) {
- if (level == null)
- throw new IllegalArgumentException("null level parameter is not admitted");
- switch (level.toInt()) {
- case Level.TRACE_INT:
- return LocationAwareLogger.TRACE_INT;
- case Level.DEBUG_INT:
- return LocationAwareLogger.DEBUG_INT;
- case Level.INFO_INT:
- return LocationAwareLogger.INFO_INT;
- case Level.WARN_INT:
- return LocationAwareLogger.WARN_INT;
- case Level.ERROR_INT:
- return LocationAwareLogger.ERROR_INT;
- default:
- throw new IllegalArgumentException(level + " not a valid level value");
- }
+ /**
+ * Convert this level instance to an integer value defined in the
+ * {@link LocationAwareLogger} interface.
+ *
+ * @param level The level to convert to LocationAwareLogger integer
+ * @return int An integer corresponding to this level as defined in LocationAwareLogger
+ * @since 1.0.1
+ */
+ public static int toLocationAwareLoggerInteger(Level level) {
+ if (level == null)
+ throw new IllegalArgumentException("null level parameter is not admitted");
+ switch (level.toInt()) {
+ case Level.TRACE_INT:
+ return LocationAwareLogger.TRACE_INT;
+ case Level.DEBUG_INT:
+ return LocationAwareLogger.DEBUG_INT;
+ case Level.INFO_INT:
+ return LocationAwareLogger.INFO_INT;
+ case Level.WARN_INT:
+ return LocationAwareLogger.WARN_INT;
+ case Level.ERROR_INT:
+ return LocationAwareLogger.ERROR_INT;
+ default:
+ throw new IllegalArgumentException(level + " not a valid level value");
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/Logger.java b/logback-classic/src/main/java/ch/qos/logback/classic/Logger.java
index 9fd7219..f4fb4a9 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/Logger.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/Logger.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,775 +15,788 @@ package ch.qos.logback.classic;
import java.io.ObjectStreamException;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
+import ch.qos.logback.classic.util.LoggerNameUtil;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.spi.LocationAwareLogger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;
-import ch.qos.logback.classic.util.LoggerNameUtil;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.spi.AppenderAttachable;
import ch.qos.logback.core.spi.AppenderAttachableImpl;
import ch.qos.logback.core.spi.FilterReply;
-public final class Logger implements org.slf4j.Logger, LocationAwareLogger, AppenderAttachable<ILoggingEvent>, Serializable {
-
- private static final long serialVersionUID = 5454405123156820674L; // 8745934908040027998L;
-
- /**
- * The fully qualified name of this class. Used in gathering caller
- * information.
- */
- public static final String FQCN = ch.qos.logback.classic.Logger.class.getName();
-
- /**
- * The name of this logger
- */
- private String name;
-
- // The assigned levelInt of this logger. Can be null.
- transient private Level level;
-
- // The effective levelInt is the assigned levelInt and if null, a levelInt is
- // inherited form a parent.
- transient private int effectiveLevelInt;
-
- /**
- * The parent of this category. All categories have at least one ancestor
- * which is the root category.
- */
- transient private Logger parent;
-
- /**
- * The children of this logger. A logger may have zero or more children.
- */
- transient private List<Logger> childrenList;
-
- /**
- * It is assumed that once the 'aai' variable is set to a non-null value, it
- * will never be reset to null. it is further assumed that only place where
- * the 'aai'ariable is set is within the addAppender method. This method is
- * synchronized on 'this' (Logger) protecting against simultaneous
- * re-configuration of this logger (a very unlikely scenario).
- *
- * <p>
- * It is further assumed that the AppenderAttachableImpl is responsible for
- * its internal synchronization and thread safety. Thus, we can get away with
- * *not* synchronizing on the 'aai' (check null/ read) because
- * <p>
- * 1) the 'aai' variable is immutable once set to non-null
- * <p>
- * 2) 'aai' is getAndSet only within addAppender which is synchronized
- * <p>
- * 3) all the other methods check whether 'aai' is null
- * <p>
- * 4) AppenderAttachableImpl is thread safe
- */
- transient private AppenderAttachableImpl<ILoggingEvent> aai;
- /**
- * Additivity is set to true by default, that is children inherit the
- * appenders of their ancestors by default. If this variable is set to
- * <code>false</code> then the appenders located in the ancestors of this
- * logger will not be used. However, the children of this logger will inherit
- * its appenders, unless the children have their additivity flag set to
- * <code>false</code> too. See the user manual for more details.
- */
- transient private boolean additive = true;
-
- final transient LoggerContext loggerContext;
-
- Logger(String name, Logger parent, LoggerContext loggerContext) {
- this.name = name;
- this.parent = parent;
- this.loggerContext = loggerContext;
- }
-
- public Level getEffectiveLevel() {
- return Level.toLevel(effectiveLevelInt);
- }
-
- int getEffectiveLevelInt() {
- return effectiveLevelInt;
- }
-
- public Level getLevel() {
- return level;
- }
-
- public String getName() {
- return name;
- }
-
- private boolean isRootLogger() {
- // only the root logger has a null parent
- return parent == null;
- }
-
- Logger getChildByName(final String childName) {
- if (childrenList == null) {
- return null;
- } else {
- int len = this.childrenList.size();
- for (int i = 0; i < len; i++) {
- final Logger childLogger_i = (Logger) childrenList.get(i);
- final String childName_i = childLogger_i.getName();
-
- if (childName.equals(childName_i)) {
- return childLogger_i;
- }
- }
- // no child found
- return null;
- }
- }
-
- public synchronized void setLevel(Level newLevel) {
- if (level == newLevel) {
- // nothing to do;
- return;
- }
- if (newLevel == null && isRootLogger()) {
- throw new IllegalArgumentException("The level of the root logger cannot be set to null");
- }
-
- level = newLevel;
- if (newLevel == null) {
- effectiveLevelInt = parent.effectiveLevelInt;
- newLevel = parent.getEffectiveLevel();
- } else {
- effectiveLevelInt = newLevel.levelInt;
- }
-
- if (childrenList != null) {
- int len = childrenList.size();
- for (int i = 0; i < len; i++) {
- Logger child = (Logger) childrenList.get(i);
- // tell child to handle parent levelInt change
- child.handleParentLevelChange(effectiveLevelInt);
- }
- }
- // inform listeners
- loggerContext.fireOnLevelChange(this, newLevel);
- }
-
- /**
- * This method is invoked by parent logger to let this logger know that the
- * prent's levelInt changed.
- *
- * @param newParentLevelInt
- */
- private synchronized void handleParentLevelChange(int newParentLevelInt) {
- // changes in the parent levelInt affect children only if their levelInt is
- // null
- if (level == null) {
- effectiveLevelInt = newParentLevelInt;
-
- // propagate the parent levelInt change to this logger's children
- if (childrenList != null) {
- int len = childrenList.size();
- for (int i = 0; i < len; i++) {
- Logger child = (Logger) childrenList.get(i);
- child.handleParentLevelChange(newParentLevelInt);
- }
- }
- }
- }
-
- /**
- * Remove all previously added appenders from this logger instance.
- * <p/>
- * This is useful when re-reading configuration information.
- */
- public void detachAndStopAllAppenders() {
- if (aai != null) {
- aai.detachAndStopAllAppenders();
- }
- }
-
- public boolean detachAppender(String name) {
- if (aai == null) {
- return false;
- }
- return aai.detachAppender(name);
- }
-
- // this method MUST be synchronized. See comments on 'aai' field for further
- // details.
- public synchronized void addAppender(Appender<ILoggingEvent> newAppender) {
- if (aai == null) {
- aai = new AppenderAttachableImpl<ILoggingEvent>();
- }
- aai.addAppender(newAppender);
- }
-
- public boolean isAttached(Appender<ILoggingEvent> appender) {
- if (aai == null) {
- return false;
- }
- return aai.isAttached(appender);
- }
-
- @SuppressWarnings("unchecked")
- public Iterator<Appender<ILoggingEvent>> iteratorForAppenders() {
- if (aai == null) {
- return Collections.EMPTY_LIST.iterator();
- }
- return aai.iteratorForAppenders();
- }
-
- public Appender<ILoggingEvent> getAppender(String name) {
- if (aai == null) {
- return null;
- }
- return aai.getAppender(name);
- }
-
- /**
- * Invoke all the appenders of this logger.
- *
- * @param event
- * The event to log
- */
- public void callAppenders(ILoggingEvent event) {
- int writes = 0;
- for (Logger l = this; l != null; l = l.parent) {
- writes += l.appendLoopOnAppenders(event);
- if (!l.additive) {
- break;
- }
- }
- // No appenders in hierarchy
- if (writes == 0) {
- loggerContext.noAppenderDefinedWarning(this);
- }
- }
-
- private int appendLoopOnAppenders(ILoggingEvent event) {
- if (aai != null) {
- return aai.appendLoopOnAppenders(event);
- } else {
- return 0;
- }
- }
-
- /**
- * Remove the appender passed as parameter form the list of appenders.
- */
- public boolean detachAppender(Appender<ILoggingEvent> appender) {
- if (aai == null) {
- return false;
- }
- return aai.detachAppender(appender);
- }
-
- /**
- * Create a child of this logger by suffix, that is, the part of the name
- * extending this logger. For example, if this logger is named "x.y" and the
- * lastPart is "z", then the created child logger will be named "x.y.z".
- *
- * <p>
- * IMPORTANT: Calls to this method must be within a synchronized block on this
- * logger.
- *
- * @param lastPart
- * the suffix (i.e. last part) of the child logger name. This
- * parameter may not include dots, i.e. the logger separator
- * character.
- * @return
- */
- Logger createChildByLastNamePart(final String lastPart) {
- int i_index = LoggerNameUtil.getFirstSeparatorIndexOf(lastPart);
- if (i_index != -1) {
- throw new IllegalArgumentException("Child name [" + lastPart + " passed as parameter, may not include [" + CoreConstants.DOT + "]");
- }
-
- if (childrenList == null) {
- childrenList = new CopyOnWriteArrayList<Logger>();
- }
- Logger childLogger;
- if (this.isRootLogger()) {
- childLogger = new Logger(lastPart, this, this.loggerContext);
- } else {
- childLogger = new Logger(name + CoreConstants.DOT + lastPart, this, this.loggerContext);
- }
- childrenList.add(childLogger);
- childLogger.effectiveLevelInt = this.effectiveLevelInt;
- return childLogger;
- }
-
- private void localLevelReset() {
- effectiveLevelInt = Level.DEBUG_INT;
- if (isRootLogger()) {
- level = Level.DEBUG;
- } else {
- level = null;
- }
- }
-
- void recursiveReset() {
- detachAndStopAllAppenders();
- localLevelReset();
- additive = true;
- if (childrenList == null) {
- return;
- }
- for (Logger childLogger : childrenList) {
- childLogger.recursiveReset();
- }
- }
-
- /**
- * The default size of child list arrays. The JDK 1.5 default is 10. We use a
- * smaller value to save a little space.
- */
-
- Logger createChildByName(final String childName) {
- int i_index = LoggerNameUtil.getSeparatorIndexOf(childName, this.name.length() + 1);
- if (i_index != -1) {
- throw new IllegalArgumentException("For logger [" + this.name + "] child name [" + childName
- + " passed as parameter, may not include '.' after index" + (this.name.length() + 1));
- }
-
- if (childrenList == null) {
- childrenList = new CopyOnWriteArrayList<Logger>();
- }
- Logger childLogger;
- childLogger = new Logger(childName, this, this.loggerContext);
- childrenList.add(childLogger);
- childLogger.effectiveLevelInt = this.effectiveLevelInt;
- return childLogger;
- }
-
- /**
- * The next methods are not merged into one because of the time we gain by not
- * creating a new Object[] with the params. This reduces the cost of not
- * logging by about 20 nanoseconds.
- */
-
- private void filterAndLog_0_Or3Plus(final String localFQCN, final Marker marker, final Level level, final String msg, final Object[] params,
- final Throwable t) {
-
- final 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);
- }
-
- private void filterAndLog_1(final String localFQCN, final Marker marker, final Level level, final String msg, final Object param, final Throwable t) {
-
- final FilterReply decision = loggerContext.getTurboFilterChainDecision_1(marker, this, level, msg, param, t);
-
- if (decision == FilterReply.NEUTRAL) {
- if (effectiveLevelInt > level.levelInt) {
- return;
- }
- } else if (decision == FilterReply.DENY) {
- return;
- }
-
- buildLoggingEventAndAppend(localFQCN, marker, level, msg, new Object[] { param }, t);
- }
-
- private void filterAndLog_2(final String localFQCN, final Marker marker, final Level level, final String msg, final Object param1, final Object param2,
- final Throwable t) {
-
- final FilterReply decision = loggerContext.getTurboFilterChainDecision_2(marker, this, level, msg, param1, param2, t);
-
- if (decision == FilterReply.NEUTRAL) {
- if (effectiveLevelInt > level.levelInt) {
- return;
- }
- } else if (decision == FilterReply.DENY) {
- return;
- }
-
- buildLoggingEventAndAppend(localFQCN, marker, level, msg, new Object[] { param1, param2 }, t);
- }
-
- private void buildLoggingEventAndAppend(final String localFQCN, final Marker marker, final Level level, final String msg, final Object[] params,
- final Throwable t) {
- LoggingEvent le = new LoggingEvent(localFQCN, this, level, msg, t, params);
- le.setMarker(marker);
- callAppenders(le);
- }
-
- public void trace(String msg) {
- filterAndLog_0_Or3Plus(FQCN, null, Level.TRACE, msg, null, null);
- }
-
- public void trace(String format, Object arg) {
- filterAndLog_1(FQCN, null, Level.TRACE, format, arg, null);
- }
-
- public void trace(String format, Object arg1, Object arg2) {
- filterAndLog_2(FQCN, null, Level.TRACE, format, arg1, arg2, null);
- }
-
- public void trace(String format, Object... argArray) {
- filterAndLog_0_Or3Plus(FQCN, null, Level.TRACE, format, argArray, null);
- }
-
- public void trace(String msg, Throwable t) {
- filterAndLog_0_Or3Plus(FQCN, null, Level.TRACE, msg, null, t);
- }
-
- public void trace(Marker marker, String msg) {
- filterAndLog_0_Or3Plus(FQCN, marker, Level.TRACE, msg, null, null);
- }
-
- public void trace(Marker marker, String format, Object arg) {
- filterAndLog_1(FQCN, marker, Level.TRACE, format, arg, null);
- }
-
- public void trace(Marker marker, String format, Object arg1, Object arg2) {
- filterAndLog_2(FQCN, marker, Level.TRACE, format, arg1, arg2, null);
- }
-
- public void trace(Marker marker, String format, Object... argArray) {
- filterAndLog_0_Or3Plus(FQCN, marker, Level.TRACE, format, argArray, null);
- }
-
- public void trace(Marker marker, String msg, Throwable t) {
- filterAndLog_0_Or3Plus(FQCN, marker, Level.TRACE, msg, null, t);
- }
-
- public boolean isDebugEnabled() {
- return isDebugEnabled(null);
- }
-
- public boolean isDebugEnabled(Marker marker) {
- final FilterReply decision = callTurboFilters(marker, Level.DEBUG);
- if (decision == FilterReply.NEUTRAL) {
- return effectiveLevelInt <= Level.DEBUG_INT;
- } else if (decision == FilterReply.DENY) {
- return false;
- } else if (decision == FilterReply.ACCEPT) {
- return true;
- } else {
- throw new IllegalStateException("Unknown FilterReply value: " + decision);
- }
- }
-
- public void debug(String msg) {
- filterAndLog_0_Or3Plus(FQCN, null, Level.DEBUG, msg, null, null);
- }
-
- public void debug(String format, Object arg) {
- filterAndLog_1(FQCN, null, Level.DEBUG, format, arg, null);
- }
-
- public void debug(String format, Object arg1, Object arg2) {
- filterAndLog_2(FQCN, null, Level.DEBUG, format, arg1, arg2, null);
- }
-
- public void debug(String format, Object... argArray) {
- filterAndLog_0_Or3Plus(FQCN, null, Level.DEBUG, format, argArray, null);
- }
-
- public void debug(String msg, Throwable t) {
- filterAndLog_0_Or3Plus(FQCN, null, Level.DEBUG, msg, null, t);
- }
-
- public void debug(Marker marker, String msg) {
- filterAndLog_0_Or3Plus(FQCN, marker, Level.DEBUG, msg, null, null);
- }
-
- public void debug(Marker marker, String format, Object arg) {
- filterAndLog_1(FQCN, marker, Level.DEBUG, format, arg, null);
- }
-
- public void debug(Marker marker, String format, Object arg1, Object arg2) {
- filterAndLog_2(FQCN, marker, Level.DEBUG, format, arg1, arg2, null);
- }
-
- public void debug(Marker marker, String format, Object... argArray) {
- filterAndLog_0_Or3Plus(FQCN, marker, Level.DEBUG, format, argArray, null);
- }
-
- public void debug(Marker marker, String msg, Throwable t) {
- filterAndLog_0_Or3Plus(FQCN, marker, Level.DEBUG, msg, null, t);
- }
-
- public void error(String msg) {
- filterAndLog_0_Or3Plus(FQCN, null, Level.ERROR, msg, null, null);
- }
-
- public void error(String format, Object arg) {
- filterAndLog_1(FQCN, null, Level.ERROR, format, arg, null);
- }
-
- public void error(String format, Object arg1, Object arg2) {
- filterAndLog_2(FQCN, null, Level.ERROR, format, arg1, arg2, null);
- }
-
- public void error(String format, Object... argArray) {
- filterAndLog_0_Or3Plus(FQCN, null, Level.ERROR, format, argArray, null);
- }
-
- public void error(String msg, Throwable t) {
- filterAndLog_0_Or3Plus(FQCN, null, Level.ERROR, msg, null, t);
- }
-
- public void error(Marker marker, String msg) {
- filterAndLog_0_Or3Plus(FQCN, marker, Level.ERROR, msg, null, null);
- }
-
- public void error(Marker marker, String format, Object arg) {
- filterAndLog_1(FQCN, marker, Level.ERROR, format, arg, null);
- }
-
- public void error(Marker marker, String format, Object arg1, Object arg2) {
- filterAndLog_2(FQCN, marker, Level.ERROR, format, arg1, arg2, null);
- }
-
- public void error(Marker marker, String format, Object... argArray) {
- filterAndLog_0_Or3Plus(FQCN, marker, Level.ERROR, format, argArray, null);
- }
-
- public void error(Marker marker, String msg, Throwable t) {
- filterAndLog_0_Or3Plus(FQCN, marker, Level.ERROR, msg, null, t);
- }
-
- public boolean isInfoEnabled() {
- return isInfoEnabled(null);
- }
-
- public boolean isInfoEnabled(Marker marker) {
- FilterReply decision = callTurboFilters(marker, Level.INFO);
- if (decision == FilterReply.NEUTRAL) {
- return effectiveLevelInt <= Level.INFO_INT;
- } else if (decision == FilterReply.DENY) {
- return false;
- } else if (decision == FilterReply.ACCEPT) {
- return true;
- } else {
- throw new IllegalStateException("Unknown FilterReply value: " + decision);
- }
- }
-
- public void info(String msg) {
- filterAndLog_0_Or3Plus(FQCN, null, Level.INFO, msg, null, null);
- }
-
- public void info(String format, Object arg) {
- filterAndLog_1(FQCN, null, Level.INFO, format, arg, null);
- }
-
- public void info(String format, Object arg1, Object arg2) {
- filterAndLog_2(FQCN, null, Level.INFO, format, arg1, arg2, null);
- }
-
- public void info(String format, Object... argArray) {
- filterAndLog_0_Or3Plus(FQCN, null, Level.INFO, format, argArray, null);
- }
-
- public void info(String msg, Throwable t) {
- filterAndLog_0_Or3Plus(FQCN, null, Level.INFO, msg, null, t);
- }
-
- public void info(Marker marker, String msg) {
- filterAndLog_0_Or3Plus(FQCN, marker, Level.INFO, msg, null, null);
- }
-
- public void info(Marker marker, String format, Object arg) {
- filterAndLog_1(FQCN, marker, Level.INFO, format, arg, null);
- }
-
- public void info(Marker marker, String format, Object arg1, Object arg2) {
- filterAndLog_2(FQCN, marker, Level.INFO, format, arg1, arg2, null);
- }
-
- public void info(Marker marker, String format, Object... argArray) {
- filterAndLog_0_Or3Plus(FQCN, marker, Level.INFO, format, argArray, null);
- }
-
- public void info(Marker marker, String msg, Throwable t) {
- filterAndLog_0_Or3Plus(FQCN, marker, Level.INFO, msg, null, t);
- }
-
- public boolean isTraceEnabled() {
- return isTraceEnabled(null);
- }
-
- public boolean isTraceEnabled(Marker marker) {
- final FilterReply decision = callTurboFilters(marker, Level.TRACE);
- if (decision == FilterReply.NEUTRAL) {
- return effectiveLevelInt <= Level.TRACE_INT;
- } else if (decision == FilterReply.DENY) {
- return false;
- } else if (decision == FilterReply.ACCEPT) {
- return true;
- } else {
- throw new IllegalStateException("Unknown FilterReply value: " + decision);
- }
- }
-
- public boolean isErrorEnabled() {
- return isErrorEnabled(null);
- }
-
- public boolean isErrorEnabled(Marker marker) {
- FilterReply decision = callTurboFilters(marker, Level.ERROR);
- if (decision == FilterReply.NEUTRAL) {
- return effectiveLevelInt <= Level.ERROR_INT;
- } else if (decision == FilterReply.DENY) {
- return false;
- } else if (decision == FilterReply.ACCEPT) {
- return true;
- } else {
- throw new IllegalStateException("Unknown FilterReply value: " + decision);
- }
- }
-
- public boolean isWarnEnabled() {
- return isWarnEnabled(null);
- }
-
- public boolean isWarnEnabled(Marker marker) {
- FilterReply decision = callTurboFilters(marker, Level.WARN);
- if (decision == FilterReply.NEUTRAL) {
- return effectiveLevelInt <= Level.WARN_INT;
- } else if (decision == FilterReply.DENY) {
- return false;
- } else if (decision == FilterReply.ACCEPT) {
- return true;
- } else {
- throw new IllegalStateException("Unknown FilterReply value: " + decision);
- }
-
- }
-
- public boolean isEnabledFor(Marker marker, Level level) {
- FilterReply decision = callTurboFilters(marker, level);
- if (decision == FilterReply.NEUTRAL) {
- return effectiveLevelInt <= level.levelInt;
- } else if (decision == FilterReply.DENY) {
- return false;
- } else if (decision == FilterReply.ACCEPT) {
- return true;
- } else {
- throw new IllegalStateException("Unknown FilterReply value: " + decision);
- }
- }
-
- public boolean isEnabledFor(Level level) {
- return isEnabledFor(null, level);
- }
-
- public void warn(String msg) {
- filterAndLog_0_Or3Plus(FQCN, null, Level.WARN, msg, null, null);
- }
-
- public void warn(String msg, Throwable t) {
- filterAndLog_0_Or3Plus(FQCN, null, Level.WARN, msg, null, t);
- }
-
- public void warn(String format, Object arg) {
- filterAndLog_1(FQCN, null, Level.WARN, format, arg, null);
- }
-
- public void warn(String format, Object arg1, Object arg2) {
- filterAndLog_2(FQCN, null, Level.WARN, format, arg1, arg2, null);
- }
-
- public void warn(String format, Object... argArray) {
- filterAndLog_0_Or3Plus(FQCN, null, Level.WARN, format, argArray, null);
- }
-
- public void warn(Marker marker, String msg) {
- filterAndLog_0_Or3Plus(FQCN, marker, Level.WARN, msg, null, null);
- }
-
- public void warn(Marker marker, String format, Object arg) {
- filterAndLog_1(FQCN, marker, Level.WARN, format, arg, null);
- }
-
- public void warn(Marker marker, String format, Object... argArray) {
- filterAndLog_0_Or3Plus(FQCN, marker, Level.WARN, format, argArray, null);
- }
-
- public void warn(Marker marker, String format, Object arg1, Object arg2) {
- filterAndLog_2(FQCN, marker, Level.WARN, format, arg1, arg2, null);
- }
-
- public void warn(Marker marker, String msg, Throwable t) {
- filterAndLog_0_Or3Plus(FQCN, marker, Level.WARN, msg, null, t);
- }
-
- public boolean isAdditive() {
- return additive;
- }
-
- public void setAdditive(boolean additive) {
- this.additive = additive;
- }
-
- public String toString() {
- return "Logger[" + name + "]";
- }
-
- /**
- * Method that calls the attached TurboFilter objects based on the logger and
- * the level.
- *
- * It is used by isYYYEnabled() methods.
- *
- * It returns the typical FilterReply values: ACCEPT, NEUTRAL or DENY.
- *
- * @param level
- * @return the reply given by the TurboFilters
- */
- private FilterReply callTurboFilters(Marker marker, Level level) {
- return loggerContext.getTurboFilterChainDecision_0_3OrMore(marker, this, level, null, null, null);
- }
-
- /**
- * Return the context for this logger.
- *
- * @return the context
- */
- public LoggerContext getLoggerContext() {
- return loggerContext;
- }
-
- public void log(Marker marker, String fqcn, int levelInt, String message, Object[] argArray, Throwable t) {
- Level level = Level.fromLocationAwareLoggerInteger(levelInt);
- filterAndLog_0_Or3Plus(fqcn, marker, level, message, argArray, t);
- }
-
- /**
- * Support SLF4J interception during initialization as introduced in SLF4J version 1.7.15
- * @since 1.1.4
- * @param slf4jEvent
- */
- public void log(org.slf4j.event.LoggingEvent slf4jEvent) {
- Level level = Level.fromLocationAwareLoggerInteger(slf4jEvent.getLevel().toInt());
- filterAndLog_0_Or3Plus(FQCN, slf4jEvent.getMarker(), level, slf4jEvent.getMessage(), slf4jEvent.getArgumentArray(), slf4jEvent.getThrowable());
- }
-
- /**
- * After serialization, the logger instance does not know its LoggerContext.
- * The best we can do here, is to return a logger with the same name
- * returned by org.slf4j.LoggerFactory.
- *
- * @return Logger instance with the same name
- * @throws ObjectStreamException
- */
- protected Object readResolve() throws ObjectStreamException {
- return LoggerFactory.getLogger(getName());
- }
+public final class Logger implements org.slf4j.Logger, LocationAwareLogger,
+ AppenderAttachable<ILoggingEvent>, Serializable {
+
+ private static final long serialVersionUID = 5454405123156820674L; //8745934908040027998L;
+
+ /**
+ * The fully qualified name of this class. Used in gathering caller
+ * information.
+ */
+ public static final String FQCN = ch.qos.logback.classic.Logger.class
+ .getName();
+
+ /**
+ * The name of this logger
+ */
+ private String name;
+
+ // The assigned levelInt of this logger. Can be null.
+ transient private Level level;
+
+ // The effective levelInt is the assigned levelInt and if null, a levelInt is
+ // inherited form a parent.
+ transient private int effectiveLevelInt;
+
+ /**
+ * The parent of this category. All categories have at least one ancestor
+ * which is the root category.
+ */
+ transient private Logger parent;
+
+ /**
+ * The children of this logger. A logger may have zero or more children.
+ */
+ transient private List<Logger> childrenList;
+
+ /**
+ * It is assumed that once the 'aai' variable is set to a non-null value, it
+ * will never be reset to null. it is further assumed that only place where
+ * the 'aai'ariable is set is within the addAppender method. This method is
+ * synchronized on 'this' (Logger) protecting against simultaneous
+ * re-configuration of this logger (a very unlikely scenario).
+ *
+ * <p>
+ * It is further assumed that the AppenderAttachableImpl is responsible for
+ * its internal synchronization and thread safety. Thus, we can get away with
+ * *not* synchronizing on the 'aai' (check null/ read) because
+ * <p>
+ * 1) the 'aai' variable is immutable once set to non-null
+ * <p>
+ * 2) 'aai' is getAndSet only within addAppender which is synchronized
+ * <p>
+ * 3) all the other methods check whether 'aai' is null
+ * <p>
+ * 4) AppenderAttachableImpl is thread safe
+ */
+ transient private AppenderAttachableImpl<ILoggingEvent> aai;
+ /**
+ * Additivity is set to true by default, that is children inherit the
+ * appenders of their ancestors by default. If this variable is set to
+ * <code>false</code> then the appenders located in the ancestors of this
+ * logger will not be used. However, the children of this logger will inherit
+ * its appenders, unless the children have their additivity flag set to
+ * <code>false</code> too. See the user manual for more details.
+ */
+ transient private boolean additive = true;
+
+ final transient LoggerContext loggerContext;
+
+ Logger(String name, Logger parent, LoggerContext loggerContext) {
+ this.name = name;
+ this.parent = parent;
+ this.loggerContext = loggerContext;
+ }
+
+ public Level getEffectiveLevel() {
+ return Level.toLevel(effectiveLevelInt);
+ }
+
+ int getEffectiveLevelInt() {
+ return effectiveLevelInt;
+ }
+
+ public Level getLevel() {
+ return level;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ private boolean isRootLogger() {
+ // only the root logger has a null parent
+ return parent == null;
+ }
+
+ Logger getChildByName(final String childName) {
+ if (childrenList == null) {
+ return null;
+ } else {
+ int len = this.childrenList.size();
+ for (int i = 0; i < len; i++) {
+ final Logger childLogger_i = (Logger) childrenList.get(i);
+ final String childName_i = childLogger_i.getName();
+
+ if (childName.equals(childName_i)) {
+ return childLogger_i;
+ }
+ }
+ // no child found
+ return null;
+ }
+ }
+
+ public synchronized void setLevel(Level newLevel) {
+ if (level == newLevel) {
+ // nothing to do;
+ return;
+ }
+ if (newLevel == null && isRootLogger()) {
+ throw new IllegalArgumentException(
+ "The level of the root logger cannot be set to null");
+ }
+
+ level = newLevel;
+ if (newLevel == null) {
+ effectiveLevelInt = parent.effectiveLevelInt;
+ newLevel = parent.getEffectiveLevel();
+ } else {
+ effectiveLevelInt = newLevel.levelInt;
+ }
+
+ if (childrenList != null) {
+ int len = childrenList.size();
+ for (int i = 0; i < len; i++) {
+ Logger child = (Logger) childrenList.get(i);
+ // tell child to handle parent levelInt change
+ child.handleParentLevelChange(effectiveLevelInt);
+ }
+ }
+ // inform listeners
+ loggerContext.fireOnLevelChange(this, newLevel);
+ }
+
+ /**
+ * This method is invoked by parent logger to let this logger know that the
+ * prent's levelInt changed.
+ *
+ * @param newParentLevelInt
+ */
+ private synchronized void handleParentLevelChange(int newParentLevelInt) {
+ // changes in the parent levelInt affect children only if their levelInt is
+ // null
+ if (level == null) {
+ effectiveLevelInt = newParentLevelInt;
+
+ // propagate the parent levelInt change to this logger's children
+ if (childrenList != null) {
+ int len = childrenList.size();
+ for (int i = 0; i < len; i++) {
+ Logger child = (Logger) childrenList.get(i);
+ child.handleParentLevelChange(newParentLevelInt);
+ }
+ }
+ }
+ }
+
+ /**
+ * Remove all previously added appenders from this logger instance.
+ * <p/>
+ * This is useful when re-reading configuration information.
+ */
+ public void detachAndStopAllAppenders() {
+ if (aai != null) {
+ aai.detachAndStopAllAppenders();
+ }
+ }
+
+ public boolean detachAppender(String name) {
+ if (aai == null) {
+ return false;
+ }
+ return aai.detachAppender(name);
+ }
+
+ // this method MUST be synchronized. See comments on 'aai' field for further
+ // details.
+ public synchronized void addAppender(Appender<ILoggingEvent> newAppender) {
+ if (aai == null) {
+ aai = new AppenderAttachableImpl<ILoggingEvent>();
+ }
+ aai.addAppender(newAppender);
+ }
+
+ public boolean isAttached(Appender<ILoggingEvent> appender) {
+ if (aai == null) {
+ return false;
+ }
+ return aai.isAttached(appender);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Iterator<Appender<ILoggingEvent>> iteratorForAppenders() {
+ if (aai == null) {
+ return Collections.EMPTY_LIST.iterator();
+ }
+ return aai.iteratorForAppenders();
+ }
+
+ public Appender<ILoggingEvent> getAppender(String name) {
+ if (aai == null) {
+ return null;
+ }
+ return aai.getAppender(name);
+ }
+
+ /**
+ * Invoke all the appenders of this logger.
+ *
+ * @param event
+ * The event to log
+ */
+ public void callAppenders(ILoggingEvent event) {
+ int writes = 0;
+ for (Logger l = this; l != null; l = l.parent) {
+ writes += l.appendLoopOnAppenders(event);
+ if (!l.additive) {
+ break;
+ }
+ }
+ // No appenders in hierarchy
+ if (writes == 0) {
+ loggerContext.noAppenderDefinedWarning(this);
+ }
+ }
+
+ private int appendLoopOnAppenders(ILoggingEvent event) {
+ if (aai != null) {
+ return aai.appendLoopOnAppenders(event);
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Remove the appender passed as parameter form the list of appenders.
+ */
+ public boolean detachAppender(Appender<ILoggingEvent> appender) {
+ if (aai == null) {
+ return false;
+ }
+ return aai.detachAppender(appender);
+ }
+
+
+
+ /**
+ * Create a child of this logger by suffix, that is, the part of the name
+ * extending this logger. For example, if this logger is named "x.y" and the
+ * lastPart is "z", then the created child logger will be named "x.y.z".
+ *
+ * <p>
+ * IMPORTANT: Calls to this method must be within a synchronized block on this
+ * logger.
+ *
+ * @param lastPart
+ * the suffix (i.e. last part) of the child logger name. This
+ * parameter may not include dots, i.e. the logger separator
+ * character.
+ * @return
+ */
+ Logger createChildByLastNamePart(final String lastPart) {
+ int i_index = LoggerNameUtil.getFirstSeparatorIndexOf(lastPart);
+ if (i_index != -1) {
+ throw new IllegalArgumentException("Child name [" + lastPart
+ + " passed as parameter, may not include [" + CoreConstants.DOT + "]");
+ }
+
+ if (childrenList == null) {
+ childrenList = new ArrayList<Logger>();
+ }
+ Logger childLogger;
+ if (this.isRootLogger()) {
+ childLogger = new Logger(lastPart, this, this.loggerContext);
+ } else {
+ childLogger = new Logger(name + CoreConstants.DOT + lastPart, this,
+ this.loggerContext);
+ }
+ childrenList.add(childLogger);
+ childLogger.effectiveLevelInt = this.effectiveLevelInt;
+ return childLogger;
+ }
+
+ private void localLevelReset() {
+ effectiveLevelInt = Level.DEBUG_INT;
+ if (isRootLogger()) {
+ level = Level.DEBUG;
+ } else {
+ level = null;
+ }
+ }
+
+ void recursiveReset() {
+ detachAndStopAllAppenders();
+ localLevelReset();
+ additive = true;
+ if (childrenList == null) {
+ return;
+ }
+ for (Logger childLogger : childrenList) {
+ childLogger.recursiveReset();
+ }
+ }
+
+ /**
+ * The default size of child list arrays. The JDK 1.5 default is 10. We use a
+ * smaller value to save a little space.
+ */
+ private static final int DEFAULT_CHILD_ARRAY_SIZE = 5;
+
+ Logger createChildByName(final String childName) {
+ int i_index = LoggerNameUtil.getSeparatorIndexOf(childName, this.name.length() + 1);
+ if (i_index != -1) {
+ throw new IllegalArgumentException("For logger [" + this.name
+ + "] child name [" + childName
+ + " passed as parameter, may not include '.' after index"
+ + (this.name.length() + 1));
+ }
+
+ if (childrenList == null) {
+ childrenList = new ArrayList<Logger>(DEFAULT_CHILD_ARRAY_SIZE);
+ }
+ Logger childLogger;
+ childLogger = new Logger(childName, this, this.loggerContext);
+ childrenList.add(childLogger);
+ childLogger.effectiveLevelInt = this.effectiveLevelInt;
+ return childLogger;
+ }
+
+ /**
+ * The next methods are not merged into one because of the time we gain by not
+ * creating a new Object[] with the params. This reduces the cost of not
+ * logging by about 20 nanoseconds.
+ */
+
+ private void filterAndLog_0_Or3Plus(final String localFQCN,
+ final Marker marker, final Level level, final String msg,
+ final Object[] params, final Throwable t) {
+
+ final 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);
+ }
+
+ private void filterAndLog_1(final String localFQCN,
+ final Marker marker, final Level level, final String msg,
+ final Object param, final Throwable t) {
+
+ final FilterReply decision = loggerContext.getTurboFilterChainDecision_1(
+ marker, this, level, msg, param, t);
+
+ if (decision == FilterReply.NEUTRAL) {
+ if (effectiveLevelInt > level.levelInt) {
+ return;
+ }
+ } else if (decision == FilterReply.DENY) {
+ return;
+ }
+
+ buildLoggingEventAndAppend(localFQCN, marker, level, msg,
+ new Object[] { param }, t);
+ }
+
+ private void filterAndLog_2(final String localFQCN,
+ final Marker marker, final Level level, final String msg,
+ final Object param1, final Object param2, final Throwable t) {
+
+ final FilterReply decision = loggerContext.getTurboFilterChainDecision_2(
+ marker, this, level, msg, param1, param2, t);
+
+ if (decision == FilterReply.NEUTRAL) {
+ if (effectiveLevelInt > level.levelInt) {
+ return;
+ }
+ } else if (decision == FilterReply.DENY) {
+ return;
+ }
+
+ buildLoggingEventAndAppend(localFQCN, marker, level, msg, new Object[] {
+ param1, param2 }, t);
+ }
+
+ private void buildLoggingEventAndAppend(final String localFQCN,
+ final Marker marker, final Level level, final String msg,
+ final Object[] params, final Throwable t) {
+ LoggingEvent le = new LoggingEvent(localFQCN, this, level, msg, t, params);
+ le.setMarker(marker);
+ callAppenders(le);
+ }
+
+ public void trace(String msg) {
+ filterAndLog_0_Or3Plus(FQCN, null, Level.TRACE, msg, null, null);
+ }
+
+ public void trace(String format, Object arg) {
+ filterAndLog_1(FQCN, null, Level.TRACE, format, arg, null);
+ }
+
+ public void trace(String format, Object arg1, Object arg2) {
+ filterAndLog_2(FQCN, null, Level.TRACE, format, arg1, arg2, null);
+ }
+
+ public void trace(String format, Object[] argArray) {
+ filterAndLog_0_Or3Plus(FQCN, null, Level.TRACE, format, argArray, null);
+ }
+
+ public void trace(String msg, Throwable t) {
+ filterAndLog_0_Or3Plus(FQCN, null, Level.TRACE, msg, null, t);
+ }
+
+ public void trace(Marker marker, String msg) {
+ filterAndLog_0_Or3Plus(FQCN, marker, Level.TRACE, msg, null, null);
+ }
+
+ public void trace(Marker marker, String format, Object arg) {
+ filterAndLog_1(FQCN, marker, Level.TRACE, format, arg, null);
+ }
+
+ public void trace(Marker marker, String format, Object arg1, Object arg2) {
+ filterAndLog_2(FQCN, marker, Level.TRACE, format, arg1, arg2, null);
+ }
+
+ public void trace(Marker marker, String format, Object[] argArray) {
+ filterAndLog_0_Or3Plus(FQCN, marker, Level.TRACE, format, argArray, null);
+ }
+
+ public void trace(Marker marker, String msg, Throwable t) {
+ filterAndLog_0_Or3Plus(FQCN, marker, Level.TRACE, msg, null, t);
+ }
+
+ public boolean isDebugEnabled() {
+ return isDebugEnabled(null);
+ }
+
+ public boolean isDebugEnabled(Marker marker) {
+ final FilterReply decision = callTurboFilters(marker, Level.DEBUG);
+ if (decision == FilterReply.NEUTRAL) {
+ return effectiveLevelInt <= Level.DEBUG_INT;
+ } else if (decision == FilterReply.DENY) {
+ return false;
+ } else if (decision == FilterReply.ACCEPT) {
+ return true;
+ } else {
+ throw new IllegalStateException("Unknown FilterReply value: " + decision);
+ }
+ }
+
+ public void debug(String msg) {
+ filterAndLog_0_Or3Plus(FQCN, null, Level.DEBUG, msg, null, null);
+ }
+
+ public void debug(String format, Object arg) {
+ filterAndLog_1(FQCN, null, Level.DEBUG, format, arg, null);
+ }
+
+ public void debug(String format, Object arg1, Object arg2) {
+ filterAndLog_2(FQCN, null, Level.DEBUG, format, arg1, arg2, null);
+ }
+
+ public void debug(String format, Object[] argArray) {
+ filterAndLog_0_Or3Plus(FQCN, null, Level.DEBUG, format, argArray, null);
+ }
+
+ public void debug(String msg, Throwable t) {
+ filterAndLog_0_Or3Plus(FQCN, null, Level.DEBUG, msg, null, t);
+ }
+
+ public void debug(Marker marker, String msg) {
+ filterAndLog_0_Or3Plus(FQCN, marker, Level.DEBUG, msg, null, null);
+ }
+
+ public void debug(Marker marker, String format, Object arg) {
+ filterAndLog_1(FQCN, marker, Level.DEBUG, format, arg, null);
+ }
+
+ public void debug(Marker marker, String format, Object arg1, Object arg2) {
+ filterAndLog_2(FQCN, marker, Level.DEBUG, format, arg1, arg2, null);
+ }
+
+ public void debug(Marker marker, String format, Object[] argArray) {
+ filterAndLog_0_Or3Plus(FQCN, marker, Level.DEBUG, format, argArray, null);
+ }
+
+ public void debug(Marker marker, String msg, Throwable t) {
+ filterAndLog_0_Or3Plus(FQCN, marker, Level.DEBUG, msg, null, t);
+ }
+
+ public void error(String msg) {
+ filterAndLog_0_Or3Plus(FQCN, null, Level.ERROR, msg, null, null);
+ }
+
+ public void error(String format, Object arg) {
+ filterAndLog_1(FQCN, null, Level.ERROR, format, arg, null);
+ }
+
+ public void error(String format, Object arg1, Object arg2) {
+ filterAndLog_2(FQCN, null, Level.ERROR, format, arg1, arg2, null);
+ }
+
+ public void error(String format, Object[] argArray) {
+ filterAndLog_0_Or3Plus(FQCN, null, Level.ERROR, format, argArray, null);
+ }
+
+ public void error(String msg, Throwable t) {
+ filterAndLog_0_Or3Plus(FQCN, null, Level.ERROR, msg, null, t);
+ }
+
+ public void error(Marker marker, String msg) {
+ filterAndLog_0_Or3Plus(FQCN, marker, Level.ERROR, msg, null, null);
+ }
+
+ public void error(Marker marker, String format, Object arg) {
+ filterAndLog_1(FQCN, marker, Level.ERROR, format, arg, null);
+ }
+
+ public void error(Marker marker, String format, Object arg1, Object arg2) {
+ filterAndLog_2(FQCN, marker, Level.ERROR, format, arg1, arg2, null);
+ }
+
+ public void error(Marker marker, String format, Object[] argArray) {
+ filterAndLog_0_Or3Plus(FQCN, marker, Level.ERROR, format, argArray, null);
+ }
+
+ public void error(Marker marker, String msg, Throwable t) {
+ filterAndLog_0_Or3Plus(FQCN, marker, Level.ERROR, msg, null, t);
+ }
+
+ public boolean isInfoEnabled() {
+ return isInfoEnabled(null);
+ }
+
+ public boolean isInfoEnabled(Marker marker) {
+ FilterReply decision = callTurboFilters(marker, Level.INFO);
+ if (decision == FilterReply.NEUTRAL) {
+ return effectiveLevelInt <= Level.INFO_INT;
+ } else if (decision == FilterReply.DENY) {
+ return false;
+ } else if (decision == FilterReply.ACCEPT) {
+ return true;
+ } else {
+ throw new IllegalStateException("Unknown FilterReply value: " + decision);
+ }
+ }
+
+ public void info(String msg) {
+ filterAndLog_0_Or3Plus(FQCN, null, Level.INFO, msg, null, null);
+ }
+
+ public void info(String format, Object arg) {
+ filterAndLog_1(FQCN, null, Level.INFO, format, arg, null);
+ }
+
+ public void info(String format, Object arg1, Object arg2) {
+ filterAndLog_2(FQCN, null, Level.INFO, format, arg1, arg2, null);
+ }
+
+ public void info(String format, Object[] argArray) {
+ filterAndLog_0_Or3Plus(FQCN, null, Level.INFO, format, argArray, null);
+ }
+
+ public void info(String msg, Throwable t) {
+ filterAndLog_0_Or3Plus(FQCN, null, Level.INFO, msg, null, t);
+ }
+
+ public void info(Marker marker, String msg) {
+ filterAndLog_0_Or3Plus(FQCN, marker, Level.INFO, msg, null, null);
+ }
+
+ public void info(Marker marker, String format, Object arg) {
+ filterAndLog_1(FQCN, marker, Level.INFO, format, arg, null);
+ }
+
+ public void info(Marker marker, String format, Object arg1, Object arg2) {
+ filterAndLog_2(FQCN, marker, Level.INFO, format, arg1, arg2, null);
+ }
+
+ public void info(Marker marker, String format, Object[] argArray) {
+ filterAndLog_0_Or3Plus(FQCN, marker, Level.INFO, format, argArray, null);
+ }
+
+ public void info(Marker marker, String msg, Throwable t) {
+ filterAndLog_0_Or3Plus(FQCN, marker, Level.INFO, msg, null, t);
+ }
+
+ public boolean isTraceEnabled() {
+ return isTraceEnabled(null);
+ }
+
+ public boolean isTraceEnabled(Marker marker) {
+ final FilterReply decision = callTurboFilters(marker, Level.TRACE);
+ if (decision == FilterReply.NEUTRAL) {
+ return effectiveLevelInt <= Level.TRACE_INT;
+ } else if (decision == FilterReply.DENY) {
+ return false;
+ } else if (decision == FilterReply.ACCEPT) {
+ return true;
+ } else {
+ throw new IllegalStateException("Unknown FilterReply value: " + decision);
+ }
+ }
+
+ public boolean isErrorEnabled() {
+ return isErrorEnabled(null);
+ }
+
+ public boolean isErrorEnabled(Marker marker) {
+ FilterReply decision = callTurboFilters(marker, Level.ERROR);
+ if (decision == FilterReply.NEUTRAL) {
+ return effectiveLevelInt <= Level.ERROR_INT;
+ } else if (decision == FilterReply.DENY) {
+ return false;
+ } else if (decision == FilterReply.ACCEPT) {
+ return true;
+ } else {
+ throw new IllegalStateException("Unknown FilterReply value: " + decision);
+ }
+ }
+
+ public boolean isWarnEnabled() {
+ return isWarnEnabled(null);
+ }
+
+ public boolean isWarnEnabled(Marker marker) {
+ FilterReply decision = callTurboFilters(marker, Level.WARN);
+ if (decision == FilterReply.NEUTRAL) {
+ return effectiveLevelInt <= Level.WARN_INT;
+ } else if (decision == FilterReply.DENY) {
+ return false;
+ } else if (decision == FilterReply.ACCEPT) {
+ return true;
+ } else {
+ throw new IllegalStateException("Unknown FilterReply value: " + decision);
+ }
+
+ }
+
+ public boolean isEnabledFor(Marker marker, Level level) {
+ FilterReply decision = callTurboFilters(marker, level);
+ if (decision == FilterReply.NEUTRAL) {
+ return effectiveLevelInt <= level.levelInt;
+ } else if (decision == FilterReply.DENY) {
+ return false;
+ } else if (decision == FilterReply.ACCEPT) {
+ return true;
+ } else {
+ throw new IllegalStateException("Unknown FilterReply value: " + decision);
+ }
+ }
+
+ public boolean isEnabledFor(Level level) {
+ return isEnabledFor(null, level);
+ }
+
+ public void warn(String msg) {
+ filterAndLog_0_Or3Plus(FQCN, null, Level.WARN, msg, null, null);
+ }
+
+ public void warn(String msg, Throwable t) {
+ filterAndLog_0_Or3Plus(FQCN, null, Level.WARN, msg, null, t);
+ }
+
+ public void warn(String format, Object arg) {
+ filterAndLog_1(FQCN, null, Level.WARN, format, arg, null);
+ }
+
+ public void warn(String format, Object arg1, Object arg2) {
+ filterAndLog_2(FQCN, null, Level.WARN, format, arg1, arg2, null);
+ }
+
+ public void warn(String format, Object[] argArray) {
+ filterAndLog_0_Or3Plus(FQCN, null, Level.WARN, format, argArray, null);
+ }
+
+ public void warn(Marker marker, String msg) {
+ filterAndLog_0_Or3Plus(FQCN, marker, Level.WARN, msg, null, null);
+ }
+
+ public void warn(Marker marker, String format, Object arg) {
+ filterAndLog_1(FQCN, marker, Level.WARN, format, arg, null);
+ }
+
+ public void warn(Marker marker, String format, Object[] argArray) {
+ filterAndLog_0_Or3Plus(FQCN, marker, Level.WARN, format, argArray, null);
+ }
+
+ public void warn(Marker marker, String format, Object arg1, Object arg2) {
+ filterAndLog_2(FQCN, marker, Level.WARN, format, arg1, arg2, null);
+ }
+
+ public void warn(Marker marker, String msg, Throwable t) {
+ filterAndLog_0_Or3Plus(FQCN, marker, Level.WARN, msg, null, t);
+ }
+
+ public boolean isAdditive() {
+ return additive;
+ }
+
+ public void setAdditive(boolean additive) {
+ this.additive = additive;
+ }
+
+ public String toString() {
+ return "Logger[" + name + "]";
+ }
+
+ /**
+ * Method that calls the attached TurboFilter objects based on the logger and
+ * the level.
+ *
+ * It is used by isYYYEnabled() methods.
+ *
+ * It returns the typical FilterReply values: ACCEPT, NEUTRAL or DENY.
+ *
+ * @param level
+ * @return the reply given by the TurboFilters
+ */
+ private FilterReply callTurboFilters(Marker marker, Level level) {
+ return loggerContext.getTurboFilterChainDecision_0_3OrMore(marker, this,
+ level, null, null, null);
+ }
+
+ /**
+ * Return the context for this logger.
+ *
+ * @return the context
+ */
+ public LoggerContext getLoggerContext() {
+ return loggerContext;
+ }
+
+ public void log(Marker marker, String fqcn, int levelInt, String message,
+ Object[] argArray, Throwable t) {
+ Level level = Level.fromLocationAwareLoggerInteger(levelInt);
+ filterAndLog_0_Or3Plus(fqcn, marker, level, message, argArray, t);
+ }
+
+ /**
+ * After serialization, the logger instance does not know its LoggerContext.
+ * The best we can do here, is to return a logger with the same name
+ * returned by org.slf4j.LoggerFactory.
+ *
+ * @return Logger instance with the same name
+ * @throws ObjectStreamException
+ */
+ protected Object readResolve() throws ObjectStreamException {
+ return LoggerFactory.getLogger(getName());
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java b/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java
index 359bff0..49fbd97 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,17 +13,10 @@
*/
package ch.qos.logback.classic;
-import static ch.qos.logback.core.CoreConstants.EVALUATOR_MAP;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledFuture;
+import ch.qos.logback.classic.util.LoggerNameUtil;
import org.slf4j.ILoggerFactory;
import org.slf4j.Marker;
@@ -32,9 +25,8 @@ import ch.qos.logback.classic.spi.LoggerContextListener;
import ch.qos.logback.classic.spi.LoggerContextVO;
import ch.qos.logback.classic.spi.TurboFilterList;
import ch.qos.logback.classic.turbo.TurboFilter;
-import ch.qos.logback.classic.util.LoggerNameUtil;
import ch.qos.logback.core.ContextBase;
-import ch.qos.logback.core.boolex.EventEvaluator;
+import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.spi.FilterReply;
import ch.qos.logback.core.spi.LifeCycle;
import ch.qos.logback.core.status.StatusListener;
@@ -50,330 +42,326 @@ import ch.qos.logback.core.status.WarnStatus;
*
* @author Ceki Gulcu
*/
-public class LoggerContext extends ContextBase implements ILoggerFactory, LifeCycle {
-
- /** Default setting of packaging data in stack traces */
- public static final boolean DEFAULT_PACKAGING_DATA = false;
-
- final Logger root;
- private int size;
- private int noAppenderWarning = 0;
- final private List<LoggerContextListener> loggerContextListenerList = new ArrayList<LoggerContextListener>();
-
- private Map<String, Logger> loggerCache;
-
- private LoggerContextVO loggerContextRemoteView;
- private final TurboFilterList turboFilterList = new TurboFilterList();
- private boolean packagingDataEnabled = DEFAULT_PACKAGING_DATA;
-
- private int maxCallerDataDepth = ClassicConstants.DEFAULT_MAX_CALLEDER_DATA_DEPTH;
-
- int resetCount = 0;
- private List<String> frameworkPackages;
-
- public LoggerContext() {
- super();
- this.loggerCache = new ConcurrentHashMap<String, Logger>();
-
- this.loggerContextRemoteView = new LoggerContextVO(this);
- this.root = new Logger(Logger.ROOT_LOGGER_NAME, null, this);
- this.root.setLevel(Level.DEBUG);
- loggerCache.put(Logger.ROOT_LOGGER_NAME, root);
- initEvaluatorMap();
- size = 1;
- this.frameworkPackages = new ArrayList<String>();
- }
-
- void initEvaluatorMap() {
- putObject(EVALUATOR_MAP, new HashMap<String, EventEvaluator<?>>());
- }
-
- /**
- * A new instance of LoggerContextRemoteView needs to be created each time the
- * name or propertyMap (including keys or values) changes.
- */
- private void updateLoggerContextVO() {
- loggerContextRemoteView = new LoggerContextVO(this);
- }
-
- @Override
- public void putProperty(String key, String val) {
- super.putProperty(key, val);
- updateLoggerContextVO();
- }
-
- @Override
- public void setName(String name) {
- super.setName(name);
- updateLoggerContextVO();
- }
-
- public final Logger getLogger(final Class<?> clazz) {
- return getLogger(clazz.getName());
- }
-
- @Override
- public final Logger getLogger(final String name) {
-
- if (name == null) {
- throw new IllegalArgumentException("name argument cannot be null");
- }
-
- // if we are asking for the root logger, then let us return it without
- // wasting time
- if (Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(name)) {
- return root;
- }
-
- int i = 0;
- Logger logger = root;
-
- // check if the desired logger exists, if it does, return it
- // without further ado.
- Logger childLogger = (Logger) loggerCache.get(name);
- // if we have the child, then let us return it without wasting time
- if (childLogger != null) {
- return childLogger;
- }
-
- // 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) {
- return childLogger;
- }
- }
- }
-
- private void incSize() {
- size++;
- }
-
- int size() {
- return size;
- }
-
- /**
- * Check if the named logger exists in the hierarchy. If so return its
- * reference, otherwise returns <code>null</code>.
- *
- * @param name the name of the logger to search for.
- */
- public Logger exists(String name) {
- return (Logger) loggerCache.get(name);
- }
-
- final void noAppenderDefinedWarning(final Logger logger) {
- if (noAppenderWarning++ == 0) {
- getStatusManager().add(new WarnStatus("No appenders present in context [" + getName() + "] for logger [" + logger.getName() + "].", logger));
- }
- }
-
- public List<Logger> getLoggerList() {
- Collection<Logger> collection = loggerCache.values();
- List<Logger> loggerList = new ArrayList<Logger>(collection);
- Collections.sort(loggerList, new LoggerComparator());
- return loggerList;
- }
-
- public LoggerContextVO getLoggerContextRemoteView() {
- return loggerContextRemoteView;
- }
-
- public void setPackagingDataEnabled(boolean packagingDataEnabled) {
- this.packagingDataEnabled = packagingDataEnabled;
- }
-
- public boolean isPackagingDataEnabled() {
- return packagingDataEnabled;
- }
-
- /**
- * This method clears all internal properties, except internal status messages,
- * closes all appenders, removes any turboFilters, fires an OnReset event,
- * removes all status listeners, removes all context listeners
- * (except those which are reset resistant).
- * <p/>
- * As mentioned above, internal status messages survive resets.
- */
- @Override
- public void reset() {
- resetCount++;
- super.reset();
- initEvaluatorMap();
- initCollisionMaps();
- root.recursiveReset();
- resetTurboFilterList();
- cancelScheduledTasks();
- fireOnReset();
- resetListenersExceptResetResistant();
- resetStatusListeners();
- }
-
- private void cancelScheduledTasks() {
- for(ScheduledFuture<?> sf: scheduledFutures) {
- sf.cancel(false);
- }
- scheduledFutures.clear();
- }
-
- private void resetStatusListeners() {
- StatusManager sm = getStatusManager();
- for (StatusListener sl : sm.getCopyOfStatusListenerList()) {
- sm.remove(sl);
- }
- }
-
- public TurboFilterList getTurboFilterList() {
- return turboFilterList;
- }
-
- public void addTurboFilter(TurboFilter newFilter) {
- turboFilterList.add(newFilter);
- }
-
- /**
- * First processPriorToRemoval all registered turbo filters and then clear the registration
- * list.
- */
- public void resetTurboFilterList() {
- for (TurboFilter tf : turboFilterList) {
- tf.stop();
- }
- turboFilterList.clear();
- }
-
- final FilterReply getTurboFilterChainDecision_0_3OrMore(final Marker marker, final Logger logger, final Level level, final String format,
- final Object[] params, final Throwable t) {
- if (turboFilterList.size() == 0) {
- return FilterReply.NEUTRAL;
- }
- return turboFilterList.getTurboFilterChainDecision(marker, logger, level, format, params, t);
- }
-
- final FilterReply getTurboFilterChainDecision_1(final Marker marker, final Logger logger, final Level level, final String format, final Object param,
- final Throwable t) {
- if (turboFilterList.size() == 0) {
- return FilterReply.NEUTRAL;
+public class LoggerContext extends ContextBase implements ILoggerFactory,
+ LifeCycle {
+
+ final Logger root;
+ private int size;
+ private int noAppenderWarning = 0;
+ final private List<LoggerContextListener> loggerContextListenerList = new ArrayList<LoggerContextListener>();
+
+ private Map<String, Logger> loggerCache;
+
+ private LoggerContextVO loggerContextRemoteView;
+ private final TurboFilterList turboFilterList = new TurboFilterList();
+ private boolean packagingDataEnabled = true;
+
+ private int maxCallerDataDepth = ClassicConstants.DEFAULT_MAX_CALLEDER_DATA_DEPTH;
+
+ int resetCount = 0;
+ private List<String> frameworkPackages;
+
+ public LoggerContext() {
+ super();
+ this.loggerCache = new ConcurrentHashMap<String, Logger>();
+
+ this.loggerContextRemoteView = new LoggerContextVO(this);
+ this.root = new Logger(Logger.ROOT_LOGGER_NAME, null, this);
+ this.root.setLevel(Level.DEBUG);
+ loggerCache.put(Logger.ROOT_LOGGER_NAME, root);
+ initEvaluatorMap();
+ size = 1;
+ this.frameworkPackages = new ArrayList<String>();
+ }
+
+ void initEvaluatorMap() {
+ putObject(CoreConstants.EVALUATOR_MAP, new HashMap());
+ }
+
+ /**
+ * A new instance of LoggerContextRemoteView needs to be created each time the
+ * name or propertyMap (including keys or values) changes.
+ */
+ private void updateLoggerContextVO() {
+ loggerContextRemoteView = new LoggerContextVO(this);
+ }
+
+ @Override
+ public void putProperty(String key, String val) {
+ super.putProperty(key, val);
+ updateLoggerContextVO();
+ }
+
+ @Override
+ public void setName(String name) {
+ super.setName(name);
+ updateLoggerContextVO();
+ }
+
+ public final Logger getLogger(final Class clazz) {
+ return getLogger(clazz.getName());
+ }
+
+ public final Logger getLogger(final String name) {
+
+ if (name == null) {
+ throw new IllegalArgumentException("name argument cannot be null");
+ }
+
+ // if we are asking for the root logger, then let us return it without
+ // wasting time
+ if (Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(name)) {
+ return root;
+ }
+
+ int i = 0;
+ Logger logger = root;
+
+ // check if the desired logger exists, if it does, return it
+ // without further ado.
+ Logger childLogger = (Logger) loggerCache.get(name);
+ // if we have the child, then let us return it without wasting time
+ if (childLogger != null) {
+ return childLogger;
+ }
+
+ // 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();
}
- return turboFilterList.getTurboFilterChainDecision(marker, logger, level, format, new Object[] { param }, t);
- }
-
- final FilterReply getTurboFilterChainDecision_2(final Marker marker, final Logger logger, final Level level, final String format, final Object param1,
- final Object param2, final Throwable t) {
- if (turboFilterList.size() == 0) {
- return FilterReply.NEUTRAL;
- }
- return turboFilterList.getTurboFilterChainDecision(marker, logger, level, format, new Object[] { param1, param2 }, t);
- }
-
- // === start listeners ==============================================
- public void addListener(LoggerContextListener listener) {
- loggerContextListenerList.add(listener);
- }
-
- public void removeListener(LoggerContextListener listener) {
- loggerContextListenerList.remove(listener);
- }
-
- private void resetListenersExceptResetResistant() {
- List<LoggerContextListener> toRetain = new ArrayList<LoggerContextListener>();
-
- for (LoggerContextListener lcl : loggerContextListenerList) {
- if (lcl.isResetResistant()) {
- toRetain.add(lcl);
- }
- }
- loggerContextListenerList.retainAll(toRetain);
- }
-
- private void resetAllListeners() {
- loggerContextListenerList.clear();
- }
-
- public List<LoggerContextListener> getCopyOfListenerList() {
- return new ArrayList<LoggerContextListener>(loggerContextListenerList);
- }
-
- void fireOnLevelChange(Logger logger, Level level) {
- for (LoggerContextListener listener : loggerContextListenerList) {
- listener.onLevelChange(logger, level);
- }
- }
-
- private void fireOnReset() {
- for (LoggerContextListener listener : loggerContextListenerList) {
- listener.onReset(this);
- }
- }
-
- private void fireOnStart() {
- for (LoggerContextListener listener : loggerContextListenerList) {
- listener.onStart(this);
- }
- }
-
- private void fireOnStop() {
- for (LoggerContextListener listener : loggerContextListenerList) {
- listener.onStop(this);
- }
- }
-
- // === end listeners ==============================================
-
- public void start() {
- super.start();
- fireOnStart();
- }
-
- public void stop() {
- reset();
- fireOnStop();
- resetAllListeners();
- super.stop();
- }
-
- @Override
- public String toString() {
- return this.getClass().getName() + "[" + getName() + "]";
- }
-
- public int getMaxCallerDataDepth() {
- return maxCallerDataDepth;
- }
-
- public void setMaxCallerDataDepth(int maxCallerDataDepth) {
- this.maxCallerDataDepth = maxCallerDataDepth;
- }
-
- /**
- * List of packages considered part of the logging framework such that they are never considered
- * as callers of the logging framework. This list used to compute the caller for logging events.
- * <p/>
- * To designate package "com.foo" as well as all its subpackages as being part of the logging framework, simply add
- * "com.foo" to this list.
- *
- * @return list of framework packages
- */
- public List<String> getFrameworkPackages() {
- return frameworkPackages;
- }
+ }
+ logger = childLogger;
+ if (h == -1) {
+ return childLogger;
+ }
+ }
+ }
+
+ private void incSize() {
+ size++;
+ }
+
+ int size() {
+ return size;
+ }
+
+ /**
+ * Check if the named logger exists in the hierarchy. If so return its
+ * reference, otherwise returns <code>null</code>.
+ *
+ * @param name the name of the logger to search for.
+ */
+ public Logger exists(String name) {
+ return (Logger) loggerCache.get(name);
+ }
+
+ final void noAppenderDefinedWarning(final Logger logger) {
+ if (noAppenderWarning++ == 0) {
+ getStatusManager().add(
+ new WarnStatus("No appenders present in context [" + getName()
+ + "] for logger [" + logger.getName() + "].", logger));
+ }
+ }
+
+ public List<Logger> getLoggerList() {
+ Collection<Logger> collection = loggerCache.values();
+ List<Logger> loggerList = new ArrayList<Logger>(collection);
+ Collections.sort(loggerList, new LoggerComparator());
+ return loggerList;
+ }
+
+ public LoggerContextVO getLoggerContextRemoteView() {
+ return loggerContextRemoteView;
+ }
+
+ public void setPackagingDataEnabled(boolean packagingDataEnabled) {
+ this.packagingDataEnabled = packagingDataEnabled;
+ }
+
+ public boolean isPackagingDataEnabled() {
+ return packagingDataEnabled;
+ }
+
+ /**
+ * This method clears all internal properties, except internal status messages,
+ * closes all appenders, removes any turboFilters, fires an OnReset event,
+ * removes all status listeners, removes all context listeners
+ * (except those which are reset resistant).
+ * <p/>
+ * As mentioned above, internal status messages survive resets.
+ */
+ @Override
+ public void reset() {
+ resetCount++;
+ super.reset();
+ initEvaluatorMap();
+ root.recursiveReset();
+ resetTurboFilterList();
+ fireOnReset();
+ resetListenersExceptResetResistant();
+ resetStatusListeners();
+ }
+
+ private void resetStatusListeners() {
+ StatusManager sm = getStatusManager();
+ for (StatusListener sl : sm.getCopyOfStatusListenerList()) {
+ sm.remove(sl);
+ }
+ }
+
+ public TurboFilterList getTurboFilterList() {
+ return turboFilterList;
+ }
+
+ public void addTurboFilter(TurboFilter newFilter) {
+ turboFilterList.add(newFilter);
+ }
+
+ /**
+ * First processPriorToRemoval all registered turbo filters and then clear the registration
+ * list.
+ */
+ public void resetTurboFilterList() {
+ for (TurboFilter tf : turboFilterList) {
+ tf.stop();
+ }
+ turboFilterList.clear();
+ }
+
+ final FilterReply getTurboFilterChainDecision_0_3OrMore(final Marker marker,
+ final Logger logger, final Level level, final String format,
+ final Object[] params, final Throwable t) {
+ if (turboFilterList.size() == 0) {
+ return FilterReply.NEUTRAL;
+ }
+ return turboFilterList.getTurboFilterChainDecision(marker, logger, level,
+ format, params, t);
+ }
+
+ final FilterReply getTurboFilterChainDecision_1(final Marker marker,
+ final Logger logger, final Level level, final String format,
+ final Object param, final Throwable t) {
+ if (turboFilterList.size() == 0) {
+ return FilterReply.NEUTRAL;
+ }
+ return turboFilterList.getTurboFilterChainDecision(marker, logger, level,
+ format, new Object[]{param}, t);
+ }
+
+ final FilterReply getTurboFilterChainDecision_2(final Marker marker,
+ final Logger logger, final Level level, final String format,
+ final Object param1, final Object param2, final Throwable t) {
+ if (turboFilterList.size() == 0) {
+ return FilterReply.NEUTRAL;
+ }
+ return turboFilterList.getTurboFilterChainDecision(marker, logger, level,
+ format, new Object[]{param1, param2}, t);
+ }
+
+ // === start listeners ==============================================
+ public void addListener(LoggerContextListener listener) {
+ loggerContextListenerList.add(listener);
+ }
+
+ public void removeListener(LoggerContextListener listener) {
+ loggerContextListenerList.remove(listener);
+ }
+
+ private void resetListenersExceptResetResistant() {
+ List<LoggerContextListener> toRetain = new ArrayList<LoggerContextListener>();
+
+ for (LoggerContextListener lcl : loggerContextListenerList) {
+ if (lcl.isResetResistant()) {
+ toRetain.add(lcl);
+ }
+ }
+ loggerContextListenerList.retainAll(toRetain);
+ }
+
+ private void resetAllListeners() {
+ loggerContextListenerList.clear();
+ }
+
+ public List<LoggerContextListener> getCopyOfListenerList() {
+ return new ArrayList<LoggerContextListener>(loggerContextListenerList);
+ }
+
+ void fireOnLevelChange(Logger logger, Level level) {
+ for (LoggerContextListener listener : loggerContextListenerList) {
+ listener.onLevelChange(logger, level);
+ }
+ }
+
+ private void fireOnReset() {
+ for (LoggerContextListener listener : loggerContextListenerList) {
+ listener.onReset(this);
+ }
+ }
+
+ private void fireOnStart() {
+ for (LoggerContextListener listener : loggerContextListenerList) {
+ listener.onStart(this);
+ }
+ }
+
+ private void fireOnStop() {
+ for (LoggerContextListener listener : loggerContextListenerList) {
+ listener.onStop(this);
+ }
+ }
+
+ // === end listeners ==============================================
+
+ public void start() {
+ super.start();
+ fireOnStart();
+ }
+
+ public void stop() {
+ reset();
+ fireOnStop();
+ resetAllListeners();
+ super.stop();
+ }
+
+ @Override
+ public String toString() {
+ return this.getClass().getName() + "[" + getName() + "]";
+ }
+
+ public int getMaxCallerDataDepth() {
+ return maxCallerDataDepth;
+ }
+
+ public void setMaxCallerDataDepth(int maxCallerDataDepth) {
+ this.maxCallerDataDepth = maxCallerDataDepth;
+ }
+
+ /**
+ * List of packages considered part of the logging framework such that they are never considered
+ * as callers of the logging framework. This list used to compute the caller for logging events.
+ * <p/>
+ * To designate package "com.foo" as well as all its subpackages as being part of the logging framework, simply add
+ * "com.foo" to this list.
+ *
+ * @return list of framework packages
+ */
+ public List<String> getFrameworkPackages() {
+ return frameworkPackages;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java b/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java
index 4f240d8..70e5612 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -38,111 +38,119 @@ import ch.qos.logback.core.pattern.parser.Parser;
public class PatternLayout extends PatternLayoutBase<ILoggingEvent> {
- public static final Map<String, String> defaultConverterMap = new HashMap<String, String>();
- public static final String HEADER_PREFIX = "#logback.classic pattern: ";
-
- static {
- defaultConverterMap.putAll(Parser.DEFAULT_COMPOSITE_CONVERTER_MAP);
-
- defaultConverterMap.put("d", DateConverter.class.getName());
- defaultConverterMap.put("date", DateConverter.class.getName());
-
- defaultConverterMap.put("r", RelativeTimeConverter.class.getName());
- defaultConverterMap.put("relative", RelativeTimeConverter.class.getName());
-
- defaultConverterMap.put("level", LevelConverter.class.getName());
- defaultConverterMap.put("le", LevelConverter.class.getName());
- defaultConverterMap.put("p", LevelConverter.class.getName());
-
- defaultConverterMap.put("t", ThreadConverter.class.getName());
- defaultConverterMap.put("thread", ThreadConverter.class.getName());
-
- defaultConverterMap.put("lo", LoggerConverter.class.getName());
- defaultConverterMap.put("logger", LoggerConverter.class.getName());
- defaultConverterMap.put("c", LoggerConverter.class.getName());
-
- defaultConverterMap.put("m", MessageConverter.class.getName());
- defaultConverterMap.put("msg", MessageConverter.class.getName());
- defaultConverterMap.put("message", MessageConverter.class.getName());
-
- defaultConverterMap.put("C", ClassOfCallerConverter.class.getName());
- defaultConverterMap.put("class", ClassOfCallerConverter.class.getName());
-
- defaultConverterMap.put("M", MethodOfCallerConverter.class.getName());
- defaultConverterMap.put("method", MethodOfCallerConverter.class.getName());
-
- defaultConverterMap.put("L", LineOfCallerConverter.class.getName());
- defaultConverterMap.put("line", LineOfCallerConverter.class.getName());
-
- defaultConverterMap.put("F", FileOfCallerConverter.class.getName());
- defaultConverterMap.put("file", FileOfCallerConverter.class.getName());
-
- defaultConverterMap.put("X", MDCConverter.class.getName());
- defaultConverterMap.put("mdc", MDCConverter.class.getName());
-
- defaultConverterMap.put("ex", ThrowableProxyConverter.class.getName());
- defaultConverterMap.put("exception", ThrowableProxyConverter.class.getName());
- defaultConverterMap.put("rEx", RootCauseFirstThrowableProxyConverter.class.getName());
- defaultConverterMap.put("rootException", RootCauseFirstThrowableProxyConverter.class.getName());
- defaultConverterMap.put("throwable", ThrowableProxyConverter.class.getName());
-
- defaultConverterMap.put("xEx", ExtendedThrowableProxyConverter.class.getName());
- defaultConverterMap.put("xException", ExtendedThrowableProxyConverter.class.getName());
- defaultConverterMap.put("xThrowable", ExtendedThrowableProxyConverter.class.getName());
-
- defaultConverterMap.put("nopex", NopThrowableInformationConverter.class.getName());
- defaultConverterMap.put("nopexception", NopThrowableInformationConverter.class.getName());
-
- defaultConverterMap.put("cn", ContextNameConverter.class.getName());
- defaultConverterMap.put("contextName", ContextNameConverter.class.getName());
-
- defaultConverterMap.put("caller", CallerDataConverter.class.getName());
-
- defaultConverterMap.put("marker", MarkerConverter.class.getName());
-
- defaultConverterMap.put("property", PropertyConverter.class.getName());
-
- defaultConverterMap.put("n", LineSeparatorConverter.class.getName());
-
- defaultConverterMap.put("black", BlackCompositeConverter.class.getName());
- defaultConverterMap.put("red", RedCompositeConverter.class.getName());
- defaultConverterMap.put("green", GreenCompositeConverter.class.getName());
- defaultConverterMap.put("yellow", YellowCompositeConverter.class.getName());
- defaultConverterMap.put("blue", BlueCompositeConverter.class.getName());
- defaultConverterMap.put("magenta", MagentaCompositeConverter.class.getName());
- defaultConverterMap.put("cyan", CyanCompositeConverter.class.getName());
- defaultConverterMap.put("white", WhiteCompositeConverter.class.getName());
- defaultConverterMap.put("gray", GrayCompositeConverter.class.getName());
- defaultConverterMap.put("boldRed", BoldRedCompositeConverter.class.getName());
- defaultConverterMap.put("boldGreen", BoldGreenCompositeConverter.class.getName());
- defaultConverterMap.put("boldYellow", BoldYellowCompositeConverter.class.getName());
- defaultConverterMap.put("boldBlue", BoldBlueCompositeConverter.class.getName());
- defaultConverterMap.put("boldMagenta", BoldMagentaCompositeConverter.class.getName());
- defaultConverterMap.put("boldCyan", BoldCyanCompositeConverter.class.getName());
- defaultConverterMap.put("boldWhite", BoldWhiteCompositeConverter.class.getName());
- defaultConverterMap.put("highlight", HighlightingCompositeConverter.class.getName());
-
- defaultConverterMap.put("lsn", LocalSequenceNumberConverter.class.getName());
+ public static final Map<String, String> defaultConverterMap = new HashMap<String, String>();
+ public static final String HEADER_PREFIX = "#logback.classic pattern: ";
+
+ static {
+ defaultConverterMap.putAll(Parser.DEFAULT_COMPOSITE_CONVERTER_MAP);
+ defaultConverterMap.put("d", DateConverter.class.getName());
+ defaultConverterMap.put("date", DateConverter.class.getName());
+
+ defaultConverterMap.put("r", RelativeTimeConverter.class.getName());
+ defaultConverterMap.put("relative", RelativeTimeConverter.class.getName());
+
+ defaultConverterMap.put("level", LevelConverter.class.getName());
+ defaultConverterMap.put("le", LevelConverter.class.getName());
+ defaultConverterMap.put("p", LevelConverter.class.getName());
+
+ defaultConverterMap.put("t", ThreadConverter.class.getName());
+ defaultConverterMap.put("thread", ThreadConverter.class.getName());
+
+ defaultConverterMap.put("lo", LoggerConverter.class.getName());
+ defaultConverterMap.put("logger", LoggerConverter.class.getName());
+ defaultConverterMap.put("c", LoggerConverter.class.getName());
+
+ defaultConverterMap.put("m", MessageConverter.class.getName());
+ defaultConverterMap.put("msg", MessageConverter.class.getName());
+ defaultConverterMap.put("message", MessageConverter.class.getName());
+
+ defaultConverterMap.put("C", ClassOfCallerConverter.class.getName());
+ defaultConverterMap.put("class", ClassOfCallerConverter.class.getName());
+
+ defaultConverterMap.put("M", MethodOfCallerConverter.class.getName());
+ defaultConverterMap.put("method", MethodOfCallerConverter.class.getName());
+
+ defaultConverterMap.put("L", LineOfCallerConverter.class.getName());
+ defaultConverterMap.put("line", LineOfCallerConverter.class.getName());
+
+ defaultConverterMap.put("F", FileOfCallerConverter.class.getName());
+ defaultConverterMap.put("file", FileOfCallerConverter.class.getName());
+
+ defaultConverterMap.put("X", MDCConverter.class.getName());
+ defaultConverterMap.put("mdc", MDCConverter.class.getName());
+
+ defaultConverterMap.put("ex", ThrowableProxyConverter.class.getName());
+ defaultConverterMap.put("exception", ThrowableProxyConverter.class
+ .getName());
+ defaultConverterMap.put("rEx", RootCauseFirstThrowableProxyConverter.class.getName());
+ defaultConverterMap.put("rootException", RootCauseFirstThrowableProxyConverter.class
+ .getName());
+ defaultConverterMap.put("throwable", ThrowableProxyConverter.class
+ .getName());
+
+ defaultConverterMap.put("xEx", ExtendedThrowableProxyConverter.class.getName());
+ defaultConverterMap.put("xException", ExtendedThrowableProxyConverter.class
+ .getName());
+ defaultConverterMap.put("xThrowable", ExtendedThrowableProxyConverter.class
+ .getName());
+
+ defaultConverterMap.put("nopex", NopThrowableInformationConverter.class
+ .getName());
+ defaultConverterMap.put("nopexception",
+ NopThrowableInformationConverter.class.getName());
+
+ defaultConverterMap.put("cn", ContextNameConverter.class.getName());
+ defaultConverterMap.put("contextName", ContextNameConverter.class.getName());
+
+ defaultConverterMap.put("caller", CallerDataConverter.class.getName());
+
+ defaultConverterMap.put("marker", MarkerConverter.class.getName());
+
+ defaultConverterMap.put("property", PropertyConverter.class.getName());
+
+ defaultConverterMap.put("n", LineSeparatorConverter.class.getName());
+
+ defaultConverterMap.put("black", BlackCompositeConverter.class.getName());
+ defaultConverterMap.put("red", RedCompositeConverter.class.getName());
+ defaultConverterMap.put("green", GreenCompositeConverter.class.getName());
+ defaultConverterMap.put("yellow", YellowCompositeConverter.class.getName());
+ defaultConverterMap.put("blue", BlueCompositeConverter.class.getName());
+ defaultConverterMap.put("magenta", MagentaCompositeConverter.class.getName());
+ defaultConverterMap.put("cyan", CyanCompositeConverter.class.getName());
+ defaultConverterMap.put("white", WhiteCompositeConverter.class.getName());
+ defaultConverterMap.put("gray", GrayCompositeConverter.class.getName());
+ defaultConverterMap.put("boldRed", BoldRedCompositeConverter.class.getName());
+ defaultConverterMap.put("boldGreen", BoldGreenCompositeConverter.class.getName());
+ defaultConverterMap.put("boldYellow", BoldYellowCompositeConverter.class.getName());
+ defaultConverterMap.put("boldBlue", BoldBlueCompositeConverter.class.getName());
+ defaultConverterMap.put("boldMagenta", BoldMagentaCompositeConverter.class.getName());
+ defaultConverterMap.put("boldCyan", BoldCyanCompositeConverter.class.getName());
+ defaultConverterMap.put("boldWhite", BoldWhiteCompositeConverter.class.getName());
+ defaultConverterMap.put("highlight", HighlightingCompositeConverter.class.getName());
+
+ defaultConverterMap.put("lsn", LocalSequenceNumberConverter.class.getName());
+
+
+ }
+
+ public PatternLayout() {
+ this.postCompileProcessor = new EnsureExceptionHandling();
+ }
+
+ public Map<String, String> getDefaultConverterMap() {
+ return defaultConverterMap;
+ }
+
+ public String doLayout(ILoggingEvent event) {
+ if (!isStarted()) {
+ return CoreConstants.EMPTY_STRING;
}
+ return writeLoopOnConverters(event);
+ }
- public PatternLayout() {
- this.postCompileProcessor = new EnsureExceptionHandling();
- }
-
- public Map<String, String> getDefaultConverterMap() {
- return defaultConverterMap;
- }
-
- public String doLayout(ILoggingEvent event) {
- if (!isStarted()) {
- return CoreConstants.EMPTY_STRING;
- }
- return writeLoopOnConverters(event);
- }
-
- @Override
- protected String getPresentationHeaderPrefix() {
- return HEADER_PREFIX;
- }
+ @Override
+ protected String getPresentationHeaderPrefix() {
+ return HEADER_PREFIX;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/ViewStatusMessagesServlet.java b/logback-classic/src/main/java/ch/qos/logback/classic/ViewStatusMessagesServlet.java
index 25fa475..8839126 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/ViewStatusMessagesServlet.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/ViewStatusMessagesServlet.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,18 +23,20 @@ import ch.qos.logback.core.status.ViewStatusMessagesServletBase;
public class ViewStatusMessagesServlet extends ViewStatusMessagesServletBase {
- private static final long serialVersionUID = 443878494348593337L;
+ private static final long serialVersionUID = 443878494348593337L;
- @Override
- protected StatusManager getStatusManager(HttpServletRequest req, HttpServletResponse resp) {
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- return lc.getStatusManager();
- }
- @Override
- protected String getPageTitle(HttpServletRequest req, HttpServletResponse resp) {
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- return "<h2>Status messages for LoggerContext named [" + lc.getName() + "]</h2>\r\n";
- }
+ @Override
+ protected StatusManager getStatusManager(HttpServletRequest req, HttpServletResponse resp) {
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ return lc.getStatusManager();
+ }
+
+ @Override
+ protected String getPageTitle(HttpServletRequest req, HttpServletResponse resp) {
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ return "<h2>Status messages for LoggerContext named ["
+ + lc.getName() + "]</h2>\r\n";
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/boolex/GEventEvaluator.java b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/GEventEvaluator.java
index 13dc33f..0ff0631 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/boolex/GEventEvaluator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/GEventEvaluator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,64 +25,66 @@ import org.codehaus.groovy.control.CompilationFailedException;
*/
public class GEventEvaluator extends EventEvaluatorBase<ILoggingEvent> {
- String expression;
+ String expression;
- IEvaluator delegateEvaluator;
- Script script;
+ IEvaluator delegateEvaluator;
+ Script script;
- public String getExpression() {
- return expression;
+ public String getExpression() {
+ return expression;
+ }
+
+ public void setExpression(String expression) {
+ this.expression = expression;
+ }
+
+ public void start() {
+ int errors = 0;
+ if (expression == null || expression.length() == 0) {
+ addError("Empty expression");
+ return;
+ } else {
+ addInfo("Expression to evaluate [" + expression + "]");
}
- public void setExpression(String expression) {
- this.expression = expression;
+
+ ClassLoader classLoader = getClass().getClassLoader();
+ String currentPackageName = this.getClass().getPackage().getName();
+ currentPackageName = currentPackageName.replace('.', '/');
+
+ FileUtil fileUtil = new FileUtil(getContext());
+ String scriptText = fileUtil.resourceAsString(classLoader, currentPackageName + "/EvaluatorTemplate.groovy");
+ if (scriptText == null) {
+ return;
}
- public void start() {
- int errors = 0;
- if (expression == null || expression.length() == 0) {
- addError("Empty expression");
- return;
- } else {
- addInfo("Expression to evaluate [" + expression + "]");
- }
-
- ClassLoader classLoader = getClass().getClassLoader();
- String currentPackageName = this.getClass().getPackage().getName();
- currentPackageName = currentPackageName.replace('.', '/');
-
- FileUtil fileUtil = new FileUtil(getContext());
- String scriptText = fileUtil.resourceAsString(classLoader, currentPackageName + "/EvaluatorTemplate.groovy");
- if (scriptText == null) {
- return;
- }
-
- // insert the expression into script text
- scriptText = scriptText.replace("//EXPRESSION", expression);
-
- GroovyClassLoader gLoader = new GroovyClassLoader(classLoader);
- try {
- Class scriptClass = gLoader.parseClass(scriptText);
-
- GroovyObject goo = (GroovyObject) scriptClass.newInstance();
- delegateEvaluator = (IEvaluator) goo;
-
- } catch (CompilationFailedException cfe) {
- addError("Failed to compile expression [" + expression + "]", cfe);
- errors++;
- } catch (Exception e) {
- addError("Failed to compile expression [" + expression + "]", e);
- errors++;
- }
- if (errors == 0)
- super.start();
+ // insert the expression into script text
+ scriptText = scriptText.replace("//EXPRESSION", expression);
+
+ GroovyClassLoader gLoader = new GroovyClassLoader(classLoader);
+ try {
+ Class scriptClass = gLoader.parseClass(scriptText);
+
+ GroovyObject goo = (GroovyObject) scriptClass.newInstance();
+ delegateEvaluator = (IEvaluator) goo;
+
+ } catch (CompilationFailedException cfe) {
+ addError("Failed to compile expression [" + expression + "]", cfe);
+ errors++;
+ } catch (Exception e) {
+ addError("Failed to compile expression [" + expression + "]", e);
+ errors++;
}
+ if (errors == 0)
+ super.start();
+ }
- public boolean evaluate(ILoggingEvent event) throws NullPointerException, EvaluationException {
- if (delegateEvaluator == null) {
- return false;
- }
- return delegateEvaluator.doEvaluate(event);
+ public boolean evaluate(ILoggingEvent event) throws NullPointerException, EvaluationException {
+ if (delegateEvaluator == null) {
+ return false;
}
+ return delegateEvaluator.doEvaluate(event);
+ }
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/boolex/IEvaluator.java b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/IEvaluator.java
index ffa9788..3185506 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/boolex/IEvaluator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/IEvaluator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,8 +18,9 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
/**
* An <b>internal</b> interface used by the GEventEvaluator.
*
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public interface IEvaluator {
- boolean doEvaluate(ILoggingEvent event);
+ boolean doEvaluate(ILoggingEvent event);
}
+
\ No newline at end of file
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/boolex/JaninoEventEvaluator.java b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/JaninoEventEvaluator.java
index 62ccfe8..78fd338 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/boolex/JaninoEventEvaluator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/JaninoEventEvaluator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,125 +28,127 @@ import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.boolex.JaninoEventEvaluatorBase;
import ch.qos.logback.core.boolex.Matcher;
-public class JaninoEventEvaluator extends JaninoEventEvaluatorBase<ILoggingEvent> {
-
- public final static String IMPORT_LEVEL = "import ch.qos.logback.classic.Level;\r\n";
-
- public final static List<String> DEFAULT_PARAM_NAME_LIST = new ArrayList<String>();
- public final static List<Class> DEFAULT_PARAM_TYPE_LIST = new ArrayList<Class>();
-
- static {
- DEFAULT_PARAM_NAME_LIST.add("DEBUG");
- DEFAULT_PARAM_NAME_LIST.add("INFO");
- DEFAULT_PARAM_NAME_LIST.add("WARN");
- DEFAULT_PARAM_NAME_LIST.add("ERROR");
-
- DEFAULT_PARAM_NAME_LIST.add("event");
- DEFAULT_PARAM_NAME_LIST.add("message");
-
- DEFAULT_PARAM_NAME_LIST.add("formattedMessage");
- DEFAULT_PARAM_NAME_LIST.add("logger");
- DEFAULT_PARAM_NAME_LIST.add("loggerContext");
- DEFAULT_PARAM_NAME_LIST.add("level");
- DEFAULT_PARAM_NAME_LIST.add("timeStamp");
- DEFAULT_PARAM_NAME_LIST.add("marker");
- DEFAULT_PARAM_NAME_LIST.add("mdc");
- DEFAULT_PARAM_NAME_LIST.add("throwableProxy");
- DEFAULT_PARAM_NAME_LIST.add("throwable");
-
- DEFAULT_PARAM_TYPE_LIST.add(int.class);
- DEFAULT_PARAM_TYPE_LIST.add(int.class);
- DEFAULT_PARAM_TYPE_LIST.add(int.class);
- DEFAULT_PARAM_TYPE_LIST.add(int.class);
-
- DEFAULT_PARAM_TYPE_LIST.add(ILoggingEvent.class);
- DEFAULT_PARAM_TYPE_LIST.add(String.class);
- DEFAULT_PARAM_TYPE_LIST.add(String.class);
- DEFAULT_PARAM_TYPE_LIST.add(String.class);
- DEFAULT_PARAM_TYPE_LIST.add(LoggerContextVO.class);
- DEFAULT_PARAM_TYPE_LIST.add(int.class);
- DEFAULT_PARAM_TYPE_LIST.add(long.class);
- DEFAULT_PARAM_TYPE_LIST.add(Marker.class);
- DEFAULT_PARAM_TYPE_LIST.add(Map.class);
- DEFAULT_PARAM_TYPE_LIST.add(IThrowableProxy.class);
- DEFAULT_PARAM_TYPE_LIST.add(Throwable.class);
+public class JaninoEventEvaluator extends
+ JaninoEventEvaluatorBase<ILoggingEvent> {
+
+ public final static String IMPORT_LEVEL = "import ch.qos.logback.classic.Level;\r\n";
+
+ public final static List<String> DEFAULT_PARAM_NAME_LIST = new ArrayList<String>();
+ public final static List<Class> DEFAULT_PARAM_TYPE_LIST = new ArrayList<Class>();
+
+ static {
+ DEFAULT_PARAM_NAME_LIST.add("DEBUG");
+ DEFAULT_PARAM_NAME_LIST.add("INFO");
+ DEFAULT_PARAM_NAME_LIST.add("WARN");
+ DEFAULT_PARAM_NAME_LIST.add("ERROR");
+
+ DEFAULT_PARAM_NAME_LIST.add("event");
+ DEFAULT_PARAM_NAME_LIST.add("message");
+
+ DEFAULT_PARAM_NAME_LIST.add("formattedMessage");
+ DEFAULT_PARAM_NAME_LIST.add("logger");
+ DEFAULT_PARAM_NAME_LIST.add("loggerContext");
+ DEFAULT_PARAM_NAME_LIST.add("level");
+ DEFAULT_PARAM_NAME_LIST.add("timeStamp");
+ DEFAULT_PARAM_NAME_LIST.add("marker");
+ DEFAULT_PARAM_NAME_LIST.add("mdc");
+ DEFAULT_PARAM_NAME_LIST.add("throwableProxy");
+ DEFAULT_PARAM_NAME_LIST.add("throwable");
+
+ DEFAULT_PARAM_TYPE_LIST.add(int.class);
+ DEFAULT_PARAM_TYPE_LIST.add(int.class);
+ DEFAULT_PARAM_TYPE_LIST.add(int.class);
+ DEFAULT_PARAM_TYPE_LIST.add(int.class);
+
+ DEFAULT_PARAM_TYPE_LIST.add(ILoggingEvent.class);
+ DEFAULT_PARAM_TYPE_LIST.add(String.class);
+ DEFAULT_PARAM_TYPE_LIST.add(String.class);
+ DEFAULT_PARAM_TYPE_LIST.add(String.class);
+ DEFAULT_PARAM_TYPE_LIST.add(LoggerContextVO.class);
+ DEFAULT_PARAM_TYPE_LIST.add(int.class);
+ DEFAULT_PARAM_TYPE_LIST.add(long.class);
+ DEFAULT_PARAM_TYPE_LIST.add(Marker.class);
+ DEFAULT_PARAM_TYPE_LIST.add(Map.class);
+ DEFAULT_PARAM_TYPE_LIST.add(IThrowableProxy.class);
+ DEFAULT_PARAM_TYPE_LIST.add(Throwable.class);
+ }
+
+ protected String getDecoratedExpression() {
+ String expression = getExpression();
+ if(!expression.contains("return")) {
+ expression = "return "+expression +";";
+ addInfo("Adding [return] prefix and a semicolon suffix. Expression becomes ["+expression+"]");
+ addInfo("See also "+CoreConstants.CODES_URL+"#block");
+
}
+ return IMPORT_LEVEL + expression;
+ }
- protected String getDecoratedExpression() {
- String expression = getExpression();
- if (!expression.contains("return")) {
- expression = "return " + expression + ";";
- addInfo("Adding [return] prefix and a semicolon suffix. Expression becomes [" + expression + "]");
- addInfo("See also " + CoreConstants.CODES_URL + "#block");
+ protected String[] getParameterNames() {
+ List<String> fullNameList = new ArrayList<String>();
+ fullNameList.addAll(DEFAULT_PARAM_NAME_LIST);
- }
- return IMPORT_LEVEL + expression;
+ for (int i = 0; i < matcherList.size(); i++) {
+ Matcher m = (Matcher) matcherList.get(i);
+ fullNameList.add(m.getName());
}
- protected String[] getParameterNames() {
- List<String> fullNameList = new ArrayList<String>();
- fullNameList.addAll(DEFAULT_PARAM_NAME_LIST);
-
- for (int i = 0; i < matcherList.size(); i++) {
- Matcher m = (Matcher) matcherList.get(i);
- fullNameList.add(m.getName());
- }
+ return (String[]) fullNameList.toArray(CoreConstants.EMPTY_STRING_ARRAY);
+ }
- return (String[]) fullNameList.toArray(CoreConstants.EMPTY_STRING_ARRAY);
+ protected Class[] getParameterTypes() {
+ List<Class> fullTypeList = new ArrayList<Class>();
+ fullTypeList.addAll(DEFAULT_PARAM_TYPE_LIST);
+ for (int i = 0; i < matcherList.size(); i++) {
+ fullTypeList.add(Matcher.class);
}
-
- protected Class[] getParameterTypes() {
- List<Class> fullTypeList = new ArrayList<Class>();
- fullTypeList.addAll(DEFAULT_PARAM_TYPE_LIST);
- for (int i = 0; i < matcherList.size(); i++) {
- fullTypeList.add(Matcher.class);
- }
- return (Class[]) fullTypeList.toArray(CoreConstants.EMPTY_CLASS_ARRAY);
+ return (Class[]) fullTypeList.toArray(CoreConstants.EMPTY_CLASS_ARRAY);
+ }
+
+ protected Object[] getParameterValues(ILoggingEvent loggingEvent) {
+ final int matcherListSize = matcherList.size();
+
+ int i = 0;
+ Object[] values = new Object[DEFAULT_PARAM_NAME_LIST.size()
+ + matcherListSize];
+
+ values[i++] = Level.DEBUG_INTEGER;
+ values[i++] = Level.INFO_INTEGER;
+ values[i++] = Level.WARN_INTEGER;
+ values[i++] = Level.ERROR_INTEGER;
+
+ values[i++] = loggingEvent;
+ values[i++] = loggingEvent.getMessage();
+ values[i++] = loggingEvent.getFormattedMessage();
+ values[i++] = loggingEvent.getLoggerName();
+ values[i++] = loggingEvent.getLoggerContextVO();
+ values[i++] = loggingEvent.getLevel().toInteger();
+ values[i++] = loggingEvent.getTimeStamp();
+ // In order to avoid NullPointerException, we could push a dummy marker if
+ // the event's marker is null. However, this would surprise user who
+ // expect to see a null marker instead of a dummy one.
+ values[i++] = loggingEvent.getMarker();
+ values[i++] = loggingEvent.getMDCPropertyMap();
+
+ IThrowableProxy iThrowableProxy = loggingEvent.getThrowableProxy();
+
+ if (iThrowableProxy != null) {
+ values[i++] = iThrowableProxy;
+ if (iThrowableProxy instanceof ThrowableProxy) {
+ values[i++] = ((ThrowableProxy) iThrowableProxy).getThrowable();
+ } else {
+ values[i++] = null;
+ }
+ } else {
+ values[i++] = null;
+ values[i++] = null;
}
- protected Object[] getParameterValues(ILoggingEvent loggingEvent) {
- final int matcherListSize = matcherList.size();
-
- int i = 0;
- Object[] values = new Object[DEFAULT_PARAM_NAME_LIST.size() + matcherListSize];
-
- values[i++] = Level.DEBUG_INTEGER;
- values[i++] = Level.INFO_INTEGER;
- values[i++] = Level.WARN_INTEGER;
- values[i++] = Level.ERROR_INTEGER;
-
- values[i++] = loggingEvent;
- values[i++] = loggingEvent.getMessage();
- values[i++] = loggingEvent.getFormattedMessage();
- values[i++] = loggingEvent.getLoggerName();
- values[i++] = loggingEvent.getLoggerContextVO();
- values[i++] = loggingEvent.getLevel().toInteger();
- values[i++] = loggingEvent.getTimeStamp();
- // In order to avoid NullPointerException, we could push a dummy marker if
- // the event's marker is null. However, this would surprise user who
- // expect to see a null marker instead of a dummy one.
- values[i++] = loggingEvent.getMarker();
- values[i++] = loggingEvent.getMDCPropertyMap();
-
- IThrowableProxy iThrowableProxy = loggingEvent.getThrowableProxy();
-
- if (iThrowableProxy != null) {
- values[i++] = iThrowableProxy;
- if (iThrowableProxy instanceof ThrowableProxy) {
- values[i++] = ((ThrowableProxy) iThrowableProxy).getThrowable();
- } else {
- values[i++] = null;
- }
- } else {
- values[i++] = null;
- values[i++] = null;
- }
-
- for (int j = 0; j < matcherListSize; j++) {
- values[i++] = (Matcher) matcherList.get(j);
- }
-
- return values;
+ for (int j = 0; j < matcherListSize; j++) {
+ values[i++] = (Matcher) matcherList.get(j);
}
+ return values;
+ }
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/boolex/OnErrorEvaluator.java b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/OnErrorEvaluator.java
index 8abeeca..8d9cdba 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/boolex/OnErrorEvaluator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/OnErrorEvaluator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,11 +27,12 @@ import ch.qos.logback.core.boolex.EventEvaluatorBase;
*/
public class OnErrorEvaluator extends EventEvaluatorBase<ILoggingEvent> {
- /**
- * Return true if event passed as parameter has level ERROR or higher, returns
- * false otherwise.
- */
- public boolean evaluate(ILoggingEvent event) throws NullPointerException, EvaluationException {
- return event.getLevel().levelInt >= Level.ERROR_INT;
- }
+ /**
+ * Return true if event passed as parameter has level ERROR or higher, returns
+ * false otherwise.
+ */
+ public boolean evaluate(ILoggingEvent event) throws NullPointerException,
+ EvaluationException {
+ return event.getLevel().levelInt >= Level.ERROR_INT;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/boolex/OnMarkerEvaluator.java b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/OnMarkerEvaluator.java
index a0e52a9..b04b980 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/boolex/OnMarkerEvaluator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/OnMarkerEvaluator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,28 +30,29 @@ import ch.qos.logback.core.boolex.EventEvaluatorBase;
*/
public class OnMarkerEvaluator extends EventEvaluatorBase<ILoggingEvent> {
- List<String> markerList = new ArrayList<String>();
+ List<String> markerList = new ArrayList<String>();
- public void addMarker(String markerStr) {
- markerList.add(markerStr);
+ public void addMarker(String markerStr) {
+ markerList.add(markerStr);
+ }
+
+ /**
+ * Return true if event passed as parameter contains one of the specified
+ * user-markers.
+ */
+ public boolean evaluate(ILoggingEvent event) throws NullPointerException,
+ EvaluationException {
+
+ Marker eventsMarker = event.getMarker();
+ if (eventsMarker == null) {
+ return false;
}
- /**
- * Return true if event passed as parameter contains one of the specified
- * user-markers.
- */
- public boolean evaluate(ILoggingEvent event) throws NullPointerException, EvaluationException {
-
- Marker eventsMarker = event.getMarker();
- if (eventsMarker == null) {
- return false;
- }
-
- for (String markerStr : markerList) {
- if (eventsMarker.contains(markerStr)) {
- return true;
- }
- }
- return false;
+ for (String markerStr : markerList) {
+ if (eventsMarker.contains(markerStr)) {
+ return true;
+ }
}
+ return false;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java
index 1a8d3ad..4c758e1 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -41,255 +41,273 @@ import ch.qos.logback.core.db.DBAppenderBase;
* @author Sébastien Pennec
*/
public class DBAppender extends DBAppenderBase<ILoggingEvent> {
- protected String insertPropertiesSQL;
- protected String insertExceptionSQL;
- protected String insertSQL;
- protected static final Method GET_GENERATED_KEYS_METHOD;
-
- private DBNameResolver dbNameResolver;
-
- static final int TIMESTMP_INDEX = 1;
- static final int FORMATTED_MESSAGE_INDEX = 2;
- static final int LOGGER_NAME_INDEX = 3;
- static final int LEVEL_STRING_INDEX = 4;
- static final int THREAD_NAME_INDEX = 5;
- static final int REFERENCE_FLAG_INDEX = 6;
- static final int ARG0_INDEX = 7;
- static final int ARG1_INDEX = 8;
- static final int ARG2_INDEX = 9;
- static final int ARG3_INDEX = 10;
- static final int CALLER_FILENAME_INDEX = 11;
- static final int CALLER_CLASS_INDEX = 12;
- static final int CALLER_METHOD_INDEX = 13;
- static final int CALLER_LINE_INDEX = 14;
- static final int EVENT_ID_INDEX = 15;
-
- static final StackTraceElement EMPTY_CALLER_DATA = CallerData.naInstance();
-
- static {
- // PreparedStatement.getGeneratedKeys() method was added in JDK 1.4
- Method getGeneratedKeysMethod;
- try {
- // the
- getGeneratedKeysMethod = PreparedStatement.class.getMethod("getGeneratedKeys", (Class[]) null);
- } catch (Exception ex) {
- getGeneratedKeysMethod = null;
- }
- GET_GENERATED_KEYS_METHOD = getGeneratedKeysMethod;
- }
-
- public void setDbNameResolver(DBNameResolver dbNameResolver) {
- this.dbNameResolver = dbNameResolver;
+ protected String insertPropertiesSQL;
+ protected String insertExceptionSQL;
+ protected String insertSQL;
+ protected static final Method GET_GENERATED_KEYS_METHOD;
+
+ private DBNameResolver dbNameResolver;
+
+ static final int TIMESTMP_INDEX = 1;
+ static final int FORMATTED_MESSAGE_INDEX = 2;
+ static final int LOGGER_NAME_INDEX = 3;
+ static final int LEVEL_STRING_INDEX = 4;
+ static final int THREAD_NAME_INDEX = 5;
+ static final int REFERENCE_FLAG_INDEX = 6;
+ static final int ARG0_INDEX = 7;
+ static final int ARG1_INDEX = 8;
+ static final int ARG2_INDEX = 9;
+ static final int ARG3_INDEX = 10;
+ static final int CALLER_FILENAME_INDEX = 11;
+ static final int CALLER_CLASS_INDEX = 12;
+ static final int CALLER_METHOD_INDEX = 13;
+ static final int CALLER_LINE_INDEX = 14;
+ static final int EVENT_ID_INDEX = 15;
+
+ static final StackTraceElement EMPTY_CALLER_DATA = CallerData.naInstance();
+
+ static {
+ // PreparedStatement.getGeneratedKeys() method was added in JDK 1.4
+ Method getGeneratedKeysMethod;
+ try {
+ // the
+ getGeneratedKeysMethod = PreparedStatement.class.getMethod(
+ "getGeneratedKeys", (Class[]) null);
+ } catch (Exception ex) {
+ getGeneratedKeysMethod = null;
}
-
- @Override
- public void start() {
- if (dbNameResolver == null)
- dbNameResolver = new DefaultDBNameResolver();
- insertExceptionSQL = SQLBuilder.buildInsertExceptionSQL(dbNameResolver);
- insertPropertiesSQL = SQLBuilder.buildInsertPropertiesSQL(dbNameResolver);
- insertSQL = SQLBuilder.buildInsertSQL(dbNameResolver);
- super.start();
+ GET_GENERATED_KEYS_METHOD = getGeneratedKeysMethod;
+ }
+
+ public void setDbNameResolver(DBNameResolver dbNameResolver) {
+ this.dbNameResolver = dbNameResolver;
+ }
+
+ @Override
+ public void start() {
+ if (dbNameResolver == null)
+ dbNameResolver = new DefaultDBNameResolver();
+ insertExceptionSQL = SQLBuilder.buildInsertExceptionSQL(dbNameResolver);
+ insertPropertiesSQL = SQLBuilder.buildInsertPropertiesSQL(dbNameResolver);
+ insertSQL = SQLBuilder.buildInsertSQL(dbNameResolver);
+ super.start();
+ }
+
+ @Override
+ protected void subAppend(ILoggingEvent event, Connection connection,
+ PreparedStatement insertStatement) throws Throwable {
+
+ bindLoggingEventWithInsertStatement(insertStatement, event);
+ bindLoggingEventArgumentsWithPreparedStatement(insertStatement, event.getArgumentArray());
+
+ // This is expensive... should we do it every time?
+ bindCallerDataWithPreparedStatement(insertStatement, event.getCallerData());
+
+ int updateCount = insertStatement.executeUpdate();
+ if (updateCount != 1) {
+ addWarn("Failed to insert loggingEvent");
}
+ }
- @Override
- protected void subAppend(ILoggingEvent event, Connection connection, PreparedStatement insertStatement) throws Throwable {
-
- bindLoggingEventWithInsertStatement(insertStatement, event);
- bindLoggingEventArgumentsWithPreparedStatement(insertStatement, event.getArgumentArray());
-
- // This is expensive... should we do it every time?
- bindCallerDataWithPreparedStatement(insertStatement, event.getCallerData());
+ protected void secondarySubAppend(ILoggingEvent event, Connection connection,
+ long eventId) throws Throwable {
+ Map<String, String> mergedMap = mergePropertyMaps(event);
+ insertProperties(mergedMap, connection, eventId);
- int updateCount = insertStatement.executeUpdate();
- if (updateCount != 1) {
- addWarn("Failed to insert loggingEvent");
- }
+ if (event.getThrowableProxy() != null) {
+ insertThrowable(event.getThrowableProxy(), connection, eventId);
}
+ }
- protected void secondarySubAppend(ILoggingEvent event, Connection connection, long eventId) throws Throwable {
- Map<String, String> mergedMap = mergePropertyMaps(event);
- insertProperties(mergedMap, connection, eventId);
+ void bindLoggingEventWithInsertStatement(PreparedStatement stmt,
+ ILoggingEvent event) throws SQLException {
+ stmt.setLong(TIMESTMP_INDEX, event.getTimeStamp());
+ stmt.setString(FORMATTED_MESSAGE_INDEX, event.getFormattedMessage());
+ stmt.setString(LOGGER_NAME_INDEX, event.getLoggerName());
+ stmt.setString(LEVEL_STRING_INDEX, event.getLevel().toString());
+ stmt.setString(THREAD_NAME_INDEX, event.getThreadName());
+ stmt.setShort(REFERENCE_FLAG_INDEX, DBHelper.computeReferenceMask(event));
+ }
- if (event.getThrowableProxy() != null) {
- insertThrowable(event.getThrowableProxy(), connection, eventId);
- }
- }
-
- void bindLoggingEventWithInsertStatement(PreparedStatement stmt, ILoggingEvent event) throws SQLException {
- stmt.setLong(TIMESTMP_INDEX, event.getTimeStamp());
- stmt.setString(FORMATTED_MESSAGE_INDEX, event.getFormattedMessage());
- stmt.setString(LOGGER_NAME_INDEX, event.getLoggerName());
- stmt.setString(LEVEL_STRING_INDEX, event.getLevel().toString());
- stmt.setString(THREAD_NAME_INDEX, event.getThreadName());
- stmt.setShort(REFERENCE_FLAG_INDEX, DBHelper.computeReferenceMask(event));
- }
+ void bindLoggingEventArgumentsWithPreparedStatement(PreparedStatement stmt,
+ Object[] argArray) throws SQLException {
- void bindLoggingEventArgumentsWithPreparedStatement(PreparedStatement stmt, Object[] argArray) throws SQLException {
+ int arrayLen = argArray != null ? argArray.length : 0;
- int arrayLen = argArray != null ? argArray.length : 0;
-
- for (int i = 0; i < arrayLen && i < 4; i++) {
- stmt.setString(ARG0_INDEX + i, asStringTruncatedTo254(argArray[i]));
- }
- if (arrayLen < 4) {
- for (int i = arrayLen; i < 4; i++) {
- stmt.setString(ARG0_INDEX + i, null);
- }
- }
+ for(int i = 0; i < arrayLen && i < 4; i++) {
+ stmt.setString(ARG0_INDEX+i, asStringTruncatedTo254(argArray[i]));
}
-
- String asStringTruncatedTo254(Object o) {
- String s = null;
- if (o != null) {
- s = o.toString();
- }
-
- if (s == null) {
- return null;
- }
- if (s.length() <= 254) {
- return s;
- } else {
- return s.substring(0, 254);
- }
+ if(arrayLen < 4) {
+ for(int i = arrayLen; i < 4; i++) {
+ stmt.setString(ARG0_INDEX+i, null);
+ }
}
+ }
- void bindCallerDataWithPreparedStatement(PreparedStatement stmt, StackTraceElement[] callerDataArray) throws SQLException {
+ String asStringTruncatedTo254(Object o) {
+ String s = null;
+ if(o != null) {
+ s= o.toString();
+ }
- StackTraceElement caller = extractFirstCaller(callerDataArray);
-
- stmt.setString(CALLER_FILENAME_INDEX, caller.getFileName());
- stmt.setString(CALLER_CLASS_INDEX, caller.getClassName());
- stmt.setString(CALLER_METHOD_INDEX, caller.getMethodName());
- stmt.setString(CALLER_LINE_INDEX, Integer.toString(caller.getLineNumber()));
+ if(s == null) {
+ return null;
}
-
- private StackTraceElement extractFirstCaller(StackTraceElement[] callerDataArray) {
- StackTraceElement caller = EMPTY_CALLER_DATA;
- if (hasAtLeastOneNonNullElement(callerDataArray))
- caller = callerDataArray[0];
- return caller;
+ if(s.length() <= 254) {
+ return s;
+ } else {
+ return s.substring(0, 254);
}
-
- private boolean hasAtLeastOneNonNullElement(StackTraceElement[] callerDataArray) {
- return callerDataArray != null && callerDataArray.length > 0 && callerDataArray[0] != null;
- }
-
- Map<String, String> mergePropertyMaps(ILoggingEvent event) {
- Map<String, String> mergedMap = new HashMap<String, String>();
- // we add the context properties first, then the event properties, since
- // we consider that event-specific properties should have priority over
- // context-wide properties.
- Map<String, String> loggerContextMap = event.getLoggerContextVO().getPropertyMap();
- Map<String, String> mdcMap = event.getMDCPropertyMap();
- if (loggerContextMap != null) {
- mergedMap.putAll(loggerContextMap);
- }
- if (mdcMap != null) {
- mergedMap.putAll(mdcMap);
- }
-
- return mergedMap;
+ }
+
+ void bindCallerDataWithPreparedStatement(PreparedStatement stmt,
+ StackTraceElement[] callerDataArray) throws SQLException {
+
+ StackTraceElement caller = extractFirstCaller(callerDataArray);
+
+ stmt.setString(CALLER_FILENAME_INDEX, caller.getFileName());
+ stmt.setString(CALLER_CLASS_INDEX, caller.getClassName());
+ stmt.setString(CALLER_METHOD_INDEX, caller.getMethodName());
+ stmt.setString(CALLER_LINE_INDEX, Integer.toString(caller.getLineNumber()));
+ }
+
+ private StackTraceElement extractFirstCaller(StackTraceElement[] callerDataArray) {
+ StackTraceElement caller = EMPTY_CALLER_DATA;
+ if(hasAtLeastOneNonNullElement(callerDataArray))
+ caller = callerDataArray[0];
+ return caller;
+ }
+
+ private boolean hasAtLeastOneNonNullElement(StackTraceElement[] callerDataArray) {
+ return callerDataArray != null && callerDataArray.length > 0 && callerDataArray[0] != null;
+ }
+
+ Map<String, String> mergePropertyMaps(ILoggingEvent event) {
+ Map<String, String> mergedMap = new HashMap<String, String>();
+ // we add the context properties first, then the event properties, since
+ // we consider that event-specific properties should have priority over
+ // context-wide properties.
+ Map<String, String> loggerContextMap = event.getLoggerContextVO()
+ .getPropertyMap();
+ Map<String, String> mdcMap = event.getMDCPropertyMap();
+ if (loggerContextMap != null) {
+ mergedMap.putAll(loggerContextMap);
}
-
- @Override
- protected Method getGeneratedKeysMethod() {
- return GET_GENERATED_KEYS_METHOD;
+ if (mdcMap != null) {
+ mergedMap.putAll(mdcMap);
}
- @Override
- protected String getInsertSQL() {
- return insertSQL;
- }
-
- protected void insertProperties(Map<String, String> mergedMap, Connection connection, long eventId) throws SQLException {
- Set<String> propertiesKeys = mergedMap.keySet();
- if (propertiesKeys.size() > 0) {
- PreparedStatement insertPropertiesStatement = null;
- try {
- insertPropertiesStatement = connection.prepareStatement(insertPropertiesSQL);
-
- for (String key : propertiesKeys) {
- String value = mergedMap.get(key);
-
- insertPropertiesStatement.setLong(1, eventId);
- insertPropertiesStatement.setString(2, key);
- insertPropertiesStatement.setString(3, value);
-
- if (cnxSupportsBatchUpdates) {
- insertPropertiesStatement.addBatch();
- } else {
- insertPropertiesStatement.execute();
- }
- }
-
- if (cnxSupportsBatchUpdates) {
- insertPropertiesStatement.executeBatch();
- }
- } finally {
- closeStatement(insertPropertiesStatement);
- }
+ return mergedMap;
+ }
+
+ @Override
+ protected Method getGeneratedKeysMethod() {
+ return GET_GENERATED_KEYS_METHOD;
+ }
+
+ @Override
+ protected String getInsertSQL() {
+ return insertSQL;
+ }
+
+ protected void insertProperties(Map<String, String> mergedMap,
+ Connection connection, long eventId) throws SQLException {
+ Set<String> propertiesKeys = mergedMap.keySet();
+ if (propertiesKeys.size() > 0) {
+ PreparedStatement insertPropertiesStatement = null;
+ try {
+ insertPropertiesStatement = connection
+ .prepareStatement(insertPropertiesSQL);
+
+ for (String key : propertiesKeys) {
+ String value = mergedMap.get(key);
+
+ insertPropertiesStatement.setLong(1, eventId);
+ insertPropertiesStatement.setString(2, key);
+ insertPropertiesStatement.setString(3, value);
+
+ if (cnxSupportsBatchUpdates) {
+ insertPropertiesStatement.addBatch();
+ } else {
+ insertPropertiesStatement.execute();
+ }
}
- }
- /**
- * Add an exception statement either as a batch or execute immediately if
- * batch updates are not supported.
- */
- void updateExceptionStatement(PreparedStatement exceptionStatement, String txt, short i, long eventId) throws SQLException {
- exceptionStatement.setLong(1, eventId);
- exceptionStatement.setShort(2, i);
- exceptionStatement.setString(3, txt);
if (cnxSupportsBatchUpdates) {
- exceptionStatement.addBatch();
- } else {
- exceptionStatement.execute();
+ insertPropertiesStatement.executeBatch();
}
+ } finally {
+ closeStatement(insertPropertiesStatement);
+ }
+ }
+ }
+
+ /**
+ * Add an exception statement either as a batch or execute immediately if
+ * batch updates are not supported.
+ */
+ void updateExceptionStatement(PreparedStatement exceptionStatement,
+ String txt, short i, long eventId) throws SQLException {
+ exceptionStatement.setLong(1, eventId);
+ exceptionStatement.setShort(2, i);
+ exceptionStatement.setString(3, txt);
+ if (cnxSupportsBatchUpdates) {
+ exceptionStatement.addBatch();
+ } else {
+ exceptionStatement.execute();
+ }
+ }
+
+ short buildExceptionStatement(IThrowableProxy tp, short baseIndex,
+ PreparedStatement insertExceptionStatement, long eventId)
+ throws SQLException {
+
+ StringBuilder buf = new StringBuilder();
+ ThrowableProxyUtil.subjoinFirstLine(buf, tp);
+ updateExceptionStatement(insertExceptionStatement, buf.toString(),
+ baseIndex++, eventId);
+
+ int commonFrames = tp.getCommonFrames();
+ StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
+ for (int i = 0; i < stepArray.length - commonFrames; i++) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(CoreConstants.TAB);
+ ThrowableProxyUtil.subjoinSTEP(sb, stepArray[i]);
+ updateExceptionStatement(insertExceptionStatement, sb.toString(),
+ baseIndex++, eventId);
}
- short buildExceptionStatement(IThrowableProxy tp, short baseIndex, PreparedStatement insertExceptionStatement, long eventId) throws SQLException {
-
- StringBuilder buf = new StringBuilder();
- ThrowableProxyUtil.subjoinFirstLine(buf, tp);
- updateExceptionStatement(insertExceptionStatement, buf.toString(), baseIndex++, eventId);
-
- int commonFrames = tp.getCommonFrames();
- StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
- for (int i = 0; i < stepArray.length - commonFrames; i++) {
- StringBuilder sb = new StringBuilder();
- sb.append(CoreConstants.TAB);
- ThrowableProxyUtil.subjoinSTEP(sb, stepArray[i]);
- updateExceptionStatement(insertExceptionStatement, sb.toString(), baseIndex++, eventId);
- }
-
- if (commonFrames > 0) {
- StringBuilder sb = new StringBuilder();
- sb.append(CoreConstants.TAB).append("... ").append(commonFrames).append(" common frames omitted");
- updateExceptionStatement(insertExceptionStatement, sb.toString(), baseIndex++, eventId);
- }
-
- return baseIndex;
+ if (commonFrames > 0) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(CoreConstants.TAB).append("... ").append(commonFrames).append(
+ " common frames omitted");
+ updateExceptionStatement(insertExceptionStatement, sb.toString(),
+ baseIndex++, eventId);
}
- protected void insertThrowable(IThrowableProxy tp, Connection connection, long eventId) throws SQLException {
+ return baseIndex;
+ }
- PreparedStatement exceptionStatement = null;
- try {
- exceptionStatement = connection.prepareStatement(insertExceptionSQL);
+ protected void insertThrowable(IThrowableProxy tp, Connection connection,
+ long eventId) throws SQLException {
- short baseIndex = 0;
- while (tp != null) {
- baseIndex = buildExceptionStatement(tp, baseIndex, exceptionStatement, eventId);
- tp = tp.getCause();
- }
+ PreparedStatement exceptionStatement = null;
+ try {
+ exceptionStatement = connection.prepareStatement(insertExceptionSQL);
- if (cnxSupportsBatchUpdates) {
- exceptionStatement.executeBatch();
- }
- } finally {
- closeStatement(exceptionStatement);
- }
+ short baseIndex = 0;
+ while (tp != null) {
+ baseIndex = buildExceptionStatement(tp, baseIndex, exceptionStatement,
+ eventId);
+ tp = tp.getCause();
+ }
+ if (cnxSupportsBatchUpdates) {
+ exceptionStatement.executeBatch();
+ }
+ } finally {
+ closeStatement(exceptionStatement);
}
+
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/db/DBHelper.java b/logback-classic/src/main/java/ch/qos/logback/classic/db/DBHelper.java
index 44df361..16a9b1a 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/db/DBHelper.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/db/DBHelper.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,27 +21,27 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
*/
public class DBHelper {
- public static final short PROPERTIES_EXIST = 0x01;
- public static final short EXCEPTION_EXISTS = 0x02;
+ public static final short PROPERTIES_EXIST = 0x01;
+ public static final short EXCEPTION_EXISTS = 0x02;
- public static short computeReferenceMask(ILoggingEvent event) {
- short mask = 0;
+ public static short computeReferenceMask(ILoggingEvent event) {
+ short mask = 0;
- int mdcPropSize = 0;
- if (event.getMDCPropertyMap() != null) {
- mdcPropSize = event.getMDCPropertyMap().keySet().size();
- }
- int contextPropSize = 0;
- if (event.getLoggerContextVO().getPropertyMap() != null) {
- contextPropSize = event.getLoggerContextVO().getPropertyMap().size();
- }
+ int mdcPropSize = 0;
+ if (event.getMDCPropertyMap() != null) {
+ mdcPropSize = event.getMDCPropertyMap().keySet().size();
+ }
+ int contextPropSize = 0;
+ if (event.getLoggerContextVO().getPropertyMap() != null) {
+ contextPropSize = event.getLoggerContextVO().getPropertyMap().size();
+ }
- if (mdcPropSize > 0 || contextPropSize > 0) {
- mask = PROPERTIES_EXIST;
- }
- if (event.getThrowableProxy() != null) {
- mask |= EXCEPTION_EXISTS;
- }
- return mask;
+ if (mdcPropSize > 0 || contextPropSize > 0) {
+ mask = PROPERTIES_EXIST;
+ }
+ if (event.getThrowableProxy() != null) {
+ mask |= EXCEPTION_EXISTS;
}
+ return mask;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/db/SQLBuilder.java b/logback-classic/src/main/java/ch/qos/logback/classic/db/SQLBuilder.java
index 02ae070..87ca709 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/db/SQLBuilder.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/db/SQLBuilder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,44 +21,44 @@ import ch.qos.logback.classic.db.names.*;
*/
public class SQLBuilder {
- static String buildInsertPropertiesSQL(DBNameResolver dbNameResolver) {
- StringBuilder sqlBuilder = new StringBuilder("INSERT INTO ");
- sqlBuilder.append(dbNameResolver.getTableName(TableName.LOGGING_EVENT_PROPERTY)).append(" (");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.EVENT_ID)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.MAPPED_KEY)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.MAPPED_VALUE)).append(") ");
- sqlBuilder.append("VALUES (?, ?, ?)");
- return sqlBuilder.toString();
- }
+ static String buildInsertPropertiesSQL(DBNameResolver dbNameResolver) {
+ StringBuilder sqlBuilder = new StringBuilder("INSERT INTO ");
+ sqlBuilder.append(dbNameResolver.getTableName(TableName.LOGGING_EVENT_PROPERTY)).append(" (");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.EVENT_ID)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.MAPPED_KEY)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.MAPPED_VALUE)).append(") ");
+ sqlBuilder.append("VALUES (?, ?, ?)");
+ return sqlBuilder.toString();
+ }
- static String buildInsertExceptionSQL(DBNameResolver dbNameResolver) {
- StringBuilder sqlBuilder = new StringBuilder("INSERT INTO ");
- sqlBuilder.append(dbNameResolver.getTableName(TableName.LOGGING_EVENT_EXCEPTION)).append(" (");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.EVENT_ID)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.I)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.TRACE_LINE)).append(") ");
- sqlBuilder.append("VALUES (?, ?, ?)");
- return sqlBuilder.toString();
- }
+ static String buildInsertExceptionSQL(DBNameResolver dbNameResolver) {
+ StringBuilder sqlBuilder = new StringBuilder("INSERT INTO ");
+ sqlBuilder.append(dbNameResolver.getTableName(TableName.LOGGING_EVENT_EXCEPTION)).append(" (");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.EVENT_ID)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.I)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.TRACE_LINE)).append(") ");
+ sqlBuilder.append("VALUES (?, ?, ?)");
+ return sqlBuilder.toString();
+ }
- static String buildInsertSQL(DBNameResolver dbNameResolver) {
- StringBuilder sqlBuilder = new StringBuilder("INSERT INTO ");
- sqlBuilder.append(dbNameResolver.getTableName(TableName.LOGGING_EVENT)).append(" (");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.TIMESTMP)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.FORMATTED_MESSAGE)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.LOGGER_NAME)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.LEVEL_STRING)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.THREAD_NAME)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.REFERENCE_FLAG)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.ARG0)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.ARG1)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.ARG2)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.ARG3)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.CALLER_FILENAME)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.CALLER_CLASS)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.CALLER_METHOD)).append(", ");
- sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.CALLER_LINE)).append(") ");
- sqlBuilder.append("VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
- return sqlBuilder.toString();
- }
+ static String buildInsertSQL(DBNameResolver dbNameResolver) {
+ StringBuilder sqlBuilder = new StringBuilder("INSERT INTO ");
+ sqlBuilder.append(dbNameResolver.getTableName(TableName.LOGGING_EVENT)).append(" (");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.TIMESTMP)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.FORMATTED_MESSAGE)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.LOGGER_NAME)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.LEVEL_STRING)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.THREAD_NAME)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.REFERENCE_FLAG)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.ARG0)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.ARG1)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.ARG2)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.ARG3)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.CALLER_FILENAME)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.CALLER_CLASS)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.CALLER_METHOD)).append(", ");
+ sqlBuilder.append(dbNameResolver.getColumnName(ColumnName.CALLER_LINE)).append(") ");
+ sqlBuilder.append("VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
+ return sqlBuilder.toString();
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/db/names/ColumnName.java b/logback-classic/src/main/java/ch/qos/logback/classic/db/names/ColumnName.java
index 2d4f607..8fb96c3 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/db/names/ColumnName.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/db/names/ColumnName.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,12 +15,27 @@ package ch.qos.logback.classic.db.names;
public enum ColumnName {
- EVENT_ID,
+ EVENT_ID,
+
+ TIMESTMP,
+ FORMATTED_MESSAGE,
+ LOGGER_NAME,
+ LEVEL_STRING,
+ THREAD_NAME,
+ REFERENCE_FLAG,
+ ARG0,
+ ARG1,
+ ARG2,
+ ARG3,
+ CALLER_FILENAME,
+ CALLER_CLASS,
+ CALLER_METHOD,
+ CALLER_LINE,
+
+ // MDC
+ MAPPED_KEY,
+ MAPPED_VALUE,
- TIMESTMP, FORMATTED_MESSAGE, LOGGER_NAME, LEVEL_STRING, THREAD_NAME, REFERENCE_FLAG, ARG0, ARG1, ARG2, ARG3, CALLER_FILENAME, CALLER_CLASS, CALLER_METHOD, CALLER_LINE,
-
- // MDC
- MAPPED_KEY, MAPPED_VALUE,
-
- I, TRACE_LINE;
+ I,
+ TRACE_LINE;
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/db/names/DBNameResolver.java b/logback-classic/src/main/java/ch/qos/logback/classic/db/names/DBNameResolver.java
index a279d42..e39a71b 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/db/names/DBNameResolver.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/db/names/DBNameResolver.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,11 +22,11 @@ package ch.qos.logback.classic.db.names;
* @author Ceki Gulcu
* @since 0.9.19
* @see ch.qos.logback.classic.db.names.DefaultDBNameResolver
- * @see ch.qos.logback.classic.db.names.SimpleDBNameResolver
+ * @see ch.qos.logback.classic.db.names.CustomDBNameResolver
*/
public interface DBNameResolver {
- <N extends Enum<?>> String getTableName(N tableName);
+ <N extends Enum<?>> String getTableName(N tableName);
- <N extends Enum<?>> String getColumnName(N columnName);
+ <N extends Enum<?>> String getColumnName(N columnName);
}
\ No newline at end of file
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/db/names/DefaultDBNameResolver.java b/logback-classic/src/main/java/ch/qos/logback/classic/db/names/DefaultDBNameResolver.java
index 489fefb..ddb097f 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/db/names/DefaultDBNameResolver.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/db/names/DefaultDBNameResolver.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,12 +23,12 @@ package ch.qos.logback.classic.db.names;
*/
public class DefaultDBNameResolver implements DBNameResolver {
- public <N extends Enum<?>> String getTableName(N tableName) {
- return tableName.toString().toLowerCase();
- }
+ public <N extends Enum<?>> String getTableName(N tableName) {
+ return tableName.toString().toLowerCase();
+ }
- public <N extends Enum<?>> String getColumnName(N columnName) {
- return columnName.toString().toLowerCase();
- }
+ public <N extends Enum<?>> String getColumnName(N columnName) {
+ return columnName.toString().toLowerCase();
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/db/names/SimpleDBNameResolver.java b/logback-classic/src/main/java/ch/qos/logback/classic/db/names/SimpleDBNameResolver.java
index 76f63af..70e9fb0 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/db/names/SimpleDBNameResolver.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/db/names/SimpleDBNameResolver.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,35 +21,35 @@ package ch.qos.logback.classic.db.names;
*/
public class SimpleDBNameResolver implements DBNameResolver {
- private String tableNamePrefix = "";
+ private String tableNamePrefix = "";
- private String tableNameSuffix = "";
+ private String tableNameSuffix = "";
- private String columnNamePrefix = "";
+ private String columnNamePrefix = "";
- private String columnNameSuffix = "";
+ private String columnNameSuffix = "";
- public <N extends Enum<?>> String getTableName(N tableName) {
- return tableNamePrefix + tableName.name().toLowerCase() + tableNameSuffix;
- }
+ public <N extends Enum<?>> String getTableName(N tableName) {
+ return tableNamePrefix + tableName.name().toLowerCase() + tableNameSuffix;
+ }
- public <N extends Enum<?>> String getColumnName(N columnName) {
- return columnNamePrefix + columnName.name().toLowerCase() + columnNameSuffix;
- }
+ public <N extends Enum<?>> String getColumnName(N columnName) {
+ return columnNamePrefix + columnName.name().toLowerCase() + columnNameSuffix;
+ }
- public void setTableNamePrefix(String tableNamePrefix) {
- this.tableNamePrefix = tableNamePrefix != null ? tableNamePrefix : "";
- }
+ public void setTableNamePrefix(String tableNamePrefix) {
+ this.tableNamePrefix = tableNamePrefix != null? tableNamePrefix : "";
+ }
- public void setTableNameSuffix(String tableNameSuffix) {
- this.tableNameSuffix = tableNameSuffix != null ? tableNameSuffix : "";
- }
+ public void setTableNameSuffix(String tableNameSuffix) {
+ this.tableNameSuffix = tableNameSuffix != null? tableNameSuffix : "";
+ }
- public void setColumnNamePrefix(String columnNamePrefix) {
- this.columnNamePrefix = columnNamePrefix != null ? columnNamePrefix : "";
- }
+ public void setColumnNamePrefix(String columnNamePrefix) {
+ this.columnNamePrefix = columnNamePrefix != null? columnNamePrefix : "";
+ }
- public void setColumnNameSuffix(String columnNameSuffix) {
- this.columnNameSuffix = columnNameSuffix != null ? columnNameSuffix : "";
- }
+ public void setColumnNameSuffix(String columnNameSuffix) {
+ this.columnNameSuffix = columnNameSuffix != null? columnNameSuffix : "";
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/db/names/TableName.java b/logback-classic/src/main/java/ch/qos/logback/classic/db/names/TableName.java
index 6134488..5d145a5 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/db/names/TableName.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/db/names/TableName.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,6 +19,8 @@ package ch.qos.logback.classic.db.names;
*/
public enum TableName {
- LOGGING_EVENT, LOGGING_EVENT_PROPERTY, LOGGING_EVENT_EXCEPTION
+ LOGGING_EVENT,
+ LOGGING_EVENT_PROPERTY,
+ LOGGING_EVENT_EXCEPTION
}
diff --git a/logback-classic/src/main/resources/ch/qos/logback/classic/db/script/db2.sql b/logback-classic/src/main/java/ch/qos/logback/classic/db/script/db2.sql
similarity index 100%
rename from logback-classic/src/main/resources/ch/qos/logback/classic/db/script/db2.sql
rename to logback-classic/src/main/java/ch/qos/logback/classic/db/script/db2.sql
diff --git a/logback-classic/src/main/resources/ch/qos/logback/classic/db/script/h2.sql b/logback-classic/src/main/java/ch/qos/logback/classic/db/script/h2.sql
similarity index 100%
rename from logback-classic/src/main/resources/ch/qos/logback/classic/db/script/h2.sql
rename to logback-classic/src/main/java/ch/qos/logback/classic/db/script/h2.sql
diff --git a/logback-classic/src/main/resources/ch/qos/logback/classic/db/script/hsqldb.sql b/logback-classic/src/main/java/ch/qos/logback/classic/db/script/hsqldb.sql
similarity index 100%
rename from logback-classic/src/main/resources/ch/qos/logback/classic/db/script/hsqldb.sql
rename to logback-classic/src/main/java/ch/qos/logback/classic/db/script/hsqldb.sql
diff --git a/logback-classic/src/main/resources/ch/qos/logback/classic/db/script/mssql.sql b/logback-classic/src/main/java/ch/qos/logback/classic/db/script/mssql.sql
similarity index 100%
rename from logback-classic/src/main/resources/ch/qos/logback/classic/db/script/mssql.sql
rename to logback-classic/src/main/java/ch/qos/logback/classic/db/script/mssql.sql
diff --git a/logback-classic/src/main/resources/ch/qos/logback/classic/db/script/mysql.sql b/logback-classic/src/main/java/ch/qos/logback/classic/db/script/mysql.sql
similarity index 100%
rename from logback-classic/src/main/resources/ch/qos/logback/classic/db/script/mysql.sql
rename to logback-classic/src/main/java/ch/qos/logback/classic/db/script/mysql.sql
diff --git a/logback-classic/src/main/resources/ch/qos/logback/classic/db/script/oracle.sql b/logback-classic/src/main/java/ch/qos/logback/classic/db/script/oracle.sql
similarity index 100%
rename from logback-classic/src/main/resources/ch/qos/logback/classic/db/script/oracle.sql
rename to logback-classic/src/main/java/ch/qos/logback/classic/db/script/oracle.sql
diff --git a/logback-classic/src/main/resources/ch/qos/logback/classic/db/script/postgresql.sql b/logback-classic/src/main/java/ch/qos/logback/classic/db/script/postgresql.sql
similarity index 100%
rename from logback-classic/src/main/resources/ch/qos/logback/classic/db/script/postgresql.sql
rename to logback-classic/src/main/java/ch/qos/logback/classic/db/script/postgresql.sql
diff --git a/logback-classic/src/main/resources/ch/qos/logback/classic/db/script/sqllite.sql b/logback-classic/src/main/java/ch/qos/logback/classic/db/script/sqllite.sql
similarity index 100%
rename from logback-classic/src/main/resources/ch/qos/logback/classic/db/script/sqllite.sql
rename to logback-classic/src/main/java/ch/qos/logback/classic/db/script/sqllite.sql
diff --git a/logback-classic/src/main/resources/ch/qos/logback/classic/db/script/sybaseSqlAnywhere.sql b/logback-classic/src/main/java/ch/qos/logback/classic/db/script/sybaseSqlAnywhere.sql
similarity index 100%
rename from logback-classic/src/main/resources/ch/qos/logback/classic/db/script/sybaseSqlAnywhere.sql
rename to logback-classic/src/main/java/ch/qos/logback/classic/db/script/sybaseSqlAnywhere.sql
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/encoder/PatternLayoutEncoder.java b/logback-classic/src/main/java/ch/qos/logback/classic/encoder/PatternLayoutEncoder.java
index 04be85d..8934329 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/encoder/PatternLayoutEncoder.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/encoder/PatternLayoutEncoder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,15 +19,15 @@ import ch.qos.logback.core.pattern.PatternLayoutEncoderBase;
public class PatternLayoutEncoder extends PatternLayoutEncoderBase<ILoggingEvent> {
- @Override
- public void start() {
- PatternLayout patternLayout = new PatternLayout();
- patternLayout.setContext(context);
- patternLayout.setPattern(getPattern());
- patternLayout.setOutputPatternAsHeader(outputPatternAsHeader);
- patternLayout.start();
- this.layout = patternLayout;
- super.start();
- }
-
+ @Override
+ public void start() {
+ PatternLayout patternLayout = new PatternLayout();
+ patternLayout.setContext(context);
+ patternLayout.setPattern(getPattern());
+ patternLayout.setOutputPatternAsHeader(outputPatternAsHeader);
+ patternLayout.start();
+ this.layout = patternLayout;
+ super.start();
+ }
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/filter/LevelFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/filter/LevelFilter.java
index 31ad58c..a013864 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/filter/LevelFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/filter/LevelFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,28 +30,28 @@ import ch.qos.logback.core.spi.FilterReply;
*/
public class LevelFilter extends AbstractMatcherFilter<ILoggingEvent> {
- Level level;
+ Level level;
- @Override
- public FilterReply decide(ILoggingEvent event) {
- if (!isStarted()) {
- return FilterReply.NEUTRAL;
- }
-
- if (event.getLevel().equals(level)) {
- return onMatch;
- } else {
- return onMismatch;
- }
+ @Override
+ public FilterReply decide(ILoggingEvent event) {
+ if (!isStarted()) {
+ return FilterReply.NEUTRAL;
}
- public void setLevel(Level level) {
- this.level = level;
+ if (event.getLevel().equals(level)) {
+ return onMatch;
+ } else {
+ return onMismatch;
}
+ }
+
+ public void setLevel(Level level) {
+ this.level = level;
+ }
- public void start() {
- if (this.level != null) {
- super.start();
- }
+ public void start() {
+ if (this.level != null) {
+ super.start();
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/filter/ThresholdFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/filter/ThresholdFilter.java
index 42de468..1386f58 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/filter/ThresholdFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/filter/ThresholdFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -34,28 +34,28 @@ import ch.qos.logback.core.spi.FilterReply;
*/
public class ThresholdFilter extends Filter<ILoggingEvent> {
- Level level;
-
- @Override
- public FilterReply decide(ILoggingEvent event) {
- if (!isStarted()) {
- return FilterReply.NEUTRAL;
- }
-
- if (event.getLevel().isGreaterOrEqual(level)) {
- return FilterReply.NEUTRAL;
- } else {
- return FilterReply.DENY;
- }
+ Level level;
+
+ @Override
+ public FilterReply decide(ILoggingEvent event) {
+ if (!isStarted()) {
+ return FilterReply.NEUTRAL;
}
-
- public void setLevel(String level) {
- this.level = Level.toLevel(level);
+
+ if (event.getLevel().isGreaterOrEqual(level)) {
+ return FilterReply.NEUTRAL;
+ } else {
+ return FilterReply.DENY;
}
-
- public void start() {
- if (this.level != null) {
- super.start();
- }
+ }
+
+ public void setLevel(String level) {
+ this.level = Level.toLevel(level);
+ }
+
+ public void start() {
+ if (this.level != null) {
+ super.start();
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/gaffer/GafferUtil.java b/logback-classic/src/main/java/ch/qos/logback/classic/gaffer/GafferUtil.java
index 94bc769..c96f0ce 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/gaffer/GafferUtil.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/gaffer/GafferUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,56 +24,57 @@ import java.lang.reflect.InvocationTargetException;
import java.net.URL;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class GafferUtil {
- private static String ERROR_MSG = "Failed to instantiate " + ClassicConstants.GAFFER_CONFIGURATOR_FQCN;
+ private static String ERROR_MSG = "Failed to instantiate " + ClassicConstants.GAFFER_CONFIGURATOR_FQCN;
- public static void runGafferConfiguratorOn(LoggerContext loggerContext, Object origin, File configFile) {
- GafferConfigurator gafferConfigurator = GafferUtil.newGafferConfiguratorInstance(loggerContext, origin);
- if (gafferConfigurator != null) {
- gafferConfigurator.run(configFile);
- }
+ public static void runGafferConfiguratorOn(LoggerContext loggerContext, Object origin, File configFile) {
+ GafferConfigurator gafferConfigurator = GafferUtil.newGafferConfiguratorInstance(loggerContext, origin);
+ if (gafferConfigurator != null) {
+ gafferConfigurator.run(configFile);
}
+ }
- public static void runGafferConfiguratorOn(LoggerContext loggerContext, Object origin, URL configFile) {
- GafferConfigurator gafferConfigurator = GafferUtil.newGafferConfiguratorInstance(loggerContext, origin);
- if (gafferConfigurator != null) {
- gafferConfigurator.run(configFile);
- }
+ public static void runGafferConfiguratorOn(LoggerContext loggerContext, Object origin, URL configFile) {
+ GafferConfigurator gafferConfigurator = GafferUtil.newGafferConfiguratorInstance(loggerContext, origin);
+ if (gafferConfigurator != null) {
+ gafferConfigurator.run(configFile);
}
+ }
- private static GafferConfigurator newGafferConfiguratorInstance(LoggerContext loggerContext, Object origin) {
+ private static GafferConfigurator newGafferConfiguratorInstance(LoggerContext loggerContext, Object origin) {
- try {
- Class gcClass = Class.forName(ClassicConstants.GAFFER_CONFIGURATOR_FQCN);
- Constructor c = gcClass.getConstructor(LoggerContext.class);
- return (GafferConfigurator) c.newInstance(loggerContext);
- } catch (ClassNotFoundException e) {
- addError(loggerContext, origin, ERROR_MSG, e);
- } catch (NoSuchMethodException e) {
- addError(loggerContext, origin, ERROR_MSG, e);
- } catch (InvocationTargetException e) {
- addError(loggerContext, origin, ERROR_MSG, e);
- } catch (InstantiationException e) {
- addError(loggerContext, origin, ERROR_MSG, e);
- } catch (IllegalAccessException e) {
- addError(loggerContext, origin, ERROR_MSG, e);
- }
- return null;
+ try {
+ Class gcClass = Class.forName(ClassicConstants.GAFFER_CONFIGURATOR_FQCN);
+ Constructor c = gcClass.getConstructor(LoggerContext.class);
+ return (GafferConfigurator) c.newInstance(loggerContext);
+ } catch (ClassNotFoundException e) {
+ addError(loggerContext, origin, ERROR_MSG, e);
+ } catch (NoSuchMethodException e) {
+ addError(loggerContext, origin, ERROR_MSG, e);
+ } catch (InvocationTargetException e) {
+ addError(loggerContext, origin, ERROR_MSG, e);
+ } catch (InstantiationException e) {
+ addError(loggerContext, origin, ERROR_MSG, e);
+ } catch (IllegalAccessException e) {
+ addError(loggerContext, origin, ERROR_MSG, e);
}
+ return null;
+ }
- private static void addError(LoggerContext context, Object origin, String msg) {
- addError(context, origin, msg, null);
- }
+ private static void addError(LoggerContext context, Object origin, String msg) {
+ addError(context, origin, msg, null);
+ }
- private static void addError(LoggerContext context, Object origin, String msg, Throwable t) {
- StatusManager sm = context.getStatusManager();
- if (sm == null) {
- return;
- }
- sm.add(new ErrorStatus(msg, origin, t));
+ private static void addError(LoggerContext context, Object origin, String msg, Throwable t) {
+ StatusManager sm = context.getStatusManager();
+ if (sm == null) {
+ return;
}
+ sm.add(new ErrorStatus(msg, origin, t));
+ }
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/helpers/MDCInsertingServletFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/helpers/MDCInsertingServletFilter.java
index c62794c..388a504 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/helpers/MDCInsertingServletFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/helpers/MDCInsertingServletFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -38,51 +38,55 @@ import ch.qos.logback.classic.ClassicConstants;
*/
public class MDCInsertingServletFilter implements Filter {
- public void destroy() {
- // do nothing
- }
+ public void destroy() {
+ // do nothing
+ }
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ public void doFilter(ServletRequest request, ServletResponse response,
+ FilterChain chain) throws IOException, ServletException {
- insertIntoMDC(request);
- try {
- chain.doFilter(request, response);
- } finally {
- clearMDC();
- }
- }
- void insertIntoMDC(ServletRequest request) {
+ insertIntoMDC(request);
+ try {
+ chain.doFilter(request, response);
+ } finally {
+ clearMDC();
+ }
+ }
- MDC.put(ClassicConstants.REQUEST_REMOTE_HOST_MDC_KEY, request.getRemoteHost());
+ void insertIntoMDC(ServletRequest request) {
- if (request instanceof HttpServletRequest) {
- HttpServletRequest httpServletRequest = (HttpServletRequest) request;
- MDC.put(ClassicConstants.REQUEST_REQUEST_URI, httpServletRequest.getRequestURI());
- StringBuffer requestURL = httpServletRequest.getRequestURL();
- if (requestURL != null) {
- MDC.put(ClassicConstants.REQUEST_REQUEST_URL, requestURL.toString());
- }
- MDC.put(ClassicConstants.REQUEST_METHOD, httpServletRequest.getMethod());
- MDC.put(ClassicConstants.REQUEST_QUERY_STRING, httpServletRequest.getQueryString());
- MDC.put(ClassicConstants.REQUEST_USER_AGENT_MDC_KEY, httpServletRequest.getHeader("User-Agent"));
- MDC.put(ClassicConstants.REQUEST_X_FORWARDED_FOR, httpServletRequest.getHeader("X-Forwarded-For"));
- }
+ MDC.put(ClassicConstants.REQUEST_REMOTE_HOST_MDC_KEY, request
+ .getRemoteHost());
+ if (request instanceof HttpServletRequest) {
+ HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+ MDC.put(ClassicConstants.REQUEST_REQUEST_URI, httpServletRequest
+ .getRequestURI());
+ StringBuffer requestURL = httpServletRequest.getRequestURL();
+ if (requestURL != null) {
+ MDC.put(ClassicConstants.REQUEST_REQUEST_URL, requestURL.toString());
+ }
+ MDC.put(ClassicConstants.REQUEST_QUERY_STRING, httpServletRequest.getQueryString());
+ MDC.put(ClassicConstants.REQUEST_USER_AGENT_MDC_KEY, httpServletRequest
+ .getHeader("User-Agent"));
+ MDC.put(ClassicConstants.REQUEST_X_FORWARDED_FOR, httpServletRequest
+ .getHeader("X-Forwarded-For"));
}
- void clearMDC() {
- MDC.remove(ClassicConstants.REQUEST_REMOTE_HOST_MDC_KEY);
- MDC.remove(ClassicConstants.REQUEST_REQUEST_URI);
- MDC.remove(ClassicConstants.REQUEST_QUERY_STRING);
- // removing possibly inexistent item is OK
- MDC.remove(ClassicConstants.REQUEST_REQUEST_URL);
- MDC.remove(ClassicConstants.REQUEST_METHOD);
- MDC.remove(ClassicConstants.REQUEST_USER_AGENT_MDC_KEY);
- MDC.remove(ClassicConstants.REQUEST_X_FORWARDED_FOR);
- }
+ }
- public void init(FilterConfig arg0) throws ServletException {
- // do nothing
- }
+ void clearMDC() {
+ MDC.remove(ClassicConstants.REQUEST_REMOTE_HOST_MDC_KEY);
+ MDC.remove(ClassicConstants.REQUEST_REQUEST_URI);
+ MDC.remove(ClassicConstants.REQUEST_QUERY_STRING);
+ // removing possibly inexistent item is OK
+ MDC.remove(ClassicConstants.REQUEST_REQUEST_URL);
+ MDC.remove(ClassicConstants.REQUEST_USER_AGENT_MDC_KEY);
+ MDC.remove(ClassicConstants.REQUEST_X_FORWARDED_FOR);
+ }
+
+ public void init(FilterConfig arg0) throws ServletException {
+ // do nothing
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultCssBuilder.java b/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultCssBuilder.java
index 4aaf75a..b230204 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultCssBuilder.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultCssBuilder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.classic.html;
+
import ch.qos.logback.core.CoreConstants;
import static ch.qos.logback.core.CoreConstants.LINE_SEPARATOR;
import ch.qos.logback.core.html.CssBuilder;
@@ -26,43 +27,49 @@ import ch.qos.logback.core.html.CssBuilder;
*/
public class DefaultCssBuilder implements CssBuilder {
- public void addCss(StringBuilder sbuf) {
- sbuf.append("<style type=\"text/css\">");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("table { margin-left: 2em; margin-right: 2em; border-left: 2px solid #AAA; }");
- sbuf.append(LINE_SEPARATOR);
+ public void addCss(StringBuilder sbuf) {
+ sbuf.append("<style type=\"text/css\">");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf
+ .append("table { margin-left: 2em; margin-right: 2em; border-left: 2px solid #AAA; }");
+ sbuf.append(LINE_SEPARATOR);
- sbuf.append("TR.even { background: #FFFFFF; }");
- sbuf.append(LINE_SEPARATOR);
+ sbuf.append("TR.even { background: #FFFFFF; }");
+ sbuf.append(LINE_SEPARATOR);
- sbuf.append("TR.odd { background: #EAEAEA; }");
- sbuf.append(LINE_SEPARATOR);
+ sbuf.append("TR.odd { background: #EAEAEA; }");
+ sbuf.append(LINE_SEPARATOR);
- sbuf.append("TR.warn TD.Level, TR.error TD.Level, TR.fatal TD.Level {font-weight: bold; color: #FF4040 }");
- sbuf.append(CoreConstants.LINE_SEPARATOR);
+ sbuf
+ .append("TR.warn TD.Level, TR.error TD.Level, TR.fatal TD.Level {font-weight: bold; color: #FF4040 }");
+ sbuf.append(CoreConstants.LINE_SEPARATOR);
- sbuf.append("TD { padding-right: 1ex; padding-left: 1ex; border-right: 2px solid #AAA; }");
- sbuf.append(LINE_SEPARATOR);
+ sbuf
+ .append("TD { padding-right: 1ex; padding-left: 1ex; border-right: 2px solid #AAA; }");
+ sbuf.append(LINE_SEPARATOR);
- sbuf.append("TD.Time, TD.Date { text-align: right; font-family: courier, monospace; font-size: smaller; }");
- sbuf.append(LINE_SEPARATOR);
+ sbuf
+ .append("TD.Time, TD.Date { text-align: right; font-family: courier, monospace; font-size: smaller; }");
+ sbuf.append(LINE_SEPARATOR);
- sbuf.append("TD.Thread { text-align: left; }");
- sbuf.append(LINE_SEPARATOR);
+ sbuf.append("TD.Thread { text-align: left; }");
+ sbuf.append(LINE_SEPARATOR);
- sbuf.append("TD.Level { text-align: right; }");
- sbuf.append(LINE_SEPARATOR);
+ sbuf.append("TD.Level { text-align: right; }");
+ sbuf.append(LINE_SEPARATOR);
- sbuf.append("TD.Logger { text-align: left; }");
- sbuf.append(LINE_SEPARATOR);
+ sbuf.append("TD.Logger { text-align: left; }");
+ sbuf.append(LINE_SEPARATOR);
- sbuf.append("TR.header { background: #596ED5; color: #FFF; font-weight: bold; font-size: larger; }");
- sbuf.append(CoreConstants.LINE_SEPARATOR);
+ sbuf
+ .append("TR.header { background: #596ED5; color: #FFF; font-weight: bold; font-size: larger; }");
+ sbuf.append(CoreConstants.LINE_SEPARATOR);
- sbuf.append("TD.Exception { background: #A2AEE8; font-family: courier, monospace;}");
- sbuf.append(LINE_SEPARATOR);
+ sbuf
+ .append("TD.Exception { background: #A2AEE8; font-family: courier, monospace;}");
+ sbuf.append(LINE_SEPARATOR);
- sbuf.append("</style>");
- sbuf.append(LINE_SEPARATOR);
- }
+ sbuf.append("</style>");
+ sbuf.append(LINE_SEPARATOR);
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultThrowableRenderer.java b/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultThrowableRenderer.java
index a556c32..1adf5f0 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultThrowableRenderer.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultThrowableRenderer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,46 +20,49 @@ import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.helpers.Transform;
import ch.qos.logback.core.html.IThrowableRenderer;
-public class DefaultThrowableRenderer implements IThrowableRenderer<ILoggingEvent> {
+public class DefaultThrowableRenderer implements
+ IThrowableRenderer<ILoggingEvent> {
- static final String TRACE_PREFIX = "<br /> ";
+ static final String TRACE_PREFIX = "<br /> ";
- public void render(StringBuilder sbuf, ILoggingEvent event) {
- IThrowableProxy tp = event.getThrowableProxy();
- sbuf.append("<tr><td class=\"Exception\" colspan=\"6\">");
- while (tp != null) {
- render(sbuf, tp);
- tp = tp.getCause();
- }
- sbuf.append("</td></tr>");
+ public void render(StringBuilder sbuf, ILoggingEvent event) {
+ IThrowableProxy tp = event.getThrowableProxy();
+ sbuf.append("<tr><td class=\"Exception\" colspan=\"6\">");
+ while (tp != null) {
+ render(sbuf, tp);
+ tp = tp.getCause();
}
+ sbuf.append("</td></tr>");
+ }
- void render(StringBuilder sbuf, IThrowableProxy tp) {
- printFirstLine(sbuf, tp);
-
- int commonFrames = tp.getCommonFrames();
- StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
-
- for (int i = 0; i < stepArray.length - commonFrames; i++) {
- StackTraceElementProxy step = stepArray[i];
- sbuf.append(TRACE_PREFIX);
- sbuf.append(Transform.escapeTags(step.toString()));
- sbuf.append(CoreConstants.LINE_SEPARATOR);
- }
-
- if (commonFrames > 0) {
- sbuf.append(TRACE_PREFIX);
- sbuf.append("\t... ").append(commonFrames).append(" common frames omitted").append(CoreConstants.LINE_SEPARATOR);
- }
+ void render(StringBuilder sbuf, IThrowableProxy tp) {
+ printFirstLine(sbuf, tp);
+
+ int commonFrames = tp.getCommonFrames();
+ StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
+
+ for (int i = 0; i < stepArray.length - commonFrames; i++) {
+ StackTraceElementProxy step = stepArray[i];
+ sbuf.append(TRACE_PREFIX);
+ sbuf.append(Transform.escapeTags(step.toString()));
+ sbuf.append(CoreConstants.LINE_SEPARATOR);
+ }
+
+ if (commonFrames > 0) {
+ sbuf.append(TRACE_PREFIX);
+ sbuf.append("\t... ").append(commonFrames).append(" common frames omitted")
+ .append(CoreConstants.LINE_SEPARATOR);
}
+ }
- public void printFirstLine(StringBuilder sb, IThrowableProxy tp) {
- int commonFrames = tp.getCommonFrames();
- if (commonFrames > 0) {
- sb.append("<br />").append(CoreConstants.CAUSED_BY);
- }
- sb.append(tp.getClassName()).append(": ").append(Transform.escapeTags(tp.getMessage()));
- sb.append(CoreConstants.LINE_SEPARATOR);
+ public void printFirstLine(StringBuilder sb, IThrowableProxy tp) {
+ int commonFrames = tp.getCommonFrames();
+ if (commonFrames > 0) {
+ sb.append("<br />").append(CoreConstants.CAUSED_BY);
}
+ sb.append(tp.getClassName()).append(": ").append(
+ Transform.escapeTags(tp.getMessage()));
+ sb.append(CoreConstants.LINE_SEPARATOR);
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/html/HTMLLayout.java b/logback-classic/src/main/java/ch/qos/logback/classic/html/HTMLLayout.java
index fa40a72..cbfdd74 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/html/HTMLLayout.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/html/HTMLLayout.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,7 +19,6 @@ import ch.qos.logback.classic.PatternLayout;
import ch.qos.logback.classic.pattern.MDCConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.html.DefaultCssBuilder;
-import ch.qos.logback.core.helpers.Transform;
import ch.qos.logback.core.html.HTMLLayoutBase;
import ch.qos.logback.core.html.IThrowableRenderer;
import ch.qos.logback.core.pattern.Converter;
@@ -39,104 +38,105 @@ import static ch.qos.logback.core.CoreConstants.LINE_SEPARATOR;
*/
public class HTMLLayout extends HTMLLayoutBase<ILoggingEvent> {
- /**
- * Default pattern string for log output.
- */
- static final String DEFAULT_CONVERSION_PATTERN = "%date%thread%level%logger%mdc%msg";
-
- IThrowableRenderer<ILoggingEvent> throwableRenderer;
-
- /**
- * Constructs a PatternLayout using the DEFAULT_LAYOUT_PATTERN.
- *
- * The default pattern just produces the application supplied message.
- */
- public HTMLLayout() {
- pattern = DEFAULT_CONVERSION_PATTERN;
- throwableRenderer = new DefaultThrowableRenderer();
- cssBuilder = new DefaultCssBuilder();
+ /**
+ * Default pattern string for log output.
+ */
+ static final String DEFAULT_CONVERSION_PATTERN = "%date%thread%level%logger%mdc%msg";
+
+ IThrowableRenderer<ILoggingEvent> throwableRenderer;
+
+ /**
+ * Constructs a PatternLayout using the DEFAULT_LAYOUT_PATTERN.
+ *
+ * The default pattern just produces the application supplied message.
+ */
+ public HTMLLayout() {
+ pattern = DEFAULT_CONVERSION_PATTERN;
+ throwableRenderer = new DefaultThrowableRenderer();
+ cssBuilder = new DefaultCssBuilder();
+ }
+
+ @Override
+ public void start() {
+ int errorCount = 0;
+ if (throwableRenderer == null) {
+ addError("ThrowableRender cannot be null.");
+ errorCount++;
}
-
- @Override
- public void start() {
- int errorCount = 0;
- if (throwableRenderer == null) {
- addError("ThrowableRender cannot be null.");
- errorCount++;
- }
- if (errorCount == 0) {
- super.start();
- }
+ if (errorCount == 0) {
+ super.start();
}
+ }
- protected Map<String, String> getDefaultConverterMap() {
- return PatternLayout.defaultConverterMap;
- }
+ protected Map<String, String> getDefaultConverterMap() {
+ return PatternLayout.defaultConverterMap;
+ }
- public String doLayout(ILoggingEvent event) {
- StringBuilder buf = new StringBuilder();
- startNewTableIfLimitReached(buf);
-
- boolean odd = true;
- if (((counter++) & 1) == 0) {
- odd = false;
- }
-
- String level = event.getLevel().toString().toLowerCase();
-
- buf.append(LINE_SEPARATOR);
- buf.append("<tr class=\"");
- buf.append(level);
- if (odd) {
- buf.append(" odd\">");
- } else {
- buf.append(" even\">");
- }
- buf.append(LINE_SEPARATOR);
-
- Converter<ILoggingEvent> c = head;
- while (c != null) {
- appendEventToBuffer(buf, c, event);
- c = c.getNext();
- }
- buf.append("</tr>");
- buf.append(LINE_SEPARATOR);
-
- if (event.getThrowableProxy() != null) {
- throwableRenderer.render(buf, event);
- }
- return buf.toString();
- }
+ public String doLayout(ILoggingEvent event) {
+ StringBuilder buf = new StringBuilder();
+ startNewTableIfLimitReached(buf);
- private void appendEventToBuffer(StringBuilder buf, Converter<ILoggingEvent> c, ILoggingEvent event) {
- buf.append("<td class=\"");
- buf.append(computeConverterName(c));
- buf.append("\">");
- buf.append(Transform.escapeTags(c.convert(event)));
- buf.append("</td>");
- buf.append(LINE_SEPARATOR);
+ boolean odd = true;
+ if (((counter++) & 1) == 0) {
+ odd = false;
}
- public IThrowableRenderer getThrowableRenderer() {
- return throwableRenderer;
+ String level = event.getLevel().toString().toLowerCase();
+
+ buf.append(LINE_SEPARATOR);
+ buf.append("<tr class=\"");
+ buf.append(level);
+ if (odd) {
+ buf.append(" odd\">");
+ } else {
+ buf.append(" even\">");
}
+ buf.append(LINE_SEPARATOR);
- public void setThrowableRenderer(IThrowableRenderer<ILoggingEvent> throwableRenderer) {
- this.throwableRenderer = throwableRenderer;
+ Converter<ILoggingEvent> c = head;
+ while (c != null) {
+ appendEventToBuffer(buf, c, event);
+ c = c.getNext();
}
+ buf.append("</tr>");
+ buf.append(LINE_SEPARATOR);
- @Override
- protected String computeConverterName(Converter c) {
- if (c instanceof MDCConverter) {
- MDCConverter mc = (MDCConverter) c;
- String key = mc.getFirstOption();
- if (key != null) {
- return key;
- } else {
- return "MDC";
- }
- } else {
- return super.computeConverterName(c);
- }
+ if (event.getThrowableProxy() != null) {
+ throwableRenderer.render(buf, event);
+ }
+ return buf.toString();
+ }
+
+ private void appendEventToBuffer(StringBuilder buf,
+ Converter<ILoggingEvent> c, ILoggingEvent event) {
+ buf.append("<td class=\"");
+ buf.append(computeConverterName(c));
+ buf.append("\">");
+ c.write(buf, event);
+ buf.append("</td>");
+ buf.append(LINE_SEPARATOR);
+ }
+
+ public IThrowableRenderer getThrowableRenderer() {
+ return throwableRenderer;
+ }
+
+ public void setThrowableRenderer(IThrowableRenderer<ILoggingEvent> throwableRenderer) {
+ this.throwableRenderer = throwableRenderer;
+ }
+
+ @Override
+ protected String computeConverterName(Converter c) {
+ if(c instanceof MDCConverter) {
+ MDCConverter mc = (MDCConverter) c;
+ String key = mc.getFirstOption();
+ if(key != null) {
+ return key;
+ } else {
+ return "MDC";
+ }
+ } else {
+ return super.computeConverterName(c);
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/html/UrlCssBuilder.java b/logback-classic/src/main/java/ch/qos/logback/classic/html/UrlCssBuilder.java
index 3f01f77..c20c0bb 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/html/UrlCssBuilder.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/html/UrlCssBuilder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,6 +15,7 @@ package ch.qos.logback.classic.html;
import ch.qos.logback.core.html.CssBuilder;
+
/**
* This class helps the HTMLLayout build the CSS link.
* It either provides the HTMLLayout with a default css file,
@@ -24,19 +25,19 @@ import ch.qos.logback.core.html.CssBuilder;
*/
public class UrlCssBuilder implements CssBuilder {
- String url = "http://logback.qos.ch/css/classic.css";
-
- public String getUrl() {
- return url;
- }
-
- public void setUrl(String url) {
- this.url = url;
- }
-
- public void addCss(StringBuilder sbuf) {
- sbuf.append("<link REL=StyleSheet HREF=\"");
- sbuf.append(url);
- sbuf.append("\" TITLE=\"Basic\" />");
- }
+ String url = "http://logback.qos.ch/css/classic.css";
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public void addCss(StringBuilder sbuf) {
+ sbuf.append("<link REL=StyleSheet HREF=\"");
+ sbuf.append(url);
+ sbuf.append("\" TITLE=\"Basic\" />");
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/jmx/JMXConfigurator.java b/logback-classic/src/main/java/ch/qos/logback/classic/jmx/JMXConfigurator.java
index a180261..137d721 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/jmx/JMXConfigurator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/jmx/JMXConfigurator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2016, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -51,243 +51,250 @@ import ch.qos.logback.core.util.StatusPrinter;
*
* Contributor: Sebastian Davids See http://bugzilla.qos.ch/show_bug.cgi?id=35
*/
-public class JMXConfigurator extends ContextAwareBase implements JMXConfiguratorMBean, LoggerContextListener {
-
- private static String EMPTY = "";
-
- LoggerContext loggerContext;
- MBeanServer mbs;
- ObjectName objectName;
- String objectNameAsString;
-
- // whether to output status events on the console when reloading the
- // configuration
- boolean debug = true;
-
- boolean started;
-
- public JMXConfigurator(LoggerContext loggerContext, MBeanServer mbs, ObjectName objectName) {
- started = true;
- this.context = loggerContext;
- this.loggerContext = loggerContext;
- this.mbs = mbs;
- this.objectName = objectName;
- this.objectNameAsString = objectName.toString();
- if (previouslyRegisteredListenerWithSameObjectName()) {
- addError("Previously registered JMXConfigurator named [" + objectNameAsString + "] in the logger context named [" + loggerContext.getName() + "]");
- } else {
- // register as a listener only if there are no homonyms
- loggerContext.addListener(this);
- }
+public class JMXConfigurator extends ContextAwareBase implements
+ JMXConfiguratorMBean, LoggerContextListener {
+
+ private static String EMPTY = "";
+
+ LoggerContext loggerContext;
+ MBeanServer mbs;
+ ObjectName objectName;
+ String objectNameAsString;
+
+ // whether to output status events on the console when reloading the
+ // configuration
+ boolean debug = true;
+
+ boolean started;
+
+ public JMXConfigurator(LoggerContext loggerContext, MBeanServer mbs,
+ ObjectName objectName) {
+ started = true;
+ this.context = loggerContext;
+ this.loggerContext = loggerContext;
+ this.mbs = mbs;
+ this.objectName = objectName;
+ this.objectNameAsString = objectName.toString();
+ if (previouslyRegisteredListenerWithSameObjectName()) {
+ addError("Previously registered JMXConfigurator named ["
+ + objectNameAsString + "] in the logger context named ["
+ + loggerContext.getName() + "]");
+ } else {
+ // register as a listener only if there are no homonyms
+ loggerContext.addListener(this);
}
-
- private boolean previouslyRegisteredListenerWithSameObjectName() {
- List<LoggerContextListener> lcll = loggerContext.getCopyOfListenerList();
- for (LoggerContextListener lcl : lcll) {
- if (lcl instanceof JMXConfigurator) {
- JMXConfigurator jmxConfigurator = (JMXConfigurator) lcl;
- if (objectName.equals(jmxConfigurator.objectName)) {
- return true;
- }
- }
+ }
+
+ private boolean previouslyRegisteredListenerWithSameObjectName() {
+ List<LoggerContextListener> lcll = loggerContext.getCopyOfListenerList();
+ for (LoggerContextListener lcl : lcll) {
+ if (lcl instanceof JMXConfigurator) {
+ JMXConfigurator jmxConfigurator = (JMXConfigurator) lcl;
+ if (objectName.equals(jmxConfigurator.objectName)) {
+ return true;
}
- return false;
+ }
}
-
- public void reloadDefaultConfiguration() throws JoranException {
- ContextInitializer ci = new ContextInitializer(loggerContext);
- URL url = ci.findURLOfDefaultConfigurationFile(true);
+ return false;
+ }
+
+ public void reloadDefaultConfiguration() throws JoranException {
+ ContextInitializer ci = new ContextInitializer(loggerContext);
+ URL url = ci.findURLOfDefaultConfigurationFile(true);
+ reloadByURL(url);
+ }
+
+ public void reloadByFileName(String fileName) throws JoranException,
+ FileNotFoundException {
+ File f = new File(fileName);
+ if (f.exists() && f.isFile()) {
+ URL url;
+ try {
+ url = f.toURI().toURL();
reloadByURL(url);
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(
+ "Unexpected MalformedURLException occured. See nexted cause.", e);
+ }
+
+ } else {
+ String errMsg = "Could not find [" + fileName + "]";
+ addInfo(errMsg);
+ throw new FileNotFoundException(errMsg);
}
-
- public void reloadByFileName(String fileName) throws JoranException, FileNotFoundException {
- File f = new File(fileName);
- if (f.exists() && f.isFile()) {
- URL url;
- try {
- url = f.toURI().toURL();
- reloadByURL(url);
- } catch (MalformedURLException e) {
- throw new RuntimeException("Unexpected MalformedURLException occured. See nexted cause.", e);
- }
-
- } else {
- String errMsg = "Could not find [" + fileName + "]";
- addInfo(errMsg);
- throw new FileNotFoundException(errMsg);
- }
+ }
+
+ void addStatusListener(StatusListener statusListener) {
+ StatusManager sm = loggerContext.getStatusManager();
+ sm.add(statusListener);
+ }
+
+ void removeStatusListener(StatusListener statusListener) {
+ StatusManager sm = loggerContext.getStatusManager();
+ sm.remove(statusListener);
+ }
+
+ public void reloadByURL(URL url) throws JoranException {
+ StatusListenerAsList statusListenerAsList = new StatusListenerAsList();
+
+ addStatusListener(statusListenerAsList);
+ addInfo("Resetting context: " + loggerContext.getName());
+ loggerContext.reset();
+ // after a reset the statusListenerAsList gets removed as a listener
+ addStatusListener(statusListenerAsList);
+
+ try {
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(loggerContext);
+ configurator.doConfigure(url);
+ addInfo("Context: " + loggerContext.getName() + " reloaded.");
+ } finally {
+ removeStatusListener(statusListenerAsList);
+ if (debug) {
+ StatusPrinter.print(statusListenerAsList.getStatusList());
+ }
}
+ }
- void addStatusListener(StatusListener statusListener) {
- StatusManager sm = loggerContext.getStatusManager();
- sm.add(statusListener);
+ public void setLoggerLevel(String loggerName, String levelStr) {
+ if (loggerName == null) {
+ return;
}
-
- void removeStatusListener(StatusListener statusListener) {
- StatusManager sm = loggerContext.getStatusManager();
- sm.remove(statusListener);
+ if (levelStr == null) {
+ return;
}
-
- public void reloadByURL(URL url) throws JoranException {
- StatusListenerAsList statusListenerAsList = new StatusListenerAsList();
-
- addStatusListener(statusListenerAsList);
- addInfo("Resetting context: " + loggerContext.getName());
- loggerContext.reset();
-
- // after a reset the statusListenerAsList gets removed as a listener
- addStatusListener(statusListenerAsList);
-
- try {
- if (url != null) {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(loggerContext);
- configurator.doConfigure(url);
- addInfo("Context: " + loggerContext.getName() + " reloaded.");
- }
- } finally {
- removeStatusListener(statusListenerAsList);
- if (debug) {
- StatusPrinter.print(statusListenerAsList.getStatusList());
- }
- }
+ loggerName = loggerName.trim();
+ levelStr = levelStr.trim();
+
+ addInfo("Trying to set level " + levelStr + " to logger " + loggerName);
+ LoggerContext lc = (LoggerContext) context;
+
+ Logger logger = lc.getLogger(loggerName);
+ if ("null".equalsIgnoreCase(levelStr)) {
+ logger.setLevel(null);
+ } else {
+ Level level = Level.toLevel(levelStr, null);
+ if (level != null) {
+ logger.setLevel(level);
+ }
}
+ }
- public void setLoggerLevel(String loggerName, String levelStr) {
- if (loggerName == null) {
- return;
- }
- if (levelStr == null) {
- return;
- }
- loggerName = loggerName.trim();
- levelStr = levelStr.trim();
-
- addInfo("Trying to set level " + levelStr + " to logger " + loggerName);
- LoggerContext lc = (LoggerContext) context;
-
- Logger logger = lc.getLogger(loggerName);
- if ("null".equalsIgnoreCase(levelStr)) {
- logger.setLevel(null);
- } else {
- Level level = Level.toLevel(levelStr, null);
- if (level != null) {
- logger.setLevel(level);
- }
- }
+ public String getLoggerLevel(String loggerName) {
+ if (loggerName == null) {
+ return EMPTY;
}
- public String getLoggerLevel(String loggerName) {
- if (loggerName == null) {
- return EMPTY;
- }
+ loggerName = loggerName.trim();
- loggerName = loggerName.trim();
-
- LoggerContext lc = (LoggerContext) context;
- Logger logger = lc.exists(loggerName);
- if (logger != null && logger.getLevel() != null) {
- return logger.getLevel().toString();
- } else {
- return EMPTY;
- }
+ LoggerContext lc = (LoggerContext) context;
+ Logger logger = lc.exists(loggerName);
+ if (logger != null && logger.getLevel() != null) {
+ return logger.getLevel().toString();
+ } else {
+ return EMPTY;
}
+ }
- public String getLoggerEffectiveLevel(String loggerName) {
- if (loggerName == null) {
- return EMPTY;
- }
-
- loggerName = loggerName.trim();
-
- LoggerContext lc = (LoggerContext) context;
- Logger logger = lc.exists(loggerName);
- if (logger != null) {
- return logger.getEffectiveLevel().toString();
- } else {
- return EMPTY;
- }
+ public String getLoggerEffectiveLevel(String loggerName) {
+ if (loggerName == null) {
+ return EMPTY;
}
- public List<String> getLoggerList() {
- LoggerContext lc = (LoggerContext) context;
- List<String> strList = new ArrayList<String>();
- Iterator<Logger> it = lc.getLoggerList().iterator();
- while (it.hasNext()) {
- Logger log = it.next();
- strList.add(log.getName());
- }
- return strList;
- }
+ loggerName = loggerName.trim();
- public List<String> getStatuses() {
- List<String> list = new ArrayList<String>();
- Iterator<Status> it = context.getStatusManager().getCopyOfStatusList().iterator();
- while (it.hasNext()) {
- list.add(it.next().toString());
- }
- return list;
+ LoggerContext lc = (LoggerContext) context;
+ Logger logger = lc.exists(loggerName);
+ if (logger != null) {
+ return logger.getEffectiveLevel().toString();
+ } else {
+ return EMPTY;
}
-
- /**
- * When the associated LoggerContext is stopped, this configurator must be
- * unregistered
- */
- public void onStop(LoggerContext context) {
- if (!started) {
- addInfo("onStop() method called on a stopped JMXActivator [" + objectNameAsString + "]");
- return;
- }
- if (mbs.isRegistered(objectName)) {
- try {
- addInfo("Unregistering mbean [" + objectNameAsString + "]");
- mbs.unregisterMBean(objectName);
- } catch (InstanceNotFoundException e) {
- // this is theoretically impossible
- addError("Unable to find a verifiably registered mbean [" + objectNameAsString + "]", e);
- } catch (MBeanRegistrationException e) {
- addError("Failed to unregister [" + objectNameAsString + "]", e);
- }
- } else {
- addInfo("mbean [" + objectNameAsString + "] was not in the mbean registry. This is OK.");
- }
- stop();
+ }
+
+ public List<String> getLoggerList() {
+ LoggerContext lc = (LoggerContext) context;
+ List<String> strList = new ArrayList<String>();
+ Iterator<Logger> it = lc.getLoggerList().iterator();
+ while (it.hasNext()) {
+ Logger log = it.next();
+ strList.add(log.getName());
}
-
- public void onLevelChange(Logger logger, Level level) {
- // nothing to do
+ return strList;
+ }
+
+ public List<String> getStatuses() {
+ List<String> list = new ArrayList<String>();
+ Iterator<Status> it = context.getStatusManager().getCopyOfStatusList()
+ .iterator();
+ while (it.hasNext()) {
+ list.add(it.next().toString());
}
-
- public void onReset(LoggerContext context) {
- addInfo("onReset() method called JMXActivator [" + objectNameAsString + "]");
+ return list;
+ }
+
+ /**
+ * When the associated LoggerContext is stopped, this configurator must be
+ * unregistered
+ */
+ public void onStop(LoggerContext context) {
+ if (!started) {
+ addInfo("onStop() method called on a stopped JMXActivator ["
+ + objectNameAsString + "]");
+ return;
}
-
- /**
- * JMXConfigurator should not be removed subsequent to a LoggerContext reset.
- *
- * @return
- */
- public boolean isResetResistant() {
- return true;
- }
-
- private void clearFields() {
- mbs = null;
- objectName = null;
- loggerContext = null;
- }
-
- private void stop() {
- started = false;
- clearFields();
- }
-
- public void onStart(LoggerContext context) {
- // nop
- }
-
- @Override
- public String toString() {
- return this.getClass().getName() + "(" + context.getName() + ")";
+ if (mbs.isRegistered(objectName)) {
+ try {
+ addInfo("Unregistering mbean [" + objectNameAsString + "]");
+ mbs.unregisterMBean(objectName);
+ } catch (InstanceNotFoundException e) {
+ // this is theoretically impossible
+ addError("Unable to find a verifiably registered mbean ["
+ + objectNameAsString + "]", e);
+ } catch (MBeanRegistrationException e) {
+ addError("Failed to unregister [" + objectNameAsString + "]", e);
+ }
+ } else {
+ addInfo("mbean [" + objectNameAsString
+ + "] was not in the mbean registry. This is OK.");
}
+ stop();
+ }
+
+ public void onLevelChange(Logger logger, Level level) {
+ // nothing to do
+ }
+
+ public void onReset(LoggerContext context) {
+ addInfo("onReset() method called JMXActivator [" + objectNameAsString + "]");
+ }
+
+ /**
+ * JMXConfigurator should not be removed subsequent to a LoggerContext reset.
+ *
+ * @return
+ */
+ public boolean isResetResistant() {
+ return true;
+ }
+
+ private void clearFields() {
+ mbs = null;
+ objectName = null;
+ loggerContext = null;
+ }
+
+ private void stop() {
+ started = false;
+ clearFields();
+ }
+
+ public void onStart(LoggerContext context) {
+ // nop
+ }
+
+ @Override
+ public String toString() {
+ return this.getClass().getName() + "(" + context.getName() + ")";
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/jmx/JMXConfiguratorMBean.java b/logback-classic/src/main/java/ch/qos/logback/classic/jmx/JMXConfiguratorMBean.java
index fe6b26f..fec9e5b 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/jmx/JMXConfiguratorMBean.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/jmx/JMXConfiguratorMBean.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,20 +20,20 @@ import java.util.List;
import ch.qos.logback.core.joran.spi.JoranException;
public interface JMXConfiguratorMBean {
-
- void reloadDefaultConfiguration() throws JoranException;
-
- void reloadByFileName(String fileName) throws JoranException, FileNotFoundException;
-
- void reloadByURL(URL url) throws JoranException;
-
- void setLoggerLevel(String loggerName, String levelStr);
-
- String getLoggerLevel(String loggerName);
-
- String getLoggerEffectiveLevel(String loggerName);
-
- List<String> getLoggerList();
-
- List<String> getStatuses();
+
+ void reloadDefaultConfiguration() throws JoranException;
+
+ void reloadByFileName(String fileName) throws JoranException, FileNotFoundException;
+
+ void reloadByURL(URL url) throws JoranException;
+
+ void setLoggerLevel(String loggerName, String levelStr);
+
+ String getLoggerLevel(String loggerName);
+
+ String getLoggerEffectiveLevel(String loggerName);
+
+ List<String> getLoggerList();
+
+ List<String> getStatuses();
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/jmx/MBeanUtil.java b/logback-classic/src/main/java/ch/qos/logback/classic/jmx/MBeanUtil.java
index cb06e8e..7b698fa 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/jmx/MBeanUtil.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/jmx/MBeanUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,58 +25,66 @@ import ch.qos.logback.core.status.StatusUtil;
public class MBeanUtil {
- static final String DOMAIN = "ch.qos.logback.classic";
+ static final String DOMAIN = "ch.qos.logback.classic";
- static public String getObjectNameFor(String contextName, Class type) {
- return DOMAIN + ":Name=" + contextName + ",Type=" + type.getName();
- }
+ static public String getObjectNameFor(String contextName, Class type) {
+ return DOMAIN + ":Name=" + contextName + ",Type="
+ + type.getName();
+ }
- public static ObjectName string2ObjectName(Context context, Object caller, String objectNameAsStr) {
- String msg = "Failed to convert [" + objectNameAsStr + "] to ObjectName";
+ public static ObjectName string2ObjectName(Context context, Object caller,
+ String objectNameAsStr) {
+ String msg = "Failed to convert [" + objectNameAsStr + "] to ObjectName";
- StatusUtil statusUtil = new StatusUtil(context);
- try {
- return new ObjectName(objectNameAsStr);
- } catch (MalformedObjectNameException e) {
- statusUtil.addError(caller, msg, e);
- return null;
- } catch (NullPointerException e) {
- statusUtil.addError(caller, msg, e);
- return null;
- }
+ StatusUtil statusUtil = new StatusUtil(context);
+ try {
+ return new ObjectName(objectNameAsStr);
+ } catch (MalformedObjectNameException e) {
+ statusUtil.addError(caller, msg, e);
+ return null;
+ } catch (NullPointerException e) {
+ statusUtil.addError(caller, msg, e);
+ return null;
}
+ }
- public static boolean isRegistered(MBeanServer mbs, ObjectName objectName) {
- return mbs.isRegistered(objectName);
- }
+ public static boolean isRegistered(MBeanServer mbs, ObjectName objectName) {
+ return mbs.isRegistered(objectName);
+ }
- public static void createAndRegisterJMXConfigurator(MBeanServer mbs, LoggerContext loggerContext, JMXConfigurator jmxConfigurator, ObjectName objectName,
- Object caller) {
- try {
- mbs.registerMBean(jmxConfigurator, objectName);
- } catch (Exception e) {
- StatusUtil statusUtil = new StatusUtil(loggerContext);
- statusUtil.addError(caller, "Failed to create mbean", e);
- }
+ public static void createAndRegisterJMXConfigurator(
+ MBeanServer mbs, LoggerContext loggerContext,
+ JMXConfigurator jmxConfigurator, ObjectName objectName, Object caller) {
+ try {
+ mbs.registerMBean(jmxConfigurator, objectName);
+ } catch (Exception e) {
+ StatusUtil statusUtil = new StatusUtil(loggerContext);
+ statusUtil.addError(caller, "Failed to create mbean", e);
}
+ }
- public static void unregister(LoggerContext loggerContext, MBeanServer mbs, ObjectName objectName, Object caller) {
+ public static void unregister(LoggerContext loggerContext, MBeanServer mbs,
+ ObjectName objectName, Object caller) {
- StatusUtil statusUtil = new StatusUtil(loggerContext);
- if (mbs.isRegistered(objectName)) {
- try {
- statusUtil.addInfo(caller, "Unregistering mbean [" + objectName + "]");
- mbs.unregisterMBean(objectName);
- } catch (InstanceNotFoundException e) {
- // this is theoretically impossible
- statusUtil.addError(caller, "Failed to unregister mbean" + objectName, e);
- } catch (MBeanRegistrationException e) {
- // this is theoretically impossible
- statusUtil.addError(caller, "Failed to unregister mbean" + objectName, e);
- }
- } else {
- statusUtil.addInfo(caller, "mbean [" + objectName + "] does not seem to be registered");
- }
+ StatusUtil statusUtil = new StatusUtil(loggerContext);
+ if (mbs.isRegistered(objectName)) {
+ try {
+ statusUtil.addInfo(caller, "Unregistering mbean ["
+ + objectName + "]");
+ mbs.unregisterMBean(objectName);
+ } catch (InstanceNotFoundException e) {
+ // this is theoretically impossible
+ statusUtil.addError(caller, "Failed to unregister mbean"
+ + objectName, e);
+ } catch (MBeanRegistrationException e) {
+ // this is theoretically impossible
+ statusUtil.addError(caller, "Failed to unregister mbean"
+ + objectName, e);
+ }
+ } else {
+ statusUtil.addInfo(caller, "mbean [" + objectName
+ + "] does not seem to be registered");
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java
index 93e92f4..45391eb 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,7 +15,6 @@ package ch.qos.logback.classic.joran;
import ch.qos.logback.classic.joran.action.*;
import ch.qos.logback.classic.sift.SiftAction;
-import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.PlatformInfo;
import ch.qos.logback.classic.util.DefaultNestedComponentRules;
import ch.qos.logback.core.joran.JoranConfiguratorBase;
@@ -34,55 +33,64 @@ import ch.qos.logback.core.joran.spi.RuleStore;
*
* @author Ceki Gülcü
*/
-public class JoranConfigurator extends JoranConfiguratorBase<ILoggingEvent> {
+public class JoranConfigurator extends JoranConfiguratorBase {
- @Override
- public void addInstanceRules(RuleStore rs) {
- // parent rules already added
- super.addInstanceRules(rs);
+ @Override
+ public void addInstanceRules(RuleStore rs) {
+ // parent rules already added
+ super.addInstanceRules(rs);
- rs.addRule(new ElementSelector("configuration"), new ConfigurationAction());
+ rs.addRule(new ElementSelector("configuration"), new ConfigurationAction());
- rs.addRule(new ElementSelector("configuration/contextName"), new ContextNameAction());
- rs.addRule(new ElementSelector("configuration/contextListener"), new LoggerContextListenerAction());
- rs.addRule(new ElementSelector("configuration/insertFromJNDI"), new InsertFromJNDIAction());
- rs.addRule(new ElementSelector("configuration/evaluator"), new EvaluatorAction());
+ rs.addRule(new ElementSelector("configuration/contextName"),
+ new ContextNameAction());
+ rs.addRule(new ElementSelector("configuration/contextListener"),
+ new LoggerContextListenerAction());
+ rs.addRule(new ElementSelector("configuration/insertFromJNDI"),
+ new InsertFromJNDIAction());
+ rs.addRule(new ElementSelector("configuration/evaluator"), new EvaluatorAction());
- rs.addRule(new ElementSelector("configuration/appender/sift"), new SiftAction());
- rs.addRule(new ElementSelector("configuration/appender/sift/*"), new NOPAction());
+ rs.addRule(new ElementSelector("configuration/appender/sift"), new SiftAction());
+ rs.addRule(new ElementSelector("configuration/appender/sift/*"), new NOPAction());
- rs.addRule(new ElementSelector("configuration/logger"), new LoggerAction());
- rs.addRule(new ElementSelector("configuration/logger/level"), new LevelAction());
-
- rs.addRule(new ElementSelector("configuration/root"), new RootLoggerAction());
- rs.addRule(new ElementSelector("configuration/root/level"), new LevelAction());
- rs.addRule(new ElementSelector("configuration/logger/appender-ref"), new AppenderRefAction<ILoggingEvent>());
- rs.addRule(new ElementSelector("configuration/root/appender-ref"), new AppenderRefAction<ILoggingEvent>());
-
- // add if-then-else support
- rs.addRule(new ElementSelector("*/if"), new IfAction());
- rs.addRule(new ElementSelector("*/if/then"), new ThenAction());
- rs.addRule(new ElementSelector("*/if/then/*"), new NOPAction());
- rs.addRule(new ElementSelector("*/if/else"), new ElseAction());
- rs.addRule(new ElementSelector("*/if/else/*"), new NOPAction());
-
- // add jmxConfigurator only if we have JMX available.
- // If running under JDK 1.4 (retrotranslateed logback) then we
- // might not have JMX.
- if (PlatformInfo.hasJMXObjectName()) {
- rs.addRule(new ElementSelector("configuration/jmxConfigurator"), new JMXConfiguratorAction());
- }
- rs.addRule(new ElementSelector("configuration/include"), new IncludeAction());
-
- rs.addRule(new ElementSelector("configuration/consolePlugin"), new ConsolePluginAction());
-
- rs.addRule(new ElementSelector("configuration/receiver"), new ReceiverAction());
+ rs.addRule(new ElementSelector("configuration/logger"), new LoggerAction());
+ rs.addRule(new ElementSelector("configuration/logger/level"), new LevelAction());
+ rs.addRule(new ElementSelector("configuration/root"), new RootLoggerAction());
+ rs.addRule(new ElementSelector("configuration/root/level"), new LevelAction());
+ rs.addRule(new ElementSelector("configuration/logger/appender-ref"),
+ new AppenderRefAction());
+ rs.addRule(new ElementSelector("configuration/root/appender-ref"),
+ new AppenderRefAction());
+
+ // add if-then-else support
+ rs.addRule(new ElementSelector("*/if"), new IfAction());
+ rs.addRule(new ElementSelector("*/if/then"), new ThenAction());
+ rs.addRule(new ElementSelector("*/if/then/*"), new NOPAction());
+ rs.addRule(new ElementSelector("*/if/else"), new ElseAction());
+ rs.addRule(new ElementSelector("*/if/else/*"), new NOPAction());
+
+ // add jmxConfigurator only if we have JMX available.
+ // If running under JDK 1.4 (retrotranslateed logback) then we
+ // might not have JMX.
+ if (PlatformInfo.hasJMXObjectName()) {
+ rs.addRule(new ElementSelector("configuration/jmxConfigurator"),
+ new JMXConfiguratorAction());
}
+ rs.addRule(new ElementSelector("configuration/include"), new IncludeAction());
- @Override
- protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
- DefaultNestedComponentRules.addDefaultNestedComponentRegistryRules(registry);
- }
+ rs.addRule(new ElementSelector("configuration/consolePlugin"),
+ new ConsolePluginAction());
+
+ rs.addRule(new ElementSelector("configuration/receiver"),
+ new ReceiverAction());
+
+ }
+
+ @Override
+ protected void addDefaultNestedComponentRegistryRules(
+ DefaultNestedComponentRegistry registry) {
+ DefaultNestedComponentRules.addDefaultNestedComponentRegistryRules(registry);
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/ReconfigureOnChangeTask.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/ReconfigureOnChangeTask.java
deleted file mode 100644
index 818b29e..0000000
--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/ReconfigureOnChangeTask.java
+++ /dev/null
@@ -1,168 +0,0 @@
-package ch.qos.logback.classic.joran;
-
-import java.io.File;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.gaffer.GafferUtil;
-import ch.qos.logback.classic.util.EnvUtil;
-import ch.qos.logback.core.CoreConstants;
-import ch.qos.logback.core.joran.event.SaxEvent;
-import ch.qos.logback.core.joran.spi.ConfigurationWatchList;
-import ch.qos.logback.core.joran.spi.JoranException;
-import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
-import ch.qos.logback.core.spi.ContextAwareBase;
-import ch.qos.logback.core.status.StatusUtil;
-
-public class ReconfigureOnChangeTask extends ContextAwareBase implements Runnable {
-
- public static final String DETECTED_CHANGE_IN_CONFIGURATION_FILES = "Detected change in configuration files.";
- static final String RE_REGISTERING_PREVIOUS_SAFE_CONFIGURATION = "Re-registering previous fallback configuration once more as a fallback configuration point";
- static final String FALLING_BACK_TO_SAFE_CONFIGURATION = "Given previous errors, falling back to previously registered safe configuration.";
-
-
-
- long birthdate = System.currentTimeMillis();
- List<ReconfigureOnChangeTaskListener> listeners;
-
-
- void addListener(ReconfigureOnChangeTaskListener listener) {
- if(listeners==null)
- listeners = new ArrayList<ReconfigureOnChangeTaskListener>();
- listeners.add(listener);
- }
-
- @Override
- public void run() {
- fireEnteredRunMethod();
-
- ConfigurationWatchList configurationWatchList = ConfigurationWatchListUtil.getConfigurationWatchList(context);
- if (configurationWatchList == null) {
- addWarn("Empty ConfigurationWatchList in context");
- return;
- }
-
- List<File> filesToWatch = configurationWatchList.getCopyOfFileWatchList();
- if (filesToWatch == null || filesToWatch.isEmpty()) {
- addInfo("Empty watch file list. Disabling ");
- return;
- }
-
- if (!configurationWatchList.changeDetected()) {
- return;
- }
-
- fireChangeDetected();
- URL mainConfigurationURL = configurationWatchList.getMainURL();
-
- addInfo(DETECTED_CHANGE_IN_CONFIGURATION_FILES);
- addInfo(CoreConstants.RESET_MSG_PREFIX + "named [" + context.getName() + "]");
-
- LoggerContext lc = (LoggerContext) context;
- if (mainConfigurationURL.toString().endsWith("xml")) {
- performXMLConfiguration(lc, mainConfigurationURL);
- } else if (mainConfigurationURL.toString().endsWith("groovy")) {
- if (EnvUtil.isGroovyAvailable()) {
- lc.reset();
- // avoid directly referring to GafferConfigurator so as to avoid
- // loading groovy.lang.GroovyObject . See also http://jira.qos.ch/browse/LBCLASSIC-214
- GafferUtil.runGafferConfiguratorOn(lc, this, mainConfigurationURL);
- } else {
- addError("Groovy classes are not available on the class path. ABORTING INITIALIZATION.");
- }
- }
- fireDoneReconfiguring();
- }
-
- private void fireEnteredRunMethod() {
- if(listeners == null)
- return;
-
- for(ReconfigureOnChangeTaskListener listener: listeners)
- listener.enteredRunMethod();
- }
-
- private void fireChangeDetected() {
- if(listeners == null)
- return;
-
- for(ReconfigureOnChangeTaskListener listener: listeners)
- listener.changeDetected();
- }
-
-
- private void fireDoneReconfiguring() {
- if(listeners == null)
- return;
-
- for(ReconfigureOnChangeTaskListener listener: listeners)
- listener.doneReconfiguring();
- }
-
- private void performXMLConfiguration(LoggerContext lc, URL mainConfigurationURL) {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(context);
- StatusUtil statusUtil = new StatusUtil(context);
- List<SaxEvent> eventList = jc.recallSafeConfiguration();
-
- URL mainURL = ConfigurationWatchListUtil.getMainWatchURL(context);
- lc.reset();
- long threshold = System.currentTimeMillis();
- try {
- jc.doConfigure(mainConfigurationURL);
- if (statusUtil.hasXMLParsingErrors(threshold)) {
- fallbackConfiguration(lc, eventList, mainURL);
- }
- } catch (JoranException e) {
- fallbackConfiguration(lc, eventList, mainURL);
- }
- }
-
- private List<SaxEvent> removeIncludeEvents(List<SaxEvent> unsanitizedEventList) {
- List<SaxEvent> sanitizedEvents = new ArrayList<SaxEvent>();
- if (unsanitizedEventList == null)
- return sanitizedEvents;
-
- for (SaxEvent e : unsanitizedEventList) {
- if (!"include".equalsIgnoreCase(e.getLocalName()))
- sanitizedEvents.add(e);
-
- }
- return sanitizedEvents;
- }
-
- private void fallbackConfiguration(LoggerContext lc, List<SaxEvent> eventList, URL mainURL) {
- // failsafe events are used only in case of errors. Therefore, we must *not*
- // invoke file inclusion since the included files may be the cause of the error.
-
- List<SaxEvent> failsafeEvents = removeIncludeEvents(eventList);
- JoranConfigurator joranConfigurator = new JoranConfigurator();
- joranConfigurator.setContext(context);
- ConfigurationWatchList oldCWL = ConfigurationWatchListUtil.getConfigurationWatchList(context);
- ConfigurationWatchList newCWL = oldCWL.buildClone();
-
- if (failsafeEvents == null || failsafeEvents.isEmpty()) {
- addWarn("No previous configuration to fall back on.");
- } else {
- addWarn(FALLING_BACK_TO_SAFE_CONFIGURATION);
- try {
- lc.reset();
- ConfigurationWatchListUtil.registerConfigurationWatchList(context, newCWL);
- joranConfigurator.doConfigure(failsafeEvents);
- addInfo(RE_REGISTERING_PREVIOUS_SAFE_CONFIGURATION);
- joranConfigurator.registerSafeConfiguration(eventList);
-
- addInfo("after registerSafeConfiguration: " + eventList);
- } catch (JoranException e) {
- addError("Unexpected exception thrown by a configuration considered safe.", e);
- }
- }
- }
-
- @Override
- public String toString() {
- return "ReconfigureOnChangeTask(born:" + birthdate + ")";
- }
-}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/ReconfigureOnChangeTaskListener.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/ReconfigureOnChangeTaskListener.java
deleted file mode 100644
index 4521006..0000000
--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/ReconfigureOnChangeTaskListener.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package ch.qos.logback.classic.joran;
-
-public class ReconfigureOnChangeTaskListener {
- void enteredRunMethod() {
- }
-
- void changeDetected() {
- }
-
- void doneReconfiguring() {
- }
-}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ConfigurationAction.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ConfigurationAction.java
index b831376..bac01f8 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ConfigurationAction.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ConfigurationAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,133 +13,97 @@
*/
package ch.qos.logback.classic.joran.action;
-import java.net.URL;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-
+import ch.qos.logback.classic.util.EnvUtil;
+import ch.qos.logback.core.status.OnConsoleStatusListener;
import org.xml.sax.Attributes;
import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.ReconfigureOnChangeTask;
-import ch.qos.logback.classic.util.EnvUtil;
-import ch.qos.logback.core.CoreConstants;
+import ch.qos.logback.classic.turbo.ReconfigureOnChangeFilter;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.InterpretationContext;
-import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
-import ch.qos.logback.core.status.OnConsoleStatusListener;
import ch.qos.logback.core.util.ContextUtil;
import ch.qos.logback.core.util.Duration;
import ch.qos.logback.core.util.OptionHelper;
-import ch.qos.logback.core.util.StatusListenerConfigHelper;
public class ConfigurationAction extends Action {
- static final String INTERNAL_DEBUG_ATTR = "debug";
- static final String PACKAGING_DATA_ATTR = "packagingData";
- static final String SCAN_ATTR = "scan";
- static final String SCAN_PERIOD_ATTR = "scanPeriod";
- static final String DEBUG_SYSTEM_PROPERTY_KEY = "logback.debug";
-
- long threshold = 0;
-
- public void begin(InterpretationContext ic, String name, Attributes attributes) {
- threshold = System.currentTimeMillis();
-
- // See LOGBACK-527 (the system property is looked up first. Thus, it overrides
- // the equivalent property in the config file. This reversal of scope priority is justified
- // by the use case: the admin trying to chase rogue config file
- String debugAttrib = getSystemProperty(DEBUG_SYSTEM_PROPERTY_KEY);
- if (debugAttrib == null) {
- debugAttrib = ic.subst(attributes.getValue(INTERNAL_DEBUG_ATTR));
- }
-
- if (OptionHelper.isEmpty(debugAttrib) || debugAttrib.equalsIgnoreCase("false") || debugAttrib.equalsIgnoreCase("null")) {
- addInfo(INTERNAL_DEBUG_ATTR + " attribute not set");
- } else {
- StatusListenerConfigHelper.addOnConsoleListenerInstance(context, new OnConsoleStatusListener());
- }
-
- processScanAttrib(ic, attributes);
-
- ContextUtil contextUtil = new ContextUtil(context);
- contextUtil.addHostNameAsProperty();
-
- LoggerContext lc = (LoggerContext) context;
- boolean packagingData = OptionHelper.toBoolean(ic.subst(attributes.getValue(PACKAGING_DATA_ATTR)), LoggerContext.DEFAULT_PACKAGING_DATA);
- lc.setPackagingDataEnabled(packagingData);
-
- if (EnvUtil.isGroovyAvailable()) {
- contextUtil.addGroovyPackages(lc.getFrameworkPackages());
- }
-
- // the context is turbo filter attachable, so it is pushed on top of the
- // stack
- ic.pushObject(getContext());
+ static final String INTERNAL_DEBUG_ATTR = "debug";
+ static final String SCAN_ATTR = "scan";
+ static final String SCAN_PERIOD_ATTR = "scanPeriod";
+ static final String DEBUG_SYSTEM_PROPERTY_KEY = "logback.debug";
+
+ long threshold = 0;
+
+ public void begin(InterpretationContext ic, String name, Attributes attributes) {
+ threshold = System.currentTimeMillis();
+
+ // See LOGBACK-527 (the system property is looked up first. Thus, it overrides
+ // the equivalent property in the config file. This reversal of scope priority is justified
+ // by the use case: the admin trying to chase rogue config file
+ String debugAttrib = getSystemProperty(DEBUG_SYSTEM_PROPERTY_KEY);
+ if (debugAttrib == null) {
+ debugAttrib = ic.subst(attributes.getValue(INTERNAL_DEBUG_ATTR));
}
- String getSystemProperty(String name) {
- /*
- * LOGBACK-743: accessing a system property in the presence of a SecurityManager (e.g. applet sandbox) can
- * result in a SecurityException.
- */
- try {
- return System.getProperty(name);
- } catch (SecurityException ex) {
- return null;
- }
+ if (OptionHelper.isEmpty(debugAttrib) || debugAttrib.equalsIgnoreCase("false")
+ || debugAttrib.equalsIgnoreCase("null")) {
+ addInfo(INTERNAL_DEBUG_ATTR + " attribute not set");
+ } else {
+ OnConsoleStatusListener.addNewInstanceToContext(context);
}
- void processScanAttrib(InterpretationContext ic, Attributes attributes) {
- String scanAttrib = ic.subst(attributes.getValue(SCAN_ATTR));
- if (!OptionHelper.isEmpty(scanAttrib) && !"false".equalsIgnoreCase(scanAttrib)) {
-
- ScheduledExecutorService scheduledExecutorService = context.getScheduledExecutorService();
- URL mainURL = ConfigurationWatchListUtil.getMainWatchURL(context);
- if (mainURL == null) {
- addWarn("Due to missing top level configuration file, reconfiguration on change (configuration file scanning) cannot be done.");
- return;
- }
- ReconfigureOnChangeTask rocTask = new ReconfigureOnChangeTask();
- rocTask.setContext(context);
-
- context.putObject(CoreConstants.RECONFIGURE_ON_CHANGE_TASK, rocTask);
+ processScanAttrib(ic, attributes);
- String scanPeriodAttrib = ic.subst(attributes.getValue(SCAN_PERIOD_ATTR));
- Duration duration = getDuration(scanAttrib, scanPeriodAttrib);
+ ContextUtil contextUtil = new ContextUtil(context);
+ contextUtil.addHostNameAsProperty();
- if (duration == null) {
- return;
- }
-
- addInfo("Will scan for changes in [" + mainURL + "] ");
- // Given that included files are encountered at a later phase, the complete list of files
- // to scan can only be determined when the configuration is loaded in full.
- // However, scan can be active if mainURL is set. Otherwise, when changes are detected
- // the top level config file cannot be accessed.
- addInfo("Setting ReconfigureOnChangeTask scanning period to " + duration);
-
- ScheduledFuture<?> scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(rocTask, duration.getMilliseconds(), duration.getMilliseconds(),
- TimeUnit.MILLISECONDS);
- context.addScheduledFuture(scheduledFuture);
- }
+ if(EnvUtil.isGroovyAvailable()) {
+ LoggerContext lc = (LoggerContext) context;
+ contextUtil.addGroovyPackages(lc.getFrameworkPackages());
}
- private Duration getDuration(String scanAttrib, String scanPeriodAttrib) {
- Duration duration = null;
-
- if (!OptionHelper.isEmpty(scanPeriodAttrib)) {
- try {
- duration = Duration.valueOf(scanPeriodAttrib);
-
- } catch (NumberFormatException nfe) {
- addError("Error while converting [" + scanAttrib + "] to long", nfe);
- }
+ // the context is turbo filter attachable, so it is pushed on top of the
+ // stack
+ ic.pushObject(getContext());
+ }
+
+ String getSystemProperty(String name) {
+ /*
+ * LOGBACK-743: accessing a system property in the presence of a
+ * SecurityManager (e.g. applet sandbox) can result in a SecurityException.
+ */
+ try {
+ return System.getProperty(name);
+ } catch (SecurityException ex) {
+ return null;
+ }
+ }
+
+ void processScanAttrib(InterpretationContext ic, Attributes attributes) {
+ String scanAttrib = ic.subst(attributes.getValue(SCAN_ATTR));
+ if (!OptionHelper.isEmpty(scanAttrib)
+ && !"false".equalsIgnoreCase(scanAttrib)) {
+ ReconfigureOnChangeFilter rocf = new ReconfigureOnChangeFilter();
+ rocf.setContext(context);
+ String scanPeriodAttrib = ic.subst(attributes.getValue(SCAN_PERIOD_ATTR));
+ if (!OptionHelper.isEmpty(scanPeriodAttrib)) {
+ try {
+ Duration duration = Duration.valueOf(scanPeriodAttrib);
+ rocf.setRefreshPeriod(duration.getMilliseconds());
+ addInfo("Setting ReconfigureOnChangeFilter scanning period to "
+ + duration);
+ } catch (NumberFormatException nfe) {
+ addError("Error while converting [" + scanAttrib + "] to long", nfe);
}
- return duration;
+ }
+ rocf.start();
+ LoggerContext lc = (LoggerContext) context;
+ addInfo("Adding ReconfigureOnChangeFilter as a turbo filter");
+ lc.addTurboFilter(rocf);
}
+ }
- public void end(InterpretationContext ec, String name) {
- addInfo("End of configuration.");
- ec.popObject();
- }
+ public void end(InterpretationContext ec, String name) {
+ addInfo("End of configuration.");
+ ec.popObject();
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ConsolePluginAction.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ConsolePluginAction.java
index 096551f..5e4bec0 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ConsolePluginAction.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ConsolePluginAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,39 +24,41 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
public class ConsolePluginAction extends Action {
- private static final String PORT_ATTR = "port";
- private static final Integer DEFAULT_PORT = 4321;
-
- @Override
- public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
- String portStr = attributes.getValue(PORT_ATTR);
- Integer port = null;
-
- if (portStr == null) {
- port = DEFAULT_PORT;
- } else {
- try {
- port = Integer.valueOf(portStr);
- } catch (NumberFormatException ex) {
- addError("Port " + portStr + " in ConsolePlugin config is not a correct number");
- }
- }
-
- LoggerContext lc = (LoggerContext) ec.getContext();
- SocketAppender appender = new SocketAppender();
- appender.setContext(lc);
- appender.setIncludeCallerData(true);
- appender.setRemoteHost("localhost");
- appender.setPort(port.intValue());
- appender.start();
- Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- root.addAppender(appender);
-
- addInfo("Sending LoggingEvents to the plugin using port " + port);
+ private static final String PORT_ATTR = "port";
+ private static final Integer DEFAULT_PORT = 4321;
+
+ @Override
+ public void begin(InterpretationContext ec, String name, Attributes attributes)
+ throws ActionException {
+ String portStr = attributes.getValue(PORT_ATTR);
+ Integer port = null;
+
+ if (portStr == null) {
+ port = DEFAULT_PORT;
+ } else {
+ try {
+ port = Integer.valueOf(portStr);
+ } catch (NumberFormatException ex) {
+ addError("Port " + portStr
+ + " in ConsolePlugin config is not a correct number");
+ }
}
- @Override
- public void end(InterpretationContext ec, String name) throws ActionException {
+ LoggerContext lc = (LoggerContext)ec.getContext();
+ SocketAppender appender = new SocketAppender();
+ appender.setContext(lc);
+ appender.setIncludeCallerData(true);
+ appender.setRemoteHost("localhost");
+ appender.setPort(port.intValue());
+ appender.start();
+ Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+ root.addAppender(appender);
+
+ addInfo("Sending LoggingEvents to the plugin using port " + port);
+ }
- }
+ @Override
+ public void end(InterpretationContext ec, String name) throws ActionException {
+
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ContextNameAction.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ContextNameAction.java
index d5d82ed..63d85a1 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ContextNameAction.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ContextNameAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,20 +20,21 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
public class ContextNameAction extends Action {
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- }
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ }
- public void body(InterpretationContext ec, String body) {
+ public void body(InterpretationContext ec, String body) {
- String finalBody = ec.subst(body);
- addInfo("Setting logger context name as [" + finalBody + "]");
- try {
- context.setName(finalBody);
- } catch (IllegalStateException e) {
- addError("Failed to rename context [" + context.getName() + "] as [" + finalBody + "]", e);
- }
+ String finalBody = ec.subst(body);
+ addInfo("Setting logger context name as [" + finalBody + "]");
+ try {
+ context.setName(finalBody);
+ } catch (IllegalStateException e) {
+ addError("Failed to rename context [" + context.getName() + "] as ["
+ + finalBody + "]", e);
}
+ }
- public void end(InterpretationContext ec, String name) {
- }
+ public void end(InterpretationContext ec, String name) {
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/EvaluatorAction.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/EvaluatorAction.java
index 6d03b27..df9bb30 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/EvaluatorAction.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/EvaluatorAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,7 +17,7 @@ import ch.qos.logback.classic.boolex.JaninoEventEvaluator;
import ch.qos.logback.core.joran.action.AbstractEventEvaluatorAction;
public class EvaluatorAction extends AbstractEventEvaluatorAction {
- protected String defaultClassName() {
- return JaninoEventEvaluator.class.getName();
- }
+ protected String defaultClassName() {
+ return JaninoEventEvaluator.class.getName();
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/InsertFromJNDIAction.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/InsertFromJNDIAction.java
index 3e5a8be..3e86101 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/InsertFromJNDIAction.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/InsertFromJNDIAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -33,51 +33,52 @@ import ch.qos.logback.core.util.OptionHelper;
*/
public class InsertFromJNDIAction extends Action {
- public static final String ENV_ENTRY_NAME_ATTR = "env-entry-name";
- public static final String AS_ATTR = "as";
+ public static final String ENV_ENTRY_NAME_ATTR="env-entry-name";
+ public static final String AS_ATTR="as";
+
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ int errorCount = 0;
+ String envEntryName = ec.subst(attributes.getValue(ENV_ENTRY_NAME_ATTR));
+ String asKey = ec.subst(attributes.getValue(AS_ATTR));
- int errorCount = 0;
- String envEntryName = ec.subst(attributes.getValue(ENV_ENTRY_NAME_ATTR));
- String asKey = ec.subst(attributes.getValue(AS_ATTR));
-
- String scopeStr = attributes.getValue(SCOPE_ATTRIBUTE);
- Scope scope = ActionUtil.stringToScope(scopeStr);
-
- String envEntryValue;
-
- if (OptionHelper.isEmpty(envEntryName)) {
- String lineColStr = getLineColStr(ec);
- addError("[" + ENV_ENTRY_NAME_ATTR + "] missing, around " + lineColStr);
- errorCount++;
- }
-
- if (OptionHelper.isEmpty(asKey)) {
- String lineColStr = getLineColStr(ec);
- addError("[" + AS_ATTR + "] missing, around " + lineColStr);
- errorCount++;
- }
-
- if (errorCount != 0) {
- return;
- }
-
- try {
- Context ctx = JNDIUtil.getInitialContext();
- envEntryValue = JNDIUtil.lookup(ctx, envEntryName);
- if (OptionHelper.isEmpty(envEntryValue)) {
- addError("[" + envEntryName + "] has null or empty value");
- } else {
- addInfo("Setting variable [" + asKey + "] to [" + envEntryValue + "] in [" + scope + "] scope");
- ActionUtil.setProperty(ec, asKey, envEntryValue, scope);
- }
- } catch (NamingException e) {
- addError("Failed to lookup JNDI env-entry [" + envEntryName + "]");
- }
+ String scopeStr = attributes.getValue(SCOPE_ATTRIBUTE);
+ Scope scope = ActionUtil.stringToScope(scopeStr);
+ String envEntryValue;
+
+ if(OptionHelper.isEmpty(envEntryName)) {
+ String lineColStr = getLineColStr(ec);
+ addError("["+ENV_ENTRY_NAME_ATTR+"] missing, around "+lineColStr);
+ errorCount++;
}
-
- public void end(InterpretationContext ec, String name) {
+
+ if(OptionHelper.isEmpty(asKey)) {
+ String lineColStr = getLineColStr(ec);
+ addError("["+AS_ATTR+"] missing, around "+lineColStr);
+ errorCount++;
+ }
+
+ if(errorCount != 0) {
+ return;
}
+
+ try {
+ Context ctx = JNDIUtil.getInitialContext();
+ envEntryValue = JNDIUtil.lookup(ctx, envEntryName);
+ if(OptionHelper.isEmpty(envEntryValue)) {
+ addError("["+envEntryName+"] has null or empty value");
+ } else {
+ addInfo("Setting variable ["+asKey+"] to ["+envEntryValue+"] in ["+scope+"] scope");
+ ActionUtil.setProperty(ec, asKey, envEntryValue, scope);
+ }
+ } catch (NamingException e) {
+ addError("Failed to lookup JNDI env-entry ["+envEntryName+"]");
+ }
+
+
+ }
+
+ public void end(InterpretationContext ec, String name) {
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/JMXConfiguratorAction.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/JMXConfiguratorAction.java
index 0c62964..121e97c 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/JMXConfiguratorAction.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/JMXConfiguratorAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,53 +30,60 @@ import ch.qos.logback.core.util.OptionHelper;
public class JMXConfiguratorAction extends Action {
- static final String OBJECT_NAME_ATTRIBUTE_NAME = "objectName";
- static final String CONTEXT_NAME_ATTRIBUTE_NAME = "contextName";
- static final char JMX_NAME_SEPARATOR = ',';
+ static final String OBJECT_NAME_ATTRIBUTE_NAME = "objectName";
+ static final String CONTEXT_NAME_ATTRIBUTE_NAME = "contextName";
+ static final char JMX_NAME_SEPARATOR = ',';
+
+ @Override
+ public void begin(InterpretationContext ec, String name, Attributes attributes)
+ throws ActionException {
+ addInfo("begin");
- @Override
- public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
- addInfo("begin");
- String contextName = context.getName();
- String contextNameAttributeVal = attributes.getValue(CONTEXT_NAME_ATTRIBUTE_NAME);
- if (!OptionHelper.isEmpty(contextNameAttributeVal)) {
- contextName = contextNameAttributeVal;
- }
-
- String objectNameAsStr;
- String objectNameAttributeVal = attributes.getValue(OBJECT_NAME_ATTRIBUTE_NAME);
- if (OptionHelper.isEmpty(objectNameAttributeVal)) {
- objectNameAsStr = MBeanUtil.getObjectNameFor(contextName, JMXConfigurator.class);
- } else {
- objectNameAsStr = objectNameAttributeVal;
- }
-
- ObjectName objectName = MBeanUtil.string2ObjectName(context, this, objectNameAsStr);
- if (objectName == null) {
- addError("Failed construct ObjectName for [" + objectNameAsStr + "]");
- return;
- }
+ String contextName = context.getName();
+ String contextNameAttributeVal = attributes
+ .getValue(CONTEXT_NAME_ATTRIBUTE_NAME);
+ if(!OptionHelper.isEmpty(contextNameAttributeVal)) {
+ contextName = contextNameAttributeVal;
+ }
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- if (!MBeanUtil.isRegistered(mbs, objectName)) {
- // register only of the named JMXConfigurator has not been previously
- // registered. Unregistering an MBean within invocation of itself
- // caused jconsole to throw an NPE. (This occurs when the reload* method
- // unregisters the
- JMXConfigurator jmxConfigurator = new JMXConfigurator((LoggerContext) context, mbs, objectName);
- try {
- mbs.registerMBean(jmxConfigurator, objectName);
- } catch (Exception e) {
- addError("Failed to create mbean", e);
- }
- }
+ String objectNameAsStr;
+ String objectNameAttributeVal = attributes
+ .getValue(OBJECT_NAME_ATTRIBUTE_NAME);
+ if (OptionHelper.isEmpty(objectNameAttributeVal)) {
+ objectNameAsStr = MBeanUtil.getObjectNameFor(contextName,
+ JMXConfigurator.class);
+ } else {
+ objectNameAsStr = objectNameAttributeVal;
+ }
+ ObjectName objectName = MBeanUtil.string2ObjectName(context, this,
+ objectNameAsStr);
+ if (objectName == null) {
+ addError("Failed construct ObjectName for ["+objectNameAsStr+"]");
+ return;
+ }
+
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ if(!MBeanUtil.isRegistered(mbs, objectName)) {
+ // register only of the named JMXConfigurator has not been previously
+ // registered. Unregistering an MBean within invocation of itself
+ // caused jconsole to throw an NPE. (This occurs when the reload* method
+ // unregisters the
+ JMXConfigurator jmxConfigurator = new JMXConfigurator((LoggerContext) context, mbs,
+ objectName);
+ try {
+ mbs.registerMBean(jmxConfigurator, objectName);
+ } catch (Exception e) {
+ addError("Failed to create mbean", e);
+ }
}
- @Override
- public void end(InterpretationContext ec, String name) throws ActionException {
+ }
- }
+ @Override
+ public void end(InterpretationContext ec, String name) throws ActionException {
+
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LevelAction.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LevelAction.java
index b6d3234..30a43b2 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LevelAction.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LevelAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,37 +31,37 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
*/
public class LevelAction extends Action {
- boolean inError = false;
+ boolean inError = false;
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- Object o = ec.peekObject();
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ Object o = ec.peekObject();
- if (!(o instanceof Logger)) {
- inError = true;
- addError("For element <level>, could not find a logger at the top of execution stack.");
- return;
- }
-
- Logger l = (Logger) o;
+ if (!(o instanceof Logger)) {
+ inError = true;
+ addError("For element <level>, could not find a logger at the top of execution stack.");
+ return;
+ }
- String loggerName = l.getName();
+ Logger l = (Logger) o;
- String levelStr = ec.subst(attributes.getValue(ActionConst.VALUE_ATTR));
- // addInfo("Encapsulating logger name is [" + loggerName
- // + "], level value is [" + levelStr + "].");
+ String loggerName = l.getName();
- if (ActionConst.INHERITED.equalsIgnoreCase(levelStr) || ActionConst.NULL.equalsIgnoreCase(levelStr)) {
- l.setLevel(null);
- } else {
- l.setLevel(Level.toLevel(levelStr, Level.DEBUG));
- }
+ String levelStr = ec.subst(attributes.getValue(ActionConst.VALUE_ATTR));
+ //addInfo("Encapsulating logger name is [" + loggerName
+ // + "], level value is [" + levelStr + "].");
- addInfo(loggerName + " level set to " + l.getLevel());
+ if (ActionConst.INHERITED.equalsIgnoreCase(levelStr) || ActionConst.NULL.equalsIgnoreCase(levelStr)) {
+ l.setLevel(null);
+ } else {
+ l.setLevel(Level.toLevel(levelStr, Level.DEBUG));
}
- public void finish(InterpretationContext ec) {
- }
+ addInfo(loggerName + " level set to " + l.getLevel());
+ }
- public void end(InterpretationContext ec, String e) {
- }
+ public void finish(InterpretationContext ec) {
+ }
+
+ public void end(InterpretationContext ec, String e) {
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LoggerAction.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LoggerAction.java
index c455ad9..6e08b21 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LoggerAction.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LoggerAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,65 +29,67 @@ import ch.qos.logback.core.util.OptionHelper;
* @author Ceki Gulcu
*/
public class LoggerAction extends Action {
- public static final String LEVEL_ATTRIBUTE = "level";
+ public static final String LEVEL_ATTRIBUTE = "level";
- boolean inError = false;
- Logger logger;
+ boolean inError = false;
+ Logger logger;
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ // Let us forget about previous errors (in this object)
+ inError = false;
+ logger = null;
+
+ LoggerContext loggerContext = (LoggerContext) this.context;
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- // Let us forget about previous errors (in this object)
- inError = false;
- logger = null;
+ String loggerName = ec.subst(attributes.getValue(NAME_ATTRIBUTE));
- LoggerContext loggerContext = (LoggerContext) this.context;
-
- String loggerName = ec.subst(attributes.getValue(NAME_ATTRIBUTE));
-
- if (OptionHelper.isEmpty(loggerName)) {
- inError = true;
- String aroundLine = getLineColStr(ec);
- String errorMsg = "No 'name' attribute in element " + name + ", around " + aroundLine;
- addError(errorMsg);
- return;
- }
-
- logger = loggerContext.getLogger(loggerName);
-
- String levelStr = ec.subst(attributes.getValue(LEVEL_ATTRIBUTE));
+ if (OptionHelper.isEmpty(loggerName)) {
+ inError = true;
+ String aroundLine = getLineColStr(ec);
+ String errorMsg = "No 'name' attribute in element " + name + ", around " +aroundLine;
+ addError(errorMsg);
+ return;
+ }
- if (!OptionHelper.isEmpty(levelStr)) {
- if (ActionConst.INHERITED.equalsIgnoreCase(levelStr) || ActionConst.NULL.equalsIgnoreCase(levelStr)) {
- addInfo("Setting level of logger [" + loggerName + "] to null, i.e. INHERITED");
- logger.setLevel(null);
- } else {
- Level level = Level.toLevel(levelStr);
- addInfo("Setting level of logger [" + loggerName + "] to " + level);
- logger.setLevel(level);
- }
- }
+ logger = loggerContext.getLogger(loggerName);
- String additivityStr = ec.subst(attributes.getValue(ActionConst.ADDITIVITY_ATTRIBUTE));
- if (!OptionHelper.isEmpty(additivityStr)) {
- boolean additive = OptionHelper.toBoolean(additivityStr, true);
- addInfo("Setting additivity of logger [" + loggerName + "] to " + additive);
- logger.setAdditive(additive);
- }
- ec.pushObject(logger);
+ String levelStr = ec.subst(attributes.getValue(LEVEL_ATTRIBUTE));
+
+ if (!OptionHelper.isEmpty(levelStr)) {
+ if (ActionConst.INHERITED.equalsIgnoreCase(levelStr)
+ || ActionConst.NULL.equalsIgnoreCase(levelStr)) {
+ addInfo("Setting level of logger [" + loggerName
+ + "] to null, i.e. INHERITED");
+ logger.setLevel(null);
+ } else {
+ Level level = Level.toLevel(levelStr);
+ addInfo("Setting level of logger [" + loggerName + "] to " + level);
+ logger.setLevel(level);
+ }
}
- public void end(InterpretationContext ec, String e) {
- if (inError) {
- return;
- }
- Object o = ec.peekObject();
- if (o != logger) {
- addWarn("The object on the top the of the stack is not " + logger + " pushed earlier");
- addWarn("It is: " + o);
- } else {
- ec.popObject();
- }
+ String additivityStr = ec.subst(attributes.getValue(ActionConst.ADDITIVITY_ATTRIBUTE));
+ if (!OptionHelper.isEmpty(additivityStr)) {
+ boolean additive = OptionHelper.toBoolean(additivityStr, true);
+ addInfo("Setting additivity of logger [" + loggerName + "] to "
+ + additive);
+ logger.setAdditive(additive);
}
+ ec.pushObject(logger);
+ }
- public void finish(InterpretationContext ec) {
+ public void end(InterpretationContext ec, String e) {
+ if (inError) {
+ return;
+ }
+ Object o = ec.peekObject();
+ if (o != logger) {
+ addWarn("The object on the top the of the stack is not "+logger+" pushed earlier");
+ addWarn("It is: " + o);
+ } else {
+ ec.popObject();
}
+ }
+
+ public void finish(InterpretationContext ec) {
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LoggerContextListenerAction.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LoggerContextListenerAction.java
index 37d14ef..a070eb4 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LoggerContextListenerAction.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LoggerContextListenerAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,54 +25,58 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.util.OptionHelper;
public class LoggerContextListenerAction extends Action {
- boolean inError = false;
- LoggerContextListener lcl;
+ boolean inError = false;
+ LoggerContextListener lcl;
- @Override
- public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
+ @Override
+ public void begin(InterpretationContext ec, String name, Attributes attributes)
+ throws ActionException {
- inError = false;
+ inError = false;
- String className = attributes.getValue(CLASS_ATTRIBUTE);
- if (OptionHelper.isEmpty(className)) {
- addError("Mandatory \"" + CLASS_ATTRIBUTE + "\" attribute not set for <loggerContextListener> element");
- inError = true;
- return;
- }
+ String className = attributes.getValue(CLASS_ATTRIBUTE);
+ if (OptionHelper.isEmpty(className)) {
+ addError("Mandatory \"" + CLASS_ATTRIBUTE
+ + "\" attribute not set for <loggerContextListener> element");
+ inError = true;
+ return;
+ }
- try {
- lcl = (LoggerContextListener) OptionHelper.instantiateByClassName(className, LoggerContextListener.class, context);
+ try {
+ lcl = (LoggerContextListener) OptionHelper.instantiateByClassName(
+ className, LoggerContextListener.class, context);
- if (lcl instanceof ContextAware) {
- ((ContextAware) lcl).setContext(context);
- }
+ if(lcl instanceof ContextAware) {
+ ((ContextAware) lcl).setContext(context);
+ }
- ec.pushObject(lcl);
- addInfo("Adding LoggerContextListener of type [" + className + "] to the object stack");
+ ec.pushObject(lcl);
+ addInfo("Adding LoggerContextListener of type [" + className
+ + "] to the object stack");
- } catch (Exception oops) {
- inError = true;
- addError("Could not create LoggerContextListener of type " + className + "].", oops);
- }
+ } catch (Exception oops) {
+ inError = true;
+ addError("Could not create LoggerContextListener of type " + className + "].", oops);
}
+ }
- @Override
- public void end(InterpretationContext ec, String name) throws ActionException {
- if (inError) {
- return;
- }
- Object o = ec.peekObject();
+ @Override
+ public void end(InterpretationContext ec, String name) throws ActionException {
+ if (inError) {
+ return;
+ }
+ Object o = ec.peekObject();
- if (o != lcl) {
- addWarn("The object on the top the of the stack is not the LoggerContextListener pushed earlier.");
- } else {
- if (lcl instanceof LifeCycle) {
- ((LifeCycle) lcl).start();
- addInfo("Starting LoggerContextListener");
- }
- ((LoggerContext) context).addListener(lcl);
- ec.popObject();
- }
+ if (o != lcl) {
+ addWarn("The object on the top the of the stack is not the LoggerContextListener pushed earlier.");
+ } else {
+ if (lcl instanceof LifeCycle) {
+ ((LifeCycle) lcl).start();
+ addInfo("Starting LoggerContextListener");
+ }
+ ((LoggerContext) context).addListener(lcl);
+ ec.popObject();
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ReceiverAction.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ReceiverAction.java
index e14c328..8b1b809 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ReceiverAction.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/ReceiverAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,48 +29,53 @@ import ch.qos.logback.core.util.OptionHelper;
*/
public class ReceiverAction extends Action {
- private ReceiverBase receiver;
- private boolean inError;
-
- @Override
- public void begin(InterpretationContext ic, String name, Attributes attributes) throws ActionException {
-
- String className = attributes.getValue(CLASS_ATTRIBUTE);
- if (OptionHelper.isEmpty(className)) {
- addError("Missing class name for receiver. Near [" + name + "] line " + getLineNumber(ic));
- inError = true;
- return;
- }
-
- try {
- addInfo("About to instantiate receiver of type [" + className + "]");
-
- receiver = (ReceiverBase) OptionHelper.instantiateByClassName(className, ReceiverBase.class, context);
- receiver.setContext(context);
-
- ic.pushObject(receiver);
- } catch (Exception ex) {
- inError = true;
- addError("Could not create a receiver of type [" + className + "].", ex);
- throw new ActionException(ex);
- }
+ private ReceiverBase receiver;
+ private boolean inError;
+
+ @Override
+ public void begin(InterpretationContext ic, String name,
+ Attributes attributes) throws ActionException {
+
+ String className = attributes.getValue(CLASS_ATTRIBUTE);
+ if (OptionHelper.isEmpty(className)) {
+ addError("Missing class name for receiver. Near [" + name
+ + "] line " + getLineNumber(ic));
+ inError = true;
+ return;
}
- @Override
- public void end(InterpretationContext ic, String name) throws ActionException {
-
- if (inError)
- return;
+ try {
+ addInfo("About to instantiate receiver of type [" + className + "]");
- ic.getContext().register(receiver);
- receiver.start();
+ receiver = (ReceiverBase) OptionHelper.instantiateByClassName(
+ className, ReceiverBase.class, context);
+ receiver.setContext(context);
+
+ ic.pushObject(receiver);
+ }
+ catch (Exception ex) {
+ inError = true;
+ addError("Could not create a receiver of type [" + className + "].", ex);
+ throw new ActionException(ex);
+ }
+ }
- Object o = ic.peekObject();
- if (o != receiver) {
- addWarn("The object at the of the stack is not the remote " + "pushed earlier.");
- } else {
- ic.popObject();
- }
+ @Override
+ public void end(InterpretationContext ic, String name)
+ throws ActionException {
+
+ if (inError) return;
+
+ ic.getContext().register(receiver);
+ receiver.start();
+
+ Object o = ic.peekObject();
+ if (o != receiver) {
+ addWarn("The object at the of the stack is not the remote " +
+ "pushed earlier.");
+ } else {
+ ic.popObject();
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/RootLoggerAction.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/RootLoggerAction.java
index 04f3a06..eaabecf 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/RootLoggerAction.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/RootLoggerAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,38 +24,38 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.util.OptionHelper;
public class RootLoggerAction extends Action {
+
+ Logger root;
+ boolean inError = false;
- Logger root;
- boolean inError = false;
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ inError = false;
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- inError = false;
+ LoggerContext loggerContext = (LoggerContext) this.context;
+ root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
- LoggerContext loggerContext = (LoggerContext) this.context;
- root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
-
- String levelStr = ec.subst(attributes.getValue(ActionConst.LEVEL_ATTRIBUTE));
- if (!OptionHelper.isEmpty(levelStr)) {
- Level level = Level.toLevel(levelStr);
- addInfo("Setting level of ROOT logger to " + level);
- root.setLevel(level);
- }
- ec.pushObject(root);
+ String levelStr = ec.subst(attributes.getValue(ActionConst.LEVEL_ATTRIBUTE));
+ if (!OptionHelper.isEmpty(levelStr)) {
+ Level level = Level.toLevel(levelStr);
+ addInfo("Setting level of ROOT logger to " + level);
+ root.setLevel(level);
}
+ ec.pushObject(root);
+ }
- public void end(InterpretationContext ec, String name) {
- if (inError) {
- return;
- }
- Object o = ec.peekObject();
- if (o != root) {
- addWarn("The object on the top the of the stack is not the root logger");
- addWarn("It is: " + o);
- } else {
- ec.popObject();
- }
+ public void end(InterpretationContext ec, String name) {
+ if (inError) {
+ return;
}
-
- public void finish(InterpretationContext ec) {
+ Object o = ec.peekObject();
+ if (o != root) {
+ addWarn("The object on the top the of the stack is not the root logger");
+ addWarn("It is: " + o);
+ } else {
+ ec.popObject();
}
+ }
+
+ public void finish(InterpretationContext ec) {
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/jul/JULHelper.java b/logback-classic/src/main/java/ch/qos/logback/classic/jul/JULHelper.java
index 1b9d923..9c9c7b1 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/jul/JULHelper.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/jul/JULHelper.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,56 +18,59 @@ import ch.qos.logback.classic.Logger;
public class JULHelper {
- static public final boolean isRegularNonRootLogger(java.util.logging.Logger julLogger) {
- if (julLogger == null)
- return false;
- return !julLogger.getName().equals("");
- }
- static public final boolean isRoot(java.util.logging.Logger julLogger) {
- if (julLogger == null)
- return false;
- return julLogger.getName().equals("");
- }
+ static public final boolean isRegularNonRootLogger(java.util.logging.Logger julLogger) {
+ if (julLogger == null)
+ return false;
+ return !julLogger.getName().equals("");
+ }
- static public java.util.logging.Level asJULLevel(Level lbLevel) {
- if (lbLevel == null)
- throw new IllegalArgumentException("Unexpected level [null]");
+ static public final boolean isRoot(java.util.logging.Logger julLogger) {
+ if (julLogger == null)
+ return false;
+ return julLogger.getName().equals("");
+ }
- switch (lbLevel.levelInt) {
- case Level.ALL_INT:
- return java.util.logging.Level.ALL;
- case Level.TRACE_INT:
- return java.util.logging.Level.FINEST;
- case Level.DEBUG_INT:
- return java.util.logging.Level.FINE;
- case Level.INFO_INT:
- return java.util.logging.Level.INFO;
- case Level.WARN_INT:
- return java.util.logging.Level.WARNING;
- case Level.ERROR_INT:
- return java.util.logging.Level.SEVERE;
- case Level.OFF_INT:
- return java.util.logging.Level.OFF;
- default:
- throw new IllegalArgumentException("Unexpected level [" + lbLevel + "]");
- }
- }
+ static public java.util.logging.Level asJULLevel(Level lbLevel) {
+ if (lbLevel == null)
+ throw new IllegalArgumentException("Unexpected level [null]");
- static public String asJULLoggerName(String loggerName) {
- if (Logger.ROOT_LOGGER_NAME.equals(loggerName))
- return "";
- else
- return loggerName;
+ switch (lbLevel.levelInt) {
+ case Level.ALL_INT:
+ return java.util.logging.Level.ALL;
+ case Level.TRACE_INT:
+ return java.util.logging.Level.FINEST;
+ case Level.DEBUG_INT:
+ return java.util.logging.Level.FINE;
+ case Level.INFO_INT:
+ return java.util.logging.Level.INFO;
+ case Level.WARN_INT:
+ return java.util.logging.Level.WARNING;
+ case Level.ERROR_INT:
+ return java.util.logging.Level.SEVERE;
+ case Level.OFF_INT:
+ return java.util.logging.Level.OFF;
+ default:
+ throw new IllegalArgumentException("Unexpected level [" + lbLevel + "]");
}
+ }
- static public java.util.logging.Logger asJULLogger(String loggerName) {
- String julLoggerName = asJULLoggerName(loggerName);
- return java.util.logging.Logger.getLogger(julLoggerName);
- }
+ static public String asJULLoggerName(String loggerName) {
+ if (Logger.ROOT_LOGGER_NAME.equals(loggerName))
+ return "";
+ else
+ return loggerName;
+ }
- static public java.util.logging.Logger asJULLogger(Logger logger) {
- return asJULLogger(logger.getName());
- }
+ static public java.util.logging.Logger asJULLogger(String loggerName) {
+ String julLoggerName = asJULLoggerName(loggerName);
+ return java.util.logging.Logger.getLogger(julLoggerName);
+ }
+
+ static public java.util.logging.Logger asJULLogger(Logger logger) {
+ return asJULLogger(logger.getName());
+ }
}
+
+
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/jul/LevelChangePropagator.java b/logback-classic/src/main/java/ch/qos/logback/classic/jul/LevelChangePropagator.java
index 746aab7..d37d727 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/jul/LevelChangePropagator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/jul/LevelChangePropagator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,84 +26,85 @@ import java.util.List;
import java.util.Set;
import java.util.logging.LogManager;
+
/**
* Propagate level changes made to a logback logger into the equivalent logger in j.u.l.
*/
public class LevelChangePropagator extends ContextAwareBase implements LoggerContextListener, LifeCycle {
- private Set<java.util.logging.Logger> julLoggerSet = new HashSet<java.util.logging.Logger>();
- boolean isStarted = false;
- boolean resetJUL = false;
-
- public void setResetJUL(boolean resetJUL) {
- this.resetJUL = resetJUL;
- }
-
- public boolean isResetResistant() {
- return false;
- }
-
- public void onStart(LoggerContext context) {
+ private Set julLoggerSet = new HashSet();
+ boolean isStarted = false;
+ boolean resetJUL = false;
+
+ public void setResetJUL(boolean resetJUL) {
+ this.resetJUL = resetJUL;
+ }
+
+ public boolean isResetResistant() {
+ return false;
+ }
+
+ public void onStart(LoggerContext context) {
+ }
+
+ public void onReset(LoggerContext context) {
+ }
+
+ public void onStop(LoggerContext context) {
+ }
+
+ public void onLevelChange(Logger logger, Level level) {
+ propagate(logger, level);
+ }
+
+ private void propagate(Logger logger, Level level) {
+ addInfo("Propagating " + level + " level on " + logger + " onto the JUL framework");
+ java.util.logging.Logger julLogger = JULHelper.asJULLogger(logger);
+ // prevent garbage collection of jul loggers whose level we set
+ // see also http://jira.qos.ch/browse/LBCLASSIC-256
+ julLoggerSet.add(julLogger);
+ java.util.logging.Level julLevel = JULHelper.asJULLevel(level);
+ julLogger.setLevel(julLevel);
+ }
+
+ public void resetJULLevels() {
+ LogManager lm = LogManager.getLogManager();
+
+ Enumeration e = lm.getLoggerNames();
+ while (e.hasMoreElements()) {
+ String loggerName = (String) e.nextElement();
+ java.util.logging.Logger julLogger = lm.getLogger(loggerName);
+ if (JULHelper.isRegularNonRootLogger(julLogger) && julLogger.getLevel() != null) {
+ addInfo("Setting level of jul logger [" + loggerName + "] to null");
+ julLogger.setLevel(null);
+ }
}
-
- public void onReset(LoggerContext context) {
+ }
+
+ private void propagateExistingLoggerLevels() {
+ LoggerContext loggerContext = (LoggerContext) context;
+ List<Logger> loggerList = loggerContext.getLoggerList();
+ for (Logger l : loggerList) {
+ if (l.getLevel() != null) {
+ propagate(l, l.getLevel());
+ }
}
+ }
- public void onStop(LoggerContext context) {
+ public void start() {
+ if (resetJUL) {
+ resetJULLevels();
}
+ propagateExistingLoggerLevels();
- public void onLevelChange(Logger logger, Level level) {
- propagate(logger, level);
- }
+ isStarted = true;
+ }
- private void propagate(Logger logger, Level level) {
- addInfo("Propagating " + level + " level on " + logger + " onto the JUL framework");
- java.util.logging.Logger julLogger = JULHelper.asJULLogger(logger);
- // prevent garbage collection of jul loggers whose level we set
- // see also http://jira.qos.ch/browse/LBCLASSIC-256
- julLoggerSet.add(julLogger);
- java.util.logging.Level julLevel = JULHelper.asJULLevel(level);
- julLogger.setLevel(julLevel);
- }
+ public void stop() {
+ isStarted = false;
+ }
- public void resetJULLevels() {
- LogManager lm = LogManager.getLogManager();
-
- Enumeration<String> e = lm.getLoggerNames();
- while (e.hasMoreElements()) {
- String loggerName = e.nextElement();
- java.util.logging.Logger julLogger = lm.getLogger(loggerName);
- if (JULHelper.isRegularNonRootLogger(julLogger) && julLogger.getLevel() != null) {
- addInfo("Setting level of jul logger [" + loggerName + "] to null");
- julLogger.setLevel(null);
- }
- }
- }
-
- private void propagateExistingLoggerLevels() {
- LoggerContext loggerContext = (LoggerContext) context;
- List<Logger> loggerList = loggerContext.getLoggerList();
- for (Logger l : loggerList) {
- if (l.getLevel() != null) {
- propagate(l, l.getLevel());
- }
- }
- }
-
- public void start() {
- if (resetJUL) {
- resetJULLevels();
- }
- propagateExistingLoggerLevels();
-
- isStarted = true;
- }
-
- public void stop() {
- isStarted = false;
- }
-
- public boolean isStarted() {
- return isStarted;
- }
+ public boolean isStarted() {
+ return isStarted;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/layout/TTLLLayout.java b/logback-classic/src/main/java/ch/qos/logback/classic/layout/TTLLLayout.java
deleted file mode 100644
index dd1a858..0000000
--- a/logback-classic/src/main/java/ch/qos/logback/classic/layout/TTLLLayout.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package ch.qos.logback.classic.layout;
-
-import ch.qos.logback.classic.pattern.ThrowableProxyConverter;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.classic.spi.IThrowableProxy;
-import ch.qos.logback.core.CoreConstants;
-import ch.qos.logback.core.LayoutBase;
-import ch.qos.logback.core.util.CachingDateFormatter;
-
-/**
- * A layout with a fixed format. The output is equivalent to that produced by {@link ch.qos.logback.classic.PatternLayout PatternLayout} with the pattern:</p>
- *
- * <pre>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pre>
- *
- *<p>TTLLLayout has the advantage of faster load time whereas {@link ch.qos.logback.classic.PatternLayout PatternLayout}
- * requires roughly 40 milliseconds to load its parser classes. Note that the second run of PatternLayout will be much much faster (approx. 10 micro-seconds).</p>
- *
- * <p>Fixed format layouts such as TTLLLayout should be considered as an alternative to PatternLayout only if the extra 40 milliseconds at application start-up is considered significant.</p>
- *
- * @author Ceki Gülcü
- * @since 1.1.6
- */
-public class TTLLLayout extends LayoutBase<ILoggingEvent> {
-
- CachingDateFormatter cachingDateFormatter = new CachingDateFormatter("HH:mm:ss.SSS");
- ThrowableProxyConverter tpc = new ThrowableProxyConverter();
-
- @Override
- public void start() {
- tpc.start();
- super.start();
- }
-
- @Override
- public String doLayout(ILoggingEvent event) {
- if (!isStarted()) {
- return CoreConstants.EMPTY_STRING;
- }
- StringBuilder sb = new StringBuilder();
-
- long timestamp = event.getTimeStamp();
-
- sb.append(cachingDateFormatter.format(timestamp));
- sb.append(" [");
- sb.append(event.getThreadName());
- sb.append("] ");
- sb.append(event.getLevel().toString());
- sb.append(" ");
- sb.append(event.getLoggerName());
- sb.append(" - ");
- sb.append(event.getFormattedMessage());
- sb.append(CoreConstants.LINE_SEPARATOR);
- IThrowableProxy tp = event.getThrowableProxy();
- if (tp != null) {
- String stackTrace = tpc.convert(event);
- sb.append(stackTrace);
- }
- return sb.toString();
- }
-
-}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/log4j/XMLLayout.java b/logback-classic/src/main/java/ch/qos/logback/classic/log4j/XMLLayout.java
index 234dd98..1873d71 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/log4j/XMLLayout.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/log4j/XMLLayout.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -37,149 +37,153 @@ import ch.qos.logback.core.helpers.Transform;
*/
public class XMLLayout extends LayoutBase<ILoggingEvent> {
- private final int DEFAULT_SIZE = 256;
- private final int UPPER_LIMIT = 2048;
-
- private StringBuilder buf = new StringBuilder(DEFAULT_SIZE);
- private boolean locationInfo = false;
- private boolean properties = false;
-
- @Override
- public void start() {
- super.start();
- }
-
- /**
- * The <b>LocationInfo</b> option takes a boolean value. By default, it is
- * set to false which means there will be no location information output by
- * this layout. If the the option is set to true, then the file name and line
- * number of the statement at the origin of the log statement will be output.
- *
- * <p>If you are embedding this layout within an {@link
- * org.apache.log4j.net.SMTPAppender} then make sure to set the
- * <b>LocationInfo</b> option of that appender as well.
- */
- public void setLocationInfo(boolean flag) {
- locationInfo = flag;
+ private final int DEFAULT_SIZE = 256;
+ private final int UPPER_LIMIT = 2048;
+
+ private StringBuilder buf = new StringBuilder(DEFAULT_SIZE);
+ private boolean locationInfo = false;
+ private boolean properties = false;
+
+ @Override
+ public void start() {
+ super.start();
+ }
+
+ /**
+ * The <b>LocationInfo</b> option takes a boolean value. By default, it is
+ * set to false which means there will be no location information output by
+ * this layout. If the the option is set to true, then the file name and line
+ * number of the statement at the origin of the log statement will be output.
+ *
+ * <p>If you are embedding this layout within an {@link
+ * org.apache.log4j.net.SMTPAppender} then make sure to set the
+ * <b>LocationInfo</b> option of that appender as well.
+ */
+ public void setLocationInfo(boolean flag) {
+ locationInfo = flag;
+ }
+
+ /**
+ * Returns the current value of the <b>LocationInfo</b> option.
+ */
+ public boolean getLocationInfo() {
+ return locationInfo;
+ }
+
+ /**
+ * Sets whether MDC key-value pairs should be output, default false.
+ *
+ * @param flag
+ * new value.
+ * @since 1.2.15
+ */
+ public void setProperties(final boolean flag) {
+ properties = flag;
+ }
+
+ /**
+ * Gets whether MDC key-value pairs should be output.
+ *
+ * @return true if MDC key-value pairs are output.
+ * @since 1.2.15
+ */
+ public boolean getProperties() {
+ return properties;
+ }
+
+ /**
+ * Formats a {@link ILoggingEvent} in conformity with the log4j.dtd.
+ */
+ public String doLayout(ILoggingEvent event) {
+
+ // Reset working buffer. If the buffer is too large, then we need a new
+ // one in order to avoid the penalty of creating a large array.
+ if (buf.capacity() > UPPER_LIMIT) {
+ buf = new StringBuilder(DEFAULT_SIZE);
+ } else {
+ buf.setLength(0);
}
- /**
- * Returns the current value of the <b>LocationInfo</b> option.
- */
- public boolean getLocationInfo() {
- return locationInfo;
+ // We yield to the \r\n heresy.
+
+ buf.append("<log4j:event logger=\"");
+ buf.append(event.getLoggerName());
+ buf.append("\"\r\n");
+ buf.append(" timestamp=\"");
+ buf.append(event.getTimeStamp());
+ buf.append("\" level=\"");
+ buf.append(event.getLevel());
+ buf.append("\" thread=\"");
+ buf.append(event.getThreadName());
+ buf.append("\">\r\n");
+
+ buf.append(" <log4j:message><![CDATA[");
+ // Append the rendered message. Also make sure to escape any
+ // existing CDATA sections.
+ Transform.appendEscapingCDATA(buf, event.getFormattedMessage());
+ buf.append("]]></log4j:message>\r\n");
+
+ // logback does not support NDC
+ // String ndc = event.getNDC();
+
+
+ IThrowableProxy tp = event.getThrowableProxy();
+ if (tp != null) {
+ StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
+ buf.append(" <log4j:throwable><![CDATA[");
+ for (StackTraceElementProxy step : stepArray) {
+ buf.append(CoreConstants.TAB);
+ buf.append(step.toString());
+ buf.append("\r\n");
+ }
+ buf.append("]]></log4j:throwable>\r\n");
}
- /**
- * Sets whether MDC key-value pairs should be output, default false.
- *
- * @param flag
- * new value.
- * @since 1.2.15
- */
- public void setProperties(final boolean flag) {
- properties = flag;
- }
-
- /**
- * Gets whether MDC key-value pairs should be output.
- *
- * @return true if MDC key-value pairs are output.
- * @since 1.2.15
- */
- public boolean getProperties() {
- return properties;
+ if (locationInfo) {
+ StackTraceElement[] callerDataArray = event.getCallerData();
+ if (callerDataArray != null && callerDataArray.length > 0) {
+ StackTraceElement immediateCallerData = callerDataArray[0];
+ buf.append(" <log4j:locationInfo class=\"");
+ buf.append(immediateCallerData.getClassName());
+ buf.append("\"\r\n");
+ buf.append(" method=\"");
+ buf.append(Transform.escapeTags(immediateCallerData.getMethodName()));
+ buf.append("\" file=\"");
+ buf.append(immediateCallerData.getFileName());
+ buf.append("\" line=\"");
+ buf.append(immediateCallerData.getLineNumber());
+ buf.append("\"/>\r\n");
+ }
}
- /**
- * Formats a {@link ILoggingEvent} in conformity with the log4j.dtd.
+ /*
+ * <log4j:properties> <log4j:data name="name" value="value"/>
+ * </log4j:properties>
*/
- public String doLayout(ILoggingEvent event) {
-
- // Reset working buffer. If the buffer is too large, then we need a new
- // one in order to avoid the penalty of creating a large array.
- if (buf.capacity() > UPPER_LIMIT) {
- buf = new StringBuilder(DEFAULT_SIZE);
- } else {
- buf.setLength(0);
- }
-
- // We yield to the \r\n heresy.
-
- buf.append("<log4j:event logger=\"");
- buf.append(Transform.escapeTags(event.getLoggerName()));
- buf.append("\"\r\n");
- buf.append(" timestamp=\"");
- buf.append(event.getTimeStamp());
- buf.append("\" level=\"");
- buf.append(event.getLevel());
- buf.append("\" thread=\"");
- buf.append(Transform.escapeTags(event.getThreadName()));
- buf.append("\">\r\n");
-
- buf.append(" <log4j:message>");
- buf.append(Transform.escapeTags(event.getFormattedMessage()));
- buf.append("</log4j:message>\r\n");
-
- // logback does not support NDC
- // String ndc = event.getNDC();
-
- IThrowableProxy tp = event.getThrowableProxy();
- if (tp != null) {
- StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
- buf.append(" <log4j:throwable><![CDATA[");
- for (StackTraceElementProxy step : stepArray) {
- buf.append(CoreConstants.TAB);
- buf.append(step.toString());
- buf.append("\r\n");
- }
- buf.append("]]></log4j:throwable>\r\n");
- }
-
- if (locationInfo) {
- StackTraceElement[] callerDataArray = event.getCallerData();
- if (callerDataArray != null && callerDataArray.length > 0) {
- StackTraceElement immediateCallerData = callerDataArray[0];
- buf.append(" <log4j:locationInfo class=\"");
- buf.append(immediateCallerData.getClassName());
- buf.append("\"\r\n");
- buf.append(" method=\"");
- buf.append(Transform.escapeTags(immediateCallerData.getMethodName()));
- buf.append("\" file=\"");
- buf.append(Transform.escapeTags(immediateCallerData.getFileName()));
- buf.append("\" line=\"");
- buf.append(immediateCallerData.getLineNumber());
- buf.append("\"/>\r\n");
- }
+ if (this.getProperties()) {
+ Map<String, String> propertyMap = event.getMDCPropertyMap();
+
+ if ((propertyMap != null) && (propertyMap.size() != 0)) {
+ Set<Entry<String, String>> entrySet = propertyMap.entrySet();
+ buf.append(" <log4j:properties>");
+ for (Entry<String, String> entry : entrySet) {
+ buf.append("\r\n <log4j:data");
+ buf.append(" name='" + Transform.escapeTags(entry.getKey()) + "'");
+ buf.append(" value='" + Transform.escapeTags(entry.getValue()) + "'");
+ buf.append(" />");
}
+ buf.append("\r\n </log4j:properties>");
+ }
+ }
- /*
- * <log4j:properties> <log4j:data name="name" value="value"/> </log4j:properties>
- */
- if (this.getProperties()) {
- Map<String, String> propertyMap = event.getMDCPropertyMap();
-
- if ((propertyMap != null) && (propertyMap.size() != 0)) {
- Set<Entry<String, String>> entrySet = propertyMap.entrySet();
- buf.append(" <log4j:properties>");
- for (Entry<String, String> entry : entrySet) {
- buf.append("\r\n <log4j:data");
- buf.append(" name='" + Transform.escapeTags(entry.getKey()) + "'");
- buf.append(" value='" + Transform.escapeTags(entry.getValue()) + "'");
- buf.append(" />");
- }
- buf.append("\r\n </log4j:properties>");
- }
- }
+ buf.append("\r\n</log4j:event>\r\n\r\n");
- buf.append("\r\n</log4j:event>\r\n\r\n");
+ return buf.toString();
+ }
- return buf.toString();
- }
-
- @Override
- public String getContentType() {
- return "text/xml";
- }
+ @Override
+ public String getContentType() {
+ return "text/xml";
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSQueueAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSQueueAppender.java
index a192ce3..8b37fc2 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSQueueAppender.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSQueueAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -41,166 +41,171 @@ import ch.qos.logback.core.spi.PreSerializationTransformer;
*/
public class JMSQueueAppender extends JMSAppenderBase<ILoggingEvent> {
- static int SUCCESSIVE_FAILURE_LIMIT = 3;
-
- String queueBindingName;
- String qcfBindingName;
- QueueConnection queueConnection;
- QueueSession queueSession;
- QueueSender queueSender;
-
- int successiveFailureCount = 0;
-
- private PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer();
-
- /**
- * The <b>QueueConnectionFactoryBindingName</b> option takes a string value.
- * Its value will be used to lookup the appropriate
- * <code>QueueConnectionFactory</code> from the JNDI context.
- */
- public void setQueueConnectionFactoryBindingName(String qcfBindingName) {
- this.qcfBindingName = qcfBindingName;
- }
-
- /**
- * Returns the value of the <b>QueueConnectionFactoryBindingName</b> option.
- */
- public String getQueueConnectionFactoryBindingName() {
- return qcfBindingName;
+ static int SUCCESSIVE_FAILURE_LIMIT = 3;
+
+ String queueBindingName;
+ String qcfBindingName;
+ QueueConnection queueConnection;
+ QueueSession queueSession;
+ QueueSender queueSender;
+
+ int successiveFailureCount = 0;
+
+ private PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer();
+
+ /**
+ * The <b>QueueConnectionFactoryBindingName</b> option takes a string value.
+ * Its value will be used to lookup the appropriate
+ * <code>QueueConnectionFactory</code> from the JNDI context.
+ */
+ public void setQueueConnectionFactoryBindingName(String qcfBindingName) {
+ this.qcfBindingName = qcfBindingName;
+ }
+
+ /**
+ * Returns the value of the <b>QueueConnectionFactoryBindingName</b> option.
+ */
+ public String getQueueConnectionFactoryBindingName() {
+ return qcfBindingName;
+ }
+
+ /**
+ * The <b>QueueBindingName</b> option takes a string value. Its value will be
+ * used to lookup the appropriate <code>Queue</code> from the JNDI context.
+ */
+ public void setQueueBindingName(String queueBindingName) {
+ this.queueBindingName = queueBindingName;
+ }
+
+ /**
+ * Returns the value of the <b>QueueBindingName</b> option.
+ */
+ public String getQueueBindingName() {
+ return queueBindingName;
+ }
+
+ /**
+ * Options are activated and become effective only after calling this method.
+ */
+ public void start() {
+ QueueConnectionFactory queueConnectionFactory;
+
+ try {
+ Context jndi = buildJNDIContext();
+
+ // addInfo("Looking up [" + qcfBindingName + "]");
+ queueConnectionFactory = (QueueConnectionFactory) lookup(jndi,
+ qcfBindingName);
+ // addInfo("About to create QueueConnection.");
+ if (userName != null) {
+ this.queueConnection = queueConnectionFactory.createQueueConnection(
+ userName, password);
+ } else {
+ this.queueConnection = queueConnectionFactory.createQueueConnection();
+ }
+
+ // addInfo(
+ // "Creating QueueSession, non-transactional, "
+ // + "in AUTO_ACKNOWLEDGE mode.");
+ this.queueSession = queueConnection.createQueueSession(false,
+ Session.AUTO_ACKNOWLEDGE);
+
+ // addInfo("Looking up queue name [" + queueBindingName + "].");
+ Queue queue = (Queue) lookup(jndi, queueBindingName);
+
+ // addInfo("Creating QueueSender.");
+ this.queueSender = queueSession.createSender(queue);
+
+ // addInfo("Starting QueueConnection.");
+ queueConnection.start();
+
+ jndi.close();
+ } catch (Exception e) {
+ addError("Error while activating options for appender named [" + name
+ + "].", e);
}
- /**
- * The <b>QueueBindingName</b> option takes a string value. Its value will be
- * used to lookup the appropriate <code>Queue</code> from the JNDI context.
- */
- public void setQueueBindingName(String queueBindingName) {
- this.queueBindingName = queueBindingName;
+ if (this.queueConnection != null && this.queueSession != null
+ && this.queueSender != null) {
+ super.start();
}
-
- /**
- * Returns the value of the <b>QueueBindingName</b> option.
- */
- public String getQueueBindingName() {
- return queueBindingName;
- }
-
- /**
- * Options are activated and become effective only after calling this method.
- */
- public void start() {
- QueueConnectionFactory queueConnectionFactory;
-
- try {
- Context jndi = buildJNDIContext();
-
- // addInfo("Looking up [" + qcfBindingName + "]");
- queueConnectionFactory = (QueueConnectionFactory) lookup(jndi, qcfBindingName);
- // addInfo("About to create QueueConnection.");
- if (userName != null) {
- this.queueConnection = queueConnectionFactory.createQueueConnection(userName, password);
- } else {
- this.queueConnection = queueConnectionFactory.createQueueConnection();
- }
-
- // addInfo(
- // "Creating QueueSession, non-transactional, "
- // + "in AUTO_ACKNOWLEDGE mode.");
- this.queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
-
- // addInfo("Looking up queue name [" + queueBindingName + "].");
- Queue queue = (Queue) lookup(jndi, queueBindingName);
-
- // addInfo("Creating QueueSender.");
- this.queueSender = queueSession.createSender(queue);
-
- // addInfo("Starting QueueConnection.");
- queueConnection.start();
-
- jndi.close();
- } catch (Exception e) {
- addError("Error while activating options for appender named [" + name + "].", e);
- }
-
- if (this.queueConnection != null && this.queueSession != null && this.queueSender != null) {
- super.start();
- }
+ }
+
+ /**
+ * Close this JMSAppender. Closing releases all resources used by the
+ * appender. A closed appender cannot be re-opened.
+ */
+ public synchronized void stop() {
+ // The synchronized modifier avoids concurrent append and close operations
+ if (!this.started) {
+ return;
}
- /**
- * Close this JMSAppender. Closing releases all resources used by the
- * appender. A closed appender cannot be re-opened.
- */
- public synchronized void stop() {
- // The synchronized modifier avoids concurrent append and close operations
- if (!this.started) {
- return;
- }
-
- this.started = false;
-
- try {
- if (queueSession != null) {
- queueSession.close();
- }
- if (queueConnection != null) {
- queueConnection.close();
- }
- } catch (Exception e) {
- addError("Error while closing JMSAppender [" + name + "].", e);
- }
-
- // Help garbage collection
- queueSender = null;
- queueSession = null;
- queueConnection = null;
+ this.started = false;
+
+ try {
+ if (queueSession != null) {
+ queueSession.close();
+ }
+ if (queueConnection != null) {
+ queueConnection.close();
+ }
+ } catch (Exception e) {
+ addError("Error while closing JMSAppender [" + name + "].", e);
}
- /**
- * This method called by {@link AppenderBase#doAppend} method to do most
- * of the real appending work.
- */
- public void append(ILoggingEvent event) {
- if (!isStarted()) {
- return;
- }
-
- try {
- ObjectMessage msg = queueSession.createObjectMessage();
- Serializable so = pst.transform(event);
- msg.setObject(so);
- queueSender.send(msg);
- successiveFailureCount = 0;
- } catch (Exception e) {
- successiveFailureCount++;
- if (successiveFailureCount > SUCCESSIVE_FAILURE_LIMIT) {
- stop();
- }
- addError("Could not send message in JMSQueueAppender [" + name + "].", e);
-
- }
+ // Help garbage collection
+ queueSender = null;
+ queueSession = null;
+ queueConnection = null;
+ }
+
+ /**
+ * This method called by {@link AppenderBase#doAppend} method to do most
+ * of the real appending work.
+ */
+ public void append(ILoggingEvent event) {
+ if (!isStarted()) {
+ return;
}
- /**
- * Returns the QueueConnection used for this appender. Only valid after
- * start() method has been invoked.
- */
- protected QueueConnection getQueueConnection() {
- return queueConnection;
- }
-
- /**
- * Returns the QueueSession used for this appender. Only valid after start()
- * method has been invoked.
- */
- protected QueueSession getQueueSession() {
- return queueSession;
- }
+ try {
+ ObjectMessage msg = queueSession.createObjectMessage();
+ Serializable so = pst.transform(event);
+ msg.setObject(so);
+ queueSender.send(msg);
+ successiveFailureCount = 0;
+ } catch (Exception e) {
+ successiveFailureCount++;
+ if (successiveFailureCount > SUCCESSIVE_FAILURE_LIMIT) {
+ stop();
+ }
+ addError("Could not send message in JMSQueueAppender [" + name + "].", e);
- /**
- * Returns the QueueSender used for this appender. Only valid after start()
- * method has been invoked.
- */
- protected QueueSender getQueueSender() {
- return queueSender;
}
+ }
+
+ /**
+ * Returns the QueueConnection used for this appender. Only valid after
+ * start() method has been invoked.
+ */
+ protected QueueConnection getQueueConnection() {
+ return queueConnection;
+ }
+
+ /**
+ * Returns the QueueSession used for this appender. Only valid after start()
+ * method has been invoked.
+ */
+ protected QueueSession getQueueSession() {
+ return queueSession;
+ }
+
+ /**
+ * Returns the QueueSender used for this appender. Only valid after start()
+ * method has been invoked.
+ */
+ protected QueueSender getQueueSender() {
+ return queueSender;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSQueueSink.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSQueueSink.java
index a64636f..460290e 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSQueueSink.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSQueueSink.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -45,97 +45,108 @@ import ch.qos.logback.classic.util.ContextInitializer;
*/
public class JMSQueueSink implements javax.jms.MessageListener {
- private Logger logger = (Logger) LoggerFactory.getLogger(JMSTopicSink.class);
-
- static public void main(String[] args) throws Exception {
- if (args.length < 2) {
- usage("Wrong number of arguments.");
- }
-
- String qcfBindingName = args[0];
- String queueBindingName = args[1];
- String username = null;
- String password = null;
- if (args.length == 4) {
- username = args[2];
- password = args[3];
- }
-
- LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
- new ContextInitializer(loggerContext).autoConfig();
-
- new JMSQueueSink(qcfBindingName, queueBindingName, username, password);
-
- BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
- // Loop until the word "exit" is typed
- System.out.println("Type \"exit\" to quit JMSQueueSink.");
- while (true) {
- String s = stdin.readLine();
- if (s.equalsIgnoreCase("exit")) {
- System.out.println("Exiting. Kill the application if it does not exit " + "due to daemon threads.");
- return;
- }
- }
- }
-
- public JMSQueueSink(String qcfBindingName, String queueBindingName, String username, String password) {
-
- try {
- Properties env = new Properties();
- env.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
- env.put(Context.PROVIDER_URL, "tcp://localhost:61616");
- Context ctx = new InitialContext(env);
- QueueConnectionFactory queueConnectionFactory;
- queueConnectionFactory = (QueueConnectionFactory) lookup(ctx, qcfBindingName);
- System.out.println("Queue Cnx Factory found");
- Queue queue = (Queue) ctx.lookup(queueBindingName);
- System.out.println("Queue found: " + queue.getQueueName());
-
- QueueConnection queueConnection = queueConnectionFactory.createQueueConnection(username, password);
- System.out.println("Queue Connection created");
-
- QueueSession queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
-
- MessageConsumer queueConsumer = queueSession.createConsumer(queue);
+ private Logger logger = (Logger)LoggerFactory.getLogger(JMSTopicSink.class);
- queueConsumer.setMessageListener(this);
-
- queueConnection.start();
- System.out.println("Queue Connection started");
-
- } catch (Exception e) {
- logger.error("Could not read JMS message.", e);
- }
+ static public void main(String[] args) throws Exception {
+ if (args.length < 2) {
+ usage("Wrong number of arguments.");
}
- public void onMessage(javax.jms.Message message) {
- ILoggingEvent event;
- try {
- if (message instanceof ObjectMessage) {
- ObjectMessage objectMessage = (ObjectMessage) message;
- event = (ILoggingEvent) objectMessage.getObject();
- Logger log = (Logger) LoggerFactory.getLogger(event.getLoggerName());
- log.callAppenders(event);
- } else {
- logger.warn("Received message is of type " + message.getJMSType() + ", was expecting ObjectMessage.");
- }
- } catch (JMSException jmse) {
- logger.error("Exception thrown while processing incoming message.", jmse);
- }
+ String qcfBindingName = args[0];
+ String queueBindingName = args[1];
+ String username = null;
+ String password = null;
+ if (args.length == 4) {
+ username = args[2];
+ password = args[3];
}
- protected Object lookup(Context ctx, String name) throws NamingException {
- try {
- return ctx.lookup(name);
- } catch (NameNotFoundException e) {
- logger.error("Could not find name [" + name + "].");
- throw e;
- }
+ LoggerContext loggerContext = (LoggerContext) LoggerFactory
+ .getILoggerFactory();
+ new ContextInitializer(loggerContext).autoConfig();
+
+ new JMSQueueSink(qcfBindingName, queueBindingName, username, password);
+
+ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+ // Loop until the word "exit" is typed
+ System.out.println("Type \"exit\" to quit JMSQueueSink.");
+ while (true) {
+ String s = stdin.readLine();
+ if (s.equalsIgnoreCase("exit")) {
+ System.out.println("Exiting. Kill the application if it does not exit "
+ + "due to daemon threads.");
+ return;
+ }
}
-
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + JMSQueueSink.class.getName() + " QueueConnectionFactoryBindingName QueueBindingName Username Password");
- System.exit(1);
+ }
+
+ public JMSQueueSink(String qcfBindingName, String queueBindingName,
+ String username, String password) {
+
+ try {
+ Properties env = new Properties();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
+ env.put(Context.PROVIDER_URL, "tcp://localhost:61616");
+ Context ctx = new InitialContext(env);
+ QueueConnectionFactory queueConnectionFactory;
+ queueConnectionFactory = (QueueConnectionFactory) lookup(ctx,
+ qcfBindingName);
+ System.out.println("Queue Cnx Factory found");
+ Queue queue = (Queue) ctx.lookup(queueBindingName);
+ System.out.println("Queue found: " + queue.getQueueName());
+
+ QueueConnection queueConnection = queueConnectionFactory
+ .createQueueConnection(username, password);
+ System.out.println("Queue Connection created");
+
+ QueueSession queueSession = queueConnection.createQueueSession(false,
+ Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer queueConsumer = queueSession.createConsumer(queue);
+
+ queueConsumer.setMessageListener(this);
+
+ queueConnection.start();
+ System.out.println("Queue Connection started");
+
+ } catch (Exception e) {
+ logger.error("Could not read JMS message.", e);
+ }
+ }
+
+ public void onMessage(javax.jms.Message message) {
+ ILoggingEvent event;
+ try {
+ if (message instanceof ObjectMessage) {
+ ObjectMessage objectMessage = (ObjectMessage) message;
+ event = (ILoggingEvent) objectMessage.getObject();
+ Logger log = (Logger) LoggerFactory.getLogger(event.getLoggerName());
+ log.callAppenders(event);
+ } else {
+ logger.warn("Received message is of type " + message.getJMSType()
+ + ", was expecting ObjectMessage.");
+ }
+ } catch (JMSException jmse) {
+ logger.error("Exception thrown while processing incoming message.", jmse);
+ }
+ }
+
+ protected Object lookup(Context ctx, String name)
+ throws NamingException {
+ try {
+ return ctx.lookup(name);
+ } catch (NameNotFoundException e) {
+ logger.error("Could not find name [" + name + "].");
+ throw e;
}
+ }
+
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err
+ .println("Usage: java "
+ + JMSQueueSink.class.getName()
+ + " QueueConnectionFactoryBindingName QueueBindingName Username Password");
+ System.exit(1);
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSTopicAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSTopicAppender.java
index 0860507..7f0da08 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSTopicAppender.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSTopicAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -41,165 +41,171 @@ import ch.qos.logback.core.spi.PreSerializationTransformer;
*/
public class JMSTopicAppender extends JMSAppenderBase<ILoggingEvent> {
- static int SUCCESSIVE_FAILURE_LIMIT = 3;
-
- String topicBindingName;
- String tcfBindingName;
- TopicConnection topicConnection;
- TopicSession topicSession;
- TopicPublisher topicPublisher;
-
- int successiveFailureCount = 0;
-
- private PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer();
-
- /**
- * The <b>TopicConnectionFactoryBindingName</b> option takes a string value.
- * Its value will be used to lookup the appropriate
- * <code>TopicConnectionFactory</code> from the JNDI context.
- */
- public void setTopicConnectionFactoryBindingName(String tcfBindingName) {
- this.tcfBindingName = tcfBindingName;
+ static int SUCCESSIVE_FAILURE_LIMIT = 3;
+
+ String topicBindingName;
+ String tcfBindingName;
+ TopicConnection topicConnection;
+ TopicSession topicSession;
+ TopicPublisher topicPublisher;
+
+ int successiveFailureCount = 0;
+
+ private PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer();
+
+ /**
+ * The <b>TopicConnectionFactoryBindingName</b> option takes a string value.
+ * Its value will be used to lookup the appropriate
+ * <code>TopicConnectionFactory</code> from the JNDI context.
+ */
+ public void setTopicConnectionFactoryBindingName(String tcfBindingName) {
+ this.tcfBindingName = tcfBindingName;
+ }
+
+ /**
+ * Returns the value of the <b>TopicConnectionFactoryBindingName</b> option.
+ */
+ public String getTopicConnectionFactoryBindingName() {
+ return tcfBindingName;
+ }
+
+ /**
+ * The <b>TopicBindingName</b> option takes a string value. Its value will be
+ * used to lookup the appropriate <code>Topic</code> from the JNDI context.
+ */
+ public void setTopicBindingName(String topicBindingName) {
+ this.topicBindingName = topicBindingName;
+ }
+
+ /**
+ * Returns the value of the <b>TopicBindingName</b> option.
+ */
+ public String getTopicBindingName() {
+ return topicBindingName;
+ }
+
+ /**
+ * Options are activated and become effective only after calling this method.
+ */
+ public void start() {
+ TopicConnectionFactory topicConnectionFactory;
+
+ try {
+ Context jndi = buildJNDIContext();
+
+ // addInfo("Looking up [" + tcfBindingName + "]");
+ topicConnectionFactory = (TopicConnectionFactory) lookup(jndi,
+ tcfBindingName);
+ // addInfo("About to create TopicConnection.");
+ if (userName != null) {
+ this.topicConnection = topicConnectionFactory.createTopicConnection(
+ userName, password);
+ } else {
+ this.topicConnection = topicConnectionFactory.createTopicConnection();
+ }
+
+ // addInfo(
+ // "Creating TopicSession, non-transactional, "
+ // + "in AUTO_ACKNOWLEDGE mode.");
+ this.topicSession = topicConnection.createTopicSession(false,
+ Session.AUTO_ACKNOWLEDGE);
+
+ // addInfo("Looking up topic name [" + topicBindingName + "].");
+ Topic topic = (Topic) lookup(jndi, topicBindingName);
+
+ // addInfo("Creating TopicPublisher.");
+ this.topicPublisher = topicSession.createPublisher(topic);
+
+ // addInfo("Starting TopicConnection.");
+ topicConnection.start();
+
+ jndi.close();
+ } catch (Exception e) {
+ addError("Error while activating options for appender named [" + name
+ + "].", e);
}
- /**
- * Returns the value of the <b>TopicConnectionFactoryBindingName</b> option.
- */
- public String getTopicConnectionFactoryBindingName() {
- return tcfBindingName;
+ if (this.topicConnection != null && this.topicSession != null
+ && this.topicPublisher != null) {
+ super.start();
}
-
- /**
- * The <b>TopicBindingName</b> option takes a string value. Its value will be
- * used to lookup the appropriate <code>Topic</code> from the JNDI context.
- */
- public void setTopicBindingName(String topicBindingName) {
- this.topicBindingName = topicBindingName;
+ }
+
+ /**
+ * Close this JMSAppender. Closing releases all resources used by the
+ * appender. A closed appender cannot be re-opened.
+ */
+ public synchronized void stop() {
+ // The synchronized modifier avoids concurrent append and close operations
+ if (!this.started) {
+ return;
}
- /**
- * Returns the value of the <b>TopicBindingName</b> option.
- */
- public String getTopicBindingName() {
- return topicBindingName;
+ this.started = false;
+
+ try {
+ if (topicSession != null) {
+ topicSession.close();
+ }
+ if (topicConnection != null) {
+ topicConnection.close();
+ }
+ } catch (Exception e) {
+ addError("Error while closing JMSAppender [" + name + "].", e);
}
- /**
- * Options are activated and become effective only after calling this method.
- */
- public void start() {
- TopicConnectionFactory topicConnectionFactory;
-
- try {
- Context jndi = buildJNDIContext();
-
- // addInfo("Looking up [" + tcfBindingName + "]");
- topicConnectionFactory = (TopicConnectionFactory) lookup(jndi, tcfBindingName);
- // addInfo("About to create TopicConnection.");
- if (userName != null) {
- this.topicConnection = topicConnectionFactory.createTopicConnection(userName, password);
- } else {
- this.topicConnection = topicConnectionFactory.createTopicConnection();
- }
-
- // addInfo(
- // "Creating TopicSession, non-transactional, "
- // + "in AUTO_ACKNOWLEDGE mode.");
- this.topicSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
-
- // addInfo("Looking up topic name [" + topicBindingName + "].");
- Topic topic = (Topic) lookup(jndi, topicBindingName);
-
- // addInfo("Creating TopicPublisher.");
- this.topicPublisher = topicSession.createPublisher(topic);
-
- // addInfo("Starting TopicConnection.");
- topicConnection.start();
-
- jndi.close();
- } catch (Exception e) {
- addError("Error while activating options for appender named [" + name + "].", e);
- }
-
- if (this.topicConnection != null && this.topicSession != null && this.topicPublisher != null) {
- super.start();
- }
- }
+ // Help garbage collection
+ topicPublisher = null;
+ topicSession = null;
+ topicConnection = null;
+ }
- /**
- * Close this JMSAppender. Closing releases all resources used by the
- * appender. A closed appender cannot be re-opened.
- */
- public synchronized void stop() {
- // The synchronized modifier avoids concurrent append and close operations
- if (!this.started) {
- return;
- }
-
- this.started = false;
-
- try {
- if (topicSession != null) {
- topicSession.close();
- }
- if (topicConnection != null) {
- topicConnection.close();
- }
- } catch (Exception e) {
- addError("Error while closing JMSAppender [" + name + "].", e);
- }
-
- // Help garbage collection
- topicPublisher = null;
- topicSession = null;
- topicConnection = null;
- }
-
- /**
- * This method called by {@link AppenderBase#doAppend} method to do most
- * of the real appending work.
- */
- public void append(ILoggingEvent event) {
- if (!isStarted()) {
- return;
- }
-
- try {
- ObjectMessage msg = topicSession.createObjectMessage();
- Serializable so = pst.transform(event);
- msg.setObject(so);
- topicPublisher.publish(msg);
- successiveFailureCount = 0;
- } catch (Exception e) {
- successiveFailureCount++;
- if (successiveFailureCount > SUCCESSIVE_FAILURE_LIMIT) {
- stop();
- }
- addError("Could not publish message in JMSTopicAppender [" + name + "].", e);
- }
- }
-
- /**
- * Returns the TopicConnection used for this appender. Only valid after
- * start() method has been invoked.
- */
- protected TopicConnection getTopicConnection() {
- return topicConnection;
- }
- /**
- * Returns the TopicSession used for this appender. Only valid after start()
- * method has been invoked.
- */
- protected TopicSession getTopicSession() {
- return topicSession;
+ /**
+ * This method called by {@link AppenderBase#doAppend} method to do most
+ * of the real appending work.
+ */
+ public void append(ILoggingEvent event) {
+ if (!isStarted()) {
+ return;
}
- /**
- * Returns the TopicPublisher used for this appender. Only valid after start()
- * method has been invoked.
- */
- protected TopicPublisher getTopicPublisher() {
- return topicPublisher;
+ try {
+ ObjectMessage msg = topicSession.createObjectMessage();
+ Serializable so = pst.transform(event);
+ msg.setObject(so);
+ topicPublisher.publish(msg);
+ successiveFailureCount = 0;
+ } catch (Exception e) {
+ successiveFailureCount++;
+ if (successiveFailureCount > SUCCESSIVE_FAILURE_LIMIT) {
+ stop();
+ }
+ addError("Could not publish message in JMSTopicAppender [" + name + "].", e);
}
+ }
+
+ /**
+ * Returns the TopicConnection used for this appender. Only valid after
+ * start() method has been invoked.
+ */
+ protected TopicConnection getTopicConnection() {
+ return topicConnection;
+ }
+
+ /**
+ * Returns the TopicSession used for this appender. Only valid after start()
+ * method has been invoked.
+ */
+ protected TopicSession getTopicSession() {
+ return topicSession;
+ }
+
+ /**
+ * Returns the TopicPublisher used for this appender. Only valid after start()
+ * method has been invoked.
+ */
+ protected TopicPublisher getTopicPublisher() {
+ return topicPublisher;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSTopicSink.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSTopicSink.java
index cd1d4d2..76e4623 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSTopicSink.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/JMSTopicSink.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -45,97 +45,108 @@ import ch.qos.logback.classic.util.ContextInitializer;
*/
public class JMSTopicSink implements javax.jms.MessageListener {
- private Logger logger = (Logger) LoggerFactory.getLogger(JMSTopicSink.class);
-
- static public void main(String[] args) throws Exception {
- if (args.length < 2) {
- usage("Wrong number of arguments.");
- }
-
- String tcfBindingName = args[0];
- String topicBindingName = args[1];
- String username = null;
- String password = null;
- if (args.length == 4) {
- username = args[2];
- password = args[3];
- }
-
- LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
- new ContextInitializer(loggerContext).autoConfig();
-
- new JMSTopicSink(tcfBindingName, topicBindingName, username, password);
-
- BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
- // Loop until the word "exit" is typed
- System.out.println("Type \"exit\" to quit JMSTopicSink.");
- while (true) {
- String s = stdin.readLine();
- if (s.equalsIgnoreCase("exit")) {
- System.out.println("Exiting. Kill the application if it does not exit " + "due to daemon threads.");
- return;
- }
- }
- }
-
- public JMSTopicSink(String tcfBindingName, String topicBindingName, String username, String password) {
-
- try {
- Properties env = new Properties();
- env.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
- env.put(Context.PROVIDER_URL, "tcp://localhost:61616");
- Context ctx = new InitialContext(env);
- TopicConnectionFactory topicConnectionFactory;
- topicConnectionFactory = (TopicConnectionFactory) lookup(ctx, tcfBindingName);
- System.out.println("Topic Cnx Factory found");
- Topic topic = (Topic) ctx.lookup(topicBindingName);
- System.out.println("Topic found: " + topic.getTopicName());
-
- TopicConnection topicConnection = topicConnectionFactory.createTopicConnection(username, password);
- System.out.println("Topic Connection created");
-
- TopicSession topicSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
-
- TopicSubscriber topicSubscriber = topicSession.createSubscriber(topic);
+ private Logger logger = (Logger)LoggerFactory.getLogger(JMSTopicSink.class);
- topicSubscriber.setMessageListener(this);
-
- topicConnection.start();
- System.out.println("Topic Connection started");
-
- } catch (Exception e) {
- logger.error("Could not read JMS message.", e);
- }
+ static public void main(String[] args) throws Exception {
+ if (args.length < 2) {
+ usage("Wrong number of arguments.");
}
- public void onMessage(javax.jms.Message message) {
- ILoggingEvent event;
- try {
- if (message instanceof ObjectMessage) {
- ObjectMessage objectMessage = (ObjectMessage) message;
- event = (ILoggingEvent) objectMessage.getObject();
- Logger log = (Logger) LoggerFactory.getLogger(event.getLoggerName());
- log.callAppenders(event);
- } else {
- logger.warn("Received message is of type " + message.getJMSType() + ", was expecting ObjectMessage.");
- }
- } catch (JMSException jmse) {
- logger.error("Exception thrown while processing incoming message.", jmse);
- }
+ String tcfBindingName = args[0];
+ String topicBindingName = args[1];
+ String username = null;
+ String password = null;
+ if (args.length == 4) {
+ username = args[2];
+ password = args[3];
}
- protected Object lookup(Context ctx, String name) throws NamingException {
- try {
- return ctx.lookup(name);
- } catch (NameNotFoundException e) {
- logger.error("Could not find name [" + name + "].");
- throw e;
- }
+ LoggerContext loggerContext = (LoggerContext) LoggerFactory
+ .getILoggerFactory();
+ new ContextInitializer(loggerContext).autoConfig();
+
+ new JMSTopicSink(tcfBindingName, topicBindingName, username, password);
+
+ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+ // Loop until the word "exit" is typed
+ System.out.println("Type \"exit\" to quit JMSTopicSink.");
+ while (true) {
+ String s = stdin.readLine();
+ if (s.equalsIgnoreCase("exit")) {
+ System.out.println("Exiting. Kill the application if it does not exit "
+ + "due to daemon threads.");
+ return;
+ }
}
-
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + JMSTopicSink.class.getName() + " TopicConnectionFactoryBindingName TopicBindingName Username Password");
- System.exit(1);
+ }
+
+ public JMSTopicSink(String tcfBindingName, String topicBindingName,
+ String username, String password) {
+
+ try {
+ Properties env = new Properties();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
+ env.put(Context.PROVIDER_URL, "tcp://localhost:61616");
+ Context ctx = new InitialContext(env);
+ TopicConnectionFactory topicConnectionFactory;
+ topicConnectionFactory = (TopicConnectionFactory) lookup(ctx,
+ tcfBindingName);
+ System.out.println("Topic Cnx Factory found");
+ Topic topic = (Topic) ctx.lookup(topicBindingName);
+ System.out.println("Topic found: " + topic.getTopicName());
+
+ TopicConnection topicConnection = topicConnectionFactory
+ .createTopicConnection(username, password);
+ System.out.println("Topic Connection created");
+
+ TopicSession topicSession = topicConnection.createTopicSession(false,
+ Session.AUTO_ACKNOWLEDGE);
+
+ TopicSubscriber topicSubscriber = topicSession.createSubscriber(topic);
+
+ topicSubscriber.setMessageListener(this);
+
+ topicConnection.start();
+ System.out.println("Topic Connection started");
+
+ } catch (Exception e) {
+ logger.error("Could not read JMS message.", e);
+ }
+ }
+
+ public void onMessage(javax.jms.Message message) {
+ ILoggingEvent event;
+ try {
+ if (message instanceof ObjectMessage) {
+ ObjectMessage objectMessage = (ObjectMessage) message;
+ event = (ILoggingEvent) objectMessage.getObject();
+ Logger log = (Logger) LoggerFactory.getLogger(event.getLoggerName());
+ log.callAppenders(event);
+ } else {
+ logger.warn("Received message is of type " + message.getJMSType()
+ + ", was expecting ObjectMessage.");
+ }
+ } catch (JMSException jmse) {
+ logger.error("Exception thrown while processing incoming message.", jmse);
+ }
+ }
+
+ protected Object lookup(Context ctx, String name)
+ throws NamingException {
+ try {
+ return ctx.lookup(name);
+ } catch (NameNotFoundException e) {
+ logger.error("Could not find name [" + name + "].");
+ throw e;
}
+ }
+
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err
+ .println("Usage: java "
+ + JMSTopicSink.class.getName()
+ + " TopicConnectionFactoryBindingName TopicBindingName Username Password");
+ System.exit(1);
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/LoggingEventPreSerializationTransformer.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/LoggingEventPreSerializationTransformer.java
index 62049f4..eabd3fd 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/LoggingEventPreSerializationTransformer.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/LoggingEventPreSerializationTransformer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,19 +20,20 @@ import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.classic.spi.LoggingEventVO;
import ch.qos.logback.core.spi.PreSerializationTransformer;
-public class LoggingEventPreSerializationTransformer implements PreSerializationTransformer<ILoggingEvent> {
+public class LoggingEventPreSerializationTransformer implements
+ PreSerializationTransformer<ILoggingEvent> {
- public Serializable transform(ILoggingEvent event) {
- if (event == null) {
- return null;
- }
- if (event instanceof LoggingEvent) {
- return LoggingEventVO.build(event);
- } else if (event instanceof LoggingEventVO) {
- return (LoggingEventVO) event;
- } else {
- throw new IllegalArgumentException("Unsupported type " + event.getClass().getName());
- }
+ public Serializable transform(ILoggingEvent event) {
+ if(event == null) {
+ return null;
}
+ if (event instanceof LoggingEvent) {
+ return LoggingEventVO.build(event);
+ } else if (event instanceof LoggingEventVO) {
+ return (LoggingEventVO) event;
+ } else {
+ throw new IllegalArgumentException("Unsupported type "+event.getClass().getName());
+ }
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/ReceiverBase.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/ReceiverBase.java
index 6e0aed3..4c9ee30 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/ReceiverBase.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/ReceiverBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,66 +22,66 @@ import ch.qos.logback.core.spi.LifeCycle;
*
* @author Carl Harris
*/
-public abstract class ReceiverBase extends ContextAwareBase implements LifeCycle {
+public abstract class ReceiverBase extends ContextAwareBase
+ implements LifeCycle {
- private boolean started;
-
- /**
- * {@inheritDoc}
- */
- public final void start() {
- if (isStarted())
- return;
- if (getContext() == null) {
- throw new IllegalStateException("context not set");
- }
- if (shouldStart()) {
- getContext().getScheduledExecutorService().execute(getRunnableTask());
- started = true;
- }
+ private boolean started;
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void start() {
+ if (isStarted()) return;
+ if (getContext() == null) {
+ throw new IllegalStateException("context not set");
}
-
- /**
- * {@inheritDoc}
- */
- public final void stop() {
- if (!isStarted())
- return;
- try {
- onStop();
- } catch (RuntimeException ex) {
- addError("on stop: " + ex, ex);
- }
- started = false;
+ if (shouldStart()) {
+ getContext().getExecutorService().execute(getRunnableTask());
+ started = true;
}
+ }
- /**
- * {@inheritDoc}
- */
- public final boolean isStarted() {
- return started;
+ /**
+ * {@inheritDoc}
+ */
+ public final void stop() {
+ if (!isStarted()) return;
+ try {
+ onStop();
}
+ catch (RuntimeException ex) {
+ addError("on stop: " + ex, ex);
+ }
+ started = false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final boolean isStarted() {
+ return started;
+ }
- /**
- * Determines whether this receiver should start.
- * <p>
- * Subclasses will implement this method to do any subclass-specific
- * validation. The subclass's {@link #getRunnableTask()} method will be
- * invoked (and the task returned will be submitted to the executor)
- * if and only if this method returns {@code true}
- * @return flag indicating whether this receiver should start
- */
- protected abstract boolean shouldStart();
-
- /**
- * Allows a subclass to participate in receiver shutdown.
- */
- protected abstract void onStop();
-
- /**
- * Provides the runnable task this receiver will execute.
- * @return runnable task
- */
- protected abstract Runnable getRunnableTask();
-
+ /**
+ * Determines whether this receiver should start.
+ * <p>
+ * Subclasses will implement this method to do any subclass-specific
+ * validation. The subclass's {@link #getRunnableTask()} method will be
+ * invoked (and the task returned will be submitted to the executor)
+ * if and only if this method returns {@code true}
+ * @return flag indicating whether this receiver should start
+ */
+ protected abstract boolean shouldStart();
+
+ /**
+ * Allows a subclass to participate in receiver shutdown.
+ */
+ protected abstract void onStop();
+
+ /**
+ * Provides the runnable task this receiver will execute.
+ * @return runnable task
+ */
+ protected abstract Runnable getRunnableTask();
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java
index a701fc8..4ad8293 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -36,96 +36,100 @@ import org.slf4j.Marker;
*/
public class SMTPAppender extends SMTPAppenderBase<ILoggingEvent> {
- // value "%logger{20} - %m" is referenced in the docs!
- static final String DEFAULT_SUBJECT_PATTERN = "%logger{20} - %m";
-
- private int bufferSize = 512;
- private boolean includeCallerData = false;
-
- /**
- * The default constructor will instantiate the appender with a
- * {@link EventEvaluator} that will trigger on events with level
- * ERROR or higher.
- */
- public SMTPAppender() {
-
- }
-
- public void start() {
- if (eventEvaluator == null) {
- OnErrorEvaluator onError = new OnErrorEvaluator();
- onError.setContext(getContext());
- onError.setName("onError");
- onError.start();
- this.eventEvaluator = onError;
- }
- super.start();
+ // value "%logger{20} - %m" is referenced in the docs!
+ static final String DEFAULT_SUBJECT_PATTERN = "%logger{20} - %m";
+
+ private int bufferSize = 512;
+ private boolean includeCallerData = false;
+
+
+
+ /**
+ * The default constructor will instantiate the appender with a
+ * {@link EventEvaluator} that will trigger on events with level
+ * ERROR or higher.
+ */
+ public SMTPAppender() {
+
+ }
+
+ public void start() {
+ if (eventEvaluator == null) {
+ OnErrorEvaluator onError = new OnErrorEvaluator();
+ onError.setContext(getContext());
+ onError.setName("onError");
+ onError.start();
+ this.eventEvaluator = onError;
}
-
- /**
- * Use the parameter as the {@link
- * EventEvaluator} for this SMTPAppender.
- */
- public SMTPAppender(EventEvaluator<ILoggingEvent> eventEvaluator) {
- this.eventEvaluator = eventEvaluator;
+ super.start();
+ }
+
+ /**
+ * Use the parameter as the {@link
+ * EventEvaluator} for this SMTPAppender.
+ */
+ public SMTPAppender(EventEvaluator<ILoggingEvent> eventEvaluator) {
+ this.eventEvaluator = eventEvaluator;
+ }
+
+ /**
+ * Perform SMTPAppender specific appending actions, mainly adding the event to
+ * a cyclic buffer.
+ */
+ protected void subAppend(CyclicBuffer<ILoggingEvent> cb, ILoggingEvent event) {
+ if(includeCallerData) {
+ event.getCallerData();
}
-
- /**
- * Perform SMTPAppender specific appending actions, mainly adding the event to
- * a cyclic buffer.
- */
- protected void subAppend(CyclicBuffer<ILoggingEvent> cb, ILoggingEvent event) {
- if (includeCallerData) {
- event.getCallerData();
- }
- event.prepareForDeferredProcessing();
- cb.add(event);
+ event.prepareForDeferredProcessing();
+ cb.add(event);
+ }
+
+ @Override
+ protected void fillBuffer(CyclicBuffer<ILoggingEvent> cb, StringBuffer sbuf) {
+ int len = cb.length();
+ for (int i = 0; i < len; i++) {
+ ILoggingEvent event = cb.get();
+ sbuf.append(layout.doLayout(event));
}
+ }
- @Override
- protected void fillBuffer(CyclicBuffer<ILoggingEvent> cb, StringBuffer sbuf) {
- int len = cb.length();
- for (int i = 0; i < len; i++) {
- ILoggingEvent event = cb.get();
- sbuf.append(layout.doLayout(event));
- }
- }
+ protected boolean eventMarksEndOfLife(ILoggingEvent eventObject) {
+ Marker marker = eventObject.getMarker();
+ if(marker == null)
+ return false;
- protected boolean eventMarksEndOfLife(ILoggingEvent eventObject) {
- Marker marker = eventObject.getMarker();
- if (marker == null)
- return false;
+ return marker.contains(ClassicConstants.FINALIZE_SESSION_MARKER);
+ }
- return marker.contains(ClassicConstants.FINALIZE_SESSION_MARKER);
- }
-
- @Override
- protected Layout<ILoggingEvent> makeSubjectLayout(String subjectStr) {
- if (subjectStr == null) {
- subjectStr = DEFAULT_SUBJECT_PATTERN;
- }
- PatternLayout pl = new PatternLayout();
- pl.setContext(getContext());
- pl.setPattern(subjectStr);
- // we don't want a ThrowableInformationConverter appended
- // to the end of the converter chain
- // This fixes issue LBCLASSIC-67
- pl.setPostCompileProcessor(null);
- pl.start();
- return pl;
- }
-
- protected PatternLayout makeNewToPatternLayout(String toPattern) {
- PatternLayout pl = new PatternLayout();
- pl.setPattern(toPattern + "%nopex");
- return pl;
- }
-
- public boolean isIncludeCallerData() {
- return includeCallerData;
- }
- public void setIncludeCallerData(boolean includeCallerData) {
- this.includeCallerData = includeCallerData;
+ @Override
+ protected Layout<ILoggingEvent> makeSubjectLayout(String subjectStr) {
+ if(subjectStr == null) {
+ subjectStr = DEFAULT_SUBJECT_PATTERN;
}
+ PatternLayout pl = new PatternLayout();
+ pl.setContext(getContext());
+ pl.setPattern(subjectStr);
+ // we don't want a ThrowableInformationConverter appended
+ // to the end of the converter chain
+ // This fixes issue LBCLASSIC-67
+ pl.setPostCompileProcessor(null);
+ pl.start();
+ return pl;
+ }
+
+
+ protected PatternLayout makeNewToPatternLayout(String toPattern) {
+ PatternLayout pl = new PatternLayout();
+ pl.setPattern(toPattern+"%nopex");
+ return pl;
+ }
+
+ public boolean isIncludeCallerData() {
+ return includeCallerData;
+ }
+
+ public void setIncludeCallerData(boolean includeCallerData) {
+ this.includeCallerData = includeCallerData;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/SSLSocketAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/SSLSocketAppender.java
index f7a58d7..552b83f 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/SSLSocketAppender.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/SSLSocketAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,26 +29,27 @@ import ch.qos.logback.core.spi.PreSerializationTransformer;
*/
public class SSLSocketAppender extends AbstractSSLSocketAppender<ILoggingEvent> {
- private final PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer();
+ private final PreSerializationTransformer<ILoggingEvent> pst =
+ new LoggingEventPreSerializationTransformer();
- private boolean includeCallerData;
+ private boolean includeCallerData;
+
+ public SSLSocketAppender() {
+ }
- public SSLSocketAppender() {
+ @Override
+ protected void postProcessEvent(ILoggingEvent event) {
+ if (includeCallerData) {
+ event.getCallerData();
}
-
- @Override
- protected void postProcessEvent(ILoggingEvent event) {
- if (includeCallerData) {
- event.getCallerData();
- }
- }
-
- public void setIncludeCallerData(boolean includeCallerData) {
- this.includeCallerData = includeCallerData;
- }
-
- public PreSerializationTransformer<ILoggingEvent> getPST() {
- return pst;
- }
-
+ }
+
+ public void setIncludeCallerData(boolean includeCallerData) {
+ this.includeCallerData = includeCallerData;
+ }
+
+ public PreSerializationTransformer<ILoggingEvent> getPST() {
+ return pst;
+ }
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/SSLSocketReceiver.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/SSLSocketReceiver.java
index a391360..425725e 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/SSLSocketReceiver.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/SSLSocketReceiver.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,56 +26,59 @@ import ch.qos.logback.core.net.ssl.SSLParametersConfiguration;
*
* @author Carl Harris
*/
-public class SSLSocketReceiver extends SocketReceiver implements SSLComponent {
+public class SSLSocketReceiver extends SocketReceiver
+ implements SSLComponent {
- private SSLConfiguration ssl;
- private SocketFactory socketFactory;
+ private SSLConfiguration ssl;
+ private SocketFactory socketFactory;
- /**
- * Gets an {@link SocketFactory} that produces SSL sockets using an
- * {@link SSLContext} that is derived from the receiver's configuration.
- * @return socket factory
- */
- @Override
- protected SocketFactory getSocketFactory() {
- return socketFactory;
- }
+ /**
+ * Gets an {@link SocketFactory} that produces SSL sockets using an
+ * {@link SSLContext} that is derived from the receiver's configuration.
+ * @return socket factory
+ */
+ @Override
+ protected SocketFactory getSocketFactory() {
+ return socketFactory;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- protected boolean shouldStart() {
- try {
- SSLContext sslContext = getSsl().createContext(this);
- SSLParametersConfiguration parameters = getSsl().getParameters();
- parameters.setContext(getContext());
- socketFactory = new ConfigurableSSLSocketFactory(parameters, sslContext.getSocketFactory());
- return super.shouldStart();
- } catch (Exception ex) {
- addError(ex.getMessage(), ex);
- return false;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean shouldStart() {
+ try {
+ SSLContext sslContext = getSsl().createContext(this);
+ SSLParametersConfiguration parameters = getSsl().getParameters();
+ parameters.setContext(getContext());
+ socketFactory = new ConfigurableSSLSocketFactory(parameters,
+ sslContext.getSocketFactory());
+ return super.shouldStart();
}
-
- /**
- * Gets the SSL configuration.
- * @return SSL configuration; if no configuration has been set, a
- * default configuration is returned
- */
- public SSLConfiguration getSsl() {
- if (ssl == null) {
- ssl = new SSLConfiguration();
- }
- return ssl;
+ catch (Exception ex) {
+ addError(ex.getMessage(), ex);
+ return false;
}
+ }
- /**
- * Sets the SSL configuration.
- * @param ssl the SSL configuration to set
- */
- public void setSsl(SSLConfiguration ssl) {
- this.ssl = ssl;
+ /**
+ * Gets the SSL configuration.
+ * @return SSL configuration; if no configuration has been set, a
+ * default configuration is returned
+ */
+ public SSLConfiguration getSsl() {
+ if (ssl == null) {
+ ssl = new SSLConfiguration();
}
+ return ssl;
+ }
+
+ /**
+ * Sets the SSL configuration.
+ * @param ssl the SSL configuration to set
+ */
+ public void setSsl(SSLConfiguration ssl) {
+ this.ssl = ssl;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/SimpleSSLSocketServer.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/SimpleSSLSocketServer.java
index 7d13e28..aba02dd 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/SimpleSSLSocketServer.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/SimpleSSLSocketServer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -56,43 +56,46 @@ import ch.qos.logback.core.net.ssl.SSLParametersConfiguration;
*/
public class SimpleSSLSocketServer extends SimpleSocketServer {
- private final ServerSocketFactory socketFactory;
+ private final ServerSocketFactory socketFactory;
- public static void main(String argv[]) throws Exception {
- doMain(SimpleSSLSocketServer.class, argv);
- }
-
- /**
- * Creates a new server using the default SSL context.
- * @param lc logger context for received events
- * @param port port on which the server is to listen
- * @throws NoSuchAlgorithmException if the default SSL context cannot be
- * created
- */
- public SimpleSSLSocketServer(LoggerContext lc, int port) throws NoSuchAlgorithmException {
- this(lc, port, SSLContext.getDefault());
- }
+ public static void main(String argv[]) throws Exception {
+ doMain(SimpleSSLSocketServer.class, argv);
+ }
- /**
- * Creates a new server using a custom SSL context.
- * @param lc logger context for received events
- * @param port port on which the server is to listen
- * @param sslContext custom SSL context
- */
- public SimpleSSLSocketServer(LoggerContext lc, int port, SSLContext sslContext) {
- super(lc, port);
- if (sslContext == null) {
- throw new NullPointerException("SSL context required");
- }
- SSLParametersConfiguration parameters = new SSLParametersConfiguration();
+ /**
+ * Creates a new server using the default SSL context.
+ * @param lc logger context for received events
+ * @param port port on which the server is to listen
+ * @throws NoSuchAlgorithmException if the default SSL context cannot be
+ * created
+ */
+ public SimpleSSLSocketServer(LoggerContext lc, int port)
+ throws NoSuchAlgorithmException {
+ this(lc, port, SSLContext.getDefault());
+ }
- parameters.setContext(lc);
- this.socketFactory = new ConfigurableSSLServerSocketFactory(parameters, sslContext.getServerSocketFactory());
+ /**
+ * Creates a new server using a custom SSL context.
+ * @param lc logger context for received events
+ * @param port port on which the server is to listen
+ * @param sslContext custom SSL context
+ */
+ public SimpleSSLSocketServer(LoggerContext lc, int port,
+ SSLContext sslContext) {
+ super(lc, port);
+ if (sslContext == null) {
+ throw new NullPointerException("SSL context required");
}
+ SSLParametersConfiguration parameters = new SSLParametersConfiguration();
+
+ parameters.setContext(lc);
+ this.socketFactory = new ConfigurableSSLServerSocketFactory(
+ parameters, sslContext.getServerSocketFactory());
+ }
- @Override
- protected ServerSocketFactory getServerSocketFactory() {
- return socketFactory;
- }
+ @Override
+ protected ServerSocketFactory getServerSocketFactory() {
+ return socketFactory;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/SimpleSocketServer.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/SimpleSocketServer.java
index 13bf6f7..e450fff 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/SimpleSocketServer.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/SimpleSocketServer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -50,188 +50,190 @@ import ch.qos.logback.core.joran.spi.JoranException;
*/
public class SimpleSocketServer extends Thread {
- Logger logger = LoggerFactory.getLogger(SimpleSocketServer.class);
-
- private final int port;
- private final LoggerContext lc;
- private boolean closed = false;
- private ServerSocket serverSocket;
- private List<SocketNode> socketNodeList = new ArrayList<SocketNode>();
-
- // used for testing purposes
- private CountDownLatch latch;
-
- public static void main(String argv[]) throws Exception {
- doMain(SimpleSocketServer.class, argv);
- }
-
- protected static void doMain(Class<? extends SimpleSocketServer> serverClass, String argv[]) throws Exception {
- int port = -1;
- if (argv.length == 2) {
- port = parsePortNumber(argv[0]);
- } else {
- usage("Wrong number of arguments.");
- }
-
- String configFile = argv[1];
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- configureLC(lc, configFile);
-
- SimpleSocketServer sss = new SimpleSocketServer(lc, port);
- sss.start();
- }
-
- public SimpleSocketServer(LoggerContext lc, int port) {
- this.lc = lc;
- this.port = port;
- }
-
- public void run() {
-
- final String oldThreadName = Thread.currentThread().getName();
-
- try {
-
- final String newThreadName = getServerThreadName();
- Thread.currentThread().setName(newThreadName);
-
- logger.info("Listening on port " + port);
- serverSocket = getServerSocketFactory().createServerSocket(port);
- while (!closed) {
- logger.info("Waiting to accept a new client.");
- signalAlmostReadiness();
- Socket socket = serverSocket.accept();
- logger.info("Connected to client at " + socket.getInetAddress());
- logger.info("Starting new socket node.");
- SocketNode newSocketNode = new SocketNode(this, socket, lc);
- synchronized (socketNodeList) {
- socketNodeList.add(newSocketNode);
- }
- final String clientThreadName = getClientThreadName(socket);
- new Thread(newSocketNode, clientThreadName).start();
- }
- } catch (Exception e) {
- if (closed) {
- logger.info("Exception in run method for a closed server. This is normal.");
- } else {
- logger.error("Unexpected failure in run method", e);
- }
- }
-
- finally {
- Thread.currentThread().setName(oldThreadName);
- }
- }
-
- /**
- * Returns the name given to the server thread.
- */
- protected String getServerThreadName() {
- return String.format("Logback %s (port %d)", getClass().getSimpleName(), port);
- }
-
- /**
- * Returns a name to identify each client thread.
- */
- protected String getClientThreadName(Socket socket) {
- return String.format("Logback SocketNode (client: %s)", socket.getRemoteSocketAddress());
- }
-
- /**
- * Gets the platform default {@link ServerSocketFactory}.
- * <p>
- * Subclasses may override to provide a custom server socket factory.
- */
- protected ServerSocketFactory getServerSocketFactory() {
- return ServerSocketFactory.getDefault();
- }
-
- /**
- * Signal another thread that we have established a connection
- * This is useful for testing purposes.
- */
- void signalAlmostReadiness() {
- if (latch != null && latch.getCount() != 0) {
- // System.out.println("signalAlmostReadiness() with latch "+latch);
- latch.countDown();
- }
- }
-
- /**
- * Used for testing purposes
- * @param latch
- */
- void setLatch(CountDownLatch latch) {
- this.latch = latch;
- }
-
- /**
- * Used for testing purposes
- */
- public CountDownLatch getLatch() {
- return latch;
- }
-
- public boolean isClosed() {
- return closed;
- }
-
- public void close() {
- closed = true;
- if (serverSocket != null) {
- try {
- serverSocket.close();
- } catch (IOException e) {
- logger.error("Failed to close serverSocket", e);
- } finally {
- serverSocket = null;
- }
- }
-
- logger.info("closing this server");
- synchronized (socketNodeList) {
- for (SocketNode sn : socketNodeList) {
- sn.close();
- }
- }
- if (socketNodeList.size() != 0) {
- logger.warn("Was expecting a 0-sized socketNodeList after server shutdown");
- }
-
- }
-
- public void socketNodeClosing(SocketNode sn) {
- logger.debug("Removing {}", sn);
-
- // don't allow simultaneous access to the socketNodeList
- // (e.g. removal whole iterating on the list causes
- // java.util.ConcurrentModificationException
+ Logger logger = LoggerFactory.getLogger(SimpleSocketServer.class);
+
+ private final int port;
+ private final LoggerContext lc;
+ private boolean closed = false;
+ private ServerSocket serverSocket;
+ private List<SocketNode> socketNodeList = new ArrayList<SocketNode>();
+
+ // used for testing purposes
+ private CountDownLatch latch;
+
+ public static void main(String argv[]) throws Exception {
+ doMain(SimpleSocketServer.class, argv);
+ }
+
+ protected static void doMain(Class<? extends SimpleSocketServer> serverClass,
+ String argv[]) throws Exception {
+ int port = -1;
+ if (argv.length == 2) {
+ port = parsePortNumber(argv[0]);
+ } else {
+ usage("Wrong number of arguments.");
+ }
+
+ String configFile = argv[1];
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ configureLC(lc, configFile);
+
+ SimpleSocketServer sss = new SimpleSocketServer(lc, port);
+ sss.start();
+ }
+
+ public SimpleSocketServer(LoggerContext lc, int port) {
+ this.lc = lc;
+ this.port = port;
+ }
+
+
+ public void run() {
+
+ final String oldThreadName = Thread.currentThread().getName();
+
+ try {
+
+ final String newThreadName = getServerThreadName();
+ Thread.currentThread().setName(newThreadName);
+
+ logger.info("Listening on port " + port);
+ serverSocket = getServerSocketFactory().createServerSocket(port);
+ while (!closed) {
+ logger.info("Waiting to accept a new client.");
+ signalAlmostReadiness();
+ Socket socket = serverSocket.accept();
+ logger.info("Connected to client at " + socket.getInetAddress());
+ logger.info("Starting new socket node.");
+ SocketNode newSocketNode = new SocketNode(this, socket, lc);
synchronized (socketNodeList) {
- socketNodeList.remove(sn);
- }
- }
-
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + SimpleSocketServer.class.getName() + " port configFile");
- System.exit(1);
- }
-
- static int parsePortNumber(String portStr) {
- try {
- return Integer.parseInt(portStr);
- } catch (java.lang.NumberFormatException e) {
- e.printStackTrace();
- usage("Could not interpret port number [" + portStr + "].");
- // we won't get here
- return -1;
+ socketNodeList.add(newSocketNode);
}
- }
-
- static public void configureLC(LoggerContext lc, String configFile) throws JoranException {
- JoranConfigurator configurator = new JoranConfigurator();
- lc.reset();
- configurator.setContext(lc);
- configurator.doConfigure(configFile);
- }
+ final String clientThreadName = getClientThreadName(socket);
+ new Thread(newSocketNode, clientThreadName).start();
+ }
+ } catch (Exception e) {
+ if(closed) {
+ logger.info("Exception in run method for a closed server. This is normal.");
+ } else {
+ logger.error("Unexpected failure in run method", e);
+ }
+ }
+
+ finally {
+ Thread.currentThread().setName(oldThreadName);
+ }
+ }
+
+ /**
+ * Returns the name given to the server thread.
+ */
+ protected String getServerThreadName() {
+ return String.format("Logback %s (port %d)", getClass().getSimpleName(), port);
+ }
+
+ /**
+ * Returns a name to identify each client thread.
+ */
+ protected String getClientThreadName(Socket socket) {
+ return String.format("Logback SocketNode (client: %s)", socket.getRemoteSocketAddress());
+ }
+
+ /**
+ * Gets the platform default {@link ServerSocketFactory}.
+ * <p>
+ * Subclasses may override to provide a custom server socket factory.
+ */
+ protected ServerSocketFactory getServerSocketFactory() {
+ return ServerSocketFactory.getDefault();
+ }
+
+ /**
+ * Signal another thread that we have established a connection
+ * This is useful for testing purposes.
+ */
+ void signalAlmostReadiness() {
+ if(latch != null && latch.getCount() != 0) {
+ //System.out.println("signalAlmostReadiness() with latch "+latch);
+ latch.countDown();
+ }
+ }
+
+ /**
+ * Used for testing purposes
+ * @param latch
+ */
+ void setLatch(CountDownLatch latch) {
+ this.latch = latch;
+ }
+ /**
+ * Used for testing purposes
+ */
+ public CountDownLatch getLatch() {
+ return latch;
+ }
+ public boolean isClosed() {
+ return closed;
+ }
+
+ public void close() {
+ closed = true;
+ if (serverSocket != null) {
+ try {
+ serverSocket.close();
+ } catch (IOException e) {
+ logger.error("Failed to close serverSocket", e);
+ } finally {
+ serverSocket = null;
+ }
+ }
+
+ logger.info("closing this server");
+ synchronized (socketNodeList) {
+ for(SocketNode sn: socketNodeList) {
+ sn.close();
+ }
+ }
+ if(socketNodeList.size() != 0) {
+ logger.warn("Was expecting a 0-sized socketNodeList after server shutdown");
+ }
+
+ }
+
+ public void socketNodeClosing(SocketNode sn) {
+ logger.debug("Removing {}", sn);
+
+ // don't allow simultaneous access to the socketNodeList
+ // (e.g. removal whole iterating on the list causes
+ // java.util.ConcurrentModificationException
+ synchronized (socketNodeList) {
+ socketNodeList.remove(sn);
+ }
+ }
+
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + SimpleSocketServer.class.getName()
+ + " port configFile");
+ System.exit(1);
+ }
+
+ static int parsePortNumber(String portStr) {
+ try {
+ return Integer.parseInt(portStr);
+ } catch (java.lang.NumberFormatException e) {
+ e.printStackTrace();
+ usage("Could not interpret port number [" + portStr + "].");
+ // we won't get here
+ return -1;
+ }
+ }
+
+ static public void configureLC(LoggerContext lc, String configFile)
+ throws JoranException {
+ JoranConfigurator configurator = new JoranConfigurator();
+ lc.reset();
+ configurator.setContext(lc);
+ configurator.doConfigure(configFile);
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAcceptor.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAcceptor.java
index 3dc9faa..06ea023 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAcceptor.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAcceptor.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,8 +15,9 @@ package ch.qos.logback.classic.net;
class SocketAcceptor extends Thread {
- @Override
- public void run() {
-
- }
+
+ @Override
+ public void run() {
+
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java
index 82518c7..1bc74a4 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -33,26 +33,28 @@ import ch.qos.logback.core.spi.PreSerializationTransformer;
public class SocketAppender extends AbstractSocketAppender<ILoggingEvent> {
- private static final PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer();
+ private static final PreSerializationTransformer<ILoggingEvent> pst =
+ new LoggingEventPreSerializationTransformer();
+
+ private boolean includeCallerData = false;
- private boolean includeCallerData = false;
+ public SocketAppender() {
+ }
- public SocketAppender() {
- }
-
- @Override
- protected void postProcessEvent(ILoggingEvent event) {
- if (includeCallerData) {
- event.getCallerData();
- }
- }
- public void setIncludeCallerData(boolean includeCallerData) {
- this.includeCallerData = includeCallerData;
+ @Override
+ protected void postProcessEvent(ILoggingEvent event) {
+ if (includeCallerData) {
+ event.getCallerData();
}
-
- public PreSerializationTransformer<ILoggingEvent> getPST() {
- return pst;
- }
-
+ }
+
+ public void setIncludeCallerData(boolean includeCallerData) {
+ this.includeCallerData = includeCallerData;
+ }
+
+ public PreSerializationTransformer<ILoggingEvent> getPST() {
+ return pst;
+ }
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketNode.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketNode.java
index 4c01cbe..98023e8 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketNode.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketNode.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -42,87 +42,88 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
*/
public class SocketNode implements Runnable {
- Socket socket;
- LoggerContext context;
- ObjectInputStream ois;
- SocketAddress remoteSocketAddress;
-
- Logger logger;
- boolean closed = false;
- SimpleSocketServer socketServer;
-
- public SocketNode(SimpleSocketServer socketServer, Socket socket, LoggerContext context) {
- this.socketServer = socketServer;
- this.socket = socket;
- remoteSocketAddress = socket.getRemoteSocketAddress();
- this.context = context;
- logger = context.getLogger(SocketNode.class);
+ Socket socket;
+ LoggerContext context;
+ ObjectInputStream ois;
+ SocketAddress remoteSocketAddress;
+
+ Logger logger;
+ boolean closed = false;
+ SimpleSocketServer socketServer;
+
+ public SocketNode(SimpleSocketServer socketServer, Socket socket, LoggerContext context) {
+ this.socketServer = socketServer;
+ this.socket = socket;
+ remoteSocketAddress = socket.getRemoteSocketAddress();
+ this.context = context;
+ logger = context.getLogger(SocketNode.class);
+ }
+
+ // public
+ // void finalize() {
+ // System.err.println("-------------------------Finalize called");
+ // System.err.flush();
+ // }
+
+ public void run() {
+
+ try {
+ ois = new ObjectInputStream(new BufferedInputStream(socket
+ .getInputStream()));
+ } catch (Exception e) {
+ logger.error("Could not open ObjectInputStream to " + socket, e);
+ closed = true;
}
- // public
- // void finalize() {
- // System.err.println("-------------------------Finalize called");
- // System.err.flush();
- // }
-
- public void run() {
-
- try {
- ois = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
- } catch (Exception e) {
- logger.error("Could not open ObjectInputStream to " + socket, e);
- closed = true;
+ ILoggingEvent event;
+ Logger remoteLogger;
+
+ try {
+ while (!closed) {
+ // read an event from the wire
+ event = (ILoggingEvent) ois.readObject();
+ // get a logger from the hierarchy. The name of the logger is taken to
+ // be the name contained in the event.
+ remoteLogger = context.getLogger(event.getLoggerName());
+ // apply the logger-level filter
+ if (remoteLogger.isEnabledFor(event.getLevel())) {
+ // finally log the event as if was generated locally
+ remoteLogger.callAppenders(event);
}
-
- ILoggingEvent event;
- Logger remoteLogger;
-
- try {
- while (!closed) {
- // read an event from the wire
- event = (ILoggingEvent) ois.readObject();
- // get a logger from the hierarchy. The name of the logger is taken to
- // be the name contained in the event.
- remoteLogger = context.getLogger(event.getLoggerName());
- // apply the logger-level filter
- if (remoteLogger.isEnabledFor(event.getLevel())) {
- // finally log the event as if was generated locally
- remoteLogger.callAppenders(event);
- }
- }
- } catch (java.io.EOFException e) {
- logger.info("Caught java.io.EOFException closing connection.");
- } catch (java.net.SocketException e) {
- logger.info("Caught java.net.SocketException closing connection.");
- } catch (IOException e) {
- logger.info("Caught java.io.IOException: " + e);
- logger.info("Closing connection.");
- } catch (Exception e) {
- logger.error("Unexpected exception. Closing connection.", e);
- }
-
- socketServer.socketNodeClosing(this);
- close();
+ }
+ } catch (java.io.EOFException e) {
+ logger.info("Caught java.io.EOFException closing connection.");
+ } catch (java.net.SocketException e) {
+ logger.info("Caught java.net.SocketException closing connection.");
+ } catch (IOException e) {
+ logger.info("Caught java.io.IOException: " + e);
+ logger.info("Closing connection.");
+ } catch (Exception e) {
+ logger.error("Unexpected exception. Closing connection.", e);
}
- void close() {
- if (closed) {
- return;
- }
- closed = true;
- if (ois != null) {
- try {
- ois.close();
- } catch (IOException e) {
- logger.warn("Could not close connection.", e);
- } finally {
- ois = null;
- }
- }
+ socketServer.socketNodeClosing(this);
+ close();
+ }
+
+ void close() {
+ if(closed) {
+ return;
}
-
- @Override
- public String toString() {
- return this.getClass().getName() + remoteSocketAddress.toString();
+ closed = true;
+ if (ois != null) {
+ try {
+ ois.close();
+ } catch (IOException e) {
+ logger.warn("Could not close connection.", e);
+ } finally {
+ ois = null;
+ }
}
+ }
+
+ @Override
+ public String toString() {
+ return this.getClass().getName()+remoteSocketAddress.toString();
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketReceiver.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketReceiver.java
index cfab994..2a99820 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketReceiver.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketReceiver.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -40,179 +40,186 @@ import ch.qos.logback.core.util.CloseUtil;
*
* @author Carl Harris
*/
-public class SocketReceiver extends ReceiverBase implements Runnable, SocketConnector.ExceptionHandler {
-
- private static final int DEFAULT_ACCEPT_CONNECTION_DELAY = 5000;
-
- private String remoteHost;
- private InetAddress address;
- private int port;
- private int reconnectionDelay;
- private int acceptConnectionTimeout = DEFAULT_ACCEPT_CONNECTION_DELAY;
-
- private String receiverId;
- private volatile Socket socket;
- private Future<Socket> connectorTask;
-
- /**
- * {@inheritDoc}
- */
- protected boolean shouldStart() {
- int errorCount = 0;
- if (port == 0) {
- errorCount++;
- addError("No port was configured for receiver. " + "For more information, please visit http://logback.qos.ch/codes.html#receiver_no_port");
- }
-
- if (remoteHost == null) {
- errorCount++;
- addError("No host name or address was configured for receiver. "
- + "For more information, please visit http://logback.qos.ch/codes.html#receiver_no_host");
- }
-
- if (reconnectionDelay == 0) {
- reconnectionDelay = AbstractSocketAppender.DEFAULT_RECONNECTION_DELAY;
- }
-
- if (errorCount == 0) {
- try {
- address = InetAddress.getByName(remoteHost);
- } catch (UnknownHostException ex) {
- addError("unknown host: " + remoteHost);
- errorCount++;
- }
- }
-
- if (errorCount == 0) {
- receiverId = "receiver " + remoteHost + ":" + port + ": ";
- }
-
- return errorCount == 0;
+public class SocketReceiver extends ReceiverBase
+ implements Runnable, SocketConnector.ExceptionHandler {
+
+ private static final int DEFAULT_ACCEPT_CONNECTION_DELAY = 5000;
+
+ private String remoteHost;
+ private InetAddress address;
+ private int port;
+ private int reconnectionDelay;
+ private int acceptConnectionTimeout = DEFAULT_ACCEPT_CONNECTION_DELAY;
+
+ private String receiverId;
+ private volatile Socket socket;
+ private Future<Socket> connectorTask;
+
+ /**
+ * {@inheritDoc}
+ */
+ protected boolean shouldStart() {
+ int errorCount = 0;
+ if (port == 0) {
+ errorCount++;
+ addError("No port was configured for receiver. "
+ + "For more information, please visit http://logback.qos.ch/codes.html#receiver_no_port");
}
- /**
- * {@inheritDoc}
- */
- protected void onStop() {
- if (socket != null) {
- CloseUtil.closeQuietly(socket);
- }
+ if (remoteHost == null) {
+ errorCount++;
+ addError("No host name or address was configured for receiver. "
+ + "For more information, please visit http://logback.qos.ch/codes.html#receiver_no_host");
}
- @Override
- protected Runnable getRunnableTask() {
- return this;
+ if (reconnectionDelay == 0) {
+ reconnectionDelay = AbstractSocketAppender.DEFAULT_RECONNECTION_DELAY;
}
- /**
- * {@inheritDoc}
- */
- public void run() {
- try {
- LoggerContext lc = (LoggerContext) getContext();
- while (!Thread.currentThread().isInterrupted()) {
- SocketConnector connector = createConnector(address, port, 0, reconnectionDelay);
- connectorTask = activateConnector(connector);
- if (connectorTask == null) {
- break;
- }
- socket = waitForConnectorToReturnASocket();
- if (socket == null)
- break;
- dispatchEvents(lc);
- }
- } catch (InterruptedException ex) {
- assert true; // ok... we'll exit now
- }
- addInfo("shutting down");
+ if (errorCount == 0) {
+ try {
+ address = InetAddress.getByName(remoteHost);
+ } catch (UnknownHostException ex) {
+ addError("unknown host: " + remoteHost);
+ errorCount++;
+ }
}
- private SocketConnector createConnector(InetAddress address, int port, int initialDelay, int retryDelay) {
- SocketConnector connector = newConnector(address, port, initialDelay, retryDelay);
- connector.setExceptionHandler(this);
- connector.setSocketFactory(getSocketFactory());
- return connector;
+ if (errorCount == 0) {
+ receiverId = "receiver " + remoteHost + ":" + port + ": ";
}
- private Future<Socket> activateConnector(SocketConnector connector) {
- try {
- return getContext().getScheduledExecutorService().submit(connector);
- } catch (RejectedExecutionException ex) {
- return null;
- }
- }
+ return errorCount == 0;
+ }
- private Socket waitForConnectorToReturnASocket() throws InterruptedException {
- try {
- Socket s = connectorTask.get();
- connectorTask = null;
- return s;
- } catch (ExecutionException e) {
- return null;
- }
+ /**
+ * {@inheritDoc}
+ */
+ protected void onStop() {
+ if (socket != null) {
+ CloseUtil.closeQuietly(socket);
}
-
- private void dispatchEvents(LoggerContext lc) {
- try {
- socket.setSoTimeout(acceptConnectionTimeout);
- ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
- socket.setSoTimeout(0);
- addInfo(receiverId + "connection established");
- while (true) {
- ILoggingEvent event = (ILoggingEvent) ois.readObject();
- Logger remoteLogger = lc.getLogger(event.getLoggerName());
- if (remoteLogger.isEnabledFor(event.getLevel())) {
- remoteLogger.callAppenders(event);
- }
- }
- } catch (EOFException ex) {
- addInfo(receiverId + "end-of-stream detected");
- } catch (IOException ex) {
- addInfo(receiverId + "connection failed: " + ex);
- } catch (ClassNotFoundException ex) {
- addInfo(receiverId + "unknown event class: " + ex);
- } finally {
- CloseUtil.closeQuietly(socket);
- socket = null;
- addInfo(receiverId + "connection closed");
- }
+ }
+
+ @Override
+ protected Runnable getRunnableTask() {
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void run() {
+ try {
+ LoggerContext lc = (LoggerContext) getContext();
+ while (!Thread.currentThread().isInterrupted()) {
+ SocketConnector connector = createConnector(address, port, 0,
+ reconnectionDelay);
+ connectorTask = activateConnector(connector);
+ if (connectorTask == null)
+ break;
+ socket = waitForConnectorToReturnASocket();
+ if (socket == null)
+ break;
+ dispatchEvents(lc);
+ }
+ } catch (InterruptedException ex) {
+ assert true; // ok... we'll exit now
}
-
- /**
- * {@inheritDoc}
- */
- public void connectionFailed(SocketConnector connector, Exception ex) {
- if (ex instanceof InterruptedException) {
- addInfo("connector interrupted");
- } else if (ex instanceof ConnectException) {
- addInfo(receiverId + "connection refused");
- } else {
- addInfo(receiverId + ex);
+ addInfo("shutting down");
+ }
+
+ private SocketConnector createConnector(InetAddress address, int port,
+ int initialDelay, int retryDelay) {
+ SocketConnector connector = newConnector(address, port, initialDelay,
+ retryDelay);
+ connector.setExceptionHandler(this);
+ connector.setSocketFactory(getSocketFactory());
+ return connector;
+ }
+
+
+ private Future<Socket> activateConnector(SocketConnector connector) {
+ try {
+ return getContext().getExecutorService().submit(connector);
+ } catch (RejectedExecutionException ex) {
+ return null;
+ }
+ }
+
+ private Socket waitForConnectorToReturnASocket() throws InterruptedException {
+ try {
+ Socket s = connectorTask.get();
+ connectorTask = null;
+ return s;
+ } catch (ExecutionException e) {
+ return null;
+ }
+ }
+
+ private void dispatchEvents(LoggerContext lc) {
+ try {
+ socket.setSoTimeout(acceptConnectionTimeout);
+ ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
+ socket.setSoTimeout(0);
+ addInfo(receiverId + "connection established");
+ while (true) {
+ ILoggingEvent event = (ILoggingEvent) ois.readObject();
+ Logger remoteLogger = lc.getLogger(event.getLoggerName());
+ if (remoteLogger.isEnabledFor(event.getLevel())) {
+ remoteLogger.callAppenders(event);
}
+ }
+ } catch (EOFException ex) {
+ addInfo(receiverId + "end-of-stream detected");
+ } catch (IOException ex) {
+ addInfo(receiverId + "connection failed: " + ex);
+ } catch (ClassNotFoundException ex) {
+ addInfo(receiverId + "unknown event class: " + ex);
+ } finally {
+ CloseUtil.closeQuietly(socket);
+ socket = null;
+ addInfo(receiverId + "connection closed");
}
-
- protected SocketConnector newConnector(InetAddress address, int port, int initialDelay, int retryDelay) {
- return new DefaultSocketConnector(address, port, initialDelay, retryDelay);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void connectionFailed(SocketConnector connector, Exception ex) {
+ if (ex instanceof InterruptedException) {
+ addInfo("connector interrupted");
+ } else if (ex instanceof ConnectException) {
+ addInfo(receiverId + "connection refused");
+ } else {
+ addInfo(receiverId + ex);
}
+ }
- protected SocketFactory getSocketFactory() {
- return SocketFactory.getDefault();
- }
- public void setRemoteHost(String remoteHost) {
- this.remoteHost = remoteHost;
- }
+ protected SocketConnector newConnector(InetAddress address,
+ int port, int initialDelay, int retryDelay) {
+ return new DefaultSocketConnector(address, port, initialDelay, retryDelay);
+ }
- public void setPort(int port) {
- this.port = port;
- }
+ protected SocketFactory getSocketFactory() {
+ return SocketFactory.getDefault();
+ }
- public void setReconnectionDelay(int reconnectionDelay) {
- this.reconnectionDelay = reconnectionDelay;
- }
+ public void setRemoteHost(String remoteHost) {
+ this.remoteHost = remoteHost;
+ }
- public void setAcceptConnectionTimeout(int acceptConnectionTimeout) {
- this.acceptConnectionTimeout = acceptConnectionTimeout;
- }
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public void setReconnectionDelay(int reconnectionDelay) {
+ this.reconnectionDelay = reconnectionDelay;
+ }
+
+ public void setAcceptConnectionTimeout(int acceptConnectionTimeout) {
+ this.acceptConnectionTimeout = acceptConnectionTimeout;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/SyslogAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/SyslogAppender.java
index 023455d..e358c97 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/SyslogAppender.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/SyslogAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -38,143 +38,146 @@ import ch.qos.logback.core.net.SyslogOutputStream;
*/
public class SyslogAppender extends SyslogAppenderBase<ILoggingEvent> {
- static final public String DEFAULT_SUFFIX_PATTERN = "[%thread] %logger %msg";
- static final public String DEFAULT_STACKTRACE_PATTERN = "" + CoreConstants.TAB;
-
- PatternLayout stackTraceLayout = new PatternLayout();
- String stackTracePattern = DEFAULT_STACKTRACE_PATTERN;
-
- boolean throwableExcluded = false;
-
- public void start() {
- super.start();
- setupStackTraceLayout();
- }
-
- String getPrefixPattern() {
- return "%syslogStart{" + getFacility() + "}%nopex{}";
- }
-
- @Override
- public SyslogOutputStream createOutputStream() throws SocketException, UnknownHostException {
- return new SyslogOutputStream(getSyslogHost(), getPort());
- }
-
- /**
- * Convert a level to equivalent syslog severity. Only levels for printing
- * methods i.e DEBUG, WARN, INFO and ERROR are converted.
- *
- * @see ch.qos.logback.core.net.SyslogAppenderBase#getSeverityForEvent(java.lang.Object)
- */
- @Override
- public int getSeverityForEvent(Object eventObject) {
- ILoggingEvent event = (ILoggingEvent) eventObject;
- return LevelToSyslogSeverity.convert(event);
- }
-
- @Override
- protected void postProcess(Object eventObject, OutputStream sw) {
- if (throwableExcluded)
- return;
-
- ILoggingEvent event = (ILoggingEvent) eventObject;
- IThrowableProxy tp = event.getThrowableProxy();
-
- if (tp == null)
- return;
-
- String stackTracePrefix = stackTraceLayout.doLayout(event);
- boolean isRootException = true;
- while (tp != null) {
- StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
- try {
- handleThrowableFirstLine(sw, tp, stackTracePrefix, isRootException);
- isRootException = false;
- for (StackTraceElementProxy step : stepArray) {
- StringBuilder sb = new StringBuilder();
- sb.append(stackTracePrefix).append(step);
- sw.write(sb.toString().getBytes());
- sw.flush();
- }
- } catch (IOException e) {
- break;
- }
- tp = tp.getCause();
- }
- }
-
- // LOGBACK-411 and LOGBACK-750
- private void handleThrowableFirstLine(OutputStream sw, IThrowableProxy tp, String stackTracePrefix, boolean isRootException) throws IOException {
- StringBuilder sb = new StringBuilder().append(stackTracePrefix);
-
- if (!isRootException) {
- sb.append(CoreConstants.CAUSED_BY);
- }
- sb.append(tp.getClassName()).append(": ").append(tp.getMessage());
- sw.write(sb.toString().getBytes());
- sw.flush();
- }
-
- boolean stackTraceHeaderLine(StringBuilder sb, boolean topException) {
-
- return false;
- }
-
- public Layout<ILoggingEvent> buildLayout() {
- PatternLayout layout = new PatternLayout();
- layout.getInstanceConverterMap().put("syslogStart", SyslogStartConverter.class.getName());
- if (suffixPattern == null) {
- suffixPattern = DEFAULT_SUFFIX_PATTERN;
+ static final public String DEFAULT_SUFFIX_PATTERN = "[%thread] %logger %msg";
+ static final public String DEFAULT_STACKTRACE_PATTERN = "" + CoreConstants.TAB;
+
+ PatternLayout stackTraceLayout = new PatternLayout();
+ String stackTracePattern = DEFAULT_STACKTRACE_PATTERN;
+
+ boolean throwableExcluded = false;
+
+
+ public void start() {
+ super.start();
+ setupStackTraceLayout();
+ }
+
+ String getPrefixPattern() {
+ return "%syslogStart{" + getFacility() + "}%nopex{}";
+ }
+
+ @Override
+ public SyslogOutputStream createOutputStream() throws SocketException, UnknownHostException {
+ return new SyslogOutputStream(getSyslogHost(), getPort());
+ }
+
+ /**
+ * Convert a level to equivalent syslog severity. Only levels for printing
+ * methods i.e DEBUG, WARN, INFO and ERROR are converted.
+ *
+ * @see ch.qos.logback.core.net.SyslogAppenderBase#getSeverityForEvent(java.lang.Object)
+ */
+ @Override
+ public int getSeverityForEvent(Object eventObject) {
+ ILoggingEvent event = (ILoggingEvent) eventObject;
+ return LevelToSyslogSeverity.convert(event);
+ }
+
+ @Override
+ protected void postProcess(Object eventObject, OutputStream sw) {
+ if (throwableExcluded)
+ return;
+
+ ILoggingEvent event = (ILoggingEvent) eventObject;
+ IThrowableProxy tp = event.getThrowableProxy();
+
+ if (tp == null)
+ return;
+
+ String stackTracePrefix = stackTraceLayout.doLayout(event);
+ boolean isRootException = true;
+ while (tp != null) {
+ StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
+ try {
+ handleThrowableFirstLine(sw, tp, stackTracePrefix, isRootException);
+ isRootException = false;
+ for (StackTraceElementProxy step : stepArray) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(stackTracePrefix).append(step);
+ sw.write(sb.toString().getBytes());
+ sw.flush();
}
- layout.setPattern(getPrefixPattern() + suffixPattern);
- layout.setContext(getContext());
- layout.start();
- return layout;
+ } catch (IOException e) {
+ break;
+ }
+ tp = tp.getCause();
}
+ }
- private void setupStackTraceLayout() {
- stackTraceLayout.getInstanceConverterMap().put("syslogStart", SyslogStartConverter.class.getName());
+ // LOGBACK-411 and LOGBACK-750
+ private void handleThrowableFirstLine(OutputStream sw, IThrowableProxy tp, String stackTracePrefix, boolean isRootException) throws IOException {
+ StringBuilder sb = new StringBuilder().append(stackTracePrefix);
- stackTraceLayout.setPattern(getPrefixPattern() + stackTracePattern);
- stackTraceLayout.setContext(getContext());
- stackTraceLayout.start();
+ if (!isRootException) {
+ sb.append(CoreConstants.CAUSED_BY);
}
-
- public boolean isThrowableExcluded() {
- return throwableExcluded;
- }
-
- /**
- * Setting throwableExcluded to true causes no Throwable's stack trace data to be sent to
- * the syslog daemon. By default, stack trace data is sent to syslog daemon.
- *
- * @param throwableExcluded
- * @since 1.0.4
- */
- public void setThrowableExcluded(boolean throwableExcluded) {
- this.throwableExcluded = throwableExcluded;
- }
-
- /**
- * See {@link #setStackTracePattern(String).
- *
- * @return the stackTraceSuffixPattern
- * @since 1.0.4
- */
- public String getStackTracePattern() {
- return stackTracePattern;
- }
-
- /**
- * Stack trace lines are sent to the syslog server separately from the main message
- * For stack trace lines, the stackTracePattern is used instead of {@link #suffixPattern}.
- * The <b>stackTracePattern</b> option allows specification of a separately format for the
- * non-standardized part of stack trace lines.
- *
- * @param stackTracePattern
- * @since 1.0.4
- */
- public void setStackTracePattern(String stackTracePattern) {
- this.stackTracePattern = stackTracePattern;
+ sb.append(tp.getClassName()).append(": ").append(tp.getMessage());
+ sw.write(sb.toString().getBytes());
+ sw.flush();
+ }
+
+ boolean stackTraceHeaderLine(StringBuilder sb, boolean topException) {
+
+ return false;
+ }
+
+ public Layout<ILoggingEvent> buildLayout() {
+ PatternLayout layout = new PatternLayout();
+ layout.getInstanceConverterMap().put("syslogStart",
+ SyslogStartConverter.class.getName());
+ if (suffixPattern == null) {
+ suffixPattern = DEFAULT_SUFFIX_PATTERN;
}
+ layout.setPattern(getPrefixPattern() + suffixPattern);
+ layout.setContext(getContext());
+ layout.start();
+ return layout;
+ }
+
+ private void setupStackTraceLayout() {
+ stackTraceLayout.getInstanceConverterMap().put("syslogStart",
+ SyslogStartConverter.class.getName());
+
+ stackTraceLayout.setPattern(getPrefixPattern() + stackTracePattern);
+ stackTraceLayout.setContext(getContext());
+ stackTraceLayout.start();
+ }
+
+ public boolean isThrowableExcluded() {
+ return throwableExcluded;
+ }
+
+ /**
+ * Setting throwableExcluded to true causes no Throwable's stack trace data to be sent to
+ * the syslog daemon. By default, stack trace data is sent to syslog daemon.
+ *
+ * @param throwableExcluded
+ * @since 1.0.4
+ */
+ public void setThrowableExcluded(boolean throwableExcluded) {
+ this.throwableExcluded = throwableExcluded;
+ }
+
+ /**
+ * See {@link #setStackTracePattern(String).
+ *
+ * @return the stackTraceSuffixPattern
+ * @since 1.0.4
+ */
+ public String getStackTracePattern() {
+ return stackTracePattern;
+ }
+
+ /**
+ * Stack trace lines are sent to the syslog server separately from the main message
+ * For stack trace lines, the stackTracePattern is used instead of {@link #suffixPattern}.
+ * The <b>stackTracePattern</b> option allows specification of a separately format for the
+ * non-standardized part of stack trace lines.
+ *
+ * @param stackTracePattern
+ * @since 1.0.4
+ */
+ public void setStackTracePattern(String stackTracePattern) {
+ this.stackTracePattern = stackTracePattern;
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderClient.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderClient.java
index b74b14a..79445c5 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderClient.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderClient.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,6 +17,7 @@ import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.net.server.Client;
import ch.qos.logback.core.net.server.ServerRunner;
+
/**
* A client of a {@link ServerRunner} that receives events from a remote
* appender.
@@ -25,16 +26,16 @@ import ch.qos.logback.core.net.server.ServerRunner;
*/
interface RemoteAppenderClient extends Client {
- /**
- * Sets the client's logger context.
- * <p>
- * This provides the local logging context to the client's service thread,
- * and is used as the destination for logging events received from the
- * client.
- * <p>
- * This method <em>must</em> be invoked before the {@link #run()} method.
- * @param lc the logger context to set
- */
- void setLoggerContext(LoggerContext lc);
-
+ /**
+ * Sets the client's logger context.
+ * <p>
+ * This provides the local logging context to the client's service thread,
+ * and is used as the destination for logging events received from the
+ * client.
+ * <p>
+ * This method <em>must</em> be invoked before the {@link #run()} method.
+ * @param lc the logger context to set
+ */
+ void setLoggerContext(LoggerContext lc);
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderServerListener.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderServerListener.java
index 5400538..d315ebe 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderServerListener.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderServerListener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,23 +25,25 @@ import ch.qos.logback.core.net.server.ServerSocketListener;
*
* @author Carl Harris
*/
-class RemoteAppenderServerListener extends ServerSocketListener<RemoteAppenderClient> {
+class RemoteAppenderServerListener
+ extends ServerSocketListener<RemoteAppenderClient> {
- /**
- * Constructs a new listener.
- * @param serverSocket the {@link ServerSocket} from which to accept
- * new client connections
- */
- public RemoteAppenderServerListener(ServerSocket serverSocket) {
- super(serverSocket);
- }
+ /**
+ * Constructs a new listener.
+ * @param serverSocket the {@link ServerSocket} from which to accept
+ * new client connections
+ */
+ public RemoteAppenderServerListener(ServerSocket serverSocket) {
+ super(serverSocket);
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- protected RemoteAppenderClient createClient(String id, Socket socket) throws IOException {
- return new RemoteAppenderStreamClient(id, socket);
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected RemoteAppenderClient createClient(String id, Socket socket)
+ throws IOException {
+ return new RemoteAppenderStreamClient(id, socket);
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderServerRunner.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderServerRunner.java
index b344b43..4e07536 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderServerRunner.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderServerRunner.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,26 +26,28 @@ import ch.qos.logback.core.net.server.ServerRunner;
*
* @author Carl Harris
*/
-class RemoteAppenderServerRunner extends ConcurrentServerRunner<RemoteAppenderClient> {
+class RemoteAppenderServerRunner
+ extends ConcurrentServerRunner<RemoteAppenderClient> {
- /**
- * Constructs a new server runner.
- * @param listener the listener from which the server will accept new
- * clients
- * @param executor that will be used to execute asynchronous tasks
- * on behalf of the runner.
- */
- public RemoteAppenderServerRunner(ServerListener<RemoteAppenderClient> listener, Executor executor) {
- super(listener, executor);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected boolean configureClient(RemoteAppenderClient client) {
- client.setLoggerContext((LoggerContext) getContext());
- return true;
- }
+ /**
+ * Constructs a new server runner.
+ * @param listener the listener from which the server will accept new
+ * clients
+ * @param executor that will be used to execute asynchronous tasks
+ * on behalf of the runner.
+ */
+ public RemoteAppenderServerRunner(
+ ServerListener<RemoteAppenderClient> listener, Executor executor) {
+ super(listener, executor);
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean configureClient(RemoteAppenderClient client) {
+ client.setLoggerContext((LoggerContext) getContext());
+ return true;
+ }
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderStreamClient.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderStreamClient.java
index 5be7e24..a4b34a9 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderStreamClient.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderStreamClient.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -32,107 +32,111 @@ import ch.qos.logback.core.util.CloseUtil;
*/
class RemoteAppenderStreamClient implements RemoteAppenderClient {
- private final String id;
- private final Socket socket;
- private final InputStream inputStream;
+ private final String id;
+ private final Socket socket;
+ private final InputStream inputStream;
+
+ private LoggerContext lc;
+ private Logger logger;
+
+ /**
+ * Constructs a new client.
+ * @param id a display name for the client
+ * @param inputStream input stream from which events will be read
+ */
+ public RemoteAppenderStreamClient(String id, Socket socket) {
+ this.id = id;
+ this.socket = socket;
+ this.inputStream = null;
+ }
- private LoggerContext lc;
- private Logger logger;
+ /**
+ * Constructs a new client.
+ * <p>
+ * This constructor is provided primarily to support unit tests for which
+ * it is inconvenient to create a socket.
+ *
+ * @param id a display name for the client
+ * @param inputStream input stream from which events will be read
+ */
+ public RemoteAppenderStreamClient(String id, InputStream inputStream) {
+ this.id = id;
+ this.socket = null;
+ this.inputStream = inputStream;
+ }
- /**
- * Constructs a new client.
- * @param id a display name for the client
- * @param inputStream input stream from which events will be read
- */
- public RemoteAppenderStreamClient(String id, Socket socket) {
- this.id = id;
- this.socket = socket;
- this.inputStream = null;
- }
+ /**
+ * {@inheritDoc}
+ */
+ public void setLoggerContext(LoggerContext lc) {
+ this.lc = lc;
+ this.logger = lc.getLogger(getClass().getPackage().getName());
+ }
- /**
- * Constructs a new client.
- * <p>
- * This constructor is provided primarily to support unit tests for which
- * it is inconvenient to create a socket.
- *
- * @param id a display name for the client
- * @param inputStream input stream from which events will be read
- */
- public RemoteAppenderStreamClient(String id, InputStream inputStream) {
- this.id = id;
- this.socket = null;
- this.inputStream = inputStream;
- }
+ /**
+ * {@inheritDoc}
+ */
+ public void close() {
+ if (socket == null) return;
+ CloseUtil.closeQuietly(socket);
+ }
- /**
- * {@inheritDoc}
- */
- public void setLoggerContext(LoggerContext lc) {
- this.lc = lc;
- this.logger = lc.getLogger(getClass().getPackage().getName());
+ /**
+ * {@inheritDoc}
+ */
+ public void run() {
+ logger.info(this + ": connected");
+ ObjectInputStream ois = null;
+ try {
+ ois = createObjectInputStream();
+ while (true) {
+ // read an event from the wire
+ ILoggingEvent event = (ILoggingEvent) ois.readObject();
+ // get a logger from the hierarchy. The name of the logger is taken to
+ // be the name contained in the event.
+ Logger remoteLogger = lc.getLogger(event.getLoggerName());
+ // apply the logger-level filter
+ if (remoteLogger.isEnabledFor(event.getLevel())) {
+ // finally log the event as if was generated locally
+ remoteLogger.callAppenders(event);
+ }
+ }
}
-
- /**
- * {@inheritDoc}
- */
- public void close() {
- if (socket == null)
- return;
- CloseUtil.closeQuietly(socket);
+ catch (EOFException ex) {
+ // this is normal and expected
+ assert true;
}
-
- /**
- * {@inheritDoc}
- */
- public void run() {
- logger.info(this + ": connected");
- ObjectInputStream ois = null;
- try {
- ois = createObjectInputStream();
- while (true) {
- // read an event from the wire
- ILoggingEvent event = (ILoggingEvent) ois.readObject();
- // get a logger from the hierarchy. The name of the logger is taken to
- // be the name contained in the event.
- Logger remoteLogger = lc.getLogger(event.getLoggerName());
- // apply the logger-level filter
- if (remoteLogger.isEnabledFor(event.getLevel())) {
- // finally log the event as if was generated locally
- remoteLogger.callAppenders(event);
- }
- }
- } catch (EOFException ex) {
- // this is normal and expected
- assert true;
- } catch (IOException ex) {
- logger.info(this + ": " + ex);
- } catch (ClassNotFoundException ex) {
- logger.error(this + ": unknown event class");
- } catch (RuntimeException ex) {
- logger.error(this + ": " + ex);
- } finally {
- if (ois != null) {
- CloseUtil.closeQuietly(ois);
- }
- close();
- logger.info(this + ": connection closed");
- }
+ catch (IOException ex) {
+ logger.info(this + ": " + ex);
}
-
- private ObjectInputStream createObjectInputStream() throws IOException {
- if (inputStream != null) {
- return new ObjectInputStream(inputStream);
- }
- return new ObjectInputStream(socket.getInputStream());
+ catch (ClassNotFoundException ex) {
+ logger.error(this + ": unknown event class");
+ }
+ catch (RuntimeException ex) {
+ logger.error(this + ": " + ex);
+ }
+ finally {
+ if (ois != null) {
+ CloseUtil.closeQuietly(ois);
+ }
+ close();
+ logger.info(this + ": connection closed");
}
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- return "client " + id;
+ private ObjectInputStream createObjectInputStream() throws IOException {
+ if (inputStream != null) {
+ return new ObjectInputStream(inputStream);
}
+ return new ObjectInputStream(socket.getInputStream());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "client " + id;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/SSLServerSocketAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/SSLServerSocketAppender.java
index 0c78dad..90ea2b5 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/SSLServerSocketAppender.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/SSLServerSocketAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,30 +23,32 @@ import ch.qos.logback.core.spi.PreSerializationTransformer;
*
* @author Carl Harris
*/
-public class SSLServerSocketAppender extends SSLServerSocketAppenderBase<ILoggingEvent> {
-
- private static final PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer();
-
- private boolean includeCallerData;
-
- @Override
- protected void postProcessEvent(ILoggingEvent event) {
- if (isIncludeCallerData()) {
- event.getCallerData();
- }
+public class SSLServerSocketAppender
+ extends SSLServerSocketAppenderBase<ILoggingEvent> {
+
+ private static final PreSerializationTransformer<ILoggingEvent> pst =
+ new LoggingEventPreSerializationTransformer();
+
+ private boolean includeCallerData;
+
+ @Override
+ protected void postProcessEvent(ILoggingEvent event) {
+ if (isIncludeCallerData()) {
+ event.getCallerData();
}
+ }
- @Override
- protected PreSerializationTransformer<ILoggingEvent> getPST() {
- return pst;
- }
+ @Override
+ protected PreSerializationTransformer<ILoggingEvent> getPST() {
+ return pst;
+ }
- public boolean isIncludeCallerData() {
- return includeCallerData;
- }
+ public boolean isIncludeCallerData() {
+ return includeCallerData;
+ }
- public void setIncludeCallerData(boolean includeCallerData) {
- this.includeCallerData = includeCallerData;
- }
+ public void setIncludeCallerData(boolean includeCallerData) {
+ this.includeCallerData = includeCallerData;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/SSLServerSocketReceiver.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/SSLServerSocketReceiver.java
index 5b10791..c9a580c 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/SSLServerSocketReceiver.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/SSLServerSocketReceiver.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,43 +26,45 @@ import ch.qos.logback.core.net.ssl.SSLParametersConfiguration;
*
* @author Carl Harris
*/
-public class SSLServerSocketReceiver extends ServerSocketReceiver implements SSLComponent {
+public class SSLServerSocketReceiver extends ServerSocketReceiver
+ implements SSLComponent {
- private SSLConfiguration ssl;
- private ServerSocketFactory socketFactory;
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected ServerSocketFactory getServerSocketFactory() throws Exception {
- if (socketFactory == null) {
- SSLContext sslContext = getSsl().createContext(this);
- SSLParametersConfiguration parameters = getSsl().getParameters();
- parameters.setContext(getContext());
- socketFactory = new ConfigurableSSLServerSocketFactory(parameters, sslContext.getServerSocketFactory());
- }
- return socketFactory;
+ private SSLConfiguration ssl;
+ private ServerSocketFactory socketFactory;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected ServerSocketFactory getServerSocketFactory() throws Exception {
+ if (socketFactory == null) {
+ SSLContext sslContext = getSsl().createContext(this);
+ SSLParametersConfiguration parameters = getSsl().getParameters();
+ parameters.setContext(getContext());
+ socketFactory = new ConfigurableSSLServerSocketFactory(
+ parameters, sslContext.getServerSocketFactory());
}
+ return socketFactory;
+ }
- /**
- * Gets the server's SSL configuration.
- * @return SSL configuration; if no SSL configuration was provided
- * a default configuration is returned
- */
- public SSLConfiguration getSsl() {
- if (ssl == null) {
- ssl = new SSLConfiguration();
- }
- return ssl;
+ /**
+ * Gets the server's SSL configuration.
+ * @return SSL configuration; if no SSL configuration was provided
+ * a default configuration is returned
+ */
+ public SSLConfiguration getSsl() {
+ if (ssl == null) {
+ ssl = new SSLConfiguration();
}
+ return ssl;
+ }
- /**
- * Gets the server's SSL configuration.
- * @param ssl the SSL configuration to set.
- */
- public void setSsl(SSLConfiguration ssl) {
- this.ssl = ssl;
- }
+ /**
+ * Gets the server's SSL configuration.
+ * @param ssl the SSL configuration to set.
+ */
+ public void setSsl(SSLConfiguration ssl) {
+ this.ssl = ssl;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/ServerSocketAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/ServerSocketAppender.java
index b465be4..7e256c1 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/ServerSocketAppender.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/ServerSocketAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,30 +25,32 @@ import ch.qos.logback.core.spi.PreSerializationTransformer;
*
* @author Carl Harris
*/
-public class ServerSocketAppender extends AbstractServerSocketAppender<ILoggingEvent> {
-
- private static final PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer();
-
- private boolean includeCallerData;
-
- @Override
- protected void postProcessEvent(ILoggingEvent event) {
- if (isIncludeCallerData()) {
- event.getCallerData();
- }
+public class ServerSocketAppender
+ extends AbstractServerSocketAppender<ILoggingEvent> {
+
+ private static final PreSerializationTransformer<ILoggingEvent> pst =
+ new LoggingEventPreSerializationTransformer();
+
+ private boolean includeCallerData;
+
+ @Override
+ protected void postProcessEvent(ILoggingEvent event) {
+ if (isIncludeCallerData()) {
+ event.getCallerData();
}
+ }
- @Override
- protected PreSerializationTransformer<ILoggingEvent> getPST() {
- return pst;
- }
+ @Override
+ protected PreSerializationTransformer<ILoggingEvent> getPST() {
+ return pst;
+ }
- public boolean isIncludeCallerData() {
- return includeCallerData;
- }
+ public boolean isIncludeCallerData() {
+ return includeCallerData;
+ }
- public void setIncludeCallerData(boolean includeCallerData) {
- this.includeCallerData = includeCallerData;
- }
+ public void setIncludeCallerData(boolean includeCallerData) {
+ this.includeCallerData = includeCallerData;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/ServerSocketReceiver.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/ServerSocketReceiver.java
index 5ca891f..d90b277 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/ServerSocketReceiver.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/ServerSocketReceiver.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -33,141 +33,146 @@ import ch.qos.logback.core.util.CloseUtil;
* @author Carl Harris
*/
public class ServerSocketReceiver extends ReceiverBase {
-
- /**
- * Default {@link ServerSocket} backlog
- */
- public static final int DEFAULT_BACKLOG = 50;
-
- private int port = AbstractSocketAppender.DEFAULT_PORT;
- private int backlog = DEFAULT_BACKLOG;
-
- private String address;
-
- private ServerSocket serverSocket;
- private ServerRunner runner;
-
- /**
- * Starts the server.
- */
- protected boolean shouldStart() {
- try {
- ServerSocket serverSocket = getServerSocketFactory().createServerSocket(getPort(), getBacklog(), getInetAddress());
-
- ServerListener<RemoteAppenderClient> listener = createServerListener(serverSocket);
-
- runner = createServerRunner(listener, getContext().getExecutorService());
- runner.setContext(getContext());
- return true;
- } catch (Exception ex) {
- addError("server startup error: " + ex, ex);
- CloseUtil.closeQuietly(serverSocket);
- return false;
- }
- }
-
- protected ServerListener<RemoteAppenderClient> createServerListener(ServerSocket socket) {
- return new RemoteAppenderServerListener(socket);
- }
-
- protected ServerRunner createServerRunner(ServerListener<RemoteAppenderClient> listener, Executor executor) {
- return new RemoteAppenderServerRunner(listener, executor);
- }
-
- @Override
- protected Runnable getRunnableTask() {
- return runner;
- }
-
- /**
- * {@inheritDoc}
- */
- protected void onStop() {
- try {
- if (runner == null)
- return;
- runner.stop();
- } catch (IOException ex) {
- addError("server shutdown error: " + ex, ex);
- }
- }
-
- /**
- * Gets the server socket factory.
- * <p>
- * Subclasses may override to provide a custom factory.
- * @return server socket factory
- * @throws Exception
- */
- protected ServerSocketFactory getServerSocketFactory() throws Exception {
- return ServerSocketFactory.getDefault();
- }
-
- /**
- * Gets the local address for the listener.
- * @return an {@link InetAddress} representation of the local address.
- * @throws UnknownHostException
- */
- protected InetAddress getInetAddress() throws UnknownHostException {
- if (getAddress() == null)
- return null;
- return InetAddress.getByName(getAddress());
- }
-
- /**
- * Gets the local port for the listener.
- * @return local port
- */
- public int getPort() {
- return port;
+
+ /**
+ * Default {@link ServerSocket} backlog
+ */
+ public static final int DEFAULT_BACKLOG = 50;
+
+ private int port = AbstractSocketAppender.DEFAULT_PORT;
+ private int backlog = DEFAULT_BACKLOG;
+
+ private String address;
+
+ private ServerSocket serverSocket;
+ private ServerRunner runner;
+
+ /**
+ * Starts the server.
+ */
+ protected boolean shouldStart() {
+ try {
+ ServerSocket serverSocket = getServerSocketFactory().createServerSocket(
+ getPort(), getBacklog(), getInetAddress());
+
+ ServerListener<RemoteAppenderClient> listener =
+ createServerListener(serverSocket);
+
+ runner = createServerRunner(listener, getContext().getExecutorService());
+ runner.setContext(getContext());
+ return true;
}
-
- /**
- * Sets the local port for the listener.
- * @param port the local port to set
- */
- public void setPort(int port) {
- this.port = port;
- }
-
- /**
- * Gets the listener queue depth.
- * <p>
- * This represents the number of connected clients whose connections
- * have not yet been accepted.
- * @return queue depth
- * @see java.net.ServerSocket
- */
- public int getBacklog() {
- return backlog;
+ catch (Exception ex) {
+ addError("server startup error: " + ex, ex);
+ CloseUtil.closeQuietly(serverSocket);
+ return false;
}
-
- /**
- * Sets the listener queue depth.
- * <p>
- * This represents the number of connected clients whose connections
- * have not yet been accepted.
- * @param backlog the queue depth to set
- * @see java.net.ServerSocket
- */
- public void setBacklog(int backlog) {
- this.backlog = backlog;
+ }
+
+ protected ServerListener<RemoteAppenderClient> createServerListener(
+ ServerSocket socket) {
+ return new RemoteAppenderServerListener(socket);
+ }
+
+ protected ServerRunner createServerRunner(
+ ServerListener<RemoteAppenderClient> listener,
+ Executor executor) {
+ return new RemoteAppenderServerRunner(listener, executor);
+ }
+
+ @Override
+ protected Runnable getRunnableTask() {
+ return runner;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void onStop() {
+ try {
+ if (runner == null) return;
+ runner.stop();
}
-
- /**
- * Gets the local address for the listener.
- * @return a string representation of the local address
- */
- public String getAddress() {
- return address;
- }
-
- /**
- * Sets the local address for the listener.
- * @param address a host name or a string representation of an IP address
- */
- public void setAddress(String address) {
- this.address = address;
+ catch (IOException ex) {
+ addError("server shutdown error: " + ex, ex);
}
+ }
+
+ /**
+ * Gets the server socket factory.
+ * <p>
+ * Subclasses may override to provide a custom factory.
+ * @return server socket factory
+ * @throws Exception
+ */
+ protected ServerSocketFactory getServerSocketFactory() throws Exception {
+ return ServerSocketFactory.getDefault();
+ }
+
+ /**
+ * Gets the local address for the listener.
+ * @return an {@link InetAddress} representation of the local address.
+ * @throws UnknownHostException
+ */
+ protected InetAddress getInetAddress() throws UnknownHostException {
+ if (getAddress() == null) return null;
+ return InetAddress.getByName(getAddress());
+ }
+
+ /**
+ * Gets the local port for the listener.
+ * @return local port
+ */
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * Sets the local port for the listener.
+ * @param port the local port to set
+ */
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ /**
+ * Gets the listener queue depth.
+ * <p>
+ * This represents the number of connected clients whose connections
+ * have not yet been accepted.
+ * @return queue depth
+ * @see java.net.ServerSocket
+ */
+ public int getBacklog() {
+ return backlog;
+ }
+
+ /**
+ * Sets the listener queue depth.
+ * <p>
+ * This represents the number of connected clients whose connections
+ * have not yet been accepted.
+ * @param backlog the queue depth to set
+ * @see java.net.ServerSocket
+ */
+ public void setBacklog(int backlog) {
+ this.backlog = backlog;
+ }
+
+ /**
+ * Gets the local address for the listener.
+ * @return a string representation of the local address
+ */
+ public String getAddress() {
+ return address;
+ }
+
+ /**
+ * Sets the local address for the listener.
+ * @param address a host name or a string representation of an IP address
+ */
+ public void setAddress(String address) {
+ this.address = address;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Abbreviator.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Abbreviator.java
index e73a973..5591453 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Abbreviator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Abbreviator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,5 +20,5 @@ package ch.qos.logback.classic.pattern;
*/
public interface Abbreviator {
- String abbreviate(String in);
+ String abbreviate(String in);
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/CallerDataConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/CallerDataConverter.java
index 669fc29..c6da9e7 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/CallerDataConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/CallerDataConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,7 +17,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import static java.util.regex.Pattern.quote;
import ch.qos.logback.classic.spi.CallerData;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Context;
@@ -27,141 +26,114 @@ import ch.qos.logback.core.boolex.EventEvaluator;
import ch.qos.logback.core.status.ErrorStatus;
/**
- * This converter outputs caller data depending on depth or depth range and marker data.
+ * This converter outputs caller data depending on depth and marker data.
*
* @author Ceki Gulcu
*/
public class CallerDataConverter extends ClassicConverter {
- public static final String DEFAULT_CALLER_LINE_PREFIX = "Caller+";
+ public static final String DEFAULT_CALLER_LINE_PREFIX = "Caller+";
- public static final String DEFAULT_RANGE_DELIMITER = "..";
+ int depth = 5;
+ List<EventEvaluator<ILoggingEvent>> evaluatorList = null;
- private int depthStart = 0;
- private int depthEnd = 5;
- List<EventEvaluator<ILoggingEvent>> evaluatorList = null;
- final int MAX_ERROR_COUNT = 4;
- int errorCount = 0;
+ final int MAX_ERROR_COUNT = 4;
+ int errorCount = 0;
- @SuppressWarnings("unchecked")
- public void start() {
- String depthStr = getFirstOption();
- if (depthStr == null) {
- return;
- }
-
- try {
- if (isRange(depthStr)) {
- String[] numbers = splitRange(depthStr);
- if (numbers.length == 2) {
- depthStart = Integer.parseInt(numbers[0]);
- depthEnd = Integer.parseInt(numbers[1]);
- checkRange();
- } else {
- addError("Failed to parse depth option as range [" + depthStr + "]");
- }
- } else {
- depthEnd = Integer.parseInt(depthStr);
- }
- } catch (NumberFormatException nfe) {
- addError("Failed to parse depth option [" + depthStr + "]", nfe);
- }
-
- final List<String> optionList = getOptionList();
-
- if (optionList != null && optionList.size() > 1) {
- final int optionListSize = optionList.size();
- for (int i = 1; i < optionListSize; i++) {
- String evaluatorStr = optionList.get(i);
- Context context = getContext();
- if (context != null) {
- Map<String, EventEvaluator<?>> evaluatorMap = (Map<String, EventEvaluator<?>>) context.getObject(CoreConstants.EVALUATOR_MAP);
- EventEvaluator<ILoggingEvent> ee = (EventEvaluator<ILoggingEvent>) evaluatorMap.get(evaluatorStr);
- if (ee != null) {
- addEvaluator(ee);
- }
- }
- }
- }
- }
-
- private boolean isRange(String depthStr) {
- return depthStr.contains(getDefaultRangeDelimiter());
+ @SuppressWarnings("unchecked")
+ public void start() {
+ String depthStr = getFirstOption();
+ if (depthStr == null) {
+ return;
}
- private String[] splitRange(String depthStr) {
- return depthStr.split(quote(getDefaultRangeDelimiter()), 2);
+ try {
+ depth = Integer.parseInt(depthStr);
+ } catch (NumberFormatException nfe) {
+ addError("Failed to parse depth option [" + depthStr + "]", nfe);
}
- private void checkRange() {
- if (depthStart < 0 || depthEnd < 0) {
- addError("Invalid depthStart/depthEnd range [" + depthStart + ", " + depthEnd + "] (negative values are not allowed)");
- } else if (depthStart >= depthEnd) {
- addError("Invalid depthEnd range [" + depthStart + ", " + depthEnd + "] (start greater or equal to end)");
+ final List optionList = getOptionList();
+
+ if (optionList != null && optionList.size() > 1) {
+ final int optionListSize = optionList.size();
+ for (int i = 1; i < optionListSize; i++) {
+ String evaluatorStr = (String) optionList.get(i);
+ Context context = getContext();
+ if (context != null) {
+ Map evaluatorMap = (Map) context
+ .getObject(CoreConstants.EVALUATOR_MAP);
+ EventEvaluator<ILoggingEvent> ee = (EventEvaluator<ILoggingEvent>) evaluatorMap
+ .get(evaluatorStr);
+ if (ee != null) {
+ addEvaluator(ee);
+ }
}
+ }
}
+ }
- private void addEvaluator(EventEvaluator<ILoggingEvent> ee) {
- if (evaluatorList == null) {
- evaluatorList = new ArrayList<EventEvaluator<ILoggingEvent>>();
- }
- evaluatorList.add(ee);
+ private void addEvaluator(EventEvaluator<ILoggingEvent> ee) {
+ if (evaluatorList == null) {
+ evaluatorList = new ArrayList<EventEvaluator<ILoggingEvent>>();
}
+ evaluatorList.add(ee);
+ }
- public String convert(ILoggingEvent le) {
- StringBuilder buf = new StringBuilder();
-
- if (evaluatorList != null) {
- boolean printCallerData = false;
- for (int i = 0; i < evaluatorList.size(); i++) {
- EventEvaluator<ILoggingEvent> ee = evaluatorList.get(i);
- try {
- if (ee.evaluate(le)) {
- printCallerData = true;
- break;
- }
- } catch (EvaluationException eex) {
- errorCount++;
- if (errorCount < MAX_ERROR_COUNT) {
- addError("Exception thrown for evaluator named [" + ee.getName() + "]", eex);
- } else if (errorCount == MAX_ERROR_COUNT) {
- ErrorStatus errorStatus = new ErrorStatus("Exception thrown for evaluator named [" + ee.getName() + "].", this, eex);
- errorStatus.add(new ErrorStatus("This was the last warning about this evaluator's errors."
- + "We don't want the StatusManager to get flooded.", this));
- addStatus(errorStatus);
- }
-
- }
- }
-
- if (!printCallerData) {
- return CoreConstants.EMPTY_STRING;
- }
- }
+ public String convert(ILoggingEvent le) {
+ StringBuilder buf = new StringBuilder();
+
+ if (evaluatorList != null) {
+ boolean printCallerData = false;
+ for (int i = 0; i < evaluatorList.size(); i++) {
+ EventEvaluator<ILoggingEvent> ee = evaluatorList.get(i);
+ try {
+ if (ee.evaluate(le)) {
+ printCallerData = true;
+ break;
+ }
+ } catch (EvaluationException eex) {
+ errorCount++;
+ if (errorCount < MAX_ERROR_COUNT) {
+ addError("Exception thrown for evaluator named [" + ee.getName()
+ + "]", eex);
+ } else if (errorCount == MAX_ERROR_COUNT) {
+ ErrorStatus errorStatus = new ErrorStatus(
+ "Exception thrown for evaluator named [" + ee.getName() + "].",
+ this, eex);
+ errorStatus.add(new ErrorStatus(
+ "This was the last warning about this evaluator's errors."
+ + "We don't want the StatusManager to get flooded.", this));
+ addStatus(errorStatus);
+ }
- StackTraceElement[] cda = le.getCallerData();
- if (cda != null && cda.length > depthStart) {
- int limit = depthEnd < cda.length ? depthEnd : cda.length;
-
- for (int i = depthStart; i < limit; i++) {
- buf.append(getCallerLinePrefix());
- buf.append(i);
- buf.append("\t at ");
- buf.append(cda[i]);
- buf.append(CoreConstants.LINE_SEPARATOR);
- }
- return buf.toString();
- } else {
- return CallerData.CALLER_DATA_NA;
}
- }
+ }
- protected String getCallerLinePrefix() {
- return DEFAULT_CALLER_LINE_PREFIX;
+ if (!printCallerData) {
+ return CoreConstants.EMPTY_STRING;
+ }
}
- protected String getDefaultRangeDelimiter() {
- return DEFAULT_RANGE_DELIMITER;
+ StackTraceElement[] cda = le.getCallerData();
+ if (cda != null && cda.length > 0) {
+ int limit = depth < cda.length ? depth : cda.length;
+
+ for (int i = 0; i < limit; i++) {
+ buf.append(getCallerLinePrefix());
+ buf.append(i);
+ buf.append("\t at ");
+ buf.append(cda[i]);
+ buf.append(CoreConstants.LINE_SEPARATOR);
+ }
+ return buf.toString();
+ } else {
+ return CallerData.CALLER_DATA_NA;
}
+ }
+
+ protected String getCallerLinePrefix() {
+ return DEFAULT_CALLER_LINE_PREFIX;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ClassNameOnlyAbbreviator.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ClassNameOnlyAbbreviator.java
index 2f647c5..b65ff84 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ClassNameOnlyAbbreviator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ClassNameOnlyAbbreviator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,15 +23,15 @@ import ch.qos.logback.core.CoreConstants;
*/
public class ClassNameOnlyAbbreviator implements Abbreviator {
- public String abbreviate(String fqClassName) {
- // we ignore the fact that the separator character can also be a dollar
- // If the inner class is org.good.AClass#Inner, returning
- // AClass#Inner seems most appropriate
- int lastIndex = fqClassName.lastIndexOf(CoreConstants.DOT);
- if (lastIndex != -1) {
- return fqClassName.substring(lastIndex + 1, fqClassName.length());
- } else {
- return fqClassName;
- }
+ public String abbreviate(String fqClassName) {
+ // we ignore the fact that the separator character can also be a dollar
+ // If the inner class is org.good.AClass#Inner, returning
+ // AClass#Inner seems most appropriate
+ int lastIndex = fqClassName.lastIndexOf(CoreConstants.DOT);
+ if (lastIndex != -1) {
+ return fqClassName.substring(lastIndex + 1, fqClassName.length());
+ } else {
+ return fqClassName;
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ClassOfCallerConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ClassOfCallerConverter.java
index 130bb80..d948d88 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ClassOfCallerConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ClassOfCallerConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,13 +18,13 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
public class ClassOfCallerConverter extends NamedConverter {
- protected String getFullyQualifiedName(ILoggingEvent event) {
-
- StackTraceElement[] cda = event.getCallerData();
- if (cda != null && cda.length > 0) {
- return cda[0].getClassName();
- } else {
- return CallerData.NA;
- }
+ protected String getFullyQualifiedName(ILoggingEvent event) {
+
+ StackTraceElement[] cda = event.getCallerData();
+ if (cda != null && cda.length > 0) {
+ return cda[0].getClassName();
+ } else {
+ return CallerData.NA;
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ClassicConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ClassicConverter.java
index c02a76e..8610e7d 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ClassicConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ClassicConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,6 +22,6 @@ import ch.qos.logback.core.pattern.DynamicConverter;
*
* @author Ceki Gulcu
*/
-abstract public class ClassicConverter extends DynamicConverter<ILoggingEvent> {
+abstract public class ClassicConverter extends DynamicConverter<ILoggingEvent> {
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ContextNameConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ContextNameConverter.java
index bfe4482..c7f1866 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ContextNameConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ContextNameConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,11 +22,11 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
*/
public class ContextNameConverter extends ClassicConverter {
- /**
- * Return the name of the logger context's name.
- */
- public String convert(ILoggingEvent event) {
- return event.getLoggerContextVO().getName();
- }
+ /**
+ * Return the name of the logger context's name.
+ */
+ public String convert(ILoggingEvent event) {
+ return event.getLoggerContextVO().getName();
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/DateConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/DateConverter.java
index e1c803d..af70f05 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/DateConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/DateConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,42 +22,44 @@ import ch.qos.logback.core.util.CachingDateFormatter;
public class DateConverter extends ClassicConverter {
- long lastTimestamp = -1;
- String timestampStrCache = null;
- CachingDateFormatter cachingDateFormatter = null;
-
- public void start() {
-
- String datePattern = getFirstOption();
- if (datePattern == null) {
- datePattern = CoreConstants.ISO8601_PATTERN;
- }
-
- if (datePattern.equals(CoreConstants.ISO8601_STR)) {
- datePattern = CoreConstants.ISO8601_PATTERN;
- }
-
- try {
- cachingDateFormatter = new CachingDateFormatter(datePattern);
- // maximumCacheValidity =
- // CachedDateFormat.getMaximumCacheValidity(pattern);
- } catch (IllegalArgumentException e) {
- addWarn("Could not instantiate SimpleDateFormat with pattern " + datePattern, e);
- // default to the ISO8601 format
- cachingDateFormatter = new CachingDateFormatter(CoreConstants.ISO8601_PATTERN);
- }
-
- List optionList = getOptionList();
-
- // if the option list contains a TZ option, then set it.
- if (optionList != null && optionList.size() > 1) {
- TimeZone tz = TimeZone.getTimeZone((String) optionList.get(1));
- cachingDateFormatter.setTimeZone(tz);
- }
+ long lastTimestamp = -1;
+ String timestampStrCache = null;
+ CachingDateFormatter cachingDateFormatter = null;
+
+ public void start() {
+
+
+ String datePattern = getFirstOption();
+ if (datePattern == null) {
+ datePattern = CoreConstants.ISO8601_PATTERN;
+ }
+
+ if (datePattern.equals(CoreConstants.ISO8601_STR)) {
+ datePattern = CoreConstants.ISO8601_PATTERN;
}
- public String convert(ILoggingEvent le) {
- long timestamp = le.getTimeStamp();
- return cachingDateFormatter.format(timestamp);
+ try {
+ cachingDateFormatter = new CachingDateFormatter(datePattern);
+ // maximumCacheValidity =
+ // CachedDateFormat.getMaximumCacheValidity(pattern);
+ } catch (IllegalArgumentException e) {
+ addWarn("Could not instantiate SimpleDateFormat with pattern "
+ + datePattern, e);
+ // default to the ISO8601 format
+ cachingDateFormatter = new CachingDateFormatter(CoreConstants.ISO8601_PATTERN);
}
+
+ List optionList = getOptionList();
+
+ // if the option list contains a TZ option, then set it.
+ if (optionList != null && optionList.size() > 1) {
+ TimeZone tz = TimeZone.getTimeZone((String) optionList.get(1));
+ cachingDateFormatter.setTimeZone(tz);
+ }
+ }
+
+ public String convert(ILoggingEvent le) {
+ long timestamp = le.getTimeStamp();
+ return cachingDateFormatter.format(timestamp);
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/EnsureExceptionHandling.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/EnsureExceptionHandling.java
index b361fda..68a1fec 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/EnsureExceptionHandling.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/EnsureExceptionHandling.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,64 +13,57 @@
*/
package ch.qos.logback.classic.pattern;
-import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.Context;
import ch.qos.logback.core.pattern.Converter;
import ch.qos.logback.core.pattern.ConverterUtil;
import ch.qos.logback.core.pattern.PostCompileProcessor;
-public class EnsureExceptionHandling implements PostCompileProcessor<ILoggingEvent> {
+public class EnsureExceptionHandling implements
+ PostCompileProcessor<ILoggingEvent> {
- /**
- * This implementation checks if any of the converters in the chain handles
- * exceptions. If not, then this method adds a
- * {@link ExtendedThrowableProxyConverter} instance to the end of the chain.
- * <p>
- * This allows appenders using this layout to output exception information
- * event if the user forgets to add %ex to the pattern. Note that the
- * appenders defined in the Core package are not aware of exceptions nor
- * LoggingEvents.
- * <p>
- * If for some reason the user wishes to NOT print exceptions, then she can
- * add %nopex to the pattern.
- *
- *
- */
- public void process(Context context, Converter<ILoggingEvent> head) {
- if (head == null) {
- // this should never happen
- throw new IllegalArgumentException("cannot process empty chain");
- }
- if (!chainHandlesThrowable(head)) {
- Converter<ILoggingEvent> tail = ConverterUtil.findTail(head);
- Converter<ILoggingEvent> exConverter = null;
- LoggerContext loggerContext = (LoggerContext) context;
- if (loggerContext.isPackagingDataEnabled()) {
- exConverter = new ExtendedThrowableProxyConverter();
- } else {
- exConverter = new ThrowableProxyConverter();
- }
- tail.setNext(exConverter);
- }
+ /**
+ * This implementation checks if any of the converters in the chain handles
+ * exceptions. If not, then this method adds a
+ * {@link ExtendedThrowableProxyConverter} instance to the end of the chain.
+ * <p>
+ * This allows appenders using this layout to output exception information
+ * event if the user forgets to add %ex to the pattern. Note that the
+ * appenders defined in the Core package are not aware of exceptions nor
+ * LoggingEvents.
+ * <p>
+ * If for some reason the user wishes to NOT print exceptions, then she can
+ * add %nopex to the pattern.
+ *
+ *
+ */
+ public void process(Converter<ILoggingEvent> head) {
+ if(head == null) {
+ // this should never happen
+ throw new IllegalArgumentException("cannot process empty chain");
}
+ if (!chainHandlesThrowable(head)) {
+ Converter<ILoggingEvent> tail = ConverterUtil.findTail(head);
+ Converter<ILoggingEvent> exConverter = new ExtendedThrowableProxyConverter();
+ tail.setNext(exConverter);
+ }
+ }
- /**
- * This method computes whether a chain of converters handles exceptions or
- * not.
- *
- * @param head
- * The first element of the chain
- * @return true if can handle throwables contained in logging events
- */
- public boolean chainHandlesThrowable(Converter<ILoggingEvent> head) {
- Converter<ILoggingEvent> c = head;
- while (c != null) {
- if (c instanceof ThrowableHandlingConverter) {
- return true;
- }
- c = c.getNext();
- }
- return false;
+ /**
+ * This method computes whether a chain of converters handles exceptions or
+ * not.
+ *
+ * @param head
+ * The first element of the chain
+ * @return true if can handle throwables contained in logging events
+ */
+ public boolean chainHandlesThrowable(Converter head) {
+ Converter c = head;
+ while (c != null) {
+ if (c instanceof ThrowableHandlingConverter) {
+ return true;
+ }
+ c = c.getNext();
}
+ return false;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ExtendedThrowableProxyConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ExtendedThrowableProxyConverter.java
index 2afca9d..2e595cd 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ExtendedThrowableProxyConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ExtendedThrowableProxyConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,13 +19,13 @@ import ch.qos.logback.classic.spi.ThrowableProxyUtil;
public class ExtendedThrowableProxyConverter extends ThrowableProxyConverter {
- @Override
- protected void extraData(StringBuilder builder, StackTraceElementProxy step) {
- ThrowableProxyUtil.subjoinPackagingData(builder, step);
- }
+ @Override
+ protected void extraData(StringBuilder builder, StackTraceElementProxy step) {
+ ThrowableProxyUtil.subjoinPackagingData(builder, step);
+ }
- protected void prepareLoggingEvent(ILoggingEvent event) {
-
- }
+ protected void prepareLoggingEvent(ILoggingEvent event) {
+
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/FileOfCallerConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/FileOfCallerConverter.java
index 04a2dfa..8ed3e78 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/FileOfCallerConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/FileOfCallerConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,13 +18,13 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
public class FileOfCallerConverter extends ClassicConverter {
- public String convert(ILoggingEvent le) {
- StackTraceElement[] cda = le.getCallerData();
- if (cda != null && cda.length > 0) {
- return cda[0].getFileName();
- } else {
- return CallerData.NA;
- }
+ public String convert(ILoggingEvent le) {
+ StackTraceElement[] cda = le.getCallerData();
+ if (cda != null && cda.length > 0) {
+ return cda[0].getFileName();
+ } else {
+ return CallerData.NA;
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LevelConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LevelConverter.java
index 0087353..2d48267 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LevelConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LevelConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,8 +22,8 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
*/
public class LevelConverter extends ClassicConverter {
- public String convert(ILoggingEvent le) {
- return le.getLevel().toString();
- }
+ public String convert(ILoggingEvent le) {
+ return le.getLevel().toString();
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LineOfCallerConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LineOfCallerConverter.java
index 06ce2ec..bbad5f6 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LineOfCallerConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LineOfCallerConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,13 +18,13 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
public class LineOfCallerConverter extends ClassicConverter {
- public String convert(ILoggingEvent le) {
- StackTraceElement[] cda = le.getCallerData();
- if (cda != null && cda.length > 0) {
- return Integer.toString(cda[0].getLineNumber());
- } else {
- return CallerData.NA;
- }
+ public String convert(ILoggingEvent le) {
+ StackTraceElement[] cda = le.getCallerData();
+ if (cda != null && cda.length > 0) {
+ return Integer.toString(cda[0].getLineNumber());
+ } else {
+ return CallerData.NA;
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LineSeparatorConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LineSeparatorConverter.java
index cd6b606..5b059ee 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LineSeparatorConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LineSeparatorConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,8 +18,8 @@ import ch.qos.logback.core.CoreConstants;
public class LineSeparatorConverter extends ClassicConverter {
- public String convert(ILoggingEvent event) {
- return CoreConstants.LINE_SEPARATOR;
- }
+ public String convert(ILoggingEvent event) {
+ return CoreConstants.LINE_SEPARATOR;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LocalSequenceNumberConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LocalSequenceNumberConverter.java
index 8789fe3..d0307df 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LocalSequenceNumberConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LocalSequenceNumberConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,10 +27,10 @@ import java.util.concurrent.atomic.AtomicLong;
*/
public class LocalSequenceNumberConverter extends ClassicConverter {
- AtomicLong sequenceNumber = new AtomicLong(System.currentTimeMillis());
+ AtomicLong sequenceNumber = new AtomicLong(System.currentTimeMillis());
- @Override
- public String convert(ILoggingEvent event) {
- return Long.toString(sequenceNumber.getAndIncrement());
- }
+ @Override
+ public String convert(ILoggingEvent event) {
+ return Long.toString(sequenceNumber.getAndIncrement());
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LoggerConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LoggerConverter.java
index 655f5e3..736ecef 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LoggerConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LoggerConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,7 +17,7 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
public class LoggerConverter extends NamedConverter {
- protected String getFullyQualifiedName(ILoggingEvent event) {
- return event.getLoggerName();
- }
+ protected String getFullyQualifiedName(ILoggingEvent event) {
+ return event.getLoggerName();
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MDCConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MDCConverter.java
index 3eb22b8..1b3ab7d 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MDCConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MDCConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,61 +21,61 @@ import static ch.qos.logback.core.util.OptionHelper.extractDefaultReplacement;
public class MDCConverter extends ClassicConverter {
- private String key;
- private String defaultValue = "";
+ private String key;
+ private String defaultValue = "";
- @Override
- public void start() {
- String[] keyInfo = extractDefaultReplacement(getFirstOption());
- key = keyInfo[0];
- if (keyInfo[1] != null) {
- defaultValue = keyInfo[1];
- }
- super.start();
+ @Override
+ public void start() {
+ String[] keyInfo = extractDefaultReplacement(getFirstOption());
+ key = keyInfo[0];
+ if (keyInfo[1] != null) {
+ defaultValue = keyInfo[1];
}
+ super.start();
+ }
- @Override
- public void stop() {
- key = null;
- super.stop();
- }
+ @Override
+ public void stop() {
+ key = null;
+ super.stop();
+ }
- @Override
- public String convert(ILoggingEvent event) {
- Map<String, String> mdcPropertyMap = event.getMDCPropertyMap();
+ @Override
+ public String convert(ILoggingEvent event) {
+ Map<String, String> mdcPropertyMap = event.getMDCPropertyMap();
- if (mdcPropertyMap == null) {
- return defaultValue;
- }
+ if (mdcPropertyMap == null) {
+ return defaultValue;
+ }
- if (key == null) {
- return outputMDCForAllKeys(mdcPropertyMap);
- } else {
+ if (key == null) {
+ return outputMDCForAllKeys(mdcPropertyMap);
+ } else {
- String value = event.getMDCPropertyMap().get(key);
- if (value != null) {
- return value;
- } else {
- return defaultValue;
- }
- }
+ String value = event.getMDCPropertyMap().get(key);
+ if (value != null) {
+ return value;
+ } else {
+ return defaultValue;
+ }
}
+ }
- /**
- * if no key is specified, return all the values present in the MDC, in the format "k1=v1, k2=v2, ..."
- */
- private String outputMDCForAllKeys(Map<String, String> mdcPropertyMap) {
- StringBuilder buf = new StringBuilder();
- boolean first = true;
- for (Map.Entry<String, String> entry : mdcPropertyMap.entrySet()) {
- if (first) {
- first = false;
- } else {
- buf.append(", ");
- }
- // format: key0=value0, key1=value1
- buf.append(entry.getKey()).append('=').append(entry.getValue());
- }
- return buf.toString();
+ /**
+ * if no key is specified, return all the values present in the MDC, in the format "k1=v1, k2=v2, ..."
+ */
+ private String outputMDCForAllKeys(Map<String, String> mdcPropertyMap) {
+ StringBuilder buf = new StringBuilder();
+ boolean first = true;
+ for (Map.Entry<String, String> entry : mdcPropertyMap.entrySet()) {
+ if (first) {
+ first = false;
+ } else {
+ buf.append(", ");
+ }
+ //format: key0=value0, key1=value1
+ buf.append(entry.getKey()).append('=').append(entry.getValue());
}
+ return buf.toString();
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MarkerConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MarkerConverter.java
index a3b6dff..3a9296d 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MarkerConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MarkerConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,15 +24,15 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
*/
public class MarkerConverter extends ClassicConverter {
- private static String EMPTY = "";
+ private static String EMPTY = "";
- public String convert(ILoggingEvent le) {
- Marker marker = le.getMarker();
- if (marker == null) {
- return EMPTY;
- } else {
- return marker.toString();
- }
+ public String convert(ILoggingEvent le) {
+ Marker marker = le.getMarker();
+ if (marker == null) {
+ return EMPTY;
+ } else {
+ return marker.toString();
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MessageConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MessageConverter.java
index 18ddbf3..e7f909d 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MessageConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MessageConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,8 +22,8 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
*/
public class MessageConverter extends ClassicConverter {
- public String convert(ILoggingEvent event) {
- return event.getFormattedMessage();
- }
+ public String convert(ILoggingEvent event) {
+ return event.getFormattedMessage();
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MethodOfCallerConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MethodOfCallerConverter.java
index 8565429..4e3f891 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MethodOfCallerConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/MethodOfCallerConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,13 +18,13 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
public class MethodOfCallerConverter extends ClassicConverter {
- public String convert(ILoggingEvent le) {
- StackTraceElement[] cda = le.getCallerData();
- if (cda != null && cda.length > 0) {
- return cda[0].getMethodName();
- } else {
- return CallerData.NA;
- }
+ public String convert(ILoggingEvent le) {
+ StackTraceElement[] cda = le.getCallerData();
+ if (cda != null && cda.length > 0) {
+ return cda[0].getMethodName();
+ } else {
+ return CallerData.NA;
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/NamedConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/NamedConverter.java
index 0c30d4e..cd5a6ed 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/NamedConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/NamedConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,40 +17,40 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
public abstract class NamedConverter extends ClassicConverter {
- Abbreviator abbreviator = null;
+ Abbreviator abbreviator = null;
- /**
- * Gets fully qualified name from event.
- *
- * @param event
- * The LoggingEvent to process, cannot not be null.
- * @return name, must not be null.
- */
- protected abstract String getFullyQualifiedName(final ILoggingEvent event);
+ /**
+ * Gets fully qualified name from event.
+ *
+ * @param event
+ * The LoggingEvent to process, cannot not be null.
+ * @return name, must not be null.
+ */
+ protected abstract String getFullyQualifiedName(final ILoggingEvent event);
- public void start() {
- String optStr = getFirstOption();
- if (optStr != null) {
- try {
- int targetLen = Integer.parseInt(optStr);
- if (targetLen == 0) {
- abbreviator = new ClassNameOnlyAbbreviator();
- } else if (targetLen > 0) {
- abbreviator = new TargetLengthBasedClassNameAbbreviator(targetLen);
- }
- } catch (NumberFormatException nfe) {
- // FIXME: better error reporting
- }
+ public void start() {
+ String optStr = getFirstOption();
+ if (optStr != null) {
+ try {
+ int targetLen = Integer.parseInt(optStr);
+ if (targetLen == 0) {
+ abbreviator = new ClassNameOnlyAbbreviator();
+ } else if (targetLen > 0) {
+ abbreviator = new TargetLengthBasedClassNameAbbreviator(targetLen);
}
+ } catch (NumberFormatException nfe) {
+ // FIXME: better error reporting
+ }
}
+ }
- public String convert(ILoggingEvent event) {
- String fqn = getFullyQualifiedName(event);
+ public String convert(ILoggingEvent event) {
+ String fqn = getFullyQualifiedName(event);
- if (abbreviator == null) {
- return fqn;
- } else {
- return abbreviator.abbreviate(fqn);
- }
+ if (abbreviator == null) {
+ return fqn;
+ } else {
+ return abbreviator.abbreviate(fqn);
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/NopThrowableInformationConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/NopThrowableInformationConverter.java
index 3efa55f..393e91f 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/NopThrowableInformationConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/NopThrowableInformationConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,6 +17,8 @@ import ch.qos.logback.classic.PatternLayout;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.CoreConstants;
+
+
/**
* Always returns an empty string.
* <p>
@@ -34,8 +36,8 @@ import ch.qos.logback.core.CoreConstants;
*/
public class NopThrowableInformationConverter extends ThrowableHandlingConverter {
- public String convert(ILoggingEvent event) {
- return CoreConstants.EMPTY_STRING;
- }
-
+ public String convert(ILoggingEvent event) {
+ return CoreConstants.EMPTY_STRING;
+ }
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/PropertyConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/PropertyConverter.java
index ca7887c..2dd6218 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/PropertyConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/PropertyConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,28 +20,28 @@ import ch.qos.logback.classic.spi.LoggerContextVO;
public final class PropertyConverter extends ClassicConverter {
- String key;
+ String key;
- public void start() {
- String optStr = getFirstOption();
- if (optStr != null) {
- key = optStr;
- super.start();
- }
+ public void start() {
+ String optStr = getFirstOption();
+ if (optStr != null) {
+ key = optStr;
+ super.start();
}
+ }
- public String convert(ILoggingEvent event) {
- if (key == null) {
- return "Property_HAS_NO_KEY";
- } else {
- LoggerContextVO lcvo = event.getLoggerContextVO();
- Map<String, String> map = lcvo.getPropertyMap();
- String val = map.get(key);
- if (val != null) {
- return val;
- } else {
- return System.getProperty(key);
- }
- }
+ public String convert(ILoggingEvent event) {
+ if (key == null) {
+ return "Property_HAS_NO_KEY";
+ } else {
+ LoggerContextVO lcvo = event.getLoggerContextVO();
+ Map<String, String> map = lcvo.getPropertyMap();
+ String val = map.get(key);
+ if (val != null) {
+ return val;
+ } else {
+ return System.getProperty(key);
+ }
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/RelativeTimeConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/RelativeTimeConverter.java
index 2b6cbc9..231ad48 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/RelativeTimeConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/RelativeTimeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,19 +17,19 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
public class RelativeTimeConverter extends ClassicConverter {
- long lastTimestamp = -1;
- String timesmapCache = null;
+ long lastTimestamp = -1;
+ String timesmapCache = null;
- public String convert(ILoggingEvent event) {
- long now = event.getTimeStamp();
+ public String convert(ILoggingEvent event) {
+ long now = event.getTimeStamp();
- synchronized (this) {
- // update timesmapStrCache only if now != lastTimestamp
- if (now != lastTimestamp) {
- lastTimestamp = now;
- timesmapCache = Long.toString(now - event.getLoggerContextVO().getBirthTime());
- }
- return timesmapCache;
- }
+ synchronized (this) {
+ // update timesmapStrCache only if now != lastTimestamp
+ if (now != lastTimestamp) {
+ lastTimestamp = now;
+ timesmapCache = Long.toString(now - event.getLoggerContextVO().getBirthTime());
+ }
+ return timesmapCache;
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverter.java
index 979f7ba..d178e6e 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,30 +23,30 @@ import ch.qos.logback.core.CoreConstants;
*/
public class RootCauseFirstThrowableProxyConverter extends ExtendedThrowableProxyConverter {
- @Override
- protected String throwableProxyToString(IThrowableProxy tp) {
- StringBuilder buf = new StringBuilder(BUILDER_CAPACITY);
- recursiveAppendRootCauseFirst(buf, null, ThrowableProxyUtil.REGULAR_EXCEPTION_INDENT, tp);
- return buf.toString();
- }
+ @Override
+ protected String throwableProxyToString(IThrowableProxy tp) {
+ StringBuilder buf = new StringBuilder(BUILDER_CAPACITY);
+ recursiveAppendRootCauseFirst(buf, null, ThrowableProxyUtil.REGULAR_EXCEPTION_INDENT, tp);
+ return buf.toString();
+ }
- protected void recursiveAppendRootCauseFirst(StringBuilder sb, String prefix, int indent, IThrowableProxy tp) {
- if (tp.getCause() != null) {
- recursiveAppendRootCauseFirst(sb, prefix, indent, tp.getCause());
- prefix = null; // to avoid adding it more than once
- }
- ThrowableProxyUtil.indent(sb, indent - 1);
- if (prefix != null) {
- sb.append(prefix);
- }
- ThrowableProxyUtil.subjoinFirstLineRootCauseFirst(sb, tp);
- sb.append(CoreConstants.LINE_SEPARATOR);
- subjoinSTEPArray(sb, indent, tp);
- IThrowableProxy[] suppressed = tp.getSuppressed();
- if (suppressed != null) {
- for (IThrowableProxy current : suppressed) {
- recursiveAppendRootCauseFirst(sb, CoreConstants.SUPPRESSED, indent + ThrowableProxyUtil.SUPPRESSED_EXCEPTION_INDENT, current);
- }
- }
+ protected void recursiveAppendRootCauseFirst(StringBuilder sb, String prefix, int indent, IThrowableProxy tp) {
+ if (tp.getCause() != null) {
+ recursiveAppendRootCauseFirst(sb, prefix, indent, tp.getCause());
+ prefix = null; // to avoid adding it more than once
+ }
+ ThrowableProxyUtil.indent(sb, indent - 1);
+ if (prefix != null) {
+ sb.append(prefix);
+ }
+ ThrowableProxyUtil.subjoinFirstLineRootCauseFirst(sb, tp);
+ sb.append(CoreConstants.LINE_SEPARATOR);
+ subjoinSTEPArray(sb, indent, tp);
+ IThrowableProxy[] suppressed = tp.getSuppressed();
+ if(suppressed != null) {
+ for(IThrowableProxy current : suppressed) {
+ recursiveAppendRootCauseFirst(sb, CoreConstants.SUPPRESSED, indent + ThrowableProxyUtil.SUPPRESSED_EXCEPTION_INDENT, current);
+ }
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/SyslogStartConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/SyslogStartConverter.java
index 1654285..b9011b4 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/SyslogStartConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/SyslogStartConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,86 +26,85 @@ import ch.qos.logback.core.net.SyslogAppenderBase;
public class SyslogStartConverter extends ClassicConverter {
- long lastTimestamp = -1;
- String timesmapStr = null;
- SimpleDateFormat simpleMonthFormat;
- SimpleDateFormat simpleTimeFormat;
- private final Calendar calendar = Calendar.getInstance(Locale.US);
-
- String localHostName;
- int facility;
-
- public void start() {
- int errorCount = 0;
-
- String facilityStr = getFirstOption();
- if (facilityStr == null) {
- addError("was expecting a facility string as an option");
- return;
- }
-
- facility = SyslogAppenderBase.facilityStringToint(facilityStr);
-
- localHostName = getLocalHostname();
- try {
- // hours should be in 0-23, see also http://jira.qos.ch/browse/LBCLASSIC-48
- simpleMonthFormat = new SimpleDateFormat("MMM", Locale.US);
- simpleTimeFormat = new SimpleDateFormat("HH:mm:ss", Locale.US);
- } catch (IllegalArgumentException e) {
- addError("Could not instantiate SimpleDateFormat", e);
- errorCount++;
- }
-
- if (errorCount == 0) {
- super.start();
- }
+ long lastTimestamp = -1;
+ String timesmapStr = null;
+ SimpleDateFormat simpleMonthFormat;
+ SimpleDateFormat simpleTimeFormat;
+ private final Calendar calendar = Calendar.getInstance(Locale.US);
+
+ String localHostName;
+ int facility;
+
+ public void start() {
+ int errorCount = 0;
+
+ String facilityStr = getFirstOption();
+ if (facilityStr == null) {
+ addError("was expecting a facility string as an option");
+ return;
}
- public String convert(ILoggingEvent event) {
- StringBuilder sb = new StringBuilder();
-
- int pri = facility + LevelToSyslogSeverity.convert(event);
-
- sb.append("<");
- sb.append(pri);
- sb.append(">");
- sb.append(computeTimeStampString(event.getTimeStamp()));
- sb.append(' ');
- sb.append(localHostName);
- sb.append(' ');
-
- return sb.toString();
+ facility = SyslogAppenderBase.facilityStringToint(facilityStr);
+
+ localHostName = getLocalHostname();
+ try {
+ // hours should be in 0-23, see also http://jira.qos.ch/browse/LBCLASSIC-48
+ simpleMonthFormat = new SimpleDateFormat("MMM", Locale.US);
+ simpleTimeFormat = new SimpleDateFormat("HH:mm:ss", Locale.US);
+ } catch (IllegalArgumentException e) {
+ addError("Could not instantiate SimpleDateFormat", e);
+ errorCount++;
}
- /**
- * This method gets the network name of the machine we are running on.
- * Returns "UNKNOWN_LOCALHOST" in the unlikely case where the host name
- * cannot be found.
- * @return String the name of the local host
- */
- public String getLocalHostname() {
- try {
- InetAddress addr = InetAddress.getLocalHost();
- return addr.getHostName();
- } catch (UnknownHostException uhe) {
- addError("Could not determine local host name", uhe);
- return "UNKNOWN_LOCALHOST";
- }
+ if(errorCount == 0) {
+ super.start();
}
-
- String computeTimeStampString(long now) {
- synchronized (this) {
- // Since the formatted output is only precise to the second, we can use the same cached string if the
- // current
- // second is the same (stripping off the milliseconds).
- if ((now / 1000) != lastTimestamp) {
- lastTimestamp = now / 1000;
- Date nowDate = new Date(now);
- calendar.setTime(nowDate);
- timesmapStr = String.format("%s %2d %s", simpleMonthFormat.format(nowDate), calendar.get(Calendar.DAY_OF_MONTH),
- simpleTimeFormat.format(nowDate));
- }
- return timesmapStr;
- }
+ }
+
+ public String convert(ILoggingEvent event) {
+ StringBuilder sb = new StringBuilder();
+
+ int pri = facility + LevelToSyslogSeverity.convert(event);
+
+ sb.append("<");
+ sb.append(pri);
+ sb.append(">");
+ sb.append(computeTimeStampString(event.getTimeStamp()));
+ sb.append(' ');
+ sb.append(localHostName);
+ sb.append(' ');
+
+ return sb.toString();
+ }
+
+ /**
+ * This method gets the network name of the machine we are running on.
+ * Returns "UNKNOWN_LOCALHOST" in the unlikely case where the host name
+ * cannot be found.
+ * @return String the name of the local host
+ */
+ public String getLocalHostname() {
+ try {
+ InetAddress addr = InetAddress.getLocalHost();
+ return addr.getHostName();
+ } catch (UnknownHostException uhe) {
+ addError("Could not determine local host name", uhe);
+ return "UNKNOWN_LOCALHOST";
+ }
+ }
+
+ String computeTimeStampString(long now) {
+ synchronized (this) {
+ // Since the formatted output is only precise to the second, we can use the same cached string if the current
+ // second is the same (stripping off the milliseconds).
+ if ((now / 1000) != lastTimestamp) {
+ lastTimestamp = now / 1000;
+ Date nowDate = new Date(now);
+ calendar.setTime(nowDate);
+ timesmapStr = String.format("%s %2d %s", simpleMonthFormat.format(nowDate),
+ calendar.get(Calendar.DAY_OF_MONTH), simpleTimeFormat.format(nowDate));
+ }
+ return timesmapStr;
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/TargetLengthBasedClassNameAbbreviator.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/TargetLengthBasedClassNameAbbreviator.java
index a632d06..70edb27 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/TargetLengthBasedClassNameAbbreviator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/TargetLengthBasedClassNameAbbreviator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,109 +18,111 @@ import ch.qos.logback.core.CoreConstants;
public class TargetLengthBasedClassNameAbbreviator implements Abbreviator {
- final int targetLength;
+ final int targetLength;
- public TargetLengthBasedClassNameAbbreviator(int targetLength) {
- this.targetLength = targetLength;
+ public TargetLengthBasedClassNameAbbreviator(int targetLength) {
+ this.targetLength = targetLength;
+ }
+
+ public String abbreviate(String fqClassName) {
+ StringBuilder buf = new StringBuilder(targetLength);
+ if (fqClassName == null) {
+ throw new IllegalArgumentException("Class name may not be null");
}
- public String abbreviate(String fqClassName) {
- StringBuilder buf = new StringBuilder(targetLength);
- if (fqClassName == null) {
- throw new IllegalArgumentException("Class name may not be null");
- }
-
- int inLen = fqClassName.length();
- if (inLen < targetLength) {
- return fqClassName;
- }
-
- int[] dotIndexesArray = new int[ClassicConstants.MAX_DOTS];
- // a.b.c contains 2 dots but 2+1 parts.
- // see also http://jira.qos.ch/browse/LBCLASSIC-110
- int[] lengthArray = new int[ClassicConstants.MAX_DOTS + 1];
-
- int dotCount = computeDotIndexes(fqClassName, dotIndexesArray);
-
- // System.out.println();
- // System.out.println("Dot count for [" + className + "] is " + dotCount);
- // if there are not dots than abbreviation is not possible
- if (dotCount == 0) {
- return fqClassName;
- }
- // printArray("dotArray: ", dotArray);
- computeLengthArray(fqClassName, dotIndexesArray, lengthArray, dotCount);
- // printArray("lengthArray: ", lengthArray);
- for (int i = 0; i <= dotCount; i++) {
- if (i == 0) {
- buf.append(fqClassName.substring(0, lengthArray[i] - 1));
- } else {
- buf.append(fqClassName.substring(dotIndexesArray[i - 1], dotIndexesArray[i - 1] + lengthArray[i]));
- }
- // System.out.println("i=" + i + ", buf=" + buf);
- }
-
- return buf.toString();
+ int inLen = fqClassName.length();
+ if (inLen < targetLength) {
+ return fqClassName;
}
- static int computeDotIndexes(final String className, int[] dotArray) {
- int dotCount = 0;
- int k = 0;
- while (true) {
- // ignore the $ separator in our computations. This is both convenient
- // and sensible.
- k = className.indexOf(CoreConstants.DOT, k);
- if (k != -1 && dotCount < ClassicConstants.MAX_DOTS) {
- dotArray[dotCount] = k;
- dotCount++;
- k++;
- } else {
- break;
- }
- }
- return dotCount;
+ int[] dotIndexesArray = new int[ClassicConstants.MAX_DOTS];
+ // a.b.c contains 2 dots but 2+1 parts.
+ // see also http://jira.qos.ch/browse/LBCLASSIC-110
+ int[] lengthArray = new int[ClassicConstants.MAX_DOTS + 1];
+
+ int dotCount = computeDotIndexes(fqClassName, dotIndexesArray);
+
+ // System.out.println();
+ // System.out.println("Dot count for [" + className + "] is " + dotCount);
+ // if there are not dots than abbreviation is not possible
+ if (dotCount == 0) {
+ return fqClassName;
+ }
+ // printArray("dotArray: ", dotArray);
+ computeLengthArray(fqClassName, dotIndexesArray, lengthArray, dotCount);
+ // printArray("lengthArray: ", lengthArray);
+ for (int i = 0; i <= dotCount; i++) {
+ if (i == 0) {
+ buf.append(fqClassName.substring(0, lengthArray[i] - 1));
+ } else {
+ buf.append(fqClassName.substring(dotIndexesArray[i - 1],
+ dotIndexesArray[i - 1] + lengthArray[i]));
+ }
+ // System.out.println("i=" + i + ", buf=" + buf);
}
- void computeLengthArray(final String className, int[] dotArray, int[] lengthArray, int dotCount) {
- int toTrim = className.length() - targetLength;
- // System.out.println("toTrim=" + toTrim);
-
- // int toTrimAvarage = 0;
-
- int len;
- for (int i = 0; i < dotCount; i++) {
- int previousDotPosition = -1;
- if (i > 0) {
- previousDotPosition = dotArray[i - 1];
- }
- int available = dotArray[i] - previousDotPosition - 1;
- // System.out.println("i=" + i + ", available = " + available);
-
- len = (available < 1) ? available : 1;
- // System.out.println("i=" + i + ", toTrim = " + toTrim);
-
- if (toTrim > 0) {
- len = (available < 1) ? available : 1;
- } else {
- len = available;
- }
- toTrim -= (available - len);
- lengthArray[i] = len + 1;
- }
-
- int lastDotIndex = dotCount - 1;
- lengthArray[dotCount] = className.length() - dotArray[lastDotIndex];
+ return buf.toString();
+ }
+
+ static int computeDotIndexes(final String className, int[] dotArray) {
+ int dotCount = 0;
+ int k = 0;
+ while (true) {
+ // ignore the $ separator in our computations. This is both convenient
+ // and sensible.
+ k = className.indexOf(CoreConstants.DOT, k);
+ if (k != -1 && dotCount < ClassicConstants.MAX_DOTS) {
+ dotArray[dotCount] = k;
+ dotCount++;
+ k++;
+ } else {
+ break;
+ }
+ }
+ return dotCount;
+ }
+
+ void computeLengthArray(final String className, int[] dotArray,
+ int[] lengthArray, int dotCount) {
+ int toTrim = className.length() - targetLength;
+ // System.out.println("toTrim=" + toTrim);
+
+ // int toTrimAvarage = 0;
+
+ int len;
+ for (int i = 0; i < dotCount; i++) {
+ int previousDotPosition = -1;
+ if (i > 0) {
+ previousDotPosition = dotArray[i - 1];
+ }
+ int available = dotArray[i] - previousDotPosition - 1;
+ // System.out.println("i=" + i + ", available = " + available);
+
+ len = (available < 1) ? available : 1;
+ // System.out.println("i=" + i + ", toTrim = " + toTrim);
+
+ if (toTrim > 0) {
+ len = (available < 1) ? available : 1;
+ } else {
+ len = available;
+ }
+ toTrim -= (available - len);
+ lengthArray[i] = len + 1;
}
- static void printArray(String msg, int[] ia) {
- System.out.print(msg);
- for (int i = 0; i < ia.length; i++) {
- if (i == 0) {
- System.out.print(ia[i]);
- } else {
- System.out.print(", " + ia[i]);
- }
- }
- System.out.println();
+ int lastDotIndex = dotCount - 1;
+ lengthArray[dotCount] = className.length() - dotArray[lastDotIndex];
+ }
+
+ static void printArray(String msg, int[] ia) {
+ System.out.print(msg);
+ for (int i = 0; i < ia.length; i++) {
+ if (i == 0) {
+ System.out.print(ia[i]);
+ } else {
+ System.out.print(", " + ia[i]);
+ }
}
+ System.out.println();
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThreadConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThreadConverter.java
index 9cf0925..c2b877c 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThreadConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThreadConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,8 +22,8 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
*/
public class ThreadConverter extends ClassicConverter {
- public String convert(ILoggingEvent event) {
- return event.getThreadName();
- }
+ public String convert(ILoggingEvent event) {
+ return event.getThreadName();
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableHandlingConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableHandlingConverter.java
index 5714ea5..f3e9cd6 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableHandlingConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableHandlingConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,13 +13,15 @@
*/
package ch.qos.logback.classic.pattern;
+
+
/**
* Converter which handle throwables should be derived from this class.
*
*/
public abstract class ThrowableHandlingConverter extends ClassicConverter {
-
- boolean handlesThrowable() {
- return true;
- }
+
+ boolean handlesThrowable() {
+ return true;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableProxyConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableProxyConverter.java
index 680ff64..ae8448d 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableProxyConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/ThrowableProxyConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -34,210 +34,168 @@ import ch.qos.logback.core.status.ErrorStatus;
*/
public class ThrowableProxyConverter extends ThrowableHandlingConverter {
- protected static final int BUILDER_CAPACITY = 2048;
-
- int lengthOption;
- List<EventEvaluator<ILoggingEvent>> evaluatorList = null;
- List<String> ignoredStackTraceLines = null;
-
- int errorCount = 0;
-
- @SuppressWarnings("unchecked")
- public void start() {
-
- String lengthStr = getFirstOption();
-
- if (lengthStr == null) {
- lengthOption = Integer.MAX_VALUE;
- } else {
- lengthStr = lengthStr.toLowerCase();
- if ("full".equals(lengthStr)) {
- lengthOption = Integer.MAX_VALUE;
- } else if ("short".equals(lengthStr)) {
- lengthOption = 1;
- } else {
- try {
- lengthOption = Integer.parseInt(lengthStr);
- } catch (NumberFormatException nfe) {
- addError("Could not parse [" + lengthStr + "] as an integer");
- lengthOption = Integer.MAX_VALUE;
- }
- }
- }
+ protected static final int BUILDER_CAPACITY = 2048;
- final List<String> optionList = getOptionList();
-
- if (optionList != null && optionList.size() > 1) {
- final int optionListSize = optionList.size();
- for (int i = 1; i < optionListSize; i++) {
- String evaluatorOrIgnoredStackTraceLine = (String) optionList.get(i);
- Context context = getContext();
- Map<String, EventEvaluator<?>> evaluatorMap = (Map<String, EventEvaluator<?>>) context.getObject(CoreConstants.EVALUATOR_MAP);
- EventEvaluator<ILoggingEvent> ee = (EventEvaluator<ILoggingEvent>) evaluatorMap.get(evaluatorOrIgnoredStackTraceLine);
- if (ee != null) {
- addEvaluator(ee);
- } else {
- addIgnoreStackTraceLine(evaluatorOrIgnoredStackTraceLine);
- }
- }
- }
- super.start();
- }
+ int lengthOption;
+ List<EventEvaluator<ILoggingEvent>> evaluatorList = null;
- private void addEvaluator(EventEvaluator<ILoggingEvent> ee) {
- if (evaluatorList == null) {
- evaluatorList = new ArrayList<EventEvaluator<ILoggingEvent>>();
- }
- evaluatorList.add(ee);
- }
+ int errorCount = 0;
+
+ @SuppressWarnings("unchecked")
+ public void start() {
- private void addIgnoreStackTraceLine(String ignoredStackTraceLine) {
- if (ignoredStackTraceLines == null) {
- ignoredStackTraceLines = new ArrayList<String>();
+ String lengthStr = getFirstOption();
+
+ if (lengthStr == null) {
+ lengthOption = Integer.MAX_VALUE;
+ } else {
+ lengthStr = lengthStr.toLowerCase();
+ if ("full".equals(lengthStr)) {
+ lengthOption = Integer.MAX_VALUE;
+ } else if ("short".equals(lengthStr)) {
+ lengthOption = 1;
+ } else {
+ try {
+ lengthOption = Integer.parseInt(lengthStr);
+ } catch (NumberFormatException nfe) {
+ addError("Could not parse [" + lengthStr + "] as an integer");
+ lengthOption = Integer.MAX_VALUE;
}
- ignoredStackTraceLines.add(ignoredStackTraceLine);
+ }
}
- public void stop() {
- evaluatorList = null;
- super.stop();
+ final List optionList = getOptionList();
+
+ if (optionList != null && optionList.size() > 1) {
+ final int optionListSize = optionList.size();
+ for (int i = 1; i < optionListSize; i++) {
+ String evaluatorStr = (String) optionList.get(i);
+ Context context = getContext();
+ Map evaluatorMap = (Map) context.getObject(CoreConstants.EVALUATOR_MAP);
+ EventEvaluator<ILoggingEvent> ee = (EventEvaluator<ILoggingEvent>) evaluatorMap
+ .get(evaluatorStr);
+ addEvaluator(ee);
+ }
}
+ super.start();
+ }
- protected void extraData(StringBuilder builder, StackTraceElementProxy step) {
- // nop
+ private void addEvaluator(EventEvaluator<ILoggingEvent> ee) {
+ if (evaluatorList == null) {
+ evaluatorList = new ArrayList<EventEvaluator<ILoggingEvent>>();
}
+ evaluatorList.add(ee);
+ }
- public String convert(ILoggingEvent event) {
+ public void stop() {
+ evaluatorList = null;
+ super.stop();
+ }
- IThrowableProxy tp = event.getThrowableProxy();
- if (tp == null) {
- return CoreConstants.EMPTY_STRING;
- }
+ protected void extraData(StringBuilder builder, StackTraceElementProxy step) {
+ // nop
+ }
+
+ public String convert(ILoggingEvent event) {
- // an evaluator match will cause stack printing to be skipped
- if (evaluatorList != null) {
- boolean printStack = true;
- for (int i = 0; i < evaluatorList.size(); i++) {
- EventEvaluator<ILoggingEvent> ee = evaluatorList.get(i);
- try {
- if (ee.evaluate(event)) {
- printStack = false;
- break;
- }
- } catch (EvaluationException eex) {
- errorCount++;
- if (errorCount < CoreConstants.MAX_ERROR_COUNT) {
- addError("Exception thrown for evaluator named [" + ee.getName() + "]", eex);
- } else if (errorCount == CoreConstants.MAX_ERROR_COUNT) {
- ErrorStatus errorStatus = new ErrorStatus("Exception thrown for evaluator named [" + ee.getName() + "].", this, eex);
- errorStatus.add(new ErrorStatus("This was the last warning about this evaluator's errors."
- + "We don't want the StatusManager to get flooded.", this));
- addStatus(errorStatus);
- }
- }
- }
-
- if (!printStack) {
- return CoreConstants.EMPTY_STRING;
- }
+ IThrowableProxy tp = event.getThrowableProxy();
+ if (tp == null) {
+ return CoreConstants.EMPTY_STRING;
+ }
+
+ // an evaluator match will cause stack printing to be skipped
+ if (evaluatorList != null) {
+ boolean printStack = true;
+ for (int i = 0; i < evaluatorList.size(); i++) {
+ EventEvaluator<ILoggingEvent> ee = evaluatorList.get(i);
+ try {
+ if (ee.evaluate(event)) {
+ printStack = false;
+ break;
+ }
+ } catch (EvaluationException eex) {
+ errorCount++;
+ if (errorCount < CoreConstants.MAX_ERROR_COUNT) {
+ addError("Exception thrown for evaluator named [" + ee.getName()
+ + "]", eex);
+ } else if (errorCount == CoreConstants.MAX_ERROR_COUNT) {
+ ErrorStatus errorStatus = new ErrorStatus(
+ "Exception thrown for evaluator named [" + ee.getName() + "].",
+ this, eex);
+ errorStatus.add(new ErrorStatus(
+ "This was the last warning about this evaluator's errors."
+ + "We don't want the StatusManager to get flooded.", this));
+ addStatus(errorStatus);
+ }
}
+ }
- return throwableProxyToString(tp);
+ if (!printStack) {
+ return CoreConstants.EMPTY_STRING;
+ }
}
- protected String throwableProxyToString(IThrowableProxy tp) {
- StringBuilder sb = new StringBuilder(BUILDER_CAPACITY);
+ return throwableProxyToString(tp);
+ }
- recursiveAppend(sb, null, ThrowableProxyUtil.REGULAR_EXCEPTION_INDENT, tp);
+ protected String throwableProxyToString(IThrowableProxy tp) {
+ StringBuilder sb = new StringBuilder(BUILDER_CAPACITY);
- return sb.toString();
- }
+ recursiveAppend(sb, null, ThrowableProxyUtil.REGULAR_EXCEPTION_INDENT, tp);
- private void recursiveAppend(StringBuilder sb, String prefix, int indent, IThrowableProxy tp) {
- if (tp == null)
- return;
- subjoinFirstLine(sb, prefix, indent, tp);
- sb.append(CoreConstants.LINE_SEPARATOR);
- subjoinSTEPArray(sb, indent, tp);
- IThrowableProxy[] suppressed = tp.getSuppressed();
- if (suppressed != null) {
- for (IThrowableProxy current : suppressed) {
- recursiveAppend(sb, CoreConstants.SUPPRESSED, indent + ThrowableProxyUtil.SUPPRESSED_EXCEPTION_INDENT, current);
- }
- }
- recursiveAppend(sb, CoreConstants.CAUSED_BY, indent, tp.getCause());
- }
+ return sb.toString();
+ }
- private void subjoinFirstLine(StringBuilder buf, String prefix, int indent, IThrowableProxy tp) {
- ThrowableProxyUtil.indent(buf, indent - 1);
- if (prefix != null) {
- buf.append(prefix);
- }
- subjoinExceptionMessage(buf, tp);
+ private void recursiveAppend(StringBuilder sb, String prefix, int indent, IThrowableProxy tp) {
+ if(tp == null)
+ return;
+ subjoinFirstLine(sb, prefix, indent, tp);
+ sb.append(CoreConstants.LINE_SEPARATOR);
+ subjoinSTEPArray(sb, indent, tp);
+ IThrowableProxy[] suppressed = tp.getSuppressed();
+ if(suppressed != null) {
+ for(IThrowableProxy current : suppressed) {
+ recursiveAppend(sb, CoreConstants.SUPPRESSED, indent + ThrowableProxyUtil.SUPPRESSED_EXCEPTION_INDENT, current);
+ }
}
+ recursiveAppend(sb, CoreConstants.CAUSED_BY, indent, tp.getCause());
+ }
- private void subjoinExceptionMessage(StringBuilder buf, IThrowableProxy tp) {
- buf.append(tp.getClassName()).append(": ").append(tp.getMessage());
+ private void subjoinFirstLine(StringBuilder buf, String prefix, int indent, IThrowableProxy tp) {
+ ThrowableProxyUtil.indent(buf, indent - 1);
+ if (prefix != null) {
+ buf.append(prefix);
}
+ subjoinExceptionMessage(buf, tp);
+ }
- protected void subjoinSTEPArray(StringBuilder buf, int indent, IThrowableProxy tp) {
- StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
- int commonFrames = tp.getCommonFrames();
+ private void subjoinExceptionMessage(StringBuilder buf, IThrowableProxy tp) {
+ buf.append(tp.getClassName()).append(": ").append(tp.getMessage());
+ }
- boolean unrestrictedPrinting = lengthOption > stepArray.length;
+ protected void subjoinSTEPArray(StringBuilder buf, int indent, IThrowableProxy tp) {
+ StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
+ int commonFrames = tp.getCommonFrames();
- int maxIndex = (unrestrictedPrinting) ? stepArray.length : lengthOption;
- if (commonFrames > 0 && unrestrictedPrinting) {
- maxIndex -= commonFrames;
- }
-
- int ignoredCount = 0;
- for (int i = 0; i < maxIndex; i++) {
- StackTraceElementProxy element = stepArray[i];
- if (!isIgnoredStackTraceLine(element.toString())) {
- ThrowableProxyUtil.indent(buf, indent);
- printStackLine(buf, ignoredCount, element);
- ignoredCount = 0;
- buf.append(CoreConstants.LINE_SEPARATOR);
- } else {
- ++ignoredCount;
- if (maxIndex < stepArray.length) {
- ++maxIndex;
- }
- }
- }
- if (ignoredCount > 0) {
- printIgnoredCount(buf, ignoredCount);
- buf.append(CoreConstants.LINE_SEPARATOR);
- }
+ boolean unrestrictedPrinting = lengthOption > stepArray.length;
- if (commonFrames > 0 && unrestrictedPrinting) {
- ThrowableProxyUtil.indent(buf, indent);
- buf.append("... ").append(tp.getCommonFrames()).append(" common frames omitted").append(CoreConstants.LINE_SEPARATOR);
- }
- }
- private void printStackLine(StringBuilder buf, int ignoredCount, StackTraceElementProxy element) {
- buf.append(element);
- extraData(buf, element); // allow other data to be added
- if (ignoredCount > 0) {
- printIgnoredCount(buf, ignoredCount);
- }
+ int maxIndex = (unrestrictedPrinting) ? stepArray.length : lengthOption;
+ if (commonFrames > 0 && unrestrictedPrinting) {
+ maxIndex -= commonFrames;
}
- private void printIgnoredCount(StringBuilder buf, int ignoredCount) {
- buf.append(" [").append(ignoredCount).append(" skipped]");
+ for (int i = 0; i < maxIndex; i++) {
+ ThrowableProxyUtil.indent(buf, indent);
+ buf.append(stepArray[i]);
+ extraData(buf, stepArray[i]); // allow other data to be added
+ buf.append(CoreConstants.LINE_SEPARATOR);
}
- private boolean isIgnoredStackTraceLine(String line) {
- if (ignoredStackTraceLines != null) {
- for (String ignoredStackTraceLine : ignoredStackTraceLines) {
- if (line.contains(ignoredStackTraceLine)) {
- return true;
- }
- }
- }
- return false;
+ if (commonFrames > 0 && unrestrictedPrinting) {
+ ThrowableProxyUtil.indent(buf, indent);
+ buf.append("... ").append(tp.getCommonFrames()).append(
+ " common frames omitted").append(CoreConstants.LINE_SEPARATOR);
}
-
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Util.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Util.java
index 95d530c..becee92 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Util.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/Util.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,24 +26,25 @@ import ch.qos.logback.classic.spi.ClassPackagingData;
*/
public class Util {
- static Map<String, ClassPackagingData> cache = new HashMap<String, ClassPackagingData>();
+ static Map<String, ClassPackagingData> cache = new HashMap<String, ClassPackagingData>();
- static public boolean match(Marker marker, Marker[] markerArray) {
- if (markerArray == null) {
- throw new IllegalArgumentException("markerArray should not be null");
- }
+ static public boolean match(Marker marker, Marker[] markerArray) {
+ if (markerArray == null) {
+ throw new IllegalArgumentException("markerArray should not be null");
+ }
- // System.out.println("event marker="+marker);
+ // System.out.println("event marker="+marker);
- final int size = markerArray.length;
- for (int i = 0; i < size; i++) {
- // System.out.println("other:"+markerArray[i]);
+ final int size = markerArray.length;
+ for (int i = 0; i < size; i++) {
+ // System.out.println("other:"+markerArray[i]);
- if (marker.contains(markerArray[i])) {
- return true;
- }
- }
- return false;
+ if (marker.contains(markerArray[i])) {
+ return true;
+ }
}
+ return false;
+ }
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/color/HighlightingCompositeConverter.java b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/color/HighlightingCompositeConverter.java
index cea5d53..a1784fb 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/pattern/color/HighlightingCompositeConverter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/pattern/color/HighlightingCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,25 +18,22 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
import static ch.qos.logback.core.pattern.color.ANSIConstants.*;
import ch.qos.logback.core.pattern.color.ForegroundCompositeConverterBase;
+
/**
* Highlights inner-text depending on the level, in bold red for events of level ERROR, in red for WARN,
* in BLUE for INFO, and in the default color for other levels.
*/
public class HighlightingCompositeConverter extends ForegroundCompositeConverterBase<ILoggingEvent> {
- @Override
- protected String getForegroundColorCode(ILoggingEvent event) {
- Level level = event.getLevel();
- switch (level.toInt()) {
- case Level.ERROR_INT:
- return BOLD + RED_FG;
- case Level.WARN_INT:
- return RED_FG;
- case Level.INFO_INT:
- return BLUE_FG;
- default:
- return DEFAULT_FG;
- }
-
+ @Override
+ protected String getForegroundColorCode(ILoggingEvent event) {
+ Level level = event.getLevel();
+ switch (level.toInt()) {
+ case Level.ERROR_INT: return BOLD+RED_FG;
+ case Level.WARN_INT: return RED_FG;
+ case Level.INFO_INT: return BLUE_FG;
+ default: return DEFAULT_FG;
}
+
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextJNDISelector.java b/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextJNDISelector.java
index e53c370..4632112 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextJNDISelector.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextJNDISelector.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -51,149 +51,155 @@ import ch.qos.logback.core.util.StatusPrinter;
*/
public class ContextJNDISelector implements ContextSelector {
- private final Map<String, LoggerContext> synchronizedContextMap;
- private final LoggerContext defaultContext;
+ private final Map<String, LoggerContext> synchronizedContextMap;
+ private final LoggerContext defaultContext;
- private static final ThreadLocal<LoggerContext> threadLocal = new ThreadLocal<LoggerContext>();
+ private static final ThreadLocal<LoggerContext> threadLocal = new ThreadLocal<LoggerContext>();
- public ContextJNDISelector(LoggerContext context) {
- synchronizedContextMap = Collections.synchronizedMap(new HashMap<String, LoggerContext>());
- defaultContext = context;
- }
-
- public LoggerContext getDefaultLoggerContext() {
- return defaultContext;
- }
-
- public LoggerContext detachLoggerContext(String loggerContextName) {
- return synchronizedContextMap.remove(loggerContextName);
- }
-
- public LoggerContext getLoggerContext() {
- String contextName = null;
- Context ctx = null;
+ public ContextJNDISelector(LoggerContext context) {
+ synchronizedContextMap = Collections
+ .synchronizedMap(new HashMap<String, LoggerContext>());
+ defaultContext = context;
+ }
- // First check if ThreadLocal has been set already
- LoggerContext lc = threadLocal.get();
- if (lc != null) {
- return lc;
- }
+ public LoggerContext getDefaultLoggerContext() {
+ return defaultContext;
+ }
- try {
- // We first try to find the name of our
- // environment's LoggerContext
- ctx = JNDIUtil.getInitialContext();
- contextName = (String) JNDIUtil.lookup(ctx, JNDI_CONTEXT_NAME);
- } catch (NamingException ne) {
- // We can't log here
- }
+ public LoggerContext detachLoggerContext(String loggerContextName) {
+ return synchronizedContextMap.remove(loggerContextName);
+ }
- if (contextName == null) {
- // We return the default context
- return defaultContext;
- } else {
- // Let's see if we already know such a context
- LoggerContext loggerContext = synchronizedContextMap.get(contextName);
-
- if (loggerContext == null) {
- // We have to create a new LoggerContext
- loggerContext = new LoggerContext();
- loggerContext.setName(contextName);
- synchronizedContextMap.put(contextName, loggerContext);
- URL url = findConfigFileURL(ctx, loggerContext);
- if (url != null) {
- configureLoggerContextByURL(loggerContext, url);
- } else {
- try {
- new ContextInitializer(loggerContext).autoConfig();
- } catch (JoranException je) {
- }
- }
- // logback-292
- if (!StatusUtil.contextHasStatusListener(loggerContext))
- StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
- }
- return loggerContext;
- }
- }
+ public LoggerContext getLoggerContext() {
+ String contextName = null;
+ Context ctx = null;
- private String conventionalConfigFileName(String contextName) {
- return "logback-" + contextName + ".xml";
+ // First check if ThreadLocal has been set already
+ LoggerContext lc = threadLocal.get();
+ if (lc != null) {
+ return lc;
}
- private URL findConfigFileURL(Context ctx, LoggerContext loggerContext) {
- StatusManager sm = loggerContext.getStatusManager();
-
- String jndiEntryForConfigResource = JNDIUtil.lookup(ctx, JNDI_CONFIGURATION_RESOURCE);
- // Do we have a dedicated configuration file?
- if (jndiEntryForConfigResource != null) {
- sm.add(new InfoStatus("Searching for [" + jndiEntryForConfigResource + "]", this));
- URL url = urlByResourceName(sm, jndiEntryForConfigResource);
- if (url == null) {
- String msg = "The jndi resource [" + jndiEntryForConfigResource + "] for context [" + loggerContext.getName()
- + "] does not lead to a valid file";
- sm.add(new WarnStatus(msg, this));
- }
- return url;
- } else {
- String resourceByConvention = conventionalConfigFileName(loggerContext.getName());
- return urlByResourceName(sm, resourceByConvention);
- }
+ try {
+ // We first try to find the name of our
+ // environment's LoggerContext
+ ctx = JNDIUtil.getInitialContext();
+ contextName = (String) JNDIUtil.lookup(ctx, JNDI_CONTEXT_NAME);
+ } catch (NamingException ne) {
+ // We can't log here
}
- private URL urlByResourceName(StatusManager sm, String resourceName) {
- sm.add(new InfoStatus("Searching for [" + resourceName + "]", this));
- URL url = Loader.getResource(resourceName, Loader.getTCL());
+ if (contextName == null) {
+ // We return the default context
+ return defaultContext;
+ } else {
+ // Let's see if we already know such a context
+ LoggerContext loggerContext = synchronizedContextMap.get(contextName);
+
+ if (loggerContext == null) {
+ // We have to create a new LoggerContext
+ loggerContext = new LoggerContext();
+ loggerContext.setName(contextName);
+ synchronizedContextMap.put(contextName, loggerContext);
+ URL url = findConfigFileURL(ctx, loggerContext);
if (url != null) {
- return url;
- }
- return Loader.getResourceBySelfClassLoader(resourceName);
- }
-
- private void configureLoggerContextByURL(LoggerContext context, URL url) {
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- context.reset();
- configurator.setContext(context);
- configurator.doConfigure(url);
- } catch (JoranException e) {
+ configureLoggerContextByURL(loggerContext, url);
+ } else {
+ try {
+ new ContextInitializer(loggerContext).autoConfig();
+ } catch (JoranException je) {
+ }
}
- StatusPrinter.printInCaseOfErrorsOrWarnings(context);
- }
-
- public List<String> getContextNames() {
- List<String> list = new ArrayList<String>();
- list.addAll(synchronizedContextMap.keySet());
- return list;
- }
-
- public LoggerContext getLoggerContext(String name) {
- return synchronizedContextMap.get(name);
+ // logback-292
+ if (!StatusUtil.contextHasStatusListener(loggerContext))
+ StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
+ }
+ return loggerContext;
}
-
- /**
- * Returns the number of managed contexts Used for testing purposes
- *
- * @return the number of managed contexts
- */
- public int getCount() {
- return synchronizedContextMap.size();
+ }
+
+ private String conventionalConfigFileName(String contextName) {
+ return "logback-" + contextName + ".xml";
+ }
+
+ private URL findConfigFileURL(Context ctx, LoggerContext loggerContext) {
+ StatusManager sm = loggerContext.getStatusManager();
+
+ String jndiEntryForConfigResource = JNDIUtil.lookup(ctx,
+ JNDI_CONFIGURATION_RESOURCE);
+ // Do we have a dedicated configuration file?
+ if (jndiEntryForConfigResource != null) {
+ sm.add(new InfoStatus("Searching for [" + jndiEntryForConfigResource
+ + "]", this));
+ URL url = urlByResourceName(sm, jndiEntryForConfigResource);
+ if (url == null) {
+ String msg = "The jndi resource [" + jndiEntryForConfigResource
+ + "] for context [" + loggerContext.getName()
+ + "] does not lead to a valid file";
+ sm.add(new WarnStatus(msg, this));
+ }
+ return url;
+ } else {
+ String resourceByConvention = conventionalConfigFileName(loggerContext
+ .getName());
+ return urlByResourceName(sm, resourceByConvention);
}
-
- /**
- * These methods are used by the LoggerContextFilter.
- * <p/>
- * They provide a way to tell the selector which context to use, thus saving
- * the cost of a JNDI call at each new request.
- *
- * @param context
- */
- public void setLocalContext(LoggerContext context) {
- threadLocal.set(context);
+ }
+
+ private URL urlByResourceName(StatusManager sm, String resourceName) {
+ sm.add(new InfoStatus("Searching for [" + resourceName + "]",
+ this));
+ URL url = Loader.getResource(resourceName, Loader.getTCL());
+ if (url != null) {
+ return url;
}
-
- public void removeLocalContext() {
- threadLocal.remove();
+ return Loader.getResourceBySelfClassLoader(resourceName);
+ }
+
+ private void configureLoggerContextByURL(LoggerContext context, URL url) {
+ try {
+ JoranConfigurator configurator = new JoranConfigurator();
+ context.reset();
+ configurator.setContext(context);
+ configurator.doConfigure(url);
+ } catch (JoranException e) {
}
+ StatusPrinter.printInCaseOfErrorsOrWarnings(context);
+ }
+
+ public List<String> getContextNames() {
+ List<String> list = new ArrayList<String>();
+ list.addAll(synchronizedContextMap.keySet());
+ return list;
+ }
+
+ public LoggerContext getLoggerContext(String name) {
+ return synchronizedContextMap.get(name);
+ }
+
+ /**
+ * Returns the number of managed contexts Used for testing purposes
+ *
+ * @return the number of managed contexts
+ */
+ public int getCount() {
+ return synchronizedContextMap.size();
+ }
+
+ /**
+ * These methods are used by the LoggerContextFilter.
+ * <p/>
+ * They provide a way to tell the selector which context to use, thus saving
+ * the cost of a JNDI call at each new request.
+ *
+ * @param context
+ */
+ public void setLocalContext(LoggerContext context) {
+ threadLocal.set(context);
+ }
+
+ public void removeLocalContext() {
+ threadLocal.remove();
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextSelector.java b/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextSelector.java
index 35b9aa5..58a40ef 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextSelector.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextSelector.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,13 +28,13 @@ import ch.qos.logback.classic.LoggerContext;
*/
public interface ContextSelector {
- LoggerContext getLoggerContext();
-
- LoggerContext getLoggerContext(String name);
-
- LoggerContext getDefaultLoggerContext();
-
- LoggerContext detachLoggerContext(String loggerContextName);
-
- List<String> getContextNames();
+ LoggerContext getLoggerContext();
+
+ LoggerContext getLoggerContext(String name);
+
+ LoggerContext getDefaultLoggerContext();
+
+ LoggerContext detachLoggerContext(String loggerContextName);
+
+ List<String> getContextNames();
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/selector/DefaultContextSelector.java b/logback-classic/src/main/java/ch/qos/logback/classic/selector/DefaultContextSelector.java
index 2b431a4..50072ea 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/selector/DefaultContextSelector.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/selector/DefaultContextSelector.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,33 +20,33 @@ import ch.qos.logback.classic.LoggerContext;
public class DefaultContextSelector implements ContextSelector {
- private LoggerContext defaultLoggerContext;
-
- public DefaultContextSelector(LoggerContext context) {
- this.defaultLoggerContext = context;
- }
-
- public LoggerContext getLoggerContext() {
- return getDefaultLoggerContext();
- }
-
- public LoggerContext getDefaultLoggerContext() {
- return defaultLoggerContext;
- }
-
- public LoggerContext detachLoggerContext(String loggerContextName) {
- return defaultLoggerContext;
- }
-
- public List<String> getContextNames() {
- return Arrays.asList(defaultLoggerContext.getName());
- }
-
- public LoggerContext getLoggerContext(String name) {
- if (defaultLoggerContext.getName().equals(name)) {
- return defaultLoggerContext;
- } else {
- return null;
- }
+ private LoggerContext defaultLoggerContext;
+
+ public DefaultContextSelector(LoggerContext context) {
+ this.defaultLoggerContext = context;
+ }
+
+ public LoggerContext getLoggerContext() {
+ return getDefaultLoggerContext();
+ }
+
+ public LoggerContext getDefaultLoggerContext() {
+ return defaultLoggerContext;
+ }
+
+ public LoggerContext detachLoggerContext(String loggerContextName) {
+ return defaultLoggerContext;
+ }
+
+ public List<String> getContextNames() {
+ return Arrays.asList(defaultLoggerContext.getName());
+ }
+
+ public LoggerContext getLoggerContext(String name) {
+ if (defaultLoggerContext.getName().equals(name)) {
+ return defaultLoggerContext;
+ } else {
+ return null;
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/selector/servlet/ContextDetachingSCL.java b/logback-classic/src/main/java/ch/qos/logback/classic/selector/servlet/ContextDetachingSCL.java
index 6f7f03b..a737180 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/selector/servlet/ContextDetachingSCL.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/selector/servlet/ContextDetachingSCL.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,38 +29,38 @@ import ch.qos.logback.classic.util.JNDIUtil;
public class ContextDetachingSCL implements ServletContextListener {
- public void contextDestroyed(ServletContextEvent servletContextEvent) {
- String loggerContextName = null;
-
- try {
- Context ctx = JNDIUtil.getInitialContext();
- loggerContextName = (String) JNDIUtil.lookup(ctx, JNDI_CONTEXT_NAME);
- } catch (NamingException ne) {
- }
-
- if (loggerContextName != null) {
- System.out.println("About to detach context named " + loggerContextName);
-
- ContextSelector selector = ContextSelectorStaticBinder.getSingleton().getContextSelector();
- if (selector == null) {
- System.out.println("Selector is null, cannot detach context. Skipping.");
- return;
- }
- LoggerContext context = selector.getLoggerContext(loggerContextName);
- if (context != null) {
- Logger logger = context.getLogger(Logger.ROOT_LOGGER_NAME);
- logger.warn("Stopping logger context " + loggerContextName);
- selector.detachLoggerContext(loggerContextName);
- // when the web-app is destroyed, its logger context should be stopped
- context.stop();
- } else {
- System.out.println("No context named " + loggerContextName + " was found.");
- }
- }
+ public void contextDestroyed(ServletContextEvent servletContextEvent) {
+ String loggerContextName = null;
+
+ try {
+ Context ctx = JNDIUtil.getInitialContext();
+ loggerContextName = (String) JNDIUtil.lookup(ctx, JNDI_CONTEXT_NAME);
+ } catch (NamingException ne) {
}
-
- public void contextInitialized(ServletContextEvent arg0) {
- // do nothing
+
+ if (loggerContextName != null) {
+ System.out.println("About to detach context named " + loggerContextName);
+
+ ContextSelector selector = ContextSelectorStaticBinder.getSingleton().getContextSelector();
+ if(selector == null) {
+ System.out.println("Selector is null, cannot detach context. Skipping.");
+ return;
+ }
+ LoggerContext context = selector.getLoggerContext(loggerContextName);
+ if (context != null) {
+ Logger logger = context.getLogger(Logger.ROOT_LOGGER_NAME);
+ logger.warn("Stopping logger context " + loggerContextName);
+ selector.detachLoggerContext(loggerContextName);
+ // when the web-app is destroyed, its logger context should be stopped
+ context.stop();
+ } else {
+ System.out.println("No context named " + loggerContextName + " was found.");
+ }
}
+ }
+
+ public void contextInitialized(ServletContextEvent arg0) {
+ // do nothing
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/selector/servlet/LoggerContextFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/selector/servlet/LoggerContextFilter.java
index d586e16..4ecc802 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/selector/servlet/LoggerContextFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/selector/servlet/LoggerContextFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -50,31 +50,32 @@ import ch.qos.logback.classic.util.ContextSelectorStaticBinder;
*/
public class LoggerContextFilter implements Filter {
- public void destroy() {
- // do nothing
- }
-
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ public void destroy() {
+ //do nothing
+ }
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- ContextSelector selector = ContextSelectorStaticBinder.getSingleton().getContextSelector();
- ContextJNDISelector sel = null;
+ public void doFilter(ServletRequest request, ServletResponse response,
+ FilterChain chain) throws IOException, ServletException {
- if (selector instanceof ContextJNDISelector) {
- sel = (ContextJNDISelector) selector;
- sel.setLocalContext(lc);
- }
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ ContextSelector selector = ContextSelectorStaticBinder.getSingleton().getContextSelector();
+ ContextJNDISelector sel = null;
- try {
- chain.doFilter(request, response);
- } finally {
- if (sel != null) {
- sel.removeLocalContext();
- }
- }
+ if (selector instanceof ContextJNDISelector) {
+ sel = (ContextJNDISelector)selector;
+ sel.setLocalContext(lc);
}
- public void init(FilterConfig arg0) throws ServletException {
- // do nothing
+ try {
+ chain.doFilter(request, response);
+ } finally {
+ if (sel != null) {
+ sel.removeLocalContext();
+ }
}
+ }
+
+ public void init(FilterConfig arg0) throws ServletException {
+ //do nothing
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactoryUsingJoran.java b/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactoryUsingJoran.java
index e6184df..9b50d50 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactoryUsingJoran.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactoryUsingJoran.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,12 +26,13 @@ import ch.qos.logback.core.sift.SiftingJoranConfiguratorBase;
*/
public class AppenderFactoryUsingJoran extends AbstractAppenderFactoryUsingJoran<ILoggingEvent> {
- AppenderFactoryUsingJoran(List<SaxEvent> eventList, String key, Map<String, String> parentPropertyMap) {
- super(eventList, key, parentPropertyMap);
- }
- public SiftingJoranConfiguratorBase<ILoggingEvent> getSiftingJoranConfigurator(String discriminatingValue) {
- return new SiftingJoranConfigurator(key, discriminatingValue, parentPropertyMap);
- }
+ AppenderFactoryUsingJoran(List<SaxEvent> eventList, String key, Map<String, String> parentPropertyMap) {
+ super(eventList, key, parentPropertyMap);
+ }
+
+ public SiftingJoranConfiguratorBase<ILoggingEvent> getSiftingJoranConfigurator(String discriminatingValue) {
+ return new SiftingJoranConfigurator(key, discriminatingValue, parentPropertyMap);
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/sift/ContextBasedDiscriminator.java b/logback-classic/src/main/java/ch/qos/logback/classic/sift/ContextBasedDiscriminator.java
index 8f0975f..c718833 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/sift/ContextBasedDiscriminator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/sift/ContextBasedDiscriminator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,45 +28,46 @@ import ch.qos.logback.core.sift.AbstractDiscriminator;
*/
public class ContextBasedDiscriminator extends AbstractDiscriminator<ILoggingEvent> {
- private static final String KEY = "contextName";
- private String defaultValue;
+ private static final String KEY = "contextName";
+ private String defaultValue;
- /**
- * Return the name of the current context name as found in the logging event.
- */
- public String getDiscriminatingValue(ILoggingEvent event) {
- String contextName = event.getLoggerContextVO().getName();
+ /**
+ * Return the name of the current context name as found in the logging event.
+ */
+ public String getDiscriminatingValue(ILoggingEvent event) {
+ String contextName = event.getLoggerContextVO().getName();
- if (contextName == null) {
- return defaultValue;
- } else {
- return contextName;
- }
+ if (contextName == null) {
+ return defaultValue;
+ } else {
+ return contextName;
}
+ }
- public String getKey() {
- return KEY;
- }
+ public String getKey() {
+ return KEY;
+ }
- public void setKey(String key) {
- throw new UnsupportedOperationException("Key cannot be set. Using fixed key " + KEY);
- }
+ public void setKey(String key) {
+ throw new UnsupportedOperationException(
+ "Key cannot be set. Using fixed key " + KEY);
+ }
- /**
- * @see #setDefaultValue(String)
- * @return
- */
- public String getDefaultValue() {
- return defaultValue;
- }
+ /**
+ * @see #setDefaultValue(String)
+ * @return
+ */
+ public String getDefaultValue() {
+ return defaultValue;
+ }
- /**
- * The default context name in case the context name is not set for the
- * current logging event.
- *
- * @param defaultValue
- */
- public void setDefaultValue(String defaultValue) {
- this.defaultValue = defaultValue;
- }
+ /**
+ * The default context name in case the context name is not set for the
+ * current logging event.
+ *
+ * @param defaultValue
+ */
+ public void setDefaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/sift/JNDIBasedContextDiscriminator.java b/logback-classic/src/main/java/ch/qos/logback/classic/sift/JNDIBasedContextDiscriminator.java
index a71f7ff..0a255f1 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/sift/JNDIBasedContextDiscriminator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/sift/JNDIBasedContextDiscriminator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,50 +31,52 @@ import ch.qos.logback.core.sift.AbstractDiscriminator;
*/
public class JNDIBasedContextDiscriminator extends AbstractDiscriminator<ILoggingEvent> {
- private static final String KEY = "contextName";
- private String defaultValue;
+ private static final String KEY = "contextName";
+ private String defaultValue;
- /**
- * Return the name of the current context name as found in the logging event.
- */
- public String getDiscriminatingValue(ILoggingEvent event) {
- ContextSelector selector = ContextSelectorStaticBinder.getSingleton().getContextSelector();
+ /**
+ * Return the name of the current context name as found in the logging event.
+ */
+ public String getDiscriminatingValue(ILoggingEvent event) {
+ ContextSelector selector = ContextSelectorStaticBinder.getSingleton()
+ .getContextSelector();
- if (selector == null) {
- return defaultValue;
- }
-
- LoggerContext lc = selector.getLoggerContext();
- if (lc == null) {
- return defaultValue;
- }
-
- return lc.getName();
+ if (selector == null) {
+ return defaultValue;
}
- public String getKey() {
- return KEY;
+ LoggerContext lc = selector.getLoggerContext();
+ if (lc == null) {
+ return defaultValue;
}
- public void setKey(String key) {
- throw new UnsupportedOperationException("Key cannot be set. Using fixed key " + KEY);
- }
+ return lc.getName();
+ }
- /**
- * @see #setDefaultValue(String)
- * @return
- */
- public String getDefaultValue() {
- return defaultValue;
- }
+ public String getKey() {
+ return KEY;
+ }
- /**
- * The default context name in case the context name is not set for the
- * current logging event.
- *
- * @param defaultValue
- */
- public void setDefaultValue(String defaultValue) {
- this.defaultValue = defaultValue;
- }
+ public void setKey(String key) {
+ throw new UnsupportedOperationException(
+ "Key cannot be set. Using fixed key " + KEY);
+ }
+
+ /**
+ * @see #setDefaultValue(String)
+ * @return
+ */
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ /**
+ * The default context name in case the context name is not set for the
+ * current logging event.
+ *
+ * @param defaultValue
+ */
+ public void setDefaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/sift/MDCBasedDiscriminator.java b/logback-classic/src/main/java/ch/qos/logback/classic/sift/MDCBasedDiscriminator.java
index 34d1560..9a3e55c 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/sift/MDCBasedDiscriminator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/sift/MDCBasedDiscriminator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,71 +29,71 @@ import java.util.Map;
*/
public class MDCBasedDiscriminator extends AbstractDiscriminator<ILoggingEvent> {
- private String key;
- private String defaultValue;
+ private String key;
+ private String defaultValue;
- /**
- * Return the value associated with an MDC entry designated by the Key
- * property. If that value is null, then return the value assigned to the
- * DefaultValue property.
- */
- public String getDiscriminatingValue(ILoggingEvent event) {
- // http://jira.qos.ch/browse/LBCLASSIC-213
- Map<String, String> mdcMap = event.getMDCPropertyMap();
- if (mdcMap == null) {
- return defaultValue;
- }
- String mdcValue = mdcMap.get(key);
- if (mdcValue == null) {
- return defaultValue;
- } else {
- return mdcValue;
- }
+ /**
+ * Return the value associated with an MDC entry designated by the Key
+ * property. If that value is null, then return the value assigned to the
+ * DefaultValue property.
+ */
+ public String getDiscriminatingValue(ILoggingEvent event) {
+ // http://jira.qos.ch/browse/LBCLASSIC-213
+ Map<String, String> mdcMap = event.getMDCPropertyMap();
+ if (mdcMap == null) {
+ return defaultValue;
}
-
- @Override
- public void start() {
- int errors = 0;
- if (OptionHelper.isEmpty(key)) {
- errors++;
- addError("The \"Key\" property must be set");
- }
- if (OptionHelper.isEmpty(defaultValue)) {
- errors++;
- addError("The \"DefaultValue\" property must be set");
- }
- if (errors == 0) {
- started = true;
- }
+ String mdcValue = mdcMap.get(key);
+ if (mdcValue == null) {
+ return defaultValue;
+ } else {
+ return mdcValue;
}
+ }
- public String getKey() {
- return key;
+ @Override
+ public void start() {
+ int errors = 0;
+ if (OptionHelper.isEmpty(key)) {
+ errors++;
+ addError("The \"Key\" property must be set");
}
-
- public void setKey(String key) {
- this.key = key;
+ if (OptionHelper.isEmpty(defaultValue)) {
+ errors++;
+ addError("The \"DefaultValue\" property must be set");
}
-
- /**
- * @return
- * @see #setDefaultValue(String)
- */
- public String getDefaultValue() {
- return defaultValue;
+ if (errors == 0) {
+ started = true;
}
+ }
- /**
- * The default MDC value in case the MDC is not set for
- * {@link #setKey(String) mdcKey}.
- * <p/>
- * <p> For example, if {@link #setKey(String) Key} is set to the value
- * "someKey", and the MDC is not set for "someKey", then this appender will
- * use the default value, which you can set with the help of this method.
- *
- * @param defaultValue
- */
- public void setDefaultValue(String defaultValue) {
- this.defaultValue = defaultValue;
- }
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ /**
+ * @return
+ * @see #setDefaultValue(String)
+ */
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ /**
+ * The default MDC value in case the MDC is not set for
+ * {@link #setKey(String) mdcKey}.
+ * <p/>
+ * <p> For example, if {@link #setKey(String) Key} is set to the value
+ * "someKey", and the MDC is not set for "someKey", then this appender will
+ * use the default value, which you can set with the help of this method.
+ *
+ * @param defaultValue
+ */
+ public void setDefaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftAction.java b/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftAction.java
index 690100d..4a0f360 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftAction.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,32 +26,34 @@ import ch.qos.logback.core.joran.spi.ActionException;
import ch.qos.logback.core.joran.spi.InterpretationContext;
public class SiftAction extends Action implements InPlayListener {
- List<SaxEvent> seList;
-
- @Override
- public void begin(InterpretationContext ic, String name, Attributes attributes) throws ActionException {
- seList = new ArrayList<SaxEvent>();
- ic.addInPlayListener(this);
+ List<SaxEvent> seList;
+
+ @Override
+ public void begin(InterpretationContext ic, String name, Attributes attributes)
+ throws ActionException {
+ seList = new ArrayList<SaxEvent>();
+ ic.addInPlayListener(this);
+ }
+
+ @Override
+ public void end(InterpretationContext ic, String name) throws ActionException {
+ ic.removeInPlayListener(this);
+ Object o = ic.peekObject();
+ if (o instanceof SiftingAppender) {
+ SiftingAppender sa = (SiftingAppender) o;
+ Map<String, String> propertyMap = ic.getCopyOfPropertyMap();
+ AppenderFactoryUsingJoran appenderFactory = new AppenderFactoryUsingJoran(seList, sa
+ .getDiscriminatorKey(), propertyMap);
+ sa.setAppenderFactory(appenderFactory);
}
+ }
- @Override
- public void end(InterpretationContext ic, String name) throws ActionException {
- ic.removeInPlayListener(this);
- Object o = ic.peekObject();
- if (o instanceof SiftingAppender) {
- SiftingAppender sa = (SiftingAppender) o;
- Map<String, String> propertyMap = ic.getCopyOfPropertyMap();
- AppenderFactoryUsingJoran appenderFactory = new AppenderFactoryUsingJoran(seList, sa.getDiscriminatorKey(), propertyMap);
- sa.setAppenderFactory(appenderFactory);
- }
- }
+ public void inPlay(SaxEvent event) {
+ seList.add(event);
+ }
- public void inPlay(SaxEvent event) {
- seList.add(event);
- }
-
- public List<SaxEvent> getSeList() {
- return seList;
- }
+ public List<SaxEvent> getSeList() {
+ return seList;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java
index 35030f9..eb43cc7 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -32,22 +32,23 @@ import org.slf4j.Marker;
*/
public class SiftingAppender extends SiftingAppenderBase<ILoggingEvent> {
- @Override
- protected long getTimestamp(ILoggingEvent event) {
- return event.getTimeStamp();
- }
+ @Override
+ protected long getTimestamp(ILoggingEvent event) {
+ return event.getTimeStamp();
+ }
+
- @Override
- @DefaultClass(MDCBasedDiscriminator.class)
- public void setDiscriminator(Discriminator<ILoggingEvent> discriminator) {
- super.setDiscriminator(discriminator);
- }
+ @Override
+ @DefaultClass(MDCBasedDiscriminator.class)
+ public void setDiscriminator(Discriminator<ILoggingEvent> discriminator) {
+ super.setDiscriminator(discriminator);
+ }
- protected boolean eventMarksEndOfLife(ILoggingEvent event) {
- Marker marker = event.getMarker();
- if (marker == null)
- return false;
+ protected boolean eventMarksEndOfLife(ILoggingEvent event) {
+ Marker marker = event.getMarker();
+ if(marker == null)
+ return false;
- return marker.contains(ClassicConstants.FINALIZE_SESSION_MARKER);
- }
+ return marker.contains(ClassicConstants.FINALIZE_SESSION_MARKER);
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingJoranConfigurator.java b/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingJoranConfigurator.java
index f794e0f..484d4c9 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingJoranConfigurator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingJoranConfigurator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,49 +28,52 @@ import ch.qos.logback.core.joran.spi.ElementSelector;
import ch.qos.logback.core.joran.spi.RuleStore;
import ch.qos.logback.core.sift.SiftingJoranConfiguratorBase;
-public class SiftingJoranConfigurator extends SiftingJoranConfiguratorBase<ILoggingEvent> {
+public class SiftingJoranConfigurator extends SiftingJoranConfiguratorBase<ILoggingEvent> {
- SiftingJoranConfigurator(String key, String value, Map<String, String> parentPropertyMap) {
- super(key, value, parentPropertyMap);
- }
-
- @Override
- protected ElementPath initialElementPath() {
- return new ElementPath("configuration");
- }
- @Override
- protected void addInstanceRules(RuleStore rs) {
- super.addInstanceRules(rs);
- rs.addRule(new ElementSelector("configuration/appender"), new AppenderAction<ILoggingEvent>());
- }
+ SiftingJoranConfigurator(String key, String value, Map<String, String> parentPropertyMap) {
+ super(key, value, parentPropertyMap);
+ }
+
+ @Override
+ protected ElementPath initialElementPath() {
+ return new ElementPath("configuration");
+ }
+
+ @Override
+ protected void addInstanceRules(RuleStore rs) {
+ super.addInstanceRules(rs);
+ rs.addRule(new ElementSelector("configuration/appender"), new AppenderAction());
+ }
- @Override
- protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
- DefaultNestedComponentRules.addDefaultNestedComponentRegistryRules(registry);
- }
- @Override
- protected void buildInterpreter() {
- super.buildInterpreter();
- Map<String, Object> omap = interpreter.getInterpretationContext().getObjectMap();
- omap.put(ActionConst.APPENDER_BAG, new HashMap<String, Appender<?>>());
- //omap.put(ActionConst.FILTER_CHAIN_BAG, new HashMap());
- Map<String, String> propertiesMap = new HashMap<String, String>();
- propertiesMap.putAll(parentPropertyMap);
- propertiesMap.put(key, value);
- interpreter.setInterpretationContextPropertiesMap(propertiesMap);
- }
+ @Override
+ protected void addDefaultNestedComponentRegistryRules(
+ DefaultNestedComponentRegistry registry) {
+ DefaultNestedComponentRules.addDefaultNestedComponentRegistryRules(registry);
+ }
+
+ @Override
+ protected void buildInterpreter() {
+ super.buildInterpreter();
+ Map<String, Object> omap = interpreter.getInterpretationContext().getObjectMap();
+ omap.put(ActionConst.APPENDER_BAG, new HashMap());
+ omap.put(ActionConst.FILTER_CHAIN_BAG, new HashMap());
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.putAll(parentPropertyMap);
+ propertiesMap.put(key, value);
+ interpreter.setInterpretationContextPropertiesMap(propertiesMap);
+ }
- @SuppressWarnings("unchecked")
- public Appender<ILoggingEvent> getAppender() {
- Map<String, Object> omap = interpreter.getInterpretationContext().getObjectMap();
- HashMap<String, Appender<?>> appenderMap = (HashMap<String, Appender<?>>) omap.get(ActionConst.APPENDER_BAG);
- oneAndOnlyOneCheck(appenderMap);
- Collection<Appender<?>> values = appenderMap.values();
- if (values.size() == 0) {
- return null;
- }
- return (Appender<ILoggingEvent>) values.iterator().next();
+ @SuppressWarnings("unchecked")
+ public Appender<ILoggingEvent> getAppender() {
+ Map<String, Object> omap = interpreter.getInterpretationContext().getObjectMap();
+ HashMap appenderMap = (HashMap) omap.get(ActionConst.APPENDER_BAG);
+ oneAndOnlyOneCheck(appenderMap);
+ Collection values = appenderMap.values();
+ if(values.size() == 0) {
+ return null;
}
+ return (Appender<ILoggingEvent>) values.iterator().next();
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/CallerData.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/CallerData.java
index 03f66da..ee7e290 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/CallerData.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/CallerData.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,101 +25,107 @@ import java.util.List;
*/
public class CallerData {
- /**
- * When caller information is not available this constant is used for file
- * name, method name, etc.
- */
- public static final String NA = "?";
-
- // All logger call's in log4j-over-slf4j use the Category class
- private static final String LOG4J_CATEGORY = "org.apache.log4j.Category";
- private static final String SLF4J_BOUNDARY = "org.slf4j.Logger";
-
- /**
- * When caller information is not available this constant is used for the line
- * number.
- */
- public static final int LINE_NA = -1;
-
- public static final String CALLER_DATA_NA = "?#?:?" + CoreConstants.LINE_SEPARATOR;
-
- /**
- * This value is returned in case no caller data could be extracted.
- */
- public static final StackTraceElement[] EMPTY_CALLER_DATA_ARRAY = new StackTraceElement[0];
-
- /**
- * Extract caller data information as an array based on a Throwable passed as
- * parameter
- */
- public static StackTraceElement[] extract(Throwable t, String fqnOfInvokingClass, final int maxDepth, List<String> frameworkPackageList) {
- if (t == null) {
- return null;
- }
- StackTraceElement[] steArray = t.getStackTrace();
- StackTraceElement[] callerDataArray;
-
- int found = LINE_NA;
- for (int i = 0; i < steArray.length; i++) {
- if (isInFrameworkSpace(steArray[i].getClassName(), fqnOfInvokingClass, frameworkPackageList)) {
- // the caller is assumed to be the next stack frame, hence the +1.
- found = i + 1;
- } else {
- if (found != LINE_NA) {
- break;
- }
- }
- }
+ /**
+ * When caller information is not available this constant is used for file
+ * name, method name, etc.
+ */
+ public static final String NA = "?";
- // we failed to extract caller data
- if (found == LINE_NA) {
- return EMPTY_CALLER_DATA_ARRAY;
- }
+ // All logger call's in log4j-over-slf4j use the Category class
+ private static final String LOG4J_CATEGORY = "org.apache.log4j.Category";
+ private static final String SLF4J_BOUNDARY = "org.slf4j.Logger";
- int availableDepth = steArray.length - found;
- int desiredDepth = maxDepth < (availableDepth) ? maxDepth : availableDepth;
+ /**
+ * When caller information is not available this constant is used for the line
+ * number.
+ */
+ public static final int LINE_NA = -1;
- callerDataArray = new StackTraceElement[desiredDepth];
- for (int i = 0; i < desiredDepth; i++) {
- callerDataArray[i] = steArray[found + i];
- }
- return callerDataArray;
+ public static final String CALLER_DATA_NA = "?#?:?" + CoreConstants.LINE_SEPARATOR;
+
+ /**
+ * This value is returned in case no caller data could be extracted.
+ */
+ public static final StackTraceElement[] EMPTY_CALLER_DATA_ARRAY = new StackTraceElement[0];
+
+
+ /**
+ * Extract caller data information as an array based on a Throwable passed as
+ * parameter
+ */
+ public static StackTraceElement[] extract(Throwable t,
+ String fqnOfInvokingClass, final int maxDepth,
+ List<String> frameworkPackageList) {
+ if (t == null) {
+ return null;
}
- static boolean isInFrameworkSpace(String currentClass, String fqnOfInvokingClass, List<String> frameworkPackageList) {
- // the check for org.apache.log4j.Category class is intended to support
- // log4j-over-slf4j. it solves http://bugzilla.slf4j.org/show_bug.cgi?id=66
- if (currentClass.equals(fqnOfInvokingClass) || currentClass.equals(LOG4J_CATEGORY) || currentClass.startsWith(SLF4J_BOUNDARY)
- || isInFrameworkSpaceList(currentClass, frameworkPackageList)) {
- return true;
- } else {
- return false;
+ StackTraceElement[] steArray = t.getStackTrace();
+ StackTraceElement[] callerDataArray;
+
+ int found = LINE_NA;
+ for (int i = 0; i < steArray.length; i++) {
+ if (isInFrameworkSpace(steArray[i].getClassName(),
+ fqnOfInvokingClass, frameworkPackageList)) {
+ // the caller is assumed to be the next stack frame, hence the +1.
+ found = i + 1;
+ } else {
+ if (found != LINE_NA) {
+ break;
}
+ }
}
- /**
- * Is currentClass present in the list of packages considered part of the logging framework?
- */
- private static boolean isInFrameworkSpaceList(String currentClass, List<String> frameworkPackageList) {
- if (frameworkPackageList == null)
- return false;
-
- for (String s : frameworkPackageList) {
- if (currentClass.startsWith(s))
- return true;
- }
- return false;
+ // we failed to extract caller data
+ if (found == LINE_NA) {
+ return EMPTY_CALLER_DATA_ARRAY;
}
- /**
- * Returns a StackTraceElement where all string fields are set to {@link #NA} and line number is set to {@link #LINE_NA}.
- *
- * @return StackTraceElement with values set to NA constants.
- * @since 1.0.10
- */
- public static StackTraceElement naInstance() {
- return new StackTraceElement(NA, NA, NA, LINE_NA);
+ int availableDepth = steArray.length - found;
+ int desiredDepth = maxDepth < (availableDepth) ? maxDepth : availableDepth;
+
+ callerDataArray = new StackTraceElement[desiredDepth];
+ for (int i = 0; i < desiredDepth; i++) {
+ callerDataArray[i] = steArray[found + i];
+ }
+ return callerDataArray;
+ }
+
+ static boolean isInFrameworkSpace(String currentClass,
+ String fqnOfInvokingClass, List<String> frameworkPackageList) {
+ // the check for org.apache.log4j.Category class is intended to support
+ // log4j-over-slf4j. it solves http://bugzilla.slf4j.org/show_bug.cgi?id=66
+ if (currentClass.equals(fqnOfInvokingClass) || currentClass.equals(LOG4J_CATEGORY)
+ || currentClass.startsWith(SLF4J_BOUNDARY) || isInFrameworkSpaceList(currentClass, frameworkPackageList)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Is currentClass present in the list of packages considered part of the logging framework?
+ */
+ private static boolean isInFrameworkSpaceList(String currentClass, List<String> frameworkPackageList) {
+ if (frameworkPackageList == null)
+ return false;
+
+ for (String s : frameworkPackageList) {
+ if (currentClass.startsWith(s))
+ return true;
}
+ return false;
+ }
+
+ /**
+ * Returns a StackTraceElement where all string fields are set to {@link #NA} and line number is set to {@link #LINE_NA}.
+ *
+ * @return StackTraceElement with values set to NA constants.
+ * @since 1.0.10
+ */
+ public static StackTraceElement naInstance() {
+ return new StackTraceElement(NA, NA, NA, LINE_NA);
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassPackagingData.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassPackagingData.java
index 0a6b2b9..d5aff3e 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassPackagingData.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassPackagingData.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,65 +17,65 @@ import java.io.Serializable;
public class ClassPackagingData implements Serializable {
- private static final long serialVersionUID = -804643281218337001L;
- final String codeLocation;
- final String version;
- private final boolean exact;
+ private static final long serialVersionUID = -804643281218337001L;
+ final String codeLocation;
+ final String version;
+ private final boolean exact;
+
+ public ClassPackagingData(String codeLocation, String version) {
+ this.codeLocation = codeLocation;
+ this.version = version;
+ this.exact = true;
+ }
- public ClassPackagingData(String codeLocation, String version) {
- this.codeLocation = codeLocation;
- this.version = version;
- this.exact = true;
- }
+ public ClassPackagingData(String classLocation, String version, boolean exact) {
+ this.codeLocation = classLocation;
+ this.version = version;
+ this.exact = exact;
+ }
+
+ public String getCodeLocation() {
+ return codeLocation;
+ }
- public ClassPackagingData(String classLocation, String version, boolean exact) {
- this.codeLocation = classLocation;
- this.version = version;
- this.exact = exact;
- }
+ public String getVersion() {
+ return version;
+ }
- public String getCodeLocation() {
- return codeLocation;
- }
+ public boolean isExact() {
+ return exact;
+ }
- public String getVersion() {
- return version;
- }
-
- public boolean isExact() {
- return exact;
- }
-
- @Override
- public int hashCode() {
- final int PRIME = 31;
- int result = 1;
- result = PRIME * result + ((codeLocation == null) ? 0 : codeLocation.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final ClassPackagingData other = (ClassPackagingData) obj;
- if (codeLocation == null) {
- if (other.codeLocation != null)
- return false;
- } else if (!codeLocation.equals(other.codeLocation))
- return false;
- if (exact != other.exact)
- return false;
- if (version == null) {
- if (other.version != null)
- return false;
- } else if (!version.equals(other.version))
- return false;
- return true;
- }
+ @Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + ((codeLocation == null) ? 0 : codeLocation.hashCode());
+ return result;
+ }
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final ClassPackagingData other = (ClassPackagingData) obj;
+ if (codeLocation == null) {
+ if (other.codeLocation != null)
+ return false;
+ } else if (!codeLocation.equals(other.codeLocation))
+ return false;
+ if (exact != other.exact)
+ return false;
+ if (version == null) {
+ if (other.version != null)
+ return false;
+ } else if (!version.equals(other.version))
+ return false;
+ return true;
+ }
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/Configurator.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/Configurator.java
deleted file mode 100644
index 4316e2f..0000000
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/Configurator.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.classic.spi;
-
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.core.spi.ContextAware;
-
-/**
- * Allows programmatic initialization and configuration of Logback.
- * The ServiceLoader is typically used to instantiate implementations and
- * thus implementations will need to follow the guidelines of the ServiceLoader
- * specifically a no-arg constructor is required.
- */
-public interface Configurator extends ContextAware {
-
- /**
- * The context will also be set before this method is called via
- * {@link ContextAware#setContext(ch.qos.logback.core.Context)}.
- */
- public void configure(LoggerContext loggerContext);
-
-}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/EventArgUtil.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/EventArgUtil.java
index ac1d7a6..ca9d21f 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/EventArgUtil.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/EventArgUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,39 +15,40 @@ package ch.qos.logback.classic.spi;
public class EventArgUtil {
- public static final Throwable extractThrowable(Object[] argArray) {
- if (argArray == null || argArray.length == 0) {
- return null;
- }
- final Object lastEntry = argArray[argArray.length - 1];
- if (lastEntry instanceof Throwable) {
- return (Throwable) lastEntry;
- }
- return null;
+ public static final Throwable extractThrowable(Object[] argArray) {
+ if (argArray == null || argArray.length == 0) {
+ return null;
}
- /**
- * This method should be called only if {@link #successfulExtraction(Throwable)} returns true.
- *
- * @param argArray
- * @return
- */
- public static Object[] trimmedCopy(Object[] argArray) {
- if (argArray == null || argArray.length == 0) {
- throw new IllegalStateException("non-sensical empty or null argument array");
- }
- final int trimemdLen = argArray.length - 1;
- Object[] trimmed = new Object[trimemdLen];
- System.arraycopy(argArray, 0, trimmed, 0, trimemdLen);
- return trimmed;
+ final Object lastEntry = argArray[argArray.length - 1];
+ if (lastEntry instanceof Throwable) {
+ return (Throwable) lastEntry;
}
+ return null;
+ }
- public static Object[] arrangeArguments(Object[] argArray) {
- return argArray;
+ /**
+ * This method should be called only if {@link #successfulExtraction(Throwable)} returns true.
+ *
+ * @param argArray
+ * @return
+ */
+ public static Object[] trimmedCopy(Object[] argArray) {
+ if (argArray == null || argArray.length == 0) {
+ throw new IllegalStateException("non-sensical empty or null argument array");
}
+ final int trimemdLen = argArray.length - 1;
+ Object[] trimmed = new Object[trimemdLen];
+ System.arraycopy(argArray, 0, trimmed, 0, trimemdLen);
+ return trimmed;
+ }
- public static boolean successfulExtraction(Throwable throwable) {
- return throwable != null;
- }
+ public static Object[] arrangeArguments(Object[] argArray) {
+ return argArray;
+ }
+
+ public static boolean successfulExtraction(Throwable throwable) {
+ return throwable != null;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ILoggingEvent.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ILoggingEvent.java
index eaf7093..5fe291d 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ILoggingEvent.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ILoggingEvent.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,59 +29,58 @@ import ch.qos.logback.core.spi.DeferredProcessingAware;
*/
public interface ILoggingEvent extends DeferredProcessingAware {
- String getThreadName();
+ String getThreadName();
- Level getLevel();
+ Level getLevel();
- String getMessage();
+ String getMessage();
- Object[] getArgumentArray();
+ Object[] getArgumentArray();
- String getFormattedMessage();
+ String getFormattedMessage();
- String getLoggerName();
+ String getLoggerName();
- LoggerContextVO getLoggerContextVO();
+ LoggerContextVO getLoggerContextVO();
- IThrowableProxy getThrowableProxy();
+ IThrowableProxy getThrowableProxy();
- /**
- * Return caller data associated with this event. Note that calling this event
- * may trigger the computation of caller data.
- *
- * @return the caller data associated with this event.
- *
- * @see #hasCallerData()
- */
- StackTraceElement[] getCallerData();
+ /**
+ * Return caller data associated with this event. Note that calling this event
+ * may trigger the computation of caller data.
+ *
+ * @return the caller data associated with this event.
+ *
+ * @see #hasCallerData()
+ */
+ StackTraceElement[] getCallerData();
- /**
- * If this event has caller data, then true is returned. Otherwise the
- * returned value is null.
- *
- * <p>Logback components wishing to use caller data if available without
- * causing it to be computed can invoke this method before invoking
- * {@link #getCallerData()}.
- *
- * @return whether this event has caller data
- */
- boolean hasCallerData();
+ /**
+ * If this event has caller data, then true is returned. Otherwise the
+ * returned value is null.
+ *
+ * <p>Logback components wishing to use caller data if available without
+ * causing it to be computed can invoke this method before invoking
+ * {@link #getCallerData()}.
+ *
+ * @return whether this event has caller data
+ */
+ boolean hasCallerData();
- Marker getMarker();
+ Marker getMarker();
- /**
- * Returns the MDC map. The returned value can be an empty map but not null.
- */
- Map<String, String> getMDCPropertyMap();
+ /**
+ * Returns the MDC map. The returned value can be an empty map but not null.
+ */
+ Map<String, String> getMDCPropertyMap();
- /**
- * Synonym for [@link #getMDCPropertyMap}.
- * @deprecated Replaced by [@link #getMDCPropertyMap}
- */
- Map<String, String> getMdc();
+ /**
+ * Synonym for [@link #getMDCPropertyMap}.
+ * @deprecated Replaced by [@link #getMDCPropertyMap}
+ */
+ Map<String, String> getMdc();
+ long getTimeStamp();
- long getTimeStamp();
-
- void prepareForDeferredProcessing();
+ void prepareForDeferredProcessing();
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/IThrowableProxy.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/IThrowableProxy.java
index 584d180..2483165 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/IThrowableProxy.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/IThrowableProxy.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,15 +14,10 @@
package ch.qos.logback.classic.spi;
public interface IThrowableProxy {
- String getMessage();
-
- String getClassName();
-
- StackTraceElementProxy[] getStackTraceElementProxyArray();
-
- int getCommonFrames();
-
- IThrowableProxy getCause();
-
- IThrowableProxy[] getSuppressed();
+ String getMessage();
+ String getClassName();
+ StackTraceElementProxy[] getStackTraceElementProxyArray();
+ int getCommonFrames();
+ IThrowableProxy getCause();
+ IThrowableProxy[] getSuppressed();
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerComparator.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerComparator.java
index 391d501..04307c4 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerComparator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerComparator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,17 +19,17 @@ import ch.qos.logback.classic.Logger;
public class LoggerComparator implements Comparator<Logger> {
- public int compare(Logger l1, Logger l2) {
- if (l1.getName().equals(l2.getName())) {
- return 0;
- }
- if (l1.getName().equals(Logger.ROOT_LOGGER_NAME)) {
- return -1;
- }
- if (l2.getName().equals(Logger.ROOT_LOGGER_NAME)) {
- return 1;
- }
- return l1.getName().compareTo(l2.getName());
+ public int compare(Logger l1, Logger l2) {
+ if (l1.getName().equals(l2.getName())) {
+ return 0;
}
+ if (l1.getName().equals(Logger.ROOT_LOGGER_NAME)) {
+ return -1;
+ }
+ if (l2.getName().equals(Logger.ROOT_LOGGER_NAME)) {
+ return 1;
+ }
+ return l1.getName().compareTo(l2.getName());
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextAware.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextAware.java
index 85d0d6a..3c7ea10 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextAware.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextAware.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,16 +16,18 @@ package ch.qos.logback.classic.spi;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.spi.ContextAware;
+
public interface LoggerContextAware extends ContextAware {
- /**
- * Set owning logger context for this component. This operation can
- * only be performed once. Once set, the owning context cannot be changed.
- *
- * @param context The context where this component is attached.
- * @throws IllegalStateException If you try to change the context after it
- * has been set.
- **/
- void setLoggerContext(LoggerContext context);
+ /**
+ * Set owning logger context for this component. This operation can
+ * only be performed once. Once set, the owning context cannot be changed.
+ *
+ * @param context The context where this component is attached.
+ * @throws IllegalStateException If you try to change the context after it
+ * has been set.
+ **/
+ void setLoggerContext(LoggerContext context);
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextAwareBase.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextAwareBase.java
index 834a5c1..3de07db 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextAwareBase.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextAwareBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,33 +17,34 @@ import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.spi.ContextAwareBase;
-public class LoggerContextAwareBase extends ContextAwareBase implements LoggerContextAware {
-
- /**
- * Set the owning context. The owning context cannot be set more than
- * once.
- */
- public void setLoggerContext(LoggerContext context) {
- super.setContext(context);
- }
- public void setContext(Context context) {
- // check that the context is of type LoggerContext. Otherwise, throw an exception
- // Context == null is a degenerate case but nonetheless permitted.
- if (context instanceof LoggerContext || context == null) {
- super.setContext(context);
- } else {
- throw new IllegalArgumentException("LoggerContextAwareBase only accepts contexts of type c.l.classic.LoggerContext");
- }
- }
+public class LoggerContextAwareBase extends ContextAwareBase implements LoggerContextAware {
+
+ /**
+ * Set the owning context. The owning context cannot be set more than
+ * once.
+ */
+ public void setLoggerContext(LoggerContext context) {
+ super.setContext(context);
+ }
- /**
- * Return the {@link LoggerContext} this component is attached to.
- *
- * @return The owning LoggerContext
- */
- public LoggerContext getLoggerContext() {
- return (LoggerContext) context;
+ public void setContext(Context context) {
+ // check that the context is of type LoggerContext. Otherwise, throw an exception
+ // Context == null is a degenerate case but nonetheless permitted.
+ if(context instanceof LoggerContext || context == null) {
+ super.setContext(context);
+ } else {
+ throw new IllegalArgumentException("LoggerContextAwareBase only accepts contexts of type c.l.classic.LoggerContext");
}
+ }
+ /**
+ * Return the {@link LoggerContext} this component is attached to.
+ *
+ * @return The owning LoggerContext
+ */
+ public LoggerContext getLoggerContext() {
+ return (LoggerContext) context;
+ }
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextListener.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextListener.java
index bc27904..a4e3667 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextListener.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextListener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,19 +18,16 @@ import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
public interface LoggerContextListener {
+
- /**
- * Some listeners should not be removed when the LoggerContext is
- * reset. Such listeners are said to be reset resistant.
- * @return whether this listener is reset resistant or not.
- */
- boolean isResetResistant();
-
- void onStart(LoggerContext context);
-
- void onReset(LoggerContext context);
-
- void onStop(LoggerContext context);
-
- void onLevelChange(Logger logger, Level level);
+ /**
+ * Some listeners should not be removed when the LoggerContext is
+ * reset. Such listeners are said to be reset resistant.
+ * @return whether this listener is reset resistant or not.
+ */
+ boolean isResetResistant();
+ void onStart(LoggerContext context);
+ void onReset(LoggerContext context);
+ void onStop(LoggerContext context);
+ void onLevelChange(Logger logger, Level level);
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextVO.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextVO.java
index 5878652..e653242 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextVO.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextVO.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -35,66 +35,65 @@ import ch.qos.logback.classic.LoggerContext;
*/
public class LoggerContextVO implements Serializable {
- private static final long serialVersionUID = 5488023392483144387L;
-
- final String name;
- final Map<String, String> propertyMap;
- final long birthTime;
-
- public LoggerContextVO(LoggerContext lc) {
- this.name = lc.getName();
- this.propertyMap = lc.getCopyOfPropertyMap();
- this.birthTime = lc.getBirthTime();
- }
-
- public LoggerContextVO(String name, Map<String, String> propertyMap, long birthTime) {
- this.name = name;
- this.propertyMap = propertyMap;
- this.birthTime = birthTime;
- }
-
- public String getName() {
- return name;
- }
-
- public Map<String, String> getPropertyMap() {
- return propertyMap;
- }
-
- public long getBirthTime() {
- return birthTime;
- }
-
- @Override
- public String toString() {
- return "LoggerContextVO{" + "name='" + name + '\'' + ", propertyMap=" + propertyMap + ", birthTime=" + birthTime + '}';
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o)
- return true;
- if (!(o instanceof LoggerContextVO))
- return false;
-
- LoggerContextVO that = (LoggerContextVO) o;
-
- if (birthTime != that.birthTime)
- return false;
- if (name != null ? !name.equals(that.name) : that.name != null)
- return false;
- if (propertyMap != null ? !propertyMap.equals(that.propertyMap) : that.propertyMap != null)
- return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = name != null ? name.hashCode() : 0;
- result = 31 * result + (propertyMap != null ? propertyMap.hashCode() : 0);
- result = 31 * result + (int) (birthTime ^ (birthTime >>> 32));
-
- return result;
- }
+ private static final long serialVersionUID = 5488023392483144387L;
+
+ final String name;
+ final Map<String, String> propertyMap;
+ final long birthTime;
+
+ public LoggerContextVO(LoggerContext lc) {
+ this.name = lc.getName();
+ this.propertyMap = lc.getCopyOfPropertyMap();
+ this.birthTime = lc.getBirthTime();
+ }
+
+ public LoggerContextVO(String name, Map<String,String> propertyMap, long birthTime) {
+ this.name = name;
+ this.propertyMap = propertyMap;
+ this.birthTime = birthTime;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Map<String, String> getPropertyMap() {
+ return propertyMap;
+ }
+
+ public long getBirthTime() {
+ return birthTime;
+ }
+
+
+ @Override
+ public String toString() {
+ return "LoggerContextVO{" +
+ "name='" + name + '\'' +
+ ", propertyMap=" + propertyMap +
+ ", birthTime=" + birthTime +
+ '}';
+ }
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof LoggerContextVO)) return false;
+
+ LoggerContextVO that = (LoggerContextVO) o;
+
+ if (birthTime != that.birthTime) return false;
+ if (name != null ? !name.equals(that.name) : that.name != null) return false;
+ if (propertyMap != null ? !propertyMap.equals(that.propertyMap) : that.propertyMap != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = name != null ? name.hashCode() : 0;
+ result = 31 * result + (propertyMap != null ? propertyMap.hashCode() : 0);
+ result = 31 * result + (int) (birthTime ^ (birthTime >>> 32));
+
+ return result;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerRemoteView.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerRemoteView.java
index e966dea..e92dea2 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerRemoteView.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerRemoteView.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,23 +28,24 @@ import ch.qos.logback.classic.LoggerContext;
*/
public class LoggerRemoteView implements Serializable {
- private static final long serialVersionUID = 5028223666108713696L;
+ private static final long serialVersionUID = 5028223666108713696L;
- final LoggerContextVO loggerContextView;
- final String name;
+ final LoggerContextVO loggerContextView;
+ final String name;
- public LoggerRemoteView(String name, LoggerContext lc) {
- this.name = name;
- assert lc.getLoggerContextRemoteView() != null;
- loggerContextView = lc.getLoggerContextRemoteView();
- }
+ public LoggerRemoteView(String name, LoggerContext lc) {
+ this.name = name;
+ assert lc.getLoggerContextRemoteView() != null;
+ loggerContextView = lc.getLoggerContextRemoteView();
+ }
- public LoggerContextVO getLoggerContextView() {
- return loggerContextView;
- }
+ public LoggerContextVO getLoggerContextView() {
+ return loggerContextView;
+ }
- public String getName() {
- return name;
- }
+ public String getName() {
+ return name;
+ }
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEvent.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEvent.java
index 1fefe6f..0f11908 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEvent.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEvent.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,18 +15,18 @@ package ch.qos.logback.classic.spi;
import java.io.IOException;
import java.io.ObjectOutputStream;
-import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
import org.slf4j.MDC;
import org.slf4j.Marker;
+import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MessageFormatter;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.util.LogbackMDCAdapter;
-
import org.slf4j.spi.MDCAdapter;
/**
@@ -47,314 +47,321 @@ import org.slf4j.spi.MDCAdapter;
*/
public class LoggingEvent implements ILoggingEvent {
- /**
- * Fully qualified name of the calling Logger class. This field does not
- * survive serialization.
- * <p/>
- * <p/>
- * Note that the getCallerInformation() method relies on this fact.
- */
- transient String fqnOfLoggerClass;
-
- /**
- * The name of thread in which this logging event was generated.
- */
- private String threadName;
-
- private String loggerName;
- private LoggerContext loggerContext;
- private LoggerContextVO loggerContextVO;
-
- /**
- * Level of logging event.
- * <p/>
- * <p>
- * This field should not be accessed directly. You should use the
- * {@link #getLevel} method instead.
- * </p>
- */
- private transient Level level;
-
- private String message;
-
- // we gain significant space at serialization time by marking
- // formattedMessage as transient and constructing it lazily in
- // getFormattedMessage()
- transient String formattedMessage;
-
- private transient Object[] argumentArray;
-
- private ThrowableProxy throwableProxy;
-
- private StackTraceElement[] callerDataArray;
-
- private Marker marker;
-
- private Map<String, String> mdcPropertyMap;
-
- /**
- * The number of milliseconds elapsed from 1/1/1970 until logging event was
- * created.
- */
- private long timeStamp;
-
- public LoggingEvent() {
- }
-
- public LoggingEvent(String fqcn, Logger logger, Level level, String message, Throwable throwable, Object[] argArray) {
- this.fqnOfLoggerClass = fqcn;
- this.loggerName = logger.getName();
- this.loggerContext = logger.getLoggerContext();
- this.loggerContextVO = loggerContext.getLoggerContextRemoteView();
- this.level = level;
-
- this.message = message;
- this.argumentArray = argArray;
-
- if (throwable == null) {
- throwable = extractThrowableAnRearrangeArguments(argArray);
- }
-
- if (throwable != null) {
- this.throwableProxy = new ThrowableProxy(throwable);
- LoggerContext lc = logger.getLoggerContext();
- if (lc.isPackagingDataEnabled()) {
- this.throwableProxy.calculatePackagingData();
- }
- }
-
- timeStamp = System.currentTimeMillis();
- }
-
- private Throwable extractThrowableAnRearrangeArguments(Object[] argArray) {
- Throwable extractedThrowable = EventArgUtil.extractThrowable(argArray);
- if (EventArgUtil.successfulExtraction(extractedThrowable)) {
- this.argumentArray = EventArgUtil.trimmedCopy(argArray);
- }
- return extractedThrowable;
- }
-
- public void setArgumentArray(Object[] argArray) {
- if (this.argumentArray != null) {
- throw new IllegalStateException("argArray has been already set");
- }
- this.argumentArray = argArray;
- }
-
- public Object[] getArgumentArray() {
- return this.argumentArray;
- }
-
- public Level getLevel() {
- return level;
- }
-
- public String getLoggerName() {
- return loggerName;
- }
-
- public void setLoggerName(String loggerName) {
- this.loggerName = loggerName;
- }
-
- public String getThreadName() {
- if (threadName == null) {
- threadName = (Thread.currentThread()).getName();
- }
- return threadName;
- }
-
- /**
- * @param threadName The threadName to set.
- * @throws IllegalStateException If threadName has been already set.
- */
- public void setThreadName(String threadName) throws IllegalStateException {
- if (this.threadName != null) {
- throw new IllegalStateException("threadName has been already set");
- }
- this.threadName = threadName;
- }
-
- /**
- * Returns the throwable information contained within this event. May be
- * <code>null</code> if there is no such information.
- */
- public IThrowableProxy getThrowableProxy() {
- return throwableProxy;
- }
-
- /**
- * Set this event's throwable information.
- */
- public void setThrowableProxy(ThrowableProxy tp) {
- if (throwableProxy != null) {
- throw new IllegalStateException("ThrowableProxy has been already set.");
- } else {
- throwableProxy = tp;
- }
- }
-
- /**
- * This method should be called prior to serializing an event. It should also
- * be called when using asynchronous or deferred logging.
- * <p/>
- * <p/>
- * Note that due to performance concerns, this method does NOT extract caller
- * data. It is the responsibility of the caller to extract caller information.
- */
- public void prepareForDeferredProcessing() {
- this.getFormattedMessage();
- this.getThreadName();
- // fixes http://jira.qos.ch/browse/LBCLASSIC-104
- this.getMDCPropertyMap();
- }
-
- public LoggerContextVO getLoggerContextVO() {
- return loggerContextVO;
- }
-
- public void setLoggerContextRemoteView(LoggerContextVO loggerContextVO) {
- this.loggerContextVO = loggerContextVO;
- }
-
- public String getMessage() {
- return message;
- }
-
- public void setMessage(String message) {
- if (this.message != null) {
- throw new IllegalStateException("The message for this event has been set already.");
- }
- this.message = message;
- }
-
- public long getTimeStamp() {
- return timeStamp;
- }
-
- public void setTimeStamp(long timeStamp) {
- this.timeStamp = timeStamp;
- }
-
- public void setLevel(Level level) {
- if (this.level != null) {
- throw new IllegalStateException("The level has been already set for this event.");
- }
- this.level = level;
- }
-
- /**
- * Get the caller information for this logging event. If caller information is
- * null at the time of its invocation, this method extracts location
- * information. The collected information is cached for future use.
- * <p/>
- * <p>
- * Note that after serialization it is impossible to correctly extract caller
- * information.
- * </p>
- */
- public StackTraceElement[] getCallerData() {
- if (callerDataArray == null) {
- callerDataArray = CallerData
- .extract(new Throwable(), fqnOfLoggerClass, loggerContext.getMaxCallerDataDepth(), loggerContext.getFrameworkPackages());
- }
- return callerDataArray;
- }
-
- public boolean hasCallerData() {
- return (callerDataArray != null);
- }
-
- public void setCallerData(StackTraceElement[] callerDataArray) {
- this.callerDataArray = callerDataArray;
- }
-
- public Marker getMarker() {
- return marker;
- }
-
- public void setMarker(Marker marker) {
- if (this.marker != null) {
- throw new IllegalStateException("The marker has been already set for this event.");
- }
- this.marker = marker;
- }
-
- public long getContextBirthTime() {
- return loggerContextVO.getBirthTime();
- }
+ /**
+ * Fully qualified name of the calling Logger class. This field does not
+ * survive serialization.
+ * <p/>
+ * <p/>
+ * Note that the getCallerInformation() method relies on this fact.
+ */
+ transient String fqnOfLoggerClass;
- // lazy computation as suggested in LOGBACK-495
- public String getFormattedMessage() {
- if (formattedMessage != null) {
- return formattedMessage;
- }
- if (argumentArray != null) {
- formattedMessage = MessageFormatter.arrayFormat(message, argumentArray).getMessage();
- } else {
- formattedMessage = message;
- }
-
- return formattedMessage;
- }
+ /**
+ * The name of thread in which this logging event was generated.
+ */
+ private String threadName;
- public Map<String, String> getMDCPropertyMap() {
- // populate mdcPropertyMap if null
- if (mdcPropertyMap == null) {
- MDCAdapter mdc = MDC.getMDCAdapter();
- if (mdc instanceof LogbackMDCAdapter)
- mdcPropertyMap = ((LogbackMDCAdapter) mdc).getPropertyMap();
- else
- mdcPropertyMap = mdc.getCopyOfContextMap();
- }
- // mdcPropertyMap still null, use emptyMap()
- if (mdcPropertyMap == null)
- mdcPropertyMap = Collections.emptyMap();
-
- return mdcPropertyMap;
- }
+ private String loggerName;
+ private LoggerContext loggerContext;
+ private LoggerContextVO loggerContextVO;
- /**
- * Set the MDC map for this event.
- *
- * @param map
- * @since 1.0.8
- */
- public void setMDCPropertyMap(Map<String, String> map) {
- if (mdcPropertyMap != null) {
- throw new IllegalStateException("The MDCPropertyMap has been already set for this event.");
- }
- this.mdcPropertyMap = map;
+ /**
+ * Level of logging event.
+ * <p/>
+ * <p>
+ * This field should not be accessed directly. You should use the
+ * {@link #getLevel} method instead.
+ * </p>
+ */
+ private transient Level level;
- }
+ private String message;
- /**
- * Synonym for [@link #getMDCPropertyMap}.
- *
- * @deprecated Replaced by [@link #getMDCPropertyMap}
- */
- public Map<String, String> getMdc() {
- return getMDCPropertyMap();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append('[');
- sb.append(level).append("] ");
- sb.append(getFormattedMessage());
- return sb.toString();
- }
-
- /**
- * LoggerEventVO instances should be used for serialization. Use
- * {@link LoggingEventVO#build(ILoggingEvent) build} method to create the LoggerEventVO instance.
- *
- * @since 1.0.11
- */
- private void writeObject(ObjectOutputStream out) throws IOException {
- throw new UnsupportedOperationException(this.getClass() + " does not support serialization. "
- + "Use LoggerEventVO instance instead. See also LoggerEventVO.build method.");
- }
+ // we gain significant space at serialization time by marking
+ // formattedMessage as transient and constructing it lazily in
+ // getFormattedMessage()
+ transient String formattedMessage;
+
+ private transient Object[] argumentArray;
+
+ private ThrowableProxy throwableProxy;
+
+ private StackTraceElement[] callerDataArray;
+
+ private Marker marker;
+
+ private Map<String, String> mdcPropertyMap;
+ private static final Map<String, String> CACHED_NULL_MAP = new HashMap<String, String>();
+
+ /**
+ * The number of milliseconds elapsed from 1/1/1970 until logging event was
+ * created.
+ */
+ private long timeStamp;
+
+ public LoggingEvent() {
+ }
+
+ public LoggingEvent(String fqcn, Logger logger, Level level, String message,
+ Throwable throwable, Object[] argArray) {
+ this.fqnOfLoggerClass = fqcn;
+ this.loggerName = logger.getName();
+ this.loggerContext = logger.getLoggerContext();
+ this.loggerContextVO = loggerContext.getLoggerContextRemoteView();
+ this.level = level;
+
+ this.message = message;
+ this.argumentArray = argArray;
+
+ if(throwable == null) {
+ throwable = extractThrowableAnRearrangeArguments(argArray);
+ }
+
+ if (throwable != null) {
+ this.throwableProxy = new ThrowableProxy(throwable);
+ LoggerContext lc = logger.getLoggerContext();
+ if (lc.isPackagingDataEnabled()) {
+ this.throwableProxy.calculatePackagingData();
+ }
+ }
+
+ timeStamp = System.currentTimeMillis();
+ }
+
+ private Throwable extractThrowableAnRearrangeArguments(Object[] argArray) {
+ Throwable extractedThrowable = EventArgUtil.extractThrowable(argArray);
+ if(EventArgUtil.successfulExtraction(extractedThrowable)) {
+ this.argumentArray = EventArgUtil.trimmedCopy(argArray);
+ }
+ return extractedThrowable;
+ }
+
+ public void setArgumentArray(Object[] argArray) {
+ if (this.argumentArray != null) {
+ throw new IllegalStateException("argArray has been already set");
+ }
+ this.argumentArray = argArray;
+ }
+
+ public Object[] getArgumentArray() {
+ return this.argumentArray;
+ }
+
+ public Level getLevel() {
+ return level;
+ }
+
+ public String getLoggerName() {
+ return loggerName;
+ }
+
+ public void setLoggerName(String loggerName) {
+ this.loggerName = loggerName;
+ }
+
+ public String getThreadName() {
+ if (threadName == null) {
+ threadName = (Thread.currentThread()).getName();
+ }
+ return threadName;
+ }
+
+ /**
+ * @param threadName The threadName to set.
+ * @throws IllegalStateException If threadName has been already set.
+ */
+ public void setThreadName(String threadName) throws IllegalStateException {
+ if (this.threadName != null) {
+ throw new IllegalStateException("threadName has been already set");
+ }
+ this.threadName = threadName;
+ }
+
+ /**
+ * Returns the throwable information contained within this event. May be
+ * <code>null</code> if there is no such information.
+ */
+ public IThrowableProxy getThrowableProxy() {
+ return throwableProxy;
+ }
+
+ /**
+ * Set this event's throwable information.
+ */
+ public void setThrowableProxy(ThrowableProxy tp) {
+ if (throwableProxy != null) {
+ throw new IllegalStateException("ThrowableProxy has been already set.");
+ } else {
+ throwableProxy = tp;
+ }
+ }
+
+ /**
+ * This method should be called prior to serializing an event. It should also
+ * be called when using asynchronous or deferred logging.
+ * <p/>
+ * <p/>
+ * Note that due to performance concerns, this method does NOT extract caller
+ * data. It is the responsibility of the caller to extract caller information.
+ */
+ public void prepareForDeferredProcessing() {
+ this.getFormattedMessage();
+ this.getThreadName();
+ // fixes http://jira.qos.ch/browse/LBCLASSIC-104
+ this.getMDCPropertyMap();
+ }
+
+ public LoggerContextVO getLoggerContextVO() {
+ return loggerContextVO;
+ }
+
+ public void setLoggerContextRemoteView(LoggerContextVO loggerContextVO) {
+ this.loggerContextVO = loggerContextVO;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ if (this.message != null) {
+ throw new IllegalStateException(
+ "The message for this event has been set already.");
+ }
+ this.message = message;
+ }
+
+ public long getTimeStamp() {
+ return timeStamp;
+ }
+
+ public void setTimeStamp(long timeStamp) {
+ this.timeStamp = timeStamp;
+ }
+
+ public void setLevel(Level level) {
+ if (this.level != null) {
+ throw new IllegalStateException(
+ "The level has been already set for this event.");
+ }
+ this.level = level;
+ }
+
+ /**
+ * Get the caller information for this logging event. If caller information is
+ * null at the time of its invocation, this method extracts location
+ * information. The collected information is cached for future use.
+ * <p/>
+ * <p>
+ * Note that after serialization it is impossible to correctly extract caller
+ * information.
+ * </p>
+ */
+ public StackTraceElement[] getCallerData() {
+ if (callerDataArray == null) {
+ callerDataArray = CallerData.extract(new Throwable(), fqnOfLoggerClass,
+ loggerContext.getMaxCallerDataDepth(), loggerContext.getFrameworkPackages());
+ }
+ return callerDataArray;
+ }
+
+ public boolean hasCallerData() {
+ return (callerDataArray != null);
+ }
+
+ public void setCallerData(StackTraceElement[] callerDataArray) {
+ this.callerDataArray = callerDataArray;
+ }
+
+ public Marker getMarker() {
+ return marker;
+ }
+
+ public void setMarker(Marker marker) {
+ if (this.marker != null) {
+ throw new IllegalStateException(
+ "The marker has been already set for this event.");
+ }
+ this.marker = marker;
+ }
+
+ public long getContextBirthTime() {
+ return loggerContextVO.getBirthTime();
+ }
+
+ // lazy computation as suggested in LOGBACK-495
+ public String getFormattedMessage() {
+ if (formattedMessage != null) {
+ return formattedMessage;
+ }
+ if (argumentArray != null) {
+ formattedMessage = MessageFormatter.arrayFormat(message, argumentArray)
+ .getMessage();
+ } else {
+ formattedMessage = message;
+ }
+
+ return formattedMessage;
+ }
+
+ public Map<String, String> getMDCPropertyMap() {
+ // populate mdcPropertyMap if null
+ if (mdcPropertyMap == null) {
+ MDCAdapter mdc = MDC.getMDCAdapter();
+ if (mdc instanceof LogbackMDCAdapter)
+ mdcPropertyMap = ((LogbackMDCAdapter) mdc).getPropertyMap();
+ else
+ mdcPropertyMap = mdc.getCopyOfContextMap();
+ }
+ // mdcPropertyMap still null, use CACHED_NULL_MAP
+ if (mdcPropertyMap == null)
+ mdcPropertyMap = CACHED_NULL_MAP;
+
+ return mdcPropertyMap;
+ }
+
+ /**
+ * Set the MDC map for this event.
+ *
+ * @param map
+ * @since 1.0.8
+ */
+ public void setMDCPropertyMap(Map<String, String> map) {
+ if (mdcPropertyMap != null) {
+ throw new IllegalStateException(
+ "The MDCPropertyMap has been already set for this event.");
+ }
+ this.mdcPropertyMap = map;
+
+ }
+
+ /**
+ * Synonym for [@link #getMDCPropertyMap}.
+ *
+ * @deprecated Replaced by [@link #getMDCPropertyMap}
+ */
+ public Map<String, String> getMdc() {
+ return getMDCPropertyMap();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append('[');
+ sb.append(level).append("] ");
+ sb.append(getFormattedMessage());
+ return sb.toString();
+ }
+
+ /**
+ * LoggerEventVO instances should be used for serialization. Use
+ * {@link LoggingEventVO#build(ILoggingEvent) build} method to create the LoggerEventVO instance.
+ *
+ * @since 1.0.11
+ */
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ throw new UnsupportedOperationException(this.getClass() + " does not support serialization. " +
+ "Use LoggerEventVO instance instead. See also LoggerEventVO.build method.");
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEventVO.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEventVO.java
index fae72f7..7a3c9ea 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEventVO.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEventVO.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -34,214 +34,216 @@ import ch.qos.logback.classic.Level;
*/
public class LoggingEventVO implements ILoggingEvent, Serializable {
- private static final long serialVersionUID = 6553722650255690312L;
-
- private static final int NULL_ARGUMENT_ARRAY = -1;
- private static final String NULL_ARGUMENT_ARRAY_ELEMENT = "NULL_ARGUMENT_ARRAY_ELEMENT";
-
- private String threadName;
- private String loggerName;
- private LoggerContextVO loggerContextVO;
-
- private transient Level level;
- private String message;
-
- // we gain significant space at serialization time by marking
- // formattedMessage as transient and constructing it lazily in
- // getFormattedMessage()
- private transient String formattedMessage;
-
- private transient Object[] argumentArray;
-
- private ThrowableProxyVO throwableProxy;
- private StackTraceElement[] callerDataArray;
- private Marker marker;
- private Map<String, String> mdcPropertyMap;
- private long timeStamp;
-
- public static LoggingEventVO build(ILoggingEvent le) {
- LoggingEventVO ledo = new LoggingEventVO();
- ledo.loggerName = le.getLoggerName();
- ledo.loggerContextVO = le.getLoggerContextVO();
- ledo.threadName = le.getThreadName();
- ledo.level = (le.getLevel());
- ledo.message = (le.getMessage());
- ledo.argumentArray = (le.getArgumentArray());
- ledo.marker = le.getMarker();
- ledo.mdcPropertyMap = le.getMDCPropertyMap();
- ledo.timeStamp = le.getTimeStamp();
- ledo.throwableProxy = ThrowableProxyVO.build(le.getThrowableProxy());
- // add caller data only if it is there already
- // fixes http://jira.qos.ch/browse/LBCLASSIC-145
- if (le.hasCallerData()) {
- ledo.callerDataArray = le.getCallerData();
- }
- return ledo;
- }
-
- public String getThreadName() {
- return threadName;
- }
-
- public LoggerContextVO getLoggerContextVO() {
- return loggerContextVO;
- }
-
- public String getLoggerName() {
- return loggerName;
- }
-
- public Level getLevel() {
- return level;
- }
-
- public String getMessage() {
- return message;
- }
-
- public String getFormattedMessage() {
- if (formattedMessage != null) {
- return formattedMessage;
- }
-
- if (argumentArray != null) {
- formattedMessage = MessageFormatter.arrayFormat(message, argumentArray).getMessage();
- } else {
- formattedMessage = message;
- }
-
- return formattedMessage;
- }
-
- public Object[] getArgumentArray() {
- return argumentArray;
- }
-
- public IThrowableProxy getThrowableProxy() {
- return throwableProxy;
- }
+ private static final long serialVersionUID = 6553722650255690312L;
- public StackTraceElement[] getCallerData() {
- return callerDataArray;
- }
-
- public boolean hasCallerData() {
- return callerDataArray != null;
- }
-
- public Marker getMarker() {
- return marker;
- }
-
- public long getTimeStamp() {
- return timeStamp;
- }
-
- public long getContextBirthTime() {
- return loggerContextVO.getBirthTime();
- }
+ private static final int NULL_ARGUMENT_ARRAY = -1;
+ private static final String NULL_ARGUMENT_ARRAY_ELEMENT = "NULL_ARGUMENT_ARRAY_ELEMENT";
- public LoggerContextVO getContextLoggerRemoteView() {
- return loggerContextVO;
- }
+ private String threadName;
+ private String loggerName;
+ private LoggerContextVO loggerContextVO;
- public Map<String, String> getMDCPropertyMap() {
- return mdcPropertyMap;
- }
+ private transient Level level;
+ private String message;
- public Map<String, String> getMdc() {
- return mdcPropertyMap;
- }
-
- public void prepareForDeferredProcessing() {
- }
-
- private void writeObject(ObjectOutputStream out) throws IOException {
- out.defaultWriteObject();
- out.writeInt(level.levelInt);
- if (argumentArray != null) {
- int len = argumentArray.length;
- out.writeInt(len);
- for (int i = 0; i < argumentArray.length; i++) {
- if (argumentArray[i] != null) {
- out.writeObject(argumentArray[i].toString());
- } else {
- out.writeObject(NULL_ARGUMENT_ARRAY_ELEMENT);
- }
- }
+ // we gain significant space at serialization time by marking
+ // formattedMessage as transient and constructing it lazily in
+ // getFormattedMessage()
+ private transient String formattedMessage;
+
+ private transient Object[] argumentArray;
+
+ private ThrowableProxyVO throwableProxy;
+ private StackTraceElement[] callerDataArray;
+ private Marker marker;
+ private Map<String, String> mdcPropertyMap;
+ private long timeStamp;
+
+ public static LoggingEventVO build(ILoggingEvent le) {
+ LoggingEventVO ledo = new LoggingEventVO();
+ ledo.loggerName = le.getLoggerName();
+ ledo.loggerContextVO = le.getLoggerContextVO();
+ ledo.threadName = le.getThreadName();
+ ledo.level = (le.getLevel());
+ ledo.message = (le.getMessage());
+ ledo.argumentArray = (le.getArgumentArray());
+ ledo.marker = le.getMarker();
+ ledo.mdcPropertyMap = le.getMDCPropertyMap();
+ ledo.timeStamp = le.getTimeStamp();
+ ledo.throwableProxy = ThrowableProxyVO.build(le.getThrowableProxy());
+ // add caller data only if it is there already
+ // fixes http://jira.qos.ch/browse/LBCLASSIC-145
+ if (le.hasCallerData()) {
+ ledo.callerDataArray = le.getCallerData();
+ }
+ return ledo;
+ }
+
+ public String getThreadName() {
+ return threadName;
+ }
+
+ public LoggerContextVO getLoggerContextVO() {
+ return loggerContextVO;
+ }
+
+ public String getLoggerName() {
+ return loggerName;
+ }
+
+ public Level getLevel() {
+ return level;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String getFormattedMessage() {
+ if (formattedMessage != null) {
+ return formattedMessage;
+ }
+
+ if (argumentArray != null) {
+ formattedMessage = MessageFormatter.arrayFormat(message, argumentArray)
+ .getMessage();
+ } else {
+ formattedMessage = message;
+ }
+
+ return formattedMessage;
+ }
+
+ public Object[] getArgumentArray() {
+ return argumentArray;
+ }
+
+ public IThrowableProxy getThrowableProxy() {
+ return throwableProxy;
+ }
+
+ public StackTraceElement[] getCallerData() {
+ return callerDataArray;
+ }
+
+ public boolean hasCallerData() {
+ return callerDataArray != null;
+ }
+
+ public Marker getMarker() {
+ return marker;
+ }
+
+ public long getTimeStamp() {
+ return timeStamp;
+ }
+
+ public long getContextBirthTime() {
+ return loggerContextVO.getBirthTime();
+ }
+
+ public LoggerContextVO getContextLoggerRemoteView() {
+ return loggerContextVO;
+ }
+
+ public Map<String, String> getMDCPropertyMap() {
+ return mdcPropertyMap;
+ }
+ public Map<String, String> getMdc() {
+ return mdcPropertyMap;
+ }
+
+ public void prepareForDeferredProcessing() {
+ }
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ out.writeInt(level.levelInt);
+ if (argumentArray != null) {
+ int len = argumentArray.length;
+ out.writeInt(len);
+ for (int i = 0; i < argumentArray.length; i++) {
+ if (argumentArray[i] != null) {
+ out.writeObject(argumentArray[i].toString());
} else {
- out.writeInt(NULL_ARGUMENT_ARRAY);
+ out.writeObject(NULL_ARGUMENT_ARRAY_ELEMENT);
}
-
- }
-
- private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
- in.defaultReadObject();
- int levelInt = in.readInt();
- level = Level.toLevel(levelInt);
-
- int argArrayLen = in.readInt();
- if (argArrayLen != NULL_ARGUMENT_ARRAY) {
- argumentArray = new String[argArrayLen];
- for (int i = 0; i < argArrayLen; i++) {
- Object val = in.readObject();
- if (!NULL_ARGUMENT_ARRAY_ELEMENT.equals(val)) {
- argumentArray[i] = val;
- }
- }
+ }
+ } else {
+ out.writeInt(NULL_ARGUMENT_ARRAY);
+ }
+
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException,
+ ClassNotFoundException {
+ in.defaultReadObject();
+ int levelInt = in.readInt();
+ level = Level.toLevel(levelInt);
+
+ int argArrayLen = in.readInt();
+ if (argArrayLen != NULL_ARGUMENT_ARRAY) {
+ argumentArray = new String[argArrayLen];
+ for (int i = 0; i < argArrayLen; i++) {
+ Object val = in.readObject();
+ if (!NULL_ARGUMENT_ARRAY_ELEMENT.equals(val)) {
+ argumentArray[i] = val;
}
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((message == null) ? 0 : message.hashCode());
- result = prime * result + ((threadName == null) ? 0 : threadName.hashCode());
- result = prime * result + (int) (timeStamp ^ (timeStamp >>> 32));
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final LoggingEventVO other = (LoggingEventVO) obj;
- if (message == null) {
- if (other.message != null)
- return false;
- } else if (!message.equals(other.message))
- return false;
-
- if (loggerName == null) {
- if (other.loggerName != null)
- return false;
- } else if (!loggerName.equals(other.loggerName))
- return false;
-
- if (threadName == null) {
- if (other.threadName != null)
- return false;
- } else if (!threadName.equals(other.threadName))
- return false;
- if (timeStamp != other.timeStamp)
- return false;
-
- if (marker == null) {
- if (other.marker != null)
- return false;
- } else if (!marker.equals(other.marker))
- return false;
-
- if (mdcPropertyMap == null) {
- if (other.mdcPropertyMap != null)
- return false;
- } else if (!mdcPropertyMap.equals(other.mdcPropertyMap))
- return false;
- return true;
- }
+ }
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((message == null) ? 0 : message.hashCode());
+ result = prime * result
+ + ((threadName == null) ? 0 : threadName.hashCode());
+ result = prime * result + (int) (timeStamp ^ (timeStamp >>> 32));
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final LoggingEventVO other = (LoggingEventVO) obj;
+ if (message == null) {
+ if (other.message != null)
+ return false;
+ } else if (!message.equals(other.message))
+ return false;
+
+ if (loggerName == null) {
+ if (other.loggerName != null)
+ return false;
+ } else if (!loggerName.equals(other.loggerName))
+ return false;
+
+ if (threadName == null) {
+ if (other.threadName != null)
+ return false;
+ } else if (!threadName.equals(other.threadName))
+ return false;
+ if (timeStamp != other.timeStamp)
+ return false;
+
+ if (marker == null) {
+ if (other.marker != null)
+ return false;
+ } else if (!marker.equals(other.marker))
+ return false;
+
+ if (mdcPropertyMap == null) {
+ if (other.mdcPropertyMap != null)
+ return false;
+ } else if (!mdcPropertyMap.equals(other.mdcPropertyMap))
+ return false;
+ return true;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/PackagingDataCalculator.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/PackagingDataCalculator.java
index be40f5e..c991702 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/PackagingDataCalculator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/PackagingDataCalculator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,7 +18,6 @@ import java.security.CodeSource;
import java.util.HashMap;
import sun.reflect.Reflection;
-
// import java.security.AccessControlException; import java.security.AccessController;import java.security.PrivilegedAction;
/**
* Given a classname locate associated PackageInfo (jar name, version name).
@@ -28,219 +27,224 @@ import sun.reflect.Reflection;
*/
public class PackagingDataCalculator {
- final static StackTraceElementProxy[] STEP_ARRAY_TEMPLATE = new StackTraceElementProxy[0];
-
- HashMap<String, ClassPackagingData> cache = new HashMap<String, ClassPackagingData>();
-
- private static boolean GET_CALLER_CLASS_METHOD_AVAILABLE = false; // private static boolean
- // HAS_GET_CLASS_LOADER_PERMISSION = false;
-
- static {
- // if either the Reflection class or the getCallerClass method
- // are unavailable, then we won't invoke Reflection.getCallerClass()
- // This approach ensures that this class will *run* on JDK's lacking
- // sun.reflect.Reflection class. However, this class will *not compile*
- // on JDKs lacking sun.reflect.Reflection.
- try {
- Reflection.getCallerClass(2);
- GET_CALLER_CLASS_METHOD_AVAILABLE = true;
- } catch (NoClassDefFoundError e) {
- } catch (NoSuchMethodError e) {
- } catch (UnsupportedOperationException e) {
- } catch (Throwable e) {
- System.err.println("Unexpected exception");
- e.printStackTrace();
- }
- }
-
- public void calculate(IThrowableProxy tp) {
- while (tp != null) {
- populateFrames(tp.getStackTraceElementProxyArray());
- IThrowableProxy[] suppressed = tp.getSuppressed();
- if (suppressed != null) {
- for (IThrowableProxy current : suppressed) {
- populateFrames(current.getStackTraceElementProxyArray());
- }
- }
- tp = tp.getCause();
- }
+ final static StackTraceElementProxy[] STEP_ARRAY_TEMPLATE = new StackTraceElementProxy[0];
+
+ HashMap<String, ClassPackagingData> cache = new HashMap<String, ClassPackagingData>();
+
+ private static boolean GET_CALLER_CLASS_METHOD_AVAILABLE = false; //private static boolean HAS_GET_CLASS_LOADER_PERMISSION = false;
+
+ static {
+ // if either the Reflection class or the getCallerClass method
+ // are unavailable, then we won't invoke Reflection.getCallerClass()
+ // This approach ensures that this class will *run* on JDK's lacking
+ // sun.reflect.Reflection class. However, this class will *not compile*
+ // on JDKs lacking sun.reflect.Reflection.
+ try {
+ Reflection.getCallerClass(2);
+ GET_CALLER_CLASS_METHOD_AVAILABLE = true;
+ } catch (NoClassDefFoundError e) {
+ } catch (NoSuchMethodError e) {
+ } catch (UnsupportedOperationException e) {
+ } catch (Throwable e) {
+ System.err.println("Unexpected exception");
+ e.printStackTrace();
}
+ }
- void populateFrames(StackTraceElementProxy[] stepArray) {
- // in the initial part of this method we populate package information for
- // common stack frames
- final Throwable t = new Throwable("local stack reference");
- final StackTraceElement[] localteSTEArray = t.getStackTrace();
- final int commonFrames = STEUtil.findNumberOfCommonFrames(localteSTEArray, stepArray);
- final int localFirstCommon = localteSTEArray.length - commonFrames;
- final int stepFirstCommon = stepArray.length - commonFrames;
-
- ClassLoader lastExactClassLoader = null;
- ClassLoader firsExactClassLoader = null;
- int missfireCount = 0;
- for (int i = 0; i < commonFrames; i++) {
- Class callerClass = null;
- if (GET_CALLER_CLASS_METHOD_AVAILABLE) {
- callerClass = Reflection.getCallerClass(localFirstCommon + i - missfireCount + 1);
- }
- StackTraceElementProxy step = stepArray[stepFirstCommon + i];
- String stepClassname = step.ste.getClassName();
-
- if (callerClass != null && stepClassname.equals(callerClass.getName())) {
- // see also LBCLASSIC-263
- lastExactClassLoader = callerClass.getClassLoader();
- if (firsExactClassLoader == null) {
- firsExactClassLoader = lastExactClassLoader;
- }
- ClassPackagingData pi = calculateByExactType(callerClass);
- step.setClassPackagingData(pi);
- } else {
- missfireCount++;
- ClassPackagingData pi = computeBySTEP(step, lastExactClassLoader);
- step.setClassPackagingData(pi);
- }
+ public void calculate(IThrowableProxy tp) {
+ while (tp != null) {
+ populateFrames(tp.getStackTraceElementProxyArray());
+ IThrowableProxy[] suppressed = tp.getSuppressed();
+ if(suppressed != null) {
+ for(IThrowableProxy current:suppressed) {
+ populateFrames(current.getStackTraceElementProxyArray());
}
- populateUncommonFrames(commonFrames, stepArray, firsExactClassLoader);
+ }
+ tp = tp.getCause();
}
-
- void populateUncommonFrames(int commonFrames, StackTraceElementProxy[] stepArray, ClassLoader firstExactClassLoader) {
- int uncommonFrames = stepArray.length - commonFrames;
- for (int i = 0; i < uncommonFrames; i++) {
- StackTraceElementProxy step = stepArray[i];
- ClassPackagingData pi = computeBySTEP(step, firstExactClassLoader);
- step.setClassPackagingData(pi);
- }
+ }
+
+ void populateFrames(StackTraceElementProxy[] stepArray) {
+ // in the initial part of this method we populate package information for
+ // common stack frames
+ final Throwable t = new Throwable("local stack reference");
+ final StackTraceElement[] localteSTEArray = t.getStackTrace();
+ final int commonFrames = STEUtil.findNumberOfCommonFrames(localteSTEArray,
+ stepArray);
+ final int localFirstCommon = localteSTEArray.length - commonFrames;
+ final int stepFirstCommon = stepArray.length - commonFrames;
+
+ ClassLoader lastExactClassLoader = null;
+ ClassLoader firsExactClassLoader = null;
+
+ int missfireCount = 0;
+ for (int i = 0; i < commonFrames; i++) {
+ Class callerClass = null;
+ if (GET_CALLER_CLASS_METHOD_AVAILABLE) {
+ callerClass = Reflection.getCallerClass(localFirstCommon + i
+ - missfireCount + 1);
+ }
+ StackTraceElementProxy step = stepArray[stepFirstCommon + i];
+ String stepClassname = step.ste.getClassName();
+
+ if (callerClass != null && stepClassname.equals(callerClass.getName())) {
+ // see also LBCLASSIC-263
+ lastExactClassLoader = callerClass.getClassLoader();
+ if (firsExactClassLoader == null) {
+ firsExactClassLoader = lastExactClassLoader;
+ }
+ ClassPackagingData pi = calculateByExactType(callerClass);
+ step.setClassPackagingData(pi);
+ } else {
+ missfireCount++;
+ ClassPackagingData pi = computeBySTEP(step, lastExactClassLoader);
+ step.setClassPackagingData(pi);
+ }
}
-
- private ClassPackagingData calculateByExactType(Class type) {
- String className = type.getName();
- ClassPackagingData cpd = cache.get(className);
- if (cpd != null) {
- return cpd;
- }
- String version = getImplementationVersion(type);
- String codeLocation = getCodeLocation(type);
- cpd = new ClassPackagingData(codeLocation, version);
- cache.put(className, cpd);
- return cpd;
- }
-
- private ClassPackagingData computeBySTEP(StackTraceElementProxy step, ClassLoader lastExactClassLoader) {
- String className = step.ste.getClassName();
- ClassPackagingData cpd = cache.get(className);
- if (cpd != null) {
- return cpd;
- }
- Class type = bestEffortLoadClass(lastExactClassLoader, className);
- String version = getImplementationVersion(type);
- String codeLocation = getCodeLocation(type);
- cpd = new ClassPackagingData(codeLocation, version, false);
- cache.put(className, cpd);
- return cpd;
+ populateUncommonFrames(commonFrames, stepArray, firsExactClassLoader);
+ }
+
+ void populateUncommonFrames(int commonFrames,
+ StackTraceElementProxy[] stepArray, ClassLoader firstExactClassLoader) {
+ int uncommonFrames = stepArray.length - commonFrames;
+ for (int i = 0; i < uncommonFrames; i++) {
+ StackTraceElementProxy step = stepArray[i];
+ ClassPackagingData pi = computeBySTEP(step, firstExactClassLoader);
+ step.setClassPackagingData(pi);
}
+ }
- String getImplementationVersion(Class type) {
- if (type == null) {
- return "na";
- }
- Package aPackage = type.getPackage();
- if (aPackage != null) {
- String v = aPackage.getImplementationVersion();
- if (v == null) {
- return "na";
- } else {
- return v;
- }
- }
- return "na";
-
+ private ClassPackagingData calculateByExactType(Class type) {
+ String className = type.getName();
+ ClassPackagingData cpd = cache.get(className);
+ if (cpd != null) {
+ return cpd;
}
-
- String getCodeLocation(Class type) {
- try {
- if (type != null) {
- // file:/C:/java/maven-2.0.8/repo/com/icegreen/greenmail/1.3/greenmail-1.3.jar
- CodeSource codeSource = type.getProtectionDomain().getCodeSource();
- if (codeSource != null) {
- URL resource = codeSource.getLocation();
- if (resource != null) {
- String locationStr = resource.toString();
- // now lets remove all but the file name
- String result = getCodeLocation(locationStr, '/');
- if (result != null) {
- return result;
- }
- return getCodeLocation(locationStr, '\\');
- }
- }
- }
- } catch (Exception e) {
- // ignore
- }
+ String version = getImplementationVersion(type);
+ String codeLocation = getCodeLocation(type);
+ cpd = new ClassPackagingData(codeLocation, version);
+ cache.put(className, cpd);
+ return cpd;
+ }
+
+ private ClassPackagingData computeBySTEP(StackTraceElementProxy step,
+ ClassLoader lastExactClassLoader) {
+ String className = step.ste.getClassName();
+ ClassPackagingData cpd = cache.get(className);
+ if (cpd != null) {
+ return cpd;
+ }
+ Class type = bestEffortLoadClass(lastExactClassLoader, className);
+ String version = getImplementationVersion(type);
+ String codeLocation = getCodeLocation(type);
+ cpd = new ClassPackagingData(codeLocation, version, false);
+ cache.put(className, cpd);
+ return cpd;
+ }
+
+ String getImplementationVersion(Class type) {
+ if (type == null) {
+ return "na";
+ }
+ Package aPackage = type.getPackage();
+ if (aPackage != null) {
+ String v = aPackage.getImplementationVersion();
+ if (v == null) {
return "na";
+ } else {
+ return v;
+ }
}
-
- private String getCodeLocation(String locationStr, char separator) {
- int idx = locationStr.lastIndexOf(separator);
- if (isFolder(idx, locationStr)) {
- idx = locationStr.lastIndexOf(separator, idx - 1);
- return locationStr.substring(idx + 1);
- } else if (idx > 0) {
- return locationStr.substring(idx + 1);
+ return "na";
+
+ }
+
+ String getCodeLocation(Class type) {
+ try {
+ if (type != null) {
+ // file:/C:/java/maven-2.0.8/repo/com/icegreen/greenmail/1.3/greenmail-1.3.jar
+ CodeSource codeSource = type.getProtectionDomain().getCodeSource();
+ if (codeSource != null) {
+ URL resource = codeSource.getLocation();
+ if (resource != null) {
+ String locationStr = resource.toString();
+ // now lets remove all but the file name
+ String result = getCodeLocation(locationStr, '/');
+ if (result != null) {
+ return result;
+ }
+ return getCodeLocation(locationStr, '\\');
+ }
}
- return null;
+ }
+ } catch (Exception e) {
+ // ignore
}
-
- private boolean isFolder(int idx, String text) {
- return (idx != -1 && idx + 1 == text.length());
+ return "na";
+ }
+
+ private String getCodeLocation(String locationStr, char separator) {
+ int idx = locationStr.lastIndexOf(separator);
+ if (isFolder(idx, locationStr)) {
+ idx = locationStr.lastIndexOf(separator, idx - 1);
+ return locationStr.substring(idx + 1);
+ } else if (idx > 0) {
+ return locationStr.substring(idx + 1);
}
+ return null;
+ }
- private Class loadClass(ClassLoader cl, String className) {
- if (cl == null) {
- return null;
- }
- try {
- return cl.loadClass(className);
- } catch (ClassNotFoundException e1) {
- return null;
- } catch (NoClassDefFoundError e1) {
- return null;
- } catch (Exception e) {
- e.printStackTrace(); // this is unexpected
- return null;
- }
+ private boolean isFolder(int idx, String text) {
+ return (idx != -1 && idx + 1 == text.length());
+ }
+ private Class loadClass(ClassLoader cl, String className) {
+ if (cl == null) {
+ return null;
+ }
+ try {
+ return cl.loadClass(className);
+ } catch (ClassNotFoundException e1) {
+ return null;
+ } catch (NoClassDefFoundError e1) {
+ return null;
+ } catch (Exception e) {
+ e.printStackTrace(); // this is unexpected
+ return null;
}
- /**
- * @param lastGuaranteedClassLoader may be null
- * @param className
- * @return
- */
- private Class bestEffortLoadClass(ClassLoader lastGuaranteedClassLoader, String className) {
- Class result = loadClass(lastGuaranteedClassLoader, className);
- if (result != null) {
- return result;
- }
- ClassLoader tccl = Thread.currentThread().getContextClassLoader();
- if (tccl != lastGuaranteedClassLoader) {
- result = loadClass(tccl, className);
- }
- if (result != null) {
- return result;
- }
+ }
+
+ /**
+ * @param lastGuaranteedClassLoader may be null
+ * @param className
+ * @return
+ */
+ private Class bestEffortLoadClass(ClassLoader lastGuaranteedClassLoader,
+ String className) {
+ Class result = loadClass(lastGuaranteedClassLoader, className);
+ if (result != null) {
+ return result;
+ }
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ if (tccl != lastGuaranteedClassLoader) {
+ result = loadClass(tccl, className);
+ }
+ if (result != null) {
+ return result;
+ }
- try {
- return Class.forName(className);
- } catch (ClassNotFoundException e1) {
- return null;
- } catch (NoClassDefFoundError e1) {
- return null;
- } catch (Exception e) {
- e.printStackTrace(); // this is unexpected
- return null;
- }
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException e1) {
+ return null;
+ } catch (NoClassDefFoundError e1) {
+ return null;
+ } catch (Exception e) {
+ e.printStackTrace(); // this is unexpected
+ return null;
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/PlatformInfo.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/PlatformInfo.java
index 376f31a..0434e50 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/PlatformInfo.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/PlatformInfo.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,19 +20,19 @@ package ch.qos.logback.classic.spi;
* */
public class PlatformInfo {
- private static final int UNINITIALIZED = -1;
+ private static final int UNINITIALIZED = -1;
- private static int hasJMXObjectName = UNINITIALIZED;
-
- public static boolean hasJMXObjectName() {
- if (hasJMXObjectName == UNINITIALIZED) {
- try {
- Class.forName("javax.management.ObjectName");
- hasJMXObjectName = 1;
- } catch (Throwable e) {
- hasJMXObjectName = 0;
- }
- }
- return (hasJMXObjectName == 1);
+ private static int hasJMXObjectName = UNINITIALIZED;
+
+ public static boolean hasJMXObjectName() {
+ if (hasJMXObjectName == UNINITIALIZED) {
+ try {
+ Class.forName("javax.management.ObjectName");
+ hasJMXObjectName = 1;
+ } catch (Throwable e) {
+ hasJMXObjectName = 0;
+ }
}
+ return (hasJMXObjectName == 1);
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/STEUtil.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/STEUtil.java
index 2e68690..a77b034 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/STEUtil.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/STEUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,43 +15,47 @@ package ch.qos.logback.classic.spi;
public class STEUtil {
- static int UNUSED_findNumberOfCommonFrames(StackTraceElement[] steArray, StackTraceElement[] otherSTEArray) {
- if (otherSTEArray == null) {
- return 0;
- }
-
- int steIndex = steArray.length - 1;
- int parentIndex = otherSTEArray.length - 1;
- int count = 0;
- while (steIndex >= 0 && parentIndex >= 0) {
- if (steArray[steIndex].equals(otherSTEArray[parentIndex])) {
- count++;
- } else {
- break;
- }
- steIndex--;
- parentIndex--;
- }
- return count;
+
+ static int UNUSED_findNumberOfCommonFrames(StackTraceElement[] steArray,
+ StackTraceElement[] otherSTEArray) {
+ if (otherSTEArray == null) {
+ return 0;
}
- static int findNumberOfCommonFrames(StackTraceElement[] steArray, StackTraceElementProxy[] otherSTEPArray) {
- if (otherSTEPArray == null) {
- return 0;
- }
+ int steIndex = steArray.length - 1;
+ int parentIndex = otherSTEArray.length - 1;
+ int count = 0;
+ while (steIndex >= 0 && parentIndex >= 0) {
+ if (steArray[steIndex].equals(otherSTEArray[parentIndex])) {
+ count++;
+ } else {
+ break;
+ }
+ steIndex--;
+ parentIndex--;
+ }
+ return count;
+ }
+
+
+ static int findNumberOfCommonFrames(StackTraceElement[] steArray,
+ StackTraceElementProxy[] otherSTEPArray) {
+ if (otherSTEPArray == null) {
+ return 0;
+ }
- int steIndex = steArray.length - 1;
- int parentIndex = otherSTEPArray.length - 1;
- int count = 0;
- while (steIndex >= 0 && parentIndex >= 0) {
- if (steArray[steIndex].equals(otherSTEPArray[parentIndex].ste)) {
- count++;
- } else {
- break;
- }
- steIndex--;
- parentIndex--;
- }
- return count;
+ int steIndex = steArray.length - 1;
+ int parentIndex = otherSTEPArray.length - 1;
+ int count = 0;
+ while (steIndex >= 0 && parentIndex >= 0) {
+ if (steArray[steIndex].equals(otherSTEPArray[parentIndex].ste)) {
+ count++;
+ } else {
+ break;
+ }
+ steIndex--;
+ parentIndex--;
}
+ return count;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/StackTraceElementProxy.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/StackTraceElementProxy.java
index edcec9b..868b6af 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/StackTraceElementProxy.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/StackTraceElementProxy.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,73 +17,74 @@ import java.io.Serializable;
public class StackTraceElementProxy implements Serializable {
- private static final long serialVersionUID = -2374374378980555982L;
+ private static final long serialVersionUID = -2374374378980555982L;
+
+ final StackTraceElement ste;
+ // save a byte or two during serialization, as we can
+ // reconstruct this field from 'ste'
+ transient private String steAsString;
+ private ClassPackagingData cpd;
- final StackTraceElement ste;
- // save a byte or two during serialization, as we can
- // reconstruct this field from 'ste'
- transient private String steAsString;
- private ClassPackagingData cpd;
-
- public StackTraceElementProxy(StackTraceElement ste) {
- if (ste == null) {
- throw new IllegalArgumentException("ste cannot be null");
- }
- this.ste = ste;
- }
-
- public String getSTEAsString() {
- if (steAsString == null) {
- steAsString = "at " + ste.toString();
- }
- return steAsString;
+ public StackTraceElementProxy(StackTraceElement ste) {
+ if (ste == null) {
+ throw new IllegalArgumentException("ste cannot be null");
}
+ this.ste = ste;
+ }
- public StackTraceElement getStackTraceElement() {
- return ste;
+
+ public String getSTEAsString() {
+ if (steAsString == null) {
+ steAsString = "at " + ste.toString();
}
-
- public void setClassPackagingData(ClassPackagingData cpd) {
- if (this.cpd != null) {
- throw new IllegalStateException("Packaging data has been already set");
- }
- this.cpd = cpd;
+ return steAsString;
+ }
+
+ public StackTraceElement getStackTraceElement() {
+ return ste;
+ }
+
+ public void setClassPackagingData(ClassPackagingData cpd) {
+ if(this.cpd != null) {
+ throw new IllegalStateException("Packaging data has been already set");
}
+ this.cpd = cpd;
+ }
- public ClassPackagingData getClassPackagingData() {
- return cpd;
- }
+ public ClassPackagingData getClassPackagingData() {
+ return cpd;
+ }
- @Override
- public int hashCode() {
- return ste.hashCode();
- }
+ @Override
+ public int hashCode() {
+ return ste.hashCode();
+ }
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final StackTraceElementProxy other = (StackTraceElementProxy) obj;
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final StackTraceElementProxy other = (StackTraceElementProxy) obj;
- if (!ste.equals(other.ste)) {
- return false;
- }
- if (cpd == null) {
- if (other.cpd != null) {
- return false;
- }
- } else if (!cpd.equals(other.cpd)) {
- return false;
- }
- return true;
+ if (!ste.equals(other.ste)) {
+ return false;
}
-
- @Override
- public String toString() {
- return getSTEAsString();
+ if (cpd == null) {
+ if (other.cpd != null) {
+ return false;
+ }
+ } else if (!cpd.equals(other.cpd)) {
+ return false;
}
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return getSTEAsString();
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxy.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxy.java
index b29a169..04a0784 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxy.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxy.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,138 +20,146 @@ import java.lang.reflect.Method;
public class ThrowableProxy implements IThrowableProxy {
- private Throwable throwable;
- private String className;
- private String message;
- // package-private because of ThrowableProxyUtil
- StackTraceElementProxy[] stackTraceElementProxyArray;
- // package-private because of ThrowableProxyUtil
- int commonFrames;
- private ThrowableProxy cause;
- private ThrowableProxy[] suppressed = NO_SUPPRESSED;
-
- private transient PackagingDataCalculator packagingDataCalculator;
- private boolean calculatedPackageData = false;
-
- private static final Method GET_SUPPRESSED_METHOD;
-
- static {
- Method method = null;
- try {
- method = Throwable.class.getMethod("getSuppressed");
- } catch (NoSuchMethodException e) {
- // ignore, will get thrown in Java < 7
- }
- GET_SUPPRESSED_METHOD = method;
+ private Throwable throwable;
+ private String className;
+ private String message;
+ // package-private because of ThrowableProxyUtil
+ StackTraceElementProxy[] stackTraceElementProxyArray;
+ // package-private because of ThrowableProxyUtil
+ int commonFrames;
+ private ThrowableProxy cause;
+ private ThrowableProxy[] suppressed=NO_SUPPRESSED;
+
+ private transient PackagingDataCalculator packagingDataCalculator;
+ private boolean calculatedPackageData = false;
+
+ private static final Method GET_SUPPRESSED_METHOD;
+
+ static {
+ Method method = null;
+ try {
+ method = Throwable.class.getMethod("getSuppressed");
+ } catch (NoSuchMethodException e) {
+ // ignore, will get thrown in Java < 7
}
-
- private static final ThrowableProxy[] NO_SUPPRESSED = new ThrowableProxy[0];
-
- public ThrowableProxy(Throwable throwable) {
-
- this.throwable = throwable;
- this.className = throwable.getClass().getName();
- this.message = throwable.getMessage();
- this.stackTraceElementProxyArray = ThrowableProxyUtil.steArrayToStepArray(throwable.getStackTrace());
-
- Throwable nested = throwable.getCause();
-
- if (nested != null) {
- this.cause = new ThrowableProxy(nested);
- this.cause.commonFrames = ThrowableProxyUtil.findNumberOfCommonFrames(nested.getStackTrace(), stackTraceElementProxyArray);
- }
- if (GET_SUPPRESSED_METHOD != null) {
- // this will only execute on Java 7
- try {
- Object obj = GET_SUPPRESSED_METHOD.invoke(throwable);
- if (obj instanceof Throwable[]) {
- Throwable[] throwableSuppressed = (Throwable[]) obj;
- if (throwableSuppressed.length > 0) {
- suppressed = new ThrowableProxy[throwableSuppressed.length];
- for (int i = 0; i < throwableSuppressed.length; i++) {
- this.suppressed[i] = new ThrowableProxy(throwableSuppressed[i]);
- this.suppressed[i].commonFrames = ThrowableProxyUtil.findNumberOfCommonFrames(throwableSuppressed[i].getStackTrace(),
- stackTraceElementProxyArray);
- }
- }
- }
- } catch (IllegalAccessException e) {
- // ignore
- } catch (InvocationTargetException e) {
- // ignore
+ GET_SUPPRESSED_METHOD = method;
+ }
+
+ private static final ThrowableProxy[] NO_SUPPRESSED=new ThrowableProxy[0];
+
+ public ThrowableProxy(Throwable throwable) {
+
+ this.throwable = throwable;
+ this.className = throwable.getClass().getName();
+ this.message = throwable.getMessage();
+ this.stackTraceElementProxyArray = ThrowableProxyUtil.steArrayToStepArray(throwable
+ .getStackTrace());
+
+ Throwable nested = throwable.getCause();
+
+ if (nested != null) {
+ this.cause = new ThrowableProxy(nested);
+ this.cause.commonFrames = ThrowableProxyUtil
+ .findNumberOfCommonFrames(nested.getStackTrace(),
+ stackTraceElementProxyArray);
+ }
+ if(GET_SUPPRESSED_METHOD != null) {
+ // this will only execute on Java 7
+ try {
+ Object obj = GET_SUPPRESSED_METHOD.invoke(throwable);
+ if(obj instanceof Throwable[]) {
+ Throwable[] throwableSuppressed = (Throwable[]) obj;
+ if(throwableSuppressed.length > 0) {
+ suppressed = new ThrowableProxy[throwableSuppressed.length];
+ for(int i=0;i<throwableSuppressed.length;i++) {
+ this.suppressed[i] = new ThrowableProxy(throwableSuppressed[i]);
+ this.suppressed[i].commonFrames = ThrowableProxyUtil
+ .findNumberOfCommonFrames(throwableSuppressed[i].getStackTrace(),
+ stackTraceElementProxyArray);
}
+ }
}
-
+ } catch (IllegalAccessException e) {
+ // ignore
+ } catch (InvocationTargetException e) {
+ // ignore
+ }
}
- public Throwable getThrowable() {
- return throwable;
+ }
+
+
+ public Throwable getThrowable() {
+ return throwable;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ch.qos.logback.classic.spi.IThrowableProxy#getClassName()
+ */
+ public String getClassName() {
+ return className;
+ }
+
+ public StackTraceElementProxy[] getStackTraceElementProxyArray() {
+ return stackTraceElementProxyArray;
+ }
+
+ public int getCommonFrames() {
+ return commonFrames;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see ch.qos.logback.classic.spi.IThrowableProxy#getCause()
+ */
+ public IThrowableProxy getCause() {
+ return cause;
+ }
+
+ public IThrowableProxy[] getSuppressed() {
+ return suppressed;
+ }
+
+ public PackagingDataCalculator getPackagingDataCalculator() {
+ // if original instance (non-deserialized), and packagingDataCalculator
+ // is not already initialized, then create an instance.
+ // here we assume that (throwable == null) for deserialized instances
+ if (throwable != null && packagingDataCalculator == null) {
+ packagingDataCalculator = new PackagingDataCalculator();
}
+ return packagingDataCalculator;
+ }
- public String getMessage() {
- return message;
+ public void calculatePackagingData() {
+ if (calculatedPackageData) {
+ return;
}
-
- /*
- * (non-Javadoc)
- *
- * @see ch.qos.logback.classic.spi.IThrowableProxy#getClassName()
- */
- public String getClassName() {
- return className;
+ PackagingDataCalculator pdc = this.getPackagingDataCalculator();
+ if (pdc != null) {
+ calculatedPackageData = true;
+ pdc.calculate(this);
}
+ }
- public StackTraceElementProxy[] getStackTraceElementProxyArray() {
- return stackTraceElementProxyArray;
- }
- public int getCommonFrames() {
- return commonFrames;
- }
- /*
- * (non-Javadoc)
- *
- * @see ch.qos.logback.classic.spi.IThrowableProxy#getCause()
- */
- public IThrowableProxy getCause() {
- return cause;
+ public void fullDump() {
+ StringBuilder builder = new StringBuilder();
+ for (StackTraceElementProxy step : stackTraceElementProxyArray) {
+ String string = step.toString();
+ builder.append(CoreConstants.TAB).append(string);
+ ThrowableProxyUtil.subjoinPackagingData(builder, step);
+ builder.append(CoreConstants.LINE_SEPARATOR);
}
+ System.out.println(builder.toString());
+ }
- public IThrowableProxy[] getSuppressed() {
- return suppressed;
- }
-
- public PackagingDataCalculator getPackagingDataCalculator() {
- // if original instance (non-deserialized), and packagingDataCalculator
- // is not already initialized, then create an instance.
- // here we assume that (throwable == null) for deserialized instances
- if (throwable != null && packagingDataCalculator == null) {
- packagingDataCalculator = new PackagingDataCalculator();
- }
- return packagingDataCalculator;
- }
-
- public void calculatePackagingData() {
- if (calculatedPackageData) {
- return;
- }
- PackagingDataCalculator pdc = this.getPackagingDataCalculator();
- if (pdc != null) {
- calculatedPackageData = true;
- pdc.calculate(this);
- }
- }
-
- public void fullDump() {
- StringBuilder builder = new StringBuilder();
- for (StackTraceElementProxy step : stackTraceElementProxyArray) {
- String string = step.toString();
- builder.append(CoreConstants.TAB).append(string);
- ThrowableProxyUtil.subjoinPackagingData(builder, step);
- builder.append(CoreConstants.LINE_SEPARATOR);
- }
- System.out.println(builder.toString());
- }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxyUtil.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxyUtil.java
index 0199317..9260720 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxyUtil.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxyUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,162 +23,167 @@ import ch.qos.logback.core.CoreConstants;
*/
public class ThrowableProxyUtil {
- public static final int REGULAR_EXCEPTION_INDENT = 1;
- public static final int SUPPRESSED_EXCEPTION_INDENT = 1;
- private static final int BUILDER_CAPACITY = 2048;
+ public static final int REGULAR_EXCEPTION_INDENT = 1;
+ public static final int SUPPRESSED_EXCEPTION_INDENT = 1;
+ private static final int BUILDER_CAPACITY = 2048;
- public static void build(ThrowableProxy nestedTP, Throwable nestedThrowable, ThrowableProxy parentTP) {
+ public static void build(ThrowableProxy nestedTP, Throwable nestedThrowable,
+ ThrowableProxy parentTP) {
- StackTraceElement[] nestedSTE = nestedThrowable.getStackTrace();
+ StackTraceElement[] nestedSTE = nestedThrowable.getStackTrace();
- int commonFramesCount = -1;
- if (parentTP != null) {
- commonFramesCount = findNumberOfCommonFrames(nestedSTE, parentTP.getStackTraceElementProxyArray());
- }
-
- nestedTP.commonFrames = commonFramesCount;
- nestedTP.stackTraceElementProxyArray = steArrayToStepArray(nestedSTE);
+ int commonFramesCount = -1;
+ if (parentTP != null) {
+ commonFramesCount = findNumberOfCommonFrames(nestedSTE, parentTP
+ .getStackTraceElementProxyArray());
}
- static StackTraceElementProxy[] steArrayToStepArray(StackTraceElement[] stea) {
- if (stea == null) {
- return new StackTraceElementProxy[0];
- }
- StackTraceElementProxy[] stepa = new StackTraceElementProxy[stea.length];
- for (int i = 0; i < stepa.length; i++) {
- stepa[i] = new StackTraceElementProxy(stea[i]);
- }
- return stepa;
- }
-
- static int findNumberOfCommonFrames(StackTraceElement[] steArray, StackTraceElementProxy[] parentSTEPArray) {
- if (parentSTEPArray == null || steArray == null) {
- return 0;
- }
+ nestedTP.commonFrames = commonFramesCount;
+ nestedTP.stackTraceElementProxyArray = steArrayToStepArray(nestedSTE);
+ }
- int steIndex = steArray.length - 1;
- int parentIndex = parentSTEPArray.length - 1;
- int count = 0;
- while (steIndex >= 0 && parentIndex >= 0) {
- StackTraceElement ste = steArray[steIndex];
- StackTraceElement otherSte = parentSTEPArray[parentIndex].ste;
- if (ste.equals(otherSte)) {
- count++;
- } else {
- break;
- }
- steIndex--;
- parentIndex--;
- }
- return count;
- }
-
- public static String asString(IThrowableProxy tp) {
- StringBuilder sb = new StringBuilder(BUILDER_CAPACITY);
-
- recursiveAppend(sb, null, REGULAR_EXCEPTION_INDENT, tp);
-
- return sb.toString();
+ static StackTraceElementProxy[] steArrayToStepArray(StackTraceElement[] stea) {
+ if(stea == null) {
+ return new StackTraceElementProxy[0];
}
-
- private static void recursiveAppend(StringBuilder sb, String prefix, int indent, IThrowableProxy tp) {
- if (tp == null)
- return;
- subjoinFirstLine(sb, prefix, indent, tp);
- sb.append(CoreConstants.LINE_SEPARATOR);
- subjoinSTEPArray(sb, indent, tp);
- IThrowableProxy[] suppressed = tp.getSuppressed();
- if (suppressed != null) {
- for (IThrowableProxy current : suppressed) {
- recursiveAppend(sb, CoreConstants.SUPPRESSED, indent + SUPPRESSED_EXCEPTION_INDENT, current);
- }
- }
- recursiveAppend(sb, CoreConstants.CAUSED_BY, indent, tp.getCause());
+ StackTraceElementProxy[] stepa = new StackTraceElementProxy[stea.length];
+ for (int i = 0; i < stepa.length; i++) {
+ stepa[i] = new StackTraceElementProxy(stea[i]);
}
+ return stepa;
+ }
- public static void indent(StringBuilder buf, int indent) {
- for (int j = 0; j < indent; j++) {
- buf.append(CoreConstants.TAB);
- }
+ static int findNumberOfCommonFrames(StackTraceElement[] steArray,
+ StackTraceElementProxy[] parentSTEPArray) {
+ if (parentSTEPArray == null || steArray == null) {
+ return 0;
}
- private static void subjoinFirstLine(StringBuilder buf, String prefix, int indent, IThrowableProxy tp) {
- indent(buf, indent - 1);
- if (prefix != null) {
- buf.append(prefix);
- }
- subjoinExceptionMessage(buf, tp);
+ int steIndex = steArray.length - 1;
+ int parentIndex = parentSTEPArray.length - 1;
+ int count = 0;
+ while (steIndex >= 0 && parentIndex >= 0) {
+ StackTraceElement ste = steArray[steIndex];
+ StackTraceElement otherSte = parentSTEPArray[parentIndex].ste;
+ if (ste.equals(otherSte)) {
+ count++;
+ } else {
+ break;
+ }
+ steIndex--;
+ parentIndex--;
}
-
- public static void subjoinPackagingData(StringBuilder builder, StackTraceElementProxy step) {
- if (step != null) {
- ClassPackagingData cpd = step.getClassPackagingData();
- if (cpd != null) {
- if (!cpd.isExact()) {
- builder.append(" ~[");
- } else {
- builder.append(" [");
- }
-
- builder.append(cpd.getCodeLocation()).append(':').append(cpd.getVersion()).append(']');
- }
- }
+ return count;
+ }
+
+ public static String asString(IThrowableProxy tp) {
+ StringBuilder sb = new StringBuilder(BUILDER_CAPACITY);
+
+ recursiveAppend(sb, null, REGULAR_EXCEPTION_INDENT, tp);
+
+ return sb.toString();
+ }
+
+ private static void recursiveAppend(StringBuilder sb, String prefix, int indent, IThrowableProxy tp) {
+ if(tp == null)
+ return;
+ subjoinFirstLine(sb, prefix, indent, tp);
+ sb.append(CoreConstants.LINE_SEPARATOR);
+ subjoinSTEPArray(sb, indent, tp);
+ IThrowableProxy[] suppressed = tp.getSuppressed();
+ if(suppressed != null) {
+ for(IThrowableProxy current : suppressed) {
+ recursiveAppend(sb, CoreConstants.SUPPRESSED, indent + SUPPRESSED_EXCEPTION_INDENT, current);
+ }
}
+ recursiveAppend(sb, CoreConstants.CAUSED_BY, indent, tp.getCause());
+ }
- public static void subjoinSTEP(StringBuilder sb, StackTraceElementProxy step) {
- sb.append(step.toString());
- subjoinPackagingData(sb, step);
+ public static void indent(StringBuilder buf, int indent) {
+ for(int j = 0; j < indent; j++) {
+ buf.append(CoreConstants.TAB);
}
+ }
- /**
- * @param sb The StringBuilder the STEPs are appended to.
- * @param tp the IThrowableProxy containing the STEPs.
- * @deprecated Use subjoinSTEPArray(StringBuilder sb, int indentLevel, IThrowableProxy tp) instead.
- */
- public static void subjoinSTEPArray(StringBuilder sb, IThrowableProxy tp) {
- // not called anymore - but it is public
- subjoinSTEPArray(sb, REGULAR_EXCEPTION_INDENT, tp);
+ private static void subjoinFirstLine(StringBuilder buf, String prefix, int indent, IThrowableProxy tp) {
+ indent(buf, indent - 1);
+ if (prefix != null) {
+ buf.append(prefix);
}
-
- /**
- * @param sb The StringBuilder the STEPs are appended to.
- * @param indentLevel indentation level used for the STEPs, usually REGULAR_EXCEPTION_INDENT.
- * @param tp the IThrowableProxy containing the STEPs.
- */
- public static void subjoinSTEPArray(StringBuilder sb, int indentLevel, IThrowableProxy tp) {
- StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
- int commonFrames = tp.getCommonFrames();
-
- for (int i = 0; i < stepArray.length - commonFrames; i++) {
- StackTraceElementProxy step = stepArray[i];
- indent(sb, indentLevel);
- subjoinSTEP(sb, step);
- sb.append(CoreConstants.LINE_SEPARATOR);
- }
-
- if (commonFrames > 0) {
- indent(sb, indentLevel);
- sb.append("... ").append(commonFrames).append(" common frames omitted").append(CoreConstants.LINE_SEPARATOR);
+ subjoinExceptionMessage(buf, tp);
+ }
+
+ public static void subjoinPackagingData(StringBuilder builder, StackTraceElementProxy step) {
+ if (step != null) {
+ ClassPackagingData cpd = step.getClassPackagingData();
+ if (cpd != null) {
+ if (!cpd.isExact()) {
+ builder.append(" ~[");
+ } else {
+ builder.append(" [");
}
+ builder.append(cpd.getCodeLocation()).append(':').append(
+ cpd.getVersion()).append(']');
+ }
+ }
+ }
+
+ public static void subjoinSTEP(StringBuilder sb, StackTraceElementProxy step) {
+ sb.append(step.toString());
+ subjoinPackagingData(sb, step);
+ }
+
+ /**
+ * @param sb The StringBuilder the STEPs are appended to.
+ * @param tp the IThrowableProxy containing the STEPs.
+ * @deprecated Use subjoinSTEPArray(StringBuilder sb, int indentLevel, IThrowableProxy tp) instead.
+ */
+ public static void subjoinSTEPArray(StringBuilder sb, IThrowableProxy tp) {
+ // not called anymore - but it is public
+ subjoinSTEPArray(sb, REGULAR_EXCEPTION_INDENT, tp);
+ }
+
+ /**
+ * @param sb The StringBuilder the STEPs are appended to.
+ * @param indentLevel indentation level used for the STEPs, usually REGULAR_EXCEPTION_INDENT.
+ * @param tp the IThrowableProxy containing the STEPs.
+ */
+ public static void subjoinSTEPArray(StringBuilder sb, int indentLevel, IThrowableProxy tp) {
+ StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
+ int commonFrames = tp.getCommonFrames();
+
+ for (int i = 0; i < stepArray.length - commonFrames; i++) {
+ StackTraceElementProxy step = stepArray[i];
+ indent(sb, indentLevel);
+ subjoinSTEP(sb, step);
+ sb.append(CoreConstants.LINE_SEPARATOR);
}
- public static void subjoinFirstLine(StringBuilder buf, IThrowableProxy tp) {
- int commonFrames = tp.getCommonFrames();
- if (commonFrames > 0) {
- buf.append(CoreConstants.CAUSED_BY);
- }
- subjoinExceptionMessage(buf, tp);
+ if (commonFrames > 0) {
+ indent(sb, indentLevel);
+ sb.append("... ").append(commonFrames).append(" common frames omitted")
+ .append(CoreConstants.LINE_SEPARATOR);
}
- public static void subjoinFirstLineRootCauseFirst(StringBuilder buf, IThrowableProxy tp) {
- if (tp.getCause() != null) {
- buf.append(CoreConstants.WRAPPED_BY);
- }
- subjoinExceptionMessage(buf, tp);
+ }
+
+ public static void subjoinFirstLine(StringBuilder buf, IThrowableProxy tp) {
+ int commonFrames = tp.getCommonFrames();
+ if (commonFrames > 0) {
+ buf.append(CoreConstants.CAUSED_BY);
}
+ subjoinExceptionMessage(buf, tp);
+ }
- private static void subjoinExceptionMessage(StringBuilder buf, IThrowableProxy tp) {
- buf.append(tp.getClassName()).append(": ").append(tp.getMessage());
+ public static void subjoinFirstLineRootCauseFirst(StringBuilder buf, IThrowableProxy tp) {
+ if (tp.getCause() != null) {
+ buf.append(CoreConstants.WRAPPED_BY);
}
+ subjoinExceptionMessage(buf, tp);
+ }
+
+ private static void subjoinExceptionMessage(StringBuilder buf, IThrowableProxy tp) {
+ buf.append(tp.getClassName()).append(": ").append(tp.getMessage());
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxyVO.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxyVO.java
index 7933e89..e285520 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxyVO.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ThrowableProxyVO.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,98 +18,100 @@ import java.util.Arrays;
public class ThrowableProxyVO implements IThrowableProxy, Serializable {
- private static final long serialVersionUID = -773438177285807139L;
-
- private String className;
- private String message;
- private int commonFramesCount;
- private StackTraceElementProxy[] stackTraceElementProxyArray;
- private IThrowableProxy cause;
- private IThrowableProxy[] suppressed;
-
- public String getMessage() {
- return message;
- }
-
- public String getClassName() {
- return className;
- }
-
- public int getCommonFrames() {
- return commonFramesCount;
+ private static final long serialVersionUID = -773438177285807139L;
+
+ private String className;
+ private String message;
+ private int commonFramesCount;
+ private StackTraceElementProxy[] stackTraceElementProxyArray;
+ private IThrowableProxy cause;
+ private IThrowableProxy[] suppressed;
+
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ public int getCommonFrames() {
+ return commonFramesCount;
+ }
+
+ public IThrowableProxy getCause() {
+ return cause;
+ }
+
+ public StackTraceElementProxy[] getStackTraceElementProxyArray() {
+ return stackTraceElementProxyArray;
+ }
+
+ public IThrowableProxy[] getSuppressed() {
+ return suppressed;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((className == null) ? 0 : className.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final ThrowableProxyVO other = (ThrowableProxyVO) obj;
+
+ if (className == null) {
+ if (other.className != null)
+ return false;
+ } else if (!className.equals(other.className))
+ return false;
+
+ if (!Arrays.equals(stackTraceElementProxyArray, other.stackTraceElementProxyArray))
+ return false;
+
+ if (!Arrays.equals(suppressed, other.suppressed))
+ return false;
+
+ if (cause == null) {
+ if (other.cause != null)
+ return false;
+ } else if (!cause.equals(other.cause))
+ return false;
+
+ return true;
+ }
+
+ public static ThrowableProxyVO build(IThrowableProxy throwableProxy) {
+ if(throwableProxy == null) {
+ return null;
}
-
- public IThrowableProxy getCause() {
- return cause;
- }
-
- public StackTraceElementProxy[] getStackTraceElementProxyArray() {
- return stackTraceElementProxyArray;
- }
-
- public IThrowableProxy[] getSuppressed() {
- return suppressed;
+ ThrowableProxyVO tpvo = new ThrowableProxyVO();
+ tpvo.className = throwableProxy.getClassName();
+ tpvo.message = throwableProxy.getMessage();
+ tpvo.commonFramesCount = throwableProxy.getCommonFrames();
+ tpvo.stackTraceElementProxyArray = throwableProxy.getStackTraceElementProxyArray();
+ IThrowableProxy cause = throwableProxy.getCause();
+ if(cause != null) {
+ tpvo.cause = ThrowableProxyVO.build(cause);
}
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((className == null) ? 0 : className.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final ThrowableProxyVO other = (ThrowableProxyVO) obj;
-
- if (className == null) {
- if (other.className != null)
- return false;
- } else if (!className.equals(other.className))
- return false;
-
- if (!Arrays.equals(stackTraceElementProxyArray, other.stackTraceElementProxyArray))
- return false;
-
- if (!Arrays.equals(suppressed, other.suppressed))
- return false;
-
- if (cause == null) {
- if (other.cause != null)
- return false;
- } else if (!cause.equals(other.cause))
- return false;
-
- return true;
- }
-
- public static ThrowableProxyVO build(IThrowableProxy throwableProxy) {
- if (throwableProxy == null) {
- return null;
- }
- ThrowableProxyVO tpvo = new ThrowableProxyVO();
- tpvo.className = throwableProxy.getClassName();
- tpvo.message = throwableProxy.getMessage();
- tpvo.commonFramesCount = throwableProxy.getCommonFrames();
- tpvo.stackTraceElementProxyArray = throwableProxy.getStackTraceElementProxyArray();
- IThrowableProxy cause = throwableProxy.getCause();
- if (cause != null) {
- tpvo.cause = ThrowableProxyVO.build(cause);
- }
- IThrowableProxy[] suppressed = throwableProxy.getSuppressed();
- if (suppressed != null) {
- tpvo.suppressed = new IThrowableProxy[suppressed.length];
- for (int i = 0; i < suppressed.length; i++) {
- tpvo.suppressed[i] = ThrowableProxyVO.build(suppressed[i]);
- }
- }
- return tpvo;
+ IThrowableProxy[] suppressed = throwableProxy.getSuppressed();
+ if(suppressed != null) {
+ tpvo.suppressed = new IThrowableProxy[suppressed.length];
+ for(int i = 0;i<suppressed.length;i++) {
+ tpvo.suppressed[i] = ThrowableProxyVO.build(suppressed[i]);
+ }
}
+ return tpvo;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterList.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterList.java
index ca2028b..fbbf826 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterList.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterList.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,52 +29,54 @@ import ch.qos.logback.core.spi.FilterReply;
*/
final public class TurboFilterList extends CopyOnWriteArrayList<TurboFilter> {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 1L;
- /**
- * Loop through the filters in the chain. As soon as a filter decides on
- * ACCEPT or DENY, then that value is returned. If all of the filters return
- * NEUTRAL, then NEUTRAL is returned.
- */
- public FilterReply getTurboFilterChainDecision(final Marker marker, final Logger logger, final Level level, final String format, final Object[] params,
- final Throwable t) {
-
- final int size = size();
- // if (size == 0) {
- // return FilterReply.NEUTRAL;
- // }
- if (size == 1) {
- try {
- TurboFilter tf = get(0);
- return tf.decide(marker, logger, level, format, params, t);
- } catch (IndexOutOfBoundsException iobe) {
- return FilterReply.NEUTRAL;
- }
- }
-
- Object[] tfa = toArray();
- final int len = tfa.length;
- for (int i = 0; i < len; i++) {
- // for (TurboFilter tf : this) {
- final TurboFilter tf = (TurboFilter) tfa[i];
- final FilterReply r = tf.decide(marker, logger, level, format, params, t);
- if (r == FilterReply.DENY || r == FilterReply.ACCEPT) {
- return r;
- }
- }
+ /**
+ * Loop through the filters in the chain. As soon as a filter decides on
+ * ACCEPT or DENY, then that value is returned. If all of the filters return
+ * NEUTRAL, then NEUTRAL is returned.
+ */
+ public FilterReply getTurboFilterChainDecision(final Marker marker,
+ final Logger logger, final Level level, final String format,
+ final Object[] params, final Throwable t) {
+
+
+ final int size = size();
+// if (size == 0) {
+// return FilterReply.NEUTRAL;
+// }
+ if (size == 1) {
+ try {
+ TurboFilter tf = get(0);
+ return tf.decide(marker, logger, level, format, params, t);
+ } catch (IndexOutOfBoundsException iobe) {
return FilterReply.NEUTRAL;
+ }
+ }
+
+ Object[] tfa = toArray();
+ final int len = tfa.length;
+ for (int i = 0; i < len; i++) {
+ //for (TurboFilter tf : this) {
+ final TurboFilter tf = (TurboFilter) tfa[i];
+ final FilterReply r = tf.decide(marker, logger, level, format, params, t);
+ if (r == FilterReply.DENY || r == FilterReply.ACCEPT) {
+ return r;
+ }
}
+ return FilterReply.NEUTRAL;
+ }
- // public boolean remove(TurboFilter turboFilter) {
- // return tfList.remove(turboFilter);
- // }
- //
- // public TurboFilter remove(int index) {
- // return tfList.remove(index);
- // }
- //
- // final public int size() {
- // return tfList.size();
- // }
+ // public boolean remove(TurboFilter turboFilter) {
+ // return tfList.remove(turboFilter);
+ // }
+ //
+ // public TurboFilter remove(int index) {
+ // return tfList.remove(index);
+ // }
+ //
+ // final public int size() {
+ // return tfList.size();
+ // }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DuplicateMessageFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DuplicateMessageFilter.java
index ca62f4c..55546b6 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DuplicateMessageFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DuplicateMessageFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,62 +29,63 @@ import ch.qos.logback.core.spi.FilterReply;
*/
public class DuplicateMessageFilter extends TurboFilter {
- /**
- * The default cache size.
- */
- public static final int DEFAULT_CACHE_SIZE = 100;
- /**
- * The default number of allows repetitions.
- */
- public static final int DEFAULT_ALLOWED_REPETITIONS = 5;
+ /**
+ * The default cache size.
+ */
+ public static final int DEFAULT_CACHE_SIZE = 100;
+ /**
+ * The default number of allows repetitions.
+ */
+ public static final int DEFAULT_ALLOWED_REPETITIONS = 5;
- public int allowedRepetitions = DEFAULT_ALLOWED_REPETITIONS;
- public int cacheSize = DEFAULT_CACHE_SIZE;
+ public int allowedRepetitions = DEFAULT_ALLOWED_REPETITIONS;
+ public int cacheSize = DEFAULT_CACHE_SIZE;
- private LRUMessageCache msgCache;
+ private LRUMessageCache msgCache;
- @Override
- public void start() {
- msgCache = new LRUMessageCache(cacheSize);
- super.start();
- }
+ @Override
+ public void start() {
+ msgCache = new LRUMessageCache(cacheSize);
+ super.start();
+ }
- @Override
- public void stop() {
- msgCache.clear();
- msgCache = null;
- super.stop();
- }
+ @Override
+ public void stop() {
+ msgCache.clear();
+ msgCache = null;
+ super.stop();
+ }
- @Override
- public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
- int count = msgCache.getMessageCountAndThenIncrement(format);
- if (count <= allowedRepetitions) {
- return FilterReply.NEUTRAL;
- } else {
- return FilterReply.DENY;
- }
+ @Override
+ public FilterReply decide(Marker marker, Logger logger, Level level,
+ String format, Object[] params, Throwable t) {
+ int count = msgCache.getMessageCountAndThenIncrement(format);
+ if (count <= allowedRepetitions) {
+ return FilterReply.NEUTRAL;
+ } else {
+ return FilterReply.DENY;
}
+ }
- public int getAllowedRepetitions() {
- return allowedRepetitions;
- }
+ public int getAllowedRepetitions() {
+ return allowedRepetitions;
+ }
- /**
- * The allowed number of repetitions before
- *
- * @param allowedRepetitions
- */
- public void setAllowedRepetitions(int allowedRepetitions) {
- this.allowedRepetitions = allowedRepetitions;
- }
+ /**
+ * The allowed number of repetitions before
+ *
+ * @param allowedRepetitions
+ */
+ public void setAllowedRepetitions(int allowedRepetitions) {
+ this.allowedRepetitions = allowedRepetitions;
+ }
- public int getCacheSize() {
- return cacheSize;
- }
+ public int getCacheSize() {
+ return cacheSize;
+ }
- public void setCacheSize(int cacheSize) {
- this.cacheSize = cacheSize;
- }
+ public void setCacheSize(int cacheSize) {
+ this.cacheSize = cacheSize;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DynamicThresholdFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DynamicThresholdFilter.java
index c931774..e8c36a2 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DynamicThresholdFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DynamicThresholdFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -121,135 +121,137 @@ import java.util.HashMap;
* </configuration>
* </pre>
*
- * @author Ralph Goers
+ * @author Raplh Goers
* @author Ceki Gülcü
*/
public class DynamicThresholdFilter extends TurboFilter {
- private Map<String, Level> valueLevelMap = new HashMap<String, Level>();
- private Level defaultThreshold = Level.ERROR;
- private String key;
-
- private FilterReply onHigherOrEqual = FilterReply.NEUTRAL;
- private FilterReply onLower = FilterReply.DENY;
-
- /**
- * Get the MDC key whose value will be used as a level threshold
- *
- * @return the name of the MDC key.
- */
- public String getKey() {
- return this.key;
- }
+ private Map<String, Level> valueLevelMap = new HashMap<String, Level>();
+ private Level defaultThreshold = Level.ERROR;
+ private String key;
- /**
- * @see setKey
- */
- public void setKey(String key) {
- this.key = key;
- }
+ private FilterReply onHigherOrEqual = FilterReply.NEUTRAL;
+ private FilterReply onLower = FilterReply.DENY;
- /**
- * Get the default threshold value when the MDC key is not set.
- *
- * @return the default threshold value in the absence of a set MDC key
- */
- public Level getDefaultThreshold() {
- return defaultThreshold;
- }
+ /**
+ * Get the MDC key whose value will be used as a level threshold
+ *
+ * @return the name of the MDC key.
+ */
+ public String getKey() {
+ return this.key;
+ }
- public void setDefaultThreshold(Level defaultThreshold) {
- this.defaultThreshold = defaultThreshold;
- }
+ /**
+ * @see setKey
+ */
+ public void setKey(String key) {
+ this.key = key;
+ }
- /**
- * Get the FilterReply when the effective level is higher or equal to the
- * level of current logging request
- *
- * @return FilterReply
- */
- public FilterReply getOnHigherOrEqual() {
- return onHigherOrEqual;
- }
+ /**
+ * Get the default threshold value when the MDC key is not set.
+ *
+ * @return the default threshold value in the absence of a set MDC key
+ */
+ public Level getDefaultThreshold() {
+ return defaultThreshold;
+ }
- public void setOnHigherOrEqual(FilterReply onHigherOrEqual) {
- this.onHigherOrEqual = onHigherOrEqual;
- }
+ public void setDefaultThreshold(Level defaultThreshold) {
+ this.defaultThreshold = defaultThreshold;
+ }
- /**
- * Get the FilterReply when the effective level is lower than the level of
- * current logging request
- *
- * @return FilterReply
- */
- public FilterReply getOnLower() {
- return onLower;
- }
+ /**
+ * Get the FilterReply when the effective level is higher or equal to the
+ * level of current logging request
+ *
+ * @return FilterReply
+ */
+ public FilterReply getOnHigherOrEqual() {
+ return onHigherOrEqual;
+ }
- public void setOnLower(FilterReply onLower) {
- this.onLower = onLower;
+ public void setOnHigherOrEqual(FilterReply onHigherOrEqual) {
+ this.onHigherOrEqual = onHigherOrEqual;
+ }
+
+ /**
+ * Get the FilterReply when the effective level is lower than the level of
+ * current logging request
+ *
+ * @return FilterReply
+ */
+ public FilterReply getOnLower() {
+ return onLower;
+ }
+
+ public void setOnLower(FilterReply onLower) {
+ this.onLower = onLower;
+ }
+
+ /**
+ * Add a new MDCValuePair
+ */
+ public void addMDCValueLevelPair(MDCValueLevelPair mdcValueLevelPair) {
+ if (valueLevelMap.containsKey(mdcValueLevelPair.getValue())) {
+ addError(mdcValueLevelPair.getValue() + " has been already set");
+ } else {
+ valueLevelMap.put(mdcValueLevelPair.getValue(), mdcValueLevelPair
+ .getLevel());
}
+ }
- /**
- * Add a new MDCValuePair
- */
- public void addMDCValueLevelPair(MDCValueLevelPair mdcValueLevelPair) {
- if (valueLevelMap.containsKey(mdcValueLevelPair.getValue())) {
- addError(mdcValueLevelPair.getValue() + " has been already set");
- } else {
- valueLevelMap.put(mdcValueLevelPair.getValue(), mdcValueLevelPair.getLevel());
- }
+ /**
+ *
+ */
+ @Override
+ public void start() {
+ if (this.key == null) {
+ addError("No key name was specified");
}
+ super.start();
+ }
- /**
- *
- */
- @Override
- public void start() {
- if (this.key == null) {
- addError("No key name was specified");
- }
- super.start();
+ /**
+ * This method first finds the MDC value for 'key'. It then finds the level
+ * threshold associated with this MDC value from the list of MDCValueLevelPair
+ * passed to this filter. This value is stored in a variable called
+ * 'levelAssociatedWithMDCValue'. If it null, then it is set to the
+ *
+ * @{link #defaultThreshold} value.
+ *
+ * If no such value exists, then
+ *
+ *
+ * @param marker
+ * @param logger
+ * @param level
+ * @param s
+ * @param objects
+ * @param throwable
+ *
+ * @return FilterReply - this filter's decision
+ */
+ @Override
+ public FilterReply decide(Marker marker, Logger logger, Level level,
+ String s, Object[] objects, Throwable throwable) {
+
+ String mdcValue = MDC.get(this.key);
+ if (!isStarted()) {
+ return FilterReply.NEUTRAL;
}
- /**
- * This method first finds the MDC value for 'key'. It then finds the level
- * threshold associated with this MDC value from the list of MDCValueLevelPair
- * passed to this filter. This value is stored in a variable called
- * 'levelAssociatedWithMDCValue'. If it null, then it is set to the
- *
- * @{link #defaultThreshold} value.
- *
- * If no such value exists, then
- *
- *
- * @param marker
- * @param logger
- * @param level
- * @param s
- * @param objects
- * @param throwable
- *
- * @return FilterReply - this filter's decision
- */
- @Override
- public FilterReply decide(Marker marker, Logger logger, Level level, String s, Object[] objects, Throwable throwable) {
-
- String mdcValue = MDC.get(this.key);
- if (!isStarted()) {
- return FilterReply.NEUTRAL;
- }
-
- Level levelAssociatedWithMDCValue = null;
- if (mdcValue != null) {
- levelAssociatedWithMDCValue = valueLevelMap.get(mdcValue);
- }
- if (levelAssociatedWithMDCValue == null) {
- levelAssociatedWithMDCValue = defaultThreshold;
- }
- if (level.isGreaterOrEqual(levelAssociatedWithMDCValue)) {
- return onHigherOrEqual;
- } else {
- return onLower;
- }
+ Level levelAssociatedWithMDCValue = null;
+ if (mdcValue != null) {
+ levelAssociatedWithMDCValue = valueLevelMap.get(mdcValue);
+ }
+ if (levelAssociatedWithMDCValue == null) {
+ levelAssociatedWithMDCValue = defaultThreshold;
+ }
+ if (level.isGreaterOrEqual(levelAssociatedWithMDCValue)) {
+ return onHigherOrEqual;
+ } else {
+ return onLower;
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/LRUMessageCache.java b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/LRUMessageCache.java
index d1ec695..3d9ba97 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/LRUMessageCache.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/LRUMessageCache.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,45 +22,45 @@ import java.util.Map;
*/
class LRUMessageCache extends LinkedHashMap<String, Integer> {
- private static final long serialVersionUID = 1L;
- final int cacheSize;
+ private static final long serialVersionUID = 1L;
+ final int cacheSize;
- LRUMessageCache(int cacheSize) {
- super((int) (cacheSize * (4.0f / 3)), 0.75f, true);
- if (cacheSize < 1) {
- throw new IllegalArgumentException("Cache size cannot be smaller than 1");
- }
- this.cacheSize = cacheSize;
+ LRUMessageCache(int cacheSize) {
+ super((int) (cacheSize * (4.0f / 3)), 0.75f, true);
+ if (cacheSize < 1) {
+ throw new IllegalArgumentException("Cache size cannot be smaller than 1");
}
+ this.cacheSize = cacheSize;
+ }
- int getMessageCountAndThenIncrement(String msg) {
- // don't insert null elements
- if (msg == null) {
- return 0;
- }
-
- Integer i;
- // LinkedHashMap is not LinkedHashMap. See also LBCLASSIC-255
- synchronized (this) {
- i = super.get(msg);
- if (i == null) {
- i = 0;
- } else {
- i = i + 1;
- }
- super.put(msg, i);
- }
- return i;
+ int getMessageCountAndThenIncrement(String msg) {
+ // don't insert null elements
+ if (msg == null) {
+ return 0;
}
- // called indirectly by get() or put() which are already supposed to be
- // called from within a synchronized block
- protected boolean removeEldestEntry(Map.Entry eldest) {
- return (size() > cacheSize);
+ Integer i;
+ // LinkedHashMap is not LinkedHashMap. See also LBCLASSIC-255
+ synchronized (this) {
+ i = super.get(msg);
+ if (i == null) {
+ i = 0;
+ } else {
+ i = i + 1;
+ }
+ super.put(msg, i);
}
+ return i;
+ }
- @Override
- synchronized public void clear() {
- super.clear();
- }
+ // called indirectly by get() or put() which are already supposed to be
+ // called from within a synchronized block
+ protected boolean removeEldestEntry(Map.Entry eldest) {
+ return (size() > cacheSize);
+ }
+
+ @Override
+ synchronized public void clear() {
+ super.clear();
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MDCFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MDCFilter.java
index 460f31e..e518f48 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MDCFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MDCFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -45,28 +45,28 @@ import ch.qos.logback.core.spi.FilterReply;
*/
public class MDCFilter extends MatchingFilter {
- String MDCKey;
- String value;
-
- @Override
- public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
- if (MDCKey == null) {
- return FilterReply.NEUTRAL;
- }
-
- String value = MDC.get(MDCKey);
- if (this.value.equals(value)) {
- return onMatch;
- }
- return onMismatch;
+ String MDCKey;
+ String value;
+
+ @Override
+ public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
+ if (MDCKey == null) {
+ return FilterReply.NEUTRAL;
}
-
- public void setValue(String value) {
- this.value = value;
- }
-
- public void setMDCKey(String MDCKey) {
- this.MDCKey = MDCKey;
+
+ String value = MDC.get(MDCKey);
+ if (this.value.equals(value)) {
+ return onMatch;
}
+ return onMismatch;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public void setMDCKey(String MDCKey) {
+ this.MDCKey = MDCKey;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MDCValueLevelPair.java b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MDCValueLevelPair.java
index 6734b98..4a9fa6c 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MDCValueLevelPair.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MDCValueLevelPair.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,29 +15,30 @@ package ch.qos.logback.classic.turbo;
import ch.qos.logback.classic.Level;
+
/**
* Bean pairing an MDC value with a log level.
*
- * @author Ralph Goers
+ * @author Raplh Goers
* @author Ceki Gülcü
*/
public class MDCValueLevelPair {
- private String value;
- private Level level;
+ private String value;
+ private Level level;
- public String getValue() {
- return value;
- }
+ public String getValue() {
+ return value;
+ }
- public void setValue(String name) {
- this.value = name;
- }
+ public void setValue(String name) {
+ this.value = name;
+ }
- public Level getLevel() {
- return level;
- }
+ public Level getLevel() {
+ return level;
+ }
- public void setLevel(Level level) {
- this.level = level;
- }
+ public void setLevel(Level level) {
+ this.level = level;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MarkerFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MarkerFilter.java
index ab185f0..45d8e9b 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MarkerFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MarkerFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,42 +26,42 @@ import ch.qos.logback.core.spi.FilterReply;
*/
public class MarkerFilter extends MatchingFilter {
- Marker markerToMatch;
+ Marker markerToMatch;
- @Override
- public void start() {
- if (markerToMatch != null) {
- super.start();
- } else {
- addError("The marker property must be set for [" + getName() + "]");
- }
+ @Override
+ public void start() {
+ if(markerToMatch != null) {
+ super.start();
+ } else {
+ addError("The marker property must be set for ["+getName()+"]");
}
-
- @Override
- public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
- if (!isStarted()) {
- return FilterReply.NEUTRAL;
- }
-
- if (marker == null) {
- return onMismatch;
- }
-
- if (marker.contains(markerToMatch)) {
- return onMatch;
- } else {
- return onMismatch;
- }
+ }
+
+ @Override
+ public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
+ if(!isStarted()) {
+ return FilterReply.NEUTRAL;
+ }
+
+ if(marker == null) {
+ return onMismatch;
+ }
+
+ if(marker.contains(markerToMatch)) {
+ return onMatch;
+ } else {
+ return onMismatch;
}
+ }
- /**
- * The marker to match in the event.
- *
- * @param markerStr
- */
- public void setMarker(String markerStr) {
- if (markerStr != null) {
- this.markerToMatch = MarkerFactory.getMarker(markerStr);
- }
+ /**
+ * The marker to match in the event.
+ *
+ * @param markerStr
+ */
+ public void setMarker(String markerStr) {
+ if(markerStr != null) {
+ this.markerToMatch = MarkerFactory.getMarker(markerStr);
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MatchingFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MatchingFilter.java
index 0453f9a..f362ca9 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MatchingFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/MatchingFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,26 +23,26 @@ import ch.qos.logback.core.spi.FilterReply;
*/
public abstract class MatchingFilter extends TurboFilter {
- protected FilterReply onMatch = FilterReply.NEUTRAL;
- protected FilterReply onMismatch = FilterReply.NEUTRAL;
-
- final public void setOnMatch(String action) {
- if ("NEUTRAL".equals(action)) {
- onMatch = FilterReply.NEUTRAL;
- } else if ("ACCEPT".equals(action)) {
- onMatch = FilterReply.ACCEPT;
- } else if ("DENY".equals(action)) {
- onMatch = FilterReply.DENY;
- }
+ protected FilterReply onMatch = FilterReply.NEUTRAL;
+ protected FilterReply onMismatch = FilterReply.NEUTRAL;
+
+ final public void setOnMatch(String action) {
+ if ("NEUTRAL".equals(action)) {
+ onMatch = FilterReply.NEUTRAL;
+ } else if ("ACCEPT".equals(action)) {
+ onMatch = FilterReply.ACCEPT;
+ } else if ("DENY".equals(action)) {
+ onMatch = FilterReply.DENY;
}
+ }
- final public void setOnMismatch(String action) {
- if ("NEUTRAL".equals(action)) {
- onMismatch = FilterReply.NEUTRAL;
- } else if ("ACCEPT".equals(action)) {
- onMismatch = FilterReply.ACCEPT;
- } else if ("DENY".equals(action)) {
- onMismatch = FilterReply.DENY;
- }
+ final public void setOnMismatch(String action) {
+ if ("NEUTRAL".equals(action)) {
+ onMismatch = FilterReply.NEUTRAL;
+ } else if ("ACCEPT".equals(action)) {
+ onMismatch = FilterReply.ACCEPT;
+ } else if ("DENY".equals(action)) {
+ onMismatch = FilterReply.DENY;
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java
index 3e55b0f..9eeed29 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -42,197 +42,203 @@ import static ch.qos.logback.core.CoreConstants.MILLIS_IN_ONE_SECOND;
*/
public class ReconfigureOnChangeFilter extends TurboFilter {
- /**
- * Scan for changes in configuration file once every minute.
- */
- // 1 minute - value mentioned in documentation
- public final static long DEFAULT_REFRESH_PERIOD = 60 * MILLIS_IN_ONE_SECOND;
-
- long refreshPeriod = DEFAULT_REFRESH_PERIOD;
- URL mainConfigurationURL;
- protected volatile long nextCheck;
-
- ConfigurationWatchList configurationWatchList;
-
- @Override
- public void start() {
- configurationWatchList = ConfigurationWatchListUtil.getConfigurationWatchList(context);
- if (configurationWatchList != null) {
- mainConfigurationURL = configurationWatchList.getMainURL();
- if (mainConfigurationURL == null) {
- addWarn("Due to missing top level configuration file, automatic reconfiguration is impossible.");
- return;
- }
- List<File> watchList = configurationWatchList.getCopyOfFileWatchList();
- long inSeconds = refreshPeriod / 1000;
- addInfo("Will scan for changes in [" + watchList + "] every " + inSeconds + " seconds. ");
- synchronized (configurationWatchList) {
- updateNextCheck(System.currentTimeMillis());
- }
- super.start();
- } else {
- addWarn("Empty ConfigurationWatchList in context");
- }
+ /**
+ * Scan for changes in configuration file once every minute.
+ */
+ // 1 minute - value mentioned in documentation
+ public final static long DEFAULT_REFRESH_PERIOD = 60 * MILLIS_IN_ONE_SECOND;
+
+ long refreshPeriod = DEFAULT_REFRESH_PERIOD;
+ URL mainConfigurationURL;
+ protected volatile long nextCheck;
+
+ ConfigurationWatchList configurationWatchList;
+
+ @Override
+ public void start() {
+ configurationWatchList = ConfigurationWatchListUtil.getConfigurationWatchList(context);
+ if (configurationWatchList != null) {
+ mainConfigurationURL = configurationWatchList.getMainURL();
+ if(mainConfigurationURL == null) {
+ addWarn("Due to missing top level configuration file, automatic reconfiguration is impossible.");
+ return;
+ }
+ List<File> watchList = configurationWatchList.getCopyOfFileWatchList();
+ long inSeconds = refreshPeriod / 1000;
+ addInfo("Will scan for changes in [" + watchList + "] every "
+ + inSeconds + " seconds. ");
+ synchronized (configurationWatchList) {
+ updateNextCheck(System.currentTimeMillis());
+ }
+ super.start();
+ } else {
+ addWarn("Empty ConfigurationWatchList in context");
}
-
- @Override
- public String toString() {
- return "ReconfigureOnChangeFilter{" + "invocationCounter=" + invocationCounter + '}';
+ }
+
+ @Override
+ public String toString() {
+ return "ReconfigureOnChangeFilter{" +
+ "invocationCounter=" + invocationCounter +
+ '}';
+ }
+
+ // The next fields counts the number of time the decide method is called
+ //
+ // IMPORTANT: This field can be updated by multiple threads. It follows that
+ // its values may *not* be incremented sequentially. However, we don't care
+ // about the actual value of the field except that from time to time the
+ // expression (invocationCounter++ & mask) == mask) should be true.
+ private long invocationCounter = 0;
+
+ private volatile long mask = 0xF;
+ private volatile long lastMaskCheck = System.currentTimeMillis();
+
+
+ @Override
+ public FilterReply decide(Marker marker, Logger logger, Level level,
+ String format, Object[] params, Throwable t) {
+ if (!isStarted()) {
+ return FilterReply.NEUTRAL;
}
- // The next fields counts the number of time the decide method is called
- //
- // IMPORTANT: This field can be updated by multiple threads. It follows that
- // its values may *not* be incremented sequentially. However, we don't care
- // about the actual value of the field except that from time to time the
- // expression (invocationCounter++ & mask) == mask) should be true.
- private long invocationCounter = 0;
-
- private volatile long mask = 0xF;
- private volatile long lastMaskCheck = System.currentTimeMillis();
-
- @Override
- public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
- if (!isStarted()) {
- return FilterReply.NEUTRAL;
- }
-
- // for performance reasons, skip change detection (MASK-1) times out of MASK.
- // Only once every MASK calls is change detection code executed
- // Note that MASK is a variable itself.
- if (((invocationCounter++) & mask) != mask) {
- return FilterReply.NEUTRAL;
- }
-
- long now = System.currentTimeMillis();
-
- synchronized (configurationWatchList) {
- updateMaskIfNecessary(now);
- if (changeDetected(now)) {
- // Even though reconfiguration involves resetting the loggerContext,
- // which clears the list of turbo filters including this instance, it is
- // still possible for this instance to be subsequently invoked by another
- // thread if it was already executing when the context was reset.
- disableSubsequentReconfiguration();
- detachReconfigurationToNewThread();
- }
- }
-
- return FilterReply.NEUTRAL;
+ // for performance reasons, skip change detection (MASK-1) times out of MASK.
+ // Only once every MASK calls is change detection code executed
+ // Note that MASK is a variable itself.
+ if (((invocationCounter++) & mask) != mask) {
+ return FilterReply.NEUTRAL;
}
- // experiments indicate that even for CPU intensive applications with 200 or more threads MASK
- // values in the order of 0xFFFF is appropriate
- private static final int MAX_MASK = 0xFFFF;
-
- // if less than MASK_INCREASE_THRESHOLD milliseconds elapse between invocations of updateMaskIfNecessary() method,
- // then the mask should be increased
- private static final long MASK_INCREASE_THRESHOLD = 100;
-
- // if more than MASK_DECREASE_THRESHOLD milliseconds elapse between invocations of updateMaskIfNecessary() method,
- // then the mask should be decreased
- private static final long MASK_DECREASE_THRESHOLD = MASK_INCREASE_THRESHOLD * 8;
-
- // update the mask so as to execute change detection code about once every 100 to 8000 milliseconds.
- private void updateMaskIfNecessary(long now) {
- final long timeElapsedSinceLastMaskUpdateCheck = now - lastMaskCheck;
- lastMaskCheck = now;
- if (timeElapsedSinceLastMaskUpdateCheck < MASK_INCREASE_THRESHOLD && (mask < MAX_MASK)) {
- mask = (mask << 1) | 1;
- } else if (timeElapsedSinceLastMaskUpdateCheck > MASK_DECREASE_THRESHOLD) {
- mask = mask >>> 2;
- }
+ long now = System.currentTimeMillis();
+
+ synchronized (configurationWatchList) {
+ updateMaskIfNecessary(now);
+ if (changeDetected(now)) {
+ // Even though reconfiguration involves resetting the loggerContext,
+ // which clears the list of turbo filters including this instance, it is
+ // still possible for this instance to be subsequently invoked by another
+ // thread if it was already executing when the context was reset.
+ disableSubsequentReconfiguration();
+ detachReconfigurationToNewThread();
+ }
}
- // by detaching reconfiguration to a new thread, we release the various
- // locks held by the current thread, in particular, the AppenderAttachable
- // reader lock.
- void detachReconfigurationToNewThread() {
- addInfo("Detected change in [" + configurationWatchList.getCopyOfFileWatchList() + "]");
- context.getExecutorService().submit(new ReconfiguringThread());
- }
+ return FilterReply.NEUTRAL;
+ }
- void updateNextCheck(long now) {
- nextCheck = now + refreshPeriod;
- }
+ // experiments indicate that even for CPU intensive applications with 200 or more threads MASK
+ // values in the order of 0xFFFF is appropriate
+ private static final int MAX_MASK = 0xFFFF;
- protected boolean changeDetected(long now) {
- if (now >= nextCheck) {
- updateNextCheck(now);
- return configurationWatchList.changeDetected();
- }
- return false;
- }
- void disableSubsequentReconfiguration() {
- nextCheck = Long.MAX_VALUE;
- }
+ // if less than MASK_INCREASE_THRESHOLD milliseconds elapse between invocations of updateMaskIfNecessary() method,
+ // then the mask should be increased
+ private static final long MASK_INCREASE_THRESHOLD = 100;
- public long getRefreshPeriod() {
- return refreshPeriod;
- }
+ // if more than MASK_DECREASE_THRESHOLD milliseconds elapse between invocations of updateMaskIfNecessary() method,
+ // then the mask should be decreased
+ private static final long MASK_DECREASE_THRESHOLD = MASK_INCREASE_THRESHOLD*8;
- public void setRefreshPeriod(long refreshPeriod) {
- this.refreshPeriod = refreshPeriod;
+ // update the mask so as to execute change detection code about once every 100 to 8000 milliseconds.
+ private void updateMaskIfNecessary(long now) {
+ final long timeElapsedSinceLastMaskUpdateCheck = now - lastMaskCheck;
+ lastMaskCheck = now;
+ if (timeElapsedSinceLastMaskUpdateCheck < MASK_INCREASE_THRESHOLD && (mask < MAX_MASK)) {
+ mask = (mask << 1) | 1;
+ } else if (timeElapsedSinceLastMaskUpdateCheck > MASK_DECREASE_THRESHOLD) {
+ mask = mask >>> 2;
}
-
- class ReconfiguringThread implements Runnable {
- public void run() {
- if (mainConfigurationURL == null) {
- addInfo("Due to missing top level configuration file, skipping reconfiguration");
- return;
- }
- LoggerContext lc = (LoggerContext) context;
- addInfo(CoreConstants.RESET_MSG_PREFIX + "named [" + context.getName() + "]");
- if (mainConfigurationURL.toString().endsWith("xml")) {
- performXMLConfiguration(lc);
- } else if (mainConfigurationURL.toString().endsWith("groovy")) {
- if (EnvUtil.isGroovyAvailable()) {
- lc.reset();
- // avoid directly referring to GafferConfigurator so as to avoid
- // loading groovy.lang.GroovyObject . See also http://jira.qos.ch/browse/LBCLASSIC-214
- GafferUtil.runGafferConfiguratorOn(lc, this, mainConfigurationURL);
- } else {
- addError("Groovy classes are not available on the class path. ABORTING INITIALIZATION.");
- }
- }
+ }
+
+ // by detaching reconfiguration to a new thread, we release the various
+ // locks held by the current thread, in particular, the AppenderAttachable
+ // reader lock.
+ void detachReconfigurationToNewThread() {
+ addInfo("Detected change in [" + configurationWatchList.getCopyOfFileWatchList() + "]");
+ context.getExecutorService().submit(new ReconfiguringThread());
+ }
+
+ void updateNextCheck(long now) {
+ nextCheck = now + refreshPeriod;
+ }
+
+ protected boolean changeDetected(long now) {
+ if (now >= nextCheck) {
+ updateNextCheck(now);
+ return configurationWatchList.changeDetected();
+ }
+ return false;
+ }
+
+ void disableSubsequentReconfiguration() {
+ nextCheck = Long.MAX_VALUE;
+ }
+
+ public long getRefreshPeriod() {
+ return refreshPeriod;
+ }
+
+ public void setRefreshPeriod(long refreshPeriod) {
+ this.refreshPeriod = refreshPeriod;
+ }
+
+ class ReconfiguringThread implements Runnable {
+ public void run() {
+ if (mainConfigurationURL == null) {
+ addInfo("Due to missing top level configuration file, skipping reconfiguration");
+ return;
+ }
+ LoggerContext lc = (LoggerContext) context;
+ addInfo(CoreConstants.RESET_MSG_PREFIX + "named [" + context.getName() + "]");
+ if (mainConfigurationURL.toString().endsWith("xml")) {
+ performXMLConfiguration(lc);
+ } else if (mainConfigurationURL.toString().endsWith("groovy")) {
+ if (EnvUtil.isGroovyAvailable()) {
+ lc.reset();
+ // avoid directly referring to GafferConfigurator so as to avoid
+ // loading groovy.lang.GroovyObject . See also http://jira.qos.ch/browse/LBCLASSIC-214
+ GafferUtil.runGafferConfiguratorOn(lc, this, mainConfigurationURL);
+ } else {
+ addError("Groovy classes are not available on the class path. ABORTING INITIALIZATION.");
}
+ }
+ }
- private void performXMLConfiguration(LoggerContext lc) {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(context);
- StatusUtil statusUtil = new StatusUtil(context);
- List<SaxEvent> eventList = jc.recallSafeConfiguration();
- URL mainURL = ConfigurationWatchListUtil.getMainWatchURL(context);
- lc.reset();
- long threshold = System.currentTimeMillis();
- try {
- jc.doConfigure(mainConfigurationURL);
- if (statusUtil.hasXMLParsingErrors(threshold)) {
- fallbackConfiguration(lc, eventList, mainURL);
- }
- } catch (JoranException e) {
- fallbackConfiguration(lc, eventList, mainURL);
- }
+ private void performXMLConfiguration(LoggerContext lc) {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(context);
+ StatusUtil statusUtil = new StatusUtil(context);
+ List<SaxEvent> eventList = jc.recallSafeConfiguration();
+ URL mainURL = ConfigurationWatchListUtil.getMainWatchURL(context);
+ lc.reset();
+ long threshold = System.currentTimeMillis();
+ try {
+ jc.doConfigure(mainConfigurationURL);
+ if (statusUtil.hasXMLParsingErrors(threshold)) {
+ fallbackConfiguration(lc, eventList, mainURL);
}
+ } catch (JoranException e) {
+ fallbackConfiguration(lc, eventList, mainURL);
+ }
+ }
- private void fallbackConfiguration(LoggerContext lc, List<SaxEvent> eventList, URL mainURL) {
- JoranConfigurator joranConfigurator = new JoranConfigurator();
- joranConfigurator.setContext(context);
- if (eventList != null) {
- addWarn("Falling back to previously registered safe configuration.");
- try {
- lc.reset();
- JoranConfigurator.informContextOfURLUsedForConfiguration(context, mainURL);
- joranConfigurator.doConfigure(eventList);
- addInfo("Re-registering previous fallback configuration once more as a fallback configuration point");
- joranConfigurator.registerSafeConfiguration(eventList);
- } catch (JoranException e) {
- addError("Unexpected exception thrown by a configuration considered safe.", e);
- }
- } else {
- addWarn("No previous configuration to fall back on.");
- }
+ private void fallbackConfiguration(LoggerContext lc, List<SaxEvent> eventList, URL mainURL) {
+ JoranConfigurator joranConfigurator = new JoranConfigurator();
+ joranConfigurator.setContext(context);
+ if (eventList != null) {
+ addWarn("Falling back to previously registered safe configuration.");
+ try {
+ lc.reset();
+ joranConfigurator.informContextOfURLUsedForConfiguration(context, mainURL);
+ joranConfigurator.doConfigure(eventList);
+ addInfo("Re-registering previous fallback configuration once more as a fallback configuration point");
+ joranConfigurator.registerSafeConfiguration();
+ } catch (JoranException e) {
+ addError("Unexpected exception thrown by a configuration considered safe.", e);
}
+ } else {
+ addWarn("No previous configuration to fall back on.");
+ }
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/TurboFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/TurboFilter.java
index 3f2975b..952479c 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/TurboFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/TurboFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -33,41 +33,44 @@ import ch.qos.logback.core.spi.LifeCycle;
*/
public abstract class TurboFilter extends ContextAwareBase implements LifeCycle {
- private String name;
- boolean start = false;
+ private String name;
+ boolean start = false;
+
+
+ /**
+ * Make a decision based on the multiple parameters passed as arguments.
+ * The returned value should be one of <code>{@link FilterReply#DENY}</code>,
+ * <code>{@link FilterReply#NEUTRAL}</code>, or <code>{@link FilterReply#ACCEPT}</code>.
+
+ * @param marker
+ * @param logger
+ * @param level
+ * @param format
+ * @param params
+ * @param t
+ * @return
+ */
+ public abstract FilterReply decide(Marker marker, Logger logger,
+ Level level, String format, Object[] params, Throwable t);
- /**
- * Make a decision based on the multiple parameters passed as arguments.
- * The returned value should be one of <code>{@link FilterReply#DENY}</code>,
- * <code>{@link FilterReply#NEUTRAL}</code>, or <code>{@link FilterReply#ACCEPT}</code>.
-
- * @param marker
- * @param logger
- * @param level
- * @param format
- * @param params
- * @param t
- * @return
- */
- public abstract FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t);
+ public void start() {
+ this.start = true;
+ }
+
+ public boolean isStarted() {
+ return this.start;
+ }
+
+ public void stop() {
+ this.start = false;
+ }
- public void start() {
- this.start = true;
- }
- public boolean isStarted() {
- return this.start;
- }
+ public String getName() {
+ return name;
+ }
- public void stop() {
- this.start = false;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
+ public void setName(String name) {
+ this.name = name;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextInitializer.java b/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextInitializer.java
index 402d7cf..6fc02ba 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextInitializer.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextInitializer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,7 +23,6 @@ import ch.qos.logback.classic.BasicConfigurator;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.gaffer.GafferUtil;
import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.classic.spi.Configurator;
import ch.qos.logback.core.LogbackException;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.status.ErrorStatus;
@@ -32,7 +31,6 @@ import ch.qos.logback.core.status.StatusManager;
import ch.qos.logback.core.status.WarnStatus;
import ch.qos.logback.core.util.Loader;
import ch.qos.logback.core.util.OptionHelper;
-import ch.qos.logback.core.util.StatusListenerConfigHelper;
// contributors
// Ted Graham, Matt Fowles, see also http://jira.qos.ch/browse/LBCORE-32
@@ -44,151 +42,146 @@ import ch.qos.logback.core.util.StatusListenerConfigHelper;
*/
public class ContextInitializer {
- final public static String GROOVY_AUTOCONFIG_FILE = "logback.groovy";
- final public static String AUTOCONFIG_FILE = "logback.xml";
- final public static String TEST_AUTOCONFIG_FILE = "logback-test.xml";
- final public static String CONFIG_FILE_PROPERTY = "logback.configurationFile";
+ final public static String GROOVY_AUTOCONFIG_FILE = "logback.groovy";
+ final public static String AUTOCONFIG_FILE = "logback.xml";
+ final public static String TEST_AUTOCONFIG_FILE = "logback-test.xml";
+ final public static String CONFIG_FILE_PROPERTY = "logback.configurationFile";
+ final public static String STATUS_LISTENER_CLASS = "logback.statusListenerClass";
+ final public static String SYSOUT = "SYSOUT";
- final LoggerContext loggerContext;
+ final LoggerContext loggerContext;
- public ContextInitializer(LoggerContext loggerContext) {
- this.loggerContext = loggerContext;
- }
+ public ContextInitializer(LoggerContext loggerContext) {
+ this.loggerContext = loggerContext;
+ }
- public void configureByResource(URL url) throws JoranException {
- if (url == null) {
- throw new IllegalArgumentException("URL argument cannot be null");
+ 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()) {
+ // avoid directly referring to GafferConfigurator so as to avoid
+ // loading groovy.lang.GroovyObject . See also http://jira.qos.ch/browse/LBCLASSIC-214
+ 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));
+ }
+ } else if (url.toString().endsWith("xml")) {
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(loggerContext);
+ configurator.doConfigure(url);
+ } else {
+ throw new LogbackException("Unexpected filename extension of file [" + url.toString() + "]. Should be either .groovy or .xml");
+ }
+ }
+
+ void joranConfigureByResource(URL url) throws JoranException {
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(loggerContext);
+ configurator.doConfigure(url);
+ }
+
+ private URL findConfigFileURLFromSystemProperties(ClassLoader classLoader, boolean updateStatus) {
+ String logbackConfigFile = OptionHelper.getSystemProperty(CONFIG_FILE_PROPERTY);
+ if (logbackConfigFile != null) {
+ URL result = null;
+ try {
+ result = new URL(logbackConfigFile);
+ return result;
+ } catch (MalformedURLException e) {
+ // so, resource is not a URL:
+ // attempt to get the resource from the class path
+ result = Loader.getResource(logbackConfigFile, classLoader);
+ if (result != null) {
+ return result;
}
- final String urlString = url.toString();
- if (urlString.endsWith("groovy")) {
- if (EnvUtil.isGroovyAvailable()) {
- // avoid directly referring to GafferConfigurator so as to avoid
- // loading groovy.lang.GroovyObject . See also http://jira.qos.ch/browse/LBCLASSIC-214
- 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));
- }
- } else if (urlString.endsWith("xml")) {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(loggerContext);
- configurator.doConfigure(url);
- } else {
- throw new LogbackException("Unexpected filename extension of file [" + url.toString() + "]. Should be either .groovy or .xml");
+ File f = new File(logbackConfigFile);
+ if (f.exists() && f.isFile()) {
+ try {
+ result = f.toURI().toURL();
+ return result;
+ } catch (MalformedURLException e1) {
+ }
}
+ } finally {
+ if (updateStatus) {
+ statusOnResourceSearch(logbackConfigFile, classLoader, result);
+ }
+ }
}
-
- void joranConfigureByResource(URL url) throws JoranException {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(loggerContext);
- configurator.doConfigure(url);
+ return null;
+ }
+
+ public URL findURLOfDefaultConfigurationFile(boolean updateStatus) {
+ ClassLoader myClassLoader = Loader.getClassLoaderOfObject(this);
+ URL url = findConfigFileURLFromSystemProperties(myClassLoader, updateStatus);
+ if (url != null) {
+ return url;
}
- private URL findConfigFileURLFromSystemProperties(ClassLoader classLoader, boolean updateStatus) {
- String logbackConfigFile = OptionHelper.getSystemProperty(CONFIG_FILE_PROPERTY);
- if (logbackConfigFile != null) {
- URL result = null;
- try {
- result = new URL(logbackConfigFile);
- return result;
- } catch (MalformedURLException e) {
- // so, resource is not a URL:
- // attempt to get the resource from the class path
- result = Loader.getResource(logbackConfigFile, classLoader);
- if (result != null) {
- return result;
- }
- File f = new File(logbackConfigFile);
- if (f.exists() && f.isFile()) {
- try {
- result = f.toURI().toURL();
- return result;
- } catch (MalformedURLException e1) {
- }
- }
- } finally {
- if (updateStatus) {
- statusOnResourceSearch(logbackConfigFile, classLoader, result);
- }
- }
- }
- return null;
+ url = getResource(GROOVY_AUTOCONFIG_FILE, myClassLoader, updateStatus);
+ if (url != null) {
+ return url;
}
- public URL findURLOfDefaultConfigurationFile(boolean updateStatus) {
- ClassLoader myClassLoader = Loader.getClassLoaderOfObject(this);
- URL url = findConfigFileURLFromSystemProperties(myClassLoader, updateStatus);
- if (url != null) {
- return url;
- }
-
- url = getResource(GROOVY_AUTOCONFIG_FILE, myClassLoader, updateStatus);
- if (url != null) {
- return url;
- }
+ url = getResource(TEST_AUTOCONFIG_FILE, myClassLoader, updateStatus);
+ if (url != null) {
+ return url;
+ }
- url = getResource(TEST_AUTOCONFIG_FILE, myClassLoader, updateStatus);
- if (url != null) {
- return url;
- }
+ return getResource(AUTOCONFIG_FILE, myClassLoader, updateStatus);
+ }
- return getResource(AUTOCONFIG_FILE, myClassLoader, updateStatus);
+ private URL getResource(String filename, ClassLoader myClassLoader, boolean updateStatus) {
+ URL url = Loader.getResource(filename, myClassLoader);
+ if (updateStatus) {
+ statusOnResourceSearch(filename, myClassLoader, url);
}
-
- private URL getResource(String filename, ClassLoader myClassLoader, boolean updateStatus) {
- URL url = Loader.getResource(filename, myClassLoader);
- if (updateStatus) {
- statusOnResourceSearch(filename, myClassLoader, url);
- }
- return url;
+ return url;
+ }
+
+ public void autoConfig() throws JoranException {
+ StatusListenerConfigHelper.installIfAsked(loggerContext);
+ URL url = findURLOfDefaultConfigurationFile(true);
+ if (url != null) {
+ configureByResource(url);
+ } else {
+ BasicConfigurator.configure(loggerContext);
}
-
- public void autoConfig() throws JoranException {
- StatusListenerConfigHelper.installIfAsked(loggerContext);
- URL url = findURLOfDefaultConfigurationFile(true);
- if (url != null) {
- configureByResource(url);
- } else {
- Configurator c = EnvUtil.loadFromServiceLoader(Configurator.class);
- if (c != null) {
- try {
- c.setContext(loggerContext);
- c.configure(loggerContext);
- } catch (Exception e) {
- throw new LogbackException(String.format("Failed to initialize Configurator: %s using ServiceLoader", c != null ? c.getClass()
- .getCanonicalName() : "null"), e);
- }
- } else {
- BasicConfigurator basicConfigurator = new BasicConfigurator();
- basicConfigurator.setContext(loggerContext);
- basicConfigurator.configure(loggerContext);
- }
- }
+ }
+
+ private void multiplicityWarning(String resourceName, ClassLoader classLoader) {
+ Set<URL> urlSet = null;
+ StatusManager sm = loggerContext.getStatusManager();
+ try {
+ urlSet = Loader.getResourceOccurrenceCount(resourceName, classLoader);
+ } catch (IOException e) {
+ sm.add(new ErrorStatus("Failed to get url list for resource [" + resourceName + "]",
+ loggerContext, e));
}
-
- private void statusOnResourceSearch(String resourceName, ClassLoader classLoader, URL url) {
- StatusManager sm = loggerContext.getStatusManager();
- if (url == null) {
- sm.add(new InfoStatus("Could NOT find resource [" + resourceName + "]", loggerContext));
- } else {
- sm.add(new InfoStatus("Found resource [" + resourceName + "] at [" + url.toString() + "]", loggerContext));
- multiplicityWarning(resourceName, classLoader);
- }
+ if (urlSet != null && urlSet.size() > 1) {
+ sm.add(new WarnStatus("Resource [" + resourceName + "] occurs multiple times on the classpath.",
+ loggerContext));
+ for (URL url : urlSet) {
+ sm.add(new WarnStatus("Resource [" + resourceName + "] occurs at [" + url.toString() + "]",
+ loggerContext));
+ }
}
-
- private void multiplicityWarning(String resourceName, ClassLoader classLoader) {
- Set<URL> urlSet = null;
- StatusManager sm = loggerContext.getStatusManager();
- try {
- urlSet = Loader.getResources(resourceName, classLoader);
- } catch (IOException e) {
- sm.add(new ErrorStatus("Failed to get url list for resource [" + resourceName + "]", loggerContext, e));
- }
- if (urlSet != null && urlSet.size() > 1) {
- sm.add(new WarnStatus("Resource [" + resourceName + "] occurs multiple times on the classpath.", loggerContext));
- for (URL url : urlSet) {
- sm.add(new WarnStatus("Resource [" + resourceName + "] occurs at [" + url.toString() + "]", loggerContext));
- }
- }
+ }
+
+ private void statusOnResourceSearch(String resourceName, ClassLoader classLoader, URL url) {
+ StatusManager sm = loggerContext.getStatusManager();
+ if (url == null) {
+ sm.add(new InfoStatus("Could NOT find resource [" + resourceName + "]",
+ loggerContext));
+ } else {
+ sm.add(new InfoStatus("Found resource [" + resourceName + "] at [" + url.toString() + "]",
+ loggerContext));
+ multiplicityWarning(resourceName, classLoader);
}
+ }
+
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextSelectorStaticBinder.java b/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextSelectorStaticBinder.java
index 8b04b84..9d826fb 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextSelectorStaticBinder.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextSelectorStaticBinder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -32,69 +32,76 @@ import ch.qos.logback.core.util.OptionHelper;
*/
public class ContextSelectorStaticBinder {
- static ContextSelectorStaticBinder singleton = new ContextSelectorStaticBinder();
+ static ContextSelectorStaticBinder singleton = new ContextSelectorStaticBinder();
- ContextSelector contextSelector;
- Object key;
+ ContextSelector contextSelector;
+ Object key;
+
+ public static ContextSelectorStaticBinder getSingleton() {
+ return singleton;
+ }
- public static ContextSelectorStaticBinder getSingleton() {
- return singleton;
+ /**
+ * FOR INTERNAL USE. This method is intended for use by StaticLoggerBinder.
+ *
+ * @param defaultLoggerContext
+ * @throws ClassNotFoundException
+ * @throws NoSuchMethodException
+ * @throws InstantiationException
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
+ public void init(LoggerContext defaultLoggerContext, Object key) throws ClassNotFoundException,
+ NoSuchMethodException, InstantiationException, IllegalAccessException,
+ InvocationTargetException {
+ if(this.key == null) {
+ this.key = key;
+ } else if (this.key != key) {
+ throw new IllegalAccessException("Only certain classes can access this method.");
}
-
- /**
- * FOR INTERNAL USE. This method is intended for use by StaticLoggerBinder.
- *
- * @param defaultLoggerContext
- * @throws ClassNotFoundException
- * @throws NoSuchMethodException
- * @throws InstantiationException
- * @throws IllegalAccessException
- * @throws InvocationTargetException
- */
- public void init(LoggerContext defaultLoggerContext, Object key) throws ClassNotFoundException, NoSuchMethodException, InstantiationException,
- IllegalAccessException, InvocationTargetException {
- if (this.key == null) {
- this.key = key;
- } else if (this.key != key) {
- throw new IllegalAccessException("Only certain classes can access this method.");
- }
-
- String contextSelectorStr = OptionHelper.getSystemProperty(ClassicConstants.LOGBACK_CONTEXT_SELECTOR);
- if (contextSelectorStr == null) {
- contextSelector = new DefaultContextSelector(defaultLoggerContext);
- } else if (contextSelectorStr.equals("JNDI")) {
- // if jndi is specified, let's use the appropriate class
- contextSelector = new ContextJNDISelector(defaultLoggerContext);
- } else {
- contextSelector = dynamicalContextSelector(defaultLoggerContext, contextSelectorStr);
- }
- }
-
- /**
- * Instantiate the context selector class designated by the user. The selector
- * must have a constructor taking a LoggerContext instance as an argument.
- *
- * @param defaultLoggerContext
- * @param contextSelectorStr
- * @return an instance of the designated context selector class
- * @throws ClassNotFoundException
- * @throws SecurityException
- * @throws NoSuchMethodException
- * @throws IllegalArgumentException
- * @throws InstantiationException
- * @throws IllegalAccessException
- * @throws InvocationTargetException
- */
- static ContextSelector dynamicalContextSelector(LoggerContext defaultLoggerContext, String contextSelectorStr) throws ClassNotFoundException,
- SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException,
- InvocationTargetException {
- Class<?> contextSelectorClass = Loader.loadClass(contextSelectorStr);
- Constructor cons = contextSelectorClass.getConstructor(new Class[] { LoggerContext.class });
- return (ContextSelector) cons.newInstance(defaultLoggerContext);
- }
-
- public ContextSelector getContextSelector() {
- return contextSelector;
+
+
+ String contextSelectorStr = OptionHelper
+ .getSystemProperty(ClassicConstants.LOGBACK_CONTEXT_SELECTOR);
+ if (contextSelectorStr == null) {
+ contextSelector = new DefaultContextSelector(defaultLoggerContext);
+ } else if (contextSelectorStr.equals("JNDI")) {
+ // if jndi is specified, let's use the appropriate class
+ contextSelector = new ContextJNDISelector(defaultLoggerContext);
+ } else {
+ contextSelector = dynamicalContextSelector(defaultLoggerContext,
+ contextSelectorStr);
}
+ }
+
+ /**
+ * Instantiate the context selector class designated by the user. The selector
+ * must have a constructor taking a LoggerContext instance as an argument.
+ *
+ * @param defaultLoggerContext
+ * @param contextSelectorStr
+ * @return an instance of the designated context selector class
+ * @throws ClassNotFoundException
+ * @throws SecurityException
+ * @throws NoSuchMethodException
+ * @throws IllegalArgumentException
+ * @throws InstantiationException
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
+ static ContextSelector dynamicalContextSelector(
+ LoggerContext defaultLoggerContext, String contextSelectorStr)
+ throws ClassNotFoundException, SecurityException, NoSuchMethodException,
+ IllegalArgumentException, InstantiationException, IllegalAccessException,
+ InvocationTargetException {
+ Class<?> contextSelectorClass = Loader.loadClass(contextSelectorStr);
+ Constructor cons = contextSelectorClass
+ .getConstructor(new Class[] { LoggerContext.class });
+ return (ContextSelector) cons.newInstance(defaultLoggerContext);
+ }
+
+ public ContextSelector getContextSelector() {
+ return contextSelector;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/util/CopyOnInheritThreadLocal.java b/logback-classic/src/main/java/ch/qos/logback/classic/util/CopyOnInheritThreadLocal.java
index 042ebc6..c6e836f 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/util/CopyOnInheritThreadLocal.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/util/CopyOnInheritThreadLocal.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,18 +21,20 @@ import java.util.HashMap;
*
* @author Ceki Gülcü
*/
-public class CopyOnInheritThreadLocal extends InheritableThreadLocal<HashMap<String, String>> {
+public class CopyOnInheritThreadLocal extends
+ InheritableThreadLocal<HashMap<String, String>> {
- /**
- * Child threads should get a copy of the parent's hashmap.
- */
- @Override
- protected HashMap<String, String> childValue(HashMap<String, String> parentValue) {
- if (parentValue == null) {
- return null;
- } else {
- return new HashMap<String, String>(parentValue);
- }
+ /**
+ * Child threads should get a copy of the parent's hashmap.
+ */
+ @Override
+ protected HashMap<String, String> childValue(
+ HashMap<String, String> parentValue) {
+ if (parentValue == null) {
+ return null;
+ } else {
+ return new HashMap<String, String>(parentValue);
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/util/DefaultNestedComponentRules.java b/logback-classic/src/main/java/ch/qos/logback/classic/util/DefaultNestedComponentRules.java
index aa8f596..a379518 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/util/DefaultNestedComponentRules.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/util/DefaultNestedComponentRules.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,16 +31,18 @@ import ch.qos.logback.core.net.ssl.SSLNestedComponentRegistryRules;
*/
public class DefaultNestedComponentRules {
- static public void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
- registry.add(AppenderBase.class, "layout", PatternLayout.class);
- registry.add(UnsynchronizedAppenderBase.class, "layout", PatternLayout.class);
+ static public void addDefaultNestedComponentRegistryRules(
+ DefaultNestedComponentRegistry registry) {
+ registry.add(AppenderBase.class, "layout", PatternLayout.class);
+ registry.add(UnsynchronizedAppenderBase.class, "layout", PatternLayout.class);
+
+ registry.add(AppenderBase.class, "encoder", PatternLayoutEncoder.class);
+ registry.add(UnsynchronizedAppenderBase.class, "encoder", PatternLayoutEncoder.class);
+
+ registry
+ .add(EvaluatorFilter.class, "evaluator", JaninoEventEvaluator.class);
- registry.add(AppenderBase.class, "encoder", PatternLayoutEncoder.class);
- registry.add(UnsynchronizedAppenderBase.class, "encoder", PatternLayoutEncoder.class);
-
- registry.add(EvaluatorFilter.class, "evaluator", JaninoEventEvaluator.class);
-
- SSLNestedComponentRegistryRules.addDefaultNestedComponentRegistryRules(registry);
- }
+ SSLNestedComponentRegistryRules.addDefaultNestedComponentRegistryRules(registry);
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/util/EnvUtil.java b/logback-classic/src/main/java/ch/qos/logback/classic/util/EnvUtil.java
index 5dd0b48..ce8ff16 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/util/EnvUtil.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/util/EnvUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,43 +13,22 @@
*/
package ch.qos.logback.classic.util;
-import java.util.Iterator;
-import java.util.ServiceLoader;
-
import ch.qos.logback.core.util.Loader;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class EnvUtil {
- /*
- * Used to replace the ClassLoader that the ServiceLoader uses for unit testing. We need this to mock the resources
- * the ServiceLoader attempts to load from /META-INF/services thus keeping the projects src/test/resources clean
- * (see src/test/resources/README.txt).
- */
- static ClassLoader testServiceLoaderClassLoader = null;
-
- static public boolean isGroovyAvailable() {
- ClassLoader classLoader = Loader.getClassLoaderOfClass(EnvUtil.class);
- try {
- Class<?> bindingClass = classLoader.loadClass("groovy.lang.Binding");
- return (bindingClass != null);
- } catch (ClassNotFoundException e) {
- return false;
- }
- }
-
- private static ClassLoader getServiceLoaderClassLoader() {
- return testServiceLoaderClassLoader == null ? Loader.getClassLoaderOfClass(EnvUtil.class) : testServiceLoaderClassLoader;
- }
- public static <T> T loadFromServiceLoader(Class<T> c) {
- ServiceLoader<T> loader = ServiceLoader.load(c, getServiceLoaderClassLoader());
- Iterator<T> it = loader.iterator();
- if (it.hasNext())
- return it.next();
- return null;
+ static public boolean isGroovyAvailable() {
+ ClassLoader classLoader = Loader.getClassLoaderOfClass(EnvUtil.class);
+ try {
+ Class bindingClass = classLoader.loadClass("groovy.lang.Binding");
+ return (bindingClass != null);
+ } catch (ClassNotFoundException e) {
+ return false;
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/util/JNDIUtil.java b/logback-classic/src/main/java/ch/qos/logback/classic/util/JNDIUtil.java
index 0da4771..9448881 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/util/JNDIUtil.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/util/JNDIUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,20 +25,20 @@ import javax.naming.NamingException;
*/
public class JNDIUtil {
+
+ public static Context getInitialContext() throws NamingException {
+ return new InitialContext();
+ }
- public static Context getInitialContext() throws NamingException {
- return new InitialContext();
+ public static String lookup(Context ctx, String name) {
+ if (ctx == null) {
+ return null;
}
-
- public static String lookup(Context ctx, String name) {
- if (ctx == null) {
- return null;
- }
- try {
- Object lookup = ctx.lookup(name);
- return lookup == null ? null : lookup.toString();
- } catch (NamingException e) {
- return null;
- }
+ try {
+ Object lookup = ctx.lookup(name);
+ return lookup == null ? null : lookup.toString();
+ } catch (NamingException e) {
+ return null;
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/util/LevelToSyslogSeverity.java b/logback-classic/src/main/java/ch/qos/logback/classic/util/LevelToSyslogSeverity.java
index 594e82a..f16dfc3 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/util/LevelToSyslogSeverity.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/util/LevelToSyslogSeverity.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,26 +19,28 @@ import ch.qos.logback.core.net.SyslogConstants;
public class LevelToSyslogSeverity {
- /*
- * Convert a level to equivalent syslog severity. Only levels for printing methods i.e TRACE, DEBUG, WARN, INFO and
- * ERROR are converted.
- */
- static public int convert(ILoggingEvent event) {
+ /*
+ * Convert a level to equivalent syslog severity. Only levels for printing
+ * methods i.e TRACE, DEBUG, WARN, INFO and ERROR are converted.
+ *
+ */
+ static public int convert(ILoggingEvent event) {
- Level level = event.getLevel();
+ Level level = event.getLevel();
- switch (level.levelInt) {
- case Level.ERROR_INT:
- return SyslogConstants.ERROR_SEVERITY;
- case Level.WARN_INT:
- return SyslogConstants.WARNING_SEVERITY;
- case Level.INFO_INT:
- return SyslogConstants.INFO_SEVERITY;
- case Level.DEBUG_INT:
- case Level.TRACE_INT:
- return SyslogConstants.DEBUG_SEVERITY;
- default:
- throw new IllegalArgumentException("Level " + level + " is not a valid level for a printing method");
- }
+ switch (level.levelInt) {
+ case Level.ERROR_INT:
+ return SyslogConstants.ERROR_SEVERITY;
+ case Level.WARN_INT:
+ return SyslogConstants.WARNING_SEVERITY;
+ case Level.INFO_INT:
+ return SyslogConstants.INFO_SEVERITY;
+ case Level.DEBUG_INT:
+ case Level.TRACE_INT:
+ return SyslogConstants.DEBUG_SEVERITY;
+ default:
+ throw new IllegalArgumentException("Level " + level
+ + " is not a valid level for a printing method");
}
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/util/LogbackMDCAdapter.java b/logback-classic/src/main/java/ch/qos/logback/classic/util/LogbackMDCAdapter.java
index 1f78f61..f68990a 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/util/LogbackMDCAdapter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/util/LogbackMDCAdapter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,11 +13,12 @@
*/
package ch.qos.logback.classic.util;
-import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.Collections;
import java.util.Set;
+
import org.slf4j.spi.MDCAdapter;
/**
@@ -36,167 +37,167 @@ import org.slf4j.spi.MDCAdapter;
*
* @author Ceki Gülcü
*/
-public class LogbackMDCAdapter implements MDCAdapter {
-
- // The internal map is copied so as
-
- // We wish to avoid unnecessarily copying of the map. To ensure
- // efficient/timely copying, we have a variable keeping track of the last
- // operation. A copy is necessary on 'put' or 'remove' but only if the last
- // operation was a 'get'. Get operations never necessitate a copy nor
- // successive 'put/remove' operations, only a get followed by a 'put/remove'
- // requires copying the map.
- // See http://jira.qos.ch/browse/LOGBACK-620 for the original discussion.
-
- // We no longer use CopyOnInheritThreadLocal in order to solve LBCLASSIC-183
- // Initially the contents of the thread local in parent and child threads
- // reference the same map. However, as soon as a thread invokes the put()
- // method, the maps diverge as they should.
- final ThreadLocal<Map<String, String>> copyOnThreadLocal = new ThreadLocal<Map<String, String>>();
-
- private static final int WRITE_OPERATION = 1;
- private static final int MAP_COPY_OPERATION = 2;
-
- // keeps track of the last operation performed
- final ThreadLocal<Integer> lastOperation = new ThreadLocal<Integer>();
-
- private Integer getAndSetLastOperation(int op) {
- Integer lastOp = lastOperation.get();
- lastOperation.set(op);
- return lastOp;
- }
-
- private boolean wasLastOpReadOrNull(Integer lastOp) {
- return lastOp == null || lastOp.intValue() == MAP_COPY_OPERATION;
- }
-
- private Map<String, String> duplicateAndInsertNewMap(Map<String, String> oldMap) {
- Map<String, String> newMap = Collections.synchronizedMap(new HashMap<String, String>());
- if (oldMap != null) {
- // we don't want the parent thread modifying oldMap while we are
- // iterating over it
- synchronized (oldMap) {
- newMap.putAll(oldMap);
- }
+public final class LogbackMDCAdapter implements MDCAdapter {
+
+ // We wish to avoid unnecessarily copying of the map. To ensure
+ // efficient/timely copying, we have a variable keeping track of the last
+ // operation. A copy is necessary on 'put' or 'remove' but only if the last
+ // operation was a 'get'. Get operations never necessitate a copy nor
+ // successive 'put/remove' operations, only a get followed by a 'put/remove'
+ // requires copying the map.
+ // See http://jira.qos.ch/browse/LBCLASSIC-254 for the original discussion.
+
+ // We no longer use CopyOnInheritThreadLocal in order to solve LBCLASSIC-183
+ // Initially the contents of the thread local in parent and child threads
+ // reference the same map. However, as soon as a thread invokes the put()
+ // method, the maps diverge as they should.
+ final InheritableThreadLocal<Map<String, String>> copyOnInheritThreadLocal = new InheritableThreadLocal<Map<String, String>>();
+
+ private static final int WRITE_OPERATION = 1;
+ private static final int READ_OPERATION = 2;
+
+ // keeps track of the last operation performed
+ final ThreadLocal<Integer> lastOperation = new ThreadLocal<Integer>();
+
+ private Integer getAndSetLastOperation(int op) {
+ Integer lastOp = lastOperation.get();
+ lastOperation.set(op);
+ return lastOp;
+ }
+
+ private boolean wasLastOpReadOrNull(Integer lastOp) {
+ return lastOp == null || lastOp.intValue() == READ_OPERATION;
+ }
+
+ private Map<String, String> duplicateAndInsertNewMap(Map<String, String> oldMap) {
+ Map<String, String> newMap = Collections.synchronizedMap(new HashMap<String, String>());
+ if (oldMap != null) {
+ // we don't want the parent thread modifying oldMap while we are
+ // iterating over it
+ synchronized (oldMap) {
+ newMap.putAll(oldMap);
}
-
- copyOnThreadLocal.set(newMap);
- return newMap;
}
- /**
- * Put a context value (the <code>val</code> parameter) as identified with the
- * <code>key</code> parameter into the current thread's context map. Note that
- * contrary to log4j, the <code>val</code> parameter can be null.
- * <p/>
- * <p/>
- * If the current thread does not have a context map it is created as a side
- * effect of this call.
- *
- * @throws IllegalArgumentException in case the "key" parameter is null
- */
- public void put(String key, String val) throws IllegalArgumentException {
- if (key == null) {
- throw new IllegalArgumentException("key cannot be null");
- }
-
- Map<String, String> oldMap = copyOnThreadLocal.get();
- Integer lastOp = getAndSetLastOperation(WRITE_OPERATION);
-
- if (wasLastOpReadOrNull(lastOp) || oldMap == null) {
- Map<String, String> newMap = duplicateAndInsertNewMap(oldMap);
- newMap.put(key, val);
- } else {
- oldMap.put(key, val);
- }
+ copyOnInheritThreadLocal.set(newMap);
+ return newMap;
+ }
+
+ /**
+ * Put a context value (the <code>val</code> parameter) as identified with the
+ * <code>key</code> parameter into the current thread's context map. Note that
+ * contrary to log4j, the <code>val</code> parameter can be null.
+ * <p/>
+ * <p/>
+ * If the current thread does not have a context map it is created as a side
+ * effect of this call.
+ *
+ * @throws IllegalArgumentException in case the "key" parameter is null
+ */
+ public void put(String key, String val) throws IllegalArgumentException {
+ if (key == null) {
+ throw new IllegalArgumentException("key cannot be null");
}
- /**
- * Remove the the context identified by the <code>key</code> parameter.
- * <p/>
- */
- public void remove(String key) {
- if (key == null) {
- return;
- }
- Map<String, String> oldMap = copyOnThreadLocal.get();
- if (oldMap == null)
- return;
-
- Integer lastOp = getAndSetLastOperation(WRITE_OPERATION);
+ Map<String, String> oldMap = copyOnInheritThreadLocal.get();
+ Integer lastOp = getAndSetLastOperation(WRITE_OPERATION);
- if (wasLastOpReadOrNull(lastOp)) {
- Map<String, String> newMap = duplicateAndInsertNewMap(oldMap);
- newMap.remove(key);
- } else {
- oldMap.remove(key);
- }
+ if (wasLastOpReadOrNull(lastOp) || oldMap == null) {
+ Map<String, String> newMap = duplicateAndInsertNewMap(oldMap);
+ newMap.put(key, val);
+ } else {
+ oldMap.put(key, val);
}
-
- /**
- * Clear all entries in the MDC.
- */
- public void clear() {
- lastOperation.set(WRITE_OPERATION);
- copyOnThreadLocal.remove();
+ }
+
+ /**
+ * Remove the the context identified by the <code>key</code> parameter.
+ * <p/>
+ */
+ public void remove(String key) {
+ if (key == null) {
+ return;
}
+ Map<String, String> oldMap = copyOnInheritThreadLocal.get();
+ if (oldMap == null) return;
- /**
- * Get the context identified by the <code>key</code> parameter.
- * <p/>
- */
- public String get(String key) {
- final Map<String, String> map = copyOnThreadLocal.get();
- if ((map != null) && (key != null)) {
- return map.get(key);
- } else {
- return null;
- }
- }
+ Integer lastOp = getAndSetLastOperation(WRITE_OPERATION);
- /**
- * Get the current thread's MDC as a map. This method is intended to be used
- * internally.
- */
- public Map<String, String> getPropertyMap() {
- lastOperation.set(MAP_COPY_OPERATION);
- return copyOnThreadLocal.get();
+ if (wasLastOpReadOrNull(lastOp)) {
+ Map<String, String> newMap = duplicateAndInsertNewMap(oldMap);
+ newMap.remove(key);
+ } else {
+ oldMap.remove(key);
}
-
- /**
- * Returns the keys in the MDC as a {@link Set}. The returned value can be
- * null.
- */
- public Set<String> getKeys() {
- Map<String, String> map = getPropertyMap();
-
- if (map != null) {
- return map.keySet();
- } else {
- return null;
- }
+ }
+
+
+ /**
+ * Clear all entries in the MDC.
+ */
+ public void clear() {
+ lastOperation.set(WRITE_OPERATION);
+ copyOnInheritThreadLocal.remove();
+ }
+
+ /**
+ * Get the context identified by the <code>key</code> parameter.
+ * <p/>
+ */
+ public String get(String key) {
+ Map<String, String> map = getPropertyMap();
+ if ((map != null) && (key != null)) {
+ return map.get(key);
+ } else {
+ return null;
}
-
- /**
- * Return a copy of the current thread's context map. Returned value may be
- * null.
- */
- public Map<String, String> getCopyOfContextMap() {
- Map<String, String> hashMap = copyOnThreadLocal.get();
- if (hashMap == null) {
- return null;
- } else {
- return new HashMap<String, String>(hashMap);
- }
+ }
+
+ /**
+ * Get the current thread's MDC as a map. This method is intended to be used
+ * internally.
+ */
+ public Map<String, String> getPropertyMap() {
+ lastOperation.set(READ_OPERATION);
+ return copyOnInheritThreadLocal.get();
+ }
+
+ /**
+ * Returns the keys in the MDC as a {@link Set}. The returned value can be
+ * null.
+ */
+ public Set<String> getKeys() {
+ Map<String, String> map = getPropertyMap();
+
+ if (map != null) {
+ return map.keySet();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Return a copy of the current thread's context map. Returned value may be
+ * null.
+ */
+ public Map getCopyOfContextMap() {
+ lastOperation.set(READ_OPERATION);
+ Map<String, String> hashMap = copyOnInheritThreadLocal.get();
+ if (hashMap == null) {
+ return null;
+ } else {
+ return new HashMap<String, String>(hashMap);
}
+ }
- public void setContextMap(Map<String, String> contextMap) {
- lastOperation.set(WRITE_OPERATION);
+ @SuppressWarnings("unchecked")
+ public void setContextMap(Map contextMap) {
+ lastOperation.set(WRITE_OPERATION);
- Map<String, String> newMap = Collections.synchronizedMap(new HashMap<String, String>());
- newMap.putAll(contextMap);
+ Map<String, String> newMap = Collections.synchronizedMap(new HashMap<String, String>());
+ newMap.putAll(contextMap);
- // the newMap replaces the old one for serialisation's sake
- copyOnThreadLocal.set(newMap);
- }
+ // the newMap replaces the old one for serialisation's sake
+ copyOnInheritThreadLocal.set(newMap);
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/util/LoggerNameUtil.java b/logback-classic/src/main/java/ch/qos/logback/classic/util/LoggerNameUtil.java
index b5a8ca2..9f53bea 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/util/LoggerNameUtil.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/util/LoggerNameUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,45 +23,43 @@ import java.util.List;
*/
public class LoggerNameUtil {
- public static int getFirstSeparatorIndexOf(String name) {
- return getSeparatorIndexOf(name, 0);
- }
- /**
- * Get the position of the separator character, if any, starting at position
- * 'fromIndex'.
- *
- * @param name
- * @param fromIndex
- * @return
- */
- public static int getSeparatorIndexOf(String name, int fromIndex) {
- int dotIndex = name.indexOf(CoreConstants.DOT, fromIndex);
- int dollarIndex = name.indexOf(CoreConstants.DOLLAR, fromIndex);
+ public static int getFirstSeparatorIndexOf(String name) {
+ return getSeparatorIndexOf(name, 0);
+ }
- if (dotIndex == -1 && dollarIndex == -1)
- return -1;
- if (dotIndex == -1)
- return dollarIndex;
- if (dollarIndex == -1)
- return dotIndex;
+ /**
+ * Get the position of the separator character, if any, starting at position
+ * 'fromIndex'.
+ *
+ * @param name
+ * @param fromIndex
+ * @return
+ */
+ public static int getSeparatorIndexOf(String name, int fromIndex) {
+ int dotIndex = name.indexOf(CoreConstants.DOT, fromIndex);
+ int dollarIndex = name.indexOf(CoreConstants.DOLLAR, fromIndex);
- return dotIndex < dollarIndex ? dotIndex : dollarIndex;
- }
+ if (dotIndex == -1 && dollarIndex == -1) return -1;
+ if (dotIndex == -1) return dollarIndex;
+ if (dollarIndex == -1) return dotIndex;
+
+ return dotIndex < dollarIndex ? dotIndex : dollarIndex;
+ }
- public static List<String> computeNameParts(String loggerName) {
- List<String> partList = new ArrayList<String>();
+ public static List<String> computeNameParts(String loggerName) {
+ List<String> partList = new ArrayList<String>();
- int fromIndex = 0;
- while (true) {
- int index = getSeparatorIndexOf(loggerName, fromIndex);
- if (index == -1) {
- partList.add(loggerName.substring(fromIndex));
- break;
- }
- partList.add(loggerName.substring(fromIndex, index));
- fromIndex = index + 1;
- }
- return partList;
+ int fromIndex = 0;
+ while(true) {
+ int index = getSeparatorIndexOf(loggerName, fromIndex);
+ if(index == -1) {
+ partList.add(loggerName.substring(fromIndex));
+ break;
+ }
+ partList.add(loggerName.substring(fromIndex, index));
+ fromIndex = index+1;
}
+ return partList;
+ }
}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/util/StatusListenerConfigHelper.java b/logback-classic/src/main/java/ch/qos/logback/classic/util/StatusListenerConfigHelper.java
new file mode 100644
index 0000000..c0ddb5c
--- /dev/null
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/util/StatusListenerConfigHelper.java
@@ -0,0 +1,64 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.util;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.core.spi.ContextAware;
+import ch.qos.logback.core.spi.LifeCycle;
+import ch.qos.logback.core.status.OnConsoleStatusListener;
+import ch.qos.logback.core.status.StatusListener;
+import ch.qos.logback.core.util.OptionHelper;
+
+public class StatusListenerConfigHelper {
+
+ static void installIfAsked(LoggerContext loggerContext) {
+ String slClass = OptionHelper.getSystemProperty(
+ ContextInitializer.STATUS_LISTENER_CLASS);
+ if (!OptionHelper.isEmpty(slClass)) {
+ addStatusListener(loggerContext, slClass);
+ }
+ }
+
+ private static void addStatusListener(LoggerContext loggerContext,
+ String listenerClass) {
+ StatusListener listener = null;
+ if (ContextInitializer.SYSOUT.equalsIgnoreCase(listenerClass)) {
+ listener = new OnConsoleStatusListener();
+ } else {
+ listener = createListenerPerClassName(loggerContext, listenerClass);
+ }
+ initListener(loggerContext, listener);
+ }
+
+ private static void initListener(LoggerContext loggerContext, StatusListener listener) {
+ if (listener != null) {
+ if(listener instanceof ContextAware) // LOGBACK-767
+ ((ContextAware) listener).setContext(loggerContext);
+ if(listener instanceof LifeCycle) // LOGBACK-767
+ ((LifeCycle) listener).start();
+ loggerContext.getStatusManager().add(listener);
+ }
+ }
+
+ private static StatusListener createListenerPerClassName(LoggerContext loggerContext, String listenerClass) {
+ try {
+ return (StatusListener) OptionHelper.instantiateByClassName(
+ listenerClass, StatusListener.class, loggerContext);
+ } catch (Exception e) {
+ // printing on the console is the best we can do
+ e.printStackTrace();
+ return null;
+ }
+ }
+}
diff --git a/logback-classic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/logback-classic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
index 23b6f88..e7b1f9f 100644
--- a/logback-classic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
+++ b/logback-classic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -35,80 +35,84 @@ import ch.qos.logback.core.util.StatusPrinter;
*/
public class StaticLoggerBinder implements LoggerFactoryBinder {
- /**
- * Declare the version of the SLF4J API this implementation is compiled
- * against. The value of this field is usually modified with each release.
- */
- // to avoid constant folding by the compiler, this field must *not* be final
- public static String REQUESTED_API_VERSION = "1.7.16"; // !final
-
- final static String NULL_CS_URL = CoreConstants.CODES_URL + "#null_CS";
-
- /**
- * The unique instance of this class.
- */
- private static StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
-
- private static Object KEY = new Object();
-
- static {
- SINGLETON.init();
- }
-
- private boolean initialized = false;
- private LoggerContext defaultLoggerContext = new LoggerContext();
- private final ContextSelectorStaticBinder contextSelectorBinder = ContextSelectorStaticBinder.getSingleton();
-
- private StaticLoggerBinder() {
- defaultLoggerContext.setName(CoreConstants.DEFAULT_CONTEXT_NAME);
+ /**
+ * Declare the version of the SLF4J API this implementation is compiled
+ * against. The value of this field is usually modified with each release.
+ */
+ // to avoid constant folding by the compiler, this field must *not* be final
+ public static String REQUESTED_API_VERSION = "1.6"; // !final
+
+ final static String NULL_CS_URL = CoreConstants.CODES_URL + "#null_CS";
+
+ /**
+ * The unique instance of this class.
+ */
+ private static StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
+
+ private static Object KEY = new Object();
+
+ static {
+ SINGLETON.init();
+ }
+
+ private boolean initialized = false;
+ private LoggerContext defaultLoggerContext = new LoggerContext();
+ private final ContextSelectorStaticBinder contextSelectorBinder = ContextSelectorStaticBinder
+ .getSingleton();
+
+ private StaticLoggerBinder() {
+ defaultLoggerContext.setName(CoreConstants.DEFAULT_CONTEXT_NAME);
+ }
+
+ public static StaticLoggerBinder getSingleton() {
+ return SINGLETON;
+ }
+
+ /**
+ * Package access for testing purposes.
+ */
+ static void reset() {
+ SINGLETON = new StaticLoggerBinder();
+ SINGLETON.init();
+ }
+
+ /**
+ * Package access for testing purposes.
+ */
+ void init() {
+ try {
+ try {
+ new ContextInitializer(defaultLoggerContext).autoConfig();
+ } catch (JoranException je) {
+ Util.report("Failed to auto configure default logger context", je);
+ }
+ // logback-292
+ if(!StatusUtil.contextHasStatusListener(defaultLoggerContext)) {
+ StatusPrinter.printInCaseOfErrorsOrWarnings(defaultLoggerContext);
+ }
+ contextSelectorBinder.init(defaultLoggerContext, KEY);
+ initialized = true;
+ } catch (Throwable t) {
+ // we should never get here
+ Util.report("Failed to instantiate [" + LoggerContext.class.getName()
+ + "]", t);
}
+ }
- public static StaticLoggerBinder getSingleton() {
- return SINGLETON;
+ public ILoggerFactory getLoggerFactory() {
+ if (!initialized) {
+ return defaultLoggerContext;
}
- /**
- * Package access for testing purposes.
- */
- static void reset() {
- SINGLETON = new StaticLoggerBinder();
- SINGLETON.init();
+ if (contextSelectorBinder.getContextSelector() == null) {
+ throw new IllegalStateException(
+ "contextSelector cannot be null. See also " + NULL_CS_URL);
}
+ return contextSelectorBinder.getContextSelector().getLoggerContext();
+ }
- /**
- * Package access for testing purposes.
- */
- void init() {
- try {
- try {
- new ContextInitializer(defaultLoggerContext).autoConfig();
- } catch (JoranException je) {
- Util.report("Failed to auto configure default logger context", je);
- }
- // logback-292
- if (!StatusUtil.contextHasStatusListener(defaultLoggerContext)) {
- StatusPrinter.printInCaseOfErrorsOrWarnings(defaultLoggerContext);
- }
- contextSelectorBinder.init(defaultLoggerContext, KEY);
- initialized = true;
- } catch (Exception t) { // see LOGBACK-1159
- Util.report("Failed to instantiate [" + LoggerContext.class.getName() + "]", t);
- }
- }
-
- public ILoggerFactory getLoggerFactory() {
- if (!initialized) {
- return defaultLoggerContext;
- }
-
- if (contextSelectorBinder.getContextSelector() == null) {
- throw new IllegalStateException("contextSelector cannot be null. See also " + NULL_CS_URL);
- }
- return contextSelectorBinder.getContextSelector().getLoggerContext();
- }
-
- public String getLoggerFactoryClassStr() {
- return contextSelectorBinder.getClass().getName();
- }
+ public String getLoggerFactoryClassStr() {
+ return contextSelectorBinder.getClass().getName();
+ }
}
diff --git a/logback-classic/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/logback-classic/src/main/java/org/slf4j/impl/StaticMDCBinder.java
index 0a29240..0d5c72d 100644
--- a/logback-classic/src/main/java/org/slf4j/impl/StaticMDCBinder.java
+++ b/logback-classic/src/main/java/org/slf4j/impl/StaticMDCBinder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,6 +17,7 @@ import org.slf4j.spi.MDCAdapter;
import ch.qos.logback.classic.util.LogbackMDCAdapter;
+
/**
* This implementation is bound to {@link LogbackMDCAdapter}.
*
@@ -24,23 +25,24 @@ import ch.qos.logback.classic.util.LogbackMDCAdapter;
*/
public class StaticMDCBinder {
- /**
- * The unique instance of this class.
- */
- public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
-
- private StaticMDCBinder() {
- }
-
- /**
- * Currently this method always returns an instance of
- * {@link StaticMDCBinder}.
- */
- public MDCAdapter getMDCA() {
- return new LogbackMDCAdapter();
- }
+
+ /**
+ * The unique instance of this class.
+ */
+ public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
- public String getMDCAdapterClassStr() {
- return LogbackMDCAdapter.class.getName();
- }
+ private StaticMDCBinder() {
+ }
+
+ /**
+ * Currently this method always returns an instance of
+ * {@link StaticMDCBinder}.
+ */
+ public MDCAdapter getMDCA() {
+ return new LogbackMDCAdapter();
+ }
+
+ public String getMDCAdapterClassStr() {
+ return LogbackMDCAdapter.class.getName();
+ }
}
diff --git a/logback-classic/src/main/java/org/slf4j/impl/StaticMarkerBinder.java b/logback-classic/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
index 2d585aa..e2954ec 100644
--- a/logback-classic/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
+++ b/logback-classic/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,30 +27,31 @@ import org.slf4j.spi.MarkerFactoryBinder;
*/
public class StaticMarkerBinder implements MarkerFactoryBinder {
- /**
- * The unique instance of this class.
- */
- public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder();
-
- final IMarkerFactory markerFactory = new BasicMarkerFactory();
-
- private StaticMarkerBinder() {
- }
-
- /**
- * Currently this method always returns an instance of
- * {@link BasicMarkerFactory}.
- */
- public IMarkerFactory getMarkerFactory() {
- return markerFactory;
- }
-
- /**
- * Currently, this method returns the class name of
- * {@link BasicMarkerFactory}.
- */
- public String getMarkerFactoryClassStr() {
- return BasicMarkerFactory.class.getName();
- }
-
+ /**
+ * The unique instance of this class.
+ */
+ public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder();
+
+ final IMarkerFactory markerFactory = new BasicMarkerFactory();
+
+ private StaticMarkerBinder() {
+ }
+
+ /**
+ * Currently this method always returns an instance of
+ * {@link BasicMarkerFactory}.
+ */
+ public IMarkerFactory getMarkerFactory() {
+ return markerFactory;
+ }
+
+ /**
+ * Currently, this method returns the class name of
+ * {@link BasicMarkerFactory}.
+ */
+ public String getMarkerFactoryClassStr() {
+ return BasicMarkerFactory.class.getName();
+ }
+
+
}
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy
index 59af568..828c489 100644
--- a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy
+++ b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -33,7 +33,6 @@ import ch.qos.logback.core.helpers.NOPAppender
import ch.qos.logback.core.ConsoleAppender
import ch.qos.logback.core.encoder.LayoutWrappingEncoder
import ch.qos.logback.classic.PatternLayout
-import ch.qos.logback.core.util.FileSize
import ch.qos.logback.core.util.StatusPrinter
import ch.qos.logback.classic.net.SMTPAppender
import ch.qos.logback.core.rolling.RollingFileAppender
@@ -70,7 +69,13 @@ class ConfigurationDelegateTest {
@Test
void scan() {
configurationDelegate.scan("10seconds")
- assertTrue(statusChecker.containsMatch("Setting ReconfigureOnChangeTask"))
+ assertTrue(statusChecker.containsMatch("Setting ReconfigureOnChangeFilter"))
+ assertTrue(statusChecker.containsMatch("Adding ReconfigureOnChangeFilter as a turbo filter"))
+
+ TurboFilter filter = context.turboFilterList[0]
+ assertTrue(filter instanceof ReconfigureOnChangeFilter)
+ ReconfigureOnChangeFilter rocf = (ReconfigureOnChangeFilter) filter;
+ assertEquals(10 * 1000, rocf.refreshPeriod)
}
@Test
@@ -236,29 +241,16 @@ class ConfigurationDelegateTest {
}
- // See LOGBACK-458
+ // See LBCLASSIC-231
@Test
void withSizeAndTimeBasedFNATP() {
- withSizeAndTimeBasedFNATP(false);
- }
-
- // See LOGBACK-1232
- @Test
- void withSizeAndTimeBasedFNATP_AsString() {
- withSizeAndTimeBasedFNATP(true);
- }
-
- void withSizeAndTimeBasedFNATP(boolean asString) {
String logFile = randomOutputDir + "log.txt";
configurationDelegate.appender("ROLLING", RollingFileAppender) {
file = logFile
rollingPolicy(TimeBasedRollingPolicy) {
fileNamePattern = "mylog-%d{yyyy-MM-dd}.%i.txt"
timeBasedFileNamingAndTriggeringPolicy(SizeAndTimeBasedFNATP) {
- if(asString)
- maxFileSize = "100MB"
- else
- maxFileSize = FileSize.valueOf("100MB")
+ maxFileSize = "100MB"
}
}
encoder(PatternLayoutEncoder) {
@@ -266,7 +258,6 @@ class ConfigurationDelegateTest {
}
}
RollingFileAppender back = configurationDelegate.appenderList.find {it.name = "ROLLING"}
- StatusPrinter.print(context)
assertNotNull(back)
assertEquals(logFile, back.rollingPolicy.getParentsRawFileProperty())
assertTrue(back.rollingPolicy.timeBasedFileNamingAndTriggeringPolicy.isStarted())
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/GafferConfiguratorTest.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/GafferConfiguratorTest.groovy
index c16c2f9..3e018c2 100644
--- a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/GafferConfiguratorTest.groovy
+++ b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/GafferConfiguratorTest.groovy
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -46,7 +46,6 @@ class GafferConfiguratorTest {
Logger logger = context.getLogger(this.getClass())
int diff = RandomUtil.getPositiveInt();
GafferConfigurator configurator = new GafferConfigurator(context);
- final shouldFail = new GroovyTestCase().&shouldFail
@Before
void setUp() {
@@ -181,12 +180,4 @@ class GafferConfiguratorTest {
assertNotNull stdout
}
- @Test
- void appenderRefWithNonAppenderAttachable() {
- String message = shouldFail(IllegalArgumentException) {
- File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + "appenderRefWithNonAppenderAttachable.groovy")
- configurator.run file.text
- }
- assertEquals message, "ch.qos.logback.core.ConsoleAppender does not implement ch.qos.logback.core.spi.AppenderAttachable."
- }
}
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/PropertyUtilTest.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/PropertyUtilTest.groovy
index 18efb8e..fbfe323 100644
--- a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/PropertyUtilTest.groovy
+++ b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/PropertyUtilTest.groovy
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
diff --git a/logback-classic/src/test/groovy/issues/logback811/LineNumTest.groovy b/logback-classic/src/test/groovy/issues/logback811/LineNumTest.groovy
index 222b966..acaf502 100644
--- a/logback-classic/src/test/groovy/issues/logback811/LineNumTest.groovy
+++ b/logback-classic/src/test/groovy/issues/logback811/LineNumTest.groovy
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
diff --git a/logback-classic/src/test/input/gaffer/appenderRefWithNonAppenderAttachable.groovy b/logback-classic/src/test/input/gaffer/appenderRefWithNonAppenderAttachable.groovy
deleted file mode 100644
index d296950..0000000
--- a/logback-classic/src/test/input/gaffer/appenderRefWithNonAppenderAttachable.groovy
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-import ch.qos.logback.classic.PatternLayout
-import ch.qos.logback.core.ConsoleAppender
-import ch.qos.logback.core.encoder.LayoutWrappingEncoder
-
-appender("STDOUT", ConsoleAppender) {
- encoder(LayoutWrappingEncoder) {
- layout(PatternLayout) {
- pattern = "${p} %m%n"
- }
- }
-}
-
-appender("STDOUT-WITH-APPENDERREF", ConsoleAppender) {
- appenderRef('STDOUT')
-}
-
-root(DEBUG, ["STDOUT-ASYNC"])
diff --git a/logback-classic/src/test/input/gaffer/asyncAppender.groovy b/logback-classic/src/test/input/gaffer/asyncAppender.groovy
index 7232e9a..2fd3337 100644
--- a/logback-classic/src/test/input/gaffer/asyncAppender.groovy
+++ b/logback-classic/src/test/input/gaffer/asyncAppender.groovy
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -11,6 +11,7 @@
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
+
import ch.qos.logback.classic.AsyncAppender
import ch.qos.logback.classic.PatternLayout
import ch.qos.logback.core.ConsoleAppender
diff --git a/logback-classic/src/test/input/gaffer/conversionRule.groovy b/logback-classic/src/test/input/gaffer/conversionRule.groovy
index 77f027a..ce015c9 100644
--- a/logback-classic/src/test/input/gaffer/conversionRule.groovy
+++ b/logback-classic/src/test/input/gaffer/conversionRule.groovy
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
import ch.qos.logback.classic.PatternLayout
import ch.qos.logback.classic.testUtil.SampleConverter
import ch.qos.logback.core.testUtil.StringListAppender
diff --git a/logback-classic/src/test/input/gaffer/evaluatorWithMatcher.groovy b/logback-classic/src/test/input/gaffer/evaluatorWithMatcher.groovy
index 695b546..e46571d 100644
--- a/logback-classic/src/test/input/gaffer/evaluatorWithMatcher.groovy
+++ b/logback-classic/src/test/input/gaffer/evaluatorWithMatcher.groovy
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
//
// Built on Wed May 19 20:51:44 CEST 2010 by logback-translator
// For more information on configuration files in Groovy
diff --git a/logback-classic/src/test/input/gaffer/onTheFly.groovy b/logback-classic/src/test/input/gaffer/onTheFly.groovy
index 6b7b340..7aae275 100644
--- a/logback-classic/src/test/input/gaffer/onTheFly.groovy
+++ b/logback-classic/src/test/input/gaffer/onTheFly.groovy
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
import ch.qos.logback.core.ConsoleAppender
import ch.qos.logback.core.encoder.LayoutWrappingEncoder
import ch.qos.logback.classic.PatternLayout
diff --git a/logback-classic/src/test/input/gaffer/propertyCascading0.groovy b/logback-classic/src/test/input/gaffer/propertyCascading0.groovy
index fa462cb..bd99143 100644
--- a/logback-classic/src/test/input/gaffer/propertyCascading0.groovy
+++ b/logback-classic/src/test/input/gaffer/propertyCascading0.groovy
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
//
// Built on Wed May 19 20:51:44 CEST 2010 by logback-translator
// For more information on configuration files in Groovy
diff --git a/logback-classic/src/test/input/gaffer/propertyCascading1.groovy b/logback-classic/src/test/input/gaffer/propertyCascading1.groovy
index 503b5ee..c22e304 100644
--- a/logback-classic/src/test/input/gaffer/propertyCascading1.groovy
+++ b/logback-classic/src/test/input/gaffer/propertyCascading1.groovy
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
//
// Built on Wed May 19 20:51:44 CEST 2010 by logback-translator
// For more information on configuration files in Groovy
diff --git a/logback-classic/src/test/input/gaffer/propertyCascading2.groovy b/logback-classic/src/test/input/gaffer/propertyCascading2.groovy
index 98aee06..5a34f47 100644
--- a/logback-classic/src/test/input/gaffer/propertyCascading2.groovy
+++ b/logback-classic/src/test/input/gaffer/propertyCascading2.groovy
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
//
// Built on Wed May 19 20:51:44 CEST 2010 by logback-translator
// For more information on configuration files in Groovy
diff --git a/logback-classic/src/test/input/gaffer/sift/noDiscriminator.groovy b/logback-classic/src/test/input/gaffer/sift/noDiscriminator.groovy
index 9deba51..ffcd9e5 100644
--- a/logback-classic/src/test/input/gaffer/sift/noDiscriminator.groovy
+++ b/logback-classic/src/test/input/gaffer/sift/noDiscriminator.groovy
@@ -1,17 +1,4 @@
/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-/**
* @author Ceki Gücü
*/
diff --git a/logback-classic/src/test/input/gaffer/sift/sample0.groovy b/logback-classic/src/test/input/gaffer/sift/sample0.groovy
index 481fbef..a6a8fa1 100644
--- a/logback-classic/src/test/input/gaffer/sift/sample0.groovy
+++ b/logback-classic/src/test/input/gaffer/sift/sample0.groovy
@@ -1,17 +1,4 @@
/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-/**
* @author Ceki Gücü
*/
diff --git a/logback-classic/src/test/input/gaffer/sift/sample1.groovy b/logback-classic/src/test/input/gaffer/sift/sample1.groovy
index 5d0588d..25ae3a9 100644
--- a/logback-classic/src/test/input/gaffer/sift/sample1.groovy
+++ b/logback-classic/src/test/input/gaffer/sift/sample1.groovy
@@ -1,17 +1,4 @@
/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-/**
* @author Ceki Gücü
*/
diff --git a/logback-classic/src/test/input/gaffer/smoke.groovy b/logback-classic/src/test/input/gaffer/smoke.groovy
index 6b1b516..01ae2cd 100644
--- a/logback-classic/src/test/input/gaffer/smoke.groovy
+++ b/logback-classic/src/test/input/gaffer/smoke.groovy
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
import ch.qos.logback.core.ConsoleAppender
import ch.qos.logback.core.encoder.LayoutWrappingEncoder
import ch.qos.logback.classic.PatternLayout
diff --git a/logback-classic/src/test/input/gaffer/x.groovy b/logback-classic/src/test/input/gaffer/x.groovy
index d30b040..03140a3 100644
--- a/logback-classic/src/test/input/gaffer/x.groovy
+++ b/logback-classic/src/test/input/gaffer/x.groovy
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
import ch.qos.logback.classic.PatternLayout
import ch.qos.logback.classic.filter.ThresholdFilter
import ch.qos.logback.classic.net.SMTPAppender
diff --git a/logback-classic/src/test/input/issue/logback-1159.xml b/logback-classic/src/test/input/issue/logback-1159.xml
deleted file mode 100644
index 40bf975..0000000
--- a/logback-classic/src/test/input/issue/logback-1159.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<configuration debug="true">
-
- <statusListener
- class="ch.qos.logback.classic.issue.logback1159.LogbackListener" />
-
- <property name="logback.rollingPattern" value="%d{yyyy-MM-dd}.gz" />
-
-
- <appender name="JOURNAL"
- class="ch.qos.logback.core.rolling.RollingFileAppender">
-
- <file>target/test.log</file>
-
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <!-- daily rollover -->
- <fileNamePattern>target/test.${logback.rollingPattern}.log
- </fileNamePattern>
- <maxHistory>30</maxHistory>
- </rollingPolicy>
- <encoder>
- <pattern>%m%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="JOURNAL" />
- </root>
-
-</configuration>
diff --git a/logback-classic/src/test/input/joran/packagingDataDisabled.xml b/logback-classic/src/test/input/joran/packagingDataDisabled.xml
deleted file mode 100644
index 817906c..0000000
--- a/logback-classic/src/test/input/joran/packagingDataDisabled.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE configuration>
-
-<configuration debug="true">
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <layout class="ch.qos.logback.classic.PatternLayout">
- <param name="Pattern" value="%d - %m%n"/>
- </layout>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-
-</configuration>
diff --git a/logback-classic/src/test/input/joran/packagingDataEnabled.xml b/logback-classic/src/test/input/joran/packagingDataEnabled.xml
deleted file mode 100644
index e516a14..0000000
--- a/logback-classic/src/test/input/joran/packagingDataEnabled.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE configuration>
-
-<configuration debug="true" packagingData="true">
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <layout class="ch.qos.logback.classic.PatternLayout">
- <param name="Pattern" value="%d - %m%n"/>
- </layout>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-
-</configuration>
diff --git a/logback-classic/src/test/input/joran/roct/inclusion/topByResource.xml b/logback-classic/src/test/input/joran/roct/inclusion/topByResource.xml
deleted file mode 100644
index 48098ec..0000000
--- a/logback-classic/src/test/input/joran/roct/inclusion/topByResource.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE x>
-
-
-<configuration scan="true" scanPeriod="5 milliseconds">
- <include resource="asResource/inner1.xml"/>
-</configuration>
-
diff --git a/logback-classic/src/test/input/joran/roct/inclusion/topLevel0.xml b/logback-classic/src/test/input/joran/roct/inclusion/topLevel0.xml
deleted file mode 100644
index 8d2a85d..0000000
--- a/logback-classic/src/test/input/joran/roct/inclusion/topLevel0.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE configuration>
-
-<configuration scan="true" scanPeriod="5 milliseconds">
-
- <include file="src/test/input/joran/roct/inclusion/inner0.xml"/>
-
-</configuration>
-
\ No newline at end of file
diff --git a/logback-classic/src/test/input/joran/roct/scan 1.groovy b/logback-classic/src/test/input/joran/roct/scan 1.groovy
deleted file mode 100644
index 59e4064..0000000
--- a/logback-classic/src/test/input/joran/roct/scan 1.groovy
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-import static ch.qos.logback.classic.Level.ERROR
-
-scan("5 millisecond")
-root(ERROR)
-
-
\ No newline at end of file
diff --git a/logback-classic/src/test/input/joran/roct/scan 1.xml b/logback-classic/src/test/input/joran/roct/scan 1.xml
deleted file mode 100644
index 05cda93..0000000
--- a/logback-classic/src/test/input/joran/roct/scan 1.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE configuration>
-
-<configuration scan="true" scanPeriod="5 millisecond">
-
- <root level="ERROR"/>
-
-</configuration>
-
\ No newline at end of file
diff --git a/logback-classic/src/test/input/joran/roct/scan_logback_474.xml b/logback-classic/src/test/input/joran/roct/scan_logback_474.xml
deleted file mode 100644
index aae1141..0000000
--- a/logback-classic/src/test/input/joran/roct/scan_logback_474.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-<configuration scan="true" scanPeriod="5 millisecond">
-
- <appender name="default" class="ch.qos.logback.classic.issue.logback474.LoggingAppender">
- </appender>
-
- <logger name="Ignore" level="ERROR" additivity="false"/>
-
- <root level="INFO">
- <appender-ref ref="default"/>
- </root>
-
-</configuration>
-
\ No newline at end of file
diff --git a/logback-classic/src/test/input/joran/rolling/depratedSizeAndTimeBasedFNATPWarning.xml b/logback-classic/src/test/input/joran/rolling/depratedSizeAndTimeBasedFNATPWarning.xml
deleted file mode 100644
index 6f42696..0000000
--- a/logback-classic/src/test/input/joran/rolling/depratedSizeAndTimeBasedFNATPWarning.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<configuration>
-
- <appender name="ROLLING"
- class="ch.qos.logback.core.rolling.RollingFileAppender">
- <File>${randomOutputDir}z${testId}</File>
- <rollingPolicy
- class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <FileNamePattern>
- ${randomOutputDir}${testId}-%d{yyyy-MM-dd_HH_mm_ss}.%i
- </FileNamePattern>
- <TimeBasedFileNamingAndTriggeringPolicy
- class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
- <MaxFileSize>100</MaxFileSize>
- </TimeBasedFileNamingAndTriggeringPolicy>
- </rollingPolicy>
- <encoder>
- <Pattern>%msg%n</Pattern>
- </encoder>
- </appender>
-
-
- <root level="debug">
- <appender-ref ref="ROLLING" />
- </root>
-
-</configuration>
diff --git a/logback-classic/src/test/input/joran/rolling/timeAndSize.xml b/logback-classic/src/test/input/joran/rolling/timeAndSize.xml
index 4060315..eeb754f 100644
--- a/logback-classic/src/test/input/joran/rolling/timeAndSize.xml
+++ b/logback-classic/src/test/input/joran/rolling/timeAndSize.xml
@@ -4,11 +4,14 @@
class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${randomOutputDir}z${testId}</File>
<rollingPolicy
- class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
- <fileNamePattern>
+ class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <FileNamePattern>
${randomOutputDir}${testId}-%d{yyyy-MM-dd_HH_mm_ss}.%i
- </fileNamePattern>
- <maxFileSize>${sizeThreshold}</maxFileSize>
+ </FileNamePattern>
+ <TimeBasedFileNamingAndTriggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+ <MaxFileSize>${sizeThreshold}</MaxFileSize>
+ </TimeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<Pattern>%msg%n</Pattern>
diff --git a/logback-classic/src/test/input/joran/rolling/timeAndSizeWithoutIntegerToken.xml b/logback-classic/src/test/input/joran/rolling/timeAndSizeWithoutIntegerToken.xml
deleted file mode 100644
index 2dce743..0000000
--- a/logback-classic/src/test/input/joran/rolling/timeAndSizeWithoutIntegerToken.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<configuration>
-
- <appender name="ROLLING"
- class="ch.qos.logback.core.rolling.RollingFileAppender">
- <File>${randomOutputDir}z${testId}</File>
- <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
- <fileNamePattern>${randomOutputDir}${testId}-%d{yyyy-MM-dd_HH_mm_ss}</fileNamePattern>
- <maxFileSize>10000</maxFileSize>
- </rollingPolicy>
- <encoder>
- <Pattern>%msg%n</Pattern>
- <outputPatternAsPresentationHeader>false</outputPatternAsPresentationHeader>
- </encoder>
- </appender>
-
-
- <root level="debug">
- <appender-ref ref="ROLLING" />
- </root>
-
-</configuration>
diff --git a/logback-classic/src/test/input/joran/rolling/timeAndSizeWithoutMaxFileSize.xml b/logback-classic/src/test/input/joran/rolling/timeAndSizeWithoutMaxFileSize.xml
deleted file mode 100644
index 254cf80..0000000
--- a/logback-classic/src/test/input/joran/rolling/timeAndSizeWithoutMaxFileSize.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<configuration debug="true">
-
- <appender name="ROLLING"
- class="ch.qos.logback.core.rolling.RollingFileAppender">
- <file>c:/tmp/logs/rolling-test.log</file>
- <encoder>
- <pattern>%d [%thread] %-5level %logger{36} - %msg%n</pattern>
- </encoder>
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>c:/tmp/logs/rolling-test-%d{yyyy-MM-dd}.%i.log
- </fileNamePattern>
- <timeBasedFileNamingAndTriggeringPolicy
- class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP" />
- <maxHistory>30</maxHistory>
- <cleanHistoryOnStart>true</cleanHistoryOnStart>
- </rollingPolicy>
- </appender>
-
- <root level="INFO">
- <appender-ref ref="ROLLING" />
- </root>
-
-</configuration>
\ No newline at end of file
diff --git a/logback-classic/src/test/input/joran/rolling/totalSizeCapSmallerThanMaxFileSize.xml b/logback-classic/src/test/input/joran/rolling/totalSizeCapSmallerThanMaxFileSize.xml
deleted file mode 100644
index f70b7c9..0000000
--- a/logback-classic/src/test/input/joran/rolling/totalSizeCapSmallerThanMaxFileSize.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<configuration>
-
- <appender name="ROLLING"
- class="ch.qos.logback.core.rolling.RollingFileAppender">
- <File>${randomOutputDir}z${testId}</File>
- <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
- <FileNamePattern>${randomOutputDir}${testId}-%d{yyyy-MM-dd_HH_mm_ss}.%i</FileNamePattern>
- <maxFileSize>100</maxFileSize>
- <maxHistory>4</maxHistory>
- <totalSizeCap>10</totalSizeCap>
- </rollingPolicy>
- <encoder>
- <Pattern>%msg%n</Pattern>
- </encoder>
- </appender>
-
-
- <root level="debug">
- <appender-ref ref="ROLLING" />
- </root>
-
-</configuration>
diff --git a/logback-classic/src/test/input/joran/scan1.xml b/logback-classic/src/test/input/joran/scan1.xml
new file mode 100644
index 0000000..995b3a4
--- /dev/null
+++ b/logback-classic/src/test/input/joran/scan1.xml
@@ -0,0 +1,10 @@
+<configuration scan="true" scanPeriod="1 millisecond">
+
+ <appender name="LIST" class="ch.qos.logback.core.read.ListAppender"/>
+
+ <root level="TRACE">
+ <appender-ref ref="LIST" />
+ </root>
+
+</configuration>
+
\ No newline at end of file
diff --git a/logback-classic/src/test/input/joran/sift/fileAppender.xml b/logback-classic/src/test/input/joran/sift/fileAppender.xml
deleted file mode 100644
index 39dfd62..0000000
--- a/logback-classic/src/test/input/joran/sift/fileAppender.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE configuration>
-
-<configuration debug="true">
-
- <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
-
- <discriminator>
- <Key>collision</Key>
- <defaultValue>collisionDefault</defaultValue>
- </discriminator>
- <sift>
- <appender name="FILE-${collision}" class="ch.qos.logback.core.FileAppender">
- <file>${DIR_PREFIX}/log-${collision}.txt</file>
- <encoder>
- <pattern>%logger{35} - %msg%n</pattern>
- </encoder>
- </appender>
- </sift>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SIFT" />
- </root>
-
-</configuration>
diff --git a/logback-classic/src/test/input/joran/sift/lbclassic203.xml b/logback-classic/src/test/input/joran/sift/lbclassic203.xml
new file mode 100644
index 0000000..29eb02b
--- /dev/null
+++ b/logback-classic/src/test/input/joran/sift/lbclassic203.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE configuration>
+
+<configuration debug="true">
+
+ <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+
+
+ <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
+
+ <discriminator>
+ <key>userid</key>
+ <defaultValue>smoke</defaultValue>
+ </discriminator>
+ <sift>
+ <appender name="list-${userid}"
+ class="ch.qos.logback.classic.issue.lbclassic203.InstanceCountingAppender" />
+ </sift>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="SIFT" />
+ </root>
+
+</configuration>
diff --git a/logback-classic/src/test/input/joran/sift/logback_416.xml b/logback-classic/src/test/input/joran/sift/logback_416.xml
deleted file mode 100644
index eb1fb9c..0000000
--- a/logback-classic/src/test/input/joran/sift/logback_416.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE configuration>
-
-<configuration debug="true">
-
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
-
-
- <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
-
- <discriminator>
- <key>userid</key>
- <defaultValue>smoke</defaultValue>
- </discriminator>
- <sift>
- <appender name="list-${userid}"
- class="ch.qos.logback.classic.issue.logback416.InstanceCountingAppender" />
- </sift>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SIFT" />
- </root>
-
-</configuration>
diff --git a/logback-classic/src/test/input/joran/unique.xml b/logback-classic/src/test/input/joran/unique.xml
index 7e19708..c48f9c4 100644
--- a/logback-classic/src/test/input/joran/unique.xml
+++ b/logback-classic/src/test/input/joran/unique.xml
@@ -1,8 +1,8 @@
<configuration>
- <timestamp key="dayTimestamp" datePattern="yyyyMMdd'T'HHmm" />
+ <timestamp key="dayTimestamp" datePattern="yyyyMMdd'T'HHmmss" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <File>target/test-output/UNIK_${dayTimestamp}${UNIK_DIFF}log.txt</File>
+ <File>target/test-output/TS_${dayTimestamp}log.txt</File>
<Append>false</Append>
<encoder>
<Pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</Pattern>
diff --git a/logback-classic/src/test/input/joran/valueOfConvention.xml b/logback-classic/src/test/input/joran/valueOfConvention.xml
deleted file mode 100644
index d98f01c..0000000
--- a/logback-classic/src/test/input/joran/valueOfConvention.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<configuration debug="true">
- <appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <file>target/test-output/valueOfConvention_${diff}/infoLog.log</file>
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>target/test-output/valueOfConvention_${diff}/infoLogs.%d{yyyy-MM-dd}.log</fileNamePattern>
-
- <maxHistory>30</maxHistory>
- <totalSizeCap>3GB</totalSizeCap>
- </rollingPolicy>
-
- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
- <level>INFO</level>
- </filter>
-
- <encoder>
- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n
- </pattern>
- </encoder>
- </appender>
-
-
-
- <root level="DEBUG">
- <appender-ref ref="FILE_INFO" />
- </root>
-</configuration>
\ No newline at end of file
diff --git a/logback-classic/src/test/input/listAppender.xml b/logback-classic/src/test/input/listAppender.xml
deleted file mode 100644
index f8a0048..0000000
--- a/logback-classic/src/test/input/listAppender.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<configuration debug="true">
-
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <Pattern>TEST %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
- </encoder>
- </appender>
-
-
- <appender name="LIST" class="ch.qos.logback.core.read.ListAppender"/>
-
- <root level="DEBUG" >
- <appender-ref ref="STDOUT" />
- <appender-ref ref="LIST" />
- </root>
-</configuration>
\ No newline at end of file
diff --git a/logback-classic/src/test/input/joran/roct/inclusion/inner0.xml b/logback-classic/src/test/input/turbo/inclusion/inner0.xml
similarity index 100%
rename from logback-classic/src/test/input/joran/roct/inclusion/inner0.xml
rename to logback-classic/src/test/input/turbo/inclusion/inner0.xml
diff --git a/logback-classic/src/test/input/turbo/inclusion/topByResource.xml b/logback-classic/src/test/input/turbo/inclusion/topByResource.xml
new file mode 100644
index 0000000..8965e91
--- /dev/null
+++ b/logback-classic/src/test/input/turbo/inclusion/topByResource.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE x>
+
+
+<configuration scan="true" scanPeriod="50 milliseconds">
+ <include resource="asResource/inner1.xml"/>
+</configuration>
+
diff --git a/logback-classic/src/test/input/turbo/inclusion/topLevel0.xml b/logback-classic/src/test/input/turbo/inclusion/topLevel0.xml
new file mode 100644
index 0000000..cd3a99a
--- /dev/null
+++ b/logback-classic/src/test/input/turbo/inclusion/topLevel0.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE configuration>
+
+<configuration scan="true" scanPeriod="50 milliseconds">
+
+ <include file="src/test/input/turbo/inclusion/inner0.xml"/>
+
+</configuration>
+
\ No newline at end of file
diff --git a/logback-classic/src/test/input/turbo/scan 1.groovy b/logback-classic/src/test/input/turbo/scan 1.groovy
new file mode 100644
index 0000000..98392b8
--- /dev/null
+++ b/logback-classic/src/test/input/turbo/scan 1.groovy
@@ -0,0 +1,6 @@
+import static ch.qos.logback.classic.Level.ERROR
+
+scan("50 millisecond")
+root(ERROR)
+
+
\ No newline at end of file
diff --git a/logback-classic/src/test/input/turbo/scan 1.xml b/logback-classic/src/test/input/turbo/scan 1.xml
new file mode 100644
index 0000000..5008660
--- /dev/null
+++ b/logback-classic/src/test/input/turbo/scan 1.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE configuration>
+
+<configuration scan="true" scanPeriod="50 millisecond">
+
+ <root level="ERROR"/>
+
+</configuration>
+
\ No newline at end of file
diff --git a/logback-classic/src/test/input/turbo/scan_logback_474.xml b/logback-classic/src/test/input/turbo/scan_logback_474.xml
new file mode 100644
index 0000000..d00c97f
--- /dev/null
+++ b/logback-classic/src/test/input/turbo/scan_logback_474.xml
@@ -0,0 +1,14 @@
+
+<configuration scan="true" scanPeriod="50 millisecond">
+
+ <appender name="default" class="ch.qos.logback.classic.issue.logback474.LoggingAppender">
+ </appender>
+
+ <logger name="Ignore" level="ERROR" additivity="false"/>
+
+ <root level="INFO">
+ <appender-ref ref="default"/>
+ </root>
+
+</configuration>
+
\ No newline at end of file
diff --git a/logback-classic/src/test/input/joran/roct/scan_perf.xml b/logback-classic/src/test/input/turbo/scan_perf.xml
similarity index 100%
rename from logback-classic/src/test/input/joran/roct/scan_perf.xml
rename to logback-classic/src/test/input/turbo/scan_perf.xml
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java
index 7369a61..7406962 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,13 +18,25 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ org.slf4j.impl.PackageTest.class, ch.qos.logback.classic.PackageTest.class, ch.qos.logback.classic.util.PackageTest.class,
- ch.qos.logback.classic.control.PackageTest.class, ch.qos.logback.classic.joran.PackageTest.class, ch.qos.logback.classic.rolling.PackageTest.class,
- ch.qos.logback.classic.jmx.PackageTest.class, ch.qos.logback.classic.boolex.PackageTest.class, ch.qos.logback.classic.selector.PackageTest.class,
- ch.qos.logback.classic.html.PackageTest.class, ch.qos.logback.classic.net.PackageTest.class, ch.qos.logback.classic.pattern.PackageTest.class,
- ch.qos.logback.classic.encoder.PackageTest.class, ch.qos.logback.classic.db.PackageTest.class, ch.qos.logback.classic.spi.PackageTest.class,
- ch.qos.logback.classic.turbo.PackageTest.class, ch.qos.logback.classic.sift.PackageTest.class, ch.qos.logback.classic.jul.PackageTest.class,
- ch.qos.logback.classic.issue.PackageTest.class })
+ at SuiteClasses({org.slf4j.impl.PackageTest.class,
+ ch.qos.logback.classic.PackageTest.class,
+ ch.qos.logback.classic.util.PackageTest.class,
+ ch.qos.logback.classic.control.PackageTest.class,
+ ch.qos.logback.classic.joran.PackageTest.class,
+ ch.qos.logback.classic.rolling.PackageTest.class,
+ ch.qos.logback.classic.jmx.PackageTest.class,
+ ch.qos.logback.classic.boolex.PackageTest.class,
+ ch.qos.logback.classic.selector.PackageTest.class,
+ ch.qos.logback.classic.html.PackageTest.class,
+ ch.qos.logback.classic.net.PackageTest.class,
+ ch.qos.logback.classic.pattern.PackageTest.class,
+ ch.qos.logback.classic.encoder.PackageTest.class,
+ ch.qos.logback.classic.db.PackageTest.class,
+ ch.qos.logback.classic.spi.PackageTest.class,
+ ch.qos.logback.classic.turbo.PackageTest.class,
+ ch.qos.logback.classic.sift.PackageTest.class,
+ ch.qos.logback.classic.jul.PackageTest.class,
+ ch.qos.logback.classic.issue.PackageTest.class})
public class AllClassicTest {
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/AsyncAppenderTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/AsyncAppenderTest.java
index d556e13..e100446 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/AsyncAppenderTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/AsyncAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,62 +31,64 @@ import static org.junit.Assert.*;
*/
public class AsyncAppenderTest {
- String thisClassName = this.getClass().getName();
- LoggerContext context = new LoggerContext();
- AsyncAppender asyncAppender = new AsyncAppender();
- ListAppender<ILoggingEvent> listAppender = new ListAppender<ILoggingEvent>();
- OnConsoleStatusListener onConsoleStatusListener = new OnConsoleStatusListener();
- LoggingEventBuilderInContext builder = new LoggingEventBuilderInContext(context, thisClassName, UnsynchronizedAppenderBase.class.getName());
- int diff = RandomUtil.getPositiveInt();
-
- @Before
- public void setUp() {
- onConsoleStatusListener.setContext(context);
- context.getStatusManager().add(onConsoleStatusListener);
- onConsoleStatusListener.start();
-
- asyncAppender.setContext(context);
- listAppender.setContext(context);
- listAppender.setName("list");
- listAppender.start();
- }
-
- @Test
- public void eventWasPreparedForDeferredProcessing() {
- asyncAppender.addAppender(listAppender);
- asyncAppender.start();
-
- String k = "k" + diff;
- MDC.put(k, "v");
- asyncAppender.doAppend(builder.build(diff));
- MDC.clear();
-
- asyncAppender.stop();
- assertFalse(asyncAppender.isStarted());
-
- // check the event
- assertEquals(1, listAppender.list.size());
- ILoggingEvent e = listAppender.list.get(0);
-
- // check that MDC values were correctly retained
- assertEquals("v", e.getMDCPropertyMap().get(k));
- assertFalse(e.hasCallerData());
- }
-
- @Test
- public void settingIncludeCallerDataPropertyCausedCallerDataToBeIncluded() {
- asyncAppender.addAppender(listAppender);
- asyncAppender.setIncludeCallerData(true);
- asyncAppender.start();
-
- asyncAppender.doAppend(builder.build(diff));
- asyncAppender.stop();
-
- // check the event
- assertEquals(1, listAppender.list.size());
- ILoggingEvent e = listAppender.list.get(0);
- assertTrue(e.hasCallerData());
- StackTraceElement ste = e.getCallerData()[0];
- assertEquals(thisClassName, ste.getClassName());
- }
+ String thisClassName = this.getClass().getName();
+ LoggerContext context = new LoggerContext();
+ AsyncAppender asyncAppender = new AsyncAppender();
+ ListAppender<ILoggingEvent> listAppender = new ListAppender<ILoggingEvent>();
+ OnConsoleStatusListener onConsoleStatusListener = new OnConsoleStatusListener();
+ LoggingEventBuilderInContext builder = new LoggingEventBuilderInContext(context, thisClassName, UnsynchronizedAppenderBase.class.getName());
+ int diff = RandomUtil.getPositiveInt();
+
+ @Before
+ public void setUp() {
+ onConsoleStatusListener.setContext(context);
+ context.getStatusManager().add(onConsoleStatusListener);
+ onConsoleStatusListener.start();
+
+ asyncAppender.setContext(context);
+ listAppender.setContext(context);
+ listAppender.setName("list");
+ listAppender.start();
+ }
+
+ @Test
+ public void eventWasPreparedForDeferredProcessing() {
+ asyncAppender.addAppender(listAppender);
+ asyncAppender.start();
+
+ String k = "k" + diff;
+ MDC.put(k, "v");
+ asyncAppender.doAppend(builder.build(diff));
+ MDC.clear();
+
+ asyncAppender.stop();
+ assertFalse(asyncAppender.isStarted());
+
+ // check the event
+ assertEquals(1, listAppender.list.size());
+ ILoggingEvent e = listAppender.list.get(0);
+
+ // check that MDC values were correctly retained
+ assertEquals("v", e.getMDCPropertyMap().get(k));
+ assertFalse(e.hasCallerData());
+ }
+
+
+ @Test
+ public void settingIncludeCallerDataPropertyCausedCallerDataToBeIncluded() {
+ asyncAppender.addAppender(listAppender);
+ asyncAppender.setIncludeCallerData(true);
+ asyncAppender.start();
+
+
+ asyncAppender.doAppend(builder.build(diff));
+ asyncAppender.stop();
+
+ // check the event
+ assertEquals(1, listAppender.list.size());
+ ILoggingEvent e = listAppender.list.get(0);
+ assertTrue(e.hasCallerData());
+ StackTraceElement ste = e.getCallerData()[0];
+ assertEquals(thisClassName, ste.getClassName());
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/ClassicTestConstants.java b/logback-classic/src/test/java/ch/qos/logback/classic/ClassicTestConstants.java
index 300d132..2f7c4e3 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/ClassicTestConstants.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/ClassicTestConstants.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,14 +16,15 @@ package ch.qos.logback.classic;
import ch.qos.logback.core.util.CoreTestConstants;
public class ClassicTestConstants {
- final static public String ISO_REGEX = "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3}";
- // pool-1-thread-47
- final static public String NAKED_MAIN_REGEX = "([mM]ain|pool-\\d-)([Tt]hread)?(-\\d{1,3})?";
+ final static public String ISO_REGEX = "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3}";
+ //pool-1-thread-47
+ final static public String NAKED_MAIN_REGEX = "([mM]ain|pool-\\d-)([Tt]hread)?(-\\d{1,3})?";
- final static public String MAIN_REGEX = "\\[" + NAKED_MAIN_REGEX + "\\]";
- final static public String INPUT_PREFIX = "src/test/input/";
- final static public String JORAN_INPUT_PREFIX = INPUT_PREFIX + "joran/";
- final static public String ISSUES_PREFIX = ClassicTestConstants.JORAN_INPUT_PREFIX + "issues/";
- final static public String GAFFER_INPUT_PREFIX = INPUT_PREFIX + "gaffer/";
- final static public String OUTPUT_DIR_PREFIX = CoreTestConstants.OUTPUT_DIR_PREFIX;
+
+ final static public String MAIN_REGEX = "\\[" + NAKED_MAIN_REGEX + "\\]";
+ final static public String INPUT_PREFIX = "src/test/input/";
+ final static public String JORAN_INPUT_PREFIX = INPUT_PREFIX + "joran/";
+ final static public String ISSUES_PREFIX = ClassicTestConstants.JORAN_INPUT_PREFIX+"issues/";
+ final static public String GAFFER_INPUT_PREFIX = INPUT_PREFIX + "gaffer/";
+ final static public String OUTPUT_DIR_PREFIX= CoreTestConstants.OUTPUT_DIR_PREFIX;
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/Foo.java b/logback-classic/src/test/java/ch/qos/logback/classic/Foo.java
index 7e062f6..f7e3a80 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/Foo.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/Foo.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,14 +16,15 @@ package ch.qos.logback.classic;
import java.io.Serializable;
class Foo implements Serializable {
- private static final long serialVersionUID = 1L;
- final Logger logger;
-
- Foo(Logger logger) {
- this.logger = logger;
- }
-
- void doFoo() {
- logger.debug("hello");
- }
+ private static final long serialVersionUID = 1L;
+ final Logger logger;
+
+ Foo(Logger logger) {
+ this.logger = logger;
+ }
+
+ void doFoo() {
+ logger.debug("hello");
+ }
}
+
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/HLogger.java b/logback-classic/src/test/java/ch/qos/logback/classic/HLogger.java
index 3d645f9..1190231 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/HLogger.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/HLogger.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,379 +24,385 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.CoreConstants;
-public class HLogger extends MarkerIgnoringBase {
-
- private static final long serialVersionUID = 1L;
-
- static int instanceCount = 0;
-
- /**
- * The name of this logger
- */
- private String name;
-
- // The assigned levelInt of this logger. Can be null.
- private Level level;
-
- // The effective levelInt is the assigned levelInt and if null, a levelInt is
- // inherited form a parent.
- private Level effectiveLevel;
-
- /**
- * The parent of this category. All categories have at least one ancestor
- * which is the root category.
- */
- HLogger parent;
-
- /**
- * The children of this logger. A logger may have zero or more children.
- */
- Map<String, HLogger> childrenMap;
-
- /**
- * Array of appenders.
- */
- private ArrayList<Appender<ILoggingEvent>> appenderList;
-
- /**
- * Additivity is set to true by default, that is children inherit the
- * appenders of their ancestors by default. If this variable is set to
- * <code>false</code> then the appenders located in the ancestors of this
- * logger will not be used. However, the children of this logger will inherit
- * its appenders, unless the children have their additivity flag set to
- * <code>false</code> too. See the user manual for more details.
- */
- protected boolean additive = true;
-
- HLogger(String name, HLogger parent) {
- this.name = name;
- this.parent = parent;
- instanceCount++;
- }
-
- Level getEffectiveLevel() {
- return effectiveLevel;
- }
-
- Level getLevel() {
- return level;
- }
-
- public String getName() {
- return name;
- }
-
- private boolean isRootLogger() {
- // only the root logger has a null parent
- return parent == null;
- }
-
- /**
- * Get a child by its suffix.
- *
- * <p>
- * IMPORTANT: Calls to this method must be within a syncronized block on this
- * logger!
- *
- * @param suffix
- * @return
- */
- HLogger getChildBySuffix(final String suffix) {
- if (childrenMap == null) {
- return null;
- } else {
- return (HLogger) childrenMap.get(suffix);
- }
- }
- public synchronized void setLevel(Level newLevel) {
- if (level == newLevel) {
- // nothing to do;
- return;
- }
-
- level = newLevel;
- effectiveLevel = newLevel;
- if (childrenMap != null) {
- for (Iterator<HLogger> i = childrenMap.values().iterator(); i.hasNext();) {
- HLogger child = (HLogger) i.next();
-
- // tell child to handle parent levelInt change
- child.handleParentLevelChange(effectiveLevel);
- }
- }
- }
-
- /**
- * This method is invoked by parent logger to let this logger know that the
- * prent's levelInt changed.
- *
- * @param newParentLevel
- */
- private synchronized void handleParentLevelChange(Level newParentLevel) {
- // changes in the parent levelInt affect children only if their levelInt is
- // null
- if (level == null) {
- effectiveLevel = newParentLevel;
-
- // propagate the parent levelInt change to this logger's children
- if (childrenMap != null) {
- for (Iterator<HLogger> i = childrenMap.values().iterator(); i.hasNext();) {
- HLogger child = (HLogger) i.next();
- // tell child to handle parent levelInt change
- child.handleParentLevelChange(effectiveLevel);
- }
- }
- }
- }
-
- /**
- * Remove all previously added appenders from this logger instance. <p/> This
- * is useful when re-reading configuration information.
- */
- public synchronized void removeAllAppenders() {
- if (appenderList != null) {
- int len = appenderList.size();
- for (int i = 0; i < len; i++) {
- Appender<ILoggingEvent> a = appenderList.get(i);
- a.stop();
- }
- appenderList.clear();
- appenderList = null;
- }
- }
-
- /**
- * Invoke all the appenders of this logger.
- *
- * @param event
- * The event to log
- */
- public void callAppenders(ILoggingEvent event) {
- int writes = 0;
-
- for (HLogger l = this; l != null; l = l.parent) {
- // Protected against simultaneous call to addAppender, removeAppender,...
- synchronized (l) {
- if (l.appenderList != null) {
- writes += l.appendLoopOnAppenders(event);
- }
- if (!l.additive) {
- break;
- }
- }
- }
-
- // No appenders in hierarchy, warn user only once.
- // if(!hierarchy.emittedNoAppenderWarning && writes == 0) {
- // LogLog.error("No appenders could be found for category (" +
- // this.getName() + ").");
- // LogLog.error("Please initialize the log4j system properly.");
- // hierarchy.emittedNoAppenderWarning = true;
- // }
- }
-
- private int appendLoopOnAppenders(ILoggingEvent event) {
- int size = 0;
- Appender<ILoggingEvent> appender;
-
- if (appenderList != null) {
- size = appenderList.size();
- for (int i = 0; i < size; i++) {
- appender = appenderList.get(i);
- appender.doAppend(event);
- }
- }
- return size;
- }
-
- /**
- * Remove the appender passed as parameter form the list of appenders.
- */
- public synchronized void removeAppender(Appender<ILoggingEvent> appender) {
- if ((appender == null) || (appenderList == null)) {
- }
- appenderList.remove(appender);
- }
-
- /**
- * Create a child of this logger by suffix, that is, the part of the name
- * extending this logger. For example, if this logger is named "x.y" and the
- * lastPart is "z", then the created child logger will be named "x.y.z".
- *
- * <p>
- * IMPORTANT: Calls to this method must be within a syncronized block on this
- * logger.
- *
- * @param lastPart
- * the suffix (i.e. last part) of the child logger name. This
- * parameter may not include dots, i.e. the logger separator
- * character.
- * @return
- */
- HLogger createChildByLastNamePart(final String lastPart) {
- int i_index = lastPart.indexOf(CoreConstants.DOT);
- if (i_index != -1) {
- throw new IllegalArgumentException("Child name [" + lastPart + " passed as parameter, may not include [" + CoreConstants.DOT + "]");
- }
+public class HLogger extends MarkerIgnoringBase {
- if (childrenMap == null) {
- childrenMap = new HashMap<String, HLogger>(2);
- }
- HLogger childHLogger;
- if (this.isRootLogger()) {
- childHLogger = new HLogger(lastPart, this);
- } else {
- childHLogger = new HLogger(name + CoreConstants.DOT + lastPart, this);
+ private static final long serialVersionUID = 1L;
+
+ static int instanceCount = 0;
+
+ /**
+ * The name of this logger
+ */
+ private String name;
+
+ // The assigned levelInt of this logger. Can be null.
+ private Level level;
+
+ // The effective levelInt is the assigned levelInt and if null, a levelInt is
+ // inherited form a parent.
+ private Level effectiveLevel;
+
+ /**
+ * The parent of this category. All categories have at least one ancestor
+ * which is the root category.
+ */
+ HLogger parent;
+
+ /**
+ * The children of this logger. A logger may have zero or more children.
+ */
+ Map<String, HLogger> childrenMap;
+
+ /**
+ * Array of appenders.
+ */
+ private ArrayList<Appender<ILoggingEvent>> appenderList;
+
+ /**
+ * Additivity is set to true by default, that is children inherit the
+ * appenders of their ancestors by default. If this variable is set to
+ * <code>false</code> then the appenders located in the ancestors of this
+ * logger will not be used. However, the children of this logger will inherit
+ * its appenders, unless the children have their additivity flag set to
+ * <code>false</code> too. See the user manual for more details.
+ */
+ protected boolean additive = true;
+
+ HLogger(String name, HLogger parent) {
+ this.name = name;
+ this.parent = parent;
+ instanceCount++;
+ }
+
+ Level getEffectiveLevel() {
+ return effectiveLevel;
+ }
+
+ Level getLevel() {
+ return level;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ private boolean isRootLogger() {
+ // only the root logger has a null parent
+ return parent == null;
+ }
+
+ /**
+ * Get a child by its suffix.
+ *
+ * <p>
+ * IMPORTANT: Calls to this method must be within a syncronized block on this
+ * logger!
+ *
+ * @param suffix
+ * @return
+ */
+ HLogger getChildBySuffix(final String suffix) {
+ if (childrenMap == null) {
+ return null;
+ } else {
+ return (HLogger) childrenMap.get(suffix);
+ }
+ }
+
+ public synchronized void setLevel(Level newLevel) {
+ if (level == newLevel) {
+ // nothing to do;
+ return;
+ }
+
+ level = newLevel;
+ effectiveLevel = newLevel;
+ if (childrenMap != null) {
+ for (Iterator<HLogger> i = childrenMap.values().iterator(); i.hasNext();) {
+ HLogger child = (HLogger) i.next();
+
+ // tell child to handle parent levelInt change
+ child.handleParentLevelChange(effectiveLevel);
+ }
+ }
+ }
+
+ /**
+ * This method is invoked by parent logger to let this logger know that the
+ * prent's levelInt changed.
+ *
+ * @param newParentLevel
+ */
+ private synchronized void handleParentLevelChange(Level newParentLevel) {
+ // changes in the parent levelInt affect children only if their levelInt is
+ // null
+ if (level == null) {
+ effectiveLevel = newParentLevel;
+
+ // propagate the parent levelInt change to this logger's children
+ if (childrenMap != null) {
+ for (Iterator<HLogger> i = childrenMap.values().iterator(); i.hasNext();) {
+ HLogger child = (HLogger) i.next();
+ // tell child to handle parent levelInt change
+ child.handleParentLevelChange(effectiveLevel);
}
- childrenMap.put(lastPart, childHLogger);
- childHLogger.effectiveLevel = this.effectiveLevel;
- return childHLogger;
- }
-
- public final void trace(String msg) {
- if (effectiveLevel.levelInt <= Level.TRACE_INT) {
- throw new UnsupportedOperationException("not yet implemented");
+ }
+ }
+ }
+
+ /**
+ * Remove all previously added appenders from this logger instance. <p/> This
+ * is useful when re-reading configuration information.
+ */
+ public synchronized void removeAllAppenders() {
+ if (appenderList != null) {
+ int len = appenderList.size();
+ for (int i = 0; i < len; i++) {
+ Appender<ILoggingEvent> a = appenderList.get(i);
+ a.stop();
+ }
+ appenderList.clear();
+ appenderList = null;
+ }
+ }
+
+ /**
+ * Invoke all the appenders of this logger.
+ *
+ * @param event
+ * The event to log
+ */
+ public void callAppenders(ILoggingEvent event) {
+ int writes = 0;
+
+ for (HLogger l = this; l != null; l = l.parent) {
+ // Protected against simultaneous call to addAppender, removeAppender,...
+ synchronized (l) {
+ if (l.appenderList != null) {
+ writes += l.appendLoopOnAppenders(event);
}
- }
-
- public void trace(String msg, Throwable t) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void trace(Object parameterizedMsg, Object param1) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void trace(String parameterizedMsg, Object param1, Object param2) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public final void debug(String msg) {
- if (effectiveLevel.levelInt <= Level.DEBUG_INT) {
- throw new UnsupportedOperationException("not yet implemented");
+ if (!l.additive) {
+ break;
}
- }
-
- public void debug(String msg, Throwable t) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void debug(Object parameterizedMsg, Object param1) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void debug(String parameterizedMsg, Object param1, Object param2) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void error(String msg) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void error(String msg, Throwable t) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void error(String parameterizedMsg, Object param1) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void error(String parameterizedMsg, Object param1, Object param2) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void info(String msg) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void info(String msg, Throwable t) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void info(String parameterizedMsg, Object param1) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void info(String parameterizedMsg, Object param1, Object param2) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public boolean isTraceEnabled() {
- return false;
- }
-
- public boolean isDebugEnabled() {
- return false;
- }
-
- public boolean isErrorEnabled() {
- return false; // To change body of implemented methods use File | Settings |
- // File Templates.
- }
-
- public boolean isInfoEnabled() {
- return false; // To change body of implemented methods use File | Settings |
- // File Templates.
- }
-
- public boolean isWarnEnabled() {
- return false; // To change body of implemented methods use File | Settings |
- // File Templates.
- }
-
- public void warn(String msg) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void warn(String msg, Throwable t) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void warn(String parameterizedMsg, Object param1) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void warn(String parameterizedMsg, Object param1, Object param2) {
- // To change body of implemented methods use File | Settings | File
- // Templates.
- }
-
- public void trace(String format, Object arg) {
- }
-
- public void trace(String format, Object[] argArray) {
- }
-
- public void debug(String format, Object arg) {
- }
-
- public void debug(String format, Object[] argArray) {
- }
-
- public void info(String format, Object[] argArray) {
- }
-
- public void warn(String format, Object[] argArray) {
- }
-
- public void error(String format, Object[] argArray) {
- }
+ }
+ }
+
+ // No appenders in hierarchy, warn user only once.
+ // if(!hierarchy.emittedNoAppenderWarning && writes == 0) {
+ // LogLog.error("No appenders could be found for category (" +
+ // this.getName() + ").");
+ // LogLog.error("Please initialize the log4j system properly.");
+ // hierarchy.emittedNoAppenderWarning = true;
+ // }
+ }
+
+ private int appendLoopOnAppenders(ILoggingEvent event) {
+ int size = 0;
+ Appender<ILoggingEvent> appender;
+
+ if (appenderList != null) {
+ size = appenderList.size();
+ for (int i = 0; i < size; i++) {
+ appender = appenderList.get(i);
+ appender.doAppend(event);
+ }
+ }
+ return size;
+ }
+
+ /**
+ * Remove the appender passed as parameter form the list of appenders.
+ */
+ public synchronized void removeAppender(Appender<ILoggingEvent> appender) {
+ if ((appender == null) || (appenderList == null)) {
+ }
+ appenderList.remove(appender);
+ }
+
+ /**
+ * Create a child of this logger by suffix, that is, the part of the name
+ * extending this logger. For example, if this logger is named "x.y" and the
+ * lastPart is "z", then the created child logger will be named "x.y.z".
+ *
+ * <p>
+ * IMPORTANT: Calls to this method must be within a syncronized block on this
+ * logger.
+ *
+ * @param lastPart
+ * the suffix (i.e. last part) of the child logger name. This
+ * parameter may not include dots, i.e. the logger separator
+ * character.
+ * @return
+ */
+ HLogger createChildByLastNamePart(final String lastPart) {
+ int i_index = lastPart.indexOf(CoreConstants.DOT);
+ if (i_index != -1) {
+ throw new IllegalArgumentException("Child name [" + lastPart
+ + " passed as parameter, may not include [" + CoreConstants.DOT
+ + "]");
+ }
+
+ if (childrenMap == null) {
+ childrenMap = new HashMap<String, HLogger>(2);
+ }
+ HLogger childHLogger;
+ if (this.isRootLogger()) {
+ childHLogger = new HLogger(lastPart, this);
+ } else {
+ childHLogger = new HLogger(name + CoreConstants.DOT + lastPart,
+ this);
+ }
+ childrenMap.put(lastPart, childHLogger);
+ childHLogger.effectiveLevel = this.effectiveLevel;
+ return childHLogger;
+ }
+
+ public final void trace(String msg) {
+ if (effectiveLevel.levelInt <= Level.TRACE_INT) {
+ throw new UnsupportedOperationException("not yet implemented");
+ }
+ }
+
+ public void trace(String msg, Throwable t) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void trace(Object parameterizedMsg, Object param1) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void trace(String parameterizedMsg, Object param1, Object param2) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+
+
+ public final void debug(String msg) {
+ if (effectiveLevel.levelInt <= Level.DEBUG_INT) {
+ throw new UnsupportedOperationException("not yet implemented");
+ }
+ }
+
+ public void debug(String msg, Throwable t) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void debug(Object parameterizedMsg, Object param1) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void debug(String parameterizedMsg, Object param1, Object param2) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void error(String msg) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void error(String msg, Throwable t) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void error(String parameterizedMsg, Object param1) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void error(String parameterizedMsg, Object param1, Object param2) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void info(String msg) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void info(String msg, Throwable t) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void info(String parameterizedMsg, Object param1) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void info(String parameterizedMsg, Object param1, Object param2) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public boolean isTraceEnabled() {
+ return false;
+ }
+
+ public boolean isDebugEnabled() {
+ return false;
+ }
+
+ public boolean isErrorEnabled() {
+ return false; // To change body of implemented methods use File | Settings |
+ // File Templates.
+ }
+
+ public boolean isInfoEnabled() {
+ return false; // To change body of implemented methods use File | Settings |
+ // File Templates.
+ }
+
+ public boolean isWarnEnabled() {
+ return false; // To change body of implemented methods use File | Settings |
+ // File Templates.
+ }
+
+ public void warn(String msg) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void warn(String msg, Throwable t) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void warn(String parameterizedMsg, Object param1) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void warn(String parameterizedMsg, Object param1, Object param2) {
+ // To change body of implemented methods use File | Settings | File
+ // Templates.
+ }
+
+ public void trace(String format, Object arg) {
+ }
+
+ public void trace(String format, Object[] argArray) {
+ }
+
+ public void debug(String format, Object arg) {
+ }
+
+ public void debug(String format, Object[] argArray) {
+ }
+
+ public void info(String format, Object[] argArray) {
+ }
+
+ public void warn(String format, Object[] argArray) {
+ }
+
+ public void error(String format, Object[] argArray) {
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/HLoggerContext.java b/logback-classic/src/test/java/ch/qos/logback/classic/HLoggerContext.java
index 6fd609e..a5f369c 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/HLoggerContext.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/HLoggerContext.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,103 +15,104 @@ package ch.qos.logback.classic;
import ch.qos.logback.classic.Level;
+
+
/**
* @author ceki
*/
public class HLoggerContext {
- private HLogger root;
- private int size;
+ private HLogger root;
+ private int size;
- public HLoggerContext() {
- this.root = new HLogger("root", null);
- this.root.setLevel(Level.DEBUG);
- size = 1;
- }
+ public HLoggerContext() {
+ this.root = new HLogger("root", null);
+ this.root.setLevel(Level.DEBUG);
+ size = 1;
+ }
- /**
- * Return this contexts root logger
- *
- * @return
- */
- public HLogger getRootLogger() {
- return root;
- }
+ /**
+ * Return this contexts root logger
+ *
+ * @return
+ */
+ public HLogger getRootLogger() {
+ return root;
+ }
- public HLogger getLogger(final String name) {
+ public HLogger getLogger(final String name) {
- int i = 0;
- HLogger HLogger = root;
- HLogger childHLogger = null;
- String childName;
+ int i = 0;
+ HLogger HLogger = root;
+ HLogger childHLogger = null;
+ String childName;
- while (true) {
- int h = name.indexOf('.', i);
- if (h == -1) {
- childName = name.substring(i);
- } else {
- childName = name.substring(i, h);
- }
- // move i left of the last point
- i = h + 1;
+ while (true) {
+ int h = name.indexOf('.', i);
+ if (h == -1) {
+ childName = name.substring(i);
+ } else {
+ childName = name.substring(i, h);
+ }
+ // move i left of the last point
+ i = h + 1;
- synchronized (HLogger) {
- childHLogger = HLogger.getChildBySuffix(childName);
- if (childHLogger == null) {
- childHLogger = HLogger.createChildByLastNamePart(childName);
- incSize();
- }
- }
- HLogger = childHLogger;
- if (h == -1) {
- return childHLogger;
- }
+ synchronized (HLogger) {
+ childHLogger = HLogger.getChildBySuffix(childName);
+ if (childHLogger == null) {
+ childHLogger = HLogger.createChildByLastNamePart(childName);
+ incSize();
}
+ }
+ HLogger = childHLogger;
+ if (h == -1) {
+ return childHLogger;
+ }
}
+ }
- private synchronized void incSize() {
- size++;
- }
-
- int size() {
- return size;
- }
+ private synchronized void incSize() {
+ size++;
+ }
- /**
- * Check if the named logger exists in the hierarchy. If so return
- * its reference, otherwise returns <code>null</code>.
- *
- * @param name the name of the logger to search for.
- */
- HLogger exists(String name) {
- int i = 0;
- HLogger HLogger = root;
- HLogger childHLogger = null;
- String childName;
- while (true) {
- int h = name.indexOf('.', i);
- if (h == -1) {
- childName = name.substring(i);
- } else {
- childName = name.substring(i, h);
- }
- // move i left of the last point
- i = h + 1;
+ int size() {
+ return size;
+ }
+ /**
+ * Check if the named logger exists in the hierarchy. If so return
+ * its reference, otherwise returns <code>null</code>.
+ *
+ * @param name the name of the logger to search for.
+ */
+ HLogger exists(String name) {
+ int i = 0;
+ HLogger HLogger = root;
+ HLogger childHLogger = null;
+ String childName;
+ while (true) {
+ int h = name.indexOf('.', i);
+ if (h == -1) {
+ childName = name.substring(i);
+ } else {
+ childName = name.substring(i, h);
+ }
+ // move i left of the last point
+ i = h + 1;
- synchronized (HLogger) {
- childHLogger = HLogger.getChildBySuffix(childName);
- if (childHLogger == null) {
- return null;
- }
- }
- HLogger = childHLogger;
- if (h == -1) {
- if (childHLogger.getName().equals(name)) {
- return childHLogger;
- } else {
- return null;
- }
- }
+ synchronized (HLogger) {
+ childHLogger = HLogger.getChildBySuffix(childName);
+ if (childHLogger == null) {
+ return null;
+ }
+ }
+ HLogger = childHLogger;
+ if (h == -1) {
+ if (childHLogger.getName().equals(name)) {
+ return childHLogger;
+ } else {
+ return null;
}
+ }
}
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextConcurrentResetTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextConcurrentResetTest.java
deleted file mode 100644
index 940b020..0000000
--- a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextConcurrentResetTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package ch.qos.logback.classic;
-
-import java.util.concurrent.CyclicBarrier;
-
-import org.junit.Test;
-
-import ch.qos.logback.core.contention.AbstractMultiThreadedHarness;
-import ch.qos.logback.core.contention.RunnableWithCounterAndDone;
-import ch.qos.logback.core.status.StatusChecker;
-
-public class LoggerContextConcurrentResetTest {
- static int CONCURRENT_RESET_THREAD_COUNT = 10;
-
- // see http://jira.qos.ch/browse/LOGBACK-397
- @Test(timeout = 1000)
- public void concurrentReset() throws InterruptedException {
- LoggerContext loggerContext = new LoggerContext();
- CyclicBarrier cyclicBarrier = new CyclicBarrier(CONCURRENT_RESET_THREAD_COUNT);
- StatusChecker statusChecker = new StatusChecker(loggerContext);
- int desiredResetCount = 100;
- RunnableWithCounterAndDone[] runnableArray = buildRunnableArray(loggerContext, cyclicBarrier);
- Harness harness = new Harness((Resetter) runnableArray[0], desiredResetCount);
- harness.execute(runnableArray);
- statusChecker.assertIsErrorFree();
- }
-
- class Harness extends AbstractMultiThreadedHarness {
- int desiredResetCount;
- Resetter resetter;
-
- Harness(Resetter resetter, int desiredResetCount) {
- this.resetter = resetter;
- this.desiredResetCount = desiredResetCount;
- }
-
- public void waitUntilEndCondition() throws InterruptedException {
- while (resetter.getCounter() < desiredResetCount) {
- Thread.yield();
- }
- }
- }
-
- static class GetLoggerRunnable extends RunnableWithCounterAndDone {
-
- final int burstLength = 30;
- LoggerContext loggerContext;
- CyclicBarrier cyclicBarrier;
- String nameSuffix;
-
- GetLoggerRunnable(LoggerContext loggerContext, CyclicBarrier cyclicBarrier, String nameSuffix) {
- this.loggerContext = loggerContext;
- this.cyclicBarrier = cyclicBarrier;
- this.nameSuffix = nameSuffix;
- }
-
- public void run() {
- try {
- cyclicBarrier.await();
- } catch (Exception e) {
- }
-
- while (!isDone()) {
- long i = counter % burstLength;
- loggerContext.getLogger("org.bla." + nameSuffix + ".x" + i);
- counter++;
- if (i == 0) {
- Thread.yield();
- }
- }
- }
- }
-
- static class Resetter extends RunnableWithCounterAndDone {
- LoggerContext loggerContext;
- CyclicBarrier cyclicBarrier;
- public int resetCount = 0;
-
- Resetter(LoggerContext loggerContext, CyclicBarrier cyclicBarrier) {
- this.loggerContext = loggerContext;
- this.cyclicBarrier = cyclicBarrier;
- }
-
- public void run() {
- try {
- cyclicBarrier.await();
- } catch (Exception e) {
- }
- while (!isDone()) {
- loggerContext.reset();
- counter++;
- Thread.yield();
- }
- }
- }
-
- private RunnableWithCounterAndDone[] buildRunnableArray(LoggerContext loggerContext, CyclicBarrier cyclicBarrier) {
- RunnableWithCounterAndDone[] rArray = new RunnableWithCounterAndDone[CONCURRENT_RESET_THREAD_COUNT];
- rArray[0] = new Resetter(loggerContext, cyclicBarrier);
- for (int i = 1; i < CONCURRENT_RESET_THREAD_COUNT; i++) {
- rArray[i] = new GetLoggerRunnable(loggerContext, cyclicBarrier, "mouse-" + i);
- }
- return rArray;
- }
-}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextDeadlockTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextDeadlockTest.java
index 0d30b94..c5347a0 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextDeadlockTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextDeadlockTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,49 +24,51 @@ import ch.qos.logback.core.joran.spi.JoranException;
public class LoggerContextDeadlockTest {
- LoggerContext loggerContext = new LoggerContext();
- JoranConfigurator jc = new JoranConfigurator();
- GetLoggerThread getLoggerThread = new GetLoggerThread(loggerContext);
+ LoggerContext loggerContext = new LoggerContext();
+ JoranConfigurator jc = new JoranConfigurator();
+ GetLoggerThread getLoggerThread = new GetLoggerThread(loggerContext);
- @Before
- public void setUp() throws Exception {
- jc.setContext(loggerContext);
- }
+ @Before
+ public void setUp() throws Exception {
+ jc.setContext(loggerContext);
+ }
- @After
- public void tearDown() throws Exception {
- }
+ @After
+ public void tearDown() throws Exception {
+ }
- @Test(timeout = 20000)
- public void testLBCLASSIC_81() throws JoranException {
+ @Test(timeout = 20000)
+ public void testLBCLASSIC_81() throws JoranException {
- getLoggerThread.start();
- for (int i = 0; i < 500; i++) {
- ByteArrayInputStream baos = new ByteArrayInputStream("<configuration><root level=\"DEBUG\"/></configuration>".getBytes());
- jc.doConfigure(baos);
- }
+
+ getLoggerThread.start();
+ for (int i = 0; i < 500; i++) {
+ ByteArrayInputStream baos = new ByteArrayInputStream(
+ "<configuration><root level=\"DEBUG\"/></configuration>".getBytes());
+ jc.doConfigure(baos);
}
+ }
- class GetLoggerThread extends Thread {
+ class GetLoggerThread extends Thread {
- final LoggerContext loggerContext;
+ final LoggerContext loggerContext;
- GetLoggerThread(LoggerContext loggerContext) {
- this.loggerContext = loggerContext;
- }
+ GetLoggerThread(LoggerContext loggerContext) {
+ this.loggerContext = loggerContext;
+ }
- @Override
- public void run() {
- for (int i = 0; i < 10000; i++) {
- if (i % 100 == 0) {
- try {
- Thread.sleep(1);
- } catch (InterruptedException e) {
- }
- }
- loggerContext.getLogger("a" + i);
- }
+ @Override
+ public void run() {
+ for (int i = 0; i < 10000; i++) {
+ if (i % 100 == 0) {
+ try {
+ Thread.sleep(1);
+ } catch (InterruptedException e) {
+ }
}
+ loggerContext.getLogger("a" + i);
+ }
}
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextPerfTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextPerfTest.java
index 93ab7f0..51747da 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextPerfTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextPerfTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.classic;
+
import ch.qos.logback.classic.corpus.CorpusModel;
import ch.qos.logback.core.contention.*;
import org.junit.Before;
@@ -23,69 +24,68 @@ import static org.junit.Assert.fail;
public class LoggerContextPerfTest {
- static int THREAD_COUNT = 10000;
- int totalTestDuration = 4000;
-
- LoggerContext loggerContext = new LoggerContext();
-
- ThreadedThroughputCalculator harness = new ThreadedThroughputCalculator(totalTestDuration);
- RunnableWithCounterAndDone[] runnableArray = buildRunnableArray();
-
- CorpusModel corpusMaker;
-
- @Before
- public void setUp() throws Exception {
- }
-
- private RunnableWithCounterAndDone[] buildRunnableArray() {
- RunnableWithCounterAndDone[] runnableArray = new RunnableWithCounterAndDone[THREAD_COUNT];
- for (int i = 0; i < THREAD_COUNT; i++) {
- runnableArray[i] = new GetLoggerRunnable();
- }
- return runnableArray;
- }
+ static int THREAD_COUNT = 10000;
+ int totalTestDuration = 4000;
- // Results computed on a Intel i7
- // 1 thread
- // 13'107 ops per milli using Hashtable for LoggerContext.loggerCache
- // 15'258 ops per milli using ConcurrentHashMap for LoggerContext.loggerCache
+ LoggerContext loggerContext = new LoggerContext();
- // 10 threads
- // 8'468 ops per milli using Hashtable for LoggerContext.loggerCache
- // 58'945 ops per milli using ConcurrentHashMap for LoggerContext.loggerCache
+ ThreadedThroughputCalculator harness = new ThreadedThroughputCalculator(totalTestDuration);
+ RunnableWithCounterAndDone[] runnableArray = buildRunnableArray();
- // 100 threads
- // 8'863 ops per milli using Hashtable for LoggerContext.loggerCache
- // 34'810 ops per milli using ConcurrentHashMap for LoggerContext.loggerCache
+ CorpusModel corpusMaker;
- // 1'000 threads
- // 8'188 ops per milli using Hashtable for LoggerContext.loggerCache
- // 24'012 ops per milli using ConcurrentHashMap for LoggerContext.loggerCache
+ @Before
+ public void setUp() throws Exception {
+ }
- // 10'000 threads
- // 7'595 ops per milli using Hashtable for LoggerContext.loggerCache
- // 8'989 ops per milli using ConcurrentHashMap for LoggerContext.loggerCache
-
- @Test
- public void computeResults() throws InterruptedException {
- harness.execute(runnableArray);
- harness.printThroughput("getLogger performance: ", true);
+ private RunnableWithCounterAndDone[] buildRunnableArray() {
+ RunnableWithCounterAndDone[] runnableArray = new RunnableWithCounterAndDone[THREAD_COUNT];
+ for(int i = 0; i < THREAD_COUNT; i++) {
+ runnableArray[i] = new GetLoggerRunnable();
}
-
- private class GetLoggerRunnable extends RunnableWithCounterAndDone {
-
- final int burstLength = 3;
-
- public void run() {
- while (!isDone()) {
- long i = counter % burstLength;
-
- loggerContext.getLogger("a" + i);
- counter++;
- if (i == 0) {
- Thread.yield();
- }
- }
+ return runnableArray;
+ }
+
+ // Results computed on a Intel i7
+ // 1 thread
+ // 13'107 ops per milli using Hashtable for LoggerContext.loggerCache
+ // 15'258 ops per milli using ConcurrentHashMap for LoggerContext.loggerCache
+
+ // 10 threads
+ // 8'468 ops per milli using Hashtable for LoggerContext.loggerCache
+ // 58'945 ops per milli using ConcurrentHashMap for LoggerContext.loggerCache
+
+ // 100 threads
+ // 8'863 ops per milli using Hashtable for LoggerContext.loggerCache
+ // 34'810 ops per milli using ConcurrentHashMap for LoggerContext.loggerCache
+
+ // 1'000 threads
+ // 8'188 ops per milli using Hashtable for LoggerContext.loggerCache
+ // 24'012 ops per milli using ConcurrentHashMap for LoggerContext.loggerCache
+
+ // 10'000 threads
+ // 7'595 ops per milli using Hashtable for LoggerContext.loggerCache
+ // 8'989 ops per milli using ConcurrentHashMap for LoggerContext.loggerCache
+
+ @Test
+ public void computeResults() throws InterruptedException {
+ harness.execute(runnableArray);
+ harness.printThroughput("getLogger performance: ", true);
+ }
+
+ private class GetLoggerRunnable extends RunnableWithCounterAndDone {
+
+ final int burstLength = 3;
+ public void run() {
+ while (!isDone()) {
+ long i = counter % burstLength;
+
+ loggerContext.getLogger("a"+i);
+ counter++;
+ if(i == 0) {
+ Thread.yield();
}
+ }
}
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextTest.java
index 0ef7f68..e92b121 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,259 +20,231 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import java.util.Map;
-
import org.junit.Before;
import org.junit.Test;
import ch.qos.logback.classic.turbo.NOPTurboFilter;
import ch.qos.logback.core.CoreConstants;
-import ch.qos.logback.core.rolling.helper.FileNamePattern;
import ch.qos.logback.core.status.StatusManager;
public class LoggerContextTest {
- LoggerContext lc;
-
- @Before
- public void setUp() throws Exception {
- lc = new LoggerContext();
- lc.setName("x");
- }
-
- @Test
- public void testRootGetLogger() {
- Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- assertEquals(Level.DEBUG, root.getLevel());
- assertEquals(Level.DEBUG, root.getEffectiveLevel());
- }
-
- @Test
- public void testLoggerX() {
- Logger x = lc.getLogger("x");
- assertNotNull(x);
- assertEquals("x", x.getName());
- assertNull(x.getLevel());
- assertEquals(Level.DEBUG, x.getEffectiveLevel());
- }
-
- @Test
- public void testNull() {
- try {
- lc.getLogger((String) null);
- fail("null should cause an exception");
- } catch (IllegalArgumentException e) {
+ LoggerContext lc;
+
+ @Before
+ public void setUp() throws Exception {
+ lc = new LoggerContext();
+ lc.setName("x");
+ }
+
+ @Test
+ public void testRootGetLogger() {
+ Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+ assertEquals(Level.DEBUG, root.getLevel());
+ assertEquals(Level.DEBUG, root.getEffectiveLevel());
+ }
+
+ @Test
+ public void testLoggerX() {
+ Logger x = lc.getLogger("x");
+ assertNotNull(x);
+ assertEquals("x", x.getName());
+ assertNull(x.getLevel());
+ assertEquals(Level.DEBUG, x.getEffectiveLevel());
+ }
+
+ @Test
+ public void testNull() {
+ try {
+ lc.getLogger((String) null);
+ fail("null should cause an exception");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ @Test
+ public void testEmpty() {
+ Logger empty = lc.getLogger("");
+ LoggerTestHelper.assertNameEquals(empty, "");
+ LoggerTestHelper.assertLevels(null, empty, Level.DEBUG);
+
+ Logger dot = lc.getLogger(".");
+ LoggerTestHelper.assertNameEquals(dot, ".");
+ // LoggerTestHelper.assertNameEquals(dot.parent, "");
+ // LoggerTestHelper.assertNameEquals(dot.parent.parent, "root");
+
+ // assertNull(dot.parent.parent.parent);
+ LoggerTestHelper.assertLevels(null, dot, Level.DEBUG);
+
+
+ assertEquals(3, lc.getLoggerList().size());
+ }
+
+ @Test
+ public void testDotDot() {
+ Logger dotdot = lc.getLogger("..");
+ assertEquals(4, lc.getLoggerList().size());
+ LoggerTestHelper.assertNameEquals(dotdot, "..");
+ // LoggerTestHelper.assertNameEquals(dotdot.parent, ".");
+ // LoggerTestHelper.assertNameEquals(dotdot.parent.parent, "");
+ // LoggerTestHelper.assertNameEquals(dotdot.parent.parent.parent, "root");
+ }
+
+ int instanceCount() {
+ return lc.getLoggerList().size();
+ }
+
+ @Test
+ public void testLoggerXY() {
+ assertEquals(1, lc.getLoggerList().size());
+
+ Logger xy = lc.getLogger("x.y");
+ assertEquals(3, instanceCount());
+ LoggerTestHelper.assertNameEquals(xy, "x.y");
+ LoggerTestHelper.assertLevels(null, xy, Level.DEBUG);
+
+ Logger x = lc.getLogger("x");
+ assertEquals(3, instanceCount());
+
+ Logger xy2 = lc.getLogger("x.y");
+ assertEquals(xy, xy2);
+
+ Logger x2 = lc.getLogger("x");
+ assertEquals(x, x2);
+ assertEquals(3, instanceCount());
+ }
+
+ @Test
+ public void testLoggerMultipleChildren() {
+ assertEquals(1, instanceCount());
+ Logger xy0 = lc.getLogger("x.y0");
+ LoggerTestHelper.assertNameEquals(xy0, "x.y0");
+
+ Logger xy1 = lc.getLogger("x.y1");
+ LoggerTestHelper.assertNameEquals(xy1, "x.y1");
+
+ LoggerTestHelper.assertLevels(null, xy0, Level.DEBUG);
+ LoggerTestHelper.assertLevels(null, xy1, Level.DEBUG);
+ assertEquals(4, instanceCount());
+
+ for (int i = 0; i < 100; i++) {
+ Logger xy_i = lc.getLogger("x.y" + i);
+ LoggerTestHelper.assertNameEquals(xy_i, "x.y" + i);
+ LoggerTestHelper.assertLevels(null, xy_i, Level.DEBUG);
+ }
+ assertEquals(102, instanceCount());
+ }
+
+ @Test
+ public void testMultiLevel() {
+ Logger wxyz = lc.getLogger("w.x.y.z");
+ LoggerTestHelper.assertNameEquals(wxyz, "w.x.y.z");
+ LoggerTestHelper.assertLevels(null, wxyz, Level.DEBUG);
+
+ Logger wx = lc.getLogger("w.x");
+ wx.setLevel(Level.INFO);
+ LoggerTestHelper.assertNameEquals(wx, "w.x");
+ LoggerTestHelper.assertLevels(Level.INFO, wx, Level.INFO);
+ LoggerTestHelper.assertLevels(null, lc.getLogger("w.x.y"), Level.INFO);
+ LoggerTestHelper.assertLevels(null, wxyz, Level.INFO);
+ }
+
+ @Test
+ public void testStatusWithUnconfiguredContext() {
+ Logger logger = lc.getLogger(LoggerContextTest.class);
+
+ for (int i = 0; i < 3; i++) {
+ logger.debug("test");
+ }
+
+ logger = lc.getLogger("x.y.z");
+
+ for (int i = 0; i < 3; i++) {
+ logger.debug("test");
+ }
+
+ StatusManager sm = lc.getStatusManager();
+ assertTrue("StatusManager has recieved too many messages",
+ sm.getCount() == 1);
+ }
+
+
+ @Test
+ public void resetTest() {
+
+ Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+ Logger a = lc.getLogger("a");
+ Logger ab = lc.getLogger("a.b");
+
+ ab.setLevel(Level.WARN);
+ root.setLevel(Level.INFO);
+ lc.reset();
+ assertEquals(Level.DEBUG, root.getEffectiveLevel());
+ assertTrue(root.isDebugEnabled());
+ assertEquals(Level.DEBUG, a.getEffectiveLevel());
+ assertEquals(Level.DEBUG, ab.getEffectiveLevel());
+
+ assertEquals(Level.DEBUG, root.getLevel());
+ assertNull(a.getLevel());
+ assertNull(ab.getLevel());
+ }
+
+ // http://jira.qos.ch/browse/LBCLASSIC-89
+ @Test
+ public void turboFilterStopOnReset() {
+ NOPTurboFilter nopTF = new NOPTurboFilter();
+ nopTF.start();
+ lc.addTurboFilter(nopTF);
+ assertTrue(nopTF.isStarted());
+ lc.reset();
+ assertFalse(nopTF.isStarted());
+ }
+
+ @Test
+ public void resetTest_LBCORE_104() {
+ lc.putProperty("keyA", "valA");
+ lc.putObject("keyA", "valA");
+ assertEquals("valA", lc.getProperty("keyA"));
+ assertEquals("valA", lc.getObject("keyA"));
+ lc.reset();
+ assertNull(lc.getProperty("keyA"));
+ assertNull(lc.getObject("keyA"));
+ }
+
+ @Test
+ public void levelResetTest() {
+ Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+ root.setLevel(Level.TRACE);
+ assertTrue(root.isTraceEnabled());
+ lc.reset();
+ assertFalse(root.isTraceEnabled());
+ assertTrue(root.isDebugEnabled());
+ }
+
+ @Test
+ public void evaluatorMapPostReset() {
+ lc.reset();
+ assertNotNull(lc.getObject(CoreConstants.EVALUATOR_MAP));
+ }
+
+ // http://jira.qos.ch/browse/LOGBACK-142
+ @Test
+ public void concurrentModification() {
+ final int runLen = 100;
+ Thread thread = new Thread(new Runnable() {
+ public void run() {
+ for (int i = 0; i < runLen; i++) {
+ lc.getLogger("a" + i);
+ Thread.yield();
}
- }
-
- @Test
- public void testEmpty() {
- Logger empty = lc.getLogger("");
- LoggerTestHelper.assertNameEquals(empty, "");
- LoggerTestHelper.assertLevels(null, empty, Level.DEBUG);
-
- Logger dot = lc.getLogger(".");
- LoggerTestHelper.assertNameEquals(dot, ".");
- // LoggerTestHelper.assertNameEquals(dot.parent, "");
- // LoggerTestHelper.assertNameEquals(dot.parent.parent, "root");
-
- // assertNull(dot.parent.parent.parent);
- LoggerTestHelper.assertLevels(null, dot, Level.DEBUG);
-
- assertEquals(3, lc.getLoggerList().size());
- }
-
- @Test
- public void testDotDot() {
- Logger dotdot = lc.getLogger("..");
- assertEquals(4, lc.getLoggerList().size());
- LoggerTestHelper.assertNameEquals(dotdot, "..");
- // LoggerTestHelper.assertNameEquals(dotdot.parent, ".");
- // LoggerTestHelper.assertNameEquals(dotdot.parent.parent, "");
- // LoggerTestHelper.assertNameEquals(dotdot.parent.parent.parent, "root");
- }
+ }
+ });
+ thread.start();
- int instanceCount() {
- return lc.getLoggerList().size();
+ for (int i = 0; i < runLen; i++) {
+ lc.putProperty("a" + i, "val");
+ Thread.yield();
}
- @Test
- public void testLoggerXY() {
- assertEquals(1, lc.getLoggerList().size());
-
- Logger xy = lc.getLogger("x.y");
- assertEquals(3, instanceCount());
- LoggerTestHelper.assertNameEquals(xy, "x.y");
- LoggerTestHelper.assertLevels(null, xy, Level.DEBUG);
-
- Logger x = lc.getLogger("x");
- assertEquals(3, instanceCount());
-
- Logger xy2 = lc.getLogger("x.y");
- assertEquals(xy, xy2);
-
- Logger x2 = lc.getLogger("x");
- assertEquals(x, x2);
- assertEquals(3, instanceCount());
- }
-
- @Test
- public void testLoggerMultipleChildren() {
- assertEquals(1, instanceCount());
- Logger xy0 = lc.getLogger("x.y0");
- LoggerTestHelper.assertNameEquals(xy0, "x.y0");
-
- Logger xy1 = lc.getLogger("x.y1");
- LoggerTestHelper.assertNameEquals(xy1, "x.y1");
-
- LoggerTestHelper.assertLevels(null, xy0, Level.DEBUG);
- LoggerTestHelper.assertLevels(null, xy1, Level.DEBUG);
- assertEquals(4, instanceCount());
-
- for (int i = 0; i < 100; i++) {
- Logger xy_i = lc.getLogger("x.y" + i);
- LoggerTestHelper.assertNameEquals(xy_i, "x.y" + i);
- LoggerTestHelper.assertLevels(null, xy_i, Level.DEBUG);
- }
- assertEquals(102, instanceCount());
- }
-
- @Test
- public void testMultiLevel() {
- Logger wxyz = lc.getLogger("w.x.y.z");
- LoggerTestHelper.assertNameEquals(wxyz, "w.x.y.z");
- LoggerTestHelper.assertLevels(null, wxyz, Level.DEBUG);
-
- Logger wx = lc.getLogger("w.x");
- wx.setLevel(Level.INFO);
- LoggerTestHelper.assertNameEquals(wx, "w.x");
- LoggerTestHelper.assertLevels(Level.INFO, wx, Level.INFO);
- LoggerTestHelper.assertLevels(null, lc.getLogger("w.x.y"), Level.INFO);
- LoggerTestHelper.assertLevels(null, wxyz, Level.INFO);
- }
-
- @Test
- public void testStatusWithUnconfiguredContext() {
- Logger logger = lc.getLogger(LoggerContextTest.class);
-
- for (int i = 0; i < 3; i++) {
- logger.debug("test");
- }
-
- logger = lc.getLogger("x.y.z");
-
- for (int i = 0; i < 3; i++) {
- logger.debug("test");
- }
-
- StatusManager sm = lc.getStatusManager();
- assertTrue("StatusManager has recieved too many messages", sm.getCount() == 1);
- }
-
- @Test
- public void resetTest() {
-
- Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- Logger a = lc.getLogger("a");
- Logger ab = lc.getLogger("a.b");
-
- ab.setLevel(Level.WARN);
- root.setLevel(Level.INFO);
- lc.reset();
- assertEquals(Level.DEBUG, root.getEffectiveLevel());
- assertTrue(root.isDebugEnabled());
- assertEquals(Level.DEBUG, a.getEffectiveLevel());
- assertEquals(Level.DEBUG, ab.getEffectiveLevel());
-
- assertEquals(Level.DEBUG, root.getLevel());
- assertNull(a.getLevel());
- assertNull(ab.getLevel());
- }
-
- // http://jira.qos.ch/browse/LBCLASSIC-89
- @Test
- public void turboFilterStopOnReset() {
- NOPTurboFilter nopTF = new NOPTurboFilter();
- nopTF.start();
- lc.addTurboFilter(nopTF);
- assertTrue(nopTF.isStarted());
- lc.reset();
- assertFalse(nopTF.isStarted());
- }
-
- @Test
- public void resetTest_LBCORE_104() {
- lc.putProperty("keyA", "valA");
- lc.putObject("keyA", "valA");
- assertEquals("valA", lc.getProperty("keyA"));
- assertEquals("valA", lc.getObject("keyA"));
- lc.reset();
- assertNull(lc.getProperty("keyA"));
- assertNull(lc.getObject("keyA"));
- }
-
- @Test
- public void loggerNameEndingInDotOrDollarShouldWork() {
- {
- String loggerName = "toto.x.";
- Logger logger = lc.getLogger(loggerName);
- assertEquals(loggerName, logger.getName());
- }
-
- {
- String loggerName = "toto.x$";
- Logger logger = lc.getLogger(loggerName);
- assertEquals(loggerName, logger.getName());
- }
- }
-
- @Test
- public void levelResetTest() {
- Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- root.setLevel(Level.TRACE);
- assertTrue(root.isTraceEnabled());
- lc.reset();
- assertFalse(root.isTraceEnabled());
- assertTrue(root.isDebugEnabled());
- }
-
- @Test
- public void evaluatorMapPostReset() {
- lc.reset();
- assertNotNull(lc.getObject(CoreConstants.EVALUATOR_MAP));
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void collisionMapsPostReset() {
- lc.reset();
-
- Map<String, String> fileCollisions = (Map<String, String>) lc.getObject(CoreConstants.FA_FILENAME_COLLISION_MAP);
- assertNotNull(fileCollisions);
- assertTrue(fileCollisions.isEmpty());
-
- Map<String, FileNamePattern> filenamePatternCollisionMap = (Map<String, FileNamePattern>) lc.getObject(CoreConstants.RFA_FILENAME_PATTERN_COLLISION_MAP);
- assertNotNull(filenamePatternCollisionMap);
- assertTrue(filenamePatternCollisionMap.isEmpty());
- }
-
- // http://jira.qos.ch/browse/LOGBACK-142
- @Test
- public void concurrentModification() {
- final int runLen = 100;
- Thread thread = new Thread(new Runnable() {
- public void run() {
- for (int i = 0; i < runLen; i++) {
- lc.getLogger("a" + i);
- Thread.yield();
- }
- }
- });
- thread.start();
-
- for (int i = 0; i < runLen; i++) {
- lc.putProperty("a" + i, "val");
- Thread.yield();
- }
- }
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerMessageFormattingTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerMessageFormattingTest.java
index 46d27ac..390852a 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerMessageFormattingTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerMessageFormattingTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,62 +23,64 @@ import ch.qos.logback.core.read.ListAppender;
public class LoggerMessageFormattingTest {
- LoggerContext lc;
- ListAppender<ILoggingEvent> listAppender;
+ LoggerContext lc;
+ ListAppender<ILoggingEvent> listAppender;
- @Before
- public void setUp() {
- lc = new LoggerContext();
- Logger logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- listAppender = new ListAppender<ILoggingEvent>();
- listAppender.setContext(lc);
- listAppender.start();
- logger.addAppender(listAppender);
- }
+ @Before
+ public void setUp() {
+ lc = new LoggerContext();
+ Logger logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+ listAppender = new ListAppender<ILoggingEvent>();
+ listAppender.setContext(lc);
+ listAppender.start();
+ logger.addAppender(listAppender);
+ }
- @Test
- public void testFormattingOneArg() {
- Logger logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- logger.debug("{}", new Integer(12));
- ILoggingEvent event = (ILoggingEvent) listAppender.list.get(0);
- assertEquals("12", event.getFormattedMessage());
- }
+ @Test
+ public void testFormattingOneArg() {
+ Logger logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+ logger.debug("{}", new Integer(12));
+ ILoggingEvent event = (ILoggingEvent) listAppender.list.get(0);
+ assertEquals("12", event.getFormattedMessage());
+ }
- @Test
- public void testFormattingTwoArg() {
- Logger logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- logger.debug("{}-{}", new Integer(12), new Integer(13));
- ILoggingEvent event = (ILoggingEvent) listAppender.list.get(0);
- assertEquals("12-13", event.getFormattedMessage());
- }
+ @Test
+ public void testFormattingTwoArg() {
+ Logger logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+ logger.debug("{}-{}", new Integer(12), new Integer(13));
+ ILoggingEvent event = (ILoggingEvent) listAppender.list.get(0);
+ assertEquals("12-13", event.getFormattedMessage());
+ }
- @Test
- public void testNoFormatting() {
- Logger logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- logger.debug("test", new Integer(12), new Integer(13));
- ILoggingEvent event = (ILoggingEvent) listAppender.list.get(0);
- assertEquals("test", event.getFormattedMessage());
- }
+ @Test
+ public void testNoFormatting() {
+ Logger logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+ logger.debug("test", new Integer(12), new Integer(13));
+ ILoggingEvent event = (ILoggingEvent) listAppender.list.get(0);
+ assertEquals("test", event.getFormattedMessage());
+ }
+
+ @Test
+ public void testNoFormatting2() {
+ Logger logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+ logger.debug("test");
+ ILoggingEvent event = (ILoggingEvent) listAppender.list.get(0);
+ assertEquals("test", event.getFormattedMessage());
+ }
+
+ @Test
+ public void testMessageConverter() {
+ Logger logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+ logger.debug("{}", 12);
+ ILoggingEvent event = (ILoggingEvent) listAppender.list.get(0);
+ PatternLayout layout = new PatternLayout();
+ layout.setContext(lc);
+ layout.setPattern("%m");
+ layout.start();
+ String formattedMessage = layout.doLayout(event);
+ assertEquals("12", formattedMessage);
+ }
- @Test
- public void testNoFormatting2() {
- Logger logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- logger.debug("test");
- ILoggingEvent event = (ILoggingEvent) listAppender.list.get(0);
- assertEquals("test", event.getFormattedMessage());
- }
- @Test
- public void testMessageConverter() {
- Logger logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- logger.debug("{}", 12);
- ILoggingEvent event = (ILoggingEvent) listAppender.list.get(0);
- PatternLayout layout = new PatternLayout();
- layout.setContext(lc);
- layout.setPattern("%m");
- layout.start();
- String formattedMessage = layout.doLayout(event);
- assertEquals("12", formattedMessage);
- }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerPerfTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerPerfTest.java
index c6c825f..98de0eb 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerPerfTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerPerfTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,225 +27,235 @@ import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import ch.qos.logback.core.helpers.NOPAppender;
+
@Ignore
public class LoggerPerfTest {
- static final long NANOS_IN_ONE_SEC = 1000 * 1000 * 1000L;
- static long NORMAL_RUN_LENGTH = 1 * 1000 * 1000;
- static long SHORTENED_RUN_LENGTH = 500 * 1000;
-
- LoggerContext lc = new LoggerContext();
- Logger lbLogger = lc.getLogger(this.getClass());
- org.slf4j.Logger logger = lbLogger;
-
- @Before
- public void setUp() throws Exception {
+ static final long NANOS_IN_ONE_SEC = 1000 * 1000 * 1000L;
+ static long NORMAL_RUN_LENGTH = 1 * 1000 * 1000;
+ static long SHORTENED_RUN_LENGTH = 500 * 1000;
+
+ LoggerContext lc = new LoggerContext();
+ Logger lbLogger = lc.getLogger(this.getClass());
+ org.slf4j.Logger logger = lbLogger;
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ // ===========================================================================
+ @Test
+ public void durationOfDisabledLogsWith_1_NOPFilter() {
+ double avg = computeDurationOfDisabledLogsWith_1_NOPFilter(1,
+ NORMAL_RUN_LENGTH);
+ System.out.println("durationOfDisabledLogsWith_1_NOPFilter=" + avg);
+ long referencePerf = 60;
+
+ BogoPerf.assertDuration(avg, referencePerf, CoreConstants.REFERENCE_BIPS);
+ }
+
+ double computeDurationOfDisabledLogsWith_1_NOPFilter(int numOfFilters,
+ long len) {
+ for (int i = 0; i < numOfFilters; i++) {
+ lc.addTurboFilter(new NOPTurboFilter());
}
-
- // ===========================================================================
- @Test
- public void durationOfDisabledLogsWith_1_NOPFilter() {
- double avg = computeDurationOfDisabledLogsWith_1_NOPFilter(1, NORMAL_RUN_LENGTH);
- System.out.println("durationOfDisabledLogsWith_1_NOPFilter=" + avg);
- long referencePerf = 60;
-
- BogoPerf.assertDuration(avg, referencePerf, CoreConstants.REFERENCE_BIPS);
+ lbLogger.setLevel(Level.OFF);
+ for (long i = 0; i < len; i++)
+ logger.debug("Toto");
+
+ long start = System.nanoTime();
+ for (long i = 0; i < len; i++)
+ logger.debug("Toto");
+
+ return (System.nanoTime() - start) / len;
+ }
+
+ // ===========================================================================
+ @Test
+ public void durationOfIsDebugEnabled() {
+ double avg = computedurationOfIsDebugEnabled(10 * NORMAL_RUN_LENGTH);
+ System.out.println("durationOfIsDebugEnabled=" + avg);
+
+ long referencePerf = 15;
+ BogoPerf.assertDuration(avg, referencePerf, CoreConstants.REFERENCE_BIPS);
+ }
+
+ double computedurationOfIsDebugEnabled(final long len) {
+ lbLogger.setLevel(Level.OFF);
+ for (long i = 0; i < len; i++)
+ logger.isDebugEnabled();
+ Thread.yield();
+ for (long i = 0; i < len; i++)
+ logger.isDebugEnabled();
+
+ long start = System.nanoTime();
+ for (long i = 0; i < len; i++)
+ logger.isDebugEnabled();
+ return (System.nanoTime() - start) / len;
+ }
+
+ // ===========================================================================
+ @Test
+ public void durationOfDisabledLog_NoParameters() {
+ double avg = computeDurationOfDisabledLog_NoParameters(10 * NORMAL_RUN_LENGTH);
+ System.out.println("durationOfDisabledLog_NoParameters=" + avg);
+
+ long referencePerf = 18;
+ BogoPerf.assertDuration(avg, referencePerf, CoreConstants.REFERENCE_BIPS);
+ }
+
+ double computeDurationOfDisabledLog_NoParameters(final long len) {
+ lbLogger.setLevel(Level.OFF);
+ for (long i = 0; i < len; i++)
+ logger.debug("Toto");
+ Thread.yield();
+ for (long i = 0; i < len; i++)
+ logger.debug("Toto");
+ Thread.yield();
+
+ long start = System.nanoTime();
+ for (long i = 0; i < len; i++)
+ logger.debug("Toto");
+ return (System.nanoTime() - start) / len;
+ }
+
+ // ===========================================================================
+
+ @Test
+ public void durationOfDisabledLog_1_Parameter() {
+ double avgDuration = computeDurationOfDisabledLog_1_Parameter(NORMAL_RUN_LENGTH);
+ System.out.println("durationOfDisabledLog_1_Parameter=" + avgDuration);
+
+ long referencePerf = 30;
+ BogoPerf.assertDuration(avgDuration, referencePerf,
+ CoreConstants.REFERENCE_BIPS);
+ }
+
+ double computeDurationOfDisabledLog_1_Parameter(long len) {
+ lbLogger.setLevel(Level.OFF);
+ final Object o = new Object();
+ for (long i = 0; i < len; i++)
+ logger.debug("Toto {}", o);
+
+ long start = System.nanoTime();
+ for (long i = 0; i < len; i++)
+ logger.debug("Toto {}", o);
+
+ long end = System.nanoTime();
+ return (end - start) / len;
+ }
+
+ // ===========================================================================
+
+ @Test
+ public void durationOfEnabledLog() {
+ if (EnvUtilForTests.isLinux()) {
+ // the JIT on Linux behaves very differently
+ return;
}
-
- double computeDurationOfDisabledLogsWith_1_NOPFilter(int numOfFilters, long len) {
- for (int i = 0; i < numOfFilters; i++) {
- lc.addTurboFilter(new NOPTurboFilter());
- }
- lbLogger.setLevel(Level.OFF);
- for (long i = 0; i < len; i++)
- logger.debug("Toto");
-
- long start = System.nanoTime();
- for (long i = 0; i < len; i++)
- logger.debug("Toto");
-
- return (System.nanoTime() - start) / len;
- }
-
- // ===========================================================================
- @Test
- public void durationOfIsDebugEnabled() {
- double avg = computedurationOfIsDebugEnabled(10 * NORMAL_RUN_LENGTH);
- System.out.println("durationOfIsDebugEnabled=" + avg);
-
- long referencePerf = 15;
- BogoPerf.assertDuration(avg, referencePerf, CoreConstants.REFERENCE_BIPS);
- }
-
- double computedurationOfIsDebugEnabled(final long len) {
- lbLogger.setLevel(Level.OFF);
- for (long i = 0; i < len; i++)
- logger.isDebugEnabled();
- Thread.yield();
- for (long i = 0; i < len; i++)
- logger.isDebugEnabled();
-
- long start = System.nanoTime();
- for (long i = 0; i < len; i++)
- logger.isDebugEnabled();
- return (System.nanoTime() - start) / len;
+ double avgDuration = computeDurationOfEnabledLog(SHORTENED_RUN_LENGTH);
+ System.out.println("durationOfEnabledLog=" + avgDuration);
+
+ long referencePerf = 800;
+ BogoPerf.assertDuration(avgDuration, referencePerf,
+ CoreConstants.REFERENCE_BIPS);
+ }
+
+ double computeDurationOfEnabledLog(long len) {
+ lbLogger.setLevel(Level.ALL);
+
+ NOPAppender<ILoggingEvent> nopAppender = new NOPAppender<ILoggingEvent>();
+ nopAppender.start();
+ ((ch.qos.logback.classic.Logger) logger).addAppender(nopAppender);
+ for (long i = 0; i < len; i++) {
+ logger.debug("Toto");
}
-
- // ===========================================================================
- @Test
- public void durationOfDisabledLog_NoParameters() {
- double avg = computeDurationOfDisabledLog_NoParameters(10 * NORMAL_RUN_LENGTH);
- System.out.println("durationOfDisabledLog_NoParameters=" + avg);
-
- long referencePerf = 18;
- BogoPerf.assertDuration(avg, referencePerf, CoreConstants.REFERENCE_BIPS);
+ long start = System.nanoTime();
+ for (long i = 0; i < len; i++) {
+ logger.debug("Toto");
}
-
- double computeDurationOfDisabledLog_NoParameters(final long len) {
- lbLogger.setLevel(Level.OFF);
- for (long i = 0; i < len; i++)
- logger.debug("Toto");
- Thread.yield();
- for (long i = 0; i < len; i++)
- logger.debug("Toto");
- Thread.yield();
-
- long start = System.nanoTime();
- for (long i = 0; i < len; i++)
- logger.debug("Toto");
- return (System.nanoTime() - start) / len;
+ long end = System.nanoTime();
+ return (end - start) / len;
+ }
+
+ // ===========================================================================
+
+ @Test
+ public void testThreadedLogging() throws InterruptedException {
+ SleepAppender<ILoggingEvent> appender = new SleepAppender<ILoggingEvent>();
+
+ int MILLIS_PER_CALL = 250;
+ int NANOS_PER_CALL = 250 * 1000 * 1000;
+
+ appender.setDuration(MILLIS_PER_CALL);
+ appender.start();
+
+ lbLogger.addAppender(appender);
+ lbLogger.setLevel(Level.DEBUG);
+ long start;
+ long end;
+ int threadCount = 10;
+ int iterCount = 5;
+ TestRunner[] threads = new TestRunner[threadCount];
+ for (int i = 0; i < threads.length; ++i) {
+ threads[i] = new TestRunner(logger, iterCount);
}
-
- // ===========================================================================
-
- @Test
- public void durationOfDisabledLog_1_Parameter() {
- double avgDuration = computeDurationOfDisabledLog_1_Parameter(NORMAL_RUN_LENGTH);
- System.out.println("durationOfDisabledLog_1_Parameter=" + avgDuration);
-
- long referencePerf = 30;
- BogoPerf.assertDuration(avgDuration, referencePerf, CoreConstants.REFERENCE_BIPS);
+ start = System.nanoTime();
+ for (Thread thread : threads) {
+ thread.start();
}
-
- double computeDurationOfDisabledLog_1_Parameter(long len) {
- lbLogger.setLevel(Level.OFF);
- final Object o = new Object();
- for (long i = 0; i < len; i++)
- logger.debug("Toto {}", o);
-
- long start = System.nanoTime();
- for (long i = 0; i < len; i++)
- logger.debug("Toto {}", o);
-
- long end = System.nanoTime();
- return (end - start) / len;
+ for (TestRunner thread : threads) {
+ thread.join();
}
-
- // ===========================================================================
-
- @Test
- public void durationOfEnabledLog() {
- if (EnvUtilForTests.isLinux()) {
- // the JIT on Linux behaves very differently
- return;
- }
- double avgDuration = computeDurationOfEnabledLog(SHORTENED_RUN_LENGTH);
- System.out.println("durationOfEnabledLog=" + avgDuration);
-
- long referencePerf = 800;
- BogoPerf.assertDuration(avgDuration, referencePerf, CoreConstants.REFERENCE_BIPS);
+ end = System.nanoTime();
+ double tolerance = threadCount * .125; // Very little thread contention
+ // should occur in this test.
+ double max = ((((double) NANOS_PER_CALL) / NANOS_IN_ONE_SEC) * iterCount)
+ * tolerance;
+ double serialized = (((double) NANOS_PER_CALL) / NANOS_IN_ONE_SEC)
+ * iterCount * threadCount;
+ double actual = ((double) (end - start)) / NANOS_IN_ONE_SEC;
+ System.out
+ .printf(
+ "Sleep duration: %,.4f seconds. Max expected: %,.4f seconds, Serialized: %,.4f\n",
+ actual, max, serialized);
+ assertTrue("Exceeded maximum expected time.", actual < max);
+ }
+
+ // ============================================================
+ private static class TestRunner extends Thread {
+ private org.slf4j.Logger logger;
+ private long len;
+
+ public TestRunner(org.slf4j.Logger logger, long len) {
+ this.logger = logger;
+ this.len = len;
}
- double computeDurationOfEnabledLog(long len) {
- lbLogger.setLevel(Level.ALL);
-
- NOPAppender<ILoggingEvent> nopAppender = new NOPAppender<ILoggingEvent>();
- nopAppender.start();
- ((ch.qos.logback.classic.Logger) logger).addAppender(nopAppender);
- for (long i = 0; i < len; i++) {
- logger.debug("Toto");
- }
- long start = System.nanoTime();
- for (long i = 0; i < len; i++) {
- logger.debug("Toto");
- }
- long end = System.nanoTime();
- return (end - start) / len;
+ public void run() {
+ Thread.yield();
+ for (long i = 0; i < len; i++) {
+ logger.debug("Toto");
+ }
}
+ }
- // ===========================================================================
-
- @Test
- public void testThreadedLogging() throws InterruptedException {
- SleepAppender<ILoggingEvent> appender = new SleepAppender<ILoggingEvent>();
-
- int MILLIS_PER_CALL = 250;
- int NANOS_PER_CALL = 250 * 1000 * 1000;
-
- appender.setDuration(MILLIS_PER_CALL);
- appender.start();
-
- lbLogger.addAppender(appender);
- lbLogger.setLevel(Level.DEBUG);
- long start;
- long end;
- int threadCount = 10;
- int iterCount = 5;
- TestRunner[] threads = new TestRunner[threadCount];
- for (int i = 0; i < threads.length; ++i) {
- threads[i] = new TestRunner(logger, iterCount);
- }
- start = System.nanoTime();
- for (Thread thread : threads) {
- thread.start();
- }
- for (TestRunner thread : threads) {
- thread.join();
- }
- end = System.nanoTime();
- double tolerance = threadCount * .125; // Very little thread contention
- // should occur in this test.
- double max = ((((double) NANOS_PER_CALL) / NANOS_IN_ONE_SEC) * iterCount) * tolerance;
- double serialized = (((double) NANOS_PER_CALL) / NANOS_IN_ONE_SEC) * iterCount * threadCount;
- double actual = ((double) (end - start)) / NANOS_IN_ONE_SEC;
- System.out.printf("Sleep duration: %,.4f seconds. Max expected: %,.4f seconds, Serialized: %,.4f\n", actual, max, serialized);
- assertTrue("Exceeded maximum expected time.", actual < max);
- }
+ // ============================================================
+ public static class SleepAppender<E> extends UnsynchronizedAppenderBase<E> {
+ private static long duration = 500;
- // ============================================================
- private static class TestRunner extends Thread {
- private org.slf4j.Logger logger;
- private long len;
-
- public TestRunner(org.slf4j.Logger logger, long len) {
- this.logger = logger;
- this.len = len;
- }
-
- public void run() {
- Thread.yield();
- for (long i = 0; i < len; i++) {
- logger.debug("Toto");
- }
- }
+ public void setDuration(long millis) {
+ duration = millis;
}
- // ============================================================
- public static class SleepAppender<E> extends UnsynchronizedAppenderBase<E> {
- private static long duration = 500;
-
- public void setDuration(long millis) {
- duration = millis;
- }
-
- @Override
- protected void append(E eventObject) {
- try {
- Thread.sleep(duration);
- } catch (InterruptedException ie) {
- // Ignore
- }
- }
+ @Override
+ protected void append(E eventObject) {
+ try {
+ Thread.sleep(duration);
+ } catch (InterruptedException ie) {
+ // Ignore
+ }
}
- // ============================================================
+ }
+ // ============================================================
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerSerializationTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerSerializationTest.java
index dd8b2e6..ec20347 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerSerializationTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerSerializationTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,129 +26,129 @@ import static org.junit.Assert.assertTrue;
public class LoggerSerializationTest {
- static final String SERIALIZATION_PREFIX = CoreTestConstants.TEST_INPUT_PREFIX + "/serialization/";
-
- // force SLF4J initialization for subsequent Logger readResolce ooperaiton
- org.slf4j.Logger unused = LoggerFactory.getLogger(this.getClass());
- LoggerContext lc;
- Logger logger;
-
- ByteArrayOutputStream bos;
- ObjectOutputStream oos;
- ObjectInputStream inputStream;
-
- @Before
- public void setUp() throws Exception {
- lc = new LoggerContext();
- lc.setName("testContext");
- logger = lc.getLogger(LoggerSerializationTest.class);
- // create the byte output stream
- bos = new ByteArrayOutputStream();
- oos = new ObjectOutputStream(bos);
- }
-
- @After
- public void tearDown() throws Exception {
- lc = null;
- logger = null;
- }
-
- @Test
- public void basicSerialization() throws IOException, ClassNotFoundException {
- Foo foo = new Foo(logger);
- foo.doFoo();
- Foo fooBack = writeAndRead(foo);
- fooBack.doFoo();
- }
-
- @Test
- public void deepTreeSerialization() throws IOException {
- // crate a tree of loggers under "aaaaaaaa"
- Logger a = lc.getLogger("aaaaaaaa");
- lc.getLogger("aaaaaaaa.a");
- lc.getLogger("aaaaaaaa.a.a");
- lc.getLogger("aaaaaaaa.a.b");
- lc.getLogger("aaaaaaaa.a.c");
- lc.getLogger("aaaaaaaa.a.d");
-
- lc.getLogger("aaaaaaaa.b");
- lc.getLogger("aaaaaaaa.b.a");
- lc.getLogger("aaaaaaaa.b.b");
- lc.getLogger("aaaaaaaa.b.c");
- lc.getLogger("aaaaaaaa.b.d");
-
- lc.getLogger("aaaaaaaa.c");
- lc.getLogger("aaaaaaaa.c.a");
- lc.getLogger("aaaaaaaa.c.b");
- lc.getLogger("aaaaaaaa.c.c");
- lc.getLogger("aaaaaaaa.c.d");
-
- lc.getLogger("aaaaaaaa.d");
- lc.getLogger("aaaaaaaa.d.a");
- lc.getLogger("aaaaaaaa.d.b");
- lc.getLogger("aaaaaaaa.d.c");
- lc.getLogger("aaaaaaaa.d.d");
-
- Logger b = lc.getLogger("b");
-
- writeObject(oos, a);
- oos.close();
- int sizeA = bos.size();
-
- bos = new ByteArrayOutputStream();
- oos = new ObjectOutputStream(bos);
-
- writeObject(oos, b);
- oos.close();
- int sizeB = bos.size();
-
- assertTrue("serialized logger should be less than 100 bytes", sizeA < 100);
- // logger tree should not influnce serialization
- assertTrue("serialized loggers should be nearly the same size a:" + sizeA + ", sizeB:" + sizeB, (sizeA - sizeB) < 10);
- }
-
- private Foo writeAndRead(Foo foo) throws IOException, ClassNotFoundException {
- writeObject(oos, foo);
- ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
- inputStream = new ObjectInputStream(bis);
- Foo fooBack = readFooObject(inputStream);
- inputStream.close();
- return fooBack;
- }
-
- Foo readFooObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
- return (Foo) readObject(inputStream);
- }
-
- private Object readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
- return inputStream.readObject();
- }
-
- private void writeObject(ObjectOutputStream oos, Object o) throws IOException {
- oos.writeObject(o);
- oos.flush();
- oos.close();
- }
-
- @Test
- public void testCompatibilityWith_v1_0_11() throws IOException, ClassNotFoundException {
- FileInputStream fis = new FileInputStream(SERIALIZATION_PREFIX + "logger_v1.0.11.ser");
- ObjectInputStream ois = new ObjectInputStream(fis);
- Logger a = (Logger) ois.readObject();
- ois.close();
- assertEquals("a", a.getName());
- }
-
- // interestingly enough, logback 1.0.11 and earlier can also read loggers serialized by 1.0.12.
- // fields not serialized are set to their default values and since the fields are not
- // used, it works out nicely
- @Test
- public void testCompatibilityWith_v1_0_12() throws IOException, ClassNotFoundException {
- FileInputStream fis = new FileInputStream(SERIALIZATION_PREFIX + "logger_v1.0.12.ser");
- ObjectInputStream ois = new ObjectInputStream(fis);
- Logger a = (Logger) ois.readObject();
- ois.close();
- assertEquals("a", a.getName());
- }
+ static final String SERIALIZATION_PREFIX = CoreTestConstants.TEST_INPUT_PREFIX+"/serialization/";
+
+ // force SLF4J initialization for subsequent Logger readResolce ooperaiton
+ org.slf4j.Logger unused = LoggerFactory.getLogger(this.getClass());
+ LoggerContext lc;
+ Logger logger;
+
+ ByteArrayOutputStream bos;
+ ObjectOutputStream oos;
+ ObjectInputStream inputStream;
+
+ @Before
+ public void setUp() throws Exception {
+ lc = new LoggerContext();
+ lc.setName("testContext");
+ logger = lc.getLogger(LoggerSerializationTest.class);
+ // create the byte output stream
+ bos = new ByteArrayOutputStream();
+ oos = new ObjectOutputStream(bos);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ lc = null;
+ logger = null;
+ }
+
+ @Test
+ public void basicSerialization() throws IOException, ClassNotFoundException {
+ Foo foo = new Foo(logger);
+ foo.doFoo();
+ Foo fooBack = writeAndRead(foo);
+ fooBack.doFoo();
+ }
+
+ @Test
+ public void deepTreeSerialization() throws IOException {
+ // crate a tree of loggers under "aaaaaaaa"
+ Logger a = lc.getLogger("aaaaaaaa");
+ lc.getLogger("aaaaaaaa.a");
+ lc.getLogger("aaaaaaaa.a.a");
+ lc.getLogger("aaaaaaaa.a.b");
+ lc.getLogger("aaaaaaaa.a.c");
+ lc.getLogger("aaaaaaaa.a.d");
+
+ lc.getLogger("aaaaaaaa.b");
+ lc.getLogger("aaaaaaaa.b.a");
+ lc.getLogger("aaaaaaaa.b.b");
+ lc.getLogger("aaaaaaaa.b.c");
+ lc.getLogger("aaaaaaaa.b.d");
+
+ lc.getLogger("aaaaaaaa.c");
+ lc.getLogger("aaaaaaaa.c.a");
+ lc.getLogger("aaaaaaaa.c.b");
+ lc.getLogger("aaaaaaaa.c.c");
+ lc.getLogger("aaaaaaaa.c.d");
+
+ lc.getLogger("aaaaaaaa.d");
+ lc.getLogger("aaaaaaaa.d.a");
+ lc.getLogger("aaaaaaaa.d.b");
+ lc.getLogger("aaaaaaaa.d.c");
+ lc.getLogger("aaaaaaaa.d.d");
+
+ Logger b = lc.getLogger("b");
+
+ writeObject(oos, a);
+ oos.close();
+ int sizeA = bos.size();
+
+ bos = new ByteArrayOutputStream();
+ oos = new ObjectOutputStream(bos);
+
+ writeObject(oos, b);
+ oos.close();
+ int sizeB = bos.size();
+
+ assertTrue("serialized logger should be less than 100 bytes", sizeA < 100);
+ // logger tree should not influnce serialization
+ assertTrue("serialized loggers should be nearly the same size a:" + sizeA + ", sizeB:" + sizeB, (sizeA - sizeB) < 10);
+ }
+
+ private Foo writeAndRead(Foo foo) throws IOException,
+ ClassNotFoundException {
+ writeObject(oos, foo);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ inputStream = new ObjectInputStream(bis);
+ Foo fooBack = readFooObject(inputStream);
+ inputStream.close();
+ return fooBack;
+ }
+
+ Foo readFooObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
+ return (Foo) readObject(inputStream);
+ }
+ private Object readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
+ return inputStream.readObject();
+ }
+
+ private void writeObject(ObjectOutputStream oos, Object o) throws IOException {
+ oos.writeObject(o);
+ oos.flush();
+ oos.close();
+ }
+
+ @Test
+ public void testCompatibilityWith_v1_0_11 () throws IOException, ClassNotFoundException {
+ FileInputStream fis = new FileInputStream(SERIALIZATION_PREFIX+"logger_v1.0.11.ser");
+ ObjectInputStream ois = new ObjectInputStream(fis);
+ Logger a = (Logger) ois.readObject();
+ ois.close();
+ assertEquals("a", a.getName());
+ }
+
+ // interestingly enough, logback 1.0.11 and earlier can also read loggers serialized by 1.0.12.
+ // fields not serialized are set to their default values and since the fields are not
+ // used, it works out nicely
+ @Test
+ public void testCompatibilityWith_v1_0_12 () throws IOException, ClassNotFoundException {
+ FileInputStream fis = new FileInputStream(SERIALIZATION_PREFIX+"logger_v1.0.12.ser");
+ ObjectInputStream ois = new ObjectInputStream(fis);
+ Logger a = (Logger) ois.readObject();
+ ois.close();
+ assertEquals("a", a.getName());
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerTest.java
index cd63b1d..9a2d2b2 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,196 +30,198 @@ import ch.qos.logback.core.status.Status;
public class LoggerTest {
- LoggerContext lc = new LoggerContext();
- Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- Logger loggerTest = lc.getLogger(LoggerTest.class);
+ LoggerContext lc = new LoggerContext();
+ Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+ Logger loggerTest = lc.getLogger(LoggerTest.class);
- ListAppender<ILoggingEvent> listAppender = new ListAppender<ILoggingEvent>();
-
- @Test
- public void smoke() {
- ListAppender<ILoggingEvent> listAppender = new ListAppender<ILoggingEvent>();
- listAppender.start();
- root.addAppender(listAppender);
- Logger logger = lc.getLogger(LoggerTest.class);
- assertEquals(0, listAppender.list.size());
- logger.debug("hello");
- assertEquals(1, listAppender.list.size());
- }
-
- @Test
- public void testNoStart() {
- // listAppender.start();
- listAppender.setContext(lc);
- root.addAppender(listAppender);
- Logger logger = lc.getLogger(LoggerTest.class);
- logger.debug("hello");
-
- List<Status> statusList = lc.getStatusManager().getCopyOfStatusList();
- Status s0 = statusList.get(0);
- assertEquals(Status.WARN, s0.getLevel());
- assertTrue(s0.getMessage().startsWith("Attempted to append to non started"));
- }
-
- @Test
- public void testAdditive() {
- listAppender.start();
- root.addAppender(listAppender);
- loggerTest.addAppender(listAppender);
- loggerTest.setAdditive(false);
- loggerTest.debug("hello");
- // 1 instead of two, since logger is not additive
- assertEquals(1, listAppender.list.size());
- }
-
- @Test
- public void testRootLogger() {
- Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
- LoggerContext lc = logger.getLoggerContext();
-
- assertNotNull("Returned logger is null", logger);
- assertEquals("Return logger isn't named root", logger.getName(), Logger.ROOT_LOGGER_NAME);
- assertTrue("logger instances should be indentical", logger == lc.root);
- }
-
- @Test
- public void testBasicFiltering() throws Exception {
- listAppender.start();
- root.addAppender(listAppender);
- root.setLevel(Level.INFO);
- loggerTest.debug("x");
- assertEquals(0, listAppender.list.size());
- loggerTest.info("x");
- loggerTest.warn("x");
- loggerTest.error("x");
- assertEquals(3, listAppender.list.size());
- }
-
- void checkLevelThreshold(Logger logger, Level threshold) {
-
- if (Level.ERROR_INT >= threshold.levelInt) {
- assertTrue(logger.isErrorEnabled());
- assertTrue(logger.isEnabledFor(Level.ERROR));
- } else {
- assertFalse(logger.isErrorEnabled());
- assertFalse(logger.isEnabledFor(Level.ERROR));
- }
-
- if (Level.WARN_INT >= threshold.levelInt) {
- assertTrue(logger.isWarnEnabled());
- assertTrue(logger.isEnabledFor(Level.WARN));
- } else {
- assertFalse(logger.isWarnEnabled());
- assertFalse(logger.isEnabledFor(Level.WARN));
- }
- if (Level.INFO_INT >= threshold.levelInt) {
- assertTrue(logger.isInfoEnabled());
- assertTrue(logger.isEnabledFor(Level.INFO));
- } else {
- assertFalse(logger.isInfoEnabled());
- assertFalse(logger.isEnabledFor(Level.INFO));
- }
- if (Level.DEBUG_INT >= threshold.levelInt) {
- assertTrue(logger.isDebugEnabled());
- assertTrue(logger.isEnabledFor(Level.DEBUG));
- } else {
- assertFalse(logger.isDebugEnabled());
- assertFalse(logger.isEnabledFor(Level.DEBUG));
- }
- if (Level.TRACE_INT >= threshold.levelInt) {
- assertTrue(logger.isTraceEnabled());
- assertTrue(logger.isEnabledFor(Level.TRACE));
- } else {
- assertFalse(logger.isTraceEnabled());
- assertFalse(logger.isEnabledFor(Level.TRACE));
- }
- }
-
- @Test
- public void innerClass_I() {
- root.setLevel(Level.DEBUG);
- Logger a = lc.getLogger("a");
- a.setLevel(Level.INFO);
- Logger a_b = lc.getLogger("a$b");
- assertEquals(Level.INFO, a_b.getEffectiveLevel());
- }
-
- @Test
- public void innerClass_II() {
- root.setLevel(Level.DEBUG);
- Logger a = lc.getLogger(this.getClass());
- a.setLevel(Level.INFO);
- Logger a_b = lc.getLogger(new Inner().getClass());
- assertEquals(Level.INFO, a_b.getEffectiveLevel());
- }
-
- class Inner {
- }
+ ListAppender<ILoggingEvent> listAppender = new ListAppender<ILoggingEvent>();
- @Test
- public void testEnabled_All() throws Exception {
- root.setLevel(Level.ALL);
- checkLevelThreshold(loggerTest, Level.ALL);
- }
-
- @Test
- public void testEnabled_Debug() throws Exception {
- root.setLevel(Level.DEBUG);
- checkLevelThreshold(loggerTest, Level.DEBUG);
- }
-
- @Test
- public void testEnabled_Info() throws Exception {
- root.setLevel(Level.INFO);
- checkLevelThreshold(loggerTest, Level.INFO);
- }
-
- @Test
- public void testEnabledX_Warn() throws Exception {
- root.setLevel(Level.WARN);
- checkLevelThreshold(loggerTest, Level.WARN);
- }
-
- public void testEnabledX_Errror() throws Exception {
- root.setLevel(Level.ERROR);
- checkLevelThreshold(loggerTest, Level.ERROR);
- }
-
- @Test
- public void testEnabledX_Off() throws Exception {
- root.setLevel(Level.OFF);
- checkLevelThreshold(loggerTest, Level.OFF);
- }
-
- @Test
- public void setRootLevelToNull() {
- try {
- root.setLevel(null);
- fail("The level of the root logger should not be settable to null");
- } catch (IllegalArgumentException e) {
- }
- }
-
- @Test
- public void setLevelToNull_A() {
- loggerTest.setLevel(null);
- assertEquals(root.getEffectiveLevel(), loggerTest.getEffectiveLevel());
- }
-
- @Test
- public void setLevelToNull_B() {
- loggerTest.setLevel(Level.DEBUG);
- loggerTest.setLevel(null);
- assertEquals(root.getEffectiveLevel(), loggerTest.getEffectiveLevel());
- }
-
- @Test
- public void setLevelToNull_LBCLASSIC_91() {
- loggerTest.setLevel(Level.DEBUG);
- ch.qos.logback.classic.Logger child = lc.getLogger(loggerTest.getName() + ".child");
- loggerTest.setLevel(null);
- assertEquals(root.getEffectiveLevel(), loggerTest.getEffectiveLevel());
- assertEquals(root.getEffectiveLevel(), child.getEffectiveLevel());
- }
+ @Test
+ public void smoke() {
+ ListAppender<ILoggingEvent> listAppender = new ListAppender<ILoggingEvent>();
+ listAppender.start();
+ root.addAppender(listAppender);
+ Logger logger = lc.getLogger(LoggerTest.class);
+ assertEquals(0, listAppender.list.size());
+ logger.debug("hello");
+ assertEquals(1, listAppender.list.size());
+ }
+
+ @Test
+ public void testNoStart() {
+ // listAppender.start();
+ listAppender.setContext(lc);
+ root.addAppender(listAppender);
+ Logger logger = lc.getLogger(LoggerTest.class);
+ logger.debug("hello");
+
+ List<Status> statusList = lc.getStatusManager().getCopyOfStatusList();
+ Status s0 = statusList.get(0);
+ assertEquals(Status.WARN, s0.getLevel());
+ assertTrue(s0.getMessage().startsWith("Attempted to append to non started"));
+ }
+
+ @Test
+ public void testAdditive() {
+ listAppender.start();
+ root.addAppender(listAppender);
+ loggerTest.addAppender(listAppender);
+ loggerTest.setAdditive(false);
+ loggerTest.debug("hello");
+ // 1 instead of two, since logger is not additive
+ assertEquals(1, listAppender.list.size());
+ }
+
+ @Test
+ public void testRootLogger() {
+ Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+ LoggerContext lc = logger.getLoggerContext();
+
+ assertNotNull("Returned logger is null", logger);
+ assertEquals("Return logger isn't named root", logger.getName(),
+ Logger.ROOT_LOGGER_NAME);
+ assertTrue("logger instances should be indentical", logger == lc.root);
+ }
+
+ @Test
+ public void testBasicFiltering() throws Exception {
+ listAppender.start();
+ root.addAppender(listAppender);
+ root.setLevel(Level.INFO);
+ loggerTest.debug("x");
+ assertEquals(0, listAppender.list.size());
+ loggerTest.info("x");
+ loggerTest.warn("x");
+ loggerTest.error("x");
+ assertEquals(3, listAppender.list.size());
+ }
+
+ void checkLevelThreshold(Logger logger, Level threshold) {
+
+ if (Level.ERROR_INT >= threshold.levelInt) {
+ assertTrue(logger.isErrorEnabled());
+ assertTrue(logger.isEnabledFor(Level.ERROR));
+ } else {
+ assertFalse(logger.isErrorEnabled());
+ assertFalse(logger.isEnabledFor(Level.ERROR));
+ }
+
+ if (Level.WARN_INT >= threshold.levelInt) {
+ assertTrue(logger.isWarnEnabled());
+ assertTrue(logger.isEnabledFor(Level.WARN));
+ } else {
+ assertFalse(logger.isWarnEnabled());
+ assertFalse(logger.isEnabledFor(Level.WARN));
+ }
+ if (Level.INFO_INT >= threshold.levelInt) {
+ assertTrue(logger.isInfoEnabled());
+ assertTrue(logger.isEnabledFor(Level.INFO));
+ } else {
+ assertFalse(logger.isInfoEnabled());
+ assertFalse(logger.isEnabledFor(Level.INFO));
+ }
+ if (Level.DEBUG_INT >= threshold.levelInt) {
+ assertTrue(logger.isDebugEnabled());
+ assertTrue(logger.isEnabledFor(Level.DEBUG));
+ } else {
+ assertFalse(logger.isDebugEnabled());
+ assertFalse(logger.isEnabledFor(Level.DEBUG));
+ }
+ if (Level.TRACE_INT >= threshold.levelInt) {
+ assertTrue(logger.isTraceEnabled());
+ assertTrue(logger.isEnabledFor(Level.TRACE));
+ } else {
+ assertFalse(logger.isTraceEnabled());
+ assertFalse(logger.isEnabledFor(Level.TRACE));
+ }
+ }
+
+ @Test
+ public void innerClass_I() {
+ root.setLevel(Level.DEBUG);
+ Logger a = lc.getLogger("a");
+ a.setLevel(Level.INFO);
+ Logger a_b = lc.getLogger("a$b");
+ assertEquals(Level.INFO, a_b.getEffectiveLevel());
+ }
+
+ @Test
+ public void innerClass_II() {
+ root.setLevel(Level.DEBUG);
+ Logger a = lc.getLogger(this.getClass());
+ a.setLevel(Level.INFO);
+ Logger a_b = lc.getLogger(new Inner().getClass());
+ assertEquals(Level.INFO, a_b.getEffectiveLevel());
+ }
+
+
+ class Inner {
+ }
+
+ @Test
+ public void testEnabled_All() throws Exception {
+ root.setLevel(Level.ALL);
+ checkLevelThreshold(loggerTest, Level.ALL);
+ }
+
+ @Test
+ public void testEnabled_Debug() throws Exception {
+ root.setLevel(Level.DEBUG);
+ checkLevelThreshold(loggerTest, Level.DEBUG);
+ }
+
+ @Test
+ public void testEnabled_Info() throws Exception {
+ root.setLevel(Level.INFO);
+ checkLevelThreshold(loggerTest, Level.INFO);
+ }
+
+ @Test
+ public void testEnabledX_Warn() throws Exception {
+ root.setLevel(Level.WARN);
+ checkLevelThreshold(loggerTest, Level.WARN);
+ }
+
+ public void testEnabledX_Errror() throws Exception {
+ root.setLevel(Level.ERROR);
+ checkLevelThreshold(loggerTest, Level.ERROR);
+ }
+
+ @Test
+ public void testEnabledX_Off() throws Exception {
+ root.setLevel(Level.OFF);
+ checkLevelThreshold(loggerTest, Level.OFF);
+ }
+
+ @Test
+ public void setRootLevelToNull() {
+ try {
+ root.setLevel(null);
+ fail("The level of the root logger should not be settable to null");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ @Test
+ public void setLevelToNull_A() {
+ loggerTest.setLevel(null);
+ assertEquals(root.getEffectiveLevel(), loggerTest.getEffectiveLevel());
+ }
+
+ @Test
+ public void setLevelToNull_B() {
+ loggerTest.setLevel(Level.DEBUG);
+ loggerTest.setLevel(null);
+ assertEquals(root.getEffectiveLevel(), loggerTest.getEffectiveLevel());
+ }
+
+ @Test
+ public void setLevelToNull_LBCLASSIC_91() {
+ loggerTest.setLevel(Level.DEBUG);
+ ch.qos.logback.classic.Logger child = lc.getLogger(loggerTest.getName() + ".child");
+ loggerTest.setLevel(null);
+ assertEquals(root.getEffectiveLevel(), loggerTest.getEffectiveLevel());
+ assertEquals(root.getEffectiveLevel(), child.getEffectiveLevel());
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerTestHelper.java b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerTestHelper.java
index 92b8f5c..94601be 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/LoggerTestHelper.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/LoggerTestHelper.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,17 +19,17 @@ import junit.framework.*;
public class LoggerTestHelper extends TestCase {
- static void assertNameEquals(Logger logger, String name) {
- assertNotNull(logger);
- assertEquals(name, logger.getName());
- }
- static void assertLevels(Level level, Logger logger, Level effectiveLevel) {
- if (level == null) {
- assertNull(logger.getLevel());
- } else {
- assertEquals(level, logger.getLevel());
- }
- assertEquals(effectiveLevel, logger.getEffectiveLevel());
+ static void assertNameEquals(Logger logger, String name) {
+ assertNotNull(logger);
+ assertEquals(name, logger.getName());
+ }
+ static void assertLevels(Level level, Logger logger, Level effectiveLevel) {
+ if(level == null) {
+ assertNull(logger.getLevel());
+ } else {
+ assertEquals(level, logger.getLevel());
}
+ assertEquals(effectiveLevel, logger.getEffectiveLevel());
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/MDCTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/MDCTest.java
index b27603f..28911c3 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/MDCTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/MDCTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,30 +23,30 @@ import org.slf4j.MDC;
public class MDCTest {
- @Test
- public void test() throws InterruptedException {
- MDCTestThread threadA = new MDCTestThread("a");
- threadA.start();
+ @Test
+ public void test() throws InterruptedException {
+ MDCTestThread threadA = new MDCTestThread("a");
+ threadA.start();
- MDCTestThread threadB = new MDCTestThread("b");
- threadB.start();
+ MDCTestThread threadB = new MDCTestThread("b");
+ threadB.start();
- threadA.join();
- threadB.join();
+ threadA.join();
+ threadB.join();
- assertNull(threadA.x0);
- assertEquals("a", threadA.x1);
- assertNull(threadA.x2);
+ assertNull(threadA.x0);
+ assertEquals("a", threadA.x1);
+ assertNull(threadA.x2);
- assertNull(threadB.x0);
- assertEquals("b", threadB.x1);
- assertNull(threadB.x2);
+ assertNull(threadB.x0);
+ assertEquals("b", threadB.x1);
+ assertNull(threadB.x2);
- }
-
- @Test
- public void testLBCLASSIC_98() {
- MDC.setContextMap(new HashMap<String, String>());
- }
+ }
+ @Test
+ public void testLBCLASSIC_98() {
+ MDC.setContextMap(new HashMap<String, String>());
+ }
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/MDCTestThread.java b/logback-classic/src/test/java/ch/qos/logback/classic/MDCTestThread.java
index 8c97aaf..e10e31d 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/MDCTestThread.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/MDCTestThread.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,24 +16,24 @@ package ch.qos.logback.classic;
import org.slf4j.MDC;
public class MDCTestThread extends Thread {
-
- String val;
-
- public MDCTestThread(String val) {
- super();
- this.val = val;
- }
-
- String x0;
- String x1;
- String x2;
-
- public void run() {
- x0 = MDC.get("x");
- MDC.put("x", val);
- x1 = MDC.get("x");
- MDC.clear();
- x2 = MDC.get("x");
- // System.out.println("Exiting "+val);
- }
-}
\ No newline at end of file
+
+ String val;
+
+ public MDCTestThread(String val) {
+ super();
+ this.val = val;
+ }
+
+ String x0;
+ String x1;
+ String x2;
+
+ public void run() {
+ x0 = MDC.get("x");
+ MDC.put("x", val);
+ x1 = MDC.get("x");
+ MDC.clear();
+ x2 = MDC.get("x");
+ //System.out.println("Exiting "+val);
+ }
+}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/PackageTest.java
index 784918d..31e61d1 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,8 +18,11 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ LoggerContextTest.class, LoggerContextConcurrentResetTest.class, LoggerPerfTest.class, ScenarioBasedLoggerContextTest.class,
- PatternLayoutTest.class, LoggerTest.class, LoggerSerializationTest.class, LoggerMessageFormattingTest.class, MDCTest.class,
- TurboFilteringInLoggerTest.class, AsyncAppenderTest.class })
+ at SuiteClasses({LoggerContextTest.class, LoggerPerfTest.class,
+ ScenarioBasedLoggerContextTest.class, PatternLayoutTest.class,
+ LoggerTest.class, LoggerSerializationTest.class,
+ LoggerMessageFormattingTest.class, MDCTest.class,
+ TurboFilteringInLoggerTest.class,
+ AsyncAppenderTest.class})
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/PatternLayoutTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/PatternLayoutTest.java
index 44bb567..faa058b 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/PatternLayoutTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/PatternLayoutTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -35,183 +35,190 @@ import static org.junit.Assert.*;
public class PatternLayoutTest extends AbstractPatternLayoutBaseTest<ILoggingEvent> {
- private PatternLayout pl = new PatternLayout();
- private LoggerContext lc = new LoggerContext();
- Logger logger = lc.getLogger(ConverterTest.class);
- Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+ private PatternLayout pl = new PatternLayout();
+ private LoggerContext lc = new LoggerContext();
+ Logger logger = lc.getLogger(ConverterTest.class);
+ Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+
+ ILoggingEvent le;
+
+ public PatternLayoutTest() {
+ super();
+ Exception ex = new Exception("Bogus exception");
+ le = makeLoggingEvent(ex);
+ }
+
+ @Before
+ public void setUp() {
+ pl.setContext(lc);
+ }
+
+ ILoggingEvent makeLoggingEvent(Exception ex) {
+ return new LoggingEvent(
+ ch.qos.logback.core.pattern.FormattingConverter.class.getName(),
+ logger, Level.INFO, "Some message", ex, null);
+ }
+
+ @Override
+ public ILoggingEvent getEventObject() {
+ return makeLoggingEvent(null);
+ }
+
+ public PatternLayoutBase<ILoggingEvent> getPatternLayoutBase() {
+ return new PatternLayout();
+ }
+
+ @Test
+ public void testOK() {
+ pl.setPattern("%d %le [%t] %lo{30} - %m%n");
+ pl.start();
+ String val = pl.doLayout(getEventObject());
+ // 2006-02-01 22:38:06,212 INFO [main] c.q.l.pattern.ConverterTest - Some
+ // message
+ //2010-12-29 19:04:26,137 INFO [pool-1-thread-47] c.q.l.c.pattern.ConverterTest - Some message
+ String regex = ISO_REGEX + " INFO " + MAIN_REGEX
+ + " c.q.l.c.pattern.ConverterTest - Some message\\s*";
+
+ assertTrue("val="+val, val.matches(regex));
+ }
+
+ @Test
+ public void testNoExeptionHandler() {
+ pl.setPattern("%m%n");
+ pl.start();
+ String val = pl.doLayout(le);
+ assertTrue(val.contains("java.lang.Exception: Bogus exception"));
+ }
+
+ @Test
+ public void testCompositePattern() {
+ pl.setPattern("%-56(%d %lo{20}) - %m%n");
+ pl.start();
+ String val = pl.doLayout(getEventObject());
+ // 2008-03-18 21:55:54,250 c.q.l.c.pattern.ConverterTest - Some message
+ String regex = ISO_REGEX
+ + " c.q.l.c.p.ConverterTest - Some message\\s*";
+ assertTrue(val.matches(regex));
+ }
+
+ @Test
+ public void contextProperty() {
+ pl.setPattern("%property{a}");
+ pl.start();
+ lc.putProperty("a", "b");
+
+ String val = pl.doLayout(getEventObject());
+ assertEquals("b", val);
+ }
+
+ @Test
+ public void testNopExeptionHandler() {
+ pl.setPattern("%nopex %m%n");
+ pl.start();
+ String val = pl.doLayout(le);
+ assertTrue(!val.contains("java.lang.Exception: Bogus exception"));
+ }
+
+ @Test
+ public void testWithParenthesis() {
+ pl.setPattern("\\(%msg:%msg\\) %msg");
+ pl.start();
+ le = makeLoggingEvent(null);
+ String val = pl.doLayout(le);
+ // System.out.println("VAL == " + val);
+ assertEquals("(Some message:Some message) Some message", val);
+ }
+
+ @Test
+ public void testWithLettersComingFromLog4j() {
+ // Letters: p = level and c = logger
+ pl.setPattern("%d %p [%t] %c{30} - %m%n");
+ pl.start();
+ String val = pl.doLayout(getEventObject());
+ // 2006-02-01 22:38:06,212 INFO [main] c.q.l.pattern.ConverterTest - Some
+ // message
+ String regex = ClassicTestConstants.ISO_REGEX + " INFO " + MAIN_REGEX
+ + " c.q.l.c.pattern.ConverterTest - Some message\\s*";
+ assertTrue(val.matches(regex));
+ }
+
+ @Test
+ public void mdcWithDefaultValue() {
+ String pattern = "%msg %mdc{foo} %mdc{bar:-[null]}";
+ pl.setPattern(OptionHelper.substVars(pattern, lc));
+ pl.start();
+ MDC.put("foo", "foo");
+ try {
+ String val = pl.doLayout(getEventObject());
+ assertEquals("Some message foo [null]", val);
+ } finally {
+ MDC.remove("foo");
+ }
+ }
+
+
+ @Test
+ public void contextNameTest() {
+ pl.setPattern("%contextName");
+ lc.setName("aValue");
+ pl.start();
+ String val = pl.doLayout(getEventObject());
+ assertEquals("aValue", val);
+ }
+
+ @Test
+ public void cnTest() {
+ pl.setPattern("%cn");
+ lc.setName("aValue");
+ pl.start();
+ String val = pl.doLayout(getEventObject());
+ assertEquals("aValue", val);
+ }
+
+ @Override
+ public Context getContext() {
+ return lc;
+ }
+
+ void configure(String file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(lc);
+ jc.doConfigure(file);
+ }
+
+ @Test
+ public void testConversionRuleSupportInPatternLayout() throws JoranException {
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "conversionRule/patternLayout0.xml");
+ root.getAppender("LIST");
+ String msg = "Simon says";
+ logger.debug(msg);
+ StringListAppender<ILoggingEvent> sla = (StringListAppender<ILoggingEvent>) root.getAppender("LIST");
+ assertNotNull(sla);
+ assertEquals(1, sla.strList.size());
+ assertEquals(SampleConverter.SAMPLE_STR + " - " + msg, sla.strList.get(0));
+ }
+
+ @Test
+ public void somekeReplace() {
+ pl.setPattern("%replace(a1234b){'\\d{4}', 'XXXX'}");
+ pl.start();
+ StatusPrinter.print(lc);
+ String val = pl.doLayout(getEventObject());
+ assertEquals("aXXXXb", val);
+ }
+
+ @Test
+ public void replaceWithJoran() throws JoranException {
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "pattern/replace0.xml");
+ StatusPrinter.print(lc);
+ root.getAppender("LIST");
+ String msg = "And the number is 4111111111110000, expiring on 12/2010";
+ logger.debug(msg);
+ StringListAppender<ILoggingEvent> sla = (StringListAppender<ILoggingEvent>) root.getAppender("LIST");
+ assertNotNull(sla);
+ assertEquals(1, sla.strList.size());
+ assertEquals("And the number is XXXX, expiring on 12/2010", sla.strList.get(0));
+ }
- ILoggingEvent le;
-
- public PatternLayoutTest() {
- super();
- Exception ex = new Exception("Bogus exception");
- le = makeLoggingEvent(ex);
- }
-
- @Before
- public void setUp() {
- pl.setContext(lc);
- }
-
- ILoggingEvent makeLoggingEvent(Exception ex) {
- return new LoggingEvent(ch.qos.logback.core.pattern.FormattingConverter.class.getName(), logger, Level.INFO, "Some message", ex, null);
- }
-
- @Override
- public ILoggingEvent getEventObject() {
- return makeLoggingEvent(null);
- }
-
- public PatternLayoutBase<ILoggingEvent> getPatternLayoutBase() {
- return new PatternLayout();
- }
-
- @Test
- public void testOK() {
- pl.setPattern("%d %le [%t] %lo{30} - %m%n");
- pl.start();
- String val = pl.doLayout(getEventObject());
- // 2006-02-01 22:38:06,212 INFO [main] c.q.l.pattern.ConverterTest - Some
- // message
- // 2010-12-29 19:04:26,137 INFO [pool-1-thread-47] c.q.l.c.pattern.ConverterTest - Some message
- String regex = ISO_REGEX + " INFO " + MAIN_REGEX + " c.q.l.c.pattern.ConverterTest - Some message\\s*";
-
- assertTrue("val=" + val, val.matches(regex));
- }
-
- @Test
- public void testNoExeptionHandler() {
- pl.setPattern("%m%n");
- pl.start();
- String val = pl.doLayout(le);
- assertTrue(val.contains("java.lang.Exception: Bogus exception"));
- }
-
- @Test
- public void testCompositePattern() {
- pl.setPattern("%-56(%d %lo{20}) - %m%n");
- pl.start();
- String val = pl.doLayout(getEventObject());
- // 2008-03-18 21:55:54,250 c.q.l.c.pattern.ConverterTest - Some message
- String regex = ISO_REGEX + " c.q.l.c.p.ConverterTest - Some message\\s*";
- assertTrue(val.matches(regex));
- }
-
- @Test
- public void contextProperty() {
- pl.setPattern("%property{a}");
- pl.start();
- lc.putProperty("a", "b");
-
- String val = pl.doLayout(getEventObject());
- assertEquals("b", val);
- }
-
- @Test
- public void testNopExeptionHandler() {
- pl.setPattern("%nopex %m%n");
- pl.start();
- String val = pl.doLayout(le);
- assertTrue(!val.contains("java.lang.Exception: Bogus exception"));
- }
-
- @Test
- public void testWithParenthesis() {
- pl.setPattern("\\(%msg:%msg\\) %msg");
- pl.start();
- le = makeLoggingEvent(null);
- String val = pl.doLayout(le);
- // System.out.println("VAL == " + val);
- assertEquals("(Some message:Some message) Some message", val);
- }
-
- @Test
- public void testWithLettersComingFromLog4j() {
- // Letters: p = level and c = logger
- pl.setPattern("%d %p [%t] %c{30} - %m%n");
- pl.start();
- String val = pl.doLayout(getEventObject());
- // 2006-02-01 22:38:06,212 INFO [main] c.q.l.pattern.ConverterTest - Some
- // message
- String regex = ClassicTestConstants.ISO_REGEX + " INFO " + MAIN_REGEX + " c.q.l.c.pattern.ConverterTest - Some message\\s*";
- assertTrue(val.matches(regex));
- }
-
- @Test
- public void mdcWithDefaultValue() {
- String pattern = "%msg %mdc{foo} %mdc{bar:-[null]}";
- pl.setPattern(OptionHelper.substVars(pattern, lc));
- pl.start();
- MDC.put("foo", "foo");
- try {
- String val = pl.doLayout(getEventObject());
- assertEquals("Some message foo [null]", val);
- } finally {
- MDC.remove("foo");
- }
- }
-
- @Test
- public void contextNameTest() {
- pl.setPattern("%contextName");
- lc.setName("aValue");
- pl.start();
- String val = pl.doLayout(getEventObject());
- assertEquals("aValue", val);
- }
-
- @Test
- public void cnTest() {
- pl.setPattern("%cn");
- lc.setName("aValue");
- pl.start();
- String val = pl.doLayout(getEventObject());
- assertEquals("aValue", val);
- }
-
- @Override
- public Context getContext() {
- return lc;
- }
-
- void configure(String file) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(lc);
- jc.doConfigure(file);
- }
-
- @Test
- public void testConversionRuleSupportInPatternLayout() throws JoranException {
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "conversionRule/patternLayout0.xml");
- root.getAppender("LIST");
- String msg = "Simon says";
- logger.debug(msg);
- StringListAppender<ILoggingEvent> sla = (StringListAppender<ILoggingEvent>) root.getAppender("LIST");
- assertNotNull(sla);
- assertEquals(1, sla.strList.size());
- assertEquals(SampleConverter.SAMPLE_STR + " - " + msg, sla.strList.get(0));
- }
-
- @Test
- public void somekeReplace() {
- pl.setPattern("%replace(a1234b){'\\d{4}', 'XXXX'}");
- pl.start();
- StatusPrinter.print(lc);
- String val = pl.doLayout(getEventObject());
- assertEquals("aXXXXb", val);
- }
-
- @Test
- public void replaceWithJoran() throws JoranException {
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "pattern/replace0.xml");
- StatusPrinter.print(lc);
- root.getAppender("LIST");
- String msg = "And the number is 4111111111110000, expiring on 12/2010";
- logger.debug(msg);
- StringListAppender<ILoggingEvent> sla = (StringListAppender<ILoggingEvent>) root.getAppender("LIST");
- assertNotNull(sla);
- assertEquals(1, sla.strList.size());
- assertEquals("And the number is XXXX, expiring on 12/2010", sla.strList.get(0));
- }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/ScenarioBasedLoggerContextTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/ScenarioBasedLoggerContextTest.java
index ef441dc..1e4401c 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/ScenarioBasedLoggerContextTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/ScenarioBasedLoggerContextTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,84 +30,86 @@ import ch.qos.logback.classic.control.ScenarioMaker;
import ch.qos.logback.classic.control.SetLevel;
import ch.qos.logback.classic.control.Scenario;
-public class ScenarioBasedLoggerContextTest {
- LoggerContext lc;
- @Test
- public void testLen3() {
- doScenarioedTest(3);
+public class ScenarioBasedLoggerContextTest {
+ LoggerContext lc;
+
+
+ @Test
+ public void testLen3() {
+ doScenarioedTest(3);
+ }
+
+ @Test
+ public void testLength_30() {
+ doScenarioedTest(30);
+ }
+
+ @Test
+ public void testLength_20000() {
+ doScenarioedTest(20*1000);
+ }
+
+ @Test
+ @Ignore
+ public void testLengthLong() {
+ doScenarioedTest(100*1000);
+ }
+
+ private void doScenarioedTest(int len) {
+ LoggerContext lc = new LoggerContext();
+ ControlLoggerContext controlContext = new ControlLoggerContext();
+ Scenario s = ScenarioMaker.makeRealisticCreationScenario(len);
+ List actionList = s.getActionList();
+ int size = actionList.size();
+ for (int i = 0; i < size; i++) {
+ ScenarioAction action = (ScenarioAction) actionList.get(i);
+ if (action instanceof CreateLogger) {
+ CreateLogger cl = (CreateLogger) action;
+ lc.getLogger(cl.getLoggerName());
+ controlContext.getLogger(cl.getLoggerName());
+ } else if (action instanceof SetLevel) {
+ SetLevel sl = (SetLevel) action;
+ Logger l = lc.getLogger(sl.getLoggerName());
+ ControlLogger controlLogger = controlContext.getLogger(sl.getLoggerName());
+ l.setLevel(sl.getLevel());
+ controlLogger.setLevel(sl.getLevel());
+ }
}
- @Test
- public void testLength_30() {
- doScenarioedTest(30);
- }
-
- @Test
- public void testLength_20000() {
- doScenarioedTest(20 * 1000);
- }
-
- @Test
- @Ignore
- public void testLengthLong() {
- doScenarioedTest(100 * 1000);
- }
-
- private void doScenarioedTest(int len) {
- LoggerContext lc = new LoggerContext();
- ControlLoggerContext controlContext = new ControlLoggerContext();
- Scenario s = ScenarioMaker.makeRealisticCreationScenario(len);
- List actionList = s.getActionList();
- int size = actionList.size();
- for (int i = 0; i < size; i++) {
- ScenarioAction action = (ScenarioAction) actionList.get(i);
- if (action instanceof CreateLogger) {
- CreateLogger cl = (CreateLogger) action;
- lc.getLogger(cl.getLoggerName());
- controlContext.getLogger(cl.getLoggerName());
- } else if (action instanceof SetLevel) {
- SetLevel sl = (SetLevel) action;
- Logger l = lc.getLogger(sl.getLoggerName());
- ControlLogger controlLogger = controlContext.getLogger(sl.getLoggerName());
- l.setLevel(sl.getLevel());
- controlLogger.setLevel(sl.getLevel());
- }
- }
-
- compareLoggerContexts(controlContext, lc);
- }
-
- void compareLoggerContexts(ControlLoggerContext controlLC, LoggerContext lc) {
- Map<String, ControlLogger> controlLoggerMap = controlLC.getLoggerMap();
+ compareLoggerContexts(controlContext, lc);
+ }
- assertEquals(controlLoggerMap.size() + 1, lc.size());
+ void compareLoggerContexts(ControlLoggerContext controlLC, LoggerContext lc) {
+ Map<String, ControlLogger> controlLoggerMap = controlLC.getLoggerMap();
- for (String loggerName : controlLoggerMap.keySet()) {
+ assertEquals(controlLoggerMap.size()+1, lc.size());
- Logger logger = lc.exists(loggerName);
- ControlLogger controlLogger = (ControlLogger) controlLoggerMap.get(loggerName);
- if (logger == null) {
- throw new IllegalStateException("logger" + loggerName + " should exist");
- }
- assertEquals(loggerName, logger.getName());
- assertEquals(loggerName, controlLogger.getName());
+ for (String loggerName: controlLoggerMap.keySet()) {
+
+ Logger logger = lc.exists(loggerName);
+ ControlLogger controlLogger = (ControlLogger) controlLoggerMap.get(loggerName);
+ if (logger == null) {
+ throw new IllegalStateException("logger" + loggerName + " should exist");
+ }
+ assertEquals(loggerName, logger.getName());
+ assertEquals(loggerName, controlLogger.getName());
- compareLoggers(controlLogger, logger);
- }
+ compareLoggers(controlLogger, logger);
}
+ }
- void compareLoggers(ControlLogger controlLogger, Logger logger) {
- assertEquals(controlLogger.getName(), logger.getName());
- assertEquals(controlLogger.getEffectiveLevel(), logger.getEffectiveLevel());
+ void compareLoggers(ControlLogger controlLogger, Logger logger) {
+ assertEquals(controlLogger.getName(), logger.getName());
+ assertEquals(controlLogger.getEffectiveLevel(), logger.getEffectiveLevel());
- Level controlLevel = controlLogger.getLevel();
- Level level = logger.getLevel();
+ Level controlLevel = controlLogger.getLevel();
+ Level level = logger.getLevel();
- if (controlLevel == null) {
- assertNull(level);
- } else {
- assertEquals(controlLevel, level);
- }
+ if (controlLevel == null) {
+ assertNull(level);
+ } else {
+ assertEquals(controlLevel, level);
}
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/TurboFilteringInLoggerTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/TurboFilteringInLoggerTest.java
index b8a1bce..40967ed 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/TurboFilteringInLoggerTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/TurboFilteringInLoggerTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,153 +27,157 @@ import ch.qos.logback.classic.turbo.MarkerFilter;
import ch.qos.logback.classic.turbo.TurboFilter;
import ch.qos.logback.core.spi.FilterReply;
-public class TurboFilteringInLoggerTest {
-
- static final String BLUE = "BLUE";
- LoggerContext context;
- Logger logger;
- Marker blueMarker = MarkerFactory.getMarker(BLUE);
-
- @Before
- public void setUp() throws Exception {
- context = new LoggerContext();
- context.setName("test");
- context.start();
- logger = context.getLogger(TurboFilteringInLoggerTest.class);
- }
-
- private void addYesFilter() {
- YesFilter filter = new YesFilter();
- filter.start();
- context.addTurboFilter(filter);
- }
-
- private void addNoFilter() {
- NoFilter filter = new NoFilter();
- filter.start();
- context.addTurboFilter(filter);
- }
-
- private void addAcceptBLUEFilter() {
- MarkerFilter filter = new MarkerFilter();
- filter.setMarker(BLUE);
- filter.setOnMatch("ACCEPT");
- filter.start();
- context.addTurboFilter(filter);
- }
-
- private void addDenyBLUEFilter() {
- MarkerFilter filter = new MarkerFilter();
- filter.setMarker(BLUE);
- filter.setOnMatch("DENY");
- filter.start();
- context.addTurboFilter(filter);
- }
-
- @Test
- public void testIsDebugEnabledWithYesFilter() {
- addYesFilter();
- logger.setLevel(Level.INFO);
- assertTrue(logger.isDebugEnabled());
- }
-
- @Test
- public void testIsInfoEnabledWithYesFilter() {
- addYesFilter();
- logger.setLevel(Level.WARN);
- assertTrue(logger.isInfoEnabled());
- }
-
- @Test
- public void testIsWarnEnabledWithYesFilter() {
- addYesFilter();
- logger.setLevel(Level.ERROR);
- assertTrue(logger.isWarnEnabled());
- }
-
- @Test
- public void testIsErrorEnabledWithYesFilter() {
- addYesFilter();
- logger.setLevel(Level.OFF);
- assertTrue(logger.isErrorEnabled());
- }
-
- @Test
- public void testIsEnabledForWithYesFilter() {
- addYesFilter();
- logger.setLevel(Level.ERROR);
- assertTrue(logger.isEnabledFor(Level.INFO));
- }
-
- @Test
- public void testIsEnabledForWithNoFilter() {
- addNoFilter();
- logger.setLevel(Level.DEBUG);
- assertFalse(logger.isEnabledFor(Level.INFO));
- }
-
- @Test
- public void testIsDebugEnabledWithNoFilter() {
- addNoFilter();
- logger.setLevel(Level.DEBUG);
- assertFalse(logger.isDebugEnabled());
- }
-
- @Test
- public void testIsInfoEnabledWithNoFilter() {
- addNoFilter();
- logger.setLevel(Level.DEBUG);
- assertFalse(logger.isInfoEnabled());
- }
-
- @Test
- public void testIsWarnEnabledWithNoFilter() {
- addNoFilter();
- logger.setLevel(Level.DEBUG);
- assertFalse(logger.isWarnEnabled());
- }
-
- @Test
- public void testIsErrorEnabledWithNoFilter() {
- addNoFilter();
- logger.setLevel(Level.DEBUG);
- assertFalse(logger.isErrorEnabled());
- }
-
- @Test
- public void testIsErrorEnabledWithAcceptBlueFilter() {
- addAcceptBLUEFilter();
- logger.setLevel(Level.ERROR);
- assertTrue(logger.isDebugEnabled(blueMarker));
- }
-
- @Test
- public void testIsErrorEnabledWithDenyBlueFilter() {
- addDenyBLUEFilter();
- logger.setLevel(Level.ALL);
- assertFalse(logger.isDebugEnabled(blueMarker));
- }
-
- @Test
- public void testLoggingContextReset() {
- addYesFilter();
- assertNotNull(context.getTurboFilterList().get(0));
- context.reset();
- assertEquals(0, context.getTurboFilterList().size());
- }
+
+public class TurboFilteringInLoggerTest {
+
+ static final String BLUE = "BLUE";
+ LoggerContext context;
+ Logger logger;
+ Marker blueMarker = MarkerFactory.getMarker(BLUE);
+
+ @Before
+ public void setUp() throws Exception {
+ context = new LoggerContext();
+ context.setName("test");
+ context.start();
+ logger = context.getLogger(TurboFilteringInLoggerTest.class);
+ }
+
+
+ private void addYesFilter() {
+ YesFilter filter = new YesFilter();
+ filter.start();
+ context.addTurboFilter(filter);
+ }
+
+ private void addNoFilter() {
+ NoFilter filter = new NoFilter();
+ filter.start();
+ context.addTurboFilter(filter);
+ }
+
+ private void addAcceptBLUEFilter() {
+ MarkerFilter filter = new MarkerFilter();
+ filter.setMarker(BLUE);
+ filter.setOnMatch("ACCEPT");
+ filter.start();
+ context.addTurboFilter(filter);
+ }
+
+ private void addDenyBLUEFilter() {
+ MarkerFilter filter = new MarkerFilter();
+ filter.setMarker(BLUE);
+ filter.setOnMatch("DENY");
+ filter.start();
+ context.addTurboFilter(filter);
+ }
+
+ @Test
+ public void testIsDebugEnabledWithYesFilter() {
+ addYesFilter();
+ logger.setLevel(Level.INFO);
+ assertTrue(logger.isDebugEnabled());
+ }
+
+ @Test
+ public void testIsInfoEnabledWithYesFilter() {
+ addYesFilter();
+ logger.setLevel(Level.WARN);
+ assertTrue(logger.isInfoEnabled());
+ }
+
+ @Test
+ public void testIsWarnEnabledWithYesFilter() {
+ addYesFilter();
+ logger.setLevel(Level.ERROR);
+ assertTrue(logger.isWarnEnabled());
+ }
+
+ @Test
+ public void testIsErrorEnabledWithYesFilter() {
+ addYesFilter();
+ logger.setLevel(Level.OFF);
+ assertTrue(logger.isErrorEnabled());
+ }
+
+ @Test
+ public void testIsEnabledForWithYesFilter() {
+ addYesFilter();
+ logger.setLevel(Level.ERROR);
+ assertTrue(logger.isEnabledFor(Level.INFO));
+ }
+
+ @Test
+ public void testIsEnabledForWithNoFilter() {
+ addNoFilter();
+ logger.setLevel(Level.DEBUG);
+ assertFalse(logger.isEnabledFor(Level.INFO));
+ }
+
+ @Test
+ public void testIsDebugEnabledWithNoFilter() {
+ addNoFilter();
+ logger.setLevel(Level.DEBUG);
+ assertFalse(logger.isDebugEnabled());
+ }
+
+ @Test
+ public void testIsInfoEnabledWithNoFilter() {
+ addNoFilter();
+ logger.setLevel(Level.DEBUG);
+ assertFalse(logger.isInfoEnabled());
+ }
+
+ @Test
+ public void testIsWarnEnabledWithNoFilter() {
+ addNoFilter();
+ logger.setLevel(Level.DEBUG);
+ assertFalse(logger.isWarnEnabled());
+ }
+
+ @Test
+ public void testIsErrorEnabledWithNoFilter() {
+ addNoFilter();
+ logger.setLevel(Level.DEBUG);
+ assertFalse(logger.isErrorEnabled());
+ }
+
+ @Test
+ public void testIsErrorEnabledWithAcceptBlueFilter() {
+ addAcceptBLUEFilter();
+ logger.setLevel(Level.ERROR);
+ assertTrue(logger.isDebugEnabled(blueMarker));
+ }
+
+ @Test
+ public void testIsErrorEnabledWithDenyBlueFilter() {
+ addDenyBLUEFilter();
+ logger.setLevel(Level.ALL);
+ assertFalse(logger.isDebugEnabled(blueMarker));
+ }
+
+ @Test
+ public void testLoggingContextReset() {
+ addYesFilter();
+ assertNotNull(context.getTurboFilterList().get(0));
+ context.reset();
+ assertEquals(0, context.getTurboFilterList().size());
+ }
}
class YesFilter extends TurboFilter {
- @Override
- public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
- return FilterReply.ACCEPT;
- }
+ @Override
+ public FilterReply decide(Marker marker, Logger logger, Level level,
+ String format, Object[] params, Throwable t) {
+ return FilterReply.ACCEPT;
+ }
}
class NoFilter extends TurboFilter {
- @Override
- public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
- return FilterReply.DENY;
- }
+ @Override
+ public FilterReply decide(Marker marker, Logger logger, Level level,
+ String format, Object[] params, Throwable t) {
+ return FilterReply.DENY;
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/boolex/ConditionalWithoutJanino.java b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/ConditionalWithoutJanino.java
index 25fd238..82003f7 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/boolex/ConditionalWithoutJanino.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/ConditionalWithoutJanino.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,34 +27,35 @@ import org.junit.Test;
import static org.junit.Assert.*;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class ConditionalWithoutJanino {
- LoggerContext loggerContext = new LoggerContext();
- Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
-
- void configure(String file) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(loggerContext);
- jc.doConfigure(file);
+ LoggerContext loggerContext = new LoggerContext();
+ Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
+
+ void configure(String file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ jc.doConfigure(file);
+ }
+
+ // assume that janino.jar ia NOT on the classpath
+ @Test
+ public void conditionalWithoutJanino() throws JoranException {
+ String configFile = ClassicTestConstants.JORAN_INPUT_PREFIX + "conditional/withoutJanino.xml";
+ String currentDir = System.getProperty("user.dir");
+ if(!currentDir.contains("logback-classic")) {
+ configFile = "logback-classic/"+configFile;
}
+ configure(configFile);
+ StatusPrinter.print(loggerContext);
+ StatusChecker checker = new StatusChecker(loggerContext);
+ checker.assertContainsMatch(IfAction.MISSING_JANINO_MSG);
- // assume that janino.jar ia NOT on the classpath
- @Test
- public void conditionalWithoutJanino() throws JoranException {
- String configFile = ClassicTestConstants.JORAN_INPUT_PREFIX + "conditional/withoutJanino.xml";
- String currentDir = System.getProperty("user.dir");
- if (!currentDir.contains("logback-classic")) {
- configFile = "logback-classic/" + configFile;
- }
- configure(configFile);
- StatusPrinter.print(loggerContext);
- StatusChecker checker = new StatusChecker(loggerContext);
- checker.assertContainsMatch(IfAction.MISSING_JANINO_MSG);
-
- assertSame(Level.WARN, loggerContext.getLogger("a").getLevel());
- assertSame(Level.WARN, root.getLevel());
- }
+ assertSame(Level.WARN, loggerContext.getLogger("a").getLevel());
+ assertSame(Level.WARN, root.getLevel());
+ }
}
+
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/boolex/GEventEvaluatorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/GEventEvaluatorTest.java
index c0f60f3..9b02442 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/boolex/GEventEvaluatorTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/GEventEvaluatorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.classic.boolex;
+
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
@@ -35,138 +36,141 @@ import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class GEventEvaluatorTest {
- LoggerContext context = new LoggerContext();
- StatusChecker statusChecker = new StatusChecker(context);
- int LEN = 100 * 1000;
-
- Logger logger = context.getLogger(this.getClass());
- Marker markerA = MarkerFactory.getMarker("A");
-
- GEventEvaluator gee = new GEventEvaluator();
-
- @Before
- public void setUp() {
- gee.setContext(context);
- }
-
- LoggingEvent makeEvent(String msg) {
- return makeEvent(Level.DEBUG, msg, null, null);
- }
-
- LoggingEvent makeEvent(Level level, String msg, Throwable t, Object[] argArray) {
- return new LoggingEvent(this.getClass().getName(), logger, level, msg, t, argArray);
- }
-
- void doEvaluateAndCheck(String expression, ILoggingEvent event, boolean expected) throws EvaluationException {
- gee.setExpression(expression);
- gee.start();
-
- StatusPrinter.printInCaseOfErrorsOrWarnings(context);
- assertTrue(statusChecker.isErrorFree(0));
-
- ContextUtil contextUtil = new ContextUtil(context);
- contextUtil.addGroovyPackages(context.getFrameworkPackages());
- contextUtil.addFrameworkPackage(context.getFrameworkPackages(), "ch.qos.logback.classic.boolex");
-
- boolean result = gee.evaluate(event);
- assertEquals(expected, result);
- }
-
- @Test
- public void smoke() throws EvaluationException {
- doEvaluateAndCheck("1==1", null, true);
- }
-
- @Test
- public void event() throws EvaluationException {
- ILoggingEvent event = makeEvent("x");
- event.getLoggerContextVO();
- doEvaluateAndCheck("e.message == 'x'", event, true);
- }
-
- @Test
- public void msgRegex() throws EvaluationException {
- LoggingEvent event = makeEvent("Hello world");
- // partial match
- doEvaluateAndCheck("e.message =~ /xyz|wor/", event, true);
- // full match
- doEvaluateAndCheck("e.message ==~ /xyz|wor/", event, false);
- }
-
- @Test
- public void level() throws EvaluationException {
- LoggingEvent event = makeEvent("x");
- doEvaluateAndCheck("e.level == DEBUG", event, true);
- }
-
- @Test
- public void nullMarker() throws EvaluationException {
- LoggingEvent event = makeEvent("x");
- doEvaluateAndCheck("e.marker?.name == 'YELLOW'", event, false);
- }
-
- @Test
- public void marker() throws EvaluationException {
- LoggingEvent event = makeEvent("x");
- event.setMarker(markerA);
- doEvaluateAndCheck("e.marker?.name == 'A'", event, true);
- }
-
- @Test
- public void nullMDC() throws EvaluationException {
- LoggingEvent event = makeEvent("x");
- doEvaluateAndCheck("e.mdc?.get('key') == 'val'", event, false);
- }
-
- @Test
- public void mdc() throws EvaluationException {
- MDC.put("key", "val");
- LoggingEvent event = makeEvent("x");
- doEvaluateAndCheck("e.mdc['key'] == 'val'", event, true);
- MDC.clear();
- }
-
- @Test
- public void callerData() throws EvaluationException {
- LoggingEvent event = makeEvent("x");
- doEvaluateAndCheck("e.callerData.find{ it.className =~ /junit/ }", event, true);
- }
-
- double loop(GEventEvaluator gee) throws EvaluationException {
- long start = System.nanoTime();
- ILoggingEvent event = makeEvent("x");
- for (int i = 0; i < LEN; i++) {
- gee.evaluate(event);
- }
- long end = System.nanoTime();
- return (end - start) / LEN;
- }
-
- @Test
- public void startMakesIsStartedReturnTrue() {
- gee.setExpression("return true");
- gee.start();
- assertTrue(gee.isStarted());
- }
-
- @Test
- @Ignore
- public void MANUAL_perfTest() throws EvaluationException {
- gee.setExpression("event.timeStamp < 100 && event.message != 'xx' ");
- gee.start();
-
- loop(gee);
- loop(gee);
- double avgDuration = loop(gee);
-
- long referencePerf = 500;
- BogoPerf.assertDuration(avgDuration, referencePerf, CoreConstants.REFERENCE_BIPS);
- System.out.println("Average duration " + avgDuration);
- }
+ LoggerContext context = new LoggerContext();
+ StatusChecker statusChecker = new StatusChecker(context);
+ int LEN = 100 * 1000;
+
+ Logger logger = context.getLogger(this.getClass());
+ Marker markerA = MarkerFactory.getMarker("A");
+
+ GEventEvaluator gee = new GEventEvaluator();
+
+ @Before
+ public void setUp() {
+ gee.setContext(context);
+ }
+
+ LoggingEvent makeEvent(String msg) {
+ return makeEvent(Level.DEBUG, msg, null, null);
+ }
+
+ LoggingEvent makeEvent(Level level, String msg, Throwable t, Object[] argArray) {
+ return new LoggingEvent(this.getClass().getName(), logger, level, msg, t, argArray);
+ }
+
+ void doEvaluateAndCheck(String expression, ILoggingEvent event, boolean expected) throws EvaluationException {
+ gee.setExpression(expression);
+ gee.start();
+
+ StatusPrinter.printInCaseOfErrorsOrWarnings(context);
+ assertTrue(statusChecker.isErrorFree(0));
+
+ ContextUtil contextUtil = new ContextUtil(context);
+ contextUtil.addGroovyPackages(context.getFrameworkPackages());
+ contextUtil.addFrameworkPackage(context.getFrameworkPackages(), "ch.qos.logback.classic.boolex");
+
+ boolean result = gee.evaluate(event);
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void smoke() throws EvaluationException {
+ doEvaluateAndCheck("1==1", null, true);
+ }
+
+ @Test
+ public void event() throws EvaluationException {
+ ILoggingEvent event = makeEvent("x");
+ event.getLoggerContextVO();
+ doEvaluateAndCheck("e.message == 'x'", event, true);
+ }
+
+ @Test
+ public void msgRegex() throws EvaluationException {
+ LoggingEvent event = makeEvent("Hello world");
+ // partial match
+ doEvaluateAndCheck("e.message =~ /xyz|wor/", event, true);
+ // full match
+ doEvaluateAndCheck("e.message ==~ /xyz|wor/", event, false);
+ }
+
+ @Test
+ public void level() throws EvaluationException {
+ LoggingEvent event = makeEvent("x");
+ doEvaluateAndCheck("e.level == DEBUG", event, true);
+ }
+
+
+ @Test
+ public void nullMarker() throws EvaluationException {
+ LoggingEvent event = makeEvent("x");
+ doEvaluateAndCheck("e.marker?.name == 'YELLOW'", event, false);
+ }
+
+ @Test
+ public void marker() throws EvaluationException {
+ LoggingEvent event = makeEvent("x");
+ event.setMarker(markerA);
+ doEvaluateAndCheck("e.marker?.name == 'A'", event, true);
+ }
+
+ @Test
+ public void nullMDC() throws EvaluationException {
+ LoggingEvent event = makeEvent("x");
+ doEvaluateAndCheck("e.mdc?.get('key') == 'val'", event, false);
+ }
+
+ @Test
+ public void mdc() throws EvaluationException {
+ MDC.put("key", "val");
+ LoggingEvent event = makeEvent("x");
+ doEvaluateAndCheck("e.mdc['key'] == 'val'", event, true);
+ MDC.clear();
+ }
+
+ @Test
+ public void callerData() throws EvaluationException {
+ LoggingEvent event = makeEvent("x");
+ doEvaluateAndCheck("e.callerData.find{ it.className =~ /junit/ }", event, true);
+ }
+
+ double loop(GEventEvaluator gee) throws EvaluationException {
+ long start = System.nanoTime();
+ ILoggingEvent event = makeEvent("x");
+ for (int i = 0; i < LEN; i++) {
+ gee.evaluate(event);
+ }
+ long end = System.nanoTime();
+ return (end - start) / LEN;
+ }
+
+
+ @Test
+ public void startMakesIsStartedReturnTrue() {
+ gee.setExpression("return true");
+ gee.start();
+ assertTrue(gee.isStarted());
+ }
+
+ @Test
+ @Ignore
+ public void MANUAL_perfTest() throws EvaluationException {
+ gee.setExpression("event.timeStamp < 100 && event.message != 'xx' ");
+ gee.start();
+
+ loop(gee);
+ loop(gee);
+ double avgDuration = loop(gee);
+
+ long referencePerf = 500;
+ BogoPerf.assertDuration(avgDuration, referencePerf,
+ CoreConstants.REFERENCE_BIPS);
+ System.out.println("Average duration " + avgDuration);
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/boolex/JaninoEventEvaluatorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/JaninoEventEvaluatorTest.java
index 56e2071..0e7c7cc 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/boolex/JaninoEventEvaluatorTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/JaninoEventEvaluatorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -40,228 +40,234 @@ import ch.qos.logback.core.util.StatusPrinter;
public class JaninoEventEvaluatorTest {
- LoggerContext loggerContext = new LoggerContext();
- Logger logger = loggerContext.getLogger(ConverterTest.class);
-
- Matcher matcherX = new Matcher();
-
- JaninoEventEvaluator jee = new JaninoEventEvaluator();
-
- int diff = RandomUtil.getPositiveInt();
-
- public JaninoEventEvaluatorTest() {
- jee.setContext(loggerContext);
-
- matcherX.setName("x");
- matcherX.setRegex("^Some\\s.*");
- matcherX.start();
-
- }
-
- LoggingEvent makeLoggingEvent(Exception ex) {
- return new LoggingEvent(ch.qos.logback.core.pattern.FormattingConverter.class.getName(), logger, Level.INFO, "Some message", ex, null);
+ LoggerContext loggerContext = new LoggerContext();
+ Logger logger = loggerContext.getLogger(ConverterTest.class);
+
+ Matcher matcherX = new Matcher();
+
+ JaninoEventEvaluator jee = new JaninoEventEvaluator();
+
+ int diff = RandomUtil.getPositiveInt();
+
+ public JaninoEventEvaluatorTest() {
+ jee.setContext(loggerContext);
+
+ matcherX.setName("x");
+ matcherX.setRegex("^Some\\s.*");
+ matcherX.start();
+
+ }
+
+ LoggingEvent makeLoggingEvent(Exception ex) {
+ return new LoggingEvent(
+ ch.qos.logback.core.pattern.FormattingConverter.class.getName(),
+ logger, Level.INFO, "Some message", ex, null);
+ }
+
+ @Test
+ public void testBasic() throws Exception {
+ jee.setExpression("message.equals(\"Some message\")");
+ jee.start();
+
+ StatusPrinter.print(loggerContext);
+ ILoggingEvent event = makeLoggingEvent(null);
+ assertTrue(jee.evaluate(event));
+ }
+
+ @Test
+ public void testLevel() throws Exception {
+ jee.setExpression("level > DEBUG");
+ jee.start();
+
+ ILoggingEvent event = makeLoggingEvent(null);
+ assertTrue(jee.evaluate(event));
+ }
+
+ @Test
+ public void testtimeStamp() throws Exception {
+ jee.setExpression("timeStamp > 10");
+ jee.start();
+
+ ILoggingEvent event = makeLoggingEvent(null);
+ assertTrue(jee.evaluate(event));
+ }
+
+ @Test
+ public void testWithMatcher() throws Exception {
+ jee.setExpression("x.matches(message)");
+ jee.addMatcher(matcherX);
+ jee.start();
+
+ ILoggingEvent event = makeLoggingEvent(null);
+ assertTrue(jee.evaluate(event));
+ }
+
+
+ @Test
+ public void mdcAsString() throws Exception {
+ String k = "key"+diff;
+
+ MDC.put("key"+diff, "value"+diff);
+ jee.setExpression("((String) mdc.get(\""+k+"\")).contains(\"alue\")");
+ jee.start();
+ StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
+
+ LoggingEvent event = makeLoggingEvent(null);
+ assertTrue(jee.evaluate(event));
+ MDC.remove(k);
+ }
+
+ @Test
+ public void marker() throws Exception {
+ jee.setExpression("marker.contains(\"BLUE\")");
+ jee.start();
+
+ LoggingEvent event = makeLoggingEvent(null);
+ event.setMarker(MarkerFactory.getMarker("BLUE"));
+ assertTrue(jee.evaluate(event));
+ }
+
+
+ @Test
+ public void withNullMarker_LBCORE_118() throws Exception {
+ jee.setExpression("marker.contains(\"BLUE\")");
+ jee.start();
+
+ ILoggingEvent event = makeLoggingEvent(null);
+ try {
+ jee.evaluate(event);
+ fail("We should not reach this point");
+ } catch (EvaluationException ee) {
+ // received an exception as expected
}
-
- @Test
- public void testBasic() throws Exception {
- jee.setExpression("message.equals(\"Some message\")");
- jee.start();
-
- StatusPrinter.print(loggerContext);
- ILoggingEvent event = makeLoggingEvent(null);
- assertTrue(jee.evaluate(event));
- }
-
- @Test
- public void testLevel() throws Exception {
- jee.setExpression("level > DEBUG");
- jee.start();
-
- ILoggingEvent event = makeLoggingEvent(null);
- assertTrue(jee.evaluate(event));
- }
-
- @Test
- public void testtimeStamp() throws Exception {
- jee.setExpression("timeStamp > 10");
- jee.start();
-
- ILoggingEvent event = makeLoggingEvent(null);
- assertTrue(jee.evaluate(event));
+ }
+
+ @Test
+ public void evaluatorFilterWithNullMarker_LBCORE_118() throws Exception {
+ EvaluatorFilter<ILoggingEvent> ef = new EvaluatorFilter<ILoggingEvent>();
+ ef.setContext(loggerContext);
+
+ ef.setOnMatch(FilterReply.ACCEPT);
+ ef.setOnMismatch(FilterReply.DENY);
+
+ jee.setExpression("marker.contains(\"BLUE\")");
+ jee.start();
+
+ ef.setEvaluator(jee);
+ ef.start();
+ ILoggingEvent event = makeLoggingEvent(null);
+ assertEquals(FilterReply.NEUTRAL, ef.decide(event));
+
+ }
+
+ @Test
+ public void testComplex() throws Exception {
+ jee
+ .setExpression("level >= INFO && x.matches(message) && marker.contains(\"BLUE\")");
+ jee.addMatcher(matcherX);
+ jee.start();
+
+ LoggingEvent event = makeLoggingEvent(null);
+ event.setMarker(MarkerFactory.getMarker("BLUE"));
+ assertTrue(jee.evaluate(event));
+ }
+
+ /**
+ * check that evaluator with bogus exp does not start
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testBogusExp1() {
+ jee.setExpression("mzzzz.get(\"key\").equals(null)");
+ jee.setName("bogus");
+ jee.start();
+
+ assertFalse(jee.isStarted());
+ }
+
+ // check that eval stops after errors
+ @Test
+ public void testBogusExp2() {
+ jee.setExpression("mdc.get(\"keyXN89\").equals(null)");
+ jee.setName("bogus");
+ jee.start();
+
+ assertTrue(jee.isStarted());
+
+ ILoggingEvent event = makeLoggingEvent(null);
+
+ for (int i = 0; i < JaninoEventEvaluatorBase.ERROR_THRESHOLD; i++) {
+ try {
+ jee.evaluate(event);
+ fail("should throw an exception");
+ } catch (EvaluationException e) {
+ }
}
-
- @Test
- public void testWithMatcher() throws Exception {
- jee.setExpression("x.matches(message)");
- jee.addMatcher(matcherX);
- jee.start();
-
- ILoggingEvent event = makeLoggingEvent(null);
- assertTrue(jee.evaluate(event));
- }
-
- @Test
- public void mdcAsString() throws Exception {
- String k = "key" + diff;
-
- MDC.put("key" + diff, "value" + diff);
- jee.setExpression("((String) mdc.get(\"" + k + "\")).contains(\"alue\")");
- jee.start();
- StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
-
- LoggingEvent event = makeLoggingEvent(null);
- assertTrue(jee.evaluate(event));
- MDC.remove(k);
- }
-
- @Test
- public void marker() throws Exception {
- jee.setExpression("marker.contains(\"BLUE\")");
- jee.start();
-
- LoggingEvent event = makeLoggingEvent(null);
- event.setMarker(MarkerFactory.getMarker("BLUE"));
- assertTrue(jee.evaluate(event));
- }
-
- @Test
- public void withNullMarker_LBCORE_118() throws Exception {
- jee.setExpression("marker.contains(\"BLUE\")");
- jee.start();
-
- ILoggingEvent event = makeLoggingEvent(null);
- try {
- jee.evaluate(event);
- fail("We should not reach this point");
- } catch (EvaluationException ee) {
- // received an exception as expected
- }
- }
-
- @Test
- public void evaluatorFilterWithNullMarker_LBCORE_118() throws Exception {
- EvaluatorFilter<ILoggingEvent> ef = new EvaluatorFilter<ILoggingEvent>();
- ef.setContext(loggerContext);
-
- ef.setOnMatch(FilterReply.ACCEPT);
- ef.setOnMismatch(FilterReply.DENY);
-
- jee.setExpression("marker.contains(\"BLUE\")");
- jee.start();
-
- ef.setEvaluator(jee);
- ef.start();
- ILoggingEvent event = makeLoggingEvent(null);
- assertEquals(FilterReply.NEUTRAL, ef.decide(event));
-
- }
-
- @Test
- public void testComplex() throws Exception {
- jee.setExpression("level >= INFO && x.matches(message) && marker.contains(\"BLUE\")");
- jee.addMatcher(matcherX);
- jee.start();
-
- LoggingEvent event = makeLoggingEvent(null);
- event.setMarker(MarkerFactory.getMarker("BLUE"));
- assertTrue(jee.evaluate(event));
- }
-
- /**
- * check that evaluator with bogus exp does not start
- *
- * @throws Exception
- */
- @Test
- public void testBogusExp1() {
- jee.setExpression("mzzzz.get(\"key\").equals(null)");
- jee.setName("bogus");
- jee.start();
-
- assertFalse(jee.isStarted());
- }
-
- // check that eval stops after errors
- @Test
- public void testBogusExp2() {
- jee.setExpression("mdc.get(\"keyXN89\").equals(null)");
- jee.setName("bogus");
- jee.start();
-
- assertTrue(jee.isStarted());
-
- ILoggingEvent event = makeLoggingEvent(null);
-
- for (int i = 0; i < JaninoEventEvaluatorBase.ERROR_THRESHOLD; i++) {
- try {
- jee.evaluate(event);
- fail("should throw an exception");
- } catch (EvaluationException e) {
- }
- }
- // after a few attempts the evaluator should processPriorToRemoval
- assertFalse(jee.isStarted());
-
- }
-
- static final long LEN = 10 * 1000;
-
- // with 6 parameters 400 nanos
- // with 7 parameters 460 nanos (all levels + selected fields from
- // LoggingEvent)
- // with 10 parameters 510 nanos (all levels + fields)
- void loop(JaninoEventEvaluator jee, String msg) throws Exception {
- ILoggingEvent event = makeLoggingEvent(null);
- // final long start = System.nanoTime();
- for (int i = 0; i < LEN; i++) {
- jee.evaluate(event);
- }
- // final long end = System.nanoTime();
- // System.out.println(msg + (end - start) / LEN + " nanos");
- }
-
- @Test
- public void testLoop1() throws Exception {
- jee.setExpression("timeStamp > 10");
- jee.start();
-
- loop(jee, "timestamp > 10]: ");
- }
-
- @Test
- public void testLoop2() throws Exception {
- jee.setExpression("x.matches(message)");
- jee.addMatcher(matcherX);
- jee.start();
-
- loop(jee, "x.matches(message): ");
- }
-
- @Test
- public void throwable_LBCLASSIC_155_I() throws EvaluationException {
- jee.setExpression("throwable instanceof java.io.IOException");
- jee.start();
-
- LoggingEvent event = makeLoggingEvent(new IOException(""));
- assertTrue(jee.evaluate(event));
- }
-
- @Test
- public void throwable_LBCLASSIC_155_II() throws EvaluationException {
- jee.setExpression("throwableProxy.getClassName().contains(\"IO\")");
- jee.start();
-
- LoggingEvent event = makeLoggingEvent(new IOException(""));
- assertTrue(jee.evaluate(event));
- }
-
- @Test
- public void nullMDC() throws EvaluationException {
- MDC.clear();
- jee.setExpression("mdc.isEmpty()");
- jee.start();
-
- LoggingEvent event = makeLoggingEvent(null);
- assertTrue(jee.evaluate(event));
+ // after a few attempts the evaluator should processPriorToRemoval
+ assertFalse(jee.isStarted());
+
+ }
+
+ static final long LEN = 10 * 1000;
+
+ // with 6 parameters 400 nanos
+ // with 7 parameters 460 nanos (all levels + selected fields from
+ // LoggingEvent)
+ // with 10 parameters 510 nanos (all levels + fields)
+ void loop(JaninoEventEvaluator jee, String msg) throws Exception {
+ ILoggingEvent event = makeLoggingEvent(null);
+ // final long start = System.nanoTime();
+ for (int i = 0; i < LEN; i++) {
+ jee.evaluate(event);
}
+ // final long end = System.nanoTime();
+ // System.out.println(msg + (end - start) / LEN + " nanos");
+ }
+
+ @Test
+ public void testLoop1() throws Exception {
+ jee.setExpression("timeStamp > 10");
+ jee.start();
+
+ loop(jee, "timestamp > 10]: ");
+ }
+
+ @Test
+ public void testLoop2() throws Exception {
+ jee.setExpression("x.matches(message)");
+ jee.addMatcher(matcherX);
+ jee.start();
+
+ loop(jee, "x.matches(message): ");
+ }
+
+ @Test
+ public void throwable_LBCLASSIC_155_I() throws EvaluationException {
+ jee.setExpression("throwable instanceof java.io.IOException");
+ jee.start();
+
+ LoggingEvent event = makeLoggingEvent(new IOException(""));
+ assertTrue(jee.evaluate(event));
+ }
+
+ @Test
+ public void throwable_LBCLASSIC_155_II() throws EvaluationException {
+ jee.setExpression("throwableProxy.getClassName().contains(\"IO\")");
+ jee.start();
+
+ LoggingEvent event = makeLoggingEvent(new IOException(""));
+ assertTrue(jee.evaluate(event));
+ }
+
+
+ @Test
+ public void nullMDC() throws EvaluationException {
+ MDC.clear();
+ jee.setExpression("mdc.isEmpty()");
+ jee.start();
+
+ LoggingEvent event = makeLoggingEvent(null);
+ assertTrue(jee.evaluate(event));
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/boolex/OnMarkerEvaluatorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/OnMarkerEvaluatorTest.java
index acb2462..6b5dbaf 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/boolex/OnMarkerEvaluatorTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/OnMarkerEvaluatorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,41 +25,44 @@ import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.boolex.EvaluationException;
-public class OnMarkerEvaluatorTest {
-
- LoggerContext lc = new LoggerContext();
- LoggingEvent event = makeEvent();
- OnMarkerEvaluator evaluator = new OnMarkerEvaluator();
-
- @Before
- public void before() {
- evaluator.setContext(lc);
- }
- @Test
- public void smoke() throws EvaluationException {
- evaluator.addMarker("M");
- evaluator.start();
-
- event.setMarker(MarkerFactory.getMarker("M"));
- assertTrue(evaluator.evaluate(event));
- }
-
- @Test
- public void nullMarkerInEvent() throws EvaluationException {
- evaluator.addMarker("M");
- evaluator.start();
- assertFalse(evaluator.evaluate(event));
- }
+public class OnMarkerEvaluatorTest {
- @Test
- public void nullMarkerInEvaluator() throws EvaluationException {
- evaluator.addMarker("M");
- evaluator.start();
- assertFalse(evaluator.evaluate(event));
- }
+
+ LoggerContext lc = new LoggerContext();
+ LoggingEvent event = makeEvent();
+ OnMarkerEvaluator evaluator = new OnMarkerEvaluator();
- LoggingEvent makeEvent() {
- return new LoggingEvent("x", lc.getLogger("x"), Level.DEBUG, "msg", null, null);
- }
+ @Before
+ public void before() {
+ evaluator.setContext(lc);
+ }
+
+ @Test
+ public void smoke() throws EvaluationException {
+ evaluator.addMarker("M");
+ evaluator.start();
+
+ event.setMarker(MarkerFactory.getMarker("M"));
+ assertTrue(evaluator.evaluate(event));
+ }
+
+ @Test
+ public void nullMarkerInEvent() throws EvaluationException {
+ evaluator.addMarker("M");
+ evaluator.start();
+ assertFalse(evaluator.evaluate(event));
+ }
+
+ @Test
+ public void nullMarkerInEvaluator() throws EvaluationException {
+ evaluator.addMarker("M");
+ evaluator.start();
+ assertFalse(evaluator.evaluate(event));
+ }
+
+
+ LoggingEvent makeEvent() {
+ return new LoggingEvent("x", lc.getLogger("x"), Level.DEBUG, "msg", null, null);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/boolex/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/PackageTest.java
index 771c4b7..a8ae160 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/boolex/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ JaninoEventEvaluatorTest.class, OnMarkerEvaluatorTest.class })
+ at SuiteClasses({JaninoEventEvaluatorTest.class, OnMarkerEvaluatorTest.class})
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/control/CLCTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/control/CLCTest.java
index 054189c..00c7513 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/control/CLCTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/control/CLCTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,35 +19,38 @@ import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.control.ControlLogger;
import ch.qos.logback.classic.control.ControlLoggerContext;
+
/**
* This class is for testing ControlLoggerContext which is a control class for testing HLoggerContext.
*/
public class CLCTest extends TestCase {
- ControlLoggerContext clc;
+ ControlLoggerContext clc;
+
+
+ protected void setUp() throws Exception {
+ clc = new ControlLoggerContext();
+ }
- protected void setUp() throws Exception {
- clc = new ControlLoggerContext();
- }
+ public void test1() {
+ ControlLogger x = clc.getLogger("x");
+ assertEquals("x", x.getName());
+ assertEquals(clc.getRootLogger(), x.parent);
- public void test1() {
- ControlLogger x = clc.getLogger("x");
- assertEquals("x", x.getName());
- assertEquals(clc.getRootLogger(), x.parent);
+ ControlLogger abc = clc.getLogger("a.b.c");
+ assertEquals("a.b.c", abc.getName());
+ assertEquals(Level.DEBUG, abc.getEffectiveLevel());
+ }
- ControlLogger abc = clc.getLogger("a.b.c");
- assertEquals("a.b.c", abc.getName());
- assertEquals(Level.DEBUG, abc.getEffectiveLevel());
- }
+ public void testCreation() {
+ ControlLogger xyz = clc.getLogger("x.y.z");
+ assertEquals("x.y.z", xyz.getName());
+ assertEquals("x.y", xyz.parent.getName());
+ assertEquals("x", xyz.parent.parent.getName());
+ assertEquals("root", xyz.parent.parent.parent.getName());
- public void testCreation() {
- ControlLogger xyz = clc.getLogger("x.y.z");
- assertEquals("x.y.z", xyz.getName());
- assertEquals("x.y", xyz.parent.getName());
- assertEquals("x", xyz.parent.parent.getName());
- assertEquals("root", xyz.parent.parent.parent.getName());
+ ControlLogger xyz_ = clc.exists("x.y.z");
+ assertEquals("x.y.z", xyz_.getName());
- ControlLogger xyz_ = clc.exists("x.y.z");
- assertEquals("x.y.z", xyz_.getName());
- }
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/control/ControlLogger.java b/logback-classic/src/test/java/ch/qos/logback/classic/control/ControlLogger.java
index 4af9123..c3f81a2 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/control/ControlLogger.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/control/ControlLogger.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,170 +22,164 @@ import ch.qos.logback.classic.Level;
*/
public class ControlLogger extends MarkerIgnoringBase {
- private static final long serialVersionUID = 1L;
- final ControlLogger parent;
- final String name;
- Level level;
-
- public ControlLogger(String name, ControlLogger parent) {
- if (name == null) {
- throw new IllegalArgumentException("name cannot be null");
- }
- this.name = name;
- this.parent = parent;
- }
-
- public String getName() {
- return name;
- }
-
- public Level getLevel() {
- return level;
- }
-
- public void setLevel(Level level) {
- this.level = level;
- }
-
- public final Level getEffectiveLevel() {
- for (ControlLogger cl = this; cl != null; cl = cl.parent) {
- if (cl.level != null)
- return cl.level;
- }
- return null; // If reached will cause an NullPointerException.
- }
-
- public boolean equals(Object o) {
- if (this == o)
- return true;
- if (!(o instanceof ControlLogger))
- return false;
-
- final ControlLogger controlLogger = (ControlLogger) o;
- return name.equals(controlLogger.name);
- }
-
- public int hashCode() {
- return name.hashCode();
- }
-
- public final void trace(String o) {
- if (getEffectiveLevel().levelInt <= Level.TRACE_INT) {
- throw new UnsupportedOperationException("not yet implemented");
- }
- }
-
- public void trace(String msg, Throwable t) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void trace(String parameterizedMsg, Object param1) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void trace(String parameterizedMsg, Object param1, Object param2) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public final void debug(String o) {
- if (getEffectiveLevel().levelInt <= Level.DEBUG_INT) {
- throw new UnsupportedOperationException("not yet implemented");
- }
- }
-
- public void debug(String msg, Throwable t) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void debug(String parameterizedMsg, Object param1) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void debug(String parameterizedMsg, Object param1, Object param2) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void error(String msg) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void error(String msg, Throwable t) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void error(String parameterizedMsg, Object param1) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void error(String parameterizedMsg, Object param1, Object param2) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void info(String msg) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void info(String msg, Throwable t) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
+ private static final long serialVersionUID = 1L;
+ final ControlLogger parent;
+ final String name;
+ Level level;
- public void info(String parameterizedMsg, Object param1) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
- public void info(String parameterizedMsg, Object param1, Object param2) {
- // To change body of implemented methods use File | Settings | File Templates.
+ public ControlLogger(String name, ControlLogger parent) {
+ if(name == null){
+ throw new IllegalArgumentException("name cannot be null");
}
+ this.name = name;
+ this.parent = parent;
+ }
+ public String getName() {
+ return name;
+ }
- public boolean isTraceEnabled() {
- return false;
- }
+ public Level getLevel() {
+ return level;
+ }
- public boolean isDebugEnabled() {
- return false; // To change body of implemented methods use File | Settings | File Templates.
- }
+ public void setLevel(Level level) {
+ this.level = level;
+ }
- public boolean isErrorEnabled() {
- return false; // To change body of implemented methods use File | Settings | File Templates.
+ public final Level getEffectiveLevel() {
+ for(ControlLogger cl = this; cl != null; cl=cl.parent) {
+ if(cl.level != null)
+ return cl.level;
}
+ return null; // If reached will cause an NullPointerException.
+ }
- public boolean isInfoEnabled() {
- return false; // To change body of implemented methods use File | Settings | File Templates.
- }
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ControlLogger)) return false;
- public boolean isWarnEnabled() {
- return false; // To change body of implemented methods use File | Settings | File Templates.
- }
+ final ControlLogger controlLogger = (ControlLogger) o;
+ return name.equals(controlLogger.name);
+ }
- public void warn(String msg) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void warn(String msg, Throwable t) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void warn(String parameterizedMsg, Object param1) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void warn(String parameterizedMsg, Object param1, Object param2) {
- // To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void trace(String format, Object[] argArray) {
- }
-
- public void debug(String format, Object[] argArray) {
- }
-
- public void info(String format, Object[] argArray) {
- }
-
- public void warn(String format, Object[] argArray) {
- }
+ public int hashCode() {
+ return name.hashCode();
+ }
- public void error(String format, Object[] argArray) {
+ public final void trace(String o) {
+ if(getEffectiveLevel().levelInt <= Level.TRACE_INT ) {
+ throw new UnsupportedOperationException("not yet implemented");
}
+ }
+
+ public void trace(String msg, Throwable t) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void trace(String parameterizedMsg, Object param1) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void trace(String parameterizedMsg, Object param1, Object param2) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public final void debug(String o) {
+ if(getEffectiveLevel().levelInt <= Level.DEBUG_INT ) {
+ throw new UnsupportedOperationException("not yet implemented");
+ }
+ }
+
+ public void debug(String msg, Throwable t) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void debug(String parameterizedMsg, Object param1) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void debug(String parameterizedMsg, Object param1, Object param2) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void error(String msg) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void error(String msg, Throwable t) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void error(String parameterizedMsg, Object param1) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void error(String parameterizedMsg, Object param1, Object param2) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void info(String msg) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void info(String msg, Throwable t) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void info(String parameterizedMsg, Object param1) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void info(String parameterizedMsg, Object param1, Object param2) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean isTraceEnabled() {
+ return false;
+ }
+
+ public boolean isDebugEnabled() {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean isErrorEnabled() {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean isInfoEnabled() {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean isWarnEnabled() {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void warn(String msg) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void warn(String msg, Throwable t) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void warn(String parameterizedMsg, Object param1) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void warn(String parameterizedMsg, Object param1, Object param2) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void trace(String format, Object[] argArray) {
+ }
+ public void debug(String format, Object[] argArray) {
+ }
+ public void info(String format, Object[] argArray) {
+ }
+ public void warn(String format, Object[] argArray) {
+ }
+ public void error(String format, Object[] argArray) {
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/control/ControlLoggerContext.java b/logback-classic/src/test/java/ch/qos/logback/classic/control/ControlLoggerContext.java
index 807da1b..eff1f76 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/control/ControlLoggerContext.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/control/ControlLoggerContext.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -37,74 +37,74 @@ import ch.qos.logback.core.CoreConstants;
*/
public class ControlLoggerContext {
- private ControlLogger root;
- //
- // Hashtable loggerMap = new Hashtable();
- Map<String, ControlLogger> loggerMap = new HashMap<String, ControlLogger>();
+ private ControlLogger root;
+ //
+ // Hashtable loggerMap = new Hashtable();
+ Map<String, ControlLogger> loggerMap = new HashMap<String, ControlLogger>();
- public ControlLoggerContext() {
- this.root = new ControlLogger("root", null);
- this.root.setLevel(Level.DEBUG);
- }
+ public ControlLoggerContext() {
+ this.root = new ControlLogger("root", null);
+ this.root.setLevel(Level.DEBUG);
+ }
- /**
- * Return this contexts root logger
- *
- * @return
- */
- public ControlLogger getRootLogger() {
- return root;
- }
+ /**
+ * Return this contexts root logger
+ *
+ * @return
+ */
+ public ControlLogger getRootLogger() {
+ return root;
+ }
- public ControlLogger exists(String name) {
- if (name == null) {
- throw new IllegalArgumentException("name parameter cannot be null");
- }
+ public ControlLogger exists(String name) {
+ if (name == null) {
+ throw new IllegalArgumentException("name parameter cannot be null");
+ }
- synchronized (loggerMap) {
- return (ControlLogger) loggerMap.get(name);
- }
+ synchronized (loggerMap) {
+ return (ControlLogger) loggerMap.get(name);
}
+ }
- public final ControlLogger getLogger(String name) {
- if (name == null) {
- throw new IllegalArgumentException("name parameter cannot be null");
- }
+ public final ControlLogger getLogger(String name) {
+ if (name == null) {
+ throw new IllegalArgumentException("name parameter cannot be null");
+ }
- synchronized (loggerMap) {
- ControlLogger cl = (ControlLogger) loggerMap.get(name);
- if (cl != null) {
- return cl;
- }
- ControlLogger parent = this.root;
+ synchronized (loggerMap) {
+ ControlLogger cl = (ControlLogger) loggerMap.get(name);
+ if (cl != null) {
+ return cl;
+ }
+ ControlLogger parent = this.root;
- int i = 0;
- while (true) {
- i = name.indexOf(CoreConstants.DOT, i);
- if (i == -1) {
- // System.out.println("FINAL-Creating logger named [" + name + "] with
- // parent " + parent.getName());
- cl = new ControlLogger(name, parent);
- loggerMap.put(name, cl);
- return cl;
- } else {
- String parentName = name.substring(0, i);
- ControlLogger p = (ControlLogger) loggerMap.get(parentName);
- if (p == null) {
- // System.out.println("INTERMEDIARY-Creating logger [" + parentName
- // + "] with parent " + parent.getName());
- p = new ControlLogger(parentName, parent);
- loggerMap.put(parentName, p);
- }
- parent = p;
- }
- // make i move past the last found dot.
- i++;
- }
+ int i = 0;
+ while (true) {
+ i = name.indexOf(CoreConstants.DOT, i);
+ if (i == -1) {
+ // System.out.println("FINAL-Creating logger named [" + name + "] with
+ // parent " + parent.getName());
+ cl = new ControlLogger(name, parent);
+ loggerMap.put(name, cl);
+ return cl;
+ } else {
+ String parentName = name.substring(0, i);
+ ControlLogger p = (ControlLogger) loggerMap.get(parentName);
+ if (p == null) {
+ // System.out.println("INTERMEDIARY-Creating logger [" + parentName
+ // + "] with parent " + parent.getName());
+ p = new ControlLogger(parentName, parent);
+ loggerMap.put(parentName, p);
+ }
+ parent = p;
}
+ // make i move past the last found dot.
+ i++;
+ }
}
+ }
- public Map<String, ControlLogger> getLoggerMap() {
- return loggerMap;
- }
+ public Map<String, ControlLogger> getLoggerMap() {
+ return loggerMap;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/control/CreateLogger.java b/logback-classic/src/test/java/ch/qos/logback/classic/control/CreateLogger.java
index fb79ae5..f44e7af 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/control/CreateLogger.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/control/CreateLogger.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,19 +13,20 @@
*/
package ch.qos.logback.classic.control;
+
public class CreateLogger extends ScenarioAction {
- final String loggerName;
+ final String loggerName;
- public CreateLogger(String loggerName) {
- this.loggerName = loggerName;
- }
+ public CreateLogger(String loggerName) {
+ this.loggerName = loggerName;
+ }
- public String getLoggerName() {
- return loggerName;
- }
+ public String getLoggerName() {
+ return loggerName;
+ }
- public String toString() {
- return "CreateLogger(" + loggerName + ")";
- }
+ public String toString() {
+ return "CreateLogger("+loggerName+")";
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/control/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/control/PackageTest.java
index 1a6f48a..0fbc097 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/control/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/control/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,6 +17,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
+
@RunWith(Suite.class)
@SuiteClasses({})
public class PackageTest {
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/control/Scenario.java b/logback-classic/src/test/java/ch/qos/logback/classic/control/Scenario.java
index 72ded3e..0d56f5d 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/control/Scenario.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/control/Scenario.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,21 +19,21 @@ import java.util.Vector;
public class Scenario {
- private List<ScenarioAction> actionList = new Vector<ScenarioAction>();
+ private List<ScenarioAction> actionList = new Vector<ScenarioAction>();
- public void add(ScenarioAction action) {
- actionList.add(action);
- }
+ public void add(ScenarioAction action) {
+ actionList.add(action);
+ }
- public List<ScenarioAction> getActionList() {
- return new ArrayList<ScenarioAction>(actionList);
- }
+ public List<ScenarioAction> getActionList() {
+ return new ArrayList<ScenarioAction>(actionList);
+ }
- public int size() {
- return actionList.size();
- }
+ public int size() {
+ return actionList.size();
+ }
- public ScenarioAction get(int i) {
- return (ScenarioAction) actionList.get(i);
- }
+ public ScenarioAction get(int i) {
+ return (ScenarioAction) actionList.get(i);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/control/ScenarioAction.java b/logback-classic/src/test/java/ch/qos/logback/classic/control/ScenarioAction.java
index 3984431..88d2fc6 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/control/ScenarioAction.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/control/ScenarioAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/control/ScenarioMaker.java b/logback-classic/src/test/java/ch/qos/logback/classic/control/ScenarioMaker.java
index 5e95d21..c386360 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/control/ScenarioMaker.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/control/ScenarioMaker.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,81 +20,84 @@ import ch.qos.logback.core.CoreConstants;
public class ScenarioMaker {
- private final static int AVERAGE_LOGGER_DEPTH = 4;
- private final static int LOGGER_DEPT_DEV = 2;
- // the frequency of a set levelInt event for every create logger event
- private final static int CREATE_LOGGER_TO_SET_LEVEL_FREQUENCY = 5;
- private final static int SECOND_SET_LEVEL_FREQUENCY = 3;
+ private final static int AVERAGE_LOGGER_DEPTH = 4;
+ private final static int LOGGER_DEPT_DEV = 2;
+ // the frequency of a set levelInt event for every create logger event
+ private final static int CREATE_LOGGER_TO_SET_LEVEL_FREQUENCY = 5;
+ private final static int SECOND_SET_LEVEL_FREQUENCY = 3;
- private static long count = 0;
+ private static long count = 0;
- /**
- * Makes a scenario with len logger creations. Logger names are generated
- * independently such that the overwhelming majority of logger names will be
- * unrelated to each other. Each logger creation may be followed with a
- * randomly generated set levelInt action on that logger.
- *
- * @param len
- * @return
- */
- static public Scenario makeTypeAScenario(int len) {
- Scenario scenario = new Scenario();
- ;
- for (int i = 0; i < len; i++) {
- String loggerName = ScenarioRandomUtil.randomLoggerName(AVERAGE_LOGGER_DEPTH, LOGGER_DEPT_DEV);
- scenario.add(new CreateLogger(loggerName));
- }
- return scenario;
+ /**
+ * Makes a scenario with len logger creations. Logger names are generated
+ * independently such that the overwhelming majority of logger names will be
+ * unrelated to each other. Each logger creation may be followed with a
+ * randomly generated set levelInt action on that logger.
+ *
+ * @param len
+ * @return
+ */
+ static public Scenario makeTypeAScenario(int len) {
+ Scenario scenario = new Scenario();
+ ;
+ for (int i = 0; i < len; i++) {
+ String loggerName = ScenarioRandomUtil.randomLoggerName(
+ AVERAGE_LOGGER_DEPTH, LOGGER_DEPT_DEV);
+ scenario.add(new CreateLogger(loggerName));
}
+ return scenario;
+ }
- static public Scenario makeRealisticCreationScenario(int len) {
- Scenario scenario = new Scenario();
- LinkedList<String> queue = new LinkedList<String>();
- int loggerCreationCount = 0;
+ static public Scenario makeRealisticCreationScenario(int len) {
+ Scenario scenario = new Scenario();
+ LinkedList<String> queue = new LinkedList<String>();
+ int loggerCreationCount = 0;
- // add an empty string to get going
- queue.add("");
+ // add an empty string to get going
+ queue.add("");
- while (loggerCreationCount < len) {
- if ((count % 100) == 0) {
- System.out.println("count=" + count);
- }
+ while (loggerCreationCount < len) {
+ if ((count % 100) == 0) {
+ System.out.println("count=" + count);
+ }
- String loggerName = (String) queue.removeFirst();
- int randomChildrenCount = ScenarioRandomUtil.randomChildrenCount(loggerName);
+ String loggerName = (String) queue.removeFirst();
+ int randomChildrenCount = ScenarioRandomUtil
+ .randomChildrenCount(loggerName);
- if (randomChildrenCount == 0) {
- scenario.add(new CreateLogger(loggerName));
- addSetLevelSubScenario(scenario, loggerName);
- loggerCreationCount++;
- } else {
- for (int i = 0; i < randomChildrenCount; i++) {
- String childName;
- if (loggerName.equals("")) {
- childName = ScenarioRandomUtil.randomId();
- count += childName.length();
- } else {
- childName = loggerName + CoreConstants.DOT + ScenarioRandomUtil.randomId();
- count += childName.length();
- }
- queue.add(childName);
- addSetLevelSubScenario(scenario, loggerName);
- loggerCreationCount++;
- }
- }
+ if (randomChildrenCount == 0) {
+ scenario.add(new CreateLogger(loggerName));
+ addSetLevelSubScenario(scenario, loggerName);
+ loggerCreationCount++;
+ } else {
+ for (int i = 0; i < randomChildrenCount; i++) {
+ String childName;
+ if (loggerName.equals("")) {
+ childName = ScenarioRandomUtil.randomId();
+ count += childName.length();
+ } else {
+ childName = loggerName + CoreConstants.DOT
+ + ScenarioRandomUtil.randomId();
+ count += childName.length();
+ }
+ queue.add(childName);
+ addSetLevelSubScenario(scenario, loggerName);
+ loggerCreationCount++;
}
- return scenario;
+ }
}
+ return scenario;
+ }
- static void addSetLevelSubScenario(Scenario scenario, String loggerName) {
- if (ScenarioRandomUtil.oneInFreq(CREATE_LOGGER_TO_SET_LEVEL_FREQUENCY)) {
- Level l = ScenarioRandomUtil.randomLevel();
- scenario.add(new SetLevel(l, loggerName));
- if (ScenarioRandomUtil.oneInFreq(SECOND_SET_LEVEL_FREQUENCY)) {
- l = ScenarioRandomUtil.randomLevel();
- scenario.add(new SetLevel(l, loggerName));
- }
- }
+ static void addSetLevelSubScenario(Scenario scenario, String loggerName) {
+ if (ScenarioRandomUtil.oneInFreq(CREATE_LOGGER_TO_SET_LEVEL_FREQUENCY)) {
+ Level l = ScenarioRandomUtil.randomLevel();
+ scenario.add(new SetLevel(l, loggerName));
+ if (ScenarioRandomUtil.oneInFreq(SECOND_SET_LEVEL_FREQUENCY)) {
+ l = ScenarioRandomUtil.randomLevel();
+ scenario.add(new SetLevel(l, loggerName));
+ }
}
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/control/ScenarioRandomUtil.java b/logback-classic/src/test/java/ch/qos/logback/classic/control/ScenarioRandomUtil.java
index 118b212..bd85fec 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/control/ScenarioRandomUtil.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/control/ScenarioRandomUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,114 +19,117 @@ import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.corpus.RandomUtil;
public class ScenarioRandomUtil {
- private final static long SEED = 74130;
+ private final static long SEED = 74130;
- private final static Random random = new Random(SEED);
- private final static int AVERAGE_ID_LEN = 32;
- private final static int AVERAGE_ID_DEV = 16;
+ private final static Random random = new Random(SEED);
+ private final static int AVERAGE_ID_LEN = 32;
+ private final static int AVERAGE_ID_DEV = 16;
- private final static int AVERAGE_CHILDREN_COUNT = 30;
- private final static int CHILDREN_COUNT_VAR = 10;
+ private final static int AVERAGE_CHILDREN_COUNT = 30;
+ private final static int CHILDREN_COUNT_VAR = 10;
- public static boolean oneInFreq(int freq) {
- return (random.nextInt(freq) % freq) == 0;
- }
+ public static boolean oneInFreq(int freq) {
+ return (random.nextInt(freq) % freq) == 0;
+ }
- public static Level randomLevel() {
- int rl = random.nextInt(6);
- switch (rl) {
- case 0:
- return null;
- case 1:
- return Level.TRACE;
- case 2:
- return Level.DEBUG;
- case 3:
- return Level.INFO;
- case 4:
- return Level.WARN;
- case 5:
- return Level.ERROR;
- default:
- throw new IllegalStateException("rl should have been a value between 0 to 5, but it is " + rl);
- }
+ public static Level randomLevel() {
+ int rl = random.nextInt(6);
+ switch (rl) {
+ case 0:
+ return null;
+ case 1:
+ return Level.TRACE;
+ case 2:
+ return Level.DEBUG;
+ case 3:
+ return Level.INFO;
+ case 4:
+ return Level.WARN;
+ case 5:
+ return Level.ERROR;
+ default:
+ throw new IllegalStateException(
+ "rl should have been a value between 0 to 5, but it is " + rl);
}
+ }
- public static String randomLoggerName(int average, int stdDeviation) {
- int depth = RandomUtil.gaussianAsPositiveInt(random, average, stdDeviation);
- StringBuilder buf = new StringBuilder();
- for (int i = 0; i < depth; i++) {
- if (i != 0) {
- buf.append('.');
- }
- buf.append(randomId());
- }
- return buf.toString();
+ public static String randomLoggerName(int average, int stdDeviation) {
+ int depth = RandomUtil.gaussianAsPositiveInt(random, average, stdDeviation);
+ StringBuilder buf = new StringBuilder();
+ for (int i = 0; i < depth; i++) {
+ if (i != 0) {
+ buf.append('.');
+ }
+ buf.append(randomId());
}
+ return buf.toString();
+ }
- public static String randomId() {
+ public static String randomId() {
- int len = RandomUtil.gaussianAsPositiveInt(random, AVERAGE_ID_LEN, AVERAGE_ID_DEV);
- StringBuilder buf = new StringBuilder();
- for (int i = 0; i < len; i++) {
- int offset = random.nextInt(26);
- char c = (char) ('a' + offset);
- buf.append(c);
- }
- return buf.toString();
+ int len = RandomUtil.gaussianAsPositiveInt(random, AVERAGE_ID_LEN, AVERAGE_ID_DEV);
+ StringBuilder buf = new StringBuilder();
+ for (int i = 0; i < len; i++) {
+ int offset = random.nextInt(26);
+ char c = (char) ('a' + offset);
+ buf.append(c);
}
+ return buf.toString();
+ }
- /**
- * Returns 3 for root, 3 for children of root, 9 for offspring of generation 2
- * and 3, and for generations 4 and later, return 0 with probability 0.5 and a
- * gaussian (average=AVERAGE_CHILDREN_COUNT) with probability 0.5.
- *
- * @param name
- * @return
- */
- public static int randomChildrenCount(String name) {
- int dots = dotCount(name);
- if (dots <= 1) {
- return 3;
- } else if (dots == 2 || dots == 3) {
- return 9;
- } else {
- if (shouldHaveChildrenWithProbabilitz(0.5)) {
- return RandomUtil.gaussianAsPositiveInt(random, AVERAGE_CHILDREN_COUNT, CHILDREN_COUNT_VAR);
- } else {
- return 0;
- }
- }
+ /**
+ * Returns 3 for root, 3 for children of root, 9 for offspring of generation 2
+ * and 3, and for generations 4 and later, return 0 with probability 0.5 and a
+ * gaussian (average=AVERAGE_CHILDREN_COUNT) with probability 0.5.
+ *
+ * @param name
+ * @return
+ */
+ public static int randomChildrenCount(String name) {
+ int dots = dotCount(name);
+ if (dots <= 1) {
+ return 3;
+ } else if (dots == 2 || dots == 3) {
+ return 9;
+ } else {
+ if (shouldHaveChildrenWithProbabilitz(0.5)) {
+ return RandomUtil.gaussianAsPositiveInt(random, AVERAGE_CHILDREN_COUNT, CHILDREN_COUNT_VAR);
+ } else {
+ return 0;
+ }
}
- /**
- * Returns true with probability p.
- *
- * @param p
- * @return
- */
- static boolean shouldHaveChildrenWithProbabilitz(double p) {
- if (p < 0 || p > 1.0) {
- throw new IllegalArgumentException("p must be a value between 0 and 1.0, it was " + p + " instead.");
- }
- double r = random.nextDouble();
- if (r < p) {
- return true;
- } else {
- return false;
- }
+ }
+
+ /**
+ * Returns true with probability p.
+ *
+ * @param p
+ * @return
+ */
+ static boolean shouldHaveChildrenWithProbabilitz(double p) {
+ if (p < 0 || p > 1.0) {
+ throw new IllegalArgumentException(
+ "p must be a value between 0 and 1.0, it was " + p + " instead.");
+ }
+ double r = random.nextDouble();
+ if (r < p) {
+ return true;
+ } else {
+ return false;
}
+ }
- static int dotCount(String s) {
- int count = 0;
- int len = s.length();
- for (int i = 0; i < len; i++) {
- char c = s.charAt(i);
- if (c == '.') {
- count++;
- }
- }
- return count;
+ static int dotCount(String s) {
+ int count = 0;
+ int len = s.length();
+ for (int i = 0; i < len; i++) {
+ char c = s.charAt(i);
+ if (c == '.') {
+ count++;
+ }
}
+ return count;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/control/SetLevel.java b/logback-classic/src/test/java/ch/qos/logback/classic/control/SetLevel.java
index e2e21d2..cb65bcb 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/control/SetLevel.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/control/SetLevel.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,23 +16,22 @@ package ch.qos.logback.classic.control;
import ch.qos.logback.classic.Level;
public class SetLevel extends ScenarioAction {
- final String loggerName;
- final Level level;
+ final String loggerName;
+ final Level level;
- public SetLevel(Level level, String loggerName) {
- this.level = level;
- this.loggerName = loggerName;
- }
+ public SetLevel(Level level, String loggerName) {
+ this.level = level;
+ this.loggerName = loggerName;
+ }
- public Level getLevel() {
- return level;
- }
+ public Level getLevel() {
+ return level;
+ }
- public String getLoggerName() {
- return loggerName;
- }
-
- public String toString() {
- return "SetLevel(" + level + ", " + loggerName + ")";
- }
+ public String getLoggerName() {
+ return loggerName;
+ }
+ public String toString() {
+ return "SetLevel("+level+", "+loggerName+")";
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/corpus/Corpus.java b/logback-classic/src/test/java/ch/qos/logback/classic/corpus/Corpus.java
index 873649b..b7f766e 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/corpus/Corpus.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/corpus/Corpus.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -43,71 +43,76 @@ import ch.qos.logback.core.CoreConstants;
*/
public class Corpus {
- static public final int STANDARD_CORPUS_SIZE = 50 * 1000;
- private static final int STANDARD_SEED = 34780;
+ static public final int STANDARD_CORPUS_SIZE = 50 * 1000;
+ private static final int STANDARD_SEED = 34780;
- static public List<String> getStandatdCorpusWordList() throws IOException {
- ClassLoader classLoader = Corpus.class.getClassLoader();
- URL originOfSpeciesURL = classLoader.getResource("corpus/origin_of_species.txt");
- return TextFileUtil.toWords(originOfSpeciesURL);
- }
+ static public List<String> getStandatdCorpusWordList() throws IOException {
+ ClassLoader classLoader = Corpus.class.getClassLoader();
+ URL originOfSpeciesURL = classLoader
+ .getResource("corpus/origin_of_species.txt");
+ return TextFileUtil.toWords(originOfSpeciesURL);
+ }
- /**
- * Make a standard corpus. The standard corpus has
- * {@link #STANDARD_CORPUS_SIZE} elements.
- *
- * @return event array representing the standard corpus
- * @throws IOException
- */
- static public ILoggingEvent[] makeStandardCorpus() throws IOException {
- List<String> worldList = getStandatdCorpusWordList();
- CorpusModel corpusMaker = new CorpusModel(STANDARD_SEED, worldList);
- return make(corpusMaker, STANDARD_CORPUS_SIZE, true);
- }
+ /**
+ * Make a standard corpus. The standard corpus has
+ * {@link #STANDARD_CORPUS_SIZE} elements.
+ *
+ * @return event array representing the standard corpus
+ * @throws IOException
+ */
+ static public ILoggingEvent[] makeStandardCorpus() throws IOException {
+ List<String> worldList = getStandatdCorpusWordList();
+ CorpusModel corpusMaker = new CorpusModel(STANDARD_SEED, worldList);
+ return make(corpusMaker, STANDARD_CORPUS_SIZE, true);
+ }
- static public ILoggingEvent[] make(CorpusModel corpusModel, int n, boolean withCallerData) {
- LoggerContextVO lcVO = corpusModel.getRandomlyNamedLoggerContextVO();
- PubLoggingEventVO[] plevoArray = new PubLoggingEventVO[n];
- for (int i = 0; i < n; i++) {
- PubLoggingEventVO e = new PubLoggingEventVO();
- plevoArray[i] = e;
- e.loggerContextVO = lcVO;
- e.timeStamp = corpusModel.getRandomTimeStamp();
+ static public ILoggingEvent[] make(CorpusModel corpusModel, int n,
+ boolean withCallerData) {
+ LoggerContextVO lcVO = corpusModel.getRandomlyNamedLoggerContextVO();
+ PubLoggingEventVO[] plevoArray = new PubLoggingEventVO[n];
+ for (int i = 0; i < n; i++) {
+ PubLoggingEventVO e = new PubLoggingEventVO();
+ plevoArray[i] = e;
+ e.loggerContextVO = lcVO;
+ e.timeStamp = corpusModel.getRandomTimeStamp();
- LogStatement logStatement = corpusModel.getRandomLogStatementFromPool();
- e.loggerName = logStatement.loggerName;
- e.level = logStatement.level;
- e.message = logStatement.mat.message;
- e.argumentArray = corpusModel.getRandomArgumentArray(logStatement.mat.numberOfArguments);
+ LogStatement logStatement = corpusModel.getRandomLogStatementFromPool();
+ e.loggerName = logStatement.loggerName;
+ e.level = logStatement.level;
+ e.message = logStatement.mat.message;
+ e.argumentArray = corpusModel
+ .getRandomArgumentArray(logStatement.mat.numberOfArguments);
- if (withCallerData) {
- e.callerDataArray = corpusModel.getRandomCallerData(ClassicConstants.DEFAULT_MAX_CALLEDER_DATA_DEPTH, e.loggerName);
- }
- e.throwableProxy = logStatement.throwableProxy;
- e.threadName = corpusModel.getRandomThreadNameFromPool();
- }
- return plevoArray;
+ if (withCallerData) {
+ e.callerDataArray = corpusModel.getRandomCallerData(
+ ClassicConstants.DEFAULT_MAX_CALLEDER_DATA_DEPTH, e.loggerName);
+ }
+ e.throwableProxy = logStatement.throwableProxy;
+ e.threadName = corpusModel.getRandomThreadNameFromPool();
}
+ return plevoArray;
+ }
- /**
- * Dump the events passed as argument into the file named targetFile.
- *
- * @param eventArray
- * @param targetFile
- * @throws IOException
- */
- public static void dump(ILoggingEvent[] eventArray, String targetFile) throws IOException {
- FileWriter fw = new FileWriter(targetFile);
- for (ILoggingEvent e : eventArray) {
- fw.write(e.toString());
- fw.append(CoreConstants.LINE_SEPARATOR);
- if (e.getThrowableProxy() != null) {
- IThrowableProxy tp = e.getThrowableProxy();
- fw.write(ThrowableProxyUtil.asString(tp));
- }
- }
- fw.flush();
- fw.close();
+ /**
+ * Dump the events passed as argument into the file named targetFile.
+ *
+ * @param eventArray
+ * @param targetFile
+ * @throws IOException
+ */
+ public static void dump(ILoggingEvent[] eventArray, String targetFile)
+ throws IOException {
+ FileWriter fw = new FileWriter(targetFile);
+ for (ILoggingEvent e : eventArray) {
+ fw.write(e.toString());
+ fw.append(CoreConstants.LINE_SEPARATOR);
+ if (e.getThrowableProxy() != null) {
+ IThrowableProxy tp = e.getThrowableProxy();
+ fw.write(ThrowableProxyUtil.asString(tp));
+ }
}
+ fw.flush();
+ fw.close();
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/corpus/CorpusModel.java b/logback-classic/src/test/java/ch/qos/logback/classic/corpus/CorpusModel.java
index e43326e..bed8f5e 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/corpus/CorpusModel.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/corpus/CorpusModel.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -35,282 +35,289 @@ import ch.qos.logback.classic.spi.ThrowableProxyVO;
*/
public class CorpusModel {
- // N(u,s) denotes a random variable normally distributed with mean u and
- // variance sqrt(s), where sqrt() is the square root function. For an
- // explanation of normal distribution please see
- // http://en.wikipedia.org/wiki/Normal_distribution
-
- // It is assumed that the number of parts in a logger name is a random
- // variable normally distributed with mean AVERAGE_LOGGER_NAME_PARTS and
- // standard deviation STD_DEV_FOR_LOGGER_NAME_PARTS
- static final int AVERAGE_LOGGER_NAME_PARTS = 6;
- static final int STD_DEV_FOR_LOGGER_NAME_PARTS = 3;
-
- // It is assumed that there are LOGGER_POOL_SIZE logger names
- // in our model corpus.
- static final int LOGGER_POOL_SIZE = 1000;
-
- // It is assumed that there are LOG_STATEMENT_POOL_SIZE log statements
- // in our model corpus.
- static final int LOG_STATEMENT_POOL_SIZE = LOGGER_POOL_SIZE * 8;
-
- // level distribution is determined by the following table
- // It corresponds to TRACE 3%, DEBUG 30%, INFO 30%, WARN 5%,
- // ERROR 5%. See also getRandomLevel() method.
- static final double[] LEVEL_DISTRIBUTION = new double[] { .3, .3, .9, .95 };
-
- // It is assumed that the number of words in the message (contained in a log
- // statement) is a random variable normally distributed with mean
- // AVERAGE_MESSAGE_WORDS and standard deviation STD_DEV_FOR_MESSAGE_WORDS
- static final int AVERAGE_MESSAGE_WORDS = 8;
- static final int STD_DEV_FOR_MESSAGE_WORDS = 4;
-
- // messages will have no arguments 80% of the time, one argument in 8%, two
- // arguments in 7% and three arguments in 5% of cases
- static final double[] ARGUMENT_DISTRIBUTION = new double[] { .80, .88, 0.95 };
-
- static final double THROWABLE_PROPABILITY_FOR_WARNING = .1;
- static final double THROWABLE_PROPABILITY_FOR_ERRORS = .3;
- // .5 of throwables are nested once
- static final double NESTING_PROBABILITY = .5;
-
- // For each logging event the timer is incremented by a certain value. it is
- // assumed that this value is a random variable normally distributed with mean
- // AVERAGE_MILLIS_INCREMENT and standard deviation
- // STD_DEV_FOR_MILLIS_INCREMENT
- static final int AVERAGE_MILLIS_INCREMENT = 10;
- static final int STD_DEV_FOR_MILLIS_INCREMENT = 5;
-
- // assume that there are THREAD_POOL_SIZE threads in the corpus
- static final int THREAD_POOL_SIZE = 10;
-
- final Random random;
- final List<String> worldList;
- String[] threadNamePool;
- LogStatement[] logStatementPool;
- String[] loggerNamePool;
-
- // 2009-03-06 13:08 GMT
- long lastTimeStamp = 1236344888578L;
-
- public CorpusModel(long seed, List<String> worldList) {
- random = new Random(seed);
- this.worldList = worldList;
- buildThreadNamePool();
- buildLoggerNamePool();
- buildLogStatementPool();
+ // N(u,s) denotes a random variable normally distributed with mean u and
+ // variance sqrt(s), where sqrt() is the square root function. For an
+ // explanation of normal distribution please see
+ // http://en.wikipedia.org/wiki/Normal_distribution
+
+ // It is assumed that the number of parts in a logger name is a random
+ // variable normally distributed with mean AVERAGE_LOGGER_NAME_PARTS and
+ // standard deviation STD_DEV_FOR_LOGGER_NAME_PARTS
+ static final int AVERAGE_LOGGER_NAME_PARTS = 6;
+ static final int STD_DEV_FOR_LOGGER_NAME_PARTS = 3;
+
+ // It is assumed that there are LOGGER_POOL_SIZE logger names
+ // in our model corpus.
+ static final int LOGGER_POOL_SIZE = 1000;
+
+ // It is assumed that there are LOG_STATEMENT_POOL_SIZE log statements
+ // in our model corpus.
+ static final int LOG_STATEMENT_POOL_SIZE = LOGGER_POOL_SIZE * 8;
+
+ // level distribution is determined by the following table
+ // It corresponds to TRACE 3%, DEBUG 30%, INFO 30%, WARN 5%,
+ // ERROR 5%. See also getRandomLevel() method.
+ static final double[] LEVEL_DISTRIBUTION = new double[] { .3, .3, .9, .95 };
+
+ // It is assumed that the number of words in the message (contained in a log
+ // statement) is a random variable normally distributed with mean
+ // AVERAGE_MESSAGE_WORDS and standard deviation STD_DEV_FOR_MESSAGE_WORDS
+ static final int AVERAGE_MESSAGE_WORDS = 8;
+ static final int STD_DEV_FOR_MESSAGE_WORDS = 4;
+
+ // messages will have no arguments 80% of the time, one argument in 8%, two
+ // arguments in 7% and three arguments in 5% of cases
+ static final double[] ARGUMENT_DISTRIBUTION = new double[] { .80, .88, 0.95 };
+
+ static final double THROWABLE_PROPABILITY_FOR_WARNING = .1;
+ static final double THROWABLE_PROPABILITY_FOR_ERRORS = .3;
+ // .5 of throwables are nested once
+ static final double NESTING_PROBABILITY = .5;
+
+ // For each logging event the timer is incremented by a certain value. it is
+ // assumed that this value is a random variable normally distributed with mean
+ // AVERAGE_MILLIS_INCREMENT and standard deviation
+ // STD_DEV_FOR_MILLIS_INCREMENT
+ static final int AVERAGE_MILLIS_INCREMENT = 10;
+ static final int STD_DEV_FOR_MILLIS_INCREMENT = 5;
+
+ // assume that there are THREAD_POOL_SIZE threads in the corpus
+ static final int THREAD_POOL_SIZE = 10;
+
+ final Random random;
+ final List<String> worldList;
+ String[] threadNamePool;
+ LogStatement[] logStatementPool;
+ String[] loggerNamePool;
+
+ // 2009-03-06 13:08 GMT
+ long lastTimeStamp = 1236344888578L;
+
+ public CorpusModel(long seed, List<String> worldList) {
+ random = new Random(seed);
+ this.worldList = worldList;
+ buildThreadNamePool();
+ buildLoggerNamePool();
+ buildLogStatementPool();
+ }
+
+ private void buildThreadNamePool() {
+ threadNamePool = new String[THREAD_POOL_SIZE];
+ for (int i = 0; i < THREAD_POOL_SIZE; i++) {
+ threadNamePool[i] = "CorpusMakerThread-" + i;
}
+ }
- private void buildThreadNamePool() {
- threadNamePool = new String[THREAD_POOL_SIZE];
- for (int i = 0; i < THREAD_POOL_SIZE; i++) {
- threadNamePool[i] = "CorpusMakerThread-" + i;
- }
+ private void buildLoggerNamePool() {
+ loggerNamePool = new String[LOGGER_POOL_SIZE];
+ for (int i = 0; i < LOGGER_POOL_SIZE; i++) {
+ loggerNamePool[i] = makeRandomLoggerName();
}
+ }
- private void buildLoggerNamePool() {
- loggerNamePool = new String[LOGGER_POOL_SIZE];
- for (int i = 0; i < LOGGER_POOL_SIZE; i++) {
- loggerNamePool[i] = makeRandomLoggerName();
- }
+ private void buildLogStatementPool() {
+ logStatementPool = new LogStatement[LOG_STATEMENT_POOL_SIZE];
+ for (int i = 0; i < LOG_STATEMENT_POOL_SIZE; i++) {
+ logStatementPool[i] = makeRandomLogStatement(loggerNamePool);
}
-
- private void buildLogStatementPool() {
- logStatementPool = new LogStatement[LOG_STATEMENT_POOL_SIZE];
- for (int i = 0; i < LOG_STATEMENT_POOL_SIZE; i++) {
- logStatementPool[i] = makeRandomLogStatement(loggerNamePool);
- }
+ }
+
+ private int[] getRandomAnchorPositions(int wordCount, int numAnchors) {
+ // note that the same position may appear multiple times in
+ // positionsIndex, but without serious consequences
+ int[] positionsIndex = new int[numAnchors];
+ for (int i = 0; i < numAnchors; i++) {
+ positionsIndex[i] = random.nextInt(wordCount);
}
+ return positionsIndex;
+ }
- private int[] getRandomAnchorPositions(int wordCount, int numAnchors) {
- // note that the same position may appear multiple times in
- // positionsIndex, but without serious consequences
- int[] positionsIndex = new int[numAnchors];
- for (int i = 0; i < numAnchors; i++) {
- positionsIndex[i] = random.nextInt(wordCount);
- }
- return positionsIndex;
+ private String[] getRandomWords(int n) {
+ String[] wordArray = new String[n];
+ for (int i = 0; i < n; i++) {
+ wordArray[i] = getRandomWord();
}
-
- private String[] getRandomWords(int n) {
- String[] wordArray = new String[n];
- for (int i = 0; i < n; i++) {
- wordArray[i] = getRandomWord();
- }
- return wordArray;
+ return wordArray;
+ }
+
+ public long getRandomLong() {
+ return random.nextLong();
+ }
+
+ public String getRandomThreadNameFromPool() {
+ int index = random.nextInt(THREAD_POOL_SIZE);
+ return threadNamePool[index];
+ }
+
+ public LogStatement getRandomLogStatementFromPool() {
+ int index = random.nextInt(logStatementPool.length);
+ return logStatementPool[index];
+ }
+
+ private String getRandomLoggerNameFromPool(String[] loggerNamePool) {
+ int index = random.nextInt(loggerNamePool.length);
+ return loggerNamePool[index];
+ }
+
+ public long getRandomTimeStamp() {
+ // subtract 1 so that 0 is allowed
+ lastTimeStamp += RandomUtil.gaussianAsPositiveInt(random,
+ AVERAGE_MILLIS_INCREMENT, STD_DEV_FOR_MILLIS_INCREMENT) - 1;
+ return lastTimeStamp;
+ }
+
+ LoggerContextVO getRandomlyNamedLoggerContextVO() {
+ LoggerContext lc = new LoggerContext();
+ lc.setName(getRandomJavaIdentifier());
+ return new LoggerContextVO(lc);
+ }
+
+ String getRandomWord() {
+ int size = worldList.size();
+ int randomIndex = random.nextInt(size);
+ return worldList.get(randomIndex);
+ }
+
+ String extractLastPart(String loggerName) {
+ int i = loggerName.lastIndexOf('.');
+ if (i == -1) {
+ return loggerName;
+ } else {
+ return loggerName.substring(i + 1);
}
-
- public long getRandomLong() {
- return random.nextLong();
+ }
+
+ public StackTraceElement[] getRandomCallerData(int depth, String loggerName) {
+ StackTraceElement[] cda = new StackTraceElement[depth];
+ StackTraceElement cd = new StackTraceElement(loggerName,
+ getRandomJavaIdentifier(), extractLastPart(loggerName), 0);
+ cda[0] = cd;
+ for (int i = 1; i < depth; i++) {
+ String ln = getRandomLoggerNameFromPool(loggerNamePool);
+ cda[i] = new StackTraceElement(ln, getRandomJavaIdentifier(),
+ extractLastPart(ln), i * 10);
}
+ return cda;
+ }
- public String getRandomThreadNameFromPool() {
- int index = random.nextInt(THREAD_POOL_SIZE);
- return threadNamePool[index];
+ public Object[] getRandomArgumentArray(int numOfArguments) {
+ if (numOfArguments == 0) {
+ return null;
}
-
- public LogStatement getRandomLogStatementFromPool() {
- int index = random.nextInt(logStatementPool.length);
- return logStatementPool[index];
+ Object[] argumentArray = new Object[numOfArguments];
+ for (int i = 0; i < numOfArguments; i++) {
+ argumentArray[i] = new Long(random.nextLong());
}
+ return argumentArray;
+ }
- private String getRandomLoggerNameFromPool(String[] loggerNamePool) {
- int index = random.nextInt(loggerNamePool.length);
- return loggerNamePool[index];
- }
+ private MessageArgumentTuple makeRandomMessageArgumentTuple() {
+ int numOfArguments = getNumberOfMessageArguments();
- public long getRandomTimeStamp() {
- // subtract 1 so that 0 is allowed
- lastTimeStamp += RandomUtil.gaussianAsPositiveInt(random, AVERAGE_MILLIS_INCREMENT, STD_DEV_FOR_MILLIS_INCREMENT) - 1;
- return lastTimeStamp;
- }
+ int wordCount = RandomUtil.gaussianAsPositiveInt(random,
+ AVERAGE_MESSAGE_WORDS, STD_DEV_FOR_MESSAGE_WORDS);
+ String[] wordArray = getRandomWords(wordCount);
- LoggerContextVO getRandomlyNamedLoggerContextVO() {
- LoggerContext lc = new LoggerContext();
- lc.setName(getRandomJavaIdentifier());
- return new LoggerContextVO(lc);
- }
+ int[] anchorPositions = getRandomAnchorPositions(wordCount, numOfArguments);
- String getRandomWord() {
- int size = worldList.size();
- int randomIndex = random.nextInt(size);
- return worldList.get(randomIndex);
+ for (int anchorIndex : anchorPositions) {
+ wordArray[anchorIndex] = "{}";
}
- String extractLastPart(String loggerName) {
- int i = loggerName.lastIndexOf('.');
- if (i == -1) {
- return loggerName;
- } else {
- return loggerName.substring(i + 1);
- }
+ StringBuilder sb = new StringBuilder();
+ for (int i = 1; i < wordCount; i++) {
+ sb.append(wordArray[i]).append(' ');
}
-
- public StackTraceElement[] getRandomCallerData(int depth, String loggerName) {
- StackTraceElement[] cda = new StackTraceElement[depth];
- StackTraceElement cd = new StackTraceElement(loggerName, getRandomJavaIdentifier(), extractLastPart(loggerName), 0);
- cda[0] = cd;
- for (int i = 1; i < depth; i++) {
- String ln = getRandomLoggerNameFromPool(loggerNamePool);
- cda[i] = new StackTraceElement(ln, getRandomJavaIdentifier(), extractLastPart(ln), i * 10);
- }
- return cda;
+ sb.append(getRandomWord());
+ return new MessageArgumentTuple(sb.toString(), numOfArguments);
+ }
+
+ private LogStatement makeRandomLogStatement(String[] loggerNamePool) {
+ MessageArgumentTuple mat = makeRandomMessageArgumentTuple();
+ String loggerName = getRandomLoggerNameFromPool(loggerNamePool);
+ Level randomLevel = getRandomLevel();
+ Throwable t = getRandomThrowable(randomLevel);
+ ThrowableProxyVO throwableProxy = null;
+ if (t != null) {
+ throwableProxy = ThrowableProxyVO.build(new ThrowableProxy(t));
+ pupulateWithPackagingData(throwableProxy.getStackTraceElementProxyArray());
}
-
- public Object[] getRandomArgumentArray(int numOfArguments) {
- if (numOfArguments == 0) {
- return null;
- }
- Object[] argumentArray = new Object[numOfArguments];
- for (int i = 0; i < numOfArguments; i++) {
- argumentArray[i] = new Long(random.nextLong());
- }
- return argumentArray;
+ return new LogStatement(loggerName, randomLevel, mat,
+ throwableProxy);
+ }
+
+ private Throwable getRandomThrowable(Level level) {
+ double rn = random.nextDouble();
+ if ((level == Level.WARN && rn < THROWABLE_PROPABILITY_FOR_WARNING)
+ || (level == Level.ERROR && rn < THROWABLE_PROPABILITY_FOR_ERRORS)) {
+ return ExceptionBuilder.build(random, NESTING_PROBABILITY);
+ } else {
+ return null;
}
-
- private MessageArgumentTuple makeRandomMessageArgumentTuple() {
- int numOfArguments = getNumberOfMessageArguments();
-
- int wordCount = RandomUtil.gaussianAsPositiveInt(random, AVERAGE_MESSAGE_WORDS, STD_DEV_FOR_MESSAGE_WORDS);
- String[] wordArray = getRandomWords(wordCount);
-
- int[] anchorPositions = getRandomAnchorPositions(wordCount, numOfArguments);
-
- for (int anchorIndex : anchorPositions) {
- wordArray[anchorIndex] = "{}";
- }
-
- StringBuilder sb = new StringBuilder();
- for (int i = 1; i < wordCount; i++) {
- sb.append(wordArray[i]).append(' ');
- }
- sb.append(getRandomWord());
- return new MessageArgumentTuple(sb.toString(), numOfArguments);
+ }
+
+ private void pupulateWithPackagingData(StackTraceElementProxy[] stepArray) {
+ int i = 0;
+ for (StackTraceElementProxy step : stepArray) {
+ String identifier = "na";
+ String version = "na";
+ if (i++ % 2 == 0) {
+ identifier = getRandomJavaIdentifier();
+ version = getRandomJavaIdentifier();
+ }
+ ClassPackagingData cpd = new ClassPackagingData(identifier, version);
+ step.setClassPackagingData(cpd);
}
+ }
- private LogStatement makeRandomLogStatement(String[] loggerNamePool) {
- MessageArgumentTuple mat = makeRandomMessageArgumentTuple();
- String loggerName = getRandomLoggerNameFromPool(loggerNamePool);
- Level randomLevel = getRandomLevel();
- Throwable t = getRandomThrowable(randomLevel);
- ThrowableProxyVO throwableProxy = null;
- if (t != null) {
- throwableProxy = ThrowableProxyVO.build(new ThrowableProxy(t));
- pupulateWithPackagingData(throwableProxy.getStackTraceElementProxyArray());
- }
- return new LogStatement(loggerName, randomLevel, mat, throwableProxy);
+ private int getNumberOfMessageArguments() {
+ double rn = random.nextDouble();
+ if (rn < ARGUMENT_DISTRIBUTION[0]) {
+ return 0;
}
-
- private Throwable getRandomThrowable(Level level) {
- double rn = random.nextDouble();
- if ((level == Level.WARN && rn < THROWABLE_PROPABILITY_FOR_WARNING) || (level == Level.ERROR && rn < THROWABLE_PROPABILITY_FOR_ERRORS)) {
- return ExceptionBuilder.build(random, NESTING_PROBABILITY);
- } else {
- return null;
- }
+ if (rn < ARGUMENT_DISTRIBUTION[1]) {
+ return 1;
}
-
- private void pupulateWithPackagingData(StackTraceElementProxy[] stepArray) {
- int i = 0;
- for (StackTraceElementProxy step : stepArray) {
- String identifier = "na";
- String version = "na";
- if (i++ % 2 == 0) {
- identifier = getRandomJavaIdentifier();
- version = getRandomJavaIdentifier();
- }
- ClassPackagingData cpd = new ClassPackagingData(identifier, version);
- step.setClassPackagingData(cpd);
- }
+ if (rn < ARGUMENT_DISTRIBUTION[2]) {
+ return 2;
}
-
- private int getNumberOfMessageArguments() {
- double rn = random.nextDouble();
- if (rn < ARGUMENT_DISTRIBUTION[0]) {
- return 0;
- }
- if (rn < ARGUMENT_DISTRIBUTION[1]) {
- return 1;
- }
- if (rn < ARGUMENT_DISTRIBUTION[2]) {
- return 2;
- }
- return 3;
+ return 3;
+ }
+
+ String getRandomJavaIdentifier() {
+ String w = getRandomWord();
+ w = w.replaceAll("\\p{Punct}", "");
+ return w;
+ }
+
+ private String makeRandomLoggerName() {
+ int parts = RandomUtil.gaussianAsPositiveInt(random,
+ AVERAGE_LOGGER_NAME_PARTS, STD_DEV_FOR_LOGGER_NAME_PARTS);
+ StringBuilder sb = new StringBuilder();
+ for (int i = 1; i < parts; i++) {
+ sb.append(getRandomJavaIdentifier()).append('.');
}
-
- String getRandomJavaIdentifier() {
- String w = getRandomWord();
- w = w.replaceAll("\\p{Punct}", "");
- return w;
+ sb.append(getRandomJavaIdentifier());
+ return sb.toString();
+ }
+
+ private Level getRandomLevel() {
+ double rn = random.nextDouble();
+ if (rn < LEVEL_DISTRIBUTION[0]) {
+ return Level.TRACE;
}
-
- private String makeRandomLoggerName() {
- int parts = RandomUtil.gaussianAsPositiveInt(random, AVERAGE_LOGGER_NAME_PARTS, STD_DEV_FOR_LOGGER_NAME_PARTS);
- StringBuilder sb = new StringBuilder();
- for (int i = 1; i < parts; i++) {
- sb.append(getRandomJavaIdentifier()).append('.');
- }
- sb.append(getRandomJavaIdentifier());
- return sb.toString();
+ if (rn < LEVEL_DISTRIBUTION[1]) {
+ return Level.DEBUG;
}
- private Level getRandomLevel() {
- double rn = random.nextDouble();
- if (rn < LEVEL_DISTRIBUTION[0]) {
- return Level.TRACE;
- }
- if (rn < LEVEL_DISTRIBUTION[1]) {
- return Level.DEBUG;
- }
-
- if (rn < LEVEL_DISTRIBUTION[2]) {
- return Level.INFO;
- }
-
- if (rn < LEVEL_DISTRIBUTION[3]) {
- return Level.WARN;
- }
+ if (rn < LEVEL_DISTRIBUTION[2]) {
+ return Level.INFO;
+ }
- return Level.ERROR;
+ if (rn < LEVEL_DISTRIBUTION[3]) {
+ return Level.WARN;
}
+
+ return Level.ERROR;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/corpus/ExceptionBuilder.java b/logback-classic/src/test/java/ch/qos/logback/classic/corpus/ExceptionBuilder.java
index b1c4b37..de885b8 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/corpus/ExceptionBuilder.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/corpus/ExceptionBuilder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,33 +19,29 @@ import javax.management.remote.JMXProviderException;
public class ExceptionBuilder {
- static Throwable build(Random r, double nestingProbability) {
- double rn = r.nextDouble();
- boolean nested = false;
- if (rn < nestingProbability) {
- nested = true;
- }
-
- Throwable cause = null;
- if (nested) {
- cause = makeThrowable(r, null);
- }
- return makeThrowable(r, cause);
+ static Throwable build(Random r, double nestingProbability) {
+ double rn = r.nextDouble();
+ boolean nested = false;
+ if (rn < nestingProbability) {
+ nested = true;
}
- private static Throwable makeThrowable(Random r, Throwable cause) {
- int exType = r.nextInt(4);
- switch (exType) {
- case 0:
- return new IllegalArgumentException("an illegal argument was passed", cause);
- case 1:
- return new Exception("this is a test", cause);
- case 2:
- return new JMXProviderException("jmx provider exception error occured", cause);
- case 3:
- return new OutOfMemoryError("ran out of memory");
- }
- return null;
- }
+ Throwable cause = null;
+ if(nested) {
+ cause = makeThrowable(r, null);
+ }
+ return makeThrowable(r, cause);
+ }
+ private static Throwable makeThrowable(Random r, Throwable cause) {
+ int exType = r.nextInt(4);
+ switch(exType) {
+ case 0: return new IllegalArgumentException("an illegal argument was passed", cause);
+ case 1: return new Exception("this is a test", cause);
+ case 2: return new JMXProviderException("jmx provider exception error occured", cause);
+ case 3: return new OutOfMemoryError("ran out of memory");
+ }
+ return null;
+ }
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/corpus/LogStatement.java b/logback-classic/src/test/java/ch/qos/logback/classic/corpus/LogStatement.java
index d3d5aee..236c8d0 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/corpus/LogStatement.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/corpus/LogStatement.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,19 +26,21 @@ import ch.qos.logback.classic.spi.IThrowableProxy;
*/
public class LogStatement {
- final String loggerName;
- final MessageArgumentTuple mat;
- final Level level;
- final IThrowableProxy throwableProxy;
+ final String loggerName;
+ final MessageArgumentTuple mat;
+ final Level level;
+ final IThrowableProxy throwableProxy;
- public LogStatement(String loggerName, Level level, MessageArgumentTuple mat, IThrowableProxy tp) {
- this.loggerName = loggerName;
- this.level = level;
- this.mat = mat;
- this.throwableProxy = tp;
- }
+ public LogStatement(String loggerName, Level level, MessageArgumentTuple mat,
+ IThrowableProxy tp) {
+ this.loggerName = loggerName;
+ this.level = level;
+ this.mat = mat;
+ this.throwableProxy = tp;
+ }
- public String getLoggerName() {
- return loggerName;
- }
+
+ public String getLoggerName() {
+ return loggerName;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/corpus/MessageArgumentTuple.java b/logback-classic/src/test/java/ch/qos/logback/classic/corpus/MessageArgumentTuple.java
index e3b1d3a..91540ad 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/corpus/MessageArgumentTuple.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/corpus/MessageArgumentTuple.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,17 +14,17 @@
package ch.qos.logback.classic.corpus;
public class MessageArgumentTuple {
+
+ final String message;
+ final int numberOfArguments;
- final String message;
- final int numberOfArguments;
+ MessageArgumentTuple(String message) {
+ this(message, 0);
+ }
- MessageArgumentTuple(String message) {
- this(message, 0);
- }
-
- public MessageArgumentTuple(String message, int numberOfArguments) {
- this.message = message;
- this.numberOfArguments = numberOfArguments;
- }
+ public MessageArgumentTuple(String message, int numberOfArguments) {
+ this.message = message;
+ this.numberOfArguments = numberOfArguments;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/corpus/RandomUtil.java b/logback-classic/src/test/java/ch/qos/logback/classic/corpus/RandomUtil.java
index a27bb91..f372e88 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/corpus/RandomUtil.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/corpus/RandomUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,27 +17,30 @@ import java.util.Random;
public class RandomUtil {
- /**
- * Approximate a gaussian distrib with only positive integer values
- *
- * @param average
- * @param stdDeviation
- * @return
- */
- static public int gaussianAsPositiveInt(Random random, int average, int stdDeviation) {
- if (average < 1) {
- throw new IllegalArgumentException("The average must not be smaller than 1.");
- }
+
+ /**
+ * Approximate a gaussian distrib with only positive integer values
+ *
+ * @param average
+ * @param stdDeviation
+ * @return
+ */
+ static public int gaussianAsPositiveInt(Random random, int average, int stdDeviation) {
+ if (average < 1) {
+ throw new IllegalArgumentException(
+ "The average must not be smaller than 1.");
+ }
- if (stdDeviation < 1) {
- throw new IllegalArgumentException("The stdDeviation must not be smaller than 1.");
- }
+ if (stdDeviation < 1) {
+ throw new IllegalArgumentException(
+ "The stdDeviation must not be smaller than 1.");
+ }
- double d = random.nextGaussian() * stdDeviation + average;
- int result = 1;
- if (d > 1.0) {
- result = (int) Math.round(d);
- }
- return result;
+ double d = random.nextGaussian() * stdDeviation + average;
+ int result = 1;
+ if (d > 1.0) {
+ result = (int) Math.round(d);
}
+ return result;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/corpus/TextFileUtil.java b/logback-classic/src/test/java/ch/qos/logback/classic/corpus/TextFileUtil.java
index fd2f4b7..5fe3d32 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/corpus/TextFileUtil.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/corpus/TextFileUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,37 +24,38 @@ import java.util.List;
public class TextFileUtil {
- public static List<String> toWords(URL url) throws IOException {
- InputStream is = url.openStream();
- InputStreamReader reader = new InputStreamReader(is);
- BufferedReader br = new BufferedReader(reader);
- return toWords(br);
- }
-
- public static List<String> toWords(String filename) throws IOException {
- FileReader fr = new FileReader(filename);
- BufferedReader br = new BufferedReader(fr);
- return toWords(br);
- }
-
- public static List<String> toWords(BufferedReader br) throws IOException {
-
- // (\\d+)$
- // String regExp = "^(\\d+) "+ msg + " ([\\dabcdef-]+)$";
- // Pattern p = Pattern.compile(regExp);
- String line;
-
- List<String> wordList = new ArrayList<String>();
-
- while ((line = br.readLine()) != null) {
- // line = line.replaceAll("\\p{Punct}+", " ");
- String[] words = line.split("\\s");
- for (String word : words) {
- wordList.add(word);
- }
- }
- br.close();
-
- return wordList;
- }
+
+ public static List<String> toWords(URL url) throws IOException {
+ InputStream is = url.openStream();
+ InputStreamReader reader = new InputStreamReader(is);
+ BufferedReader br = new BufferedReader(reader);
+ return toWords(br);
+ }
+
+ public static List<String> toWords(String filename) throws IOException {
+ FileReader fr = new FileReader(filename);
+ BufferedReader br = new BufferedReader(fr);
+ return toWords(br);
+ }
+
+ public static List<String> toWords(BufferedReader br) throws IOException {
+
+ // (\\d+)$
+ //String regExp = "^(\\d+) "+ msg + " ([\\dabcdef-]+)$";
+ //Pattern p = Pattern.compile(regExp);
+ String line;
+
+ List<String> wordList = new ArrayList<String>();
+
+ while ((line = br.readLine()) != null) {
+ //line = line.replaceAll("\\p{Punct}+", " ");
+ String[] words = line.split("\\s");
+ for(String word: words) {
+ wordList.add(word);
+ }
+ }
+ br.close();
+
+ return wordList;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/corpusTest/RandomUtilTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/corpusTest/RandomUtilTest.java
index 6d2f5e5..f726b3b 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/corpusTest/RandomUtilTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/corpusTest/RandomUtilTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,38 +22,40 @@ import org.junit.Test;
import ch.qos.logback.classic.corpus.RandomUtil;
-public class RandomUtilTest {
- long now = System.currentTimeMillis();
-
- @Before
- public void setup() {
- System.out.println(RandomUtilTest.class.getName() + " now=" + now);
- }
-
- @Test
- public void smoke() {
-
- int EXPECTED_AVERAGE = 6;
- int EXPECTED_STD_DEVIATION = 3;
- System.out.println();
- Random r = new Random(now);
- int len = 3000;
- int[] valArray = new int[len];
- for (int i = 0; i < len; i++) {
- valArray[i] = RandomUtil.gaussianAsPositiveInt(r, EXPECTED_AVERAGE, EXPECTED_STD_DEVIATION);
- }
- double avg = average(valArray);
-
- assertEquals(EXPECTED_AVERAGE, avg, 0.3);
+public class RandomUtilTest {
+ long now = System.currentTimeMillis();
+
+ @Before
+ public void setup() {
+ System.out.println(RandomUtilTest.class.getName()+" now="+now);
+ }
+
+ @Test
+ public void smoke() {
+
+ int EXPECTED_AVERAGE = 6;
+ int EXPECTED_STD_DEVIATION = 3;
+
+
+ System.out.println();
+ Random r = new Random(now);
+ int len = 3000;
+ int[] valArray = new int[len];
+ for(int i = 0; i < len; i++) {
+ valArray[i] = RandomUtil.gaussianAsPositiveInt(r, EXPECTED_AVERAGE, EXPECTED_STD_DEVIATION);
}
-
- public double average(int[] va) {
- double avg = 0;
- for (int i = 0; i < va.length; i++) {
- avg = (avg * i + va[i]) / (i + 1);
- }
- return avg;
+ double avg = average(valArray);
+
+ assertEquals(EXPECTED_AVERAGE, avg, 0.3);
+ }
+
+ public double average(int[] va) {
+ double avg = 0;
+ for(int i = 0; i < va.length; i++) {
+ avg = (avg*i+va[i])/(i+1);
}
-
+ return avg;
+ }
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/corpusTest/TextFileUtilTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/corpusTest/TextFileUtilTest.java
index 2e968d1..20e9bce 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/corpusTest/TextFileUtilTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/corpusTest/TextFileUtilTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,19 +26,20 @@ import ch.qos.logback.classic.corpus.TextFileUtil;
public class TextFileUtilTest {
- @Test
- public void smoke() throws IOException {
- String s = "When on board H.M.S. 'Beagle,' as naturalist, I was much struck with\r\n"
- + "certain facts in the distribution of the inhabitants of South America,\r\n"
- + "and in the geological relations of the present to the past inhabitants\r\n" + "of that continent.";
-
- StringReader sr = new StringReader(s);
- BufferedReader br = new BufferedReader(sr);
- List<String> wordList = TextFileUtil.toWords(br);
- assertEquals(38, wordList.size());
- assertEquals("When", wordList.get(0));
- assertEquals("'Beagle,'", wordList.get(4));
- assertEquals("of", wordList.get(17));
-
- }
+ @Test
+ public void smoke() throws IOException {
+ String s = "When on board H.M.S. 'Beagle,' as naturalist, I was much struck with\r\n"
+ + "certain facts in the distribution of the inhabitants of South America,\r\n"
+ + "and in the geological relations of the present to the past inhabitants\r\n"
+ + "of that continent.";
+
+ StringReader sr = new StringReader(s);
+ BufferedReader br = new BufferedReader(sr);
+ List<String> wordList = TextFileUtil.toWords(br);
+ assertEquals(38, wordList.size());
+ assertEquals("When", wordList.get(0));
+ assertEquals("'Beagle,'", wordList.get(4));
+ assertEquals("of", wordList.get(17));
+
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderH2Test.java b/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderH2Test.java
index 0adf207..90e7803 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderH2Test.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderH2Test.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -41,179 +41,185 @@ import ch.qos.logback.core.util.StatusPrinter;
public class DBAppenderH2Test {
- LoggerContext loggerContext = new LoggerContext();;
- Logger logger;
- DBAppender appender;
- DriverManagerConnectionSource connectionSource;
- DBAppenderH2TestFixture dbAppenderH2TestFixture;
- int diff = RandomUtil.getPositiveInt();
- StatusChecker checker = new StatusChecker(loggerContext);
-
- @Before
- public void setUp() throws SQLException {
- dbAppenderH2TestFixture = new DBAppenderH2TestFixture();
- dbAppenderH2TestFixture.setUp();
- loggerContext.setName("default");
- logger = loggerContext.getLogger("root");
- appender = new DBAppender();
- appender.setName("DB");
- appender.setContext(loggerContext);
- connectionSource = new DriverManagerConnectionSource();
- connectionSource.setContext(loggerContext);
- connectionSource.setDriverClass(DBAppenderH2TestFixture.H2_DRIVER_CLASS);
- connectionSource.setUrl(dbAppenderH2TestFixture.url);
- System.out.println("cs.url=" + dbAppenderH2TestFixture.url);
- connectionSource.setUser(dbAppenderH2TestFixture.user);
- connectionSource.setPassword(dbAppenderH2TestFixture.password);
-
- connectionSource.start();
- appender.setConnectionSource(connectionSource);
- appender.start();
+ LoggerContext loggerContext = new LoggerContext();;
+ Logger logger;
+ DBAppender appender;
+ DriverManagerConnectionSource connectionSource;
+ DBAppenderH2TestFixture dbAppenderH2TestFixture;
+ int diff = RandomUtil.getPositiveInt();
+ StatusChecker checker = new StatusChecker(loggerContext);
+
+ @Before
+ public void setUp() throws SQLException {
+ dbAppenderH2TestFixture = new DBAppenderH2TestFixture();
+ dbAppenderH2TestFixture.setUp();
+ loggerContext.setName("default");
+ logger = loggerContext.getLogger("root");
+ appender = new DBAppender();
+ appender.setName("DB");
+ appender.setContext(loggerContext);
+ connectionSource = new DriverManagerConnectionSource();
+ connectionSource.setContext(loggerContext);
+ connectionSource.setDriverClass(DBAppenderH2TestFixture.H2_DRIVER_CLASS);
+ connectionSource.setUrl(dbAppenderH2TestFixture.url);
+ System.out.println("cs.url=" + dbAppenderH2TestFixture.url);
+ connectionSource.setUser(dbAppenderH2TestFixture.user);
+ connectionSource.setPassword(dbAppenderH2TestFixture.password);
+
+
+ connectionSource.start();
+ appender.setConnectionSource(connectionSource);
+ appender.start();
+ }
+
+ @After
+ public void tearDown() throws SQLException {
+ logger = null;
+ loggerContext = null;
+ appender = null;
+ connectionSource = null;
+ dbAppenderH2TestFixture.tearDown();
+ }
+
+ @Test
+ public void testAppendLoggingEvent() throws SQLException {
+ ILoggingEvent event = createLoggingEvent();
+
+ appender.append(event);
+
+ StatusPrinter.print(loggerContext);
+
+ Statement stmt = connectionSource.getConnection().createStatement();
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM logging_event");
+ if (rs.next()) {
+ assertEquals(event.getTimeStamp(), rs.getLong(DBAppender.TIMESTMP_INDEX));
+ assertEquals(event.getFormattedMessage(), rs.getString(DBAppender.FORMATTED_MESSAGE_INDEX));
+ assertEquals(event.getLoggerName(), rs.getString(DBAppender.LOGGER_NAME_INDEX));
+ assertEquals(event.getLevel().toString(), rs.getString(DBAppender.LEVEL_STRING_INDEX));
+ assertEquals(event.getThreadName(), rs.getString(DBAppender.THREAD_NAME_INDEX));
+ assertEquals(DBHelper.computeReferenceMask(event), rs.getShort(DBAppender.REFERENCE_FLAG_INDEX));
+ assertEquals(String.valueOf(diff), rs.getString(DBAppender.ARG0_INDEX));
+ StackTraceElement callerData = event.getCallerData()[0];
+ assertEquals(callerData.getFileName(), rs.getString(DBAppender.CALLER_FILENAME_INDEX));
+ assertEquals(callerData.getClassName(), rs.getString(DBAppender.CALLER_CLASS_INDEX));
+ assertEquals(callerData.getMethodName(), rs.getString(DBAppender.CALLER_METHOD_INDEX));
+ } else {
+ fail("No row was inserted in the database");
}
- @After
- public void tearDown() throws SQLException {
- logger = null;
- loggerContext = null;
- appender = null;
- connectionSource = null;
- dbAppenderH2TestFixture.tearDown();
+ rs.close();
+ stmt.close();
+ }
+
+ @Test
+ public void testAppendThrowable() throws SQLException {
+ ILoggingEvent event = createLoggingEvent();
+ appender.append(event);
+ Statement stmt = connectionSource.getConnection().createStatement();
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM LOGGING_EVENT_EXCEPTION WHERE EVENT_ID=1");
+ rs.next();
+ String expected = "java.lang.Exception: test Ex";
+ String firstLine = rs.getString(3);
+ assertTrue("[" + firstLine + "] does not match [" + expected + "]", firstLine.contains(expected));
+
+ int i = 0;
+ while (rs.next()) {
+ expected = event.getThrowableProxy().getStackTraceElementProxyArray()[i].toString();
+ String st = rs.getString(3);
+ assertTrue("[" + st + "] does not match [" + expected + "]", st.contains(expected));
+ i++;
}
+ assertTrue(i != 0);
- @Test
- public void testAppendLoggingEvent() throws SQLException {
- ILoggingEvent event = createLoggingEvent();
-
- appender.append(event);
-
- StatusPrinter.print(loggerContext);
-
- Statement stmt = connectionSource.getConnection().createStatement();
- ResultSet rs = null;
- rs = stmt.executeQuery("SELECT * FROM logging_event");
- if (rs.next()) {
- assertEquals(event.getTimeStamp(), rs.getLong(DBAppender.TIMESTMP_INDEX));
- assertEquals(event.getFormattedMessage(), rs.getString(DBAppender.FORMATTED_MESSAGE_INDEX));
- assertEquals(event.getLoggerName(), rs.getString(DBAppender.LOGGER_NAME_INDEX));
- assertEquals(event.getLevel().toString(), rs.getString(DBAppender.LEVEL_STRING_INDEX));
- assertEquals(event.getThreadName(), rs.getString(DBAppender.THREAD_NAME_INDEX));
- assertEquals(DBHelper.computeReferenceMask(event), rs.getShort(DBAppender.REFERENCE_FLAG_INDEX));
- assertEquals(String.valueOf(diff), rs.getString(DBAppender.ARG0_INDEX));
- StackTraceElement callerData = event.getCallerData()[0];
- assertEquals(callerData.getFileName(), rs.getString(DBAppender.CALLER_FILENAME_INDEX));
- assertEquals(callerData.getClassName(), rs.getString(DBAppender.CALLER_CLASS_INDEX));
- assertEquals(callerData.getMethodName(), rs.getString(DBAppender.CALLER_METHOD_INDEX));
- } else {
- fail("No row was inserted in the database");
- }
-
- rs.close();
- stmt.close();
- }
+ rs.close();
+ stmt.close();
+ }
- @Test
- public void testAppendThrowable() throws SQLException {
- ILoggingEvent event = createLoggingEvent();
- appender.append(event);
- Statement stmt = connectionSource.getConnection().createStatement();
- ResultSet rs = null;
- rs = stmt.executeQuery("SELECT * FROM LOGGING_EVENT_EXCEPTION WHERE EVENT_ID=1");
- rs.next();
- String expected = "java.lang.Exception: test Ex";
- String firstLine = rs.getString(3);
- assertTrue("[" + firstLine + "] does not match [" + expected + "]", firstLine.contains(expected));
-
- int i = 0;
- while (rs.next()) {
- expected = event.getThrowableProxy().getStackTraceElementProxyArray()[i].toString();
- String st = rs.getString(3);
- assertTrue("[" + st + "] does not match [" + expected + "]", st.contains(expected));
- i++;
- }
- assertTrue(i != 0);
-
- rs.close();
- stmt.close();
- }
+ @Test
+ public void withNullArgument() throws SQLException {
+ ILoggingEvent event = createLoggingEvent("Processing code {}; code type is {}; request date {}; record from date {}", new Object[] { 1, 2, new Date(), null });
+ appender.append(event);
- @Test
- public void withNullArgument() throws SQLException {
- ILoggingEvent event = createLoggingEvent("Processing code {}; code type is {}; request date {}; record from date {}", new Object[] { 1, 2, new Date(),
- null });
- appender.append(event);
-
- Statement stmt = connectionSource.getConnection().createStatement();
- ResultSet rs = null;
- rs = stmt.executeQuery("SELECT * FROM logging_event");
- if (rs.next()) {
- assertEquals(event.getTimeStamp(), rs.getLong(DBAppender.TIMESTMP_INDEX));
- assertEquals(event.getFormattedMessage(), rs.getString(DBAppender.FORMATTED_MESSAGE_INDEX));
- }
- }
- @Test
- public void testContextInfo() throws SQLException {
- loggerContext.putProperty("testKey1", "testValue1");
- MDC.put("k" + diff, "v" + diff);
- ILoggingEvent event = createLoggingEvent();
-
- appender.append(event);
-
- Statement stmt = connectionSource.getConnection().createStatement();
- ResultSet rs = null;
- rs = stmt.executeQuery("SELECT * FROM LOGGING_EVENT_PROPERTY WHERE EVENT_ID=1");
- Map<String, String> map = appender.mergePropertyMaps(event);
- int i = 0;
- while (rs.next()) {
- String key = rs.getString(2);
- assertEquals(map.get(key), rs.getString(3));
- i++;
- }
- assertTrue(map.size() != 0);
- assertEquals(map.size(), i);
- rs.close();
- stmt.close();
+ Statement stmt = connectionSource.getConnection().createStatement();
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM logging_event");
+ if (rs.next()) {
+ assertEquals(event.getTimeStamp(), rs.getLong(DBAppender.TIMESTMP_INDEX));
+ assertEquals(event.getFormattedMessage(), rs.getString(DBAppender.FORMATTED_MESSAGE_INDEX));
+ }
+ }
+
+ @Test
+ public void testContextInfo() throws SQLException {
+ loggerContext.putProperty("testKey1", "testValue1");
+ MDC.put("k" + diff, "v" + diff);
+ ILoggingEvent event = createLoggingEvent();
+
+ appender.append(event);
+
+ Statement stmt = connectionSource.getConnection().createStatement();
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM LOGGING_EVENT_PROPERTY WHERE EVENT_ID=1");
+ Map<String, String> map = appender.mergePropertyMaps(event);
+ int i = 0;
+ while (rs.next()) {
+ String key = rs.getString(2);
+ assertEquals(map.get(key), rs.getString(3));
+ i++;
+ }
+ assertTrue(map.size() != 0);
+ assertEquals(map.size(), i);
+ rs.close();
+ stmt.close();
+ }
+
+
+ @Test
+ public void testAppendMultipleEvents() throws SQLException {
+ for (int i = 0; i < 10; i++) {
+ ILoggingEvent event = createLoggingEvent();
+ appender.append(event);
}
- @Test
- public void testAppendMultipleEvents() throws SQLException {
- for (int i = 0; i < 10; i++) {
- ILoggingEvent event = createLoggingEvent();
- appender.append(event);
- }
-
- Statement stmt = connectionSource.getConnection().createStatement();
- ResultSet rs = null;
- rs = stmt.executeQuery("SELECT * FROM logging_event");
- int count = 0;
- while (rs.next()) {
- count++;
- }
- assertEquals(10, count);
-
- rs.close();
- stmt.close();
+ Statement stmt = connectionSource.getConnection().createStatement();
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM logging_event");
+ int count = 0;
+ while (rs.next()) {
+ count++;
}
+ assertEquals(10, count);
- // http://jira.qos.ch/browse/LOGBACK-805
- @Test
- public void emptyCallerDataShouldBeHandledGracefully() {
- LoggingEvent event = createLoggingEvent();
- event.setCallerData(new StackTraceElement[0]);
- appender.append(event);
+ rs.close();
+ stmt.close();
+ }
- event.setCallerData(new StackTraceElement[] { null });
- appender.append(event);
+ // http://jira.qos.ch/browse/LOGBACK-805
+ @Test
+ public void emptyCallerDataShouldBeHandledGracefully() {
+ LoggingEvent event = createLoggingEvent();
+ event.setCallerData(new StackTraceElement[0]);
+ appender.append(event);
- checker.assertIsErrorFree();
- }
+ event.setCallerData(new StackTraceElement[] {null});
+ appender.append(event);
- private LoggingEvent createLoggingEvent(String msg, Object[] args) {
- return new LoggingEvent(this.getClass().getName(), logger, Level.DEBUG, msg, new Exception("test Ex"), args);
- }
+ checker.assertIsErrorFree();
+ }
+
+
+ private LoggingEvent createLoggingEvent(String msg, Object[] args) {
+ return new LoggingEvent(this.getClass().getName(), logger,
+ Level.DEBUG, msg, new Exception("test Ex"), args);
+ }
+
+
+ private LoggingEvent createLoggingEvent() {
+ return createLoggingEvent("test message", new Integer[]{diff});
+ }
- private LoggingEvent createLoggingEvent() {
- return createLoggingEvent("test message", new Integer[] { diff });
- }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderH2TestFixture.java b/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderH2TestFixture.java
index c5b50f7..98d2e8d 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderH2TestFixture.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderH2TestFixture.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,118 +24,119 @@ import org.h2.Driver;
import ch.qos.logback.core.testUtil.RandomUtil;
-public class DBAppenderH2TestFixture {
+public class DBAppenderH2TestFixture {
+
+ public enum H2Mode {
+ MEM, FILE, NET;
+ }
+
+ public static final String H2_DRIVER_CLASS = "org.h2.Driver";
+ String url = null;
+ String user = "sa";
+ String password = "";
+
+ // boolean isNetwork = true;
+ H2Mode mode = H2Mode.MEM;
+
+ int diff = RandomUtil.getPositiveInt();
+
+ Connection connection;
+
+ public void setUp() throws SQLException {
+
+ switch (mode) {
+ case NET:
+ url = "jdbc:h2:tcp://localhost:4808/test";
+ break;
+ case MEM:
+ url = "jdbc:h2:mem:test"+diff;
+ break;
+ case FILE:
+ url = "jdbc:hsqldb:file:test;sql.enforce_strict_size=true";
+ break;
- public enum H2Mode {
- MEM, FILE, NET;
}
-
- public static final String H2_DRIVER_CLASS = "org.h2.Driver";
- String url = null;
- String user = "sa";
- String password = "";
-
- // boolean isNetwork = true;
- H2Mode mode = H2Mode.MEM;
-
- int diff = RandomUtil.getPositiveInt();
-
- Connection connection;
-
- public void setUp() throws SQLException {
-
- switch (mode) {
- case NET:
- url = "jdbc:h2:tcp://localhost:4808/test";
- break;
- case MEM:
- url = "jdbc:h2:mem:test" + diff;
- break;
- case FILE:
- url = "jdbc:hsqldb:file:test;sql.enforce_strict_size=true";
- break;
-
- }
- connection = newConnection();
- createTables();
- }
-
- public void tearDown() throws SQLException {
- dropTables();
- connection.close();
+ connection = newConnection();
+ createTables();
+ }
+
+ public void tearDown() throws SQLException {
+ dropTables();
+ connection.close();
+ }
+
+ Connection newConnection() throws SQLException {
+ System.out.println("url="+url);
+ org.h2.Driver driver = Driver.load();
+ Properties props = new Properties();
+ props.setProperty("user", user);
+ props.setProperty("password", password);
+ return driver.connect(url, props);
+ }
+
+ private void createTables() throws SQLException {
+ assertNotNull(connection);
+ StringBuilder buf = new StringBuilder();
+ buf.append("CREATE TABLE LOGGING_EVENT (");
+ buf.append("TIMESTMP BIGINT NOT NULL,");
+ buf.append("FORMATTED_MESSAGE LONGVARCHAR NOT NULL,");
+ buf.append("LOGGER_NAME VARCHAR(256) NOT NULL,");
+ buf.append("LEVEL_STRING VARCHAR(256) NOT NULL,");
+ buf.append("THREAD_NAME VARCHAR(256),");
+ buf.append("REFERENCE_FLAG SMALLINT,");
+ buf.append("ARG0 VARCHAR(256),");
+ buf.append("ARG1 VARCHAR(256),");
+ buf.append("ARG2 VARCHAR(256),");
+ buf.append("ARG3 VARCHAR(256),");
+ buf.append("CALLER_FILENAME VARCHAR(256), ");
+ buf.append("CALLER_CLASS VARCHAR(256), ");
+ buf.append("CALLER_METHOD VARCHAR(256), ");
+ buf.append("CALLER_LINE CHAR(4), ");
+ buf.append("EVENT_ID IDENTITY NOT NULL);");
+ executeQuery(connection, buf.toString());
+
+ buf = new StringBuilder();
+ buf.append("CREATE TABLE LOGGING_EVENT_PROPERTY (");
+ buf.append("EVENT_ID BIGINT NOT NULL,");
+ buf.append("MAPPED_KEY VARCHAR(254) NOT NULL,");
+ buf.append("MAPPED_VALUE LONGVARCHAR,");
+ buf.append("PRIMARY KEY(EVENT_ID, MAPPED_KEY),");
+ buf.append("FOREIGN KEY (EVENT_ID) REFERENCES LOGGING_EVENT(EVENT_ID));");
+ executeQuery(connection, buf.toString());
+
+ buf = new StringBuilder();
+ buf.append("CREATE TABLE LOGGING_EVENT_EXCEPTION (");
+ buf.append("EVENT_ID BIGINT NOT NULL,");
+ buf.append("I SMALLINT NOT NULL,");
+ buf.append("TRACE_LINE VARCHAR(256) NOT NULL,");
+ buf.append("PRIMARY KEY(EVENT_ID, I),");
+ buf.append("FOREIGN KEY (EVENT_ID) REFERENCES LOGGING_EVENT(EVENT_ID));");
+ executeQuery(connection, buf.toString());
+ }
+
+ private void dropTables() throws SQLException {
+ StringBuilder buf = new StringBuilder();
+ buf.append("DROP TABLE LOGGING_EVENT_EXCEPTION IF EXISTS;");
+ executeQuery(connection, buf.toString());
+
+ buf = new StringBuilder();
+ buf.append("DROP TABLE LOGGING_EVENT_PROPERTY IF EXISTS;");
+ executeQuery(connection, buf.toString());
+
+ buf = new StringBuilder();
+ buf.append("DROP TABLE LOGGING_EVENT IF EXISTS;");
+ executeQuery(connection, buf.toString());
+ }
+
+ private void executeQuery(Connection conn, String expression) throws SQLException {
+ Statement st = null;
+ st = conn.createStatement();
+ int i = st.executeUpdate(expression);
+ if (i == -1) {
+ throw new IllegalStateException("db error : " + expression);
}
+ st.close();
+ }
- Connection newConnection() throws SQLException {
- System.out.println("url=" + url);
- org.h2.Driver driver = Driver.load();
- Properties props = new Properties();
- props.setProperty("user", user);
- props.setProperty("password", password);
- return driver.connect(url, props);
- }
-
- private void createTables() throws SQLException {
- assertNotNull(connection);
- StringBuilder buf = new StringBuilder();
- buf.append("CREATE TABLE LOGGING_EVENT (");
- buf.append("TIMESTMP BIGINT NOT NULL,");
- buf.append("FORMATTED_MESSAGE LONGVARCHAR NOT NULL,");
- buf.append("LOGGER_NAME VARCHAR(256) NOT NULL,");
- buf.append("LEVEL_STRING VARCHAR(256) NOT NULL,");
- buf.append("THREAD_NAME VARCHAR(256),");
- buf.append("REFERENCE_FLAG SMALLINT,");
- buf.append("ARG0 VARCHAR(256),");
- buf.append("ARG1 VARCHAR(256),");
- buf.append("ARG2 VARCHAR(256),");
- buf.append("ARG3 VARCHAR(256),");
- buf.append("CALLER_FILENAME VARCHAR(256), ");
- buf.append("CALLER_CLASS VARCHAR(256), ");
- buf.append("CALLER_METHOD VARCHAR(256), ");
- buf.append("CALLER_LINE CHAR(4), ");
- buf.append("EVENT_ID IDENTITY NOT NULL);");
- executeQuery(connection, buf.toString());
-
- buf = new StringBuilder();
- buf.append("CREATE TABLE LOGGING_EVENT_PROPERTY (");
- buf.append("EVENT_ID BIGINT NOT NULL,");
- buf.append("MAPPED_KEY VARCHAR(254) NOT NULL,");
- buf.append("MAPPED_VALUE LONGVARCHAR,");
- buf.append("PRIMARY KEY(EVENT_ID, MAPPED_KEY),");
- buf.append("FOREIGN KEY (EVENT_ID) REFERENCES LOGGING_EVENT(EVENT_ID));");
- executeQuery(connection, buf.toString());
-
- buf = new StringBuilder();
- buf.append("CREATE TABLE LOGGING_EVENT_EXCEPTION (");
- buf.append("EVENT_ID BIGINT NOT NULL,");
- buf.append("I SMALLINT NOT NULL,");
- buf.append("TRACE_LINE VARCHAR(256) NOT NULL,");
- buf.append("PRIMARY KEY(EVENT_ID, I),");
- buf.append("FOREIGN KEY (EVENT_ID) REFERENCES LOGGING_EVENT(EVENT_ID));");
- executeQuery(connection, buf.toString());
- }
-
- private void dropTables() throws SQLException {
- StringBuilder buf = new StringBuilder();
- buf.append("DROP TABLE LOGGING_EVENT_EXCEPTION IF EXISTS;");
- executeQuery(connection, buf.toString());
-
- buf = new StringBuilder();
- buf.append("DROP TABLE LOGGING_EVENT_PROPERTY IF EXISTS;");
- executeQuery(connection, buf.toString());
-
- buf = new StringBuilder();
- buf.append("DROP TABLE LOGGING_EVENT IF EXISTS;");
- executeQuery(connection, buf.toString());
- }
-
- private void executeQuery(Connection conn, String expression) throws SQLException {
- Statement st = null;
- st = conn.createStatement();
- int i = st.executeUpdate(expression);
- if (i == -1) {
- throw new IllegalStateException("db error : " + expression);
- }
- st.close();
- }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderHSQLTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderHSQLTest.java
index 03f8263..09c6178 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderHSQLTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderHSQLTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -34,166 +34,173 @@ import ch.qos.logback.core.db.DriverManagerConnectionSource;
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.util.StatusPrinter;
-public class DBAppenderHSQLTest {
-
- LoggerContext lc;
- Logger logger;
- DBAppender appender;
- DriverManagerConnectionSource connectionSource;
-
- static DBAppenderHSQLTestFixture DB_APPENDER_HSQL_TEST_FIXTURE;
- int diff = RandomUtil.getPositiveInt();
- int existingRowCount;
- Statement stmt;
-
- @BeforeClass
- public static void beforeClass() throws SQLException {
- DB_APPENDER_HSQL_TEST_FIXTURE = new DBAppenderHSQLTestFixture();
- DB_APPENDER_HSQL_TEST_FIXTURE.setUp();
+public class DBAppenderHSQLTest {
+
+ LoggerContext lc;
+ Logger logger;
+ DBAppender appender;
+ DriverManagerConnectionSource connectionSource;
+
+ static DBAppenderHSQLTestFixture DB_APPENDER_HSQL_TEST_FIXTURE;
+ int diff = RandomUtil.getPositiveInt();
+ int existingRowCount;
+ Statement stmt;
+
+ @BeforeClass
+ public static void beforeClass() throws SQLException {
+ DB_APPENDER_HSQL_TEST_FIXTURE = new DBAppenderHSQLTestFixture();
+ DB_APPENDER_HSQL_TEST_FIXTURE.setUp();
+ }
+
+ @AfterClass
+ public static void afterClass() throws SQLException {
+ DB_APPENDER_HSQL_TEST_FIXTURE.tearDown();
+ }
+
+ @Before
+ public void setUp() throws SQLException {
+ lc = new LoggerContext();
+ lc.setName("default");
+ logger = lc.getLogger("root");
+ appender = new DBAppender();
+ appender.setName("DB");
+ appender.setContext(lc);
+ connectionSource = new DriverManagerConnectionSource();
+ connectionSource.setContext(lc);
+ connectionSource.setDriverClass(DBAppenderHSQLTestFixture.HSQLDB_DRIVER_CLASS);
+ connectionSource.setUrl(DB_APPENDER_HSQL_TEST_FIXTURE.url);
+ connectionSource.setUser(DB_APPENDER_HSQL_TEST_FIXTURE.user);
+ connectionSource.setPassword(DB_APPENDER_HSQL_TEST_FIXTURE.password);
+ connectionSource.start();
+ appender.setConnectionSource(connectionSource);
+ appender.start();
+
+ stmt = connectionSource.getConnection().createStatement();
+ existingRowCount = existingRowCount(stmt);
+
+ }
+
+
+
+ @After
+ public void tearDown() throws SQLException {
+ logger = null;
+ lc = null;
+ appender = null;
+ connectionSource = null;
+ stmt.close();
+ }
+
+ int existingRowCount(Statement stmt) throws SQLException {
+ ResultSet rs = stmt.executeQuery("SELECT count(*) FROM logging_event");
+ int result = -1;
+ if (rs.next()) {
+ result = rs.getInt(1);
}
-
- @AfterClass
- public static void afterClass() throws SQLException {
- DB_APPENDER_HSQL_TEST_FIXTURE.tearDown();
+ rs.close();
+ return result;
+ }
+
+ @Test
+ public void testAppendLoggingEvent() throws SQLException {
+
+
+ ILoggingEvent event = createLoggingEvent();
+ appender.append(event);
+ StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
+
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM logging_event where EVENT_ID = "+ existingRowCount);
+ if (rs.next()) {
+ assertEquals(event.getTimeStamp(), rs.getLong(DBAppender.TIMESTMP_INDEX));
+ assertEquals(event.getFormattedMessage(), rs.getString(DBAppender.FORMATTED_MESSAGE_INDEX));
+ assertEquals(event.getLoggerName(), rs.getString(DBAppender.LOGGER_NAME_INDEX));
+ assertEquals(event.getLevel().toString(), rs.getString(DBAppender.LEVEL_STRING_INDEX));
+ assertEquals(event.getThreadName(), rs.getString(DBAppender.THREAD_NAME_INDEX));
+ assertEquals(DBHelper.computeReferenceMask(event), rs.getShort(DBAppender.REFERENCE_FLAG_INDEX));
+ assertEquals(String.valueOf(diff), rs.getString(DBAppender.ARG0_INDEX));
+ StackTraceElement callerData = event.getCallerData()[0];
+ assertEquals(callerData.getFileName(), rs.getString(DBAppender.CALLER_FILENAME_INDEX));
+ assertEquals(callerData.getClassName(), rs.getString(DBAppender.CALLER_CLASS_INDEX));
+ assertEquals(callerData.getMethodName(), rs.getString(DBAppender.CALLER_METHOD_INDEX));
+ } else {
+ fail("No row was inserted in the database");
}
-
- @Before
- public void setUp() throws SQLException {
- lc = new LoggerContext();
- lc.setName("default");
- logger = lc.getLogger("root");
- appender = new DBAppender();
- appender.setName("DB");
- appender.setContext(lc);
- connectionSource = new DriverManagerConnectionSource();
- connectionSource.setContext(lc);
- connectionSource.setDriverClass(DBAppenderHSQLTestFixture.HSQLDB_DRIVER_CLASS);
- connectionSource.setUrl(DB_APPENDER_HSQL_TEST_FIXTURE.url);
- connectionSource.setUser(DB_APPENDER_HSQL_TEST_FIXTURE.user);
- connectionSource.setPassword(DB_APPENDER_HSQL_TEST_FIXTURE.password);
- connectionSource.start();
- appender.setConnectionSource(connectionSource);
- appender.start();
-
- stmt = connectionSource.getConnection().createStatement();
- existingRowCount = existingRowCount(stmt);
-
+ rs.close();
+ }
+
+
+
+ @Test
+ public void testAppendThrowable() throws SQLException {
+ ILoggingEvent event = createLoggingEvent();
+ appender.append(event);
+
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM LOGGING_EVENT_EXCEPTION where EVENT_ID = "+ existingRowCount);
+
+ rs.next();
+ String expected = "java.lang.Exception: test Ex";
+ String firstLine = rs.getString(3);
+ assertTrue("["+firstLine+"] does not match ["+expected+"]", firstLine.contains(expected));
+
+ int i = 0;
+ while (rs.next()) {
+ expected = event.getThrowableProxy().getStackTraceElementProxyArray()[i].toString();
+ String st = rs.getString(3);
+ assertTrue("["+st+"] does not match ["+expected+"]", st.contains(expected));
+ i++;
}
-
- @After
- public void tearDown() throws SQLException {
- logger = null;
- lc = null;
- appender = null;
- connectionSource = null;
- stmt.close();
+ assertTrue(i != 0);
+ rs.close();
+ }
+
+ @Test
+ public void testContextInfo() throws SQLException {
+ lc.putProperty("testKey1", "testValue1");
+ MDC.put("k"+diff, "v"+diff);
+ ILoggingEvent event = createLoggingEvent();
+
+ appender.append(event);
+
+ Statement stmt = connectionSource.getConnection().createStatement();
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM LOGGING_EVENT_PROPERTY WHERE EVENT_ID = "+ existingRowCount);
+ Map<String, String> map = appender.mergePropertyMaps(event);
+ System.out.println("ma.size="+map.size());
+ int i = 0;
+ while (rs.next()) {
+ String key = rs.getString(2);
+ assertEquals(map.get(key), rs.getString(3));
+ i++;
}
-
- int existingRowCount(Statement stmt) throws SQLException {
- ResultSet rs = stmt.executeQuery("SELECT count(*) FROM logging_event");
- int result = -1;
- if (rs.next()) {
- result = rs.getInt(1);
- }
- rs.close();
- return result;
+ assertTrue(map.size() != 0);
+ assertEquals(map.size(), i);
+ rs.close();
+ }
+
+ @Test
+ public void testAppendMultipleEvents() throws SQLException {
+ int numEvents = 3;
+ for (int i = 0; i < numEvents; i++) {
+ ILoggingEvent event = createLoggingEvent();
+ appender.append(event);
}
-
- @Test
- public void testAppendLoggingEvent() throws SQLException {
-
- ILoggingEvent event = createLoggingEvent();
- appender.append(event);
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
-
- ResultSet rs = null;
- rs = stmt.executeQuery("SELECT * FROM logging_event where EVENT_ID = " + existingRowCount);
- if (rs.next()) {
- assertEquals(event.getTimeStamp(), rs.getLong(DBAppender.TIMESTMP_INDEX));
- assertEquals(event.getFormattedMessage(), rs.getString(DBAppender.FORMATTED_MESSAGE_INDEX));
- assertEquals(event.getLoggerName(), rs.getString(DBAppender.LOGGER_NAME_INDEX));
- assertEquals(event.getLevel().toString(), rs.getString(DBAppender.LEVEL_STRING_INDEX));
- assertEquals(event.getThreadName(), rs.getString(DBAppender.THREAD_NAME_INDEX));
- assertEquals(DBHelper.computeReferenceMask(event), rs.getShort(DBAppender.REFERENCE_FLAG_INDEX));
- assertEquals(String.valueOf(diff), rs.getString(DBAppender.ARG0_INDEX));
- StackTraceElement callerData = event.getCallerData()[0];
- assertEquals(callerData.getFileName(), rs.getString(DBAppender.CALLER_FILENAME_INDEX));
- assertEquals(callerData.getClassName(), rs.getString(DBAppender.CALLER_CLASS_INDEX));
- assertEquals(callerData.getMethodName(), rs.getString(DBAppender.CALLER_METHOD_INDEX));
- } else {
- fail("No row was inserted in the database");
- }
- rs.close();
- }
-
- @Test
- public void testAppendThrowable() throws SQLException {
- ILoggingEvent event = createLoggingEvent();
- appender.append(event);
-
- ResultSet rs = null;
- rs = stmt.executeQuery("SELECT * FROM LOGGING_EVENT_EXCEPTION where EVENT_ID = " + existingRowCount);
-
- rs.next();
- String expected = "java.lang.Exception: test Ex";
- String firstLine = rs.getString(3);
- assertTrue("[" + firstLine + "] does not match [" + expected + "]", firstLine.contains(expected));
-
- int i = 0;
- while (rs.next()) {
- expected = event.getThrowableProxy().getStackTraceElementProxyArray()[i].toString();
- String st = rs.getString(3);
- assertTrue("[" + st + "] does not match [" + expected + "]", st.contains(expected));
- i++;
- }
- assertTrue(i != 0);
- rs.close();
+
+ Statement stmt = connectionSource.getConnection().createStatement();
+ ResultSet rs = null;
+ rs = stmt.executeQuery("SELECT * FROM logging_event WHERE EVENT_ID >="+ existingRowCount);
+ int count = 0;
+ while (rs.next()) {
+ count++;
}
+ assertEquals(numEvents, count);
+ rs.close();
+ }
- @Test
- public void testContextInfo() throws SQLException {
- lc.putProperty("testKey1", "testValue1");
- MDC.put("k" + diff, "v" + diff);
- ILoggingEvent event = createLoggingEvent();
-
- appender.append(event);
-
- Statement stmt = connectionSource.getConnection().createStatement();
- ResultSet rs = null;
- rs = stmt.executeQuery("SELECT * FROM LOGGING_EVENT_PROPERTY WHERE EVENT_ID = " + existingRowCount);
- Map<String, String> map = appender.mergePropertyMaps(event);
- System.out.println("ma.size=" + map.size());
- int i = 0;
- while (rs.next()) {
- String key = rs.getString(2);
- assertEquals(map.get(key), rs.getString(3));
- i++;
- }
- assertTrue(map.size() != 0);
- assertEquals(map.size(), i);
- rs.close();
- }
- @Test
- public void testAppendMultipleEvents() throws SQLException {
- int numEvents = 3;
- for (int i = 0; i < numEvents; i++) {
- ILoggingEvent event = createLoggingEvent();
- appender.append(event);
- }
-
- Statement stmt = connectionSource.getConnection().createStatement();
- ResultSet rs = null;
- rs = stmt.executeQuery("SELECT * FROM logging_event WHERE EVENT_ID >=" + existingRowCount);
- int count = 0;
- while (rs.next()) {
- count++;
- }
- assertEquals(numEvents, count);
- rs.close();
- }
-
- private ILoggingEvent createLoggingEvent() {
- return new LoggingEvent(this.getClass().getName(), logger, Level.DEBUG, "test message", new Exception("test Ex"), new Integer[] { diff });
- }
+ private ILoggingEvent createLoggingEvent() {
+ return new LoggingEvent(this.getClass().getName(), logger,
+ Level.DEBUG, "test message", new Exception("test Ex"), new Integer[]{diff});
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderHSQLTestFixture.java b/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderHSQLTestFixture.java
index 897b553..e16d38e 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderHSQLTestFixture.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderHSQLTestFixture.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,151 +25,153 @@ import org.hsqldb.Server;
import org.hsqldb.ServerConstants;
import org.hsqldb.jdbcDriver;
-public class DBAppenderHSQLTestFixture {
-
- public static final String HSQLDB_DRIVER_CLASS = "org.hsqldb.jdbcDriver";
- // String serverProps;
- String url = null;
- String user = "sa";
- String password = "";
- Server server;
-
- // boolean isNetwork = true;
- HsqlMode mode = HsqlMode.MEM;
-
- public void setUp() throws SQLException {
-
- switch (mode) {
- case NET:
- url = "jdbc:hsqldb:hsql://localhost:4808/test";
- break;
- case MEM:
- url = "jdbc:hsqldb:mem:test;sql.enforce_strict_size=true";
- server = new Server();
- server.setDatabaseName(0, "test");
- server.setDatabasePath(0, url);
- server.setLogWriter(new PrintWriter(System.out));
- server.setErrWriter(new PrintWriter(System.out));
- server.setTrace(false);
- server.setSilent(false);
- server.start();
-
- break;
- case FILE:
- url = "jdbc:hsqldb:file:test;sql.enforce_strict_size=true";
- break;
-
- }
-
- // try {
- // Class.forName(DRIVER_CLASS);
- // } catch (Exception e) {
- // e.printStackTrace();
- // System.out.println(this + ".setUp() error: " + e.getMessage());
- // }
- // Thread.yield();
- System.out.println(server.getState());
-
- int waitCount = 0;
- while (server.getState() != ServerConstants.SERVER_STATE_ONLINE && waitCount < 5) {
- try {
- waitCount++;
- Thread.sleep(1);
- } catch (InterruptedException e) {
- }
- }
- createTables();
- }
-
- public void tearDown() throws SQLException {
- dropTables();
-
- if (mode == HsqlMode.MEM) {
- server.stop();
- server = null;
- }
- }
-
- Connection newConnection() throws SQLException {
- jdbcDriver driver = new jdbcDriver();
- Properties props = new Properties();
- props.setProperty("user", user);
- props.setProperty("password", password);
- return driver.connect(url, props);
+public class DBAppenderHSQLTestFixture {
+
+ public static final String HSQLDB_DRIVER_CLASS = "org.hsqldb.jdbcDriver";
+ // String serverProps;
+ String url = null;
+ String user = "sa";
+ String password = "";
+ Server server;
+
+ // boolean isNetwork = true;
+ HsqlMode mode = HsqlMode.MEM;
+
+ public void setUp() throws SQLException {
+
+ switch (mode) {
+ case NET:
+ url = "jdbc:hsqldb:hsql://localhost:4808/test";
+ break;
+ case MEM:
+ url = "jdbc:hsqldb:mem:test;sql.enforce_strict_size=true";
+ server = new Server();
+ server.setDatabaseName(0, "test");
+ server.setDatabasePath(0, url);
+ server.setLogWriter(new PrintWriter(System.out));
+ server.setErrWriter(new PrintWriter(System.out));
+ server.setTrace(false);
+ server.setSilent(false);
+ server.start();
+
+ break;
+ case FILE:
+ url = "jdbc:hsqldb:file:test;sql.enforce_strict_size=true";
+ break;
- // return DriverManager.getConnection(url, user, password);
}
- private void createTables() throws SQLException {
- Connection conn = newConnection();
- assertNotNull(conn);
- StringBuilder buf = new StringBuilder();
- buf.append("CREATE TABLE LOGGING_EVENT (");
- buf.append("TIMESTMP BIGINT NOT NULL,");
- buf.append("FORMATTED_MESSAGE LONGVARCHAR NOT NULL,");
- buf.append("LOGGER_NAME VARCHAR(256) NOT NULL,");
- buf.append("LEVEL_STRING VARCHAR(256) NOT NULL,");
- buf.append("THREAD_NAME VARCHAR(256),");
- buf.append("REFERENCE_FLAG SMALLINT,");
-
- buf.append("ARG0 VARCHAR(256),");
- buf.append("ARG1 VARCHAR(256),");
- buf.append("ARG2 VARCHAR(256),");
- buf.append("ARG3 VARCHAR(256),");
-
- buf.append("CALLER_FILENAME VARCHAR(256), ");
- buf.append("CALLER_CLASS VARCHAR(256), ");
- buf.append("CALLER_METHOD VARCHAR(256), ");
- buf.append("CALLER_LINE CHAR(4), ");
- buf.append("EVENT_ID BIGINT NOT NULL IDENTITY);");
- query(conn, buf.toString());
-
- buf = new StringBuilder();
- buf.append("CREATE TABLE LOGGING_EVENT_PROPERTY (");
- buf.append("EVENT_ID BIGINT NOT NULL,");
- buf.append("MAPPED_KEY VARCHAR(254) NOT NULL,");
- buf.append("MAPPED_VALUE LONGVARCHAR,");
- buf.append("PRIMARY KEY(EVENT_ID, MAPPED_KEY),");
- buf.append("FOREIGN KEY (EVENT_ID) REFERENCES LOGGING_EVENT(EVENT_ID));");
- query(conn, buf.toString());
-
- buf = new StringBuilder();
- buf.append("CREATE TABLE LOGGING_EVENT_EXCEPTION (");
- buf.append("EVENT_ID BIGINT NOT NULL,");
- buf.append("I SMALLINT NOT NULL,");
- buf.append("TRACE_LINE VARCHAR(256) NOT NULL,");
- buf.append("PRIMARY KEY(EVENT_ID, I),");
- buf.append("FOREIGN KEY (EVENT_ID) REFERENCES LOGGING_EVENT(EVENT_ID));");
- query(conn, buf.toString());
+ // try {
+ // Class.forName(DRIVER_CLASS);
+ // } catch (Exception e) {
+ // e.printStackTrace();
+ // System.out.println(this + ".setUp() error: " + e.getMessage());
+ // }
+ // Thread.yield();
+ System.out.println(server.getState());
+
+ int waitCount = 0;
+ while (server.getState() != ServerConstants.SERVER_STATE_ONLINE
+ && waitCount < 5) {
+ try {
+ waitCount++;
+ Thread.sleep(1);
+ } catch (InterruptedException e) {
+ }
}
+ createTables();
+ }
- private void dropTables() throws SQLException {
- Connection conn = newConnection();
- StringBuilder buf = new StringBuilder();
- buf.append("DROP TABLE LOGGING_EVENT_EXCEPTION IF EXISTS;");
- query(conn, buf.toString());
+ public void tearDown() throws SQLException {
+ dropTables();
- buf = new StringBuilder();
- buf.append("DROP TABLE LOGGING_EVENT_PROPERTY IF EXISTS;");
- query(conn, buf.toString());
-
- buf = new StringBuilder();
- buf.append("DROP TABLE LOGGING_EVENT IF EXISTS;");
- query(conn, buf.toString());
+ if (mode == HsqlMode.MEM) {
+ server.stop();
+ server = null;
}
-
- private void query(Connection conn, String expression) throws SQLException {
-
- Statement st = null;
- st = conn.createStatement();
- int i = st.executeUpdate(expression);
- if (i == -1) {
- System.out.println("db error : " + expression);
- }
- st.close();
+ }
+
+ Connection newConnection() throws SQLException {
+ jdbcDriver driver = new jdbcDriver();
+ Properties props = new Properties();
+ props.setProperty("user", user);
+ props.setProperty("password", password);
+ return driver.connect(url, props);
+
+ // return DriverManager.getConnection(url, user, password);
+ }
+
+ private void createTables() throws SQLException {
+ Connection conn = newConnection();
+ assertNotNull(conn);
+ StringBuilder buf = new StringBuilder();
+ buf.append("CREATE TABLE LOGGING_EVENT (");
+ buf.append("TIMESTMP BIGINT NOT NULL,");
+ buf.append("FORMATTED_MESSAGE LONGVARCHAR NOT NULL,");
+ buf.append("LOGGER_NAME VARCHAR(256) NOT NULL,");
+ buf.append("LEVEL_STRING VARCHAR(256) NOT NULL,");
+ buf.append("THREAD_NAME VARCHAR(256),");
+ buf.append("REFERENCE_FLAG SMALLINT,");
+
+ buf.append("ARG0 VARCHAR(256),");
+ buf.append("ARG1 VARCHAR(256),");
+ buf.append("ARG2 VARCHAR(256),");
+ buf.append("ARG3 VARCHAR(256),");
+
+
+ buf.append("CALLER_FILENAME VARCHAR(256), ");
+ buf.append("CALLER_CLASS VARCHAR(256), ");
+ buf.append("CALLER_METHOD VARCHAR(256), ");
+ buf.append("CALLER_LINE CHAR(4), ");
+ buf.append("EVENT_ID BIGINT NOT NULL IDENTITY);");
+ query(conn, buf.toString());
+
+ buf = new StringBuilder();
+ buf.append("CREATE TABLE LOGGING_EVENT_PROPERTY (");
+ buf.append("EVENT_ID BIGINT NOT NULL,");
+ buf.append("MAPPED_KEY VARCHAR(254) NOT NULL,");
+ buf.append("MAPPED_VALUE LONGVARCHAR,");
+ buf.append("PRIMARY KEY(EVENT_ID, MAPPED_KEY),");
+ buf.append("FOREIGN KEY (EVENT_ID) REFERENCES LOGGING_EVENT(EVENT_ID));");
+ query(conn, buf.toString());
+
+ buf = new StringBuilder();
+ buf.append("CREATE TABLE LOGGING_EVENT_EXCEPTION (");
+ buf.append("EVENT_ID BIGINT NOT NULL,");
+ buf.append("I SMALLINT NOT NULL,");
+ buf.append("TRACE_LINE VARCHAR(256) NOT NULL,");
+ buf.append("PRIMARY KEY(EVENT_ID, I),");
+ buf.append("FOREIGN KEY (EVENT_ID) REFERENCES LOGGING_EVENT(EVENT_ID));");
+ query(conn, buf.toString());
+ }
+
+ private void dropTables() throws SQLException {
+ Connection conn = newConnection();
+ StringBuilder buf = new StringBuilder();
+ buf.append("DROP TABLE LOGGING_EVENT_EXCEPTION IF EXISTS;");
+ query(conn, buf.toString());
+
+ buf = new StringBuilder();
+ buf.append("DROP TABLE LOGGING_EVENT_PROPERTY IF EXISTS;");
+ query(conn, buf.toString());
+
+ buf = new StringBuilder();
+ buf.append("DROP TABLE LOGGING_EVENT IF EXISTS;");
+ query(conn, buf.toString());
+ }
+
+ private void query(Connection conn, String expression) throws SQLException {
+
+ Statement st = null;
+ st = conn.createStatement();
+ int i = st.executeUpdate(expression);
+ if (i == -1) {
+ System.out.println("db error : " + expression);
}
+ st.close();
+ }
- public enum HsqlMode {
- MEM, FILE, NET;
- }
+ public enum HsqlMode {
+ MEM, FILE, NET;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderIntegrationTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderIntegrationTest.java
index 5de152f..f939cae 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderIntegrationTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderIntegrationTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -37,199 +37,207 @@ import static org.junit.Assert.*;
public class DBAppenderIntegrationTest {
- static String LOCAL_HOST_NAME;
- static String[] CONFORMING_HOST_LIST = new String[] { "Orion" };
- static String[] POSTGRES_CONFORMING_HOST_LIST = new String[] { "haro" };
- static String[] MYSQL_CONFORMING_HOST_LIST = new String[] { "xharo" };
- static String[] ORACLE_CONFORMING_HOST_LIST = new String[] { "xharo" };
-
- int diff = RandomUtil.getPositiveInt();
- LoggerContext lc = new LoggerContext();
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- InetAddress localhostIA = InetAddress.getLocalHost();
- LOCAL_HOST_NAME = localhostIA.getHostName();
- }
-
- @AfterClass
- public static void tearDownAfterClass() throws Exception {
- }
-
- @Before
- public void setUp() throws Exception {
- lc.setName("lc" + diff);
- }
-
- @After
- public void tearDown() throws Exception {
- // lc will never be used again
- lc.stop();
- }
-
- DriverManagerConnectionSource getConnectionSource() {
- ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) lc.getLogger(Logger.ROOT_LOGGER_NAME);
-
- DBAppender dbAppender = (DBAppender) root.getAppender("DB");
- assertNotNull(dbAppender);
- return (DriverManagerConnectionSource) dbAppender.getConnectionSource();
-
- }
-
- public void doTest(String configFile) throws JoranException, SQLException {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- configurator.doConfigure(configFile);
-
- Logger logger = lc.getLogger(DBAppenderIntegrationTest.class);
-
- // the key userid is used in SiftingAppender test
- // suffix with diff to avoid collision
- MDC.put("userid" + diff, "user" + diff);
- int runLength = 5;
- for (int i = 1; i <= runLength; i++) {
- logger.debug("This is a debug message. Message number: " + (diff + i));
- }
-
- Exception e = new Exception("Just testing", getCause());
- logger.error("At last an error.", e);
-
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
-
- long lastEventId = getLastEventId();
- verify(lastEventId);
-
- // check that there were no errors
- StatusChecker checker = new StatusChecker(lc);
- checker.assertIsErrorFree();
- }
-
- long getLastEventId() throws SQLException {
- DriverManagerConnectionSource cs = getConnectionSource();
-
- Connection con = cs.getConnection();
- Statement statement = con.createStatement();
- statement.setMaxRows(1);
- ResultSet rs = statement.executeQuery("select event_id from logging_event order by event_id desc");
- rs.next();
- long eventId = rs.getLong(1);
- rs.close();
- statement.close();
- return eventId;
- }
-
- void verify(long lastEventId) throws SQLException {
- verifyDebugMsg(lastEventId);
- verifyException(lastEventId);
- verifyProperty(lastEventId);
-
- }
-
- void verifyDebugMsg(long lastEventId) throws SQLException {
- DriverManagerConnectionSource cs = getConnectionSource();
- Connection con = cs.getConnection();
- Statement statement = con.createStatement();
- ResultSet rs = statement.executeQuery("select formatted_message from logging_event where event_id='" + (lastEventId - 1) + "'");
- rs.next();
- String msg = rs.getString(1);
- assertEquals("This is a debug message. Message number: " + (diff + 5), msg);
- }
-
- @SuppressWarnings("unchecked")
- void verifyProperty(long lastEventId) throws SQLException {
- DriverManagerConnectionSource cs = getConnectionSource();
- Connection con = cs.getConnection();
- Statement statement = con.createStatement();
- ResultSet rs = statement.executeQuery("select mapped_key, mapped_value from logging_event_property where event_id='" + (lastEventId - 1) + "'");
-
- Map<String, String> witness = lc.getCopyOfPropertyMap();
- witness.putAll(MDC.getCopyOfContextMap());
-
- Map<String, String> map = new HashMap<String, String>();
- while (rs.next()) {
- String key = rs.getString(1);
- String val = rs.getString(2);
- map.put(key, val);
- }
-
- assertEquals(witness, map);
- }
-
- void verifyException(long lastEventId) throws SQLException {
- DriverManagerConnectionSource cs = getConnectionSource();
- Connection con = cs.getConnection();
- Statement statement = con.createStatement();
- ResultSet rs = statement.executeQuery("select trace_line from logging_event_exception where event_id='" + (lastEventId) + "' AND I='0'");
- rs.next();
- String traceLine = rs.getString(1);
- assertEquals("java.lang.Exception: Just testing", traceLine);
- }
-
- Throwable getCause() {
- return new IllegalStateException("test cause");
- }
-
- static boolean isConformingHostAndJDK16OrHigher(String[] conformingHostList) {
- if (!EnvUtil.isJDK6OrHigher()) {
- return false;
- }
- for (String conformingHost : conformingHostList) {
- if (conformingHost.equalsIgnoreCase(LOCAL_HOST_NAME)) {
- return true;
- }
- }
- return false;
- }
-
- static boolean isConformingHostAndJDK16OrHigher() {
- return isConformingHostAndJDK16OrHigher(CONFORMING_HOST_LIST);
- }
-
- @Test
- public void sqlserver() throws Exception {
- // perform test only on conforming hosts
- if (!isConformingHostAndJDK16OrHigher()) {
- return;
- }
- doTest("src/test/input/integration/db/sqlserver-with-driver.xml");
- }
-
- @Test
- public void oracle10g() throws Exception {
- // perform test only on conforming hosts
- if (!isConformingHostAndJDK16OrHigher(ORACLE_CONFORMING_HOST_LIST)) {
- return;
- }
- doTest("src/test/input/integration/db/oracle10g-with-driver.xml");
- }
-
- @Test
- @Ignore
- public void oracle11g() throws Exception {
- // perform test only on conforming hosts
- if (!isConformingHostAndJDK16OrHigher()) {
- return;
- }
- doTest("src/test/input/integration/db/oracle11g-with-driver.xml");
- }
-
- @Test
- public void mysql() throws Exception {
- // perform test only on conforming hosts
- if (!isConformingHostAndJDK16OrHigher(MYSQL_CONFORMING_HOST_LIST)) {
- return;
- }
- doTest("src/test/input/integration/db/mysql-with-driver.xml");
- }
-
- @Test
- public void postgres() throws Exception {
- // perform test only on conforming hosts
- if (!isConformingHostAndJDK16OrHigher(POSTGRES_CONFORMING_HOST_LIST)) {
- return;
- }
- System.out.println("running postgres() test");
- doTest("src/test/input/integration/db/postgresql-with-driver.xml");
- }
+ static String LOCAL_HOST_NAME;
+ static String[] CONFORMING_HOST_LIST = new String[] { "Orion" };
+ static String[] POSTGRES_CONFORMING_HOST_LIST = new String[] { "haro" };
+ static String[] MYSQL_CONFORMING_HOST_LIST = new String[] { "xharo" };
+ static String[] ORACLE_CONFORMING_HOST_LIST = new String[] { "xharo" };
+
+ int diff = RandomUtil.getPositiveInt();
+ LoggerContext lc = new LoggerContext();
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ InetAddress localhostIA = InetAddress.getLocalHost();
+ LOCAL_HOST_NAME = localhostIA.getHostName();
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ lc.setName("lc" + diff);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ // lc will never be used again
+ lc.stop();
+ }
+
+ DriverManagerConnectionSource getConnectionSource() {
+ ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) lc
+ .getLogger(Logger.ROOT_LOGGER_NAME);
+
+ DBAppender dbAppender = (DBAppender) root.getAppender("DB");
+ assertNotNull(dbAppender);
+ return (DriverManagerConnectionSource) dbAppender.getConnectionSource();
+
+ }
+
+ public void doTest(String configFile) throws JoranException, SQLException {
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ configurator.doConfigure(configFile);
+
+ Logger logger = lc.getLogger(DBAppenderIntegrationTest.class);
+
+ // the key userid is used in SiftingAppender test
+ // suffix with diff to avoid collision
+ MDC.put("userid"+diff, "user" + diff);
+ int runLength = 5;
+ for (int i = 1; i <= runLength; i++) {
+ logger.debug("This is a debug message. Message number: " + (diff + i));
+ }
+
+ Exception e = new Exception("Just testing", getCause());
+ logger.error("At last an error.", e);
+
+ StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
+
+ long lastEventId = getLastEventId();
+ verify(lastEventId);
+
+ // check that there were no errors
+ StatusChecker checker = new StatusChecker(lc);
+ checker.assertIsErrorFree();
+ }
+
+ long getLastEventId() throws SQLException {
+ DriverManagerConnectionSource cs = getConnectionSource();
+
+ Connection con = cs.getConnection();
+ Statement statement = con.createStatement();
+ statement.setMaxRows(1);
+ ResultSet rs = statement
+ .executeQuery("select event_id from logging_event order by event_id desc");
+ rs.next();
+ long eventId = rs.getLong(1);
+ rs.close();
+ statement.close();
+ return eventId;
+ }
+
+ void verify(long lastEventId) throws SQLException {
+ verifyDebugMsg(lastEventId);
+ verifyException(lastEventId);
+ verifyProperty(lastEventId);
+
+ }
+
+ void verifyDebugMsg(long lastEventId) throws SQLException {
+ DriverManagerConnectionSource cs = getConnectionSource();
+ Connection con = cs.getConnection();
+ Statement statement = con.createStatement();
+ ResultSet rs = statement
+ .executeQuery("select formatted_message from logging_event where event_id='"
+ + (lastEventId - 1) + "'");
+ rs.next();
+ String msg = rs.getString(1);
+ assertEquals("This is a debug message. Message number: " + (diff + 5), msg);
+ }
+
+ @SuppressWarnings("unchecked")
+ void verifyProperty(long lastEventId) throws SQLException {
+ DriverManagerConnectionSource cs = getConnectionSource();
+ Connection con = cs.getConnection();
+ Statement statement = con.createStatement();
+ ResultSet rs = statement
+ .executeQuery("select mapped_key, mapped_value from logging_event_property where event_id='"
+ + (lastEventId - 1) + "'");
+
+ Map<String, String> witness = lc.getCopyOfPropertyMap();
+ witness.putAll(MDC.getCopyOfContextMap());
+
+ Map<String, String> map = new HashMap<String, String>();
+ while (rs.next()) {
+ String key = rs.getString(1);
+ String val = rs.getString(2);
+ map.put(key, val);
+ }
+
+ assertEquals(witness, map);
+ }
+
+ void verifyException(long lastEventId) throws SQLException {
+ DriverManagerConnectionSource cs = getConnectionSource();
+ Connection con = cs.getConnection();
+ Statement statement = con.createStatement();
+ ResultSet rs = statement
+ .executeQuery("select trace_line from logging_event_exception where event_id='"
+ + (lastEventId) + "' AND I='0'");
+ rs.next();
+ String traceLine = rs.getString(1);
+ assertEquals("java.lang.Exception: Just testing", traceLine);
+ }
+
+ Throwable getCause() {
+ return new IllegalStateException("test cause");
+ }
+
+ static boolean isConformingHostAndJDK16OrHigher(String[] conformingHostList) {
+ if (!EnvUtil.isJDK6OrHigher()) {
+ return false;
+ }
+ for (String conformingHost : conformingHostList) {
+ if (conformingHost.equalsIgnoreCase(LOCAL_HOST_NAME)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static boolean isConformingHostAndJDK16OrHigher() {
+ return isConformingHostAndJDK16OrHigher(CONFORMING_HOST_LIST);
+ }
+
+ @Test
+ public void sqlserver() throws Exception {
+ // perform test only on conforming hosts
+ if (!isConformingHostAndJDK16OrHigher()) {
+ return;
+ }
+ doTest("src/test/input/integration/db/sqlserver-with-driver.xml");
+ }
+
+ @Test
+ public void oracle10g() throws Exception {
+ // perform test only on conforming hosts
+ if (!isConformingHostAndJDK16OrHigher(ORACLE_CONFORMING_HOST_LIST)) {
+ return;
+ }
+ doTest("src/test/input/integration/db/oracle10g-with-driver.xml");
+ }
+
+ @Test
+ @Ignore
+ public void oracle11g() throws Exception {
+ // perform test only on conforming hosts
+ if (!isConformingHostAndJDK16OrHigher()) {
+ return;
+ }
+ doTest("src/test/input/integration/db/oracle11g-with-driver.xml");
+ }
+
+ @Test
+ public void mysql() throws Exception {
+ // perform test only on conforming hosts
+ if (!isConformingHostAndJDK16OrHigher(MYSQL_CONFORMING_HOST_LIST)) {
+ return;
+ }
+ doTest("src/test/input/integration/db/mysql-with-driver.xml");
+ }
+
+ @Test
+ public void postgres() throws Exception {
+ // perform test only on conforming hosts
+ if (!isConformingHostAndJDK16OrHigher(POSTGRES_CONFORMING_HOST_LIST)) {
+ return;
+ }
+ System.out.println("running postgres() test");
+ doTest("src/test/input/integration/db/postgresql-with-driver.xml");
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/db/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/db/PackageTest.java
index ab587f1..7114bdf 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/db/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/db/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,7 +18,8 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ DBAppenderHSQLTest.class, DBAppenderH2Test.class, DBAppenderIntegrationTest.class, SQLBuilderTest.class,
- ch.qos.logback.classic.db.names.PackageTest.class })
+ at SuiteClasses( { DBAppenderHSQLTest.class, DBAppenderH2Test.class,
+ DBAppenderIntegrationTest.class, SQLBuilderTest.class,
+ ch.qos.logback.classic.db.names.PackageTest.class})
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/db/SQLBuilderTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/db/SQLBuilderTest.java
index 9f0a6c6..7f5b63c 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/db/SQLBuilderTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/db/SQLBuilderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,7 +13,7 @@
*/
package ch.qos.logback.classic.db;
-import static org.assertj.core.api.Assertions.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
import org.junit.Test;
@@ -27,91 +27,92 @@ import ch.qos.logback.classic.db.names.SimpleDBNameResolver;
*/
public class SQLBuilderTest {
- @Test
- public void shouldReturnDefaultSqlInsertLoggingEventQuery() throws Exception {
- // given
- DBNameResolver nameResolver = new DefaultDBNameResolver();
-
- // when
- String sql = SQLBuilder.buildInsertSQL(nameResolver);
-
- // then
- final String expected = "INSERT INTO logging_event (timestmp, formatted_message, logger_name, level_string, thread_name, reference_flag, arg0, arg1, arg2, arg3, caller_filename, caller_class, caller_method, caller_line) VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
- assertThat(sql).isEqualTo(expected);
- }
-
- @Test
- public void shouldReturnDefaultSqlInsertExceptionQuery() throws Exception {
- // given
- DBNameResolver nameResolver = new DefaultDBNameResolver();
-
- // when
- String sql = SQLBuilder.buildInsertExceptionSQL(nameResolver);
-
- // then
- final String expected = "INSERT INTO logging_event_exception (event_id, i, trace_line) VALUES (?, ?, ?)";
- assertThat(sql).isEqualTo(expected);
- }
-
- @Test
- public void shouldReturnDefaultSqlInsertLoggingPropertyQuery() throws Exception {
- // given
- DBNameResolver nameResolver = new DefaultDBNameResolver();
-
- // when
- String sql = SQLBuilder.buildInsertPropertiesSQL(nameResolver);
-
- // then
- final String expected = "INSERT INTO logging_event_property (event_id, mapped_key, mapped_value) VALUES (?, ?, ?)";
- assertThat(sql).isEqualTo(expected);
- }
-
- private DBNameResolver createSimpleDBNameResolver() {
- final SimpleDBNameResolver nameResolver = new SimpleDBNameResolver();
- nameResolver.setTableNamePrefix("tp_");
- nameResolver.setTableNameSuffix("_ts");
- nameResolver.setColumnNamePrefix("cp_");
- nameResolver.setColumnNameSuffix("_cs");
- return nameResolver;
- }
-
- @Test
- public void shouldReturnSimpleSqlInsertLoggingEventQuery() throws Exception {
- // given
- DBNameResolver nameResolver = createSimpleDBNameResolver();
-
- // when
- String sql = SQLBuilder.buildInsertSQL(nameResolver);
-
- // then
- final String expected = "INSERT INTO tp_logging_event_ts (cp_timestmp_cs, cp_formatted_message_cs, cp_logger_name_cs, cp_level_string_cs, cp_thread_name_cs, cp_reference_flag_cs, cp_arg0_cs, cp_arg1_cs, cp_arg2_cs, cp_arg3_cs, cp_caller_filename_cs, cp_caller_class_cs, cp_caller_method_cs, cp_caller_line_cs) VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
- assertThat(sql).isEqualTo(expected);
- }
-
- @Test
- public void shouldReturnSimpleSqlInsertExceptionQuery() throws Exception {
- // given
- DBNameResolver nameResolver = createSimpleDBNameResolver();
-
- // when
- String sql = SQLBuilder.buildInsertExceptionSQL(nameResolver);
-
- // then
- final String expected = "INSERT INTO tp_logging_event_exception_ts (cp_event_id_cs, cp_i_cs, cp_trace_line_cs) VALUES (?, ?, ?)";
- assertThat(sql).isEqualTo(expected);
- }
-
- @Test
- public void shouldReturnSimpleSqlInsertLoggingPropertyQuery() throws Exception {
- // given
- DBNameResolver nameResolver = createSimpleDBNameResolver();
-
- // when
- String sql = SQLBuilder.buildInsertPropertiesSQL(nameResolver);
-
- // then
- final String expected = "INSERT INTO tp_logging_event_property_ts (cp_event_id_cs, cp_mapped_key_cs, cp_mapped_value_cs) VALUES (?, ?, ?)";
- assertThat(sql).isEqualTo(expected);
- }
+ @Test
+ public void shouldReturnDefaultSqlInsertLoggingEventQuery() throws Exception {
+ //given
+ DBNameResolver nameResolver = new DefaultDBNameResolver();
+
+ //when
+ String sql = SQLBuilder.buildInsertSQL(nameResolver);
+
+ //then
+ final String expected = "INSERT INTO logging_event (timestmp, formatted_message, logger_name, level_string, thread_name, reference_flag, arg0, arg1, arg2, arg3, caller_filename, caller_class, caller_method, caller_line) VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+ assertThat(sql).isEqualTo(expected);
+ }
+
+ @Test
+ public void shouldReturnDefaultSqlInsertExceptionQuery() throws Exception {
+ //given
+ DBNameResolver nameResolver = new DefaultDBNameResolver();
+
+ //when
+ String sql = SQLBuilder.buildInsertExceptionSQL(nameResolver);
+
+ //then
+ final String expected = "INSERT INTO logging_event_exception (event_id, i, trace_line) VALUES (?, ?, ?)";
+ assertThat(sql).isEqualTo(expected);
+ }
+
+ @Test
+ public void shouldReturnDefaultSqlInsertLoggingPropertyQuery() throws Exception {
+ //given
+ DBNameResolver nameResolver = new DefaultDBNameResolver();
+
+ //when
+ String sql = SQLBuilder.buildInsertPropertiesSQL(nameResolver);
+
+ //then
+ final String expected = "INSERT INTO logging_event_property (event_id, mapped_key, mapped_value) VALUES (?, ?, ?)";
+ assertThat(sql).isEqualTo(expected);
+ }
+
+
+ private DBNameResolver createSimpleDBNameResolver() {
+ final SimpleDBNameResolver nameResolver = new SimpleDBNameResolver();
+ nameResolver.setTableNamePrefix("tp_");
+ nameResolver.setTableNameSuffix("_ts");
+ nameResolver.setColumnNamePrefix("cp_");
+ nameResolver.setColumnNameSuffix("_cs");
+ return nameResolver;
+ }
+
+ @Test
+ public void shouldReturnSimpleSqlInsertLoggingEventQuery() throws Exception {
+ //given
+ DBNameResolver nameResolver = createSimpleDBNameResolver();
+
+ //when
+ String sql = SQLBuilder.buildInsertSQL(nameResolver);
+
+ //then
+ final String expected = "INSERT INTO tp_logging_event_ts (cp_timestmp_cs, cp_formatted_message_cs, cp_logger_name_cs, cp_level_string_cs, cp_thread_name_cs, cp_reference_flag_cs, cp_arg0_cs, cp_arg1_cs, cp_arg2_cs, cp_arg3_cs, cp_caller_filename_cs, cp_caller_class_cs, cp_caller_method_cs, cp_caller_line_cs) VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+ assertThat(sql).isEqualTo(expected);
+ }
+
+ @Test
+ public void shouldReturnSimpleSqlInsertExceptionQuery() throws Exception {
+ //given
+ DBNameResolver nameResolver = createSimpleDBNameResolver();
+
+ //when
+ String sql = SQLBuilder.buildInsertExceptionSQL(nameResolver);
+
+ //then
+ final String expected = "INSERT INTO tp_logging_event_exception_ts (cp_event_id_cs, cp_i_cs, cp_trace_line_cs) VALUES (?, ?, ?)";
+ assertThat(sql).isEqualTo(expected);
+ }
+
+ @Test
+ public void shouldReturnSimpleSqlInsertLoggingPropertyQuery() throws Exception {
+ //given
+ DBNameResolver nameResolver = createSimpleDBNameResolver();
+
+ //when
+ String sql = SQLBuilder.buildInsertPropertiesSQL(nameResolver);
+
+ //then
+ final String expected = "INSERT INTO tp_logging_event_property_ts (cp_event_id_cs, cp_mapped_key_cs, cp_mapped_value_cs) VALUES (?, ?, ?)";
+ assertThat(sql).isEqualTo(expected);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/db/names/DefaultDBNameResolverTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/db/names/DefaultDBNameResolverTest.java
index f5c4ce7..db49943 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/db/names/DefaultDBNameResolverTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/db/names/DefaultDBNameResolverTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,7 +16,7 @@ package ch.qos.logback.classic.db.names;
import org.junit.Before;
import org.junit.Test;
-import static org.assertj.core.api.Assertions.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
/**
* @author Tomasz Nurkiewicz
@@ -24,47 +24,47 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
public class DefaultDBNameResolverTest {
- private DefaultDBNameResolver resolver;
+ private DefaultDBNameResolver resolver;
- @Before
- public void setUp() throws Exception {
- resolver = new DefaultDBNameResolver();
- }
+ @Before
+ public void setUp() throws Exception {
+ resolver = new DefaultDBNameResolver();
+ }
- @Test
- public void testGetLoggingEventColumnName() throws Exception {
- // when
- String columnName = resolver.getColumnName(ColumnName.LOGGER_NAME);
+ @Test
+ public void testGetLoggingEventColumnName() throws Exception {
+ //when
+ String columnName = resolver.getColumnName(ColumnName.LOGGER_NAME);
- // then
- assertThat(columnName).isEqualTo("logger_name");
- }
+ //then
+ assertThat(columnName).isEqualTo("logger_name");
+ }
- @Test
- public void testGetLoggingEventPropertyColumnName() throws Exception {
- // when
- String columnName = resolver.getColumnName(ColumnName.MAPPED_KEY);
+ @Test
+ public void testGetLoggingEventPropertyColumnName() throws Exception {
+ //when
+ String columnName = resolver.getColumnName(ColumnName.MAPPED_KEY);
- // then
- assertThat(columnName).isEqualTo("mapped_key");
- }
+ //then
+ assertThat(columnName).isEqualTo("mapped_key");
+ }
- @Test
- public void testGetLoggingEventExceptionColumnName() throws Exception {
- // when
- String columnName = resolver.getColumnName(ColumnName.TRACE_LINE);
+ @Test
+ public void testGetLoggingEventExceptionColumnName() throws Exception {
+ //when
+ String columnName = resolver.getColumnName(ColumnName.TRACE_LINE);
- // then
- assertThat(columnName).isEqualTo("trace_line");
- }
+ //then
+ assertThat(columnName).isEqualTo("trace_line");
+ }
- @Test
- public void testGetTableName() throws Exception {
- // when
- String tableName = resolver.getTableName(TableName.LOGGING_EVENT_EXCEPTION);
+ @Test
+ public void testGetTableName() throws Exception {
+ //when
+ String tableName = resolver.getTableName(TableName.LOGGING_EVENT_EXCEPTION);
- // then
- assertThat(tableName).isEqualTo("logging_event_exception");
- }
+ //then
+ assertThat(tableName).isEqualTo("logging_event_exception");
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/db/names/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/db/names/PackageTest.java
index f84fa4e..8a6331f 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/db/names/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/db/names/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,7 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ DefaultDBNameResolverTest.class, SimpleDBNameResolverTest.class })
+ at SuiteClasses( { DefaultDBNameResolverTest.class,
+ SimpleDBNameResolverTest.class })
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/db/names/SimpleDBNameResolverTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/db/names/SimpleDBNameResolverTest.java
index 8a57774..3380724 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/db/names/SimpleDBNameResolverTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/db/names/SimpleDBNameResolverTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,7 +16,7 @@ package ch.qos.logback.classic.db.names;
import org.junit.Before;
import org.junit.Test;
-import static org.assertj.core.api.Assertions.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
/**
* @author Tomasz Nurkiewicz
@@ -24,119 +24,118 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
public class SimpleDBNameResolverTest {
- private SimpleDBNameResolver nameResolver;
-
- @Before
- public void setUp() throws Exception {
- nameResolver = new SimpleDBNameResolver();
- /*
- * nameResolver.setTableNameSuffix("_ts"); nameResolver.setColumnNamePrefix("cp_");
- * nameResolver.setColumnNameSuffix("_cs");
- */
- }
-
- @Test
- public void shouldReturnTableNameWithPrefix() throws Exception {
- // given
-
- // when
- nameResolver.setTableNamePrefix("tp_");
-
- // then
- assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("tp_logging_event");
- assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("thread_name");
- }
-
- @Test
- public void shouldReturnTableNameWithSuffix() throws Exception {
- // given
-
- // when
- nameResolver.setTableNameSuffix("_ts");
-
- // then
- assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("logging_event_ts");
- assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("thread_name");
- }
-
- @Test
- public void shouldReturnTableNameWithBothPrefixAndSuffix() throws Exception {
- // given
-
- // when
- nameResolver.setTableNamePrefix("tp_");
- nameResolver.setTableNameSuffix("_ts");
-
- // then
- assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("tp_logging_event_ts");
- assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("thread_name");
- }
-
- @Test
- public void shouldReturnColumnNameWithPrefix() throws Exception {
- // given
-
- // when
- nameResolver.setColumnNamePrefix("cp_");
-
- // then
- assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("logging_event");
- assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("cp_thread_name");
- }
-
- @Test
- public void shouldReturnColumnNameWithSuffix() throws Exception {
- // given
-
- // when
- nameResolver.setColumnNameSuffix("_cs");
-
- // then
- assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("logging_event");
- assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("thread_name_cs");
- }
-
- @Test
- public void shouldReturnColumnNameWithBothPrefixAndSuffix() throws Exception {
- // given
-
- // when
- nameResolver.setColumnNamePrefix("cp_");
- nameResolver.setColumnNameSuffix("_cs");
-
- // then
- assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("logging_event");
- assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("cp_thread_name_cs");
- }
-
- @Test
- public void shouldReturnTableAndColumnNamesWithBothPrefixAndSuffix() throws Exception {
- // given
-
- // when
- nameResolver.setTableNamePrefix("tp_");
- nameResolver.setTableNameSuffix("_ts");
- nameResolver.setColumnNamePrefix("cp_");
- nameResolver.setColumnNameSuffix("_cs");
-
- // then
- assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("tp_logging_event_ts");
- assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("cp_thread_name_cs");
- }
-
- @Test
- public void shouldHandleNullsAsEmptyStrings() throws Exception {
- // given
-
- // when
- nameResolver.setTableNamePrefix(null);
- nameResolver.setTableNameSuffix(null);
- nameResolver.setColumnNamePrefix(null);
- nameResolver.setColumnNameSuffix(null);
-
- // then
- assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("logging_event");
- assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("thread_name");
- }
+ private SimpleDBNameResolver nameResolver;
+
+ @Before
+ public void setUp() throws Exception {
+ nameResolver = new SimpleDBNameResolver();
+ /*nameResolver.setTableNameSuffix("_ts");
+ nameResolver.setColumnNamePrefix("cp_");
+ nameResolver.setColumnNameSuffix("_cs");*/
+ }
+
+ @Test
+ public void shouldReturnTableNameWithPrefix() throws Exception {
+ //given
+
+ //when
+ nameResolver.setTableNamePrefix("tp_");
+
+ //then
+ assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("tp_logging_event");
+ assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("thread_name");
+ }
+
+ @Test
+ public void shouldReturnTableNameWithSuffix() throws Exception {
+ //given
+
+ //when
+ nameResolver.setTableNameSuffix("_ts");
+
+ //then
+ assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("logging_event_ts");
+ assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("thread_name");
+ }
+
+ @Test
+ public void shouldReturnTableNameWithBothPrefixAndSuffix() throws Exception {
+ //given
+
+ //when
+ nameResolver.setTableNamePrefix("tp_");
+ nameResolver.setTableNameSuffix("_ts");
+
+ //then
+ assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("tp_logging_event_ts");
+ assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("thread_name");
+ }
+
+ @Test
+ public void shouldReturnColumnNameWithPrefix() throws Exception {
+ //given
+
+ //when
+ nameResolver.setColumnNamePrefix("cp_");
+
+ //then
+ assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("logging_event");
+ assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("cp_thread_name");
+ }
+
+ @Test
+ public void shouldReturnColumnNameWithSuffix() throws Exception {
+ //given
+
+ //when
+ nameResolver.setColumnNameSuffix("_cs");
+
+ //then
+ assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("logging_event");
+ assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("thread_name_cs");
+ }
+
+ @Test
+ public void shouldReturnColumnNameWithBothPrefixAndSuffix() throws Exception {
+ //given
+
+ //when
+ nameResolver.setColumnNamePrefix("cp_");
+ nameResolver.setColumnNameSuffix("_cs");
+
+ //then
+ assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("logging_event");
+ assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("cp_thread_name_cs");
+ }
+
+ @Test
+ public void shouldReturnTableAndColumnNamesWithBothPrefixAndSuffix() throws Exception {
+ //given
+
+ //when
+ nameResolver.setTableNamePrefix("tp_");
+ nameResolver.setTableNameSuffix("_ts");
+ nameResolver.setColumnNamePrefix("cp_");
+ nameResolver.setColumnNameSuffix("_cs");
+
+ //then
+ assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("tp_logging_event_ts");
+ assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("cp_thread_name_cs");
+ }
+
+ @Test
+ public void shouldHandleNullsAsEmptyStrings() throws Exception {
+ //given
+
+ //when
+ nameResolver.setTableNamePrefix(null);
+ nameResolver.setTableNameSuffix(null);
+ nameResolver.setColumnNamePrefix(null);
+ nameResolver.setColumnNameSuffix(null);
+
+ //then
+ assertThat(nameResolver.getTableName(TableName.LOGGING_EVENT)).isEqualTo("logging_event");
+ assertThat(nameResolver.getColumnName(ColumnName.THREAD_NAME)).isEqualTo("thread_name");
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/encoder/LayoutInsteadOfEncoderTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/encoder/LayoutInsteadOfEncoderTest.java
index 89d31e7..ce9bcab 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/encoder/LayoutInsteadOfEncoderTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/encoder/LayoutInsteadOfEncoderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -33,29 +33,30 @@ import ch.qos.logback.core.util.StatusPrinter;
public class LayoutInsteadOfEncoderTest {
- // TeztConstants.TEST_SRC_PREFIX + "input/joran/ignore.xml"
- JoranConfigurator jc = new JoranConfigurator();
- LoggerContext loggerContext = new LoggerContext();
-
- @Before
- public void setUp() {
- jc.setContext(loggerContext);
-
- }
-
- // jc.doConfigure(TeztConstants.TEST_SRC_PREFIX + "input/joran/ignore.xml");
-
- @Test
- public void layoutInsteadOfEncoer() throws JoranException {
- jc.doConfigure(ClassicTestConstants.JORAN_INPUT_PREFIX + "compatibility/layoutInsteadOfEncoder.xml");
- StatusPrinter.print(loggerContext);
- StatusChecker checker = new StatusChecker(loggerContext);
- checker.assertContainsMatch(Status.WARN, "This appender no longer admits a layout as a sub-component");
- checker.assertContainsMatch(Status.WARN, "See also " + CODES_URL + "#layoutInsteadOfEncoder for details");
-
- ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
- FileAppender<ILoggingEvent> fileAppender = (FileAppender<ILoggingEvent>) root.getAppender("LIOE");
- assertTrue(fileAppender.isStarted());
- assertTrue(fileAppender.getEncoder() instanceof LayoutWrappingEncoder);
- }
+ // TeztConstants.TEST_SRC_PREFIX + "input/joran/ignore.xml"
+ JoranConfigurator jc = new JoranConfigurator();
+ LoggerContext loggerContext = new LoggerContext();
+
+ @Before
+ public void setUp() {
+ jc.setContext(loggerContext);
+
+ }
+
+ // jc.doConfigure(TeztConstants.TEST_SRC_PREFIX + "input/joran/ignore.xml");
+
+ @Test
+ public void layoutInsteadOfEncoer() throws JoranException {
+ jc.doConfigure(ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "compatibility/layoutInsteadOfEncoder.xml");
+ StatusPrinter.print(loggerContext);
+ StatusChecker checker = new StatusChecker(loggerContext);
+ checker.assertContainsMatch(Status.WARN, "This appender no longer admits a layout as a sub-component");
+ checker.assertContainsMatch(Status.WARN, "See also "+CODES_URL+"#layoutInsteadOfEncoder for details");
+
+ ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
+ FileAppender<ILoggingEvent> fileAppender = (FileAppender<ILoggingEvent>) root.getAppender("LIOE");
+ assertTrue(fileAppender.isStarted());
+ assertTrue(fileAppender.getEncoder() instanceof LayoutWrappingEncoder);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/encoder/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/encoder/PackageTest.java
index 3711453..c96c9a3 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/encoder/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/encoder/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ PatternLayoutEncoderTest.class, LayoutInsteadOfEncoderTest.class })
+ at SuiteClasses( { PatternLayoutEncoderTest.class, LayoutInsteadOfEncoderTest.class})
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/encoder/PatternLayoutEncoderTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/encoder/PatternLayoutEncoderTest.java
index 324204a..220c083 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/encoder/PatternLayoutEncoderTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/encoder/PatternLayoutEncoderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,47 +31,47 @@ import ch.qos.logback.classic.spi.LoggingEvent;
public class PatternLayoutEncoderTest {
- PatternLayoutEncoder ple = new PatternLayoutEncoder();
- LoggerContext context = new LoggerContext();
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- Logger logger = context.getLogger(PatternLayoutEncoderTest.class);
- Charset utf8Charset = Charset.forName("UTF-8");
+ PatternLayoutEncoder ple = new PatternLayoutEncoder();
+ LoggerContext context = new LoggerContext();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Logger logger = context.getLogger(PatternLayoutEncoderTest.class);
+ Charset utf8Charset = Charset.forName("UTF-8");
+
+ @Before
+ public void setUp() {
+ ple.setPattern("%m");
+ ple.setContext(context);
+ }
- @Before
- public void setUp() {
- ple.setPattern("%m");
- ple.setContext(context);
- }
+ ILoggingEvent makeLoggingEvent(String message) {
+ return new LoggingEvent("", logger, Level.DEBUG, message, null, null);
+ }
- ILoggingEvent makeLoggingEvent(String message) {
- return new LoggingEvent("", logger, Level.DEBUG, message, null, null);
- }
+ @Test
+ public void smoke() throws IOException {
+ init(baos);
+ String msg = "hello";
+ ILoggingEvent event = makeLoggingEvent(msg);
+ ple.doEncode(event);
+ ple.close();
+ assertEquals(msg, baos.toString());
+ }
- @Test
- public void smoke() throws IOException {
- init(baos);
- String msg = "hello";
- ILoggingEvent event = makeLoggingEvent(msg);
- ple.doEncode(event);
- ple.close();
- assertEquals(msg, baos.toString());
- }
+ void init(ByteArrayOutputStream baos) throws IOException {
+ ple.start();
+ ((PatternLayout) ple.getLayout()).setOutputPatternAsHeader(false);
+ ple.init(baos);
+ }
- void init(ByteArrayOutputStream baos) throws IOException {
- ple.start();
- ((PatternLayout) ple.getLayout()).setOutputPatternAsHeader(false);
- ple.init(baos);
- }
-
- @Test
- public void charset() throws IOException {
- ple.setCharset(utf8Charset);
- init(baos);
- String msg = "\u03b1";
- ILoggingEvent event = makeLoggingEvent(msg);
- ple.doEncode(event);
- ple.close();
- assertEquals(msg, new String(baos.toByteArray(), utf8Charset.name()));
- }
+ @Test
+ public void charset() throws IOException {
+ ple.setCharset(utf8Charset);
+ init(baos);
+ String msg = "\u03b1";
+ ILoggingEvent event = makeLoggingEvent(msg);
+ ple.doEncode(event);
+ ple.close();
+ assertEquals(msg, new String(baos.toByteArray(), utf8Charset.name()));
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java
index 669e83a..c846280 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -47,197 +47,205 @@ import ch.qos.logback.core.util.StatusPrinter;
public class HTMLLayoutTest {
- LoggerContext lc;
- Logger root;
- HTMLLayout layout;
-
- @Before
- public void setUp() throws Exception {
- lc = new LoggerContext();
- lc.setName("default");
-
- layout = new HTMLLayout();
- layout.setThrowableRenderer(new DefaultThrowableRenderer());
- layout.setContext(lc);
- layout.setPattern("%level%thread%msg");
- layout.start();
-
- root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
-
- }
-
- @After
- public void tearDown() throws Exception {
- lc = null;
- layout = null;
- }
-
- @Test
- public void testHeader() throws Exception {
- String header = layout.getFileHeader();
- // System.out.println(header);
-
- Document doc = parseOutput(header + "</body></html>");
- Element rootElement = doc.getRootElement();
- assertNotNull(rootElement.element("body"));
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testPresentationHeader() throws Exception {
- String header = layout.getFileHeader();
- String presentationHeader = layout.getPresentationHeader();
- header = header + presentationHeader;
- // System.out.println(header);
-
- Document doc = parseOutput(header + "</table></body></html>");
- Element rootElement = doc.getRootElement();
- Element bodyElement = rootElement.element("body");
- Element tableElement = bodyElement.element("table");
- Element trElement = tableElement.element("tr");
- List<Element> elementList = trElement.elements();
- assertEquals("Level", elementList.get(0).getText());
- assertEquals("Thread", elementList.get(1).getText());
- assertEquals("Message", elementList.get(2).getText());
- }
-
- @Test
- public void testAppendThrowable() throws Exception {
- StringBuilder buf = new StringBuilder();
- DummyThrowableProxy tp = new DummyThrowableProxy();
- tp.setClassName("test1");
- tp.setMessage("msg1");
-
- StackTraceElement ste1 = new StackTraceElement("c1", "m1", "f1", 1);
- StackTraceElement ste2 = new StackTraceElement("c2", "m2", "f2", 2);
-
- StackTraceElementProxy[] stepArray = { new StackTraceElementProxy(ste1), new StackTraceElementProxy(ste2) };
- tp.setStackTraceElementProxyArray(stepArray);
- DefaultThrowableRenderer renderer = (DefaultThrowableRenderer) layout.getThrowableRenderer();
-
- renderer.render(buf, tp);
- System.out.println(buf.toString());
- String[] result = buf.toString().split(CoreConstants.LINE_SEPARATOR);
- System.out.println(result[0]);
- assertEquals("test1: msg1", result[0]);
- assertEquals(DefaultThrowableRenderer.TRACE_PREFIX + "at c1.m1(f1:1)", result[1]);
- }
-
- @Test
- public void testDoLayout() throws Exception {
- ILoggingEvent le = createLoggingEvent();
-
- String result = layout.getFileHeader();
- result += layout.getPresentationHeader();
- result += layout.doLayout(le);
- result += layout.getPresentationFooter();
- result += layout.getFileFooter();
-
- Document doc = parseOutput(result);
- Element rootElement = doc.getRootElement();
- rootElement.toString();
-
- // the rest of this test is very dependent of the output generated
- // by HTMLLayout. Given that the XML parser already verifies
- // that the result conforms to xhtml-strict, we may want to
- // skip the assertions below. However, the assertions below are another
- // *independent* way to check the output format.
-
- // head, body
- assertEquals(2, rootElement.elements().size());
- Element bodyElement = (Element) rootElement.elements().get(1);
- Element tableElement = (Element) bodyElement.elements().get(3);
- assertEquals("table", tableElement.getName());
- Element trElement = (Element) tableElement.elements().get(1);
- {
- Element tdElement = (Element) trElement.elements().get(0);
- assertEquals("DEBUG", tdElement.getText());
- }
- {
- Element tdElement = (Element) trElement.elements().get(1);
- String regex = ClassicTestConstants.NAKED_MAIN_REGEX;
- System.out.println(tdElement.getText());
- assertTrue(tdElement.getText().matches(regex));
- }
- {
- Element tdElement = (Element) trElement.elements().get(2);
- assertEquals("test message", tdElement.getText());
- }
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void layoutWithException() throws Exception {
- layout.setPattern("%level %thread %msg %ex");
- LoggingEvent le = createLoggingEvent();
- le.setThrowableProxy(new ThrowableProxy(new Exception("test Exception")));
- String result = layout.doLayout(le);
-
- String stringToParse = layout.getFileHeader();
- stringToParse = stringToParse + layout.getPresentationHeader();
- stringToParse += result;
- stringToParse += "</table></body></html>";
-
- // System.out.println(stringToParse);
-
- Document doc = parseOutput(stringToParse);
- Element rootElement = doc.getRootElement();
- Element bodyElement = rootElement.element("body");
- Element tableElement = bodyElement.element("table");
- List<Element> trElementList = tableElement.elements();
- Element exceptionRowElement = trElementList.get(2);
- Element exceptionElement = exceptionRowElement.element("td");
-
- assertEquals(3, tableElement.elements().size());
- assertTrue(exceptionElement.getText().contains("java.lang.Exception: test Exception"));
- }
-
- @Test
- @Ignore
- public void rawLimit() throws Exception {
- StringBuilder sb = new StringBuilder();
- String header = layout.getFileHeader();
- assertTrue(header.startsWith("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"));
- sb.append(header);
- sb.append(layout.getPresentationHeader());
- for (int i = 0; i < CoreConstants.TABLE_ROW_LIMIT * 3; i++) {
- sb.append(layout.doLayout(new LoggingEvent(this.getClass().getName(), root, Level.DEBUG, "test message" + i, null, null)));
- }
- sb.append(layout.getPresentationFooter());
- sb.append(layout.getFileFooter());
- // check that the output adheres to xhtml-strict.dtd
- parseOutput(sb.toString());
- }
-
- private LoggingEvent createLoggingEvent() {
- return new LoggingEvent(this.getClass().getName(), root, Level.DEBUG, "test message", null, null);
+ LoggerContext lc;
+ Logger root;
+ HTMLLayout layout;
+
+ @Before
+ public void setUp() throws Exception {
+ lc = new LoggerContext();
+ lc.setName("default");
+
+ layout = new HTMLLayout();
+ layout.setThrowableRenderer(new DefaultThrowableRenderer());
+ layout.setContext(lc);
+ layout.setPattern("%level%thread%msg");
+ layout.start();
+
+ root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ lc = null;
+ layout = null;
+ }
+
+ @Test
+ public void testHeader() throws Exception {
+ String header = layout.getFileHeader();
+ // System.out.println(header);
+
+ Document doc = parseOutput(header + "</body></html>");
+ Element rootElement = doc.getRootElement();
+ assertNotNull(rootElement.element("body"));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testPresentationHeader() throws Exception {
+ String header = layout.getFileHeader();
+ String presentationHeader = layout.getPresentationHeader();
+ header = header + presentationHeader;
+ // System.out.println(header);
+
+ Document doc = parseOutput(header + "</table></body></html>");
+ Element rootElement = doc.getRootElement();
+ Element bodyElement = rootElement.element("body");
+ Element tableElement = bodyElement.element("table");
+ Element trElement = tableElement.element("tr");
+ List<Element> elementList = trElement.elements();
+ assertEquals("Level", elementList.get(0).getText());
+ assertEquals("Thread", elementList.get(1).getText());
+ assertEquals("Message", elementList.get(2).getText());
+ }
+
+ @Test
+ public void testAppendThrowable() throws Exception {
+ StringBuilder buf = new StringBuilder();
+ DummyThrowableProxy tp = new DummyThrowableProxy();
+ tp.setClassName("test1");
+ tp.setMessage("msg1");
+
+ StackTraceElement ste1 = new StackTraceElement("c1", "m1", "f1", 1);
+ StackTraceElement ste2 = new StackTraceElement("c2", "m2", "f2", 2);
+
+ StackTraceElementProxy[] stepArray = { new StackTraceElementProxy(ste1),
+ new StackTraceElementProxy(ste2) };
+ tp.setStackTraceElementProxyArray(stepArray);
+ DefaultThrowableRenderer renderer = (DefaultThrowableRenderer) layout
+ .getThrowableRenderer();
+
+ renderer.render(buf, tp);
+ System.out.println(buf.toString());
+ String[] result = buf.toString().split(CoreConstants.LINE_SEPARATOR);
+ System.out.println(result[0]);
+ assertEquals("test1: msg1", result[0]);
+ assertEquals(DefaultThrowableRenderer.TRACE_PREFIX + "at c1.m1(f1:1)", result[1]);
+ }
+
+ @Test
+ public void testDoLayout() throws Exception {
+ ILoggingEvent le = createLoggingEvent();
+
+ String result = layout.getFileHeader();
+ result += layout.getPresentationHeader();
+ result += layout.doLayout(le);
+ result += layout.getPresentationFooter();
+ result += layout.getFileFooter();
+
+ Document doc = parseOutput(result);
+ Element rootElement = doc.getRootElement();
+ rootElement.toString();
+
+ // the rest of this test is very dependent of the output generated
+ // by HTMLLayout. Given that the XML parser already verifies
+ // that the result conforms to xhtml-strict, we may want to
+ // skip the assertions below. However, the assertions below are another
+ // *independent* way to check the output format.
+
+ // head, body
+ assertEquals(2, rootElement.elements().size());
+ Element bodyElement = (Element) rootElement.elements().get(1);
+ Element tableElement = (Element) bodyElement.elements().get(3);
+ assertEquals("table", tableElement.getName());
+ Element trElement = (Element) tableElement.elements().get(1);
+ {
+ Element tdElement = (Element) trElement.elements().get(0);
+ assertEquals("DEBUG", tdElement.getText());
}
-
- Document parseOutput(String output) throws Exception {
- EntityResolver resolver = new XHTMLEntityResolver();
- SAXReader reader = new SAXReader();
- reader.setValidation(true);
- reader.setEntityResolver(resolver);
- return reader.read(new ByteArrayInputStream(output.getBytes()));
+ {
+ Element tdElement = (Element) trElement.elements().get(1);
+ String regex = ClassicTestConstants.NAKED_MAIN_REGEX;
+ System.out.println(tdElement.getText());
+ assertTrue(tdElement.getText().matches(regex));
}
-
- void configure(String file) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(lc);
- jc.doConfigure(file);
+ {
+ Element tdElement = (Element) trElement.elements().get(2);
+ assertEquals("test message", tdElement.getText());
}
-
- @Test
- public void testConversionRuleSupportInHtmlLayout() throws JoranException {
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "conversionRule/htmlLayout0.xml");
-
- root.getAppender("LIST");
- String msg = "Simon says";
- root.debug(msg);
- StringListAppender<ILoggingEvent> sla = (StringListAppender<ILoggingEvent>) root.getAppender("LIST");
- assertNotNull(sla);
- StatusPrinter.print(lc);
- assertEquals(1, sla.strList.size());
- assertFalse(sla.strList.get(0).contains("PARSER_ERROR"));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void layoutWithException() throws Exception {
+ layout.setPattern("%level %thread %msg %ex");
+ LoggingEvent le = createLoggingEvent();
+ le.setThrowableProxy(new ThrowableProxy(new Exception("test Exception")));
+ String result = layout.doLayout(le);
+
+ String stringToParse = layout.getFileHeader();
+ stringToParse = stringToParse + layout.getPresentationHeader();
+ stringToParse += result;
+ stringToParse += "</table></body></html>";
+
+ // System.out.println(stringToParse);
+
+ Document doc = parseOutput(stringToParse);
+ Element rootElement = doc.getRootElement();
+ Element bodyElement = rootElement.element("body");
+ Element tableElement = bodyElement.element("table");
+ List<Element> trElementList = tableElement.elements();
+ Element exceptionRowElement = trElementList.get(2);
+ Element exceptionElement = exceptionRowElement.element("td");
+
+ assertEquals(3, tableElement.elements().size());
+ assertTrue(exceptionElement.getText().contains(
+ "java.lang.Exception: test Exception"));
+ }
+
+ @Test
+ @Ignore
+ public void rawLimit() throws Exception {
+ StringBuilder sb = new StringBuilder();
+ String header = layout.getFileHeader();
+ assertTrue(header
+ .startsWith("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"));
+ sb.append(header);
+ sb.append(layout.getPresentationHeader());
+ for (int i = 0; i < CoreConstants.TABLE_ROW_LIMIT * 3; i++) {
+ sb.append(layout.doLayout(new LoggingEvent(this.getClass().getName(),
+ root, Level.DEBUG, "test message" + i, null, null)));
}
+ sb.append(layout.getPresentationFooter());
+ sb.append(layout.getFileFooter());
+ // check that the output adheres to xhtml-strict.dtd
+ parseOutput(sb.toString());
+ }
+
+ private LoggingEvent createLoggingEvent() {
+ return new LoggingEvent(this.getClass().getName(), root,
+ Level.DEBUG, "test message", null, null);
+ }
+
+ Document parseOutput(String output) throws Exception {
+ EntityResolver resolver = new XHTMLEntityResolver();
+ SAXReader reader = new SAXReader();
+ reader.setValidation(true);
+ reader.setEntityResolver(resolver);
+ return reader.read(new ByteArrayInputStream(output.getBytes()));
+ }
+
+ void configure(String file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(lc);
+ jc.doConfigure(file);
+ }
+
+ @Test
+ public void testConversionRuleSupportInHtmlLayout() throws JoranException {
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "conversionRule/htmlLayout0.xml");
+
+ root.getAppender("LIST");
+ String msg = "Simon says";
+ root.debug(msg);
+ StringListAppender<ILoggingEvent> sla = (StringListAppender<ILoggingEvent>) root
+ .getAppender("LIST");
+ assertNotNull(sla);
+ StatusPrinter.print(lc);
+ assertEquals(1, sla.strList.size());
+ assertFalse(sla.strList.get(0).contains("PARSER_ERROR"));
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/html/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/html/PackageTest.java
index 8600a27..781be1d 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/html/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/html/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/html/XHTMLEntityResolver.java b/logback-classic/src/test/java/ch/qos/logback/classic/html/XHTMLEntityResolver.java
index c5cc9bc..c13fa99 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/html/XHTMLEntityResolver.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/html/XHTMLEntityResolver.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,30 +22,35 @@ import org.xml.sax.InputSource;
public class XHTMLEntityResolver implements EntityResolver {
- // key: public id, value: relative path to DTD file
- static Map<String, String> entityMap = new HashMap<String, String>();
+ // key: public id, value: relative path to DTD file
+ static Map<String, String> entityMap = new HashMap<String, String>();
- static {
- entityMap.put("-//W3C//DTD XHTML 1.0 Strict//EN", "/dtd/xhtml1-strict.dtd");
- entityMap.put("-//W3C//ENTITIES Latin 1 for XHTML//EN", "/dtd/xhtml-lat1.ent");
- entityMap.put("-//W3C//ENTITIES Symbols for XHTML//EN", "/dtd/xhtml-symbol.ent");
- entityMap.put("-//W3C//ENTITIES Special for XHTML//EN", "/dtd/xhtml-special.ent");
- }
+ static {
+ entityMap.put("-//W3C//DTD XHTML 1.0 Strict//EN",
+ "/dtd/xhtml1-strict.dtd");
+ entityMap.put("-//W3C//ENTITIES Latin 1 for XHTML//EN",
+ "/dtd/xhtml-lat1.ent");
+ entityMap.put("-//W3C//ENTITIES Symbols for XHTML//EN",
+ "/dtd/xhtml-symbol.ent");
+ entityMap.put("-//W3C//ENTITIES Special for XHTML//EN",
+ "/dtd/xhtml-special.ent");
+ }
- public InputSource resolveEntity(String publicId, String systemId) {
- // System.out.println(publicId);
- final String relativePath = (String) entityMap.get(publicId);
+ public InputSource resolveEntity(String publicId, String systemId) {
+ //System.out.println(publicId);
+ final String relativePath = (String)entityMap.get(publicId);
- if (relativePath != null) {
- Class clazz = getClass();
- InputStream in = clazz.getResourceAsStream(relativePath);
- if (in == null) {
- return null;
- } else {
- return new InputSource(in);
- }
- } else {
- return null;
- }
+ if (relativePath != null) {
+ Class clazz = getClass();
+ InputStream in =
+ clazz.getResourceAsStream(relativePath);
+ if (in == null) {
+ return null;
+ } else {
+ return new InputSource(in);
+ }
+ } else {
+ return null;
}
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/DarioCampagna/Main.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/DarioCampagna/Main.java
index c9ca60a..a8144d3 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/DarioCampagna/Main.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/DarioCampagna/Main.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,18 +27,18 @@ import org.slf4j.cal10n.LocLoggerFactory;
import java.util.Locale;
public class Main {
- public static void main(String[] args) throws JoranException {
+ public static void main(String[] args) throws JoranException {
- LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
- context.reset();
- JoranConfigurator joranConfigurator = new JoranConfigurator();
- joranConfigurator.setContext(context);
- joranConfigurator.doConfigure("src/test/java/ch/qos/logback/classic/issue/DarioCampagna/logback-marker.xml");
- IMessageConveyor mc = new MessageConveyor(Locale.getDefault());
- LocLoggerFactory llFactory_default = new LocLoggerFactory(mc);
- LocLogger locLogger = llFactory_default.getLocLogger("defaultLocLogger");
- Marker alwaysMarker = MarkerFactory.getMarker("ALWAYS");
- locLogger.info(alwaysMarker, "This will always appear.");
- locLogger.info("Hello!");
- }
+ LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+ context.reset();
+ JoranConfigurator joranConfigurator = new JoranConfigurator();
+ joranConfigurator.setContext(context);
+ joranConfigurator.doConfigure("src/test/java/ch/qos/logback/classic/issue/DarioCampagna/logback-marker.xml");
+ IMessageConveyor mc = new MessageConveyor(Locale.getDefault());
+ LocLoggerFactory llFactory_default = new LocLoggerFactory(mc);
+ LocLogger locLogger = llFactory_default.getLocLogger("defaultLocLogger");
+ Marker alwaysMarker = MarkerFactory.getMarker("ALWAYS");
+ locLogger.info(alwaysMarker, "This will always appear.");
+ locLogger.info("Hello!");
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/LBCORE63.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/LBCORE63.java
index b73a45b..79bf97a 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/LBCORE63.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/LBCORE63.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,75 +26,75 @@ import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.util.StatusPrinter;
public class LBCORE63 extends Thread {
- private final static String LOGGER_CONFIGURATION_FILE = "./src/test/input/issue/lbcore63.xml";
- private final Logger logger = LoggerFactory.getLogger(LBCORE63.class);
+ private final static String LOGGER_CONFIGURATION_FILE = "./src/test/input/issue/lbcore63.xml";
+ private final Logger logger = LoggerFactory.getLogger(LBCORE63.class);
- private final long start;
+ private final long start;
- public LBCORE63() throws JoranException {
- start = new Date().getTime();
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator configurator = new JoranConfigurator();
- lc.reset();
- configurator.setContext(lc);
- configurator.doConfigure(LOGGER_CONFIGURATION_FILE);
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
- }
+ public LBCORE63() throws JoranException {
+ start = new Date().getTime();
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ JoranConfigurator configurator = new JoranConfigurator();
+ lc.reset();
+ configurator.setContext(lc);
+ configurator.doConfigure(LOGGER_CONFIGURATION_FILE);
+ StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
+ }
- public void start() {
- ScheduledThreadPoolExecutor ex1 = new ScheduledThreadPoolExecutor(1);
- ScheduledThreadPoolExecutor ex2 = new ScheduledThreadPoolExecutor(1);
- ScheduledThreadPoolExecutor ex3 = new ScheduledThreadPoolExecutor(1);
- ScheduledThreadPoolExecutor ex4 = new ScheduledThreadPoolExecutor(1);
- ScheduledThreadPoolExecutor ex5 = new ScheduledThreadPoolExecutor(1);
- ex1.scheduleAtFixedRate(new Task("EX1"), 10, 10, TimeUnit.MICROSECONDS);
- ex2.scheduleAtFixedRate(new Task("EX2"), 10, 10, TimeUnit.MICROSECONDS);
- ex3.scheduleAtFixedRate(new Task("EX3"), 10, 10, TimeUnit.MICROSECONDS);
- ex4.scheduleAtFixedRate(new Task("EX4"), 10, 10, TimeUnit.MICROSECONDS);
- ex5.scheduleAtFixedRate(new Task("EX5"), 10, 10, TimeUnit.MICROSECONDS);
+ public void start() {
+ ScheduledThreadPoolExecutor ex1 = new ScheduledThreadPoolExecutor(1);
+ ScheduledThreadPoolExecutor ex2 = new ScheduledThreadPoolExecutor(1);
+ ScheduledThreadPoolExecutor ex3 = new ScheduledThreadPoolExecutor(1);
+ ScheduledThreadPoolExecutor ex4 = new ScheduledThreadPoolExecutor(1);
+ ScheduledThreadPoolExecutor ex5 = new ScheduledThreadPoolExecutor(1);
+ ex1.scheduleAtFixedRate(new Task("EX1"), 10, 10, TimeUnit.MICROSECONDS);
+ ex2.scheduleAtFixedRate(new Task("EX2"), 10, 10, TimeUnit.MICROSECONDS);
+ ex3.scheduleAtFixedRate(new Task("EX3"), 10, 10, TimeUnit.MICROSECONDS);
+ ex4.scheduleAtFixedRate(new Task("EX4"), 10, 10, TimeUnit.MICROSECONDS);
+ ex5.scheduleAtFixedRate(new Task("EX5"), 10, 10, TimeUnit.MICROSECONDS);
- super.start();
- }
+ super.start();
+ }
- public void run() {
- try {
- while (true) {
- logger.debug("[MAIN] {}", new Date().getTime() - start);
- Thread.sleep(10);
- }
- } catch (InterruptedException e) {
- logger.info("[MAIN]: Interrupted: {}", e.getMessage());
- }
+ public void run() {
+ try {
+ while (true) {
+ logger.debug("[MAIN] {}", new Date().getTime() - start);
+ Thread.sleep(10);
+ }
+ } catch (InterruptedException e) {
+ logger.info("[MAIN]: Interrupted: {}", e.getMessage());
}
+ }
- public static void main(String[] args) {
- try {
- LBCORE63 main = new LBCORE63();
- main.start();
- } catch (JoranException e) {
- System.out.println("Failed to load application: " + e.getMessage());
- }
+ public static void main(String[] args) {
+ try {
+ LBCORE63 main = new LBCORE63();
+ main.start();
+ } catch (JoranException e) {
+ System.out.println("Failed to load application: " + e.getMessage());
}
+ }
- class Task implements Runnable {
- private final Logger logger = LoggerFactory.getLogger(Task.class);
- // private final Logger logger_main = LoggerFactory.getLogger(LBCORE63.class);
- final String name;
- private final long start;
-
- int counter = 0;
- public long diff;
+ class Task implements Runnable {
+ private final Logger logger = LoggerFactory.getLogger(Task.class);
+ //private final Logger logger_main = LoggerFactory.getLogger(LBCORE63.class);
+ final String name;
+ private final long start;
- public Task(final String name) {
- this.name = name;
- start = new Date().getTime();
- }
+ int counter = 0;
+ public long diff;
+
+ public Task(final String name) {
+ this.name = name;
+ start = new Date().getTime();
+ }
- public void run() {
- counter++;
- diff = new Date().getTime() - start;
- logger.debug("counter={}", counter);
- // logger_main.debug("[MAIN] - [{}] {}", name, new Date().getTime() - start);
- }
+ public void run() {
+ counter++;
+ diff = new Date().getTime() - start;
+ logger.debug("counter={}", counter);
+ //logger_main.debug("[MAIN] - [{}] {}", name, new Date().getTime() - start);
}
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/PackageTest.java
index 43f0b22..ee7eda2 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,6 +20,8 @@ import org.junit.runners.Suite.SuiteClasses;
import ch.qos.logback.classic.issue.lbclassic135.lbclassic139.LB139_DeadlockTest;
@RunWith(Suite.class)
- at SuiteClasses({ LB139_DeadlockTest.class, ch.qos.logback.classic.issue.logback416.PackageTest.class })
+ at SuiteClasses({LB139_DeadlockTest.class,
+ ch.qos.logback.classic.issue.lbclassic135.lbclassic139.PackageTest.class,
+ ch.qos.logback.classic.issue.lbclassic203.PackageTest.class})
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/LoggingRunnable.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/LoggingRunnable.java
index c381e7b..9a06e81 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/LoggingRunnable.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/LoggingRunnable.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,31 +18,32 @@ import ch.qos.logback.core.contention.RunnableWithCounterAndDone;
public class LoggingRunnable extends RunnableWithCounterAndDone {
- final Logger logger;
- final int burstLength;
+ final Logger logger;
+ final int burstLength;
- public LoggingRunnable(Logger logger, int burstLength) {
- this.logger = logger;
- this.burstLength = burstLength;
- }
- public LoggingRunnable(Logger logger) {
- this(logger, 10);
- }
+ public LoggingRunnable(Logger logger, int burstLength) {
+ this.logger = logger;
+ this.burstLength = burstLength;
+ }
+
+ public LoggingRunnable(Logger logger) {
+ this(logger, 100);
+ }
- public void run() {
- while (!isDone()) {
- logger.info("hello world ABCDEFGHI");
- counter++;
- // don't hog the CPU forever
- if (counter % burstLength == 0) {
- try {
- Thread.sleep(1);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
+ public void run() {
+ while (!isDone()) {
+ logger.info("hello world ABCDEFGHI");
+ counter++;
+ // don't hog the CPU forever
+ if (counter % burstLength == 0) {
+ try {
+ Thread.sleep(1);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
}
+ }
}
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/LoggingToFileThroughput.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/LoggingToFileThroughput.java
index ba2bc32..8098783 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/LoggingToFileThroughput.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/LoggingToFileThroughput.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,89 +27,90 @@ import ch.qos.logback.core.contention.ThreadedThroughputCalculator;
*/
public class LoggingToFileThroughput {
- static int THREAD_COUNT = 1;
- static long OVERALL_DURATION_IN_MILLIS = 5000;
+ static int THREAD_COUNT = 1;
+ static long OVERALL_DURATION_IN_MILLIS = 5000;
- public static void main(String args[]) throws InterruptedException {
+ public static void main(String args[]) throws InterruptedException {
- ThreadedThroughputCalculator tp = new ThreadedThroughputCalculator(OVERALL_DURATION_IN_MILLIS);
- tp.printEnvironmentInfo("lbclassic135 LoggingToFileThrouhput");
+ ThreadedThroughputCalculator tp = new ThreadedThroughputCalculator(
+ OVERALL_DURATION_IN_MILLIS);
+ tp.printEnvironmentInfo("lbclassic135 LoggingToFileThrouhput");
- LoggerContext lc = new LoggerContext();
- Logger logger = buildLoggerContext(lc);
-
- for (int i = 0; i < 2; i++) {
- tp.execute(buildArray(logger));
- }
-
- tp.execute(buildArray(logger));
- tp.printThroughput("File: ");
- lc.stop();
+ LoggerContext lc = new LoggerContext();
+ Logger logger = buildLoggerContext(lc);
+
+ for (int i = 0; i < 2; i++) {
+ tp.execute(buildArray(logger));
}
- static Logger buildLoggerContext(LoggerContext lc) {
- Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
-
- PatternLayoutEncoder patternLayout = new PatternLayoutEncoder();
- patternLayout.setContext(lc);
- patternLayout.setPattern("%d %l [%t] - %msg%n");
- patternLayout.start();
- FileAppender<ILoggingEvent> fileAppender = new FileAppender<ILoggingEvent>();
- fileAppender.setContext(lc);
- fileAppender.setFile("target/lbclassic135.log");
- fileAppender.setEncoder(patternLayout);
- fileAppender.setAppend(false);
- fileAppender.start();
- root.addAppender(fileAppender);
- return lc.getLogger(LoggingToFileThroughput.class);
- }
-
- static LoggingRunnable[] buildArray(Logger logger) {
-
- LoggingRunnable[] array = new LoggingRunnable[THREAD_COUNT];
- for (int i = 0; i < THREAD_COUNT; i++) {
- array[i] = new LoggingRunnable(logger);
- }
- return array;
+ tp.execute(buildArray(logger));
+ tp.printThroughput("File: ");
+ lc.stop();
+ }
+
+ static Logger buildLoggerContext(LoggerContext lc) {
+ Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+
+ PatternLayoutEncoder patternLayout = new PatternLayoutEncoder();
+ patternLayout.setContext(lc);
+ patternLayout.setPattern("%d %l [%t] - %msg%n");
+ patternLayout.start();
+ FileAppender<ILoggingEvent> fileAppender = new FileAppender<ILoggingEvent>();
+ fileAppender.setContext(lc);
+ fileAppender.setFile("target/lbclassic135.log");
+ fileAppender.setEncoder(patternLayout);
+ fileAppender.setAppend(false);
+ fileAppender.start();
+ root.addAppender(fileAppender);
+ return lc.getLogger(LoggingToFileThroughput.class);
+ }
+
+ static LoggingRunnable[] buildArray(Logger logger) {
+
+ LoggingRunnable[] array = new LoggingRunnable[THREAD_COUNT];
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ array[i] = new LoggingRunnable(logger);
}
+ return array;
+ }
}
-// === lbclassic135 LoggingToFileThrouhput ===
+//=== lbclassic135 LoggingToFileThrouhput ===
// ******** 10 Threads *****
// synchronized doAppend() method
//
// java.runtime.version = 1.6.0_05-b13
-// java.vendor = Sun Microsystems Inc.
-// os.name = Windows XP
+// java.vendor = Sun Microsystems Inc.
+// os.name = Windows XP
//
-// Threads 1: total of 485077 operations, or 97 operations per millisecond
-// Threads 10: total of 309402 operations, or 61 operations per millisecond
+// Threads 1: total of 485077 operations, or 97 operations per millisecond
+// Threads 10: total of 309402 operations, or 61 operations per millisecond
-// * After revision 2310
-// * Threads 1: total of 462465 operations, or 92 operations per millisecond
-// * Threads 10: total of 243362 operations, or 48 operations per millisecond
+//* After revision 2310
+//* Threads 1: total of 462465 operations, or 92 operations per millisecond
+//* Threads 10: total of 243362 operations, or 48 operations per millisecond
-// ==================== Linux ========================
+// ==================== Linux ========================
// java.runtime.version = 1.6.0_11-b03
-// java.vendor = Sun Microsystems Inc.
-// os.name = Linux
-// os.version = 2.6.25-gentoo-r6
-// Threads 1: total of 356355 operations, or 71 operations per millisecond
+// java.vendor = Sun Microsystems Inc.
+// os.name = Linux
+// os.version = 2.6.25-gentoo-r6
+// Threads 1: total of 356355 operations, or 71 operations per millisecond
// Threads 10: total of 287943 operations, or 57 operations per millisecond
-// * After revision 2310
-// * Threads 1: total of 331494 operations, or 66 operations per millisecond
-// * Threads 10: total of 311104 operations, or 58 operations per millisecond
+//* After revision 2310
+//* Threads 1: total of 331494 operations, or 66 operations per millisecond
+//* Threads 10: total of 311104 operations, or 58 operations per millisecond
// java.runtime.version = jvmxa6460-20081105_25433
-// java.vendor = IBM Corporation
-// java.version = 1.6.0
-// os.name = Linux
-// os.version = 2.6.25-gentoo-r6
-// Threads 1: total of 280381 operations, or 56 operations per millisecond
-// Threads 10 total of 142989 operations, or 28 operations per millisecond
-
-// * After revision 2310
-// * Threads 1: total of 305638 operations, or 61 operations per millisecond
-// * Threads 10: total of 147660 operations, or 29 operations per millisecond
\ No newline at end of file
+// java.vendor = IBM Corporation
+// java.version = 1.6.0
+// os.name = Linux
+// os.version = 2.6.25-gentoo-r6
+// Threads 1: total of 280381 operations, or 56 operations per millisecond
+// Threads 10 total of 142989 operations, or 28 operations per millisecond
+
+//* After revision 2310
+//* Threads 1: total of 305638 operations, or 61 operations per millisecond
+//* Threads 10: total of 147660 operations, or 29 operations per millisecond
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/lbclassic139/Accessor.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/lbclassic139/Accessor.java
index 0e0d656..cff1c06 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/lbclassic139/Accessor.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/lbclassic139/Accessor.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,27 +24,28 @@ import ch.qos.logback.core.contention.RunnableWithCounterAndDone;
*
*/
public class Accessor extends RunnableWithCounterAndDone {
- private Logger logger;
- final Worker worker;
- final LoggerContext loggerContext;
+ private Logger logger;
+ final Worker worker;
+ final LoggerContext loggerContext;
- Accessor(Worker worker, LoggerContext lc) {
- this.worker = worker;
- this.loggerContext = lc;
- logger = lc.getLogger(this.getClass());
- }
-
- public void run() {
- print("entered run()");
- // Thread.yield();
- while (!isDone()) {
- logger.info("Current worker status is: {}.", worker);
- }
- print("leaving run()");
- }
+
+ Accessor(Worker worker, LoggerContext lc) {
+ this.worker = worker;
+ this.loggerContext = lc;
+ logger = lc.getLogger(this.getClass());
+ }
- void print(String msg) {
- String thread = Thread.currentThread().getName();
- System.out.println("[" + thread + "] " + msg);
+ public void run() {
+ print("entered run()");
+ //Thread.yield();
+ while (!isDone()) {
+ logger.info("Current worker status is: {}.", worker);
}
+ print("leaving run()");
+ }
+
+ void print(String msg) {
+ String thread = Thread.currentThread().getName();
+ System.out.println("["+thread+"] "+msg);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/lbclassic139/LB139_DeadlockTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/lbclassic139/LB139_DeadlockTest.java
index 3efbccc..b4fed8a 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/lbclassic139/LB139_DeadlockTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/lbclassic139/LB139_DeadlockTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,37 +21,34 @@ import ch.qos.logback.classic.LoggerContext;
public class LB139_DeadlockTest {
- LoggerContext loggerContext = new LoggerContext();
-
- @Before
- public void setUp() {
- loggerContext.setName("LB139");
- BasicConfigurator bc = new BasicConfigurator();
- bc.setContext(loggerContext);
- bc.configure(loggerContext);
- }
-
- @Test
- // (timeout=3000)
- public void test() throws Exception {
- Worker worker = new Worker(loggerContext);
- Accessor accessor = new Accessor(worker, loggerContext);
-
- Thread workerThread = new Thread(worker, "WorkerThread");
- Thread accessorThread = new Thread(accessor, "AccessorThread");
-
- workerThread.start();
- accessorThread.start();
-
- int sleep = Worker.SLEEP_DUIRATION * 10;
-
- System.out.println("Will sleep for " + sleep + " millis");
- Thread.sleep(sleep);
- System.out.println("Done sleeping (" + sleep + " millis)");
- worker.setDone(true);
- accessor.setDone(true);
-
- workerThread.join();
- accessorThread.join();
- }
+ LoggerContext loggerContext = new LoggerContext();
+
+ @Before
+ public void setUp() {
+ loggerContext.setName("LB139");
+ BasicConfigurator.configure(loggerContext);
+ }
+
+ @Test //(timeout=3000)
+ public void test() throws Exception {
+ Worker worker = new Worker(loggerContext);
+ Accessor accessor = new Accessor(worker, loggerContext);
+
+ Thread workerThread = new Thread(worker, "WorkerThread");
+ Thread accessorThread = new Thread(accessor, "AccessorThread");
+
+ workerThread.start();
+ accessorThread.start();
+
+ int sleep = Worker.SLEEP_DUIRATION*10;
+
+ System.out.println("Will sleep for "+sleep+" millis");
+ Thread.sleep(sleep);
+ System.out.println("Done sleeping ("+sleep+" millis)");
+ worker.setDone(true);
+ accessor.setDone(true);
+
+ workerThread.join();
+ accessorThread.join();
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/lbclassic139/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/lbclassic139/PackageTest.java
new file mode 100644
index 0000000..c59cee7
--- /dev/null
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/lbclassic139/PackageTest.java
@@ -0,0 +1,23 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.issue.lbclassic135.lbclassic139;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+ at RunWith(Suite.class)
+ at SuiteClasses(LB139_DeadlockTest.class)
+public class PackageTest {
+}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/lbclassic139/Worker.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/lbclassic139/Worker.java
index 5fbb648..73ceca6 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/lbclassic139/Worker.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/lbclassic139/Worker.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,51 +26,50 @@ import ch.qos.logback.core.contention.RunnableWithCounterAndDone;
*
*/
public class Worker extends RunnableWithCounterAndDone {
- static final int SLEEP_DUIRATION = 50;
+ static final int SLEEP_DUIRATION = 50;
+
+ private Logger logger;
+ private final Vector lock = new Vector();
- private Logger logger;
- private final Vector lock = new Vector();
-
- final LoggerContext loggerContext;
-
- Worker(LoggerContext lc) {
- loggerContext = lc;
- logger = lc.getLogger(this.getClass());
- }
-
- public void run() {
- print("entered run()");
- while (!isDone()) {
- synchronized (lock) {
- sleep();
- logger.info("lock the logger");
- }
- }
- print("leaving run()");
+ final LoggerContext loggerContext;
+ Worker(LoggerContext lc) {
+ loggerContext = lc;
+ logger = lc.getLogger(this.getClass());
+ }
+
+ public void run() {
+ print("entered run()");
+ while (!isDone()) {
+ synchronized (lock) {
+ sleep();
+ logger.info("lock the logger");
+ }
}
+ print("leaving run()");
+ }
- @Override
- public String toString() {
- print("In Worker.toString() - about to access lock");
- synchronized (lock) {
- print("In Worker.toString() - got the lock");
- // sleep();
- return "STATUS";
- }
+ @Override
+ public String toString() {
+ print("In Worker.toString() - about to access lock");
+ synchronized (lock) {
+ print("In Worker.toString() - got the lock");
+ //sleep();
+ return "STATUS";
}
-
- public void sleep() {
- try {
- print("About to go to sleep");
- Thread.sleep(SLEEP_DUIRATION);
- print("just woke up");
- } catch (InterruptedException exc) {
- exc.printStackTrace();
- }
- }
-
- void print(String msg) {
- String thread = Thread.currentThread().getName();
- System.out.println("[" + thread + "] " + msg);
+ }
+
+ public void sleep() {
+ try {
+ print("About to go to sleep");
+ Thread.sleep(SLEEP_DUIRATION);
+ print("just woke up");
+ } catch (InterruptedException exc) {
+ exc.printStackTrace();
}
+ }
+
+ void print(String msg) {
+ String thread = Thread.currentThread().getName();
+ System.out.println("["+thread+"] "+msg);
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic180/HtmlEscapedMessageConverter.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic180/HtmlEscapedMessageConverter.java
index d654f7b..71de33e 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic180/HtmlEscapedMessageConverter.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic180/HtmlEscapedMessageConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,7 +19,7 @@ import ch.qos.logback.core.helpers.Transform;
public class HtmlEscapedMessageConverter extends ClassicConverter {
- public String convert(ILoggingEvent event) {
- return Transform.escapeTags(event.getFormattedMessage());
- }
+ public String convert(ILoggingEvent event) {
+ return Transform.escapeTags(event.getFormattedMessage());
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic180/Main.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic180/Main.java
index b0c9c40..9186464 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic180/Main.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic180/Main.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,21 +19,23 @@ import ch.qos.logback.core.joran.spi.JoranException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
public class Main {
- static Logger logger = LoggerFactory.getLogger(Main.class);
- static String DIR_PREFIX = "src/test/java/ch/qos/logback/classic/issue/lbclassic180/";
+ static Logger logger = LoggerFactory.getLogger(Main.class);
+ static String DIR_PREFIX = "src/test/java/ch/qos/logback/classic/issue/lbclassic180/";
+
+ public static void main(String[] args) throws JoranException, InterruptedException {
+ init(DIR_PREFIX + "logback.xml");
+ logger.debug("<p>hello</p>");
+ }
- public static void main(String[] args) throws JoranException, InterruptedException {
- init(DIR_PREFIX + "logback.xml");
- logger.debug("<p>hello</p>");
- }
- static void init(String file) throws JoranException {
- LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(loggerContext);
- loggerContext.reset();
- jc.doConfigure(file);
- }
+ static void init(String file) throws JoranException {
+ LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ loggerContext.reset();
+ jc.doConfigure(file);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic203/ConcurrentSiftingTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic203/ConcurrentSiftingTest.java
new file mode 100644
index 0000000..476d13f
--- /dev/null
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic203/ConcurrentSiftingTest.java
@@ -0,0 +1,61 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.issue.lbclassic203;
+
+import ch.qos.logback.classic.ClassicTestConstants;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.issue.lbclassic135.LoggingRunnable;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.core.contention.MultiThreadedHarness;
+import ch.qos.logback.core.contention.RunnableWithCounterAndDone;
+import ch.qos.logback.core.joran.spi.JoranException;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ConcurrentSiftingTest {
+ final static int THREAD_COUNT = 5;
+ static String FOLDER_PREFIX = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "sift/";
+
+ LoggerContext loggerContext = new LoggerContext();
+ protected Logger logger = loggerContext.getLogger(this.getClass().getName());
+ protected Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
+
+ int totalTestDuration = 50;
+ MultiThreadedHarness harness = new MultiThreadedHarness(totalTestDuration);
+ RunnableWithCounterAndDone[] runnableArray = buildRunnableArray();
+
+ protected void configure(String file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ jc.doConfigure(file);
+ }
+
+ RunnableWithCounterAndDone[] buildRunnableArray() {
+ RunnableWithCounterAndDone[] rArray = new RunnableWithCounterAndDone[THREAD_COUNT];
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ rArray[i] = new LoggingRunnable(logger);
+ }
+ return rArray;
+ }
+
+ @Test
+ public void concurrentAccess() throws JoranException, InterruptedException {
+ configure(FOLDER_PREFIX + "lbclassic203.xml");
+ harness.execute(runnableArray);
+ assertEquals(1, InstanceCountingAppender.INSTANCE_COUNT);
+ }
+}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic203/InstanceCountingAppender.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic203/InstanceCountingAppender.java
new file mode 100644
index 0000000..052df56
--- /dev/null
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic203/InstanceCountingAppender.java
@@ -0,0 +1,30 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.issue.lbclassic203;
+
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.AppenderBase;
+
+public class InstanceCountingAppender extends AppenderBase<ILoggingEvent> {
+
+ static public volatile int INSTANCE_COUNT = 0;
+
+ public InstanceCountingAppender() {
+ INSTANCE_COUNT++;
+ }
+
+ protected void append(ILoggingEvent e) {
+ }
+
+}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic203/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic203/PackageTest.java
new file mode 100644
index 0000000..99b514a
--- /dev/null
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic203/PackageTest.java
@@ -0,0 +1,23 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.issue.lbclassic203;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+ at RunWith(Suite.class)
+ at SuiteClasses(ConcurrentSiftingTest.class)
+public class PackageTest {
+}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic323/Barebones.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic323/Barebones.java
index d9b27b7..c718b5b 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic323/Barebones.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic323/Barebones.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,29 +18,28 @@ import ch.qos.logback.core.ContextBase;
public class Barebones {
- public static void main(String[] args) {
- Context context = new ContextBase();
- for (int i = 0; i < 3; i++) {
- SenderRunnable senderRunnable = new SenderRunnable("" + i);
- context.getExecutorService().execute(senderRunnable);
- }
- System.out.println("done");
- // System.exit(0);
+ public static void main(String[] args) {
+ Context context = new ContextBase();
+ for(int i = 0; i < 3; i++) {
+ SenderRunnable senderRunnable = new SenderRunnable(""+i);
+ context.getExecutorService().execute(senderRunnable);
}
+ System.out.println("done");
+ //System.exit(0);
+ }
- static class SenderRunnable implements Runnable {
- String id;
-
- SenderRunnable(String id) {
- this.id = id;
- }
+ static class SenderRunnable implements Runnable {
+ String id;
+ SenderRunnable(String id) {
+ this.id = id;
+ }
- public void run() {
- try {
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- }
- System.out.println("SenderRunnable " + id);
- }
+ public void run() {
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ }
+ System.out.println("SenderRunnable " +id);
}
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic323/Simple.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic323/Simple.java
index 69070fa..6e51e41 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic323/Simple.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic323/Simple.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,26 +23,27 @@ import org.slf4j.LoggerFactory;
*/
public class Simple {
- static Logger logger = LoggerFactory.getLogger(Simple.class);
- static String DIR_PREFIX = "src/test/java/ch/qos/logback/classic/issue/lbclassic323/";
+ static Logger logger = LoggerFactory.getLogger(Simple.class);
+ static String DIR_PREFIX = "src/test/java/ch/qos/logback/classic/issue/lbclassic323/";
- public static void main(String[] args) throws JoranException, InterruptedException {
- init(DIR_PREFIX + "logback_smtp.xml");
+ public static void main(String[] args) throws JoranException, InterruptedException {
+ init(DIR_PREFIX + "logback_smtp.xml");
- for (int i = 0; i < 10; i++) {
- logger.debug("SEE IF THIS IS LOGGED {}.", i);
- }
- logger.error("trigger");
- System.out.println("done");
- System.exit(0);
+ for (int i = 0; i < 10; i++) {
+ logger.debug("SEE IF THIS IS LOGGED {}.", i);
}
+ logger.error("trigger");
+ System.out.println("done");
+ System.exit(0);
+ }
- static void init(String file) throws JoranException {
- LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(loggerContext);
- loggerContext.reset();
- jc.doConfigure(file);
- }
+
+ static void init(String file) throws JoranException {
+ LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ loggerContext.reset();
+ jc.doConfigure(file);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic330/Main.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic330/Main.java
index aea2f70..f881963 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic330/Main.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic330/Main.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,21 +19,23 @@ import ch.qos.logback.core.joran.spi.JoranException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
public class Main {
- static Logger logger = LoggerFactory.getLogger(Main.class);
- static String DIR_PREFIX = "src/test/java/ch/qos/logback/classic/issue/lbclassic330/";
+ static Logger logger = LoggerFactory.getLogger(Main.class);
+ static String DIR_PREFIX = "src/test/java/ch/qos/logback/classic/issue/lbclassic330/";
+
+ public static void main(String[] args) throws JoranException, InterruptedException {
+ init(DIR_PREFIX + "logback.xml");
+ logger.debug("hello");
+ }
- public static void main(String[] args) throws JoranException, InterruptedException {
- init(DIR_PREFIX + "logback.xml");
- logger.debug("hello");
- }
- static void init(String file) throws JoranException {
- LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(loggerContext);
- loggerContext.reset();
- jc.doConfigure(file);
- }
+ static void init(String file) throws JoranException {
+ LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ loggerContext.reset();
+ jc.doConfigure(file);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/DateFormatOriginal_tzest.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/DateFormatOriginal_tzest.java
index 85a7eb0..b129789 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/DateFormatOriginal_tzest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/DateFormatOriginal_tzest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,228 +25,228 @@ import java.util.Date;
//import org.joda.time.DateTime;
public class DateFormatOriginal_tzest extends TestCase {
- public static final String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS";
- static final long NANOS_IN_ONE_SEC = 1000 * 1000 * 1000L;
-
- /**
- * Create the test case
- *
- * @param testName
- * name of the test case
- */
- public DateFormatOriginal_tzest(String testName) {
- super(testName);
+ public static final String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS";
+ static final long NANOS_IN_ONE_SEC = 1000 * 1000 * 1000L;
+
+ /**
+ * Create the test case
+ *
+ * @param testName
+ * name of the test case
+ */
+ public DateFormatOriginal_tzest(String testName) {
+ super(testName);
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite() {
+ return new TestSuite(DateFormatOriginal_tzest.class);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+// public void testRaw() throws Exception {
+// SimpleDateFormat simpleFormat = new SimpleDateFormat(ISO8601_PATTERN);
+// DateTimeFormatter jodaFormat = DateTimeFormat.forPattern(ISO8601_PATTERN);
+//
+// Date date = new Date();
+// DateTime dateTime = new DateTime(date);
+//
+// long start = System.nanoTime();
+// for (int i = 0; i < 100000; ++i) {
+// jodaFormat.print(dateTime);
+// }
+// long jodaAvg = (System.nanoTime() - start) / 100000;
+//
+//
+// start = System.nanoTime();
+// for (int i = 0; i < 100000; ++i) {
+// simpleFormat.format(date);
+// }
+// long simpleAvg = (System.nanoTime() - start) / 100000;
+//
+// float diff = (((float) (simpleAvg - jodaAvg)) / simpleAvg) * 100;
+// System.out.println("Raw - JDK: " + simpleAvg + " ns Joda: " + jodaAvg
+// + " ns - Difference: " + diff + "%");
+// }
+
+ public void testSynchronized() throws Exception {
+ SynchronizedDateFormatter formatter = new SynchronizedDateFormatter();
+ int threads = 10;
+ int iterations = 10000;
+ Thread[] formatThreads = new Thread[threads];
+ Date date = new Date();
+
+ for (int i = 0; i < threads; i++) {
+ formatThreads[i] = new DateFormatThread(formatter, date, iterations);
}
-
- /**
- * @return the suite of tests being tested
- */
- public static Test suite() {
- return new TestSuite(DateFormatOriginal_tzest.class);
- }
-
- public static void main(String[] args) {
- junit.textui.TestRunner.run(suite());
+ long start = System.nanoTime();
+ for (Thread thread : formatThreads) {
+ thread.start();
}
-
- public void setUp() throws Exception {
- super.setUp();
+ for (Thread thread : formatThreads) {
+ thread.join();
}
+ long end = System.nanoTime();
+ double actual = ((double) (end - start)) / NANOS_IN_ONE_SEC;
+ System.out.printf("Synchronized DateFormat: %,.4f seconds\n", actual);
- public void tearDown() throws Exception {
- super.tearDown();
- }
+ }
- // public void testRaw() throws Exception {
- // SimpleDateFormat simpleFormat = new SimpleDateFormat(ISO8601_PATTERN);
- // DateTimeFormatter jodaFormat = DateTimeFormat.forPattern(ISO8601_PATTERN);
- //
- // Date date = new Date();
- // DateTime dateTime = new DateTime(date);
- //
- // long start = System.nanoTime();
- // for (int i = 0; i < 100000; ++i) {
- // jodaFormat.print(dateTime);
- // }
- // long jodaAvg = (System.nanoTime() - start) / 100000;
- //
- //
- // start = System.nanoTime();
- // for (int i = 0; i < 100000; ++i) {
- // simpleFormat.format(date);
- // }
- // long simpleAvg = (System.nanoTime() - start) / 100000;
- //
- // float diff = (((float) (simpleAvg - jodaAvg)) / simpleAvg) * 100;
- // System.out.println("Raw - JDK: " + simpleAvg + " ns Joda: " + jodaAvg
- // + " ns - Difference: " + diff + "%");
- // }
-
- public void testSynchronized() throws Exception {
- SynchronizedDateFormatter formatter = new SynchronizedDateFormatter();
- int threads = 10;
- int iterations = 10000;
- Thread[] formatThreads = new Thread[threads];
- Date date = new Date();
-
- for (int i = 0; i < threads; i++) {
- formatThreads[i] = new DateFormatThread(formatter, date, iterations);
- }
- long start = System.nanoTime();
- for (Thread thread : formatThreads) {
- thread.start();
- }
- for (Thread thread : formatThreads) {
- thread.join();
- }
- long end = System.nanoTime();
- double actual = ((double) (end - start)) / NANOS_IN_ONE_SEC;
- System.out.printf("Synchronized DateFormat: %,.4f seconds\n", actual);
+ public void testUnSynchronized() throws Exception {
+ UnsynchronizedDateFormatter formatter = new UnsynchronizedDateFormatter();
+ int threads = 10;
+ int iterations = 10000;
+ Thread[] formatThreads = new Thread[threads];
+ Date date = new Date();
+ for (int i = 0; i < threads; i++) {
+ formatThreads[i] = new DateFormatThread(formatter, date, iterations);
}
-
- public void testUnSynchronized() throws Exception {
- UnsynchronizedDateFormatter formatter = new UnsynchronizedDateFormatter();
- int threads = 10;
- int iterations = 10000;
- Thread[] formatThreads = new Thread[threads];
- Date date = new Date();
-
- for (int i = 0; i < threads; i++) {
- formatThreads[i] = new DateFormatThread(formatter, date, iterations);
- }
- long start = System.nanoTime();
- for (Thread thread : formatThreads) {
- thread.start();
- }
- for (Thread thread : formatThreads) {
- thread.join();
- }
- long end = System.nanoTime();
- double actual = ((double) (end - start)) / NANOS_IN_ONE_SEC;
- System.out.printf("Unsynchronized DateFormat: %,.4f seconds\n", actual);
-
+ long start = System.nanoTime();
+ for (Thread thread : formatThreads) {
+ thread.start();
}
-
- public void testThreadLocal() throws Exception {
- ThreadLocalDateFormatter formatter = new ThreadLocalDateFormatter();
- int threads = 10;
- int iterations = 10000;
- Thread[] formatThreads = new Thread[threads];
- Date date = new Date();
-
- for (int i = 0; i < threads; i++) {
- formatThreads[i] = new DateFormatThread(formatter, date, iterations);
- }
- long start = System.nanoTime();
- for (Thread thread : formatThreads) {
- thread.start();
- }
- for (Thread thread : formatThreads) {
- thread.join();
- }
- long end = System.nanoTime();
- double actual = ((double) (end - start)) / NANOS_IN_ONE_SEC;
- System.out.printf("ThreadLocal DateFormat: %,.4f seconds\n", actual);
-
+ for (Thread thread : formatThreads) {
+ thread.join();
}
+ long end = System.nanoTime();
+ double actual = ((double) (end - start)) / NANOS_IN_ONE_SEC;
+ System.out.printf("Unsynchronized DateFormat: %,.4f seconds\n", actual);
- // public void testDateTimeFormatter() throws Exception {
- // int threads = 10;
- // int iterations = 10000;
- // Thread[] formatThreads = new DateTimeFormatThread[threads];
- // JodaFormatter formatter = new JodaFormatter();
- // Date date = new Date();
- // DateTime dateTime = new DateTime(date);
- //
- // for (int i = 0; i < threads; i++) {
- // formatThreads[i] = new DateTimeFormatThread(formatter, dateTime,
- // iterations);
- // }
- // long start = System.nanoTime();
- // for (Thread thread : formatThreads) {
- // thread.start();
- // }
- // for (Thread thread : formatThreads) {
- // thread.join();
- // }
- // long end = System.nanoTime();
- // double actual = ((double) (end - start)) / NANOS_IN_ONE_SEC;
- // System.out.printf("Joda DateTimeFormatter: %,.4f seconds\n", actual);
- //
- // }
-
- public interface Formatter {
- String format(Date date);
- }
+ }
- public static class SynchronizedDateFormatter implements Formatter {
- SimpleDateFormat simpleFormat = new SimpleDateFormat(ISO8601_PATTERN);
+ public void testThreadLocal() throws Exception {
+ ThreadLocalDateFormatter formatter = new ThreadLocalDateFormatter();
+ int threads = 10;
+ int iterations = 10000;
+ Thread[] formatThreads = new Thread[threads];
+ Date date = new Date();
- public synchronized String format(Date date) {
- return simpleFormat.format(date);
- }
+ for (int i = 0; i < threads; i++) {
+ formatThreads[i] = new DateFormatThread(formatter, date, iterations);
+ }
+ long start = System.nanoTime();
+ for (Thread thread : formatThreads) {
+ thread.start();
+ }
+ for (Thread thread : formatThreads) {
+ thread.join();
}
+ long end = System.nanoTime();
+ double actual = ((double) (end - start)) / NANOS_IN_ONE_SEC;
+ System.out.printf("ThreadLocal DateFormat: %,.4f seconds\n", actual);
+
+ }
+
+// public void testDateTimeFormatter() throws Exception {
+// int threads = 10;
+// int iterations = 10000;
+// Thread[] formatThreads = new DateTimeFormatThread[threads];
+// JodaFormatter formatter = new JodaFormatter();
+// Date date = new Date();
+// DateTime dateTime = new DateTime(date);
+//
+// for (int i = 0; i < threads; i++) {
+// formatThreads[i] = new DateTimeFormatThread(formatter, dateTime,
+// iterations);
+// }
+// long start = System.nanoTime();
+// for (Thread thread : formatThreads) {
+// thread.start();
+// }
+// for (Thread thread : formatThreads) {
+// thread.join();
+// }
+// long end = System.nanoTime();
+// double actual = ((double) (end - start)) / NANOS_IN_ONE_SEC;
+// System.out.printf("Joda DateTimeFormatter: %,.4f seconds\n", actual);
+//
+// }
+
+ public interface Formatter {
+ String format(Date date);
+ }
+
+ public static class SynchronizedDateFormatter implements Formatter {
+ SimpleDateFormat simpleFormat = new SimpleDateFormat(ISO8601_PATTERN);
+
+ public synchronized String format(Date date) {
+ return simpleFormat.format(date);
+ }
+ }
- public static class UnsynchronizedDateFormatter implements Formatter {
- public synchronized String format(Date date) {
- return new SimpleDateFormat(ISO8601_PATTERN).format(date);
- }
+ public static class UnsynchronizedDateFormatter implements Formatter {
+ public synchronized String format(Date date) {
+ return new SimpleDateFormat(ISO8601_PATTERN).format(date);
}
+ }
- public static class ThreadLocalDateFormatter implements Formatter {
- ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>() {
- protected synchronized SimpleDateFormat initialValue() {
- return new SimpleDateFormat(ISO8601_PATTERN);
- }
- };
+ public static class ThreadLocalDateFormatter implements Formatter {
+ ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>() {
+ protected synchronized SimpleDateFormat initialValue() {
+ return new SimpleDateFormat(ISO8601_PATTERN);
+ }
+ };
- public String format(Date date) {
- return formatter.get().format(date);
- }
+ public String format(Date date) {
+ return formatter.get().format(date);
}
-
- // public static class JodaFormatter {
- // DateTimeFormatter formatter = DateTimeFormat.forPattern(ISO8601_PATTERN);
- //
- // public String format(DateTime date) {
- // return formatter.print(date);
- // }
- // }
-
- public static class DateFormatThread extends Thread {
- Formatter formatter;
- Date date;
- long iterCount;
-
- public DateFormatThread(Formatter f, Date date, long iterations) {
- this.formatter = f;
- this.date = date;
- this.iterCount = iterations;
- }
-
- public void run() {
- for (int i = 0; i < iterCount; i++) {
- formatter.format(this.date);
- }
- }
+ }
+
+// public static class JodaFormatter {
+// DateTimeFormatter formatter = DateTimeFormat.forPattern(ISO8601_PATTERN);
+//
+// public String format(DateTime date) {
+// return formatter.print(date);
+// }
+// }
+
+ public static class DateFormatThread extends Thread {
+ Formatter formatter;
+ Date date;
+ long iterCount;
+
+ public DateFormatThread(Formatter f, Date date, long iterations) {
+ this.formatter = f;
+ this.date = date;
+ this.iterCount = iterations;
}
- // public static class DateTimeFormatThread extends Thread {
- // JodaFormatter formatter;
- // DateTime date;
- // long iterCount;
- //
- // public DateTimeFormatThread(JodaFormatter f, DateTime date, long iterations) {
- // this.formatter = f;
- // this.date = date;
- // this.iterCount = iterations;
- // }
- //
- // public void run() {
- // for (int i = 0; i < iterCount; i++) {
- // formatter.format(this.date);
- // }
- // }
- // }
+ public void run() {
+ for (int i = 0; i < iterCount; i++) {
+ formatter.format(this.date);
+ }
+ }
+ }
+
+// public static class DateTimeFormatThread extends Thread {
+// JodaFormatter formatter;
+// DateTime date;
+// long iterCount;
+//
+// public DateTimeFormatThread(JodaFormatter f, DateTime date, long iterations) {
+// this.formatter = f;
+// this.date = date;
+// this.iterCount = iterations;
+// }
+//
+// public void run() {
+// for (int i = 0; i < iterCount; i++) {
+// formatter.format(this.date);
+// }
+// }
+// }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/DateFormatPerf_Tapp.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/DateFormatPerf_Tapp.java
index f6c8fb4..5a511cd 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/DateFormatPerf_Tapp.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/DateFormatPerf_Tapp.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,43 +20,43 @@ import java.util.Date;
//import org.joda.time.format.DateTimeFormatter;
public class DateFormatPerf_Tapp {
- public static final String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS";
- static final long NANOS_IN_ONE_SEC = 1000 * 1000 * 1000L;
+ public static final String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS";
+ static final long NANOS_IN_ONE_SEC = 1000 * 1000 * 1000L;
- static long RUN_LENGTH = 1000 * 1000;
+ static long RUN_LENGTH = 1000 * 1000;
- public static void main(String[] args) {
- for (int i = 0; i < 5; i++) {
- doRawJoda();
- doRawSDF();
- }
-
- print("Raw Joda: ", doRawJoda());
- print("Raw SDF: ", doRawSDF());
+ public static void main(String[] args) {
+ for (int i = 0; i < 5; i++) {
+ doRawJoda();
+ doRawSDF();
}
- static void print(String msg, double avg) {
- System.out.println(msg + " average tick " + avg + " nanoseconds");
- }
+ print("Raw Joda: ", doRawJoda());
+ print("Raw SDF: ", doRawSDF());
+ }
- static double doRawJoda() {
- // DateTimeFormatter jodaFormat = DateTimeFormat.forPattern(ISO8601_PATTERN);
- long timeInMillis = new Date().getTime();
- long start = System.nanoTime();
- for (int i = 0; i < RUN_LENGTH; ++i) {
- // jodaFormat.print(timeInMillis);
- }
- return (System.nanoTime() - start) * 1.0d / RUN_LENGTH;
- }
+ static void print(String msg, double avg) {
+ System.out.println(msg + " average tick " + avg + " nanoseconds");
+ }
- static double doRawSDF() {
- SimpleDateFormat simpleFormat = new SimpleDateFormat(ISO8601_PATTERN);
- long timeInMillis = new Date().getTime();
- long start = System.nanoTime();
- for (int i = 0; i < RUN_LENGTH; ++i) {
- simpleFormat.format(timeInMillis);
- }
- return (System.nanoTime() - start) * 1.0d / RUN_LENGTH;
+ static double doRawJoda() {
+// DateTimeFormatter jodaFormat = DateTimeFormat.forPattern(ISO8601_PATTERN);
+ long timeInMillis = new Date().getTime();
+ long start = System.nanoTime();
+ for (int i = 0; i < RUN_LENGTH; ++i) {
+// jodaFormat.print(timeInMillis);
+ }
+ return (System.nanoTime() - start) * 1.0d / RUN_LENGTH;
+ }
+
+ static double doRawSDF() {
+ SimpleDateFormat simpleFormat = new SimpleDateFormat(ISO8601_PATTERN);
+ long timeInMillis = new Date().getTime();
+ long start = System.nanoTime();
+ for (int i = 0; i < RUN_LENGTH; ++i) {
+ simpleFormat.format(timeInMillis);
}
+ return (System.nanoTime() - start) * 1.0d / RUN_LENGTH;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/DateFormattingThreadedThroughputCalculator.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/DateFormattingThreadedThroughputCalculator.java
index a7a71ce..736fc18 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/DateFormattingThreadedThroughputCalculator.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/DateFormattingThreadedThroughputCalculator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,33 +24,35 @@ import ch.qos.logback.core.contention.ThreadedThroughputCalculator;
*/
public class DateFormattingThreadedThroughputCalculator {
- static int THREAD_COUNT = 16;
- static long OVERALL_DURATION_IN_MILLIS = 3000;
+ static int THREAD_COUNT = 16;
+ static long OVERALL_DURATION_IN_MILLIS = 3000;
- public static void main(String args[]) throws InterruptedException {
+ public static void main(String args[]) throws InterruptedException {
- ThreadedThroughputCalculator tp = new ThreadedThroughputCalculator(OVERALL_DURATION_IN_MILLIS);
- tp.printEnvironmentInfo("DateFormatting");
+ ThreadedThroughputCalculator tp = new ThreadedThroughputCalculator(
+ OVERALL_DURATION_IN_MILLIS);
+ tp.printEnvironmentInfo("DateFormatting");
- for (int i = 0; i < 2; i++) {
- tp.execute(buildArray(FormattingModel.SDF));
- tp.execute(buildArray(FormattingModel.JODA));
- }
+ for (int i = 0; i < 2; i++) {
+ tp.execute(buildArray(FormattingModel.SDF));
+ tp.execute(buildArray(FormattingModel.JODA));
+ }
- tp.execute(buildArray(FormattingModel.JODA));
- tp.printThroughput("JODA: ");
+ tp.execute(buildArray(FormattingModel.JODA));
+ tp.printThroughput("JODA: ");
+
+ tp.execute(buildArray(FormattingModel.SDF));
+ tp.printThroughput("SDF: ");
- tp.execute(buildArray(FormattingModel.SDF));
- tp.printThroughput("SDF: ");
- }
+ }
- static SelectiveDateFormattingRunnable[] buildArray(FormattingModel model) {
- SelectiveDateFormattingRunnable[] array = new SelectiveDateFormattingRunnable[THREAD_COUNT];
- for (int i = 0; i < THREAD_COUNT; i++) {
- array[i] = new SelectiveDateFormattingRunnable(model);
- }
- return array;
+ static SelectiveDateFormattingRunnable[] buildArray(FormattingModel model) {
+ SelectiveDateFormattingRunnable[] array = new SelectiveDateFormattingRunnable[THREAD_COUNT];
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ array[i] = new SelectiveDateFormattingRunnable(model);
}
+ return array;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/SelectiveDateFormattingRunnable.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/SelectiveDateFormattingRunnable.java
index e02c963..e7226ac 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/SelectiveDateFormattingRunnable.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic36/SelectiveDateFormattingRunnable.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,78 +22,78 @@ import ch.qos.logback.core.contention.RunnableWithCounterAndDone;
/**
* A runnable which behaves differently depending on the desired locking model.
*
- * @author Ralph Goers
+ * @author Raplh Goers
* @author Ceki Gulcu
*/
-public class SelectiveDateFormattingRunnable extends RunnableWithCounterAndDone {
+public class SelectiveDateFormattingRunnable extends
+ RunnableWithCounterAndDone {
- public static final String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS";
+ public static final String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS";
- enum FormattingModel {
- SDF, JODA;
- }
-
- FormattingModel model;
- static long CACHE = 0;
+ enum FormattingModel {
+ SDF, JODA;
+ }
- static SimpleDateFormat SDF = new SimpleDateFormat(ISO8601_PATTERN);
+ FormattingModel model;
+ static long CACHE = 0;
- // static final DateTimeFormatter JODA = DateTimeFormat
- // .forPattern(ISO8601_PATTERN);
+ static SimpleDateFormat SDF = new SimpleDateFormat(ISO8601_PATTERN);
+// static final DateTimeFormatter JODA = DateTimeFormat
+// .forPattern(ISO8601_PATTERN);
- SelectiveDateFormattingRunnable(FormattingModel model) {
- this.model = model;
- }
+ SelectiveDateFormattingRunnable(FormattingModel model) {
+ this.model = model;
+ }
- public void run() {
- switch (model) {
- case SDF:
- sdfRun();
- break;
- case JODA:
- jodaRun();
- break;
- }
+ public void run() {
+ switch (model) {
+ case SDF:
+ sdfRun();
+ break;
+ case JODA:
+ jodaRun();
+ break;
}
+ }
- void sdfRun() {
-
- for (;;) {
- synchronized (SDF) {
- long now = System.currentTimeMillis();
- if (CACHE != now) {
- CACHE = now;
- SDF.format(now);
- }
- }
- counter++;
- if (done) {
- return;
- }
- }
- }
+ void sdfRun() {
- void jodaRun() {
- for (;;) {
- long now = System.currentTimeMillis();
- if (isCacheStale(now)) {
- // JODA.print(now);
- }
- counter++;
- if (done) {
- return;
- }
+ for (;;) {
+ synchronized (SDF) {
+ long now = System.currentTimeMillis();
+ if (CACHE != now) {
+ CACHE = now;
+ SDF.format(now);
}
+ }
+ counter++;
+ if (done) {
+ return;
+ }
}
+ }
- private static boolean isCacheStale(long now) {
- // synchronized (JODA) {
- // if (CACHE != now) {
- // CACHE = now;
- // return true;
- // }
- // }
- return false;
+ void jodaRun() {
+ for (;;) {
+ long now = System.currentTimeMillis();
+ if (isCacheStale(now)) {
+ //JODA.print(now);
+ }
+ counter++;
+ if (done) {
+ return;
+ }
}
+ }
+
+ private static boolean isCacheStale(long now) {
+// synchronized (JODA) {
+// if (CACHE != now) {
+// CACHE = now;
+// return true;
+// }
+// }
+ return false;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore211/Lbcore211.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore211/Lbcore211.java
index a1ef8bf..8c6763c 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore211/Lbcore211.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore211/Lbcore211.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,26 +22,26 @@ import org.junit.Test;
import org.slf4j.LoggerFactory;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class Lbcore211 {
- @Test
- public void lbcore211() throws JoranException {
+ @Test
+ public void lbcore211() throws JoranException {
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- lc.reset();
- configurator.doConfigure("/home/ceki/lbcore211.xml");
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ lc.reset();
+ configurator.doConfigure("/home/ceki/lbcore211.xml");
- Logger l = lc.getLogger("file.logger");
- StatusPrinter.print(lc);
- for (int i = 0; i < 10; i++) {
- l.info("hello " + i);
- }
-
- lc.stop();
+ Logger l = lc.getLogger("file.logger");
+ StatusPrinter.print(lc);
+ for (int i = 0; i < 10; i++) {
+ l.info("hello " + i);
}
+
+ lc.stop();
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore224/Reduce.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore224/Reduce.java
index 10badea..46fc2bd 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore224/Reduce.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore224/Reduce.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,146 +24,150 @@ import java.util.regex.Pattern;
*/
public class Reduce {
- static int NA = -1;
+ static int NA = -1;
- enum OperationType {
- LOCK, UNLOCK
- }
-
- public static void main(String[] args) throws IOException {
- File inputFile = new File(args[0]);
- if (!inputFile.exists()) {
- throw new IllegalArgumentException("Missing file [" + args[0] + "]");
- }
- List<String> lines = readFile(inputFile);
- System.out.println("Lines count=" + lines.size());
- List<Structure> structuredLines = structure(lines);
- List<Structure> reduction = reduce(structuredLines);
- if (reduction.isEmpty()) {
- System.out.println("Reduction is EMPTY as it should be.");
- } else {
- System.out.println("Non-empty reduction!!! WTF?");
- System.out.println(reduction);
- }
+ enum OperationType {LOCK, UNLOCK}
+ public static void main(String[] args) throws IOException {
+ File inputFile = new File(args[0]);
+ if(!inputFile.exists()) {
+ throw new IllegalArgumentException("Missing file ["+args[0]+"]");
}
-
- private static List<String> readFile(File inputFile) throws IOException {
- BufferedReader reader = null;
- List<String> lines = new ArrayList();
- try {
- reader = new BufferedReader(new FileReader(inputFile));
- String line;
- while ((line = reader.readLine()) != null) {
- lines.add(line);
- }
- } finally {
- if (reader != null)
- try {
- reader.close();
- } catch (IOException e) {
- }
- }
- return lines;
+ List<String> lines = readFile(inputFile);
+ System.out.println("Lines count=" + lines.size());
+ List<Structure> structuredLines = structure(lines);
+ List<Structure> reduction = reduce(structuredLines);
+ if (reduction.isEmpty()) {
+ System.out.println("Reduction is EMPTY as it should be.");
+ } else {
+ System.out.println("Non-empty reduction!!! WTF?");
+ System.out.println(reduction);
}
- private static List<Structure> reduce(List<Structure> structuredLines) {
- List<Structure> matching = new ArrayList<Structure>();
- int lockIndex = 0;
- while (lockIndex < structuredLines.size()) {
- lockIndex = findNearestLock(structuredLines, lockIndex);
- if (lockIndex == NA)
- break;
- else {
- int unlockIndex = findNearestUnlockInSameThread(structuredLines, lockIndex);
- if (unlockIndex != NA) {
- matching.add(structuredLines.get(lockIndex));
- matching.add(structuredLines.get(unlockIndex));
- }
- lockIndex++;
- }
- }
- System.out.println("matching list size: " + matching.size());
- List<Structure> reduction = new ArrayList<Structure>();
- for (Structure s : structuredLines) {
- if (!matching.contains(s)) {
- reduction.add(s);
- }
- }
- return reduction;
- }
+ }
- private static int findNearestLock(List<Structure> reduction, int index) {
- for (int i = index; i < reduction.size(); i++) {
- Structure s = reduction.get(i);
- if (s.operationType == OperationType.LOCK) {
- return i;
- }
+ private static List<String> readFile(File inputFile) throws IOException {
+ BufferedReader reader = null;
+ List<String> lines = new ArrayList();
+ try {
+ reader = new BufferedReader(new FileReader(inputFile));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ lines.add(line);
+ }
+ } finally {
+ if (reader != null)
+ try {
+ reader.close();
+ } catch (IOException e) {
}
- return NA;
}
-
- private static int findNearestUnlockInSameThread(List<Structure> reduction, int lockIndex) {
- int firstCandidateIndex = lockIndex + 1;
- Structure lockStructure = reduction.get(lockIndex);
- for (int i = firstCandidateIndex; i < reduction.size(); i++) {
- Structure s = reduction.get(i);
- if (s.operationType == OperationType.UNLOCK && lockStructure.thread.equals(s.thread)) {
- return i;
- }
+ return lines;
+ }
+
+ private static List<Structure> reduce(List<Structure> structuredLines) {
+ List<Structure> matching = new ArrayList<Structure>();
+ int lockIndex = 0;
+ while (lockIndex < structuredLines.size()) {
+ lockIndex = findNearestLock(structuredLines, lockIndex);
+ if (lockIndex == NA)
+ break;
+ else {
+ int unlockIndex = findNearestUnlockInSameThread(structuredLines, lockIndex);
+ if (unlockIndex != NA) {
+ matching.add(structuredLines.get(lockIndex));
+ matching.add(structuredLines.get(unlockIndex));
}
- return NA;
+ lockIndex++;
+ }
+ }
+ System.out.println("matching list size: " + matching.size());
+ List<Structure> reduction = new ArrayList<Structure>();
+ for (Structure s : structuredLines) {
+ if (!matching.contains(s)) {
+ reduction.add(s);
+ }
}
+ return reduction;
- static List<Structure> structure(List<String> lines) {
- List<Structure> structuredLines = new ArrayList();
- Pattern p = Pattern.compile("(\\d{2,5})\\ +(.*) (LOCK|UNLOCK)");
-
- for (String line : lines) {
- Matcher m = p.matcher(line);
- if (m.matches()) {
- String relTime = m.group(1);
- String t = m.group(2);
- String opStr = m.group(3);
- Structure structure = buildStructure(relTime, t, opStr);
- structuredLines.add(structure);
- } else {
- System.out.println("NON MATCHING LINE: [" + line + "]");
- }
+ }
- }
- return structuredLines;
+ private static int findNearestLock(List<Structure> reduction, int index) {
+ for (int i = index; i < reduction.size(); i++) {
+ Structure s = reduction.get(i);
+ if (s.operationType == OperationType.LOCK) {
+ return i;
+ }
}
+ return NA;
+ }
+
+ private static int findNearestUnlockInSameThread(List<Structure> reduction, int lockIndex) {
+ int firstCandidateIndex = lockIndex+1;
+ Structure lockStructure = reduction.get(lockIndex);
+ for (int i = firstCandidateIndex; i < reduction.size(); i++) {
+ Structure s = reduction.get(i);
+ if (s.operationType == OperationType.UNLOCK && lockStructure.thread.equals(s.thread)) {
+ return i;
+ }
+ }
+ return NA;
+ }
+
+ static List<Structure> structure(List<String> lines) {
+ List<Structure> structuredLines = new ArrayList();
+ Pattern p = Pattern.compile("(\\d{2,5})\\ +(.*) (LOCK|UNLOCK)");
+
+ for (String line : lines) {
+ Matcher m = p.matcher(line);
+ if (m.matches()) {
+ String relTime = m.group(1);
+ String t = m.group(2);
+ String opStr = m.group(3);
+ Structure structure = buildStructure(relTime, t, opStr);
+ structuredLines.add(structure);
+ } else {
+ System.out.println("NON MATCHING LINE: ["+ line+"]");
+ }
- private static Structure buildStructure(String relTime, String t, String opStr) {
- long r = Long.parseLong(relTime);
- OperationType operationType;
- if (opStr.equals("LOCK"))
- operationType = OperationType.LOCK;
- else if (opStr.equals("UNLOCK")) {
- operationType = OperationType.UNLOCK;
- } else {
- throw new IllegalArgumentException(opStr + " is not LOCK|UNLOCK");
- }
- return new Structure(r, t, operationType);
}
+ return structuredLines;
+ }
+
+ private static Structure buildStructure(String relTime, String t, String opStr) {
+ long r = Long.parseLong(relTime);
+ OperationType operationType;
+ if (opStr.equals("LOCK"))
+ operationType = OperationType.LOCK;
+ else if (opStr.equals("UNLOCK")) {
+ operationType = OperationType.UNLOCK;
+ } else {
+ throw new IllegalArgumentException(opStr + " is not LOCK|UNLOCK");
+ }
+ return new Structure(r, t, operationType);
+ }
- static class Structure {
- long time;
- String thread;
- OperationType operationType;
- Structure(long time, String thread, OperationType operationType) {
- this.time = time;
- this.thread = thread;
- this.operationType = operationType;
- }
+ static class Structure {
+ long time;
+ String thread;
+ OperationType operationType;
- @Override
- public String toString() {
- return "Structure{" + "time=" + time + ", thread='" + thread + '\'' + ", operationType=" + operationType + '}';
- }
+ Structure(long time, String thread, OperationType operationType) {
+ this.time = time;
+ this.thread = thread;
+ this.operationType = operationType;
+ }
+
+ @Override
+ public String toString() {
+ return "Structure{" +
+ "time=" + time +
+ ", thread='" + thread + '\'' +
+ ", operationType=" + operationType +
+ '}';
}
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/Common.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/Common.java
index ddcb663..aa19be0 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/Common.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/Common.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,7 +15,7 @@ package ch.qos.logback.classic.issue.lbcore243;
public class Common {
- // How many times should we try to log:
- static int loop = 800 * 1000;
+ // How many times should we try to log:
+ static int loop = 800*1000;
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLog4j.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLog4j.java
index 9db2e98..7ed085c 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLog4j.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLog4j.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.classic.issue.lbcore243;
+
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
@@ -20,42 +21,42 @@ import org.apache.log4j.xml.DOMConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
// WARNING This code compiles but does not measure anything useful because log4j-over-slf4j is a dependency. Log4j
// should be used instead
public class PerformanceComparatorLog4j {
- static org.apache.log4j.Logger log4jlogger = org.apache.log4j.Logger.getLogger(PerformanceComparatorLog4j.class);
-
- public static void main(String[] args) throws JoranException, InterruptedException {
- initLog4jWithoutImmediateFlush();
-
- // Let's run once for Just In Time compiler
- log4jDirectDebugCall();
-
- System.out.println("###############################################");
- System.out.println("Log4j without immediate flush: " + log4jDirectDebugCall() + " nanos per call");
- System.out.println("###############################################");
- }
-
- private static long log4jDirectDebugCall() {
- Integer j = new Integer(2);
- long start = System.nanoTime();
- for (int i = 0; i < Common.loop; i++) {
- log4jlogger.debug("SEE IF THIS IS LOGGED " + j + ".");
- }
- return (System.nanoTime() - start) / Common.loop;
- }
-
- static String DIR_PREFIX = "src/test/java/ch/qos/logback/classic/issue/lbcore243/";
-
- static void initLog4jWithoutImmediateFlush() {
- DOMConfigurator domConfigurator = new DOMConfigurator();
- domConfigurator.configure(DIR_PREFIX + "log4j_without_immediateFlush.xml");
- }
-
- static void initLog4jWithImmediateFlush() {
- DOMConfigurator domConfigurator = new DOMConfigurator();
- domConfigurator.configure(DIR_PREFIX + "log4j_with_immediateFlush.xml");
- }
+ static org.apache.log4j.Logger log4jlogger = org.apache.log4j.Logger.getLogger(PerformanceComparatorLog4j.class);
+
+ public static void main(String[] args) throws JoranException, InterruptedException {
+ initLog4jWithoutImmediateFlush();
+
+ // Let's run once for Just In Time compiler
+ log4jDirectDebugCall();
+
+ System.out.println("###############################################");
+ System.out.println("Log4j without immediate flush: " + log4jDirectDebugCall()+ " nanos per call");
+ System.out.println("###############################################");
+ }
+
+ private static long log4jDirectDebugCall() {
+ Integer j = new Integer(2);
+ long start = System.nanoTime();
+ for (int i = 0; i < Common.loop; i++) {
+ log4jlogger.debug("SEE IF THIS IS LOGGED " + j + ".");
+ }
+ return (System.nanoTime() - start) / Common.loop;
+ }
+
+ static String DIR_PREFIX = "src/test/java/ch/qos/logback/classic/issue/lbcore243/";
+
+ static void initLog4jWithoutImmediateFlush() {
+ DOMConfigurator domConfigurator = new DOMConfigurator();
+ domConfigurator.configure(DIR_PREFIX+"log4j_without_immediateFlush.xml");
+ }
+ static void initLog4jWithImmediateFlush() {
+ DOMConfigurator domConfigurator = new DOMConfigurator();
+ domConfigurator.configure(DIR_PREFIX+"log4j_with_immediateFlush.xml");
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLogback.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLogback.java
index ddad0d9..2bf224a 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLogback.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLogback.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.classic.issue.lbcore243;
+
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
@@ -24,48 +25,50 @@ import org.slf4j.LoggerFactory;
//Logback without immediate flush: 1758 nanos per call
public class PerformanceComparatorLogback {
- static Logger logbacklogger = LoggerFactory.getLogger(PerformanceComparatorLogback.class);
+ static Logger logbacklogger = LoggerFactory.getLogger(PerformanceComparatorLogback.class);
- public static void main(String[] args) throws JoranException, InterruptedException {
- initLogbackWithoutImmediateFlush();
- logbackParametrizedDebugCall();
+ public static void main(String[] args) throws JoranException, InterruptedException {
+ initLogbackWithoutImmediateFlush();
+ logbackParametrizedDebugCall();
- initLogbackWithImmediateFlush();
- logbackParametrizedDebugCall();
- System.out.println("###############################################");
- System.out.println("Logback with immediate flush: " + logbackParametrizedDebugCall() + " nanos per call");
+ initLogbackWithImmediateFlush();
+ logbackParametrizedDebugCall();
+ System.out.println("###############################################");
+ System.out.println("Logback with immediate flush: " + logbackParametrizedDebugCall() + " nanos per call");
- initLogbackWithoutImmediateFlush();
- System.out.println("Logback without immediate flush: " + logbackParametrizedDebugCall() + " nanos per call");
+ initLogbackWithoutImmediateFlush();
+ System.out.println("Logback without immediate flush: " + logbackParametrizedDebugCall() + " nanos per call");
- System.out.println("###############################################");
- }
+ System.out.println("###############################################");
+ }
- private static long logbackParametrizedDebugCall() {
+ private static long logbackParametrizedDebugCall() {
- Integer j = new Integer(2);
- long start = System.nanoTime();
- for (int i = 0; i < Common.loop; i++) {
- logbacklogger.debug("SEE IF THIS IS LOGGED {}.", j);
- }
- return (System.nanoTime() - start) / Common.loop;
+ Integer j = new Integer(2);
+ long start = System.nanoTime();
+ for (int i = 0; i < Common.loop; i++) {
+ logbacklogger.debug("SEE IF THIS IS LOGGED {}.", j);
}
+ return (System.nanoTime() - start) / Common.loop;
+ }
- static String DIR_PREFIX = "src/test/java/ch/qos/logback/classic/issue/lbcore243/";
+ static String DIR_PREFIX = "src/test/java/ch/qos/logback/classic/issue/lbcore243/";
- static void configure(String file) throws JoranException {
- LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(loggerContext);
- loggerContext.reset();
- jc.doConfigure(file);
- }
- private static void initLogbackWithoutImmediateFlush() throws JoranException {
- configure(DIR_PREFIX + "logback_without_immediateFlush.xml");
- }
+ static void configure(String file) throws JoranException {
+ LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ loggerContext.reset();
+ jc.doConfigure(file);
+ }
- private static void initLogbackWithImmediateFlush() throws JoranException {
- configure(DIR_PREFIX + "logback_with_immediateFlush.xml");
- }
+
+ private static void initLogbackWithoutImmediateFlush() throws JoranException {
+ configure(DIR_PREFIX + "logback_without_immediateFlush.xml");
+ }
+
+ private static void initLogbackWithImmediateFlush() throws JoranException {
+ configure(DIR_PREFIX + "logback_with_immediateFlush.xml");
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore26/Main.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore26/Main.java
index 6fa803a..f0ade02 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore26/Main.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore26/Main.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,19 +26,20 @@ import ch.qos.logback.core.util.StatusPrinter;
public class Main {
- public static void main(String[] args) throws JoranException {
+ public static void main(String[] args) throws JoranException {
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- configurator.doConfigure(ClassicTestConstants.INPUT_PREFIX + "issue/lbcore26.xml");
-
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
- Logger logger = LoggerFactory.getLogger(Main.class);
- for (int i = 0; i < 16; i++) {
- logger.info("hello " + new Date());
- }
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ configurator.doConfigure(ClassicTestConstants.INPUT_PREFIX
+ + "issue/lbcore26.xml");
+ StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
+ Logger logger = LoggerFactory.getLogger(Main.class);
+ for (int i = 0; i < 16; i++) {
+ logger.info("hello " + new Date());
}
+ }
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore_155/Main.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore_155/Main.java
index 1f5555e..cfb57ab 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore_155/Main.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore_155/Main.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,21 +19,21 @@ import ch.qos.logback.core.util.StatusPrinter;
import org.slf4j.LoggerFactory;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class Main {
- public static void main(String[] args) throws InterruptedException {
+ public static void main(String[] args) throws InterruptedException {
- Logger logger = (Logger) LoggerFactory.getLogger(Main.class);
- StatusPrinter.print((LoggerContext) LoggerFactory.getILoggerFactory());
- OThread ot = new OThread();
- ot.start();
- Thread.sleep(OThread.WAIT_MILLIS - 500);
- logger.info("About to interrupt");
- ot.interrupt();
- logger.info("After interrupt");
- logger.info("Leaving main");
+ Logger logger = (Logger) LoggerFactory.getLogger(Main.class);
+ StatusPrinter.print((LoggerContext) LoggerFactory.getILoggerFactory());
+ OThread ot = new OThread();
+ ot.start();
+ Thread.sleep(OThread.WAIT_MILLIS-500);
+ logger.info("About to interrupt");
+ ot.interrupt();
+ logger.info("After interrupt");
+ logger.info("Leaving main");
- }
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore_155/OThread.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore_155/OThread.java
index fc83aaa..8cbf5a1 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore_155/OThread.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore_155/OThread.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,40 +13,42 @@
*/
package ch.qos.logback.classic.issue.lbcore_155;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class OThread extends Thread {
- static int NANOS_IN_MILLI = 1000 * 1000;
-
- static int WAIT_MILLIS = 10;
- Logger logger = LoggerFactory.getLogger(this.getClass());
+ static int NANOS_IN_MILLI = 1000 * 1000;
- public void run() {
+ static int WAIT_MILLIS = 10;
- while (!isInterrupted()) {
- long start = System.nanoTime();
- for (long now = System.nanoTime(); now < start + 2 * WAIT_MILLIS * NANOS_IN_MILLI; now = System.nanoTime()) {
- logger.info("in time loop");
- }
+ Logger logger = LoggerFactory.getLogger(this.getClass());
- logger.info("before 2nd sleep");
+ public void run() {
- try {
- sleep(1000);
- } catch (InterruptedException e) {
- logger.info("While sleeping", e);
- e.printStackTrace();
- break;
- }
- logger.info("after sleep");
- }
- logger.info("exiting WHILE");
+ while (!isInterrupted()) {
+ long start = System.nanoTime();
+ for (long now = System.nanoTime(); now < start + 2*WAIT_MILLIS*NANOS_IN_MILLI; now = System.nanoTime()) {
+ logger.info("in time loop");
+ }
+ logger.info("before 2nd sleep");
+
+ try {
+ sleep(1000);
+ } catch (InterruptedException e) {
+ logger.info("While sleeping", e);
+ e.printStackTrace();
+ break;
+ }
+ logger.info("after sleep");
}
+ logger.info("exiting WHILE");
+
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback1159/LogbackListener.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback1159/LogbackListener.java
deleted file mode 100644
index 0ffaa3c..0000000
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback1159/LogbackListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package ch.qos.logback.classic.issue.logback1159;
-
-import java.io.IOException;
-
-import ch.qos.logback.core.spi.ContextAwareBase;
-import ch.qos.logback.core.spi.LifeCycle;
-import ch.qos.logback.core.status.Status;
-import ch.qos.logback.core.status.StatusListener;
-import ch.qos.logback.core.status.ErrorStatus;
-
-public class LogbackListener extends ContextAwareBase implements StatusListener, LifeCycle {
- private boolean started;
-
- @Override
- public void start() {
- this.started = true;
- }
-
- @Override
- public void stop() {
- this.started = false;
- }
-
- @Override
- public boolean isStarted() {
- return this.started;
- }
-
- @Override
- public void addStatusEvent(final Status status) {
- if (status instanceof ErrorStatus && status.getThrowable() instanceof IOException) {
- System.out.println("*************************LogbackListener.addStatusEvent");
- throw new LoggingError(status.getMessage(), status.getThrowable());
- }
- }
-
-}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback1159/LogbackListenerTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback1159/LogbackListenerTest.java
deleted file mode 100644
index fe393a7..0000000
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback1159/LogbackListenerTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package ch.qos.logback.classic.issue.logback1159;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.attribute.PosixFilePermission;
-import java.util.Collections;
-import java.util.Set;
-
-
-//import org.apache.commons.io.FileUtils;
-//import org.apache.commons.lang3.RandomStringUtils;
-import org.junit.After;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.impl.StaticLoggerBinderFriend;
-
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.core.joran.spi.JoranException;
-
-public class LogbackListenerTest {
- private File logFile = new File("target/test.log");
-
- private void doConfigure() throws JoranException {
- LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(context);
- configurator.doConfigure(new File("src/test/input/issue/logback-1159.xml"));
- }
-
- @After
- public void after() {
- logFile.delete();
- StaticLoggerBinderFriend.reset();
- }
-
- private void disableLogFileAccess() throws IOException {
- logFile.createNewFile();
- logFile.deleteOnExit();
- Path path = Paths.get(logFile.toURI());
- Set<PosixFilePermission> permissions = Collections.emptySet();
- try {
- Files.setPosixFilePermissions(path, permissions);
- } catch (UnsupportedOperationException e) {
- path.toFile().setReadOnly();
- }
- }
-
- @Test(expected = LoggingError.class)
- public void testThatErrorIsDetectedAtLogInit() throws Exception {
- disableLogFileAccess();
- doConfigure();
- }
-
- @Test
- public void assertThatNonFailSafeAppendersNotAffected() throws JoranException {
- doConfigure();
- Logger logger = LoggerFactory.getLogger("NOTJOURNAL");
- logger.error("This should not fail");
- }
-
-}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback1159/LoggingError.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback1159/LoggingError.java
deleted file mode 100644
index b1fbced..0000000
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback1159/LoggingError.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package ch.qos.logback.classic.issue.logback1159;
-
-/**
- * Based error class to be thrown in a logging failsafe situation. I.e. any unexpected error
- * situations during logging (e.g. database access, I/O failure)
- *
- */
-public class LoggingError extends Error {
-
- private static final long serialVersionUID = -4881940499551760472L;
-
- public LoggingError(String msg, Throwable cause) {
- super(msg, cause);
- }
-
-}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback416/ConcurrentSiftingTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback416/ConcurrentSiftingTest.java
deleted file mode 100644
index c6ff355..0000000
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback416/ConcurrentSiftingTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.classic.issue.logback416;
-
-import ch.qos.logback.classic.ClassicTestConstants;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.issue.lbclassic135.LoggingRunnable;
-import ch.qos.logback.classic.issue.logback416.InstanceCountingAppender;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.core.contention.MultiThreadedHarness;
-import ch.qos.logback.core.contention.RunnableWithCounterAndDone;
-import ch.qos.logback.core.joran.spi.JoranException;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-public class ConcurrentSiftingTest {
- final static int THREAD_COUNT = 5;
- static String FOLDER_PREFIX = ClassicTestConstants.JORAN_INPUT_PREFIX + "sift/";
-
- LoggerContext loggerContext = new LoggerContext();
- protected Logger logger = loggerContext.getLogger(this.getClass().getName());
- protected Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
-
- int totalTestDuration = 50;
- MultiThreadedHarness harness = new MultiThreadedHarness(totalTestDuration);
- RunnableWithCounterAndDone[] runnableArray = buildRunnableArray();
-
- protected void configure(String file) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(loggerContext);
- jc.doConfigure(file);
- }
-
- RunnableWithCounterAndDone[] buildRunnableArray() {
- RunnableWithCounterAndDone[] rArray = new RunnableWithCounterAndDone[THREAD_COUNT];
- for (int i = 0; i < THREAD_COUNT; i++) {
- rArray[i] = new LoggingRunnable(logger);
- }
- return rArray;
- }
-
- @Test
- public void concurrentAccess() throws JoranException, InterruptedException {
- configure(FOLDER_PREFIX + "logback_416.xml");
- harness.execute(runnableArray);
- assertEquals(1, InstanceCountingAppender.INSTANCE_COUNT.get());
- }
-}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback416/InstanceCountingAppender.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback416/InstanceCountingAppender.java
deleted file mode 100644
index 6e3d96b..0000000
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback416/InstanceCountingAppender.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.classic.issue.logback416;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.AppenderBase;
-
-public class InstanceCountingAppender extends AppenderBase<ILoggingEvent> {
-
- static public AtomicInteger INSTANCE_COUNT = new AtomicInteger(0);
-
- public InstanceCountingAppender() {
- INSTANCE_COUNT.getAndIncrement();
- }
-
- protected void append(ILoggingEvent e) {
- }
-
-}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback416/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback416/PackageTest.java
deleted file mode 100644
index c1e55ad..0000000
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback416/PackageTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.classic.issue.logback416;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-import org.junit.runners.Suite.SuiteClasses;
-
- at RunWith(Suite.class)
- at SuiteClasses(ConcurrentSiftingTest.class)
-public class PackageTest {
-}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback474/LoggingAppender.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback474/LoggingAppender.java
index 15ac547..4eecafa 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback474/LoggingAppender.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/logback474/LoggingAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,14 +27,14 @@ import ch.qos.logback.core.AppenderBase;
public class LoggingAppender extends AppenderBase<ILoggingEvent> {
- Logger logger;
+ Logger logger;
- public void start() {
- super.start();
- logger = ((LoggerContext) getContext()).getLogger("Ignore");
- }
+ public void start() {
+ super.start();
+ logger = ((LoggerContext) getContext()).getLogger("Ignore");
+ }
- protected void append(ILoggingEvent eventObject) {
- logger.debug("Ignore this");
- }
+ protected void append(ILoggingEvent eventObject) {
+ logger.debug("Ignore this");
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/jmx/JMXConfiguratorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/jmx/JMXConfiguratorTest.java
index f920bc2..3d0867e 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/jmx/JMXConfiguratorTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/jmx/JMXConfiguratorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2016, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -35,132 +35,124 @@ import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.LoggerContextListener;
import ch.qos.logback.core.testUtil.RandomUtil;
-import static org.slf4j.Logger.ROOT_LOGGER_NAME;
-
public class JMXConfiguratorTest {
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- LoggerContext lc = new LoggerContext();
- Logger testLogger = lc.getLogger(this.getClass());
-
- List<LoggerContextListener> listenerList;
- int diff = RandomUtil.getPositiveInt();
-
- @Before
- public void setUp() throws Exception {
- lc.setName("context-" + diff);
- assertNotNull(mbs);
- }
-
- @After
- public void tearDown() throws Exception {
- lc.stop();
- }
-
- @Override
- public String toString() {
- return this.getClass().getName() + "(" + lc.getName() + ")";
- }
-
- @Test
- public void contextReset() throws Exception {
- String randomizedObjectNameAsStr = "ch.qos.logback." + diff + ":Name=" + lc.getName() + ",Type=" + this.getClass().getName();
-
- ObjectName objectName = MBeanUtil.string2ObjectName(lc, this, randomizedObjectNameAsStr);
- JMXConfigurator jmxConfigurator = new JMXConfigurator(lc, mbs, objectName);
- mbs.registerMBean(jmxConfigurator, objectName);
-
- listenerList = lc.getCopyOfListenerList();
- assertEquals(1, listenerList.size());
-
- lc.reset();
-
- // check that after lc.reset, jmxConfigurator should still be
- // registered as a listener in the loggerContext and also as an
- // MBean in mbs
- listenerList = lc.getCopyOfListenerList();
- assertEquals(1, listenerList.size());
- assertTrue(listenerList.contains(jmxConfigurator));
-
- assertTrue(mbs.isRegistered(objectName));
- }
-
- @Test
- public void contextStop() throws Exception {
- String randomizedObjectNameAsStr = "ch.qos.logback." + diff + ":Name=" + lc.getName() + ",Type=" + this.getClass().getName();
-
- ObjectName objectName = MBeanUtil.string2ObjectName(lc, this, randomizedObjectNameAsStr);
- JMXConfigurator jmxConfigurator = new JMXConfigurator(lc, mbs, objectName);
- mbs.registerMBean(jmxConfigurator, objectName);
-
- listenerList = lc.getCopyOfListenerList();
- assertEquals(1, listenerList.size());
-
- lc.stop();
-
- // check that after lc.processPriorToRemoval, jmxConfigurator is no longer
- // registered as a listener in the loggerContext nor as an
- // MBean in mbs
- listenerList = lc.getCopyOfListenerList();
- assertEquals(0, listenerList.size());
-
- assertFalse(mbs.isRegistered(objectName));
- }
-
- @Test
- public void testNonRemovalOfPreviousIntanceFromTheContextListenerList() {
- String objectNameAsStr = "ch.qos.logback.toto" + ":Name=" + lc.getName() + ",Type=" + this.getClass().getName();
- ObjectName objectName = MBeanUtil.string2ObjectName(lc, this, objectNameAsStr);
- JMXConfigurator jmxConfigurator0 = new JMXConfigurator(lc, mbs, objectName);
-
- listenerList = lc.getCopyOfListenerList();
- assertTrue(listenerList.contains(jmxConfigurator0));
-
- JMXConfigurator jmxConfigurator1 = new JMXConfigurator(lc, mbs, objectName);
- listenerList = lc.getCopyOfListenerList();
- assertEquals(1, listenerList.size());
- assertTrue("old configurator should be present", listenerList.contains(jmxConfigurator0));
- assertFalse("new configurator should be absent", listenerList.contains(jmxConfigurator1));
- }
-
- @Test
- public void getLoggerLevel_LBCLASSIC_78() {
- String objectNameAsStr = "ch.qos" + diff + ":Name=" + lc.getName() + ",Type=" + this.getClass().getName();
-
- ObjectName on = MBeanUtil.string2ObjectName(lc, this, objectNameAsStr);
- JMXConfigurator configurator = new JMXConfigurator(lc, mbs, on);
- assertEquals("", configurator.getLoggerLevel(testLogger.getName()));
- MBeanUtil.unregister(lc, mbs, on, this);
- }
-
- @Test
- public void setLoggerLevel_LBCLASSIC_79() {
- String objectNameAsStr = "ch.qos" + diff + ":Name=" + lc.getName() + ",Type=" + this.getClass().getName();
-
- ObjectName on = MBeanUtil.string2ObjectName(lc, this, objectNameAsStr);
- JMXConfigurator configurator = new JMXConfigurator(lc, mbs, on);
- configurator.setLoggerLevel(testLogger.getName(), "DEBUG");
- assertEquals(Level.DEBUG, testLogger.getLevel());
-
- configurator.setLoggerLevel(testLogger.getName(), "null");
- assertNull(testLogger.getLevel());
-
- MBeanUtil.unregister(lc, mbs, on, this);
- }
-
- @Test
- public void testReloadDefaultConfiguration() throws Exception {
- String objectNameAsStr = "ch.qos" + diff + ":Name=" + lc.getName() + ",Type=" + this.getClass().getName();
-
- ObjectName on = MBeanUtil.string2ObjectName(lc, this, objectNameAsStr);
- JMXConfigurator configurator = new JMXConfigurator(lc, mbs, on);
- configurator.setLoggerLevel(testLogger.getName(), "DEBUG");
- assertEquals(Level.DEBUG, testLogger.getLevel());
-
- configurator.reloadDefaultConfiguration();
- assertNull(testLogger.getLevel());
- assertEquals(Level.DEBUG, lc.getLogger(ROOT_LOGGER_NAME).getLevel());
- MBeanUtil.unregister(lc, mbs, on, this);
- }
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ LoggerContext lc = new LoggerContext();
+ Logger testLogger = lc.getLogger(this.getClass());
+
+ List<LoggerContextListener> listenerList;
+ int diff = RandomUtil.getPositiveInt();
+
+
+ @Before
+ public void setUp() throws Exception {
+ lc.setName("context-" + diff);
+ assertNotNull(mbs);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ lc.stop();
+ }
+
+ @Override
+ public String toString() {
+ return this.getClass().getName() + "(" + lc.getName() + ")";
+ }
+
+ @Test
+ public void contextReset() throws Exception {
+ String randomizedObjectNameAsStr = "ch.qos.logback."+diff + ":Name=" + lc.getName()
+ + ",Type=" + this.getClass().getName();
+
+ ObjectName objectName = MBeanUtil.string2ObjectName(lc, this, randomizedObjectNameAsStr);
+ JMXConfigurator jmxConfigurator = new JMXConfigurator(lc, mbs, objectName);
+ mbs.registerMBean(jmxConfigurator, objectName);
+
+ listenerList = lc.getCopyOfListenerList();
+ assertEquals(1, listenerList.size());
+
+ lc.reset();
+
+ // check that after lc.reset, jmxConfigurator should still be
+ // registered as a listener in the loggerContext and also as an
+ // MBean in mbs
+ listenerList = lc.getCopyOfListenerList();
+ assertEquals(1, listenerList.size());
+ assertTrue(listenerList.contains(jmxConfigurator));
+
+ assertTrue(mbs.isRegistered(objectName));
+ }
+
+ @Test
+ public void contextStop() throws Exception {
+ String randomizedObjectNameAsStr = "ch.qos.logback."+diff + ":Name=" + lc.getName()
+ + ",Type=" + this.getClass().getName();
+
+ ObjectName objectName = MBeanUtil.string2ObjectName(lc, this, randomizedObjectNameAsStr);
+ JMXConfigurator jmxConfigurator = new JMXConfigurator(lc, mbs, objectName);
+ mbs.registerMBean(jmxConfigurator, objectName);
+
+ listenerList = lc.getCopyOfListenerList();
+ assertEquals(1, listenerList.size());
+
+ lc.stop();
+
+ // check that after lc.processPriorToRemoval, jmxConfigurator is no longer
+ // registered as a listener in the loggerContext nor as an
+ // MBean in mbs
+ listenerList = lc.getCopyOfListenerList();
+ assertEquals(0, listenerList.size());
+
+ assertFalse(mbs.isRegistered(objectName));
+ }
+
+ @Test
+ public void testNonRemovalOfPreviousIntanceFromTheContextListenerList() {
+ String objectNameAsStr = "ch.qos.logback.toto" + ":Name=" + lc.getName()
+ + ",Type=" + this.getClass().getName();
+ ObjectName objectName = MBeanUtil.string2ObjectName(lc, this, objectNameAsStr);
+ JMXConfigurator jmxConfigurator0 = new JMXConfigurator(lc, mbs, objectName);
+
+ listenerList = lc.getCopyOfListenerList();
+ assertTrue(listenerList.contains(jmxConfigurator0));
+
+ JMXConfigurator jmxConfigurator1 = new JMXConfigurator(lc, mbs, objectName);
+ listenerList = lc.getCopyOfListenerList();
+ assertEquals(1, listenerList.size());
+ assertTrue("old configurator should be present", listenerList
+ .contains(jmxConfigurator0));
+ assertFalse("new configurator should be absent", listenerList
+ .contains(jmxConfigurator1));
+ }
+
+ @Test
+ public void getLoggerLevel_LBCLASSIC_78() {
+ String objectNameAsStr = "ch.qos"+diff + ":Name=" + lc.getName()
+ + ",Type=" + this.getClass().getName();
+
+ ObjectName on = MBeanUtil.string2ObjectName(lc, this, objectNameAsStr);
+ JMXConfigurator configurator = new JMXConfigurator(lc, mbs, on);
+ assertEquals("", configurator.getLoggerLevel(testLogger.getName()));
+ MBeanUtil.unregister(lc, mbs, on, this);
+ }
+
+
+ @Test
+ public void setLoggerLevel_LBCLASSIC_79() {
+ String objectNameAsStr = "ch.qos"+diff + ":Name=" + lc.getName()
+ + ",Type=" + this.getClass().getName();
+
+ ObjectName on = MBeanUtil.string2ObjectName(lc, this, objectNameAsStr);
+ JMXConfigurator configurator = new JMXConfigurator(lc, mbs, on);
+ configurator.setLoggerLevel(testLogger.getName(), "DEBUG");
+ assertEquals(Level.DEBUG, testLogger.getLevel());
+
+ configurator.setLoggerLevel(testLogger.getName(), "null");
+ assertNull(testLogger.getLevel());
+
+ MBeanUtil.unregister(lc, mbs, on, this);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/jmx/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/jmx/PackageTest.java
index 9cdd3c9..3fb092c 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/jmx/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/jmx/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,12 +13,13 @@
*/
package ch.qos.logback.classic.jmx;
+
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses(JMXConfiguratorTest.class)
-public class PackageTest {
-
+public class PackageTest {
+
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/joran/EvaluatorJoranTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/joran/EvaluatorJoranTest.java
index bc06e27..b068c3a 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/joran/EvaluatorJoranTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/joran/EvaluatorJoranTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -32,76 +32,75 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.boolex.EvaluationException;
-import ch.qos.logback.core.boolex.EventEvaluator;
import ch.qos.logback.core.joran.spi.JoranException;
-public class EvaluatorJoranTest {
- @Test
- public void testSimpleEvaluator() throws NullPointerException, EvaluationException, JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- LoggerContext loggerContext = new LoggerContext();
- jc.setContext(loggerContext);
- jc.doConfigure(ClassicTestConstants.JORAN_INPUT_PREFIX + "simpleEvaluator.xml");
-
- @SuppressWarnings("unchecked")
- Map<String, EventEvaluator<?>> evalMap = (Map<String, EventEvaluator<?>>) loggerContext.getObject(CoreConstants.EVALUATOR_MAP);
- assertNotNull(evalMap);
- JaninoEventEvaluator evaluator = (JaninoEventEvaluator) evalMap.get("msgEval");
- assertNotNull(evaluator);
-
- Logger logger = loggerContext.getLogger("xx");
- ILoggingEvent event0 = new LoggingEvent("foo", logger, Level.DEBUG, "Hello world", null, null);
- assertTrue(evaluator.evaluate(event0));
-
- ILoggingEvent event1 = new LoggingEvent("foo", logger, Level.DEBUG, "random blurb", null, null);
- assertFalse(evaluator.evaluate(event1));
- }
-
- @Test
- public void testIgnoreMarker() throws NullPointerException, EvaluationException, JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- LoggerContext loggerContext = new LoggerContext();
- jc.setContext(loggerContext);
- jc.doConfigure(ClassicTestConstants.JORAN_INPUT_PREFIX + "ignore.xml");
-
- @SuppressWarnings("unchecked")
- Map<String, EventEvaluator<?>> evalMap = (Map<String, EventEvaluator<?>>) loggerContext.getObject(CoreConstants.EVALUATOR_MAP);
- assertNotNull(evalMap);
-
- Logger logger = loggerContext.getLogger("xx");
-
- JaninoEventEvaluator evaluator = (JaninoEventEvaluator) evalMap.get("IGNORE_EVAL");
- LoggingEvent event = new LoggingEvent("foo", logger, Level.DEBUG, "Hello world", null, null);
-
- Marker ignoreMarker = MarkerFactory.getMarker("IGNORE");
- event.setMarker(ignoreMarker);
- assertTrue(evaluator.evaluate(event));
-
- logger.debug("hello", new Exception("test"));
- logger.debug(ignoreMarker, "hello ignore", new Exception("test"));
-
- // logger.debug("hello", new Exception("test"));
-
- // StatusPrinter.print(loggerContext.getStatusManager());
- }
-
- @Test
- public void testMultipleConditionsInExpression() throws NullPointerException, EvaluationException {
- LoggerContext loggerContext = new LoggerContext();
- Logger logger = loggerContext.getLogger("xx");
- JaninoEventEvaluator ee = new JaninoEventEvaluator();
- ee.setName("testEval");
- ee.setContext(loggerContext);
- // &&
- // &&
- ee.setExpression("message.contains(\"stacktrace\") && message.contains(\"logging\")");
- ee.start();
- // StatusPrinter.print(loggerContext);
-
- String message = "stacktrace bla bla logging";
- ILoggingEvent event = new LoggingEvent(this.getClass().getName(), logger, Level.DEBUG, message, null, null);
-
- assertTrue(ee.evaluate(event));
- }
+public class EvaluatorJoranTest {
+
+ @Test
+ public void testSimpleEvaluator() throws NullPointerException, EvaluationException, JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ LoggerContext loggerContext = new LoggerContext();
+ jc.setContext(loggerContext);
+ jc.doConfigure(ClassicTestConstants.JORAN_INPUT_PREFIX + "simpleEvaluator.xml");
+
+
+ Map evalMap = (Map) loggerContext.getObject(CoreConstants.EVALUATOR_MAP);
+ assertNotNull(evalMap);
+ JaninoEventEvaluator evaluator = (JaninoEventEvaluator) evalMap.get("msgEval");
+ assertNotNull(evaluator);
+
+ Logger logger = loggerContext.getLogger("xx");
+ ILoggingEvent event0 = new LoggingEvent("foo", logger, Level.DEBUG, "Hello world", null, null);
+ assertTrue(evaluator.evaluate(event0));
+
+ ILoggingEvent event1 = new LoggingEvent("foo", logger, Level.DEBUG, "random blurb", null, null);
+ assertFalse(evaluator.evaluate(event1));
+ }
+
+ @Test
+ public void testIgnoreMarker() throws NullPointerException, EvaluationException, JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ LoggerContext loggerContext = new LoggerContext();
+ jc.setContext(loggerContext);
+ jc.doConfigure(ClassicTestConstants.JORAN_INPUT_PREFIX + "ignore.xml");
+
+ Map evalMap = (Map) loggerContext.getObject(CoreConstants.EVALUATOR_MAP);
+ assertNotNull(evalMap);
+
+ Logger logger = loggerContext.getLogger("xx");
+
+ JaninoEventEvaluator evaluator = (JaninoEventEvaluator) evalMap.get("IGNORE_EVAL");
+ LoggingEvent event = new LoggingEvent("foo", logger, Level.DEBUG, "Hello world",null, null);
+
+ Marker ignoreMarker = MarkerFactory.getMarker("IGNORE");
+ event.setMarker(ignoreMarker);
+ assertTrue(evaluator.evaluate(event));
+
+ logger.debug("hello", new Exception("test"));
+ logger.debug(ignoreMarker, "hello ignore", new Exception("test"));
+
+ //logger.debug("hello", new Exception("test"));
+
+ //StatusPrinter.print(loggerContext.getStatusManager());
+ }
+
+ @Test
+ public void testMultipleConditionsInExpression() throws NullPointerException, EvaluationException {
+ LoggerContext loggerContext = new LoggerContext();
+ Logger logger = loggerContext.getLogger("xx");
+ JaninoEventEvaluator ee = new JaninoEventEvaluator();
+ ee.setName("testEval");
+ ee.setContext(loggerContext);
+ //&&
+ //&&
+ ee.setExpression("message.contains(\"stacktrace\") && message.contains(\"logging\")");
+ ee.start();
+ //StatusPrinter.print(loggerContext);
+
+ String message = "stacktrace bla bla logging";
+ ILoggingEvent event = new LoggingEvent(this.getClass().getName(), logger, Level.DEBUG, message, null, null);
+
+ assertTrue(ee.evaluate(event));
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java
index d93f1cc..c3b7581 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,16 +13,18 @@
*/
package ch.qos.logback.classic.joran;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
+import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.concurrent.TimeUnit;
+import ch.qos.logback.classic.jul.JULHelper;
+import ch.qos.logback.core.pattern.parser.Parser;
+import ch.qos.logback.core.spi.ScanException;
+import ch.qos.logback.core.status.Status;
+import ch.qos.logback.core.testUtil.RandomUtil;
+import ch.qos.logback.core.util.CachingDateFormatter;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.MDC;
@@ -31,7 +33,6 @@ import ch.qos.logback.classic.ClassicTestConstants;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.jul.JULHelper;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.turbo.DebugUsersTurboFilter;
import ch.qos.logback.classic.turbo.NOPTurboFilter;
@@ -40,399 +41,425 @@ import ch.qos.logback.core.ConsoleAppender;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.encoder.LayoutWrappingEncoder;
import ch.qos.logback.core.joran.spi.JoranException;
-import ch.qos.logback.core.pattern.parser.Parser;
import ch.qos.logback.core.read.ListAppender;
-import ch.qos.logback.core.spi.ScanException;
-import ch.qos.logback.core.status.Status;
import ch.qos.logback.core.status.StatusChecker;
-import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.testUtil.StringListAppender;
-import ch.qos.logback.core.util.CachingDateFormatter;
-
-public class JoranConfiguratorTest {
- LoggerContext loggerContext = new LoggerContext();
- Logger logger = loggerContext.getLogger(this.getClass().getName());
- Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
- StatusChecker checker = new StatusChecker(loggerContext);
- int diff = RandomUtil.getPositiveInt();
-
- void configure(String file) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(loggerContext);
- loggerContext.putProperty("diff", "" + diff);
- jc.doConfigure(file);
- }
-
- @Test
- public void simpleList() throws JoranException {
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "simpleList.xml");
-
- Logger logger = loggerContext.getLogger(this.getClass().getName());
- Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
- ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
- assertEquals(0, listAppender.list.size());
- String msg = "hello world";
- logger.debug(msg);
- assertEquals(1, listAppender.list.size());
- ILoggingEvent le = (ILoggingEvent) listAppender.list.get(0);
- assertEquals(msg, le.getMessage());
- }
- @Test
- public void level() throws JoranException {
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "simpleLevel.xml");
- ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
- assertEquals(0, listAppender.list.size());
- String msg = "hello world";
- logger.debug(msg);
- assertEquals(0, listAppender.list.size());
- }
-
- @Test
- public void additivity() throws JoranException {
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "additivity.xml");
- Logger logger = loggerContext.getLogger("additivityTest");
- assertFalse(logger.isAdditive());
- }
-
- @Test
- public void rootLoggerLevelSettingBySystemProperty() throws JoranException {
- String propertyName = "logback.level";
-
- System.setProperty(propertyName, "INFO");
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "rootLevelByProperty.xml");
- // StatusPrinter.print(loggerContext);
- ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
- assertEquals(0, listAppender.list.size());
- String msg = "hello world";
- logger.debug(msg);
- assertEquals(0, listAppender.list.size());
- System.clearProperty(propertyName);
- }
-
- @Test
- public void loggerLevelSettingBySystemProperty() throws JoranException {
- String propertyName = "logback.level";
- System.setProperty(propertyName, "DEBUG");
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "loggerLevelByProperty.xml");
- // StatusPrinter.print(loggerContext);
- ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
- assertEquals(0, listAppender.list.size());
- String msg = "hello world";
- logger.debug(msg);
- assertEquals(1, listAppender.list.size());
- System.clearProperty(propertyName);
- }
-
- @Test
- public void appenderRefSettingBySystemProperty() throws JoranException {
- final String propertyName = "logback.appenderRef";
- System.setProperty(propertyName, "A");
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "appenderRefByProperty.xml");
- final Logger logger = loggerContext.getLogger("ch.qos.logback.classic.joran");
- final ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) logger.getAppender("A");
- assertEquals(0, listAppender.list.size());
- final String msg = "hello world";
- logger.info(msg);
- assertEquals(1, listAppender.list.size());
- System.clearProperty(propertyName);
- }
-
- @Test
- public void statusListener() throws JoranException {
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "statusListener.xml");
- }
-
- @Test
- public void contextRename() throws JoranException {
- loggerContext.setName(CoreConstants.DEFAULT_CONTEXT_NAME);
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "contextRename.xml");
- assertEquals("wombat", loggerContext.getName());
- }
-
- @Test
- public void eval() throws JoranException {
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "callerData.xml");
-
- String msg = "hello world";
- logger.debug("toto");
- logger.debug(msg);
-
- StringListAppender<ILoggingEvent> slAppender = (StringListAppender<ILoggingEvent>) loggerContext.getLogger("root").getAppender("STR_LIST");
- assertNotNull(slAppender);
- assertEquals(2, slAppender.strList.size());
- assertTrue(slAppender.strList.get(0).contains(" DEBUG - toto"));
-
- String str1 = slAppender.strList.get(1);
- assertTrue(str1.contains("Caller+0"));
- assertTrue(str1.contains(" DEBUG - hello world"));
- }
-
- @Test
- public void turboFilter() throws JoranException {
- // Although this test uses turbo filters, it only checks
- // that Joran can see the xml element and create
- // and place the relevant object correctly.
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "turbo.xml");
-
- TurboFilter filter = loggerContext.getTurboFilterList().get(0);
- assertTrue(filter instanceof NOPTurboFilter);
- }
+import static org.junit.Assert.*;
- @Test
- public void testTurboFilterWithStringList() throws JoranException {
- // Although this test uses turbo filters, it only checks
- // that Joran can see <user> elements, and behave correctly
- // that is call the addUser method and pass the correct values
- // to that method.
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "turbo2.xml");
-
- // StatusPrinter.print(loggerContext.getStatusManager());
-
- TurboFilter filter = loggerContext.getTurboFilterList().get(0);
- assertTrue(filter instanceof DebugUsersTurboFilter);
- DebugUsersTurboFilter dutf = (DebugUsersTurboFilter) filter;
- assertEquals(2, dutf.getUsers().size());
- }
-
- @Test
- public void testLevelFilter() throws JoranException {
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "levelFilter.xml");
-
- // StatusPrinter.print(loggerContext);
-
- logger.warn("hello");
- logger.error("to be ignored");
-
- ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
-
- assertNotNull(listAppender);
- assertEquals(1, listAppender.list.size());
- ILoggingEvent back = listAppender.list.get(0);
- assertEquals(Level.WARN, back.getLevel());
- assertEquals("hello", back.getMessage());
- }
-
- @Test
- public void testEvaluatorFilter() throws JoranException {
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "evaluatorFilter.xml");
-
- // StatusPrinter.print(loggerContext);
-
- logger.warn("hello");
- logger.error("to be ignored");
-
- ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
-
- assertNotNull(listAppender);
- assertEquals(1, listAppender.list.size());
- ILoggingEvent back = listAppender.list.get(0);
- assertEquals(Level.WARN, back.getLevel());
- assertEquals("hello", back.getMessage());
- }
-
- @Test
- public void testTurboDynamicThreshold() throws JoranException {
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "turboDynamicThreshold.xml");
-
- ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
- assertEquals(0, listAppender.list.size());
-
- // this one should be denied
- MDC.put("userId", "user1");
- logger.debug("hello user1");
- // this one should log
- MDC.put("userId", "user2");
- logger.debug("hello user2");
-
- assertEquals(1, listAppender.list.size());
- ILoggingEvent le = (ILoggingEvent) listAppender.list.get(0);
- assertEquals("hello user2", le.getMessage());
- }
+public class JoranConfiguratorTest {
- @Test
- public void testTurboDynamicThreshold2() throws JoranException {
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "turboDynamicThreshold2.xml");
-
- ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
- assertEquals(0, listAppender.list.size());
-
- // this one should log
- MDC.put("userId", "user1");
- logger.debug("hello user1");
- // this one should log
- MDC.put("userId", "user2");
- logger.debug("hello user2");
- // this one should fail
- MDC.put("userId", "user3");
- logger.debug("hello user3");
-
- assertEquals(2, listAppender.list.size());
- ILoggingEvent le = (ILoggingEvent) listAppender.list.get(0);
- assertEquals("hello user1", le.getMessage());
- le = (ILoggingEvent) listAppender.list.get(1);
- assertEquals("hello user2", le.getMessage());
- }
+ LoggerContext loggerContext = new LoggerContext();
+ Logger logger = loggerContext.getLogger(this.getClass().getName());
+ Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
+ StatusChecker checker = new StatusChecker(loggerContext);
+ int diff = RandomUtil.getPositiveInt();
- @Test
- public void timestamp() throws JoranException, IOException, InterruptedException {
+ void configure(String file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ loggerContext.putProperty("diff", "" + diff);
+ jc.doConfigure(file);
+ }
- String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "timestamp-context.xml";
- configure(configFileAsStr);
+ @Test
+ public void simpleList() throws JoranException {
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "simpleList.xml");
- String r = loggerContext.getProperty("testTimestamp");
- assertNotNull(r);
- CachingDateFormatter sdf = new CachingDateFormatter("yyyy-MM");
- String expected = sdf.format(System.currentTimeMillis());
- assertEquals("expected \"" + expected + "\" but got " + r, expected, r);
+ Logger logger = loggerContext.getLogger(this.getClass().getName());
+ Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
+ ListAppender listAppender = (ListAppender) root.getAppender("LIST");
+ assertEquals(0, listAppender.list.size());
+ String msg = "hello world";
+ logger.debug(msg);
+ assertEquals(1, listAppender.list.size());
+ ILoggingEvent le = (ILoggingEvent) listAppender.list.get(0);
+ assertEquals(msg, le.getMessage());
+ }
+
+ @Test
+ public void level() throws JoranException {
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "simpleLevel.xml");
+ ListAppender listAppender = (ListAppender) root.getAppender("LIST");
+ assertEquals(0, listAppender.list.size());
+ String msg = "hello world";
+ logger.debug(msg);
+ assertEquals(0, listAppender.list.size());
+ }
+
+ @Test
+ public void additivity() throws JoranException {
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "additivity.xml");
+ Logger logger = loggerContext.getLogger("additivityTest");
+ assertFalse(logger.isAdditive());
+ }
+
+ @Test
+ public void rootLoggerLevelSettingBySystemProperty() throws JoranException {
+ String propertyName = "logback.level";
+
+ System.setProperty(propertyName, "INFO");
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "rootLevelByProperty.xml");
+ // StatusPrinter.print(loggerContext);
+ ListAppender listAppender = (ListAppender) root.getAppender("LIST");
+ assertEquals(0, listAppender.list.size());
+ String msg = "hello world";
+ logger.debug(msg);
+ assertEquals(0, listAppender.list.size());
+ System.clearProperty(propertyName);
+ }
+
+ @Test
+ public void loggerLevelSettingBySystemProperty() throws JoranException {
+ String propertyName = "logback.level";
+ System.setProperty(propertyName, "DEBUG");
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "loggerLevelByProperty.xml");
+ // StatusPrinter.print(loggerContext);
+ ListAppender listAppender = (ListAppender) root.getAppender("LIST");
+ assertEquals(0, listAppender.list.size());
+ String msg = "hello world";
+ logger.debug(msg);
+ assertEquals(1, listAppender.list.size());
+ System.clearProperty(propertyName);
+ }
+
+ @Test
+ public void appenderRefSettingBySystemProperty() throws JoranException {
+ final String propertyName = "logback.appenderRef";
+ System.setProperty(propertyName, "A");
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "appenderRefByProperty.xml");
+ final Logger logger = loggerContext
+ .getLogger("ch.qos.logback.classic.joran");
+ final ListAppender listAppender = (ListAppender) logger.getAppender("A");
+ assertEquals(0, listAppender.list.size());
+ final String msg = "hello world";
+ logger.info(msg);
+ assertEquals(1, listAppender.list.size());
+ System.clearProperty(propertyName);
+ }
+
+ @Test
+ public void statusListener() throws JoranException {
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "statusListener.xml");
+ }
+
+ @Test
+ public void contextRename() throws JoranException {
+ loggerContext.setName(CoreConstants.DEFAULT_CONTEXT_NAME);
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "contextRename.xml");
+ assertEquals("wombat", loggerContext.getName());
+ }
+
+ @Test
+ public void eval() throws JoranException {
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "callerData.xml");
+
+ String msg = "hello world";
+ logger.debug("toto");
+ logger.debug(msg);
+
+ StringListAppender<ILoggingEvent> slAppender = (StringListAppender<ILoggingEvent>) loggerContext
+ .getLogger("root").getAppender("STR_LIST");
+ assertNotNull(slAppender);
+ assertEquals(2, slAppender.strList.size());
+ assertTrue(slAppender.strList.get(0).contains(" DEBUG - toto"));
+
+ String str1 = slAppender.strList.get(1);
+ assertTrue(str1.contains("Caller+0"));
+ assertTrue(str1.contains(" DEBUG - hello world"));
+ }
+
+ @Test
+ public void turboFilter() throws JoranException {
+ // Although this test uses turbo filters, it only checks
+ // that Joran can see the xml element and create
+ // and place the relevant object correctly.
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "turbo.xml");
+
+ TurboFilter filter = loggerContext.getTurboFilterList().get(0);
+ assertTrue(filter instanceof NOPTurboFilter);
+ }
+
+ @Test
+ public void testTurboFilterWithStringList() throws JoranException {
+ // Although this test uses turbo filters, it only checks
+ // that Joran can see <user> elements, and behave correctly
+ // that is call the addUser method and pass the correct values
+ // to that method.
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "turbo2.xml");
+
+ // StatusPrinter.print(loggerContext.getStatusManager());
+
+ TurboFilter filter = loggerContext.getTurboFilterList().get(0);
+ assertTrue(filter instanceof DebugUsersTurboFilter);
+ DebugUsersTurboFilter dutf = (DebugUsersTurboFilter) filter;
+ assertEquals(2, dutf.getUsers().size());
+ }
+
+ @Test
+ public void testLevelFilter() throws JoranException {
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "levelFilter.xml");
+
+ // StatusPrinter.print(loggerContext);
+
+ logger.warn("hello");
+ logger.error("to be ignored");
+
+ @SuppressWarnings("unchecked")
+ ListAppender<ILoggingEvent> listAppender = (ListAppender) root
+ .getAppender("LIST");
+
+ assertNotNull(listAppender);
+ assertEquals(1, listAppender.list.size());
+ ILoggingEvent back = listAppender.list.get(0);
+ assertEquals(Level.WARN, back.getLevel());
+ assertEquals("hello", back.getMessage());
+ }
+
+ @Test
+ public void testEvaluatorFilter() throws JoranException {
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "evaluatorFilter.xml");
+
+ // StatusPrinter.print(loggerContext);
+
+ logger.warn("hello");
+ logger.error("to be ignored");
+
+ @SuppressWarnings("unchecked")
+ ListAppender<ILoggingEvent> listAppender = (ListAppender) root
+ .getAppender("LIST");
+
+ assertNotNull(listAppender);
+ assertEquals(1, listAppender.list.size());
+ ILoggingEvent back = listAppender.list.get(0);
+ assertEquals(Level.WARN, back.getLevel());
+ assertEquals("hello", back.getMessage());
+ }
+
+ @Test
+ public void testTurboDynamicThreshold() throws JoranException {
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "turboDynamicThreshold.xml");
+
+ ListAppender listAppender = (ListAppender) root.getAppender("LIST");
+ assertEquals(0, listAppender.list.size());
+
+ // this one should be denied
+ MDC.put("userId", "user1");
+ logger.debug("hello user1");
+ // this one should log
+ MDC.put("userId", "user2");
+ logger.debug("hello user2");
+
+ assertEquals(1, listAppender.list.size());
+ ILoggingEvent le = (ILoggingEvent) listAppender.list.get(0);
+ assertEquals("hello user2", le.getMessage());
+ }
+
+ @Test
+ public void testTurboDynamicThreshold2() throws JoranException {
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "turboDynamicThreshold2.xml");
+
+ ListAppender listAppender = (ListAppender) root.getAppender("LIST");
+ assertEquals(0, listAppender.list.size());
+
+ // this one should log
+ MDC.put("userId", "user1");
+ logger.debug("hello user1");
+ // this one should log
+ MDC.put("userId", "user2");
+ logger.debug("hello user2");
+ // this one should fail
+ MDC.put("userId", "user3");
+ logger.debug("hello user3");
+
+ assertEquals(2, listAppender.list.size());
+ ILoggingEvent le = (ILoggingEvent) listAppender.list.get(0);
+ assertEquals("hello user1", le.getMessage());
+ le = (ILoggingEvent) listAppender.list.get(1);
+ assertEquals("hello user2", le.getMessage());
+ }
+
+ // Tests whether ConfigurationAction is installing ReconfigureOnChangeFilter
+ @Test
+ public void autoscanShouldReconfigureOnFileChange() throws Exception {
+
+ String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "scan1.xml";
+ configure(configFileAsStr);
+
+ File file = new File(configFileAsStr);
+ file.setLastModified(System.currentTimeMillis());
+
+ Thread.sleep(10);
+ // scanning requires 16 logs
+ for (int i = 0; i < 16; i++) {
+ logger.debug("after " + i);
}
- @Test
- public void timestampLocal() throws JoranException, IOException, InterruptedException {
+ loggerContext.getExecutorService().shutdown();
+ loggerContext.getExecutorService().awaitTermination(1000, TimeUnit.MILLISECONDS);
- String sysProp = "ch.qos.logback.classic.joran.JoranConfiguratorTest.timestampLocal";
- System.setProperty(sysProp, "");
+ StatusChecker checker = new StatusChecker(loggerContext);
+ checker.assertIsErrorFree();
+ checker.assertContainsMatch(CoreConstants.RESET_MSG_PREFIX);
+ }
- String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "timestamp-local.xml";
- configure(configFileAsStr);
+ @Test
+ public void timestamp() throws JoranException, IOException,
+ InterruptedException {
- // It's hard to test the local variable has been set, as it's not
- // visible from here. But instead we test that it's not set in the
- // context. And check that a system property has been replaced with the
- // contents of the local variable
+ String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "timestamp-context.xml";
+ configure(configFileAsStr);
- String r = loggerContext.getProperty("testTimestamp");
- assertNull(r);
+ String r = loggerContext.getProperty("testTimestamp");
+ assertNotNull(r);
+ CachingDateFormatter sdf = new CachingDateFormatter("yyyy-MM");
+ String expected = sdf.format(System.currentTimeMillis());
+ assertEquals("expected \"" + expected + "\" but got " + r, expected, r);
+ }
- String expected = "today is " + new SimpleDateFormat("yyyy-MM").format(new Date());
- String sysPropValue = System.getProperty(sysProp);
- assertEquals(expected, sysPropValue);
- }
+ @Test
+ public void timestampLocal() throws JoranException, IOException,
+ InterruptedException {
- @Test
- public void encoderCharset() throws JoranException, IOException, InterruptedException {
+ String sysProp = "ch.qos.logback.classic.joran.JoranConfiguratorTest.timestampLocal";
+ System.setProperty(sysProp, "");
- String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "encoderCharset.xml";
- configure(configFileAsStr);
+ String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "timestamp-local.xml";
+ configure(configFileAsStr);
- ConsoleAppender<ILoggingEvent> consoleAppender = (ConsoleAppender<ILoggingEvent>) root.getAppender("CONSOLE");
- assertNotNull(consoleAppender);
- LayoutWrappingEncoder<ILoggingEvent> encoder = (LayoutWrappingEncoder<ILoggingEvent>) consoleAppender.getEncoder();
+ // It's hard to test the local variable has been set, as it's not
+ // visible from here. But instead we test that it's not set in the
+ // context. And check that a system property has been replaced with the
+ // contents of the local variable
- assertEquals("UTF-8", encoder.getCharset().displayName());
+ String r = loggerContext.getProperty("testTimestamp");
+ assertNull(r);
- StatusChecker checker = new StatusChecker(loggerContext);
- checker.assertIsErrorFree();
- }
+ String expected = "today is " + new SimpleDateFormat("yyyy-MM").format(new Date());
+ String sysPropValue = System.getProperty(sysProp);
+ assertEquals(expected, sysPropValue);
+ }
- void verifyJULLevel(String loggerName, Level expectedLevel) {
- java.util.logging.Logger julLogger = JULHelper.asJULLogger(loggerName);
- java.util.logging.Level julLevel = julLogger.getLevel();
+ @Test
+ public void encoderCharset() throws JoranException, IOException,
+ InterruptedException {
- if (expectedLevel == null) {
- assertNull(julLevel);
- } else {
- assertEquals(JULHelper.asJULLevel(expectedLevel), julLevel);
- }
+ String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "encoderCharset.xml";
+ configure(configFileAsStr);
- }
-
- @Test
- public void levelChangePropagator0() throws JoranException, IOException, InterruptedException {
- String loggerName = "changePropagator0" + diff;
- java.util.logging.Logger.getLogger(loggerName).setLevel(java.util.logging.Level.INFO);
- String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "/jul/levelChangePropagator0.xml";
- configure(configFileAsStr);
- StatusChecker checker = new StatusChecker(loggerContext);
- checker.assertIsErrorFree();
- verifyJULLevel(loggerName, null);
- verifyJULLevel("a.b.c." + diff, Level.WARN);
- verifyJULLevel(Logger.ROOT_LOGGER_NAME, Level.TRACE);
- }
-
- @Test
- public void levelChangePropagator1() throws JoranException, IOException, InterruptedException {
- String loggerName = "changePropagator1" + diff;
- java.util.logging.Logger logger1 = java.util.logging.Logger.getLogger(loggerName);
- logger1.setLevel(java.util.logging.Level.INFO);
- verifyJULLevel(loggerName, Level.INFO);
- String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "/jul/levelChangePropagator1.xml";
- configure(configFileAsStr);
- StatusChecker checker = new StatusChecker(loggerContext);
- checker.assertIsErrorFree();
- verifyJULLevel(loggerName, Level.INFO); //
- verifyJULLevel("a.b.c." + diff, Level.WARN);
- verifyJULLevel(Logger.ROOT_LOGGER_NAME, Level.TRACE);
- }
+ ConsoleAppender<ILoggingEvent> consoleAppender = (ConsoleAppender<ILoggingEvent>) root.getAppender("CONSOLE");
+ assertNotNull(consoleAppender);
+ LayoutWrappingEncoder<ILoggingEvent> encoder = (LayoutWrappingEncoder<ILoggingEvent>) consoleAppender.getEncoder();
- @Test
- @Ignore
- public void onConsoleRetro() throws JoranException, IOException, InterruptedException {
- String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "/onConsoleRetro.xml";
- configure(configFileAsStr);
- System.out.println("xxxxxxxxxxxxx");
- Thread.sleep(400);
+ assertEquals("UTF-8", encoder.getCharset().displayName());
- loggerContext.reset();
- configure(configFileAsStr);
- }
+ StatusChecker checker = new StatusChecker(loggerContext);
+ checker.assertIsErrorFree();
+ }
- @Test
- public void lbcore193() throws JoranException {
- String configFileAsStr = ClassicTestConstants.ISSUES_PREFIX + "lbcore193.xml";
- configure(configFileAsStr);
- checker.asssertContainsException(ScanException.class);
- checker.assertContainsMatch(Status.ERROR, "Expecting RIGHT_PARENTHESIS token but got null");
- checker.assertContainsMatch(Status.ERROR, "See also " + Parser.MISSING_RIGHT_PARENTHESIS);
- }
+ void verifyJULLevel(String loggerName, Level expectedLevel) {
+ java.util.logging.Logger julLogger = JULHelper.asJULLogger(loggerName);
+ java.util.logging.Level julLevel = julLogger.getLevel();
- @Test
- public void properties() throws JoranException {
- String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "properties.xml";
- assertNull(loggerContext.getProperty(CoreConstants.HOSTNAME_KEY));
- assertNull(System.getProperty("sys"));
-
- configure(configFileAsStr);
- assertNotNull(loggerContext.getProperty(CoreConstants.HOSTNAME_KEY));
- assertNull(loggerContext.getProperty("transientKey1"));
- assertNull(loggerContext.getProperty("transientKey2"));
- assertEquals("node0", loggerContext.getProperty("nodeId"));
- assertEquals("tem", System.getProperty("sys"));
- assertNotNull(loggerContext.getProperty("path"));
- checker.assertIsErrorFree();
+ if (expectedLevel == null) {
+ assertNull(julLevel);
+ } else {
+ assertEquals(JULHelper.asJULLevel(expectedLevel), julLevel);
}
- // see also http://jira.qos.ch/browse/LBCORE-254
- @Test
- public void sysProps() throws JoranException {
- System.setProperty("k.lbcore254", ClassicTestConstants.ISSUES_PREFIX + "lbcore254");
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(loggerContext);
- configurator.doConfigure(ClassicTestConstants.ISSUES_PREFIX + "lbcore254.xml");
-
- checker.assertIsErrorFree();
- }
- @Test
- public void packageDataDisabledByConfigAttribute() throws JoranException {
- String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "packagingDataDisabled.xml";
- configure(configFileAsStr);
- assertFalse(loggerContext.isPackagingDataEnabled());
- }
+ }
- @Test
- public void packageDataEnabledByConfigAttribute() throws JoranException {
- String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "packagingDataEnabled.xml";
- configure(configFileAsStr);
- assertTrue(loggerContext.isPackagingDataEnabled());
- }
-
-
- @Test
- public void valueOfConvention() throws JoranException {
- String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "valueOfConvention.xml";
- configure(configFileAsStr);
- checker.assertIsWarningOrErrorFree();
- }
+ @Test
+ public void levelChangePropagator0() throws JoranException, IOException,
+ InterruptedException {
+ String loggerName = "changePropagator0" + diff;
+ java.util.logging.Logger.getLogger(loggerName).setLevel(java.util.logging.Level.INFO);
+ String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "/jul/levelChangePropagator0.xml";
+ configure(configFileAsStr);
+ StatusChecker checker = new StatusChecker(loggerContext);
+ checker.assertIsErrorFree();
+ verifyJULLevel(loggerName, null);
+ verifyJULLevel("a.b.c." + diff, Level.WARN);
+ verifyJULLevel(Logger.ROOT_LOGGER_NAME, Level.TRACE);
+ }
+
+ @Test
+ public void levelChangePropagator1() throws JoranException, IOException,
+ InterruptedException {
+ String loggerName = "changePropagator1" + diff;
+ java.util.logging.Logger.getLogger(loggerName).setLevel(java.util.logging.Level.INFO);
+ verifyJULLevel(loggerName, Level.INFO);
+ String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "/jul/levelChangePropagator1.xml";
+ configure(configFileAsStr);
+ StatusChecker checker = new StatusChecker(loggerContext);
+ checker.assertIsErrorFree();
+ verifyJULLevel(loggerName, Level.INFO);
+ verifyJULLevel("a.b.c." + diff, Level.WARN);
+ verifyJULLevel(Logger.ROOT_LOGGER_NAME, Level.TRACE);
+ }
+
+ @Test
+ @Ignore
+ public void onConsoleRetro() throws JoranException, IOException, InterruptedException {
+ String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "/onConsoleRetro.xml";
+ configure(configFileAsStr);
+ System.out.println("xxxxxxxxxxxxx");
+ Thread.sleep(400);
+
+ loggerContext.reset();
+ configure(configFileAsStr);
+ }
+
+ @Test
+ public void lbcore193() throws JoranException {
+ String configFileAsStr = ClassicTestConstants.ISSUES_PREFIX + "lbcore193.xml";
+ configure(configFileAsStr);
+ checker.asssertContainsException(ScanException.class);
+ checker.assertContainsMatch(Status.ERROR, "Expecting RIGHT_PARENTHESIS token but got null");
+ checker.assertContainsMatch(Status.ERROR, "See also " + Parser.MISSING_RIGHT_PARENTHESIS);
+ }
+
+
+ @Test
+ public void properties() throws JoranException {
+ String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "properties.xml";
+ assertNull(loggerContext.getProperty(CoreConstants.HOSTNAME_KEY));
+ assertNull(System.getProperty("sys"));
+
+ configure(configFileAsStr);
+ assertNotNull(loggerContext.getProperty(CoreConstants.HOSTNAME_KEY));
+ assertNull(loggerContext.getProperty("transientKey1"));
+ assertNull(loggerContext.getProperty("transientKey2"));
+ assertEquals("node0", loggerContext.getProperty("nodeId"));
+ assertEquals("tem", System.getProperty("sys"));
+ assertNotNull(loggerContext.getProperty("path"));
+ checker.assertIsErrorFree();
+ }
+
+
+ // see also http://jira.qos.ch/browse/LBCORE-254
+ @Test
+ public void sysProps() throws JoranException {
+ System.setProperty("k.lbcore254", ClassicTestConstants.ISSUES_PREFIX + "lbcore254");
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(loggerContext);
+ configurator.doConfigure(ClassicTestConstants.ISSUES_PREFIX + "lbcore254.xml");
+
+ checker.assertIsErrorFree();
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/joran/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/joran/PackageTest.java
index ed24dd6..f4688c4 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/joran/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/joran/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,7 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ JoranConfiguratorTest.class, EvaluatorJoranTest.class, ch.qos.logback.classic.joran.conditional.PackageTest.class })
+ at SuiteClasses( { JoranConfiguratorTest.class, EvaluatorJoranTest.class,
+ ch.qos.logback.classic.joran.conditional.PackageTest.class })
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/joran/ReconfigureOnChangeTaskTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/joran/ReconfigureOnChangeTaskTest.java
deleted file mode 100644
index 33a965f..0000000
--- a/logback-classic/src/test/java/ch/qos/logback/classic/joran/ReconfigureOnChangeTaskTest.java
+++ /dev/null
@@ -1,472 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.classic.joran;
-
-import static ch.qos.logback.classic.ClassicTestConstants.JORAN_INPUT_PREFIX;
-import static ch.qos.logback.classic.joran.ReconfigureOnChangeTask.DETECTED_CHANGE_IN_CONFIGURATION_FILES;
-import static ch.qos.logback.classic.joran.ReconfigureOnChangeTask.FALLING_BACK_TO_SAFE_CONFIGURATION;
-import static ch.qos.logback.classic.joran.ReconfigureOnChangeTask.RE_REGISTERING_PREVIOUS_SAFE_CONFIGURATION;
-import static ch.qos.logback.core.CoreConstants.RECONFIGURE_ON_CHANGE_TASK;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ScheduledFuture;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.gaffer.GafferConfigurator;
-import ch.qos.logback.classic.issue.lbclassic135.LoggingRunnable;
-import ch.qos.logback.core.CoreConstants;
-import ch.qos.logback.core.contention.AbstractMultiThreadedHarness;
-import ch.qos.logback.core.contention.RunnableWithCounterAndDone;
-import ch.qos.logback.core.joran.spi.ConfigurationWatchList;
-import ch.qos.logback.core.joran.spi.JoranException;
-import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
-import ch.qos.logback.core.status.InfoStatus;
-import ch.qos.logback.core.status.Status;
-import ch.qos.logback.core.status.StatusChecker;
-import ch.qos.logback.core.testUtil.FileTestUtil;
-import ch.qos.logback.core.testUtil.RandomUtil;
-import ch.qos.logback.core.util.CoreTestConstants;
-import ch.qos.logback.core.util.StatusPrinter;
-
-public class ReconfigureOnChangeTaskTest {
- final static int THREAD_COUNT = 5;
-
- int diff = RandomUtil.getPositiveInt();
-
- // the space in the file name mandated by
- // http://jira.qos.ch/browse/LBCORE-119
- final static String SCAN1_FILE_AS_STR = JORAN_INPUT_PREFIX + "roct/scan 1.xml";
-
- final static String G_SCAN1_FILE_AS_STR = JORAN_INPUT_PREFIX + "roct/scan 1.groovy";
-
- final static String SCAN_LOGBACK_474_FILE_AS_STR = JORAN_INPUT_PREFIX + "roct/scan_logback_474.xml";
-
- final static String INCLUSION_SCAN_TOPLEVEL0_AS_STR = JORAN_INPUT_PREFIX + "roct/inclusion/topLevel0.xml";
-
- final static String INCLUSION_SCAN_TOP_BY_RESOURCE_AS_STR = JORAN_INPUT_PREFIX + "roct/inclusion/topByResource.xml";
-
- final static String INCLUSION_SCAN_INNER0_AS_STR = JORAN_INPUT_PREFIX + "roct/inclusion/inner0.xml";
-
- final static String INCLUSION_SCAN_INNER1_AS_STR = "target/test-classes/asResource/inner1.xml";
-
- LoggerContext loggerContext = new LoggerContext();
- Logger logger = loggerContext.getLogger(this.getClass());
- StatusChecker statusChecker = new StatusChecker(loggerContext);
-
- @BeforeClass
- static public void classSetup() {
- FileTestUtil.makeTestOutputDir();
- }
-
- void configure(File file) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(loggerContext);
- jc.doConfigure(file);
- }
-
- void configure(InputStream is) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(loggerContext);
- jc.doConfigure(is);
- }
-
- void gConfigure(File file) throws JoranException {
- GafferConfigurator gc = new GafferConfigurator(loggerContext);
- gc.run(file);
- }
-
- @Test(timeout = 4000L)
- public void checkBasicLifecyle() throws JoranException, IOException, InterruptedException {
- File file = new File(SCAN1_FILE_AS_STR);
- configure(file);
- List<File> fileList = getConfigurationWatchList(loggerContext);
- assertThatListContainsFile(fileList, file);
- checkThatTaskHasRan();
- checkThatTaskCanBeStopped();
- }
-
- @Test(timeout = 4000L)
- public void checkBasicLifecyleWithGaffer() throws JoranException, IOException, InterruptedException {
- File file = new File(G_SCAN1_FILE_AS_STR);
- gConfigure(file);
- List<File> fileList = getConfigurationWatchList(loggerContext);
- assertThatListContainsFile(fileList, file);
- checkThatTaskHasRan();
- checkThatTaskCanBeStopped();
- }
-
- private void checkThatTaskCanBeStopped() {
- ScheduledFuture<?> future = loggerContext.getScheduledFutures().get(0);
- loggerContext.stop();
- assertTrue(future.isCancelled());
- }
-
- private void checkThatTaskHasRan() throws InterruptedException {
- waitForReconfigureOnChangeTaskToRun();
- }
-
- List<File> getConfigurationWatchList(LoggerContext context) {
- ConfigurationWatchList configurationWatchList = ConfigurationWatchListUtil.getConfigurationWatchList(loggerContext);
- return configurationWatchList.getCopyOfFileWatchList();
- }
-
- @Test(timeout = 4000L)
- public void scanWithFileInclusion() throws JoranException, IOException, InterruptedException {
- File topLevelFile = new File(INCLUSION_SCAN_TOPLEVEL0_AS_STR);
- File innerFile = new File(INCLUSION_SCAN_INNER0_AS_STR);
- configure(topLevelFile);
- List<File> fileList = getConfigurationWatchList(loggerContext);
- assertThatListContainsFile(fileList, topLevelFile);
- assertThatListContainsFile(fileList, innerFile);
- checkThatTaskHasRan();
- checkThatTaskCanBeStopped();
- }
-
- @Test(timeout = 4000L)
- public void scanWithResourceInclusion() throws JoranException, IOException, InterruptedException {
- File topLevelFile = new File(INCLUSION_SCAN_TOP_BY_RESOURCE_AS_STR);
- File innerFile = new File(INCLUSION_SCAN_INNER1_AS_STR);
- configure(topLevelFile);
- List<File> fileList = getConfigurationWatchList(loggerContext);
- assertThatListContainsFile(fileList, topLevelFile);
- assertThatListContainsFile(fileList, innerFile);
- }
-
- // See also http://jira.qos.ch/browse/LOGBACK-338
- @Test(timeout = 4000L)
- public void reconfigurationIsNotPossibleInTheAbsenceOfATopFile() throws IOException, JoranException, InterruptedException {
- String configurationStr = "<configuration scan=\"true\" scanPeriod=\"50 millisecond\"><include resource=\"asResource/inner1.xml\"/></configuration>";
- configure(new ByteArrayInputStream(configurationStr.getBytes("UTF-8")));
-
- ConfigurationWatchList configurationWatchList = ConfigurationWatchListUtil.getConfigurationWatchList(loggerContext);
- assertNull(configurationWatchList);
- // assertNull(configurationWatchList.getMainURL());
-
- statusChecker.containsMatch(Status.WARN, "Due to missing top level");
- StatusPrinter.print(loggerContext);
- ReconfigureOnChangeTask roct = getRegisteredReconfigureTask();
- assertNull(roct);
- assertEquals(0, loggerContext.getScheduledFutures().size());
- }
-
- @Test(timeout = 3000L)
- public void fallbackToSafe_FollowedByRecovery() throws IOException, JoranException, InterruptedException {
- String path = CoreTestConstants.OUTPUT_DIR_PREFIX + "reconfigureOnChangeConfig_fallbackToSafe-" + diff + ".xml";
- File topLevelFile = new File(path);
- writeToFile(topLevelFile, "<configuration scan=\"true\" scanPeriod=\"5 millisecond\"><root level=\"ERROR\"/></configuration> ");
- configure(topLevelFile);
- CountDownLatch changeDetectedLatch = waitForReconfigurationToBeDone(null);
- ReconfigureOnChangeTask oldRoct = getRegisteredReconfigureTask();
- assertNotNull(oldRoct);
- writeToFile(topLevelFile, "<configuration scan=\"true\" scanPeriod=\"5 millisecond\">\n" + " <root></configuration>");
- changeDetectedLatch.await();
- statusChecker.assertContainsMatch(Status.WARN, FALLING_BACK_TO_SAFE_CONFIGURATION);
- statusChecker.assertContainsMatch(Status.INFO, RE_REGISTERING_PREVIOUS_SAFE_CONFIGURATION);
-
- loggerContext.getStatusManager().clear();
-
- CountDownLatch secondDoneLatch = waitForReconfigurationToBeDone(oldRoct);
- writeToFile(topLevelFile, "<configuration scan=\"true\" scanPeriod=\"5 millisecond\"><root level=\"ERROR\"/></configuration> ");
- secondDoneLatch.await();
- StatusPrinter.print(loggerContext);
- statusChecker.assertIsErrorFree();
- statusChecker.containsMatch(DETECTED_CHANGE_IN_CONFIGURATION_FILES);
- }
-
- @Test(timeout = 4000L)
- public void fallbackToSafeWithIncludedFile_FollowedByRecovery() throws IOException, JoranException, InterruptedException, ExecutionException {
- String topLevelFileAsStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "reconfigureOnChangeConfig_top-" + diff + ".xml";
- String innerFileAsStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "reconfigureOnChangeConfig_inner-" + diff + ".xml";
- File topLevelFile = new File(topLevelFileAsStr);
- writeToFile(topLevelFile, "<configuration xdebug=\"true\" scan=\"true\" scanPeriod=\"5 millisecond\"><include file=\"" + innerFileAsStr
- + "\"/></configuration> ");
-
- File innerFile = new File(innerFileAsStr);
- writeToFile(innerFile, "<included><root level=\"ERROR\"/></included> ");
- configure(topLevelFile);
-
- CountDownLatch doneLatch = waitForReconfigurationToBeDone(null);
- ReconfigureOnChangeTask oldRoct = getRegisteredReconfigureTask();
- assertNotNull(oldRoct);
-
- writeToFile(innerFile, "<included>\n<root>\n</included>");
- doneLatch.await();
-
- statusChecker.assertContainsMatch(Status.WARN, FALLING_BACK_TO_SAFE_CONFIGURATION);
- statusChecker.assertContainsMatch(Status.INFO, RE_REGISTERING_PREVIOUS_SAFE_CONFIGURATION);
-
- loggerContext.getStatusManager().clear();
-
- CountDownLatch secondDoneLatch = waitForReconfigurationToBeDone(oldRoct);
- writeToFile(innerFile, "<included><root level=\"ERROR\"/></included> ");
- secondDoneLatch.await();
-
- StatusPrinter.print(loggerContext);
- statusChecker.assertIsErrorFree();
- statusChecker.containsMatch(DETECTED_CHANGE_IN_CONFIGURATION_FILES);
- }
-
- private ReconfigureOnChangeTask getRegisteredReconfigureTask() {
- return (ReconfigureOnChangeTask) loggerContext.getObject(RECONFIGURE_ON_CHANGE_TASK);
- }
-
- class RunMethodInvokedListener extends ReconfigureOnChangeTaskListener {
- CountDownLatch countDownLatch;
-
- RunMethodInvokedListener(CountDownLatch countDownLatch) {
- this.countDownLatch = countDownLatch;
- }
-
- @Override
- public void enteredRunMethod() {
- countDownLatch.countDown();
- }
- };
-
- class ChangeDetectedListener extends ReconfigureOnChangeTaskListener {
- CountDownLatch countDownLatch;
-
- ChangeDetectedListener(CountDownLatch countDownLatch) {
- this.countDownLatch = countDownLatch;
- }
-
- @Override
- public void changeDetected() {
- countDownLatch.countDown();
- }
- };
-
- class ReconfigurationDoneListener extends ReconfigureOnChangeTaskListener {
- CountDownLatch countDownLatch;
-
- ReconfigurationDoneListener(CountDownLatch countDownLatch) {
- this.countDownLatch = countDownLatch;
- }
-
- @Override
- public void doneReconfiguring() {
- countDownLatch.countDown();
- }
- };
-
- private ReconfigureOnChangeTask waitForReconfigureOnChangeTaskToRun() throws InterruptedException {
- ReconfigureOnChangeTask roct = null;
- while (roct == null) {
- roct = getRegisteredReconfigureTask();
- Thread.yield();
- }
-
- CountDownLatch countDownLatch = new CountDownLatch(1);
- roct.addListener(new RunMethodInvokedListener(countDownLatch));
- countDownLatch.await();
- return roct;
- }
-
- private CountDownLatch waitForReconfigurationToBeDone(ReconfigureOnChangeTask oldTask) throws InterruptedException {
- ReconfigureOnChangeTask roct = oldTask;
- while (roct == oldTask) {
- roct = getRegisteredReconfigureTask();
- Thread.yield();
- }
-
- CountDownLatch countDownLatch = new CountDownLatch(1);
- roct.addListener(new ReconfigurationDoneListener(countDownLatch));
- return countDownLatch;
- }
-
- private RunnableWithCounterAndDone[] buildRunnableArray(File configFile, UpdateType updateType) {
- RunnableWithCounterAndDone[] rArray = new RunnableWithCounterAndDone[THREAD_COUNT];
- rArray[0] = new Updater(configFile, updateType);
- for (int i = 1; i < THREAD_COUNT; i++) {
- rArray[i] = new LoggingRunnable(logger);
- }
- return rArray;
- }
-
- // check for deadlocks
- @Test(timeout = 4000L)
- public void scan_LOGBACK_474() throws JoranException, IOException, InterruptedException {
- loggerContext.setName("scan_LOGBACK_474");
- File file = new File(SCAN_LOGBACK_474_FILE_AS_STR);
- // StatusListenerConfigHelper.addOnConsoleListenerInstance(loggerContext, new OnConsoleStatusListener());
- configure(file);
-
- // ReconfigureOnChangeTask roct = waitForReconfigureOnChangeTaskToRun();
-
- int expectedResets = 2;
- Harness harness = new Harness(expectedResets);
-
- RunnableWithCounterAndDone[] runnableArray = buildRunnableArray(file, UpdateType.TOUCH);
- harness.execute(runnableArray);
-
- loggerContext.getStatusManager().add(new InfoStatus("end of execution ", this));
- StatusPrinter.print(loggerContext);
- checkResetCount(expectedResets);
- }
-
- private void assertThatListContainsFile(List<File> fileList, File file) {
- // conversion to absolute file seems to work nicely
- assertTrue(fileList.contains(file.getAbsoluteFile()));
- }
-
- private void checkResetCount(int expected) {
- StatusChecker checker = new StatusChecker(loggerContext);
- checker.assertIsErrorFree();
-
- int effectiveResets = checker.matchCount(CoreConstants.RESET_MSG_PREFIX);
- assertEquals(expected, effectiveResets);
-
- // String failMsg = "effective=" + effectiveResets + ", expected=" + expected;
- //
- // there might be more effective resets than the expected amount
- // since the harness may be sleeping while a reset occurs
- // assertTrue(failMsg, expected <= effectiveResets && (expected + 2) >= effectiveResets);
-
- }
-
- void addInfo(String msg, Object o) {
- loggerContext.getStatusManager().add(new InfoStatus(msg, o));
- }
-
- enum UpdateType {
- TOUCH, MALFORMED, MALFORMED_INNER
- }
-
- void writeToFile(File file, String contents) throws IOException {
- FileWriter fw = new FileWriter(file);
- fw.write(contents);
- fw.close();
- // on linux changes to last modified are not propagated if the
- // time stamp is near the previous time stamp hence the random delta
- file.setLastModified(System.currentTimeMillis()+RandomUtil.getPositiveInt());
- }
-
- class Harness extends AbstractMultiThreadedHarness {
- int changeCountLimit;
-
- Harness(int changeCount) {
- this.changeCountLimit = changeCount;
- }
-
- public void waitUntilEndCondition() throws InterruptedException {
- ReconfigureOnChangeTaskTest.this.addInfo("Entering " + this.getClass() + ".waitUntilEndCondition()", this);
-
- int changeCount = 0;
- ReconfigureOnChangeTask lastRoct = null;
- CountDownLatch countDownLatch = null;
-
- while (changeCount < changeCountLimit) {
- ReconfigureOnChangeTask roct = (ReconfigureOnChangeTask) loggerContext.getObject(RECONFIGURE_ON_CHANGE_TASK);
- if (lastRoct != roct && roct != null) {
- lastRoct = roct;
- countDownLatch = new CountDownLatch(1);
- roct.addListener(new ChangeDetectedListener(countDownLatch));
- } else if (countDownLatch != null) {
- countDownLatch.await();
- countDownLatch = null;
- changeCount++;
- }
- Thread.yield();
- }
- ReconfigureOnChangeTaskTest.this.addInfo("*****Exiting " + this.getClass() + ".waitUntilEndCondition()", this);
- }
-
- }
-
- class Updater extends RunnableWithCounterAndDone {
- File configFile;
- UpdateType updateType;
-
- // it actually takes time for Windows to propagate file modification changes
- // values below 100 milliseconds can be problematic the same propagation
- // latency occurs in Linux but is even larger (>600 ms)
- // final static int DEFAULT_SLEEP_BETWEEN_UPDATES = 60;
-
- int sleepBetweenUpdates = 100;
-
- Updater(File configFile, UpdateType updateType) {
- this.configFile = configFile;
- this.updateType = updateType;
- }
-
- Updater(File configFile) {
- this(configFile, UpdateType.TOUCH);
- }
-
- public void run() {
- while (!isDone()) {
- try {
- Thread.sleep(sleepBetweenUpdates);
- } catch (InterruptedException e) {
- }
- if (isDone()) {
- ReconfigureOnChangeTaskTest.this.addInfo("Exiting Updater.run()", this);
- return;
- }
- counter++;
- ReconfigureOnChangeTaskTest.this.addInfo("Touching [" + configFile + "]", this);
- switch (updateType) {
- case TOUCH:
- touchFile();
- break;
- case MALFORMED:
- try {
- malformedUpdate();
- } catch (IOException e) {
- e.printStackTrace();
- fail("malformedUpdate failed");
- }
- break;
- case MALFORMED_INNER:
- try {
- malformedInnerUpdate();
- } catch (IOException e) {
- e.printStackTrace();
- fail("malformedInnerUpdate failed");
- }
- }
- }
- ReconfigureOnChangeTaskTest.this.addInfo("Exiting Updater.run()", this);
- }
-
- private void malformedUpdate() throws IOException {
- writeToFile(configFile, "<configuration scan=\"true\" scanPeriod=\"50 millisecond\">\n" + " <root level=\"ERROR\">\n" + "</configuration>");
- }
-
- private void malformedInnerUpdate() throws IOException {
- writeToFile(configFile, "<included>\n" + " <root>\n" + "</included>");
- }
-
- void touchFile() {
- configFile.setLastModified(System.currentTimeMillis());
- }
- }
-
-}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java
index 431243f..fbac410 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -40,106 +40,116 @@ import ch.qos.logback.core.util.StatusPrinter;
public class ConditionalTest {
- LoggerContext context = new LoggerContext();
- Logger root = context.getLogger(Logger.ROOT_LOGGER_NAME);
-
- int diff = RandomUtil.getPositiveInt();
- String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "/";
-
- @Before
- public void setUp() throws UnknownHostException {
- context.setName("c" + diff);
- context.putProperty("randomOutputDir", randomOutputDir);
- }
-
- @After
- public void tearDown() {
- StatusPrinter.printIfErrorsOccured(context);
- }
-
- void configure(String file) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(context);
- jc.doConfigure(file);
- }
-
- @SuppressWarnings("rawtypes")
- @Test
- public void conditionalConsoleApp_IF_THEN_True() throws JoranException, IOException, InterruptedException {
- InetAddress localhost = InetAddress.getLocalHost();
- System.out.println("In conditionalConsoleApp_IF_THEN_True, canonicalHostName=\"" + localhost.getCanonicalHostName() + "] and hostNmae=\""
- + localhost.getHostName() + "\"");
- context.putProperty("aHost", localhost.getHostName());
-
- String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "conditional/conditionalConsoleApp.xml";
- configure(configFileAsStr);
- FileAppender fileAppender = (FileAppender) root.getAppender("FILE");
- assertNotNull(fileAppender);
-
- ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
- assertNotNull(consoleAppender);
- StatusChecker checker = new StatusChecker(context);
- checker.assertIsErrorFree();
- }
-
- @SuppressWarnings("rawtypes")
- @Test
- public void conditionalConsoleApp_IF_THEN_False() throws JoranException, IOException, InterruptedException {
-
- String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "conditional/conditionalConsoleApp.xml";
- configure(configFileAsStr);
- FileAppender fileAppender = (FileAppender) root.getAppender("FILE");
- assertNotNull(fileAppender);
-
- ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
- assertNull(consoleAppender);
- StatusChecker checker = new StatusChecker(context);
- checker.assertIsErrorFree();
- }
-
- @SuppressWarnings("rawtypes")
- @Test
- public void conditionalConsoleApp_IF_THEN_ELSE() throws JoranException, IOException, InterruptedException {
-
- String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "conditional/conditionalConsoleApp_ELSE.xml";
- configure(configFileAsStr);
-
- FileAppender fileAppender = (FileAppender) root.getAppender("FILE");
- assertNotNull(fileAppender);
-
- ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
- assertNull(consoleAppender);
-
- ListAppender listAppender = (ListAppender) root.getAppender("LIST");
- assertNotNull(listAppender);
-
- // StatusPrinter.printIfErrorsOccured(context);
- StatusChecker checker = new StatusChecker(context);
- checker.assertIsErrorFree();
- }
-
- @Test
- public void conditionalInclusionWithExistingFile() throws JoranException, IOException, InterruptedException {
-
- String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "conditional/conditionalIncludeExistingFile.xml";
- configure(configFileAsStr);
-
- ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
- assertNotNull(consoleAppender);
- StatusChecker checker = new StatusChecker(context);
- checker.assertIsErrorFree();
- }
-
- @Test
- public void conditionalInclusionWithInexistentFile() throws JoranException, IOException, InterruptedException {
-
- String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX + "conditional/conditionalIncludeInexistentFile.xml";
- configure(configFileAsStr);
-
- ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
- assertNull(consoleAppender);
- StatusChecker checker = new StatusChecker(context);
- checker.assertIsErrorFree();
- }
+ LoggerContext context = new LoggerContext();
+ Logger root = context.getLogger(Logger.ROOT_LOGGER_NAME);
+
+ int diff = RandomUtil.getPositiveInt();
+ String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "/";
+
+ @Before
+ public void setUp() throws UnknownHostException {
+ context.setName("c" + diff);
+ context.putProperty("randomOutputDir", randomOutputDir);
+ }
+
+ @After
+ public void tearDown() {
+ StatusPrinter.printIfErrorsOccured(context);
+ }
+
+ void configure(String file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(context);
+ jc.doConfigure(file);
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Test
+ public void conditionalConsoleApp_IF_THEN_True() throws JoranException,
+ IOException, InterruptedException {
+ InetAddress localhost = InetAddress.getLocalHost();
+ System.out.println("In conditionalConsoleApp_IF_THEN_True, canonicalHostName=\"" + localhost.getCanonicalHostName() + "] and hostNmae=\"" + localhost.getHostName() + "\"");
+ context.putProperty("aHost", localhost.getHostName());
+
+ String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "conditional/conditionalConsoleApp.xml";
+ configure(configFileAsStr);
+ FileAppender fileAppender = (FileAppender) root.getAppender("FILE");
+ assertNotNull(fileAppender);
+
+ ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
+ assertNotNull(consoleAppender);
+ StatusChecker checker = new StatusChecker(context);
+ checker.assertIsErrorFree();
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Test
+ public void conditionalConsoleApp_IF_THEN_False() throws JoranException,
+ IOException, InterruptedException {
+
+ String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "conditional/conditionalConsoleApp.xml";
+ configure(configFileAsStr);
+ FileAppender fileAppender = (FileAppender) root.getAppender("FILE");
+ assertNotNull(fileAppender);
+
+ ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
+ assertNull(consoleAppender);
+ StatusChecker checker = new StatusChecker(context);
+ checker.assertIsErrorFree();
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Test
+ public void conditionalConsoleApp_IF_THEN_ELSE() throws JoranException,
+ IOException, InterruptedException {
+
+ String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "conditional/conditionalConsoleApp_ELSE.xml";
+ configure(configFileAsStr);
+
+ FileAppender fileAppender = (FileAppender) root.getAppender("FILE");
+ assertNotNull(fileAppender);
+
+ ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
+ assertNull(consoleAppender);
+
+ ListAppender listAppender = (ListAppender) root.getAppender("LIST");
+ assertNotNull(listAppender);
+
+ // StatusPrinter.printIfErrorsOccured(context);
+ StatusChecker checker = new StatusChecker(context);
+ checker.assertIsErrorFree();
+ }
+
+ @Test
+ public void conditionalInclusionWithExistingFile() throws JoranException,
+ IOException, InterruptedException {
+
+ String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "conditional/conditionalIncludeExistingFile.xml";
+ configure(configFileAsStr);
+
+ ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
+ assertNotNull(consoleAppender);
+ StatusChecker checker = new StatusChecker(context);
+ checker.assertIsErrorFree();
+ }
+ @Test
+
+ public void conditionalInclusionWithInexistentFile() throws JoranException,
+ IOException, InterruptedException {
+
+ String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "conditional/conditionalIncludeInexistentFile.xml";
+ configure(configFileAsStr);
+
+ ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
+ assertNull(consoleAppender);
+ StatusChecker checker = new StatusChecker(context);
+ checker.assertIsErrorFree();
+ }
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/PackageTest.java
index 9d37ce3..096cd8f 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,7 +17,8 @@ import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
+
@RunWith(Suite.class)
- at SuiteClasses({ ConditionalTest.class })
+ at SuiteClasses( { ConditionalTest.class})
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/jul/LevelChangePropagatorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/jul/LevelChangePropagatorTest.java
index e7bc2a3..1f1c74d 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/jul/LevelChangePropagatorTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/jul/LevelChangePropagatorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,72 +26,72 @@ import org.junit.rules.ExpectedException;
import static org.junit.Assert.assertEquals;
public class LevelChangePropagatorTest {
- int rand = RandomUtil.getPositiveInt();
- LoggerContext loggerContext = new LoggerContext();
- LevelChangePropagator levelChangePropagator = new LevelChangePropagator();
-
- @Rule
- public ExpectedException exception = ExpectedException.none();
-
- @Before
- public void setUp() {
- levelChangePropagator.setContext(loggerContext);
- loggerContext.addListener(levelChangePropagator);
- }
-
- void checkLevelChange(String loggerName, Level level) {
- Logger logger = loggerContext.getLogger(loggerName);
- logger.setLevel(level);
- java.util.logging.Logger julLogger = JULHelper.asJULLogger(logger);
- java.util.logging.Level julLevel = JULHelper.asJULLevel(level);
-
- assertEquals(julLevel, julLogger.getLevel());
- }
-
- @Test
- public void smoke() {
- checkLevelChange("a", Level.INFO);
- checkLevelChange("a.b", Level.DEBUG);
- }
-
- @Test
- public void root() {
- checkLevelChange(Logger.ROOT_LOGGER_NAME, Level.TRACE);
- }
-
- // see http://jira.qos.ch/browse/LBCLASSIC-256
- @Test
- public void gc() {
- Logger logger = loggerContext.getLogger("gc" + rand);
- logger.setLevel(Level.INFO);
- // invoke GC so that the relevant julLogger can be garbage collected.
- System.gc();
- java.util.logging.Logger julLogger = JULHelper.asJULLogger(logger);
- java.util.logging.Level julLevel = JULHelper.asJULLevel(Level.INFO);
-
- assertEquals(julLevel, julLogger.getLevel());
- }
-
- @Test
- public void julHelperAsJulLevelRejectsNull() {
- exception.expect(IllegalArgumentException.class);
- exception.expectMessage("Unexpected level [null]");
- JULHelper.asJULLevel(null);
- }
-
- @Test
- public void settingLevelToNullGetsParentLevel() {
- // first set level of "a" (the parent) to DEBUG
- Logger parent = loggerContext.getLogger("a");
- parent.setLevel(Level.DEBUG);
-
- // then set level of "a.b" (child logger of a) to null
- // for b to inherit its parent's level
- Logger child = loggerContext.getLogger("a.b");
- child.setLevel(Level.INFO);
- child.setLevel(null);
-
- assertEquals(parent.getEffectiveLevel(), child.getEffectiveLevel());
- assertEquals(Level.DEBUG, child.getEffectiveLevel());
- }
+ int rand = RandomUtil.getPositiveInt();
+ LoggerContext loggerContext = new LoggerContext();
+ LevelChangePropagator levelChangePropagator = new LevelChangePropagator();
+
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
+ @Before
+ public void setUp() {
+ levelChangePropagator.setContext(loggerContext);
+ loggerContext.addListener(levelChangePropagator);
+ }
+
+ void checkLevelChange(String loggerName, Level level) {
+ Logger logger = loggerContext.getLogger(loggerName);
+ logger.setLevel(level);
+ java.util.logging.Logger julLogger = JULHelper.asJULLogger(logger);
+ java.util.logging.Level julLevel = JULHelper.asJULLevel(level);
+
+ assertEquals(julLevel, julLogger.getLevel());
+ }
+
+ @Test
+ public void smoke() {
+ checkLevelChange("a", Level.INFO);
+ checkLevelChange("a.b", Level.DEBUG);
+ }
+
+ @Test
+ public void root() {
+ checkLevelChange(Logger.ROOT_LOGGER_NAME, Level.TRACE);
+ }
+
+ // see http://jira.qos.ch/browse/LBCLASSIC-256
+ @Test
+ public void gc() {
+ Logger logger = loggerContext.getLogger("gc"+rand);
+ logger.setLevel(Level.INFO);
+ // invoke GC so that the relevant julLogger can be garbage collected.
+ System.gc();
+ java.util.logging.Logger julLogger = JULHelper.asJULLogger(logger);
+ java.util.logging.Level julLevel = JULHelper.asJULLevel(Level.INFO);
+
+ assertEquals(julLevel, julLogger.getLevel());
+ }
+
+ @Test
+ public void julHelperAsJulLevelRejectsNull() {
+ exception.expect(IllegalArgumentException.class);
+ exception.expectMessage("Unexpected level [null]");
+ JULHelper.asJULLevel(null);
+ }
+
+ @Test
+ public void settingLevelToNullGetsParentLevel() {
+ // first set level of "a" (the parent) to DEBUG
+ Logger parent = loggerContext.getLogger("a");
+ parent.setLevel(Level.DEBUG);
+
+ // then set level of "a.b" (child logger of a) to null
+ // for b to inherit its parent's level
+ Logger child = loggerContext.getLogger("a.b");
+ child.setLevel(Level.INFO);
+ child.setLevel(null);
+
+ assertEquals(parent.getEffectiveLevel(), child.getEffectiveLevel());
+ assertEquals(Level.DEBUG, child.getEffectiveLevel());
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/jul/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/jul/PackageTest.java
index ca36fb6..6bc5e2b 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/jul/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/jul/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ LevelChangePropagatorTest.class })
+ at SuiteClasses({LevelChangePropagatorTest.class})
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/layout/TTLLLayoutTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/layout/TTLLLayoutTest.java
deleted file mode 100644
index 6257285..0000000
--- a/logback-classic/src/test/java/ch/qos/logback/classic/layout/TTLLLayoutTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package ch.qos.logback.classic.layout;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.spi.LoggingEvent;
-
-public class TTLLLayoutTest {
-
- LoggerContext context = new LoggerContext();
- Logger logger = context.getLogger(TTLLLayoutTest.class);
- TTLLLayout layout = new TTLLLayout();
-
- @Before
- public void setUp() {
- layout.setContext(context);
- layout.start();
- }
-
- @Test
- public void nullMessage() {
- LoggingEvent event = new LoggingEvent("", logger, Level.INFO, null, null, null);
- event.setTimeStamp(0);
- String result = layout.doLayout(event);
-
- assertEquals("[main] INFO ch.qos.logback.classic.layout.TTLLLayoutTest - null", result.substring(13).trim());
- }
-}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/log4j/XMLLayoutTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/log4j/XMLLayoutTest.java
deleted file mode 100644
index d5226f9..0000000
--- a/logback-classic/src/test/java/ch/qos/logback/classic/log4j/XMLLayoutTest.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 2014, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.classic.log4j;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.util.Iterator;
-
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathFactory;
-
-import org.apache.log4j.MDC;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.classic.spi.LoggingEvent;
-
-/**
- * A test for correct (well-formed, valid) log4j XML layout.
- *
- * @author Gabriel Corona
- */
-public class XMLLayoutTest {
-
- private static final String DOCTYPE = "<!DOCTYPE log4j:eventSet SYSTEM \"http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd\">";
- private static final String NAMESPACE = "http://jakarta.apache.org/log4j/";
- private static final String DTD_URI = "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd";
-
- private static final String MDC_KEY = "key <&>'\"]]>";
- private static final String MDC_VALUE = "value <&>'\"]]>";
-
- private static final String MESSAGE = "test message, <&>'\"";
-
- private LoggerContext lc;
- private Logger root;
- private XMLLayout layout;
-
- @Before
- public void setUp() throws Exception {
- lc = new LoggerContext();
- lc.setName("default");
-
- layout = new XMLLayout();
- layout.setLocationInfo(true);
- layout.setContext(lc);
- layout.setProperties(true);
- layout.setLocationInfo(true);
- layout.start();
-
- root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
-
- }
-
- @After
- public void tearDown() throws Exception {
- lc = null;
- layout = null;
- MDC.clear();
- }
-
- @Test
- public void testDoLayout() throws Exception {
- ILoggingEvent le = createLoggingEvent();
-
- String result = DOCTYPE + "<log4j:eventSet xmlns:log4j='http://jakarta.apache.org/log4j/'>";
- if (layout.getFileHeader() != null) {
- result += layout.getFileHeader();
- }
- if (layout.getPresentationHeader() != null) {
- result += layout.getPresentationHeader();
- }
- result += layout.doLayout(le);
- if (layout.getPresentationFooter() != null) {
- result += layout.getPresentationFooter();
- }
- if (layout.getFileFooter() != null) {
- result += layout.getFileFooter();
- }
- result += "</log4j:eventSet>";
-
- Document document = parse(result);
-
- XPath xpath = this.newXPath();
-
- // Test log4j:event:
- NodeList eventNodes = (NodeList) xpath.compile("//log4j:event").evaluate(document, XPathConstants.NODESET);
- Assert.assertEquals(1, eventNodes.getLength());
-
- // Test log4g:message:
- Assert.assertEquals(MESSAGE, xpath.compile("//log4j:message").evaluate(document, XPathConstants.STRING));
-
- // Test log4j:data:
- NodeList dataNodes = (NodeList) xpath.compile("//log4j:data").evaluate(document, XPathConstants.NODESET);
- boolean foundMdc = false;
- for (int i = 0; i != dataNodes.getLength(); ++i) {
- Node dataNode = dataNodes.item(i);
- if (dataNode.getAttributes().getNamedItem("name").getNodeValue().equals(MDC_KEY)) {
- foundMdc = true;
- Assert.assertEquals(MDC_VALUE, dataNode.getAttributes().getNamedItem("value").getNodeValue());
- break;
- }
- }
- Assert.assertTrue(foundMdc);
- }
-
- /**
- * Create a XPath instance with xmlns:log4j="http://jakarta.apache.org/log4j/"
- *
- * @return XPath instance with log4 namespace
- */
- private XPath newXPath() {
- XPathFactory xPathfactory = XPathFactory.newInstance();
- XPath xpath = xPathfactory.newXPath();
-
- xpath.setNamespaceContext(new NamespaceContext() {
- @SuppressWarnings("rawtypes")
- public Iterator getPrefixes(String namespaceURI) {
- throw new UnsupportedOperationException();
- }
-
- public String getPrefix(String namespaceURI) {
- throw new UnsupportedOperationException();
- }
-
- public String getNamespaceURI(String prefix) {
- if ("log4j".equals(prefix)) {
- return NAMESPACE;
- } else {
- return XMLConstants.NULL_NS_URI;
- }
- }
- });
-
- return xpath;
- }
-
- private LoggingEvent createLoggingEvent() {
- MDC.put(MDC_KEY, MDC_VALUE);
- LoggingEvent event = new LoggingEvent("com.example.XMLLayoutTest-<&>'\"]]>", root, Level.DEBUG, MESSAGE, new RuntimeException(
- "Dummy exception: <&>'\"]]>"), null);
- event.setThreadName("Dummy thread <&>'\"");
-
- StackTraceElement ste1 = new StackTraceElement("c1", "m1", "f1", 1);
- StackTraceElement ste2 = new StackTraceElement("c2", "m2", "f2", 2);
- event.setCallerData(new StackTraceElement[] { ste1, ste2 });
-
- return event;
- }
-
- /**
- * Parse and validate Log4j XML
- *
- * @param output Log4j XML
- * @return Document
- * @throws Exception
- */
- private Document parse(String output) throws Exception {
-
- // Lookup the DTD in log4j.jar:
- EntityResolver resolver = new EntityResolver() {
- public InputSource resolveEntity(String publicId, String systemId) {
- if (publicId == null && systemId != null && systemId.equals(DTD_URI)) {
- final String path = "/org/apache/log4j/xml/log4j.dtd";
- InputStream in = this.getClass().getResourceAsStream(path);
- return new InputSource(in);
- } else {
- throw new RuntimeException("Not found");
- }
- }
- };
-
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(true);
- factory.setValidating(true);
-
- DocumentBuilder builder = factory.newDocumentBuilder();
- builder.setEntityResolver(resolver);
-
- return builder.parse(new ByteArrayInputStream(output.getBytes("UTF-8")));
- }
-
-}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/Checker.java b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/Checker.java
index c08799c..8723821 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/Checker.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/Checker.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,60 +20,69 @@ import java.util.regex.Pattern;
public class Checker {
- static long LEN;
- static String FILENAME;
+ static long LEN;
+ static String FILENAME;
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + Checker.class.getName() + " runLength filename stamp0 stamp1 ..stampN\n"
- + " runLength (integer) the number of logs to generate perthread\n" + " filename (string) the filename where to write\n"
- + " stamp0 JVM instance stamp0\n" + " stamp1 JVM instance stamp1\n");
- System.exit(1);
- }
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err
+ .println("Usage: java "
+ + Checker.class.getName()
+ + " runLength filename stamp0 stamp1 ..stampN\n"
+ + " runLength (integer) the number of logs to generate perthread\n"
+ + " filename (string) the filename where to write\n"
+ + " stamp0 JVM instance stamp0\n"
+ + " stamp1 JVM instance stamp1\n");
+ System.exit(1);
+ }
- public static void main(String[] argv) throws Exception {
- if (argv.length < 3) {
- usage("Wrong number of arguments.");
- }
+ public static void main(String[] argv) throws Exception {
+ if (argv.length < 3) {
+ usage("Wrong number of arguments.");
+ }
- LEN = Integer.parseInt(argv[0]);
- FILENAME = argv[1];
+ LEN = Integer.parseInt(argv[0]);
+ FILENAME = argv[1];
- for (int i = 2; i < argv.length; i++) {
- check(argv[i], FILENAME, true);
- }
+ for (int i = 2; i < argv.length; i++) {
+ check(argv[i], FILENAME, true);
}
+ }
- static void check(String stamp, String filename, boolean safetyMode) throws Exception {
+ static void check(String stamp, String filename, boolean safetyMode)
+ throws Exception {
- FileReader fr = new FileReader(FILENAME);
- BufferedReader br = new BufferedReader(fr);
+ FileReader fr = new FileReader(FILENAME);
+ BufferedReader br = new BufferedReader(fr);
- String regExp = "^" + stamp + " DEBUG - " + LoggingThread.msgLong + " (\\d+)$";
- Pattern p = Pattern.compile(regExp);
+ String regExp = "^" + stamp + " DEBUG - " + LoggingThread.msgLong
+ + " (\\d+)$";
+ Pattern p = Pattern.compile(regExp);
- String line;
- int expected = 0;
- while ((line = br.readLine()) != null) {
- Matcher m = p.matcher(line);
- if (m.matches()) {
- String g = m.group(1);
- int num = Integer.parseInt(g);
- if (num != expected) {
- System.err.println("ERROR: out of sequence line: ");
- System.err.println(line);
- return;
- }
- expected++;
- }
+ String line;
+ int expected = 0;
+ while ((line = br.readLine()) != null) {
+ Matcher m = p.matcher(line);
+ if (m.matches()) {
+ String g = m.group(1);
+ int num = Integer.parseInt(g);
+ if (num != expected) {
+ System.err.println("ERROR: out of sequence line: ");
+ System.err.println(line);
+ return;
}
+ expected++;
+ }
+ }
- if (expected != LEN) {
- System.err.println("ERROR: For JVM stamp " + stamp + " found " + expected + " was expecting " + LEN);
- } else {
- System.out.println("For JVM stamp " + stamp + " found " + LEN + " lines in correct sequence");
- }
- fr.close();
- br.close();
+ if (expected != LEN) {
+ System.err.println("ERROR: For JVM stamp " + stamp + " found " + expected
+ + " was expecting " + LEN);
+ } else {
+ System.out.println("For JVM stamp " + stamp + " found " + LEN
+ + " lines in correct sequence");
}
+ fr.close();
+ br.close();
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/FileAppenderPerf.java b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/FileAppenderPerf.java
index a38e4a7..a21c373 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/FileAppenderPerf.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/FileAppenderPerf.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,72 +22,76 @@ import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.testUtil.RandomUtil;
public class FileAppenderPerf {
- static String msgLong = "ABCDEGHIJKLMNOPQRSTUVWXYZabcdeghijklmnopqrstuvwxyz1234567890";
+ static String msgLong = "ABCDEGHIJKLMNOPQRSTUVWXYZabcdeghijklmnopqrstuvwxyz1234567890";
- static long LEN = 100 * 1000;
- static int DIFF = RandomUtil.getPositiveInt() % 1000;
- static String FILENAME;
+ static long LEN = 100 * 1000;
+ static int DIFF = RandomUtil.getPositiveInt() % 1000;
+ static String FILENAME;
- static LoggerContext buildLoggerContext(String filename, boolean safetyMode) {
- LoggerContext loggerContext = new LoggerContext();
+ static LoggerContext buildLoggerContext(String filename, boolean safetyMode) {
+ LoggerContext loggerContext = new LoggerContext();
- FileAppender<ILoggingEvent> fa = new FileAppender<ILoggingEvent>();
+ FileAppender<ILoggingEvent> fa = new FileAppender<ILoggingEvent>();
- PatternLayoutEncoder patternLayout = new PatternLayoutEncoder();
- patternLayout.setPattern("%5p %c - %m%n");
- patternLayout.setContext(loggerContext);
- patternLayout.start();
+ PatternLayoutEncoder patternLayout = new PatternLayoutEncoder();
+ patternLayout.setPattern("%5p %c - %m%n");
+ patternLayout.setContext(loggerContext);
+ patternLayout.start();
- fa.setEncoder(patternLayout);
- fa.setFile(filename);
- fa.setAppend(false);
- fa.setPrudent(safetyMode);
- fa.setContext(loggerContext);
- fa.start();
+ fa.setEncoder(patternLayout);
+ fa.setFile(filename);
+ fa.setAppend(false);
+ fa.setPrudent(safetyMode);
+ fa.setContext(loggerContext);
+ fa.start();
- ch.qos.logback.classic.Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
- root.addAppender(fa);
+ ch.qos.logback.classic.Logger root = loggerContext
+ .getLogger(Logger.ROOT_LOGGER_NAME);
+ root.addAppender(fa);
- return loggerContext;
- }
-
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + FileAppenderPerf.class.getName() + " filename");
-
- System.exit(1);
- }
+ return loggerContext;
+ }
- public static void main(String[] argv) throws Exception {
- if (argv.length > 1) {
- usage("Wrong number of arguments.");
- }
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + FileAppenderPerf.class.getName()
+ + " filename");
- if (argv.length == 0) {
- FILENAME = DIFF + "";
- } else {
- FILENAME = argv[0];
- }
+ System.exit(1);
+ }
- perfCase(false);
- perfCase(true);
+ public static void main(String[] argv) throws Exception {
+ if (argv.length > 1) {
+ usage("Wrong number of arguments.");
}
- static void perfCase(boolean safetyMode) throws Exception {
- LoggerContext lc = buildLoggerContext(FILENAME + "-" + safetyMode + ".log", safetyMode);
- Logger logger = lc.getLogger(FileAppenderPerf.class);
+ if (argv.length == 0) {
+ FILENAME = DIFF+"";
+ } else {
+ FILENAME = argv[0];
+ }
- long start = System.nanoTime();
- for (int i = 0; i < LEN; i++) {
- logger.debug(msgLong + " " + i);
- }
- // in microseconds
- double durationPerLog = (System.nanoTime() - start) / (LEN * 1000.0);
+ perfCase(false);
+ perfCase(true);
+ }
- lc.stop();
+ static void perfCase(boolean safetyMode) throws Exception {
+ LoggerContext lc = buildLoggerContext(FILENAME + "-" + safetyMode + ".log",
+ safetyMode);
+ Logger logger = lc.getLogger(FileAppenderPerf.class);
- System.out.println("Average duration of " + (durationPerLog) + " microseconds per log. Prudent mode=" + safetyMode);
- System.out.println("------------------------------------------------");
+ long start = System.nanoTime();
+ for (int i = 0; i < LEN; i++) {
+ logger.debug(msgLong + " " + i);
}
+ // in microseconds
+ double durationPerLog = (System.nanoTime() - start) / (LEN * 1000.0);
+
+ lc.stop();
+
+ System.out.println("Average duration of " + (durationPerLog)
+ + " microseconds per log. Prudent mode=" + safetyMode);
+ System.out.println("------------------------------------------------");
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/LoggingThread.java b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/LoggingThread.java
index 3f8a7d3..3334350 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/LoggingThread.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/LoggingThread.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,32 +16,33 @@ package ch.qos.logback.classic.multiJVM;
import org.slf4j.Logger;
public class LoggingThread extends Thread {
- static String msgLong = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+ static String msgLong = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
- final long len;
- final Logger logger;
- private double durationPerLog;
+ final long len;
+ final Logger logger;
+ private double durationPerLog;
- public LoggingThread(Logger logger, long len) {
- this.logger = logger;
- this.len = len;
- }
-
- public void run() {
- long before = System.nanoTime();
- for (int i = 0; i < len; i++) {
- logger.debug(msgLong + " " + i);
- // try {
- // Thread.sleep(100);
- // } catch (InterruptedException e) {
- // }
- }
- // in microseconds
- durationPerLog = (System.nanoTime() - before) / (len * 1000.0);
- }
+ public LoggingThread(Logger logger, long len) {
+ this.logger = logger;
+ this.len = len;
+ }
- public double getDurationPerLogInMicroseconds() {
- return durationPerLog;
+ public void run() {
+ long before = System.nanoTime();
+ for (int i = 0; i < len; i++) {
+ logger.debug(msgLong + " " + i);
+// try {
+// Thread.sleep(100);
+// } catch (InterruptedException e) {
+// }
}
+ // in microseconds
+ durationPerLog = (System.nanoTime() - before) / (len * 1000.0);
+ }
+ public double getDurationPerLogInMicroseconds() {
+ return durationPerLog;
+ }
+
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeFileAppender.java b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeFileAppender.java
index bc1cc17..4fc00a9 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeFileAppender.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeFileAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,63 +28,69 @@ import ch.qos.logback.core.FileAppender;
*/
public class SafeModeFileAppender {
- static long LEN;
- static String FILENAME;
- static String STAMP;
+ static long LEN;
+ static String FILENAME;
+ static String STAMP;
- static public void main(String[] argv) throws Exception {
- if (argv.length != 3) {
- usage("Wrong number of arguments.");
- }
-
- STAMP = argv[0];
- LEN = Integer.parseInt(argv[1]);
- FILENAME = argv[2];
- writeContinously(STAMP, FILENAME, true);
+ static public void main(String[] argv) throws Exception {
+ if (argv.length != 3) {
+ usage("Wrong number of arguments.");
}
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + SafeModeFileAppender.class.getName() + " stamp runLength filename\n" + " stamp JVM instance stamp\n"
- + " runLength (integer) the number of logs to generate perthread" + " filename (string) the filename where to write\n");
- System.exit(1);
+ STAMP = argv[0];
+ LEN = Integer.parseInt(argv[1]);
+ FILENAME = argv[2];
+ writeContinously(STAMP, FILENAME, true);
+ }
+
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + SafeModeFileAppender.class.getName()
+ + " stamp runLength filename\n" + " stamp JVM instance stamp\n"
+ + " runLength (integer) the number of logs to generate perthread"
+ + " filename (string) the filename where to write\n");
+ System.exit(1);
+ }
+
+ static LoggerContext buildLoggerContext(String stamp, String filename,
+ boolean safetyMode) {
+ LoggerContext loggerContext = new LoggerContext();
+
+ FileAppender<ILoggingEvent> fa = new FileAppender<ILoggingEvent>();
+
+ PatternLayoutEncoder patternLayout = new PatternLayoutEncoder();
+ patternLayout.setPattern(stamp + " %5p - %m%n");
+ patternLayout.setContext(loggerContext);
+ patternLayout.start();
+
+ fa.setEncoder(patternLayout);
+ fa.setFile(filename);
+ fa.setAppend(true);
+ fa.setPrudent(safetyMode);
+ fa.setContext(loggerContext);
+ fa.start();
+
+ ch.qos.logback.classic.Logger root = loggerContext
+ .getLogger(Logger.ROOT_LOGGER_NAME);
+ root.addAppender(fa);
+
+ return loggerContext;
+ }
+
+ static void writeContinously(String stamp, String filename, boolean safetyMode)
+ throws Exception {
+ LoggerContext lc = buildLoggerContext(stamp, filename, safetyMode);
+ Logger logger = lc.getLogger(SafeModeFileAppender.class);
+
+ long before = System.nanoTime();
+ for (int i = 0; i < LEN; i++) {
+ logger.debug(LoggingThread.msgLong + " " + i);
}
+ lc.stop();
+ double durationPerLog = (System.nanoTime() - before) / (LEN * 1000.0);
- static LoggerContext buildLoggerContext(String stamp, String filename, boolean safetyMode) {
- LoggerContext loggerContext = new LoggerContext();
-
- FileAppender<ILoggingEvent> fa = new FileAppender<ILoggingEvent>();
-
- PatternLayoutEncoder patternLayout = new PatternLayoutEncoder();
- patternLayout.setPattern(stamp + " %5p - %m%n");
- patternLayout.setContext(loggerContext);
- patternLayout.start();
-
- fa.setEncoder(patternLayout);
- fa.setFile(filename);
- fa.setAppend(true);
- fa.setPrudent(safetyMode);
- fa.setContext(loggerContext);
- fa.start();
-
- ch.qos.logback.classic.Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
- root.addAppender(fa);
-
- return loggerContext;
- }
-
- static void writeContinously(String stamp, String filename, boolean safetyMode) throws Exception {
- LoggerContext lc = buildLoggerContext(stamp, filename, safetyMode);
- Logger logger = lc.getLogger(SafeModeFileAppender.class);
-
- long before = System.nanoTime();
- for (int i = 0; i < LEN; i++) {
- logger.debug(LoggingThread.msgLong + " " + i);
- }
- lc.stop();
- double durationPerLog = (System.nanoTime() - before) / (LEN * 1000.0);
-
- System.out.println("Average duration of " + (durationPerLog) + " microseconds per log. Safety mode " + safetyMode);
- System.out.println("------------------------------------------------");
- }
+ System.out.println("Average duration of " + (durationPerLog)
+ + " microseconds per log. Safety mode " + safetyMode);
+ System.out.println("------------------------------------------------");
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeRollingFileAppender.java b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeRollingFileAppender.java
index 5c1a905..c5bb880 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeRollingFileAppender.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeRollingFileAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,75 +30,82 @@ import ch.qos.logback.core.util.StatusPrinter;
*/
public class SafeModeRollingFileAppender {
- static long LEN;
- static String FILENAME;
- static String STAMP;
+ static long LEN;
+ static String FILENAME;
+ static String STAMP;
+
+ static final String DATE_PATTERN = "yyyy-MM-dd_HH_mm_ss";
- static final String DATE_PATTERN = "yyyy-MM-dd_HH_mm_ss";
-
- static public void main(String[] argv) throws Exception {
- if (argv.length != 3) {
- usage("Wrong number of arguments.");
- }
-
- STAMP = argv[0];
- LEN = Integer.parseInt(argv[1]);
- FILENAME = argv[2];
- writeContinously(STAMP, FILENAME, true);
+ static public void main(String[] argv) throws Exception {
+ if (argv.length != 3) {
+ usage("Wrong number of arguments.");
}
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + SafeModeRollingFileAppender.class.getName() + " stamp runLength filename\n" + " stamp JVM instance stamp\n"
- + " runLength (integer) the number of logs to generate perthread" + " filename (string) the filename where to write\n");
- System.exit(1);
- }
-
- static LoggerContext buildLoggerContext(String stamp, String filename, boolean safetyMode) {
- LoggerContext loggerContext = new LoggerContext();
-
- RollingFileAppender<ILoggingEvent> rfa = new RollingFileAppender<ILoggingEvent>();
- PatternLayoutEncoder patternLayout = new PatternLayoutEncoder();
- patternLayout.setPattern(stamp + " %5p - %-50m%n");
- patternLayout.setContext(loggerContext);
- patternLayout.start();
-
- rfa.setEncoder(patternLayout);
-
- rfa.setAppend(true);
- rfa.setPrudent(safetyMode);
- rfa.setContext(loggerContext);
-
- TimeBasedRollingPolicy tbrp = new TimeBasedRollingPolicy();
-
- tbrp.setContext(loggerContext);
- tbrp.setFileNamePattern(filename + "-%d{" + DATE_PATTERN + "}.log");
- tbrp.setParent(rfa);
- tbrp.start();
-
- rfa.setRollingPolicy(tbrp);
-
- rfa.start();
-
- ch.qos.logback.classic.Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
- root.addAppender(rfa);
-
- return loggerContext;
- }
-
- static void writeContinously(String stamp, String filename, boolean safetyMode) throws Exception {
- LoggerContext lc = buildLoggerContext(stamp, filename, safetyMode);
- Logger logger = lc.getLogger(SafeModeRollingFileAppender.class);
-
- long before = System.nanoTime();
- for (int i = 0; i < LEN; i++) {
- logger.debug(LoggingThread.msgLong + " " + i);
- }
- lc.stop();
- StatusPrinter.print(lc);
- double durationPerLog = (System.nanoTime() - before) / (LEN * 1000.0);
-
- System.out.println("Average duration of " + (durationPerLog) + " microseconds per log. Safety mode " + safetyMode);
- System.out.println("------------------------------------------------");
+ STAMP = argv[0];
+ LEN = Integer.parseInt(argv[1]);
+ FILENAME = argv[2];
+ writeContinously(STAMP, FILENAME, true);
+ }
+
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + SafeModeRollingFileAppender.class.getName()
+ + " stamp runLength filename\n" + " stamp JVM instance stamp\n"
+ + " runLength (integer) the number of logs to generate perthread"
+ + " filename (string) the filename where to write\n");
+ System.exit(1);
+ }
+
+ static LoggerContext buildLoggerContext(String stamp, String filename,
+ boolean safetyMode) {
+ LoggerContext loggerContext = new LoggerContext();
+
+ RollingFileAppender<ILoggingEvent> rfa = new RollingFileAppender<ILoggingEvent>();
+ PatternLayoutEncoder patternLayout = new PatternLayoutEncoder();
+ patternLayout.setPattern(stamp + " %5p - %-50m%n");
+ patternLayout.setContext(loggerContext);
+ patternLayout.start();
+
+ rfa.setEncoder(patternLayout);
+
+ rfa.setAppend(true);
+ rfa.setPrudent(safetyMode);
+ rfa.setContext(loggerContext);
+
+ TimeBasedRollingPolicy tbrp = new TimeBasedRollingPolicy();
+
+ tbrp.setContext(loggerContext);
+ tbrp.setFileNamePattern(filename+"-%d{"+DATE_PATTERN+"}.log");
+ tbrp.setParent(rfa);
+ tbrp.start();
+
+ rfa.setRollingPolicy(tbrp);
+
+
+ rfa.start();
+
+ ch.qos.logback.classic.Logger root = loggerContext
+ .getLogger(Logger.ROOT_LOGGER_NAME);
+ root.addAppender(rfa);
+
+ return loggerContext;
+ }
+
+ static void writeContinously(String stamp, String filename, boolean safetyMode)
+ throws Exception {
+ LoggerContext lc = buildLoggerContext(stamp, filename, safetyMode);
+ Logger logger = lc.getLogger(SafeModeRollingFileAppender.class);
+
+ long before = System.nanoTime();
+ for (int i = 0; i < LEN; i++) {
+ logger.debug(LoggingThread.msgLong + " " + i);
}
+ lc.stop();
+ StatusPrinter.print(lc);
+ double durationPerLog = (System.nanoTime() - before) / (LEN * 1000.0);
+
+ System.out.println("Average duration of " + (durationPerLog)
+ + " microseconds per log. Safety mode " + safetyMode);
+ System.out.println("------------------------------------------------");
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/CounterBasedEvaluator.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/CounterBasedEvaluator.java
index 7fe2c58..c1dc63d 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/CounterBasedEvaluator.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/CounterBasedEvaluator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,49 +25,51 @@ import ch.qos.logback.core.spi.ContextAwareBase;
*/
public class CounterBasedEvaluator extends ContextAwareBase implements EventEvaluator {
- static int DEFAULT_LIMIT = 1024;
- int limit = DEFAULT_LIMIT;
- int counter = 0;
- String name;
- boolean started;
+ static int DEFAULT_LIMIT = 1024;
+ int limit = DEFAULT_LIMIT;
+ int counter = 0;
+ String name;
+ boolean started;
- public boolean evaluate(Object event) throws NullPointerException, EvaluationException {
- counter++;
+ public boolean evaluate(Object event) throws NullPointerException,
+ EvaluationException {
+ counter++;
- if (counter == limit) {
- counter = 0;
- return true;
- } else {
- return false;
- }
+ if (counter == limit) {
+ counter = 0;
+ return true;
+ } else {
+ return false;
}
+ }
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
+ public String getName() {
+ return name;
+ }
- public boolean isStarted() {
- return started;
- }
+ public void setName(String name) {
+ this.name = name;
+ }
- public void start() {
- started = true;
- }
+ public boolean isStarted() {
+ return started;
+ }
- public void stop() {
- started = false;
- }
+ public void start() {
+ started = true;
+ }
- public int getLimit() {
- return limit;
- }
+ public void stop() {
+ started = false;
+ }
- public void setLimit(int limit) {
- this.limit = limit;
- }
+ public int getLimit() {
+ return limit;
+ }
+ public void setLimit(int limit) {
+ this.limit = limit;
+ }
+
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/DilutedSMTPAppenderTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/DilutedSMTPAppenderTest.java
index 1246a71..afe30ac 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/DilutedSMTPAppenderTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/DilutedSMTPAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -35,78 +35,100 @@ import ch.qos.logback.core.Layout;
public class DilutedSMTPAppenderTest {
- SMTPAppender appender;
- CyclicBufferTracker<ILoggingEvent> cbTracker;
- CyclicBuffer<ILoggingEvent> cb;
-
- @Before
- public void setUp() throws Exception {
- LoggerContext lc = new LoggerContext();
- appender = new SMTPAppender();
- appender.setContext(lc);
- appender.setName("smtp");
- appender.setFrom("user at host.dom");
- appender.setLayout(buildLayout(lc));
- appender.setSMTPHost("mail2.qos.ch");
- appender.setSubject("logging report");
- appender.addTo("sebastien.nospam at qos.ch");
- appender.start();
- cbTracker = appender.getCyclicBufferTracker();
- cb = cbTracker.getOrCreate("", 0);
-
- }
-
- private static Layout<ILoggingEvent> buildLayout(LoggerContext lc) {
- PatternLayout layout = new PatternLayout();
- layout.setContext(lc);
- layout.setFileHeader("Some header\n");
- layout.setPattern("%-4relative [%thread] %-5level %class - %msg%n");
- layout.setFileFooter("Some footer");
- layout.start();
- return layout;
- }
-
- @After
- public void tearDown() throws Exception {
- appender = null;
- }
-
- @Test
- public void testStart() {
- assertEquals("sebastien.nospam at qos.ch%nopex", appender.getToAsListOfString().get(0));
-
- assertEquals("logging report", appender.getSubject());
-
- assertTrue(appender.isStarted());
+ SMTPAppender appender;
+ CyclicBufferTracker<ILoggingEvent> cbTracker;
+ CyclicBuffer<ILoggingEvent> cb;
+
+ @Before
+ public void setUp() throws Exception {
+ LoggerContext lc = new LoggerContext();
+ appender = new SMTPAppender();
+ appender.setContext(lc);
+ appender.setName("smtp");
+ appender.setFrom("user at host.dom");
+ appender.setLayout(buildLayout(lc));
+ appender.setSMTPHost("mail2.qos.ch");
+ appender.setSubject("logging report");
+ appender.addTo("sebastien.nospam at qos.ch");
+ appender.start();
+ cbTracker = appender.getCyclicBufferTracker();
+ cb = cbTracker.getOrCreate("", 0);
+
+ }
+
+ private static Layout<ILoggingEvent> buildLayout(LoggerContext lc) {
+ PatternLayout layout = new PatternLayout();
+ layout.setContext(lc);
+ layout.setFileHeader("Some header\n");
+ layout.setPattern("%-4relative [%thread] %-5level %class - %msg%n");
+ layout.setFileFooter("Some footer");
+ layout.start();
+ return layout;
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ appender = null;
+ }
+
+ @Test
+ public void testStart() {
+ try {
+ Address[] addressArray = appender.getMessage().getFrom();
+ Address address = addressArray[0];
+ assertEquals("user at host.dom", address.toString());
+
+ addressArray = null;
+ address = null;
+
+ assertEquals("sebastien.nospam at qos.ch%nopex", appender.getToAsListOfString().get(0));
+
+ assertEquals("logging report", appender.getSubject());
+
+ assertTrue(appender.isStarted());
+
+ } catch (MessagingException ex) {
+ fail("Unexpected exception.");
}
-
- @Test
- public void testAppendNonTriggeringEvent() {
- LoggingEvent event = new LoggingEvent();
- event.setThreadName("thead name");
- event.setLevel(Level.DEBUG);
- appender.subAppend(cb, event);
- assertEquals(1, cb.length());
- }
-
- @Test
- public void testEntryConditionsCheck() {
- appender.checkEntryConditions();
- assertEquals(0, appender.getContext().getStatusManager().getCount());
- }
-
- @Test
- public void testTriggeringPolicy() {
- appender.setEvaluator(null);
- appender.checkEntryConditions();
- assertEquals(1, appender.getContext().getStatusManager().getCount());
- }
-
- @Test
- public void testEntryConditionsCheckNoLayout() {
- appender.setLayout(null);
- appender.checkEntryConditions();
- assertEquals(1, appender.getContext().getStatusManager().getCount());
- }
-
+ }
+
+ @Test
+ public void testAppendNonTriggeringEvent() {
+ LoggingEvent event = new LoggingEvent();
+ event.setThreadName("thead name");
+ event.setLevel(Level.DEBUG);
+ appender.subAppend(cb, event);
+ assertEquals(1, cb.length());
+ }
+
+ @Test
+ public void testEntryConditionsCheck() {
+ appender.checkEntryConditions();
+ assertEquals(0, appender.getContext().getStatusManager().getCount());
+ }
+
+ @Test
+ public void testEntryConditionsCheckNoMessage() {
+ appender.setMessage(null);
+ appender.checkEntryConditions();
+ assertEquals(1, appender.getContext().getStatusManager().getCount());
+ }
+
+ @Test
+ public void testTriggeringPolicy() {
+ appender.setEvaluator(null);
+ appender.checkEntryConditions();
+ assertEquals(1, appender.getContext().getStatusManager().getCount());
+ }
+
+ @Test
+ public void testEntryConditionsCheckNoLayout() {
+ appender.setLayout(null);
+ appender.checkEntryConditions();
+ assertEquals(1, appender.getContext().getStatusManager().getCount());
+ }
+
+
+
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/ExternalMockSocketServer.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/ExternalMockSocketServer.java
index 9992ee9..1657160 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/ExternalMockSocketServer.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/ExternalMockSocketServer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,71 +21,73 @@ import java.util.List;
public class ExternalMockSocketServer {
- static final String LOGGINGEVENT = "LoggingEvent";
- static final String LOGGINGEVENT2 = "LoggingEvent2";
- static final String MINIMALEXT = "MinimalExt";
- static final String MINIMALSER = "MinimalSer";
+ static final String LOGGINGEVENT = "LoggingEvent";
+ static final String LOGGINGEVENT2 = "LoggingEvent2";
+ static final String MINIMALEXT = "MinimalExt";
+ static final String MINIMALSER = "MinimalSer";
- static final int PORT = 4560;
+ static final int PORT = 4560;
- // static int loopLen;
- static int clientNumber;
+ //static int loopLen;
+ static int clientNumber;
- static List<String> msgList = new ArrayList<String>();
- static boolean finished = false;
+ static List<String> msgList = new ArrayList<String>();
+ static boolean finished = false;
- String className = LOGGINGEVENT;
+ String className = LOGGINGEVENT;
- public static void main(String[] args) {
- if (args.length == 1) {
- clientNumber = Integer.parseInt(args[0]);
- // loopLen = Integer.parseInt((args[1]));
- runServer();
- } else {
- usage("Wrong number of arguments.");
- }
- }
+ public static void main(String[] args) {
+ if (args.length == 1) {
+ clientNumber = Integer.parseInt(args[0]);
+ //loopLen = Integer.parseInt((args[1]));
+ runServer();
+ } else {
+ usage("Wrong number of arguments.");
+ }
+ }
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + ExternalMockSocketServer.class.getName() + " loopNumber");
- System.exit(1);
- }
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err
+ .println("Usage: java " + ExternalMockSocketServer.class.getName()
+ + " loopNumber");
+ System.exit(1);
+ }
- static void runServer() {
+ static void runServer() {
- try {
- System.out.println("Starting Server...");
- ServerSocket serverSocket = new ServerSocket(PORT);
- System.out.println("Listening on port " + PORT);
- for (int j = 0; j < clientNumber; j++) {
- Socket socket = serverSocket.accept();
- System.out.println("New client accepted.");
- System.out.println("Connected to client at " + socket.getInetAddress());
+ try {
+ System.out.println("Starting Server...");
+ ServerSocket serverSocket = new ServerSocket(PORT);
+ System.out.println("Listening on port " + PORT);
+ for (int j = 0; j < clientNumber; j++) {
+ Socket socket = serverSocket.accept();
+ System.out.println("New client accepted.");
+ System.out.println("Connected to client at " + socket.getInetAddress());
- InputStream is = socket.getInputStream();
- long sum = 0;
-
- while (true) {
- // this call is blocking
- int val = is.read();
- if (val == -1) {
- break;
- }
- // if a byte is available, we skip it.
- // this allows to pass all available bytes in a quick manner.
- int a = is.available();
- sum += a + 1;
- is.skip(a);
- }
- System.out.println(sum / 1000 + " KB");
- }
- serverSocket.close();
- } catch (Exception se) {
- se.printStackTrace();
- }
- System.out.println("Server finished.");
- finished = true;
- }
+ InputStream is = socket.getInputStream();
+ long sum = 0;
+
+ while (true) {
+ // this call is blocking
+ int val = is.read();
+ if(val == -1) {
+ break;
+ }
+ // if a byte is available, we skip it.
+ // this allows to pass all available bytes in a quick manner.
+ int a = is.available();
+ sum += a + 1;
+ is.skip(a);
+ }
+ System.out.println(sum/1000 + " KB");
+ }
+ serverSocket.close();
+ } catch (Exception se) {
+ se.printStackTrace();
+ }
+ System.out.println("Server finished.");
+ finished = true;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSQueueAppenderTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSQueueAppenderTest.java
index 3aaa1f4..6544371 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSQueueAppenderTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSQueueAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,113 +31,113 @@ import ch.qos.logback.core.spi.PreSerializationTransformer;
public class JMSQueueAppenderTest extends TestCase {
- ch.qos.logback.core.Context context;
- JMSQueueAppender appender;
- PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer();
-
- @Override
- protected void setUp() throws Exception {
- context = new ContextBase();
- appender = new JMSQueueAppender();
- appender.setContext(context);
- appender.setName("jmsQueue");
- appender.qcfBindingName = "queueCnxFactory";
- appender.queueBindingName = "testQueue";
- appender.setProviderURL("url");
- appender.setInitialContextFactoryName(MockInitialContextFactory.class.getName());
-
- MockInitialContext mic = MockInitialContextFactory.getContext();
- mic.map.put(appender.qcfBindingName, new MockQueueConnectionFactory());
- mic.map.put(appender.queueBindingName, new MockQueue(appender.queueBindingName));
-
- super.setUp();
+ ch.qos.logback.core.Context context;
+ JMSQueueAppender appender;
+ PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer();
+
+ @Override
+ protected void setUp() throws Exception {
+ context = new ContextBase();
+ appender = new JMSQueueAppender();
+ appender.setContext(context);
+ appender.setName("jmsQueue");
+ appender.qcfBindingName = "queueCnxFactory";
+ appender.queueBindingName = "testQueue";
+ appender.setProviderURL("url");
+ appender.setInitialContextFactoryName(MockInitialContextFactory.class.getName());
+
+ MockInitialContext mic = MockInitialContextFactory.getContext();
+ mic.map.put(appender.qcfBindingName, new MockQueueConnectionFactory());
+ mic.map.put(appender.queueBindingName, new MockQueue(appender.queueBindingName));
+
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ appender = null;
+ context = null;
+ super.tearDown();
+ }
+
+ public void testAppendOk() {
+ appender.start();
+
+ ILoggingEvent le = createLoggingEvent();
+ appender.append(le);
+
+ MockQueueSender qs = (MockQueueSender)appender.queueSender;
+ assertEquals(1, qs.getMessageList().size());
+ ObjectMessage message = (ObjectMessage) qs.getMessageList().get(0);
+ try {
+ Serializable witness = pst.transform(le);
+ assertEquals(witness, message.getObject());
+ } catch (Exception e) {
+ fail();
}
-
- @Override
- protected void tearDown() throws Exception {
- appender = null;
- context = null;
- super.tearDown();
+ }
+
+ public void testAppendFailure() {
+ appender.start();
+
+ //make sure the append method does not work
+ appender.queueSender = null;
+
+ ILoggingEvent le = createLoggingEvent();
+ for (int i = 1; i <= 3; i++) {
+ appender.append(le);
+ assertEquals(i, context.getStatusManager().getCount());
+ assertTrue(appender.isStarted());
}
-
- public void testAppendOk() {
- appender.start();
-
- ILoggingEvent le = createLoggingEvent();
- appender.append(le);
-
- MockQueueSender qs = (MockQueueSender) appender.queueSender;
- assertEquals(1, qs.getMessageList().size());
- ObjectMessage message = (ObjectMessage) qs.getMessageList().get(0);
- try {
- Serializable witness = pst.transform(le);
- assertEquals(witness, message.getObject());
- } catch (Exception e) {
- fail();
- }
+ appender.append(le);
+ assertEquals(4, context.getStatusManager().getCount());
+ assertFalse(appender.isStarted());
+ }
+
+ public void testStartMinimalInfo() {
+ //let's leave only what's in the setup()
+ //method, minus the providerURL
+ appender.setProviderURL(null);
+ appender.start();
+
+ assertTrue(appender.isStarted());
+
+ try {
+ assertEquals(appender.queueBindingName, appender.queueSender.getQueue().getQueueName());
+ } catch (Exception e) {
+ fail();
}
-
- public void testAppendFailure() {
- appender.start();
-
- // make sure the append method does not work
- appender.queueSender = null;
-
- ILoggingEvent le = createLoggingEvent();
- for (int i = 1; i <= 3; i++) {
- appender.append(le);
- assertEquals(i, context.getStatusManager().getCount());
- assertTrue(appender.isStarted());
- }
- appender.append(le);
- assertEquals(4, context.getStatusManager().getCount());
- assertFalse(appender.isStarted());
- }
-
- public void testStartMinimalInfo() {
- // let's leave only what's in the setup()
- // method, minus the providerURL
- appender.setProviderURL(null);
- appender.start();
-
- assertTrue(appender.isStarted());
-
- try {
- assertEquals(appender.queueBindingName, appender.queueSender.getQueue().getQueueName());
- } catch (Exception e) {
- fail();
- }
- }
-
- public void testStartUserPass() {
- appender.setUserName("test");
- appender.setPassword("test");
-
- appender.start();
-
- assertTrue(appender.isStarted());
-
- try {
- assertEquals(appender.queueBindingName, appender.queueSender.getQueue().getQueueName());
- } catch (Exception e) {
- fail();
- }
- }
-
- public void testStartFails() {
- appender.queueBindingName = null;
-
- appender.start();
-
- assertFalse(appender.isStarted());
- }
-
- private ILoggingEvent createLoggingEvent() {
- LoggingEvent le = new LoggingEvent();
- le.setLevel(Level.DEBUG);
- le.setMessage("test message");
- le.setTimeStamp(System.currentTimeMillis());
- le.setThreadName(Thread.currentThread().getName());
- return le;
+ }
+
+ public void testStartUserPass() {
+ appender.setUserName("test");
+ appender.setPassword("test");
+
+ appender.start();
+
+ assertTrue(appender.isStarted());
+
+ try {
+ assertEquals(appender.queueBindingName, appender.queueSender.getQueue().getQueueName());
+ } catch (Exception e) {
+ fail();
}
+ }
+
+ public void testStartFails() {
+ appender.queueBindingName = null;
+
+ appender.start();
+
+ assertFalse(appender.isStarted());
+ }
+
+ private ILoggingEvent createLoggingEvent() {
+ LoggingEvent le = new LoggingEvent();
+ le.setLevel(Level.DEBUG);
+ le.setMessage("test message");
+ le.setTimeStamp(System.currentTimeMillis());
+ le.setThreadName(Thread.currentThread().getName());
+ return le;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSQueueAppenderTestApp.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSQueueAppenderTestApp.java
index 01fd043..3245e8b 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSQueueAppenderTestApp.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSQueueAppenderTestApp.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,42 +20,42 @@ import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.util.StatusPrinter;
public class JMSQueueAppenderTestApp {
-
- public static void main(String[] args) {
- Logger logger = (Logger) LoggerFactory.getLogger(JMSTopicAppenderTestApp.class);
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- lc.reset();
-
- JMSQueueAppender appender = new JMSQueueAppender();
- appender.setContext(lc);
- appender.setName("jmsQueue");
- appender.setInitialContextFactoryName("org.apache.activemq.jndi.ActiveMQInitialContextFactory");
- // appender.setPassword("");
- appender.setProviderURL("tcp://localhost:61616");
- // appender.setSecurityCredentials("");
- // appender.setSecurityPrincipalName("");
- appender.setQueueBindingName("MyQueue");
- appender.setQueueConnectionFactoryBindingName("ConnectionFactory");
- // appender.setURLPkgPrefixes("");
- // appender.setUserName("");
-
- appender.start();
- logger.addAppender(appender);
-
- // JIT
- for (int i = 0; i < 10000; i++) {
- logger.debug("** Hello world. n=" + i);
- }
-
- long before = System.nanoTime();
- for (int i = 0; i < 10000; i++) {
- logger.debug("** Hello world. n=" + i);
- }
- long after = System.nanoTime();
-
- System.out.println("Time per logs for 10'000 logs: " + (after - before) / 10000);
-
- StatusPrinter.print(lc.getStatusManager());
+
+ public static void main(String[] args) {
+ Logger logger = (Logger)LoggerFactory.getLogger(JMSTopicAppenderTestApp.class);
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ lc.reset();
+
+ JMSQueueAppender appender = new JMSQueueAppender();
+ appender.setContext(lc);
+ appender.setName("jmsQueue");
+ appender.setInitialContextFactoryName("org.apache.activemq.jndi.ActiveMQInitialContextFactory");
+ //appender.setPassword("");
+ appender.setProviderURL("tcp://localhost:61616");
+ //appender.setSecurityCredentials("");
+ //appender.setSecurityPrincipalName("");
+ appender.setQueueBindingName("MyQueue");
+ appender.setQueueConnectionFactoryBindingName("ConnectionFactory");
+ //appender.setURLPkgPrefixes("");
+ //appender.setUserName("");
+
+ appender.start();
+ logger.addAppender(appender);
+
+ //JIT
+ for (int i = 0; i < 10000; i++) {
+ logger.debug("** Hello world. n=" + i);
+ }
+
+ long before = System.nanoTime();
+ for (int i = 0; i < 10000; i++) {
+ logger.debug("** Hello world. n=" + i);
}
+ long after = System.nanoTime();
+
+ System.out.println("Time per logs for 10'000 logs: " + (after-before)/10000);
+
+ StatusPrinter.print(lc.getStatusManager());
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSTopicAppenderTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSTopicAppenderTest.java
index 6862e8a..341cf0d 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSTopicAppenderTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSTopicAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -39,192 +39,210 @@ import ch.qos.logback.classic.util.MockInitialContextFactory;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.spi.PreSerializationTransformer;
-public class JMSTopicAppenderTest {
-
- ch.qos.logback.core.Context context;
- JMSTopicAppender appender;
- PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer();
-
- @Before
- public void setUp() throws Exception {
- context = new ContextBase();
- appender = new JMSTopicAppender();
- appender.setContext(context);
- appender.setName("jmsTopic");
- appender.tcfBindingName = "topicCnxFactory";
- appender.topicBindingName = "testTopic";
- appender.setProviderURL("url");
- appender.setInitialContextFactoryName(MockInitialContextFactory.class.getName());
-
- MockInitialContext mic = MockInitialContextFactory.getContext();
- mic.map.put(appender.tcfBindingName, new MockTopicConnectionFactory());
- mic.map.put(appender.topicBindingName, new MockTopic(appender.topicBindingName));
-
- }
-
- @After
- public void tearDown() throws Exception {
- appender = null;
- context = null;
- }
-
- @Test
- public void testAppendOk() {
- appender.start();
-
- ILoggingEvent le = createLoggingEvent();
- appender.append(le);
-
- MockTopicPublisher tp = (MockTopicPublisher) appender.topicPublisher;
- assertEquals(1, tp.getMessageList().size());
- ObjectMessage message = (ObjectMessage) tp.getMessageList().get(0);
- try {
- Serializable witness = pst.transform(le);
- assertEquals(witness, message.getObject());
- } catch (Exception e) {
- fail();
- }
- }
-
- @Test
- public void testAppendFailure() {
- appender.start();
-
- // make sure the append method does not work
- appender.topicPublisher = null;
-
- ILoggingEvent le = createLoggingEvent();
- for (int i = 1; i <= 3; i++) {
- appender.append(le);
- assertEquals(i, context.getStatusManager().getCount());
- assertTrue(appender.isStarted());
- }
- appender.append(le);
- assertEquals(4, context.getStatusManager().getCount());
- assertFalse(appender.isStarted());
- }
-
- @Test
- public void testBuildEnvProperties() {
- appender.setInitialContextFactoryName("icfn");
- appender.setProviderURL("url");
- appender.setURLPkgPrefixes("pkgPref");
- appender.setSecurityPrincipalName("user");
- appender.setSecurityCredentials("cred");
-
- Properties props = appender.buildEnvProperties();
- assertEquals(5, props.size());
- assertEquals(appender.getInitialContextFactoryName(), props.getProperty(Context.INITIAL_CONTEXT_FACTORY));
- assertEquals(appender.getProviderURL(), props.getProperty(Context.PROVIDER_URL));
- assertEquals(appender.getURLPkgPrefixes(), props.getProperty(Context.URL_PKG_PREFIXES));
- assertEquals(appender.getSecurityPrincipalName(), props.getProperty(Context.SECURITY_PRINCIPAL));
- assertEquals(appender.getSecurityCredentials(), props.getProperty(Context.SECURITY_CREDENTIALS));
- }
-
- @Test
- public void testBuildEnvPropertiesWithNullProviderURL() {
- appender.setInitialContextFactoryName("icfn");
- appender.setProviderURL(null);
- appender.setURLPkgPrefixes("pkgPref");
- appender.setSecurityPrincipalName("user");
- appender.setSecurityCredentials("cred");
-
- Properties props = appender.buildEnvProperties();
- assertEquals(4, props.size());
- assertEquals(appender.getInitialContextFactoryName(), props.getProperty(Context.INITIAL_CONTEXT_FACTORY));
- assertEquals(null, props.getProperty(Context.PROVIDER_URL));
- assertEquals(appender.getURLPkgPrefixes(), props.getProperty(Context.URL_PKG_PREFIXES));
- assertEquals(appender.getSecurityPrincipalName(), props.getProperty(Context.SECURITY_PRINCIPAL));
- assertEquals(appender.getSecurityCredentials(), props.getProperty(Context.SECURITY_CREDENTIALS));
-
- assertEquals(1, context.getStatusManager().getCount());
- }
-
- @Test
- public void testBuildEnvPropertiesWithNullCredentials() {
- appender.setInitialContextFactoryName("icfn");
- appender.setProviderURL("url");
- appender.setURLPkgPrefixes("pkgPref");
- appender.setSecurityPrincipalName("user");
- appender.setSecurityCredentials(null);
-
- Properties props = appender.buildEnvProperties();
- assertEquals(4, props.size());
- assertEquals(appender.getInitialContextFactoryName(), props.getProperty(Context.INITIAL_CONTEXT_FACTORY));
- assertEquals(appender.getProviderURL(), props.getProperty(Context.PROVIDER_URL));
- assertEquals(appender.getURLPkgPrefixes(), props.getProperty(Context.URL_PKG_PREFIXES));
- assertEquals(appender.getSecurityPrincipalName(), props.getProperty(Context.SECURITY_PRINCIPAL));
- assertEquals(null, props.getProperty(Context.SECURITY_CREDENTIALS));
-
- assertEquals(1, context.getStatusManager().getCount());
+public class JMSTopicAppenderTest {
+
+ ch.qos.logback.core.Context context;
+ JMSTopicAppender appender;
+ PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer();
+
+
+ @Before
+ public void setUp() throws Exception {
+ context = new ContextBase();
+ appender = new JMSTopicAppender();
+ appender.setContext(context);
+ appender.setName("jmsTopic");
+ appender.tcfBindingName = "topicCnxFactory";
+ appender.topicBindingName = "testTopic";
+ appender.setProviderURL("url");
+ appender.setInitialContextFactoryName(MockInitialContextFactory.class.getName());
+
+ MockInitialContext mic = MockInitialContextFactory.getContext();
+ mic.map.put(appender.tcfBindingName, new MockTopicConnectionFactory());
+ mic.map.put(appender.topicBindingName, new MockTopic(appender.topicBindingName));
+
+ }
+
+
+ @After
+ public void tearDown() throws Exception {
+ appender = null;
+ context = null;
+ }
+
+ @Test
+ public void testAppendOk() {
+ appender.start();
+
+ ILoggingEvent le = createLoggingEvent();
+ appender.append(le);
+
+ MockTopicPublisher tp = (MockTopicPublisher)appender.topicPublisher;
+ assertEquals(1, tp.getMessageList().size());
+ ObjectMessage message = (ObjectMessage) tp.getMessageList().get(0);
+ try {
+ Serializable witness = pst.transform(le);
+ assertEquals(witness, message.getObject());
+ } catch (Exception e) {
+ fail();
}
-
- @Test
- public void testBuildEnvPropertiesWithPkgNull() {
- appender.setInitialContextFactoryName("icfn");
- appender.setProviderURL("url");
- appender.setURLPkgPrefixes(null);
- appender.setSecurityPrincipalName("user");
- appender.setSecurityCredentials("cred");
-
- Properties props = appender.buildEnvProperties();
- assertEquals(4, props.size());
- assertEquals(appender.getInitialContextFactoryName(), props.getProperty(Context.INITIAL_CONTEXT_FACTORY));
- assertEquals(appender.getProviderURL(), props.getProperty(Context.PROVIDER_URL));
- assertEquals(null, props.getProperty(Context.URL_PKG_PREFIXES));
- assertEquals(appender.getSecurityPrincipalName(), props.getProperty(Context.SECURITY_PRINCIPAL));
- assertEquals(appender.getSecurityCredentials(), props.getProperty(Context.SECURITY_CREDENTIALS));
-
- assertEquals(0, context.getStatusManager().getCount());
+ }
+
+ @Test
+ public void testAppendFailure() {
+ appender.start();
+
+ //make sure the append method does not work
+ appender.topicPublisher = null;
+
+ ILoggingEvent le = createLoggingEvent();
+ for (int i = 1; i <= 3; i++) {
+ appender.append(le);
+ assertEquals(i, context.getStatusManager().getCount());
+ assertTrue(appender.isStarted());
}
-
- @Test
- public void testStartMinimalInfo() {
- // let's leave only what's in the setup()
- // method, minus the providerURL
- appender.setProviderURL(null);
- appender.start();
-
- assertTrue(appender.isStarted());
-
- try {
- assertEquals(appender.topicBindingName, appender.topicPublisher.getTopic().getTopicName());
- } catch (Exception e) {
- fail();
- }
+ appender.append(le);
+ assertEquals(4, context.getStatusManager().getCount());
+ assertFalse(appender.isStarted());
+ }
+
+ @Test
+ public void testBuildEnvProperties() {
+ appender.setInitialContextFactoryName("icfn");
+ appender.setProviderURL("url");
+ appender.setURLPkgPrefixes("pkgPref");
+ appender.setSecurityPrincipalName("user");
+ appender.setSecurityCredentials("cred");
+
+ Properties props = appender.buildEnvProperties();
+ assertEquals(5, props.size());
+ assertEquals(appender.getInitialContextFactoryName(), props
+ .getProperty(Context.INITIAL_CONTEXT_FACTORY));
+ assertEquals(appender.getProviderURL(), props.getProperty(Context.PROVIDER_URL));
+ assertEquals(appender.getURLPkgPrefixes(), props
+ .getProperty(Context.URL_PKG_PREFIXES));
+ assertEquals(appender.getSecurityPrincipalName(), props
+ .getProperty(Context.SECURITY_PRINCIPAL));
+ assertEquals(appender.getSecurityCredentials(), props
+ .getProperty(Context.SECURITY_CREDENTIALS));
+ }
+
+ @Test
+ public void testBuildEnvPropertiesWithNullProviderURL() {
+ appender.setInitialContextFactoryName("icfn");
+ appender.setProviderURL(null);
+ appender.setURLPkgPrefixes("pkgPref");
+ appender.setSecurityPrincipalName("user");
+ appender.setSecurityCredentials("cred");
+
+ Properties props = appender.buildEnvProperties();
+ assertEquals(4, props.size());
+ assertEquals(appender.getInitialContextFactoryName(), props
+ .getProperty(Context.INITIAL_CONTEXT_FACTORY));
+ assertEquals(null, props.getProperty(Context.PROVIDER_URL));
+ assertEquals(appender.getURLPkgPrefixes(), props
+ .getProperty(Context.URL_PKG_PREFIXES));
+ assertEquals(appender.getSecurityPrincipalName(), props
+ .getProperty(Context.SECURITY_PRINCIPAL));
+ assertEquals(appender.getSecurityCredentials(), props
+ .getProperty(Context.SECURITY_CREDENTIALS));
+
+ assertEquals(1, context.getStatusManager().getCount());
+ }
+
+ @Test
+ public void testBuildEnvPropertiesWithNullCredentials() {
+ appender.setInitialContextFactoryName("icfn");
+ appender.setProviderURL("url");
+ appender.setURLPkgPrefixes("pkgPref");
+ appender.setSecurityPrincipalName("user");
+ appender.setSecurityCredentials(null);
+
+ Properties props = appender.buildEnvProperties();
+ assertEquals(4, props.size());
+ assertEquals(appender.getInitialContextFactoryName(), props
+ .getProperty(Context.INITIAL_CONTEXT_FACTORY));
+ assertEquals(appender.getProviderURL(), props.getProperty(Context.PROVIDER_URL));
+ assertEquals(appender.getURLPkgPrefixes(), props
+ .getProperty(Context.URL_PKG_PREFIXES));
+ assertEquals(appender.getSecurityPrincipalName(), props
+ .getProperty(Context.SECURITY_PRINCIPAL));
+ assertEquals(null, props
+ .getProperty(Context.SECURITY_CREDENTIALS));
+
+ assertEquals(1, context.getStatusManager().getCount());
+ }
+
+ @Test
+ public void testBuildEnvPropertiesWithPkgNull() {
+ appender.setInitialContextFactoryName("icfn");
+ appender.setProviderURL("url");
+ appender.setURLPkgPrefixes(null);
+ appender.setSecurityPrincipalName("user");
+ appender.setSecurityCredentials("cred");
+
+ Properties props = appender.buildEnvProperties();
+ assertEquals(4, props.size());
+ assertEquals(appender.getInitialContextFactoryName(), props
+ .getProperty(Context.INITIAL_CONTEXT_FACTORY));
+ assertEquals(appender.getProviderURL(), props.getProperty(Context.PROVIDER_URL));
+ assertEquals(null, props
+ .getProperty(Context.URL_PKG_PREFIXES));
+ assertEquals(appender.getSecurityPrincipalName(), props
+ .getProperty(Context.SECURITY_PRINCIPAL));
+ assertEquals(appender.getSecurityCredentials(), props
+ .getProperty(Context.SECURITY_CREDENTIALS));
+
+ assertEquals(0, context.getStatusManager().getCount());
+ }
+
+ @Test
+ public void testStartMinimalInfo() {
+ //let's leave only what's in the setup()
+ //method, minus the providerURL
+ appender.setProviderURL(null);
+ appender.start();
+
+ assertTrue(appender.isStarted());
+
+ try {
+ assertEquals(appender.topicBindingName, appender.topicPublisher.getTopic().getTopicName());
+ } catch (Exception e) {
+ fail();
}
-
- @Test
- public void testStartUserPass() {
- appender.setUserName("test");
- appender.setPassword("test");
-
- appender.start();
-
- assertTrue(appender.isStarted());
-
- try {
- assertEquals(appender.topicBindingName, appender.topicPublisher.getTopic().getTopicName());
- } catch (Exception e) {
- fail();
- }
- }
-
- @Test
- public void testStartFails() {
- appender.topicBindingName = null;
-
- appender.start();
-
- assertFalse(appender.isStarted());
- }
-
- private ILoggingEvent createLoggingEvent() {
- LoggingEvent le = new LoggingEvent();
- le.setLevel(Level.DEBUG);
- le.setMessage("test message");
- le.setTimeStamp(System.currentTimeMillis());
- le.setThreadName(Thread.currentThread().getName());
- return le;
+ }
+
+ @Test
+ public void testStartUserPass() {
+ appender.setUserName("test");
+ appender.setPassword("test");
+
+ appender.start();
+
+ assertTrue(appender.isStarted());
+
+ try {
+ assertEquals(appender.topicBindingName, appender.topicPublisher.getTopic().getTopicName());
+ } catch (Exception e) {
+ fail();
}
+ }
+
+ @Test
+ public void testStartFails() {
+ appender.topicBindingName = null;
+
+ appender.start();
+
+ assertFalse(appender.isStarted());
+ }
+
+ private ILoggingEvent createLoggingEvent() {
+ LoggingEvent le = new LoggingEvent();
+ le.setLevel(Level.DEBUG);
+ le.setMessage("test message");
+ le.setTimeStamp(System.currentTimeMillis());
+ le.setThreadName(Thread.currentThread().getName());
+ return le;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSTopicAppenderTestApp.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSTopicAppenderTestApp.java
index 432458c..935bf4d 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSTopicAppenderTestApp.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/JMSTopicAppenderTestApp.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,42 +20,43 @@ import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.util.StatusPrinter;
public class JMSTopicAppenderTestApp {
-
- public static void main(String[] args) {
- Logger logger = (Logger) LoggerFactory.getLogger(JMSTopicAppenderTestApp.class);
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- lc.reset();
-
- JMSTopicAppender appender = new JMSTopicAppender();
- appender.setContext(lc);
- appender.setName("jmsTopic");
- appender.setInitialContextFactoryName("org.apache.activemq.jndi.ActiveMQInitialContextFactory");
- // appender.setPassword("");
- appender.setProviderURL("tcp://localhost:61616");
- // appender.setSecurityCredentials("");
- // appender.setSecurityPrincipalName("");
- appender.setTopicBindingName("MyTopic");
- appender.setTopicConnectionFactoryBindingName("ConnectionFactory");
- // appender.setURLPkgPrefixes("");
- // appender.setUserName("");
-
- appender.start();
- logger.addAppender(appender);
-
- // JIT
- for (int i = 0; i < 10000; i++) {
- logger.debug("** Hello world. n=" + i);
- }
-
- long before = System.nanoTime();
- for (int i = 0; i < 10000; i++) {
- logger.debug("** Hello world. n=" + i);
- }
- long after = System.nanoTime();
-
- System.out.println("Time per logs for 10'000 logs: " + (after - before) / 10000);
-
- StatusPrinter.print(lc.getStatusManager());
+
+ public static void main(String[] args) {
+ Logger logger = (Logger)LoggerFactory.getLogger(JMSTopicAppenderTestApp.class);
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ lc.reset();
+
+ JMSTopicAppender appender = new JMSTopicAppender();
+ appender.setContext(lc);
+ appender.setName("jmsTopic");
+ appender.setInitialContextFactoryName("org.apache.activemq.jndi.ActiveMQInitialContextFactory");
+ //appender.setPassword("");
+ appender.setProviderURL("tcp://localhost:61616");
+ //appender.setSecurityCredentials("");
+ //appender.setSecurityPrincipalName("");
+ appender.setTopicBindingName("MyTopic");
+ appender.setTopicConnectionFactoryBindingName("ConnectionFactory");
+ //appender.setURLPkgPrefixes("");
+ //appender.setUserName("");
+
+ appender.start();
+ logger.addAppender(appender);
+
+
+ //JIT
+ for (int i = 0; i < 10000; i++) {
+ logger.debug("** Hello world. n=" + i);
+ }
+
+ long before = System.nanoTime();
+ for (int i = 0; i < 10000; i++) {
+ logger.debug("** Hello world. n=" + i);
}
+ long after = System.nanoTime();
+
+ System.out.println("Time per logs for 10'000 logs: " + (after-before)/10000);
+
+ StatusPrinter.print(lc.getStatusManager());
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/NOPOutputStream.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/NOPOutputStream.java
index 58845b0..07720fd 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/NOPOutputStream.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/NOPOutputStream.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,24 +18,25 @@ import java.io.OutputStream;
public class NOPOutputStream extends OutputStream {
- long count;
+ long count;
- @Override
- public void write(int b) throws IOException {
- count++;
- // do nothing
- }
+ @Override
+ public void write(int b) throws IOException {
+ count++;
+ // do nothing
+ }
- public long getCount() {
- return count;
- }
+ public long getCount() {
+ return count;
+ }
- public long size() {
- return count;
- }
+ public long size() {
+ return count;
+ }
- public void reset() {
- count = 0;
- }
+
+ public void reset() {
+ count = 0;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/PackageTest.java
index 80b70e2..85d9920 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,7 +18,9 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ SyslogAppenderTest.class, DilutedSMTPAppenderTest.class, JMSQueueAppenderTest.class, JMSTopicAppenderTest.class, SMTPAppender_GreenTest.class,
- SMTPAppender_SubethaSMTPTest.class, SocketReceiverTest.class, SSLSocketReceiverTest.class })
+ at SuiteClasses( { SyslogAppenderTest.class, DilutedSMTPAppenderTest.class,
+ JMSQueueAppenderTest.class, JMSTopicAppenderTest.class,
+ SMTPAppender_GreenTest.class, SMTPAppender_SubethaSMTPTest.class,
+ SocketReceiverTest.class, SSLSocketReceiverTest.class })
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java
index f4f5c62..7f54c79 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,7 +26,6 @@ import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.status.OnConsoleStatusListener;
import ch.qos.logback.core.testUtil.EnvUtilForTests;
import ch.qos.logback.core.testUtil.RandomUtil;
-import ch.qos.logback.core.util.StatusListenerConfigHelper;
import com.icegreen.greenmail.util.GreenMail;
import com.icegreen.greenmail.util.GreenMailUtil;
@@ -53,316 +52,321 @@ import static org.junit.Assert.*;
public class SMTPAppender_GreenTest {
- static final String HEADER = "HEADER\n";
- static final String FOOTER = "FOOTER\n";
- static final String DEFAULT_PATTERN = "%-4relative %mdc [%thread] %-5level %class - %msg%n";
-
- static final boolean SYNCHRONOUS = false;
- static final boolean ASYNCHRONOUS = true;
-
- int port = RandomUtil.getRandomServerPort();
- // GreenMail cannot be static. As a shared server induces race conditions
- GreenMail greenMailServer;
-
- SMTPAppender smtpAppender;
- LoggerContext loggerContext = new LoggerContext();
- Logger logger = loggerContext.getLogger(this.getClass());
-
- @Before
- public void setUp() throws Exception {
-
- StatusListenerConfigHelper.addOnConsoleListenerInstance(loggerContext, new OnConsoleStatusListener());
- MDC.clear();
- ServerSetup serverSetup = new ServerSetup(port, "localhost", ServerSetup.PROTOCOL_SMTP);
- greenMailServer = new GreenMail(serverSetup);
- greenMailServer.start();
- // give the server a head start
- if (EnvUtilForTests.isRunningOnSlowJenkins()) {
- Thread.sleep(2000);
- } else {
- Thread.sleep(50);
- }
- }
-
- @After
- public void tearDown() throws Exception {
- greenMailServer.stop();
- }
+ static final String HEADER = "HEADER\n";
+ static final String FOOTER = "FOOTER\n";
+ static final String DEFAULT_PATTERN = "%-4relative %mdc [%thread] %-5level %class - %msg%n";
- void buildSMTPAppender(String subject, boolean synchronicity) throws Exception {
- smtpAppender = new SMTPAppender();
- smtpAppender.setContext(loggerContext);
- smtpAppender.setName("smtp");
- smtpAppender.setFrom("user at host.dom");
- smtpAppender.setSMTPHost("localhost");
- smtpAppender.setSMTPPort(port);
- smtpAppender.setSubject(subject);
- smtpAppender.addTo("nospam at qos.ch");
- smtpAppender.setAsynchronousSending(synchronicity);
- }
+ static final boolean SYNCHRONOUS = false;
+ static final boolean ASYNCHRONOUS = true;
- private Layout<ILoggingEvent> buildPatternLayout(String pattern) {
- PatternLayout layout = new PatternLayout();
- layout.setContext(loggerContext);
- layout.setFileHeader(HEADER);
- layout.setOutputPatternAsHeader(false);
- layout.setPattern(pattern);
- layout.setFileFooter(FOOTER);
- layout.start();
- return layout;
- }
+ int port = RandomUtil.getRandomServerPort();
+ // GreenMail cannot be static. As a shared server induces race conditions
+ GreenMail greenMailServer;
- private Layout<ILoggingEvent> buildHTMLLayout() {
- HTMLLayout layout = new HTMLLayout();
- layout.setContext(loggerContext);
- layout.setPattern("%level%class%msg");
- layout.start();
- return layout;
- }
+ SMTPAppender smtpAppender;
+ LoggerContext loggerContext = new LoggerContext();
+ Logger logger = loggerContext.getLogger(this.getClass());
- private void waitForServerToReceiveEmails(int emailCount) throws InterruptedException {
- greenMailServer.waitForIncomingEmail(5000, emailCount);
- }
- private MimeMultipart verifyAndExtractMimeMultipart(String subject) throws MessagingException, IOException, InterruptedException {
- int oldCount = 0;
- int expectedEmailCount = 1;
- // wait for the server to receive the messages
- waitForServerToReceiveEmails(expectedEmailCount);
- MimeMessage[] mma = greenMailServer.getReceivedMessages();
- assertNotNull(mma);
- assertEquals(expectedEmailCount, mma.length);
- MimeMessage mm = mma[oldCount];
- // http://jira.qos.ch/browse/LBCLASSIC-67
- assertEquals(subject, mm.getSubject());
- return (MimeMultipart) mm.getContent();
- }
+ @Before
+ public void setUp() throws Exception {
- void waitUntilEmailIsSent() throws InterruptedException {
- loggerContext.getExecutorService().shutdown();
- loggerContext.getExecutorService().awaitTermination(1000, TimeUnit.MILLISECONDS);
+ OnConsoleStatusListener.addNewInstanceToContext(loggerContext);
+ MDC.clear();
+ ServerSetup serverSetup = new ServerSetup(port, "localhost",
+ ServerSetup.PROTOCOL_SMTP);
+ greenMailServer = new GreenMail(serverSetup);
+ greenMailServer.start();
+ // give the server a head start
+ if (EnvUtilForTests.isRunningOnSlowJenkins()) {
+ Thread.sleep(2000);
+ } else {
+ Thread.sleep(50);
}
-
- @Test
- public void synchronousSmoke() throws Exception {
- String subject = "synchronousSmoke";
- buildSMTPAppender(subject, SYNCHRONOUS);
-
- smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
- smtpAppender.start();
- logger.addAppender(smtpAppender);
- logger.debug("hello");
- logger.error("en error", new Exception("an exception"));
-
- MimeMultipart mp = verifyAndExtractMimeMultipart(subject);
- String body = GreenMailUtil.getBody(mp.getBodyPart(0));
- assertTrue(body.startsWith(HEADER.trim()));
- assertTrue(body.endsWith(FOOTER.trim()));
- }
-
- @Test
- public void asynchronousSmoke() throws Exception {
- String subject = "asynchronousSmoke";
- buildSMTPAppender(subject, ASYNCHRONOUS);
- smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
- smtpAppender.start();
- logger.addAppender(smtpAppender);
- logger.debug("hello");
- logger.error("en error", new Exception("an exception"));
-
- waitUntilEmailIsSent();
- MimeMultipart mp = verifyAndExtractMimeMultipart(subject);
- String body = GreenMailUtil.getBody(mp.getBodyPart(0));
- assertTrue(body.startsWith(HEADER.trim()));
- assertTrue(body.endsWith(FOOTER.trim()));
- }
-
- // See also http://jira.qos.ch/browse/LOGBACK-734
- @Test
- public void callerDataShouldBeCorrectlySetWithAsynchronousSending() throws Exception {
- String subject = "LOGBACK-734";
- buildSMTPAppender("LOGBACK-734", ASYNCHRONOUS);
- smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
- smtpAppender.setIncludeCallerData(true);
- smtpAppender.start();
- logger.addAppender(smtpAppender);
- logger.debug("LOGBACK-734");
- logger.error("callerData", new Exception("ShouldBeCorrectlySetWithAsynchronousSending"));
-
- waitUntilEmailIsSent();
- MimeMultipart mp = verifyAndExtractMimeMultipart(subject);
- String body = GreenMailUtil.getBody(mp.getBodyPart(0));
- assertTrue("actual [" + body + "]", body.contains("DEBUG " + this.getClass().getName() + " - LOGBACK-734"));
- }
-
- // lost MDC
- @Test
- public void LBCLASSIC_104() throws Exception {
- String subject = "LBCLASSIC_104";
- buildSMTPAppender(subject, SYNCHRONOUS);
- smtpAppender.setAsynchronousSending(false);
- smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
- smtpAppender.start();
- logger.addAppender(smtpAppender);
- MDC.put("key", "val");
- logger.debug("LBCLASSIC_104");
- MDC.clear();
- logger.error("en error", new Exception("test"));
-
- MimeMultipart mp = verifyAndExtractMimeMultipart(subject);
- String body = GreenMailUtil.getBody(mp.getBodyPart(0));
- assertTrue(body.startsWith(HEADER.trim()));
- System.out.println(body);
- assertTrue(body.contains("key=val"));
- assertTrue(body.endsWith(FOOTER.trim()));
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ greenMailServer.stop();
+ }
+
+ void buildSMTPAppender(String subject, boolean synchronicity) throws Exception {
+ smtpAppender = new SMTPAppender();
+ smtpAppender.setContext(loggerContext);
+ smtpAppender.setName("smtp");
+ smtpAppender.setFrom("user at host.dom");
+ smtpAppender.setSMTPHost("localhost");
+ smtpAppender.setSMTPPort(port);
+ smtpAppender.setSubject(subject);
+ smtpAppender.addTo("nospam at qos.ch");
+ smtpAppender.setAsynchronousSending(synchronicity);
+ }
+
+ private Layout<ILoggingEvent> buildPatternLayout(String pattern) {
+ PatternLayout layout = new PatternLayout();
+ layout.setContext(loggerContext);
+ layout.setFileHeader(HEADER);
+ layout.setOutputPatternAsHeader(false);
+ layout.setPattern(pattern);
+ layout.setFileFooter(FOOTER);
+ layout.start();
+ return layout;
+ }
+
+ private Layout<ILoggingEvent> buildHTMLLayout() {
+ HTMLLayout layout = new HTMLLayout();
+ layout.setContext(loggerContext);
+ layout.setPattern("%level%class%msg");
+ layout.start();
+ return layout;
+ }
+
+ private void waitForServerToReceiveEmails(int emailCount) throws InterruptedException {
+ greenMailServer.waitForIncomingEmail(5000, emailCount);
+ }
+
+ private MimeMultipart verifyAndExtractMimeMultipart(String subject) throws MessagingException,
+ IOException, InterruptedException {
+ int oldCount = 0;
+ int expectedEmailCount = 1;
+ // wait for the server to receive the messages
+ waitForServerToReceiveEmails(expectedEmailCount);
+ MimeMessage[] mma = greenMailServer.getReceivedMessages();
+ assertNotNull(mma);
+ assertEquals(expectedEmailCount, mma.length);
+ MimeMessage mm = mma[oldCount];
+ // http://jira.qos.ch/browse/LBCLASSIC-67
+ assertEquals(subject, mm.getSubject());
+ return (MimeMultipart) mm.getContent();
+ }
+
+ void waitUntilEmailIsSent() throws InterruptedException {
+ loggerContext.getExecutorService().shutdown();
+ loggerContext.getExecutorService().awaitTermination(1000, TimeUnit.MILLISECONDS);
+ }
+
+ @Test
+ public void synchronousSmoke() throws Exception {
+ String subject = "synchronousSmoke";
+ buildSMTPAppender(subject, SYNCHRONOUS);
+
+ smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
+ smtpAppender.start();
+ logger.addAppender(smtpAppender);
+ logger.debug("hello");
+ logger.error("en error", new Exception("an exception"));
+
+ MimeMultipart mp = verifyAndExtractMimeMultipart(subject);
+ String body = GreenMailUtil.getBody(mp.getBodyPart(0));
+ assertTrue(body.startsWith(HEADER.trim()));
+ assertTrue(body.endsWith(FOOTER.trim()));
+ }
+
+ @Test
+ public void asynchronousSmoke() throws Exception {
+ String subject = "asynchronousSmoke";
+ buildSMTPAppender(subject, ASYNCHRONOUS);
+ smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
+ smtpAppender.start();
+ logger.addAppender(smtpAppender);
+ logger.debug("hello");
+ logger.error("en error", new Exception("an exception"));
+
+ waitUntilEmailIsSent();
+ MimeMultipart mp = verifyAndExtractMimeMultipart(subject);
+ String body = GreenMailUtil.getBody(mp.getBodyPart(0));
+ assertTrue(body.startsWith(HEADER.trim()));
+ assertTrue(body.endsWith(FOOTER.trim()));
+ }
+
+ // See also http://jira.qos.ch/browse/LOGBACK-734
+ @Test
+ public void callerDataShouldBeCorrectlySetWithAsynchronousSending() throws Exception {
+ String subject = "LOGBACK-734";
+ buildSMTPAppender("LOGBACK-734", ASYNCHRONOUS);
+ smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
+ smtpAppender.setIncludeCallerData(true);
+ smtpAppender.start();
+ logger.addAppender(smtpAppender);
+ logger.debug("LOGBACK-734");
+ logger.error("callerData", new Exception("ShouldBeCorrectlySetWithAsynchronousSending"));
+
+ waitUntilEmailIsSent();
+ MimeMultipart mp = verifyAndExtractMimeMultipart(subject);
+ String body = GreenMailUtil.getBody(mp.getBodyPart(0));
+ assertTrue("actual [" + body + "]", body.contains("DEBUG " + this.getClass().getName() + " - LOGBACK-734"));
+ }
+
+ // lost MDC
+ @Test
+ public void LBCLASSIC_104() throws Exception {
+ String subject = "LBCLASSIC_104";
+ buildSMTPAppender(subject, SYNCHRONOUS);
+ smtpAppender.setAsynchronousSending(false);
+ smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
+ smtpAppender.start();
+ logger.addAppender(smtpAppender);
+ MDC.put("key", "val");
+ logger.debug("LBCLASSIC_104");
+ MDC.clear();
+ logger.error("en error", new Exception("test"));
+
+ MimeMultipart mp = verifyAndExtractMimeMultipart(subject);
+ String body = GreenMailUtil.getBody(mp.getBodyPart(0));
+ assertTrue(body.startsWith(HEADER.trim()));
+ System.out.println(body);
+ assertTrue(body.contains("key=val"));
+ assertTrue(body.endsWith(FOOTER.trim()));
+ }
+
+ @Test
+ public void html() throws Exception {
+ String subject = "html";
+ buildSMTPAppender(subject, SYNCHRONOUS);
+ smtpAppender.setAsynchronousSending(false);
+ smtpAppender.setLayout(buildHTMLLayout());
+ smtpAppender.start();
+ logger.addAppender(smtpAppender);
+ logger.debug("html");
+ logger.error("en error", new Exception("an exception"));
+
+ MimeMultipart mp = verifyAndExtractMimeMultipart(subject);
+
+ // verifyAndExtractMimeMultipart strict adherence to xhtml1-strict.dtd
+ SAXReader reader = new SAXReader();
+ reader.setValidation(true);
+ reader.setEntityResolver(new XHTMLEntityResolver());
+ byte[] messageBytes = getAsByteArray(mp.getBodyPart(0).getInputStream());
+ ByteArrayInputStream bais = new ByteArrayInputStream(messageBytes);
+ try {
+ reader.read(bais);
+ } catch (DocumentException de) {
+ System.out.println("incoming message:");
+ System.out.println(new String(messageBytes));
+ throw de;
}
+ }
- @Test
- public void html() throws Exception {
- String subject = "html";
- buildSMTPAppender(subject, SYNCHRONOUS);
- smtpAppender.setAsynchronousSending(false);
- smtpAppender.setLayout(buildHTMLLayout());
- smtpAppender.start();
- logger.addAppender(smtpAppender);
- logger.debug("html");
- logger.error("en error", new Exception("an exception"));
-
- MimeMultipart mp = verifyAndExtractMimeMultipart(subject);
-
- // verifyAndExtractMimeMultipart strict adherence to xhtml1-strict.dtd
- SAXReader reader = new SAXReader();
- reader.setValidation(true);
- reader.setEntityResolver(new XHTMLEntityResolver());
- byte[] messageBytes = getAsByteArray(mp.getBodyPart(0).getInputStream());
- ByteArrayInputStream bais = new ByteArrayInputStream(messageBytes);
- try {
- reader.read(bais);
- } catch (DocumentException de) {
- System.out.println("incoming message:");
- System.out.println(new String(messageBytes));
- throw de;
- }
- }
-
- private byte[] getAsByteArray(InputStream inputStream) throws IOException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
- byte[] buffer = new byte[1024];
- int n = -1;
- while ((n = inputStream.read(buffer)) != -1) {
- baos.write(buffer, 0, n);
- }
- return baos.toByteArray();
- }
-
- private void configure(String file) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(loggerContext);
- loggerContext.putProperty("port", "" + port);
- jc.doConfigure(file);
- }
-
- @Test
- public void testCustomEvaluator() throws Exception {
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "smtp/customEvaluator.xml");
-
- logger.debug("test");
- String msg2 = "CustomEvaluator";
- logger.debug(msg2);
- logger.debug("invisible");
- waitUntilEmailIsSent();
- MimeMultipart mp = verifyAndExtractMimeMultipart("testCustomEvaluator " + this.getClass().getName() + " - " + msg2);
- String body = GreenMailUtil.getBody(mp.getBodyPart(0));
- assertEquals("testCustomEvaluator", body);
- }
-
- @Test
- public void testCustomBufferSize() throws Exception {
- configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "smtp/customBufferSize.xml");
-
- logger.debug("invisible1");
- logger.debug("invisible2");
- String msg = "hello";
- logger.error(msg);
- waitUntilEmailIsSent();
- MimeMultipart mp = verifyAndExtractMimeMultipart("testCustomBufferSize " + this.getClass().getName() + " - " + msg);
- String body = GreenMailUtil.getBody(mp.getBodyPart(0));
- assertEquals(msg, body);
- }
-
- // this test fails intermittently on Jenkins.
- @Test
- public void testMultipleTo() throws Exception {
- buildSMTPAppender("testMultipleTo", SYNCHRONOUS);
- smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
- // buildSMTPAppender() already added one destination address
- smtpAppender.addTo("Test <test at example.com>, other-test at example.com");
- smtpAppender.start();
- logger.addAppender(smtpAppender);
- logger.debug("testMultipleTo hello");
- logger.error("testMultipleTo en error", new Exception("an exception"));
- Thread.yield();
- int expectedEmailCount = 3;
- waitForServerToReceiveEmails(expectedEmailCount);
- MimeMessage[] mma = greenMailServer.getReceivedMessages();
- assertNotNull(mma);
- assertEquals(expectedEmailCount, mma.length);
- }
-
- // http://jira.qos.ch/browse/LBCLASSIC-221
- @Test
- public void bufferShouldBeResetBetweenMessages() throws Exception {
- buildSMTPAppender("bufferShouldBeResetBetweenMessages", SYNCHRONOUS);
- smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
- smtpAppender.start();
- logger.addAppender(smtpAppender);
- String msg0 = "hello zero";
- logger.debug(msg0);
- logger.error("error zero");
-
- String msg1 = "hello one";
- logger.debug(msg1);
- logger.error("error one");
-
- Thread.yield();
- int oldCount = 0;
- int expectedEmailCount = oldCount + 2;
- waitForServerToReceiveEmails(expectedEmailCount);
-
- MimeMessage[] mma = greenMailServer.getReceivedMessages();
- assertNotNull(mma);
- assertEquals(expectedEmailCount, mma.length);
-
- MimeMessage mm0 = mma[oldCount];
- MimeMultipart content0 = (MimeMultipart) mm0.getContent();
- String body0 = GreenMailUtil.getBody(content0.getBodyPart(0));
-
- MimeMessage mm1 = mma[oldCount + 1];
- MimeMultipart content1 = (MimeMultipart) mm1.getContent();
- String body1 = GreenMailUtil.getBody(content1.getBodyPart(0));
- // second body should not contain content from first message
- assertFalse(body1.contains(msg0));
- }
+ private byte[] getAsByteArray(InputStream inputStream) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
- @Test
- public void multiLineSubjectTruncatedAtFirstNewLine() throws Exception {
- String line1 = "line 1 of subject";
- String subject = line1 + "\nline 2 of subject\n";
- buildSMTPAppender(subject, ASYNCHRONOUS);
-
- smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
- smtpAppender.start();
- logger.addAppender(smtpAppender);
- logger.debug("hello");
- logger.error("en error", new Exception("an exception"));
-
- Thread.yield();
- waitUntilEmailIsSent();
- waitForServerToReceiveEmails(1);
-
- MimeMessage[] mma = greenMailServer.getReceivedMessages();
- assertEquals(1, mma.length);
- assertEquals(line1, mma[0].getSubject());
+ byte[] buffer = new byte[1024];
+ int n = -1;
+ while ((n = inputStream.read(buffer)) != -1) {
+ baos.write(buffer, 0, n);
}
+ return baos.toByteArray();
+ }
+
+ private void configure(String file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ loggerContext.putProperty("port", "" + port);
+ jc.doConfigure(file);
+ }
+
+ @Test
+ public void testCustomEvaluator() throws Exception {
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "smtp/customEvaluator.xml");
+
+ logger.debug("test");
+ String msg2 = "CustomEvaluator";
+ logger.debug(msg2);
+ logger.debug("invisible");
+ waitUntilEmailIsSent();
+ MimeMultipart mp = verifyAndExtractMimeMultipart("testCustomEvaluator " + this.getClass().getName() + " - " + msg2);
+ String body = GreenMailUtil.getBody(mp.getBodyPart(0));
+ assertEquals("testCustomEvaluator", body);
+ }
+
+ @Test
+ public void testCustomBufferSize() throws Exception {
+ configure(ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "smtp/customBufferSize.xml");
+
+ logger.debug("invisible1");
+ logger.debug("invisible2");
+ String msg = "hello";
+ logger.error(msg);
+ waitUntilEmailIsSent();
+ MimeMultipart mp = verifyAndExtractMimeMultipart("testCustomBufferSize " + this.getClass().getName() + " - " + msg);
+ String body = GreenMailUtil.getBody(mp.getBodyPart(0));
+ assertEquals(msg, body);
+ }
+
+ // this test fails intermittently on Jenkins.
+ @Test
+ public void testMultipleTo() throws Exception {
+ buildSMTPAppender("testMultipleTo", SYNCHRONOUS);
+ smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
+ // buildSMTPAppender() already added one destination address
+ smtpAppender.addTo("Test <test at example.com>, other-test at example.com");
+ smtpAppender.start();
+ logger.addAppender(smtpAppender);
+ logger.debug("testMultipleTo hello");
+ logger.error("testMultipleTo en error", new Exception("an exception"));
+ Thread.yield();
+ int expectedEmailCount = 3;
+ waitForServerToReceiveEmails(expectedEmailCount);
+ MimeMessage[] mma = greenMailServer.getReceivedMessages();
+ assertNotNull(mma);
+ assertEquals(expectedEmailCount, mma.length);
+ }
+
+ // http://jira.qos.ch/browse/LBCLASSIC-221
+ @Test
+ public void bufferShouldBeResetBetweenMessages() throws Exception {
+ buildSMTPAppender("bufferShouldBeResetBetweenMessages", SYNCHRONOUS);
+ smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
+ smtpAppender.start();
+ logger.addAppender(smtpAppender);
+ String msg0 = "hello zero";
+ logger.debug(msg0);
+ logger.error("error zero");
+
+ String msg1 = "hello one";
+ logger.debug(msg1);
+ logger.error("error one");
+
+ Thread.yield();
+ int oldCount = 0;
+ int expectedEmailCount = oldCount + 2;
+ waitForServerToReceiveEmails(expectedEmailCount);
+
+ MimeMessage[] mma = greenMailServer.getReceivedMessages();
+ assertNotNull(mma);
+ assertEquals(expectedEmailCount, mma.length);
+
+ MimeMessage mm0 = mma[oldCount];
+ MimeMultipart content0 = (MimeMultipart) mm0.getContent();
+ String body0 = GreenMailUtil.getBody(content0.getBodyPart(0));
+
+ MimeMessage mm1 = mma[oldCount + 1];
+ MimeMultipart content1 = (MimeMultipart) mm1.getContent();
+ String body1 = GreenMailUtil.getBody(content1.getBodyPart(0));
+ // second body should not contain content from first message
+ assertFalse(body1.contains(msg0));
+ }
+
+ @Test
+ public void multiLineSubjectTruncatedAtFirstNewLine() throws Exception {
+ String line1 = "line 1 of subject";
+ String subject = line1 + "\nline 2 of subject\n";
+ buildSMTPAppender(subject, ASYNCHRONOUS);
+
+ smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
+ smtpAppender.start();
+ logger.addAppender(smtpAppender);
+ logger.debug("hello");
+ logger.error("en error", new Exception("an exception"));
+
+ Thread.yield();
+ waitUntilEmailIsSent();
+ waitForServerToReceiveEmails(1);
+
+ MimeMessage[] mma = greenMailServer.getReceivedMessages();
+ assertEquals(1, mma.length);
+ assertEquals(line1, mma[0].getSubject());
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_SubethaSMTPTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_SubethaSMTPTest.java
index 4201b06..8636cde 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_SubethaSMTPTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_SubethaSMTPTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -51,315 +51,320 @@ import ch.qos.logback.core.Layout;
import ch.qos.logback.core.util.StatusPrinter;
public class SMTPAppender_SubethaSMTPTest {
- static final String TEST_SUBJECT = "test subject";
- static final String HEADER = "HEADER\n";
- static final String FOOTER = "FOOTER\n";
-
- static int DIFF = 1024 + new Random().nextInt(30000);
- static Wiser WISER;
-
- SMTPAppender smtpAppender;
- LoggerContext loggerContext = new LoggerContext();
-
- int numberOfOldMessages;
-
- @BeforeClass
- static public void beforeClass() {
- WISER = new Wiser();
- WISER.setPort(DIFF);
- WISER.start();
- }
-
- @AfterClass
- static public void afterClass() throws Exception {
- WISER.stop();
- }
-
- @Before
- public void setUp() throws Exception {
- numberOfOldMessages = WISER.getMessages().size();
- buildSMTPAppender();
- }
-
- @After
- public void tearDown() {
- // clear any authentication handler factory
- MessageListenerAdapter mla = (MessageListenerAdapter) WISER.getServer().getMessageHandlerFactory();
- mla.setAuthenticationHandlerFactory(null);
- }
-
- void buildSMTPAppender() throws Exception {
- smtpAppender = new SMTPAppender();
- smtpAppender.setContext(loggerContext);
- smtpAppender.setName("smtp");
- smtpAppender.setFrom("user at host.dom");
- smtpAppender.setSMTPHost("localhost");
- smtpAppender.setSMTPPort(DIFF);
- smtpAppender.setSubject(TEST_SUBJECT);
- smtpAppender.addTo("noreply at qos.ch");
- }
-
- private Layout<ILoggingEvent> buildPatternLayout(LoggerContext lc) {
- PatternLayout layout = new PatternLayout();
- layout.setContext(lc);
- layout.setFileHeader(HEADER);
- layout.setPattern("%-4relative [%thread] %-5level %logger %class - %msg%n");
- layout.setFileFooter(FOOTER);
- layout.start();
- return layout;
- }
-
- private Layout<ILoggingEvent> buildHTMLLayout(LoggerContext lc) {
- HTMLLayout layout = new HTMLLayout();
- layout.setContext(lc);
- // layout.setFileHeader(HEADER);
- layout.setPattern("%level%class%msg");
- // layout.setFileFooter(FOOTER);
- layout.start();
- return layout;
- }
-
- private static String getWholeMessage(Part msg) {
- try {
- ByteArrayOutputStream bodyOut = new ByteArrayOutputStream();
- msg.writeTo(bodyOut);
- return bodyOut.toString("US-ASCII").trim();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- void waitUntilEmailIsSent() throws Exception {
- System.out.println("About to wait for sending thread to finish");
- loggerContext.getExecutorService().shutdown();
- loggerContext.getExecutorService().awaitTermination(3000, TimeUnit.MILLISECONDS);
- }
-
- private static String getBody(Part msg) {
- String all = getWholeMessage(msg);
- int i = all.indexOf("\r\n\r\n");
- return all.substring(i + 4, all.length());
- }
-
- @Test
- public void smoke() throws Exception {
- smtpAppender.setLayout(buildPatternLayout(loggerContext));
- smtpAppender.start();
- Logger logger = loggerContext.getLogger("test");
- logger.addAppender(smtpAppender);
- logger.debug("hello");
- logger.error("en error", new Exception("an exception"));
-
- waitUntilEmailIsSent();
- System.out.println("*** " + ((ThreadPoolExecutor) loggerContext.getExecutorService()).getCompletedTaskCount());
- List<WiserMessage> wiserMsgList = WISER.getMessages();
-
- assertNotNull(wiserMsgList);
- assertEquals(numberOfOldMessages + 1, wiserMsgList.size());
- WiserMessage wm = wiserMsgList.get(numberOfOldMessages);
- // http://jira.qos.ch/browse/LBCLASSIC-67
- MimeMessage mm = wm.getMimeMessage();
- assertEquals(TEST_SUBJECT, mm.getSubject());
-
- MimeMultipart mp = (MimeMultipart) mm.getContent();
- String body = getBody(mp.getBodyPart(0));
- System.out.println("[" + body);
- assertTrue(body.startsWith(HEADER.trim()));
- assertTrue(body.endsWith(FOOTER.trim()));
- }
-
- @Test
- public void html() throws Exception {
-
- smtpAppender.setLayout(buildHTMLLayout(loggerContext));
- smtpAppender.start();
- Logger logger = loggerContext.getLogger("test");
- logger.addAppender(smtpAppender);
- logger.debug("hello");
- logger.error("en error", new Exception("an exception"));
- waitUntilEmailIsSent();
-
- List<WiserMessage> wiserMsgList = WISER.getMessages();
-
- assertNotNull(wiserMsgList);
- assertEquals(numberOfOldMessages + 1, wiserMsgList.size());
- WiserMessage wm = wiserMsgList.get(numberOfOldMessages);
- MimeMessage mm = wm.getMimeMessage();
- assertEquals(TEST_SUBJECT, mm.getSubject());
-
- MimeMultipart mp = (MimeMultipart) mm.getContent();
-
- // verify strict adherence to xhtml1-strict.dtd
- SAXReader reader = new SAXReader();
- reader.setValidation(true);
- reader.setEntityResolver(new XHTMLEntityResolver());
- reader.read(mp.getBodyPart(0).getInputStream());
- // System.out.println(GreenMailUtil.getBody(mp.getBodyPart(0)));
- }
-
- @Test
- /**
- * Checks that even when many events are processed, the output is still
- * conforms to xhtml-strict.dtd.
- *
- * Note that SMTPAppender only keeps only 500 or so (=buffer size) events. So
- * the generated output will be rather short.
- */
- public void htmlLong() throws Exception {
- smtpAppender.setLayout(buildHTMLLayout(loggerContext));
- smtpAppender.start();
- Logger logger = loggerContext.getLogger("test");
- logger.addAppender(smtpAppender);
- for (int i = 0; i < CoreConstants.TABLE_ROW_LIMIT * 3; i++) {
- logger.debug("hello " + i);
- }
- logger.error("en error", new Exception("an exception"));
- waitUntilEmailIsSent();
- List<WiserMessage> wiserMsgList = WISER.getMessages();
-
- assertNotNull(wiserMsgList);
- assertEquals(numberOfOldMessages + 1, wiserMsgList.size());
- WiserMessage wm = wiserMsgList.get(numberOfOldMessages);
- MimeMessage mm = wm.getMimeMessage();
- assertEquals(TEST_SUBJECT, mm.getSubject());
-
- MimeMultipart mp = (MimeMultipart) mm.getContent();
-
- // verify strict adherence to xhtml1-strict.dtd
- SAXReader reader = new SAXReader();
- reader.setValidation(true);
- reader.setEntityResolver(new XHTMLEntityResolver());
- reader.read(mp.getBodyPart(0).getInputStream());
+ static final String TEST_SUBJECT = "test subject";
+ static final String HEADER = "HEADER\n";
+ static final String FOOTER = "FOOTER\n";
+
+ static int DIFF = 1024 + new Random().nextInt(30000);
+ static Wiser WISER;
+
+ SMTPAppender smtpAppender;
+ LoggerContext loggerContext = new LoggerContext();
+
+ int numberOfOldMessages;
+
+
+ @BeforeClass
+ static public void beforeClass() {
+ WISER = new Wiser();
+ WISER.setPort(DIFF);
+ WISER.start();
+ }
+
+ @AfterClass
+ static public void afterClass() throws Exception {
+ WISER.stop();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ numberOfOldMessages = WISER.getMessages().size();
+ buildSMTPAppender();
+ }
+
+ @After
+ public void tearDown() {
+ // clear any authentication handler factory
+ MessageListenerAdapter mla = (MessageListenerAdapter) WISER.getServer().getMessageHandlerFactory();
+ mla.setAuthenticationHandlerFactory(null);
+ }
+
+ void buildSMTPAppender() throws Exception {
+ smtpAppender = new SMTPAppender();
+ smtpAppender.setContext(loggerContext);
+ smtpAppender.setName("smtp");
+ smtpAppender.setFrom("user at host.dom");
+ smtpAppender.setSMTPHost("localhost");
+ smtpAppender.setSMTPPort(DIFF);
+ smtpAppender.setSubject(TEST_SUBJECT);
+ smtpAppender.addTo("noreply at qos.ch");
+ }
+
+ private Layout<ILoggingEvent> buildPatternLayout(LoggerContext lc) {
+ PatternLayout layout = new PatternLayout();
+ layout.setContext(lc);
+ layout.setFileHeader(HEADER);
+ layout.setPattern("%-4relative [%thread] %-5level %logger %class - %msg%n");
+ layout.setFileFooter(FOOTER);
+ layout.start();
+ return layout;
+ }
+
+ private Layout<ILoggingEvent> buildHTMLLayout(LoggerContext lc) {
+ HTMLLayout layout = new HTMLLayout();
+ layout.setContext(lc);
+ // layout.setFileHeader(HEADER);
+ layout.setPattern("%level%class%msg");
+ // layout.setFileFooter(FOOTER);
+ layout.start();
+ return layout;
+ }
+
+
+ private static String getWholeMessage(Part msg) {
+ try {
+ ByteArrayOutputStream bodyOut = new ByteArrayOutputStream();
+ msg.writeTo(bodyOut);
+ return bodyOut.toString("US-ASCII").trim();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
}
-
- @Test
- public void authenticated() throws Exception {
- MessageListenerAdapter mla = (MessageListenerAdapter) WISER.getServer().getMessageHandlerFactory();
- mla.setAuthenticationHandlerFactory(new TrivialAuthHandlerFactory());
-
- smtpAppender.setUsername("x");
- smtpAppender.setPassword("x");
-
- smtpAppender.setLayout(buildPatternLayout(loggerContext));
- smtpAppender.start();
- Logger logger = loggerContext.getLogger("test");
- logger.addAppender(smtpAppender);
- logger.debug("hello");
- logger.error("en error", new Exception("an exception"));
- waitUntilEmailIsSent();
- List<WiserMessage> wiserMsgList = WISER.getMessages();
-
- assertNotNull(wiserMsgList);
- assertEquals(numberOfOldMessages + 1, wiserMsgList.size());
- WiserMessage wm = wiserMsgList.get(numberOfOldMessages);
- // http://jira.qos.ch/browse/LBCLASSIC-67
- MimeMessage mm = wm.getMimeMessage();
- assertEquals(TEST_SUBJECT, mm.getSubject());
-
- MimeMultipart mp = (MimeMultipart) mm.getContent();
- String body = getBody(mp.getBodyPart(0));
- assertTrue(body.startsWith(HEADER.trim()));
- assertTrue(body.endsWith(FOOTER.trim()));
- }
-
- @Test
- @Ignore
- // Unfortunately, there seems to be a problem with SubethaSMTP's implementation
- // of startTLS. The same SMTPAppender code works fine when tested with gmail.
- public void authenticatedSSL() throws Exception {
- MessageListenerAdapter mla = (MessageListenerAdapter) WISER.getServer().getMessageHandlerFactory();
- mla.setAuthenticationHandlerFactory(new TrivialAuthHandlerFactory());
-
- smtpAppender.setSTARTTLS(true);
- smtpAppender.setUsername("xx");
- smtpAppender.setPassword("xx");
-
- smtpAppender.setLayout(buildPatternLayout(loggerContext));
- smtpAppender.start();
- Logger logger = loggerContext.getLogger("test");
- logger.addAppender(smtpAppender);
- logger.debug("hello");
- logger.error("en error", new Exception("an exception"));
-
- waitUntilEmailIsSent();
- List<WiserMessage> wiserMsgList = WISER.getMessages();
-
- assertNotNull(wiserMsgList);
- assertEquals(1, wiserMsgList.size());
- }
-
- @Test
- @Ignore
- public void authenticatedGmailStartTLS() throws Exception {
- smtpAppender.setSMTPHost("smtp.gmail.com");
- smtpAppender.setSMTPPort(587);
-
- smtpAppender.addTo("XXX at gmail.com");
- smtpAppender.setSTARTTLS(true);
- smtpAppender.setUsername("XXX at gmail.com");
- smtpAppender.setPassword("XXX");
-
- smtpAppender.setLayout(buildPatternLayout(loggerContext));
- smtpAppender.start();
- Logger logger = loggerContext.getLogger("authenticatedGmailSTARTTLS");
- logger.addAppender(smtpAppender);
- logger.debug("hello");
- logger.error("en error", new Exception("an exception"));
-
- StatusPrinter.print(loggerContext);
+ }
+
+ void waitUntilEmailIsSent() throws Exception {
+ System.out.println("About to wait for sending thread to finish");
+ loggerContext.getExecutorService().shutdown();
+ loggerContext.getExecutorService().awaitTermination(3000, TimeUnit.MILLISECONDS);
+ }
+
+ private static String getBody(Part msg) {
+ String all = getWholeMessage(msg);
+ int i = all.indexOf("\r\n\r\n");
+ return all.substring(i + 4, all.length());
+ }
+
+ @Test
+ public void smoke() throws Exception {
+ smtpAppender.setLayout(buildPatternLayout(loggerContext));
+ smtpAppender.start();
+ Logger logger = loggerContext.getLogger("test");
+ logger.addAppender(smtpAppender);
+ logger.debug("hello");
+ logger.error("en error", new Exception("an exception"));
+
+ waitUntilEmailIsSent();
+ System.out.println("*** " + ((ThreadPoolExecutor) loggerContext.getExecutorService()).getCompletedTaskCount());
+ List<WiserMessage> wiserMsgList = WISER.getMessages();
+
+ assertNotNull(wiserMsgList);
+ assertEquals(numberOfOldMessages+1, wiserMsgList.size());
+ WiserMessage wm = wiserMsgList.get(numberOfOldMessages);
+ // http://jira.qos.ch/browse/LBCLASSIC-67
+ MimeMessage mm = wm.getMimeMessage();
+ assertEquals(TEST_SUBJECT, mm.getSubject());
+
+ MimeMultipart mp = (MimeMultipart) mm.getContent();
+ String body = getBody(mp.getBodyPart(0));
+ System.out.println("[" + body);
+ assertTrue(body.startsWith(HEADER.trim()));
+ assertTrue(body.endsWith(FOOTER.trim()));
+ }
+
+
+ @Test
+ public void html() throws Exception {
+
+ smtpAppender.setLayout(buildHTMLLayout(loggerContext));
+ smtpAppender.start();
+ Logger logger = loggerContext.getLogger("test");
+ logger.addAppender(smtpAppender);
+ logger.debug("hello");
+ logger.error("en error", new Exception("an exception"));
+ waitUntilEmailIsSent();
+
+ List<WiserMessage> wiserMsgList = WISER.getMessages();
+
+ assertNotNull(wiserMsgList);
+ assertEquals(numberOfOldMessages + 1, wiserMsgList.size());
+ WiserMessage wm = wiserMsgList.get(numberOfOldMessages);
+ MimeMessage mm = wm.getMimeMessage();
+ assertEquals(TEST_SUBJECT, mm.getSubject());
+
+ MimeMultipart mp = (MimeMultipart) mm.getContent();
+
+ // verify strict adherence to xhtml1-strict.dtd
+ SAXReader reader = new SAXReader();
+ reader.setValidation(true);
+ reader.setEntityResolver(new XHTMLEntityResolver());
+ reader.read(mp.getBodyPart(0).getInputStream());
+ // System.out.println(GreenMailUtil.getBody(mp.getBodyPart(0)));
+ }
+
+ @Test
+ /**
+ * Checks that even when many events are processed, the output is still
+ * conforms to xhtml-strict.dtd.
+ *
+ * Note that SMTPAppender only keeps only 500 or so (=buffer size) events. So
+ * the generated output will be rather short.
+ */
+ public void htmlLong() throws Exception {
+ smtpAppender.setLayout(buildHTMLLayout(loggerContext));
+ smtpAppender.start();
+ Logger logger = loggerContext.getLogger("test");
+ logger.addAppender(smtpAppender);
+ for (int i = 0; i < CoreConstants.TABLE_ROW_LIMIT * 3; i++) {
+ logger.debug("hello " + i);
}
-
- @Test
- @Ignore
- public void authenticatedGmail_SSL() throws Exception {
- smtpAppender.setSMTPHost("smtp.gmail.com");
- smtpAppender.setSMTPPort(465);
-
- smtpAppender.addTo("XXX at gmail.com");
- smtpAppender.setSSL(true);
- smtpAppender.setUsername("XXX at gmail.com");
- smtpAppender.setPassword("XXX");
-
- smtpAppender.setLayout(buildPatternLayout(loggerContext));
- smtpAppender.start();
- Logger logger = loggerContext.getLogger("authenticatedGmail_SSL");
- logger.addAppender(smtpAppender);
- logger.debug("hello");
- logger.error("en error", new Exception("an exception"));
-
- StatusPrinter.print(loggerContext);
- }
-
- @Test
- public void testMultipleTo() throws Exception {
- smtpAppender.setLayout(buildPatternLayout(loggerContext));
- smtpAppender.addTo("Test <test at example.com>, other-test at example.com");
- smtpAppender.start();
- Logger logger = loggerContext.getLogger("test");
- logger.addAppender(smtpAppender);
- logger.debug("hello");
- logger.error("en error", new Exception("an exception"));
- waitUntilEmailIsSent();
-
- List<WiserMessage> wiserMsgList = WISER.getMessages();
- assertNotNull(wiserMsgList);
- assertEquals(numberOfOldMessages + 3, wiserMsgList.size());
- }
-
- public class TrivialAuthHandlerFactory implements AuthenticationHandlerFactory {
- public AuthenticationHandler create() {
- PluginAuthenticationHandler ret = new PluginAuthenticationHandler();
- UsernamePasswordValidator validator = new UsernamePasswordValidator() {
- public void login(String username, String password) throws LoginFailedException {
- if (!username.equals(password)) {
- throw new LoginFailedException("username=" + username + ", password=" + password);
- }
- }
- };
- ret.addPlugin(new PlainAuthenticationHandler(validator));
- ret.addPlugin(new LoginAuthenticationHandler(validator));
- return ret;
+ logger.error("en error", new Exception("an exception"));
+ waitUntilEmailIsSent();
+ List<WiserMessage> wiserMsgList = WISER.getMessages();
+
+ assertNotNull(wiserMsgList);
+ assertEquals(numberOfOldMessages + 1, wiserMsgList.size());
+ WiserMessage wm = wiserMsgList.get(numberOfOldMessages);
+ MimeMessage mm = wm.getMimeMessage();
+ assertEquals(TEST_SUBJECT, mm.getSubject());
+
+ MimeMultipart mp = (MimeMultipart) mm.getContent();
+
+ // verify strict adherence to xhtml1-strict.dtd
+ SAXReader reader = new SAXReader();
+ reader.setValidation(true);
+ reader.setEntityResolver(new XHTMLEntityResolver());
+ reader.read(mp.getBodyPart(0).getInputStream());
+ }
+
+ @Test
+ public void authenticated() throws Exception {
+ MessageListenerAdapter mla = (MessageListenerAdapter) WISER.getServer().getMessageHandlerFactory();
+ mla.setAuthenticationHandlerFactory(new TrivialAuthHandlerFactory());
+
+ smtpAppender.setUsername("x");
+ smtpAppender.setPassword("x");
+
+ smtpAppender.setLayout(buildPatternLayout(loggerContext));
+ smtpAppender.start();
+ Logger logger = loggerContext.getLogger("test");
+ logger.addAppender(smtpAppender);
+ logger.debug("hello");
+ logger.error("en error", new Exception("an exception"));
+ waitUntilEmailIsSent();
+ List<WiserMessage> wiserMsgList = WISER.getMessages();
+
+ assertNotNull(wiserMsgList);
+ assertEquals(numberOfOldMessages + 1, wiserMsgList.size());
+ WiserMessage wm = wiserMsgList.get(numberOfOldMessages);
+ // http://jira.qos.ch/browse/LBCLASSIC-67
+ MimeMessage mm = wm.getMimeMessage();
+ assertEquals(TEST_SUBJECT, mm.getSubject());
+
+ MimeMultipart mp = (MimeMultipart) mm.getContent();
+ String body = getBody(mp.getBodyPart(0));
+ assertTrue(body.startsWith(HEADER.trim()));
+ assertTrue(body.endsWith(FOOTER.trim()));
+ }
+
+ @Test
+ @Ignore
+ // Unfortunately, there seems to be a problem with SubethaSMTP's implementation
+ // of startTLS. The same SMTPAppender code works fine when tested with gmail.
+ public void authenticatedSSL() throws Exception {
+ MessageListenerAdapter mla = (MessageListenerAdapter) WISER.getServer().getMessageHandlerFactory();
+ mla.setAuthenticationHandlerFactory(new TrivialAuthHandlerFactory());
+
+
+ smtpAppender.setSTARTTLS(true);
+ smtpAppender.setUsername("xx");
+ smtpAppender.setPassword("xx");
+
+ smtpAppender.setLayout(buildPatternLayout(loggerContext));
+ smtpAppender.start();
+ Logger logger = loggerContext.getLogger("test");
+ logger.addAppender(smtpAppender);
+ logger.debug("hello");
+ logger.error("en error", new Exception("an exception"));
+
+ waitUntilEmailIsSent();
+ List<WiserMessage> wiserMsgList = WISER.getMessages();
+
+ assertNotNull(wiserMsgList);
+ assertEquals(1, wiserMsgList.size());
+ }
+
+ @Test
+ @Ignore
+ public void authenticatedGmailStartTLS() throws Exception {
+ smtpAppender.setSMTPHost("smtp.gmail.com");
+ smtpAppender.setSMTPPort(587);
+
+ smtpAppender.addTo("XXX at gmail.com");
+ smtpAppender.setSTARTTLS(true);
+ smtpAppender.setUsername("XXX at gmail.com");
+ smtpAppender.setPassword("XXX");
+
+ smtpAppender.setLayout(buildPatternLayout(loggerContext));
+ smtpAppender.start();
+ Logger logger = loggerContext.getLogger("authenticatedGmailSTARTTLS");
+ logger.addAppender(smtpAppender);
+ logger.debug("hello");
+ logger.error("en error", new Exception("an exception"));
+
+ StatusPrinter.print(loggerContext);
+ }
+
+ @Test
+ @Ignore
+ public void authenticatedGmail_SSL() throws Exception {
+ smtpAppender.setSMTPHost("smtp.gmail.com");
+ smtpAppender.setSMTPPort(465);
+
+ smtpAppender.addTo("XXX at gmail.com");
+ smtpAppender.setSSL(true);
+ smtpAppender.setUsername("XXX at gmail.com");
+ smtpAppender.setPassword("XXX");
+
+ smtpAppender.setLayout(buildPatternLayout(loggerContext));
+ smtpAppender.start();
+ Logger logger = loggerContext.getLogger("authenticatedGmail_SSL");
+ logger.addAppender(smtpAppender);
+ logger.debug("hello");
+ logger.error("en error", new Exception("an exception"));
+
+ StatusPrinter.print(loggerContext);
+ }
+
+ @Test
+ public void testMultipleTo() throws Exception {
+ smtpAppender.setLayout(buildPatternLayout(loggerContext));
+ smtpAppender.addTo("Test <test at example.com>, other-test at example.com");
+ smtpAppender.start();
+ Logger logger = loggerContext.getLogger("test");
+ logger.addAppender(smtpAppender);
+ logger.debug("hello");
+ logger.error("en error", new Exception("an exception"));
+ waitUntilEmailIsSent();
+
+ List<WiserMessage> wiserMsgList = WISER.getMessages();
+ assertNotNull(wiserMsgList);
+ assertEquals(numberOfOldMessages + 3, wiserMsgList.size());
+ }
+
+ public class TrivialAuthHandlerFactory implements AuthenticationHandlerFactory {
+ public AuthenticationHandler create() {
+ PluginAuthenticationHandler ret = new PluginAuthenticationHandler();
+ UsernamePasswordValidator validator = new UsernamePasswordValidator() {
+ public void login(String username, String password)
+ throws LoginFailedException {
+ if (!username.equals(password)) {
+ throw new LoginFailedException("username=" + username + ", password=" + password);
+ }
}
+ };
+ ret.addPlugin(new PlainAuthenticationHandler(validator));
+ ret.addPlugin(new LoginAuthenticationHandler(validator));
+ return ret;
}
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/SSLSocketReceiverTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/SSLSocketReceiverTest.java
index 1b270c0..dad1166 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/SSLSocketReceiverTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/SSLSocketReceiverTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,21 +30,22 @@ import ch.qos.logback.classic.LoggerContext;
*/
public class SSLSocketReceiverTest {
- private SSLSocketReceiver remote = new SSLSocketReceiver();
-
- @Before
- public void setUp() throws Exception {
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- remote.setContext(lc);
- }
-
- @Test
- public void testUsingDefaultConfig() throws Exception {
- // should be able to start successfully with no SSL configuration at all
- remote.setRemoteHost(InetAddress.getLocalHost().getHostAddress());
- remote.setPort(6000);
- remote.start();
- assertNotNull(remote.getSocketFactory());
- }
-
+ private SSLSocketReceiver remote =
+ new SSLSocketReceiver();
+
+ @Before
+ public void setUp() throws Exception {
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ remote.setContext(lc);
+ }
+
+ @Test
+ public void testUsingDefaultConfig() throws Exception {
+ // should be able to start successfully with no SSL configuration at all
+ remote.setRemoteHost(InetAddress.getLocalHost().getHostAddress());
+ remote.setPort(6000);
+ remote.start();
+ assertNotNull(remote.getSocketFactory());
+ }
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/SerializationPerfTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/SerializationPerfTest.java
index 53024bf..2438ada 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/SerializationPerfTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/SerializationPerfTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,176 +24,180 @@ import ch.qos.logback.classic.net.testObjectBuilders.TrivialLoggingEventVOBuilde
public class SerializationPerfTest extends TestCase {
- ObjectOutputStream oos;
-
- int loopNumber = 10000;
- int resetFrequency = 100;
- int pauseFrequency = 10;
- long pauseLengthInMillis = 20;
-
- /**
- * <p>
- * Run the test with a MockSocketServer or with a NOPOutputStream
- *
- * <p>
- * Run with external mock can be done using the ExternalMockSocketServer. It
- * needs to be launched from a separate JVM. The ExternalMockSocketServer does
- * not consume the events but passes through the available bytes that it is
- * receiving.
- *
- * <p>
- * For example, with 4 test methods, you can launch the
- * ExternalMockSocketServer this way:
- * </p>
- * <p>
- * <code>java ch.qos.logback.classic.net.ExternalMockSocketServer 4</code>
- * </p>
- */
- boolean runWithExternalMockServer = true;
-
- /**
- * Last results:
- * Data sent mesured in kilobytes.
- * Avg time mesured in microsecs.
- *
- * NOPOutputStream:
- * | | Runs | Avg time | Data sent |
- * | MinimalObj Ext | 10000 | | |
- * | MinimalObj Ser | 10000 | | |
- * | LoggEvent Ext | 10000 | | |
- * | LoggEvent Ser | 10000 | | |
- *
- * External MockServer with 45 letters-long message: on localhost
- * (always the same message)
- * | | Runs | Avg time | Data sent |
- * | MinimalObj Ext | 10000 | - | - |
- * | MinimalObj Ser | 10000 | 74 | 248 |
- * | LoggEvent Ext | 10000 | - | - |
- * | LoggEvent Ser | 10000 | 156 | 835 |
- * pauseFrequency = 10 and pauseLengthInMillis = 20
- *
- * External MockServer with 45 letters-long message: on localhost
- * (different message each time)
- * | | Runs | Avg time | Data sent |
- * | MinimalObj Ext | 10000 | | |
- * | MinimalObj Ser | 10000 | 73 | 1139 |
- * | LoggEvent Ext | 10000 | | |
- * | LoggEvent Ser | 10000 | 162 | 1752 |
- * pauseFrequency = 10 and pauseLengthInMillis = 20
- *
- * External MockServer with 45 letters-long message: on PIXIE
- * (always the same message)
- * | | Runs | Avg time | Data sent |
- * | MinimalObj Ext | 10000 | - | - |
- * | MinimalObj Ser | 10000 | 29 | 248 |
- * | LoggEvent Ext | 10000 | - | - |
- * | LoggEvent Ser | 10000 | 42 | 835 |
- * pauseFrequency = 10 and pauseLengthInMillis = 20
- *
- * External MockServer with 45 letters-long message: on PIXIE
- * (different message each time)
- * | | Runs | Avg time | Data sent |
- * | MinimalObj Ext | 10000 | | |
- * | MinimalObj Ser | 10000 | 27 | 1139 |
- * | LoggEvent Ext | 10000 | | |
- * | LoggEvent Ser | 10000 | 44 | 1752 |
- * pauseFrequency = 10 and pauseLengthInMillis = 20
- *
- */
-
- public void setUp() throws Exception {
- super.setUp();
- if (runWithExternalMockServer) {
- oos = new ObjectOutputStream(new Socket("localhost", ExternalMockSocketServer.PORT).getOutputStream());
- } else {
- oos = new ObjectOutputStream(new NOPOutputStream());
- }
- }
-
- public void tearDown() throws Exception {
- super.tearDown();
- oos.close();
- oos = null;
+ ObjectOutputStream oos;
+
+ int loopNumber = 10000;
+ int resetFrequency = 100;
+ int pauseFrequency = 10;
+ long pauseLengthInMillis = 20;
+
+ /**
+ * <p>
+ * Run the test with a MockSocketServer or with a NOPOutputStream
+ *
+ * <p>
+ * Run with external mock can be done using the ExternalMockSocketServer. It
+ * needs to be launched from a separate JVM. The ExternalMockSocketServer does
+ * not consume the events but passes through the available bytes that it is
+ * receiving.
+ *
+ * <p>
+ * For example, with 4 test methods, you can launch the
+ * ExternalMockSocketServer this way:
+ * </p>
+ * <p>
+ * <code>java ch.qos.logback.classic.net.ExternalMockSocketServer 4</code>
+ * </p>
+ */
+ boolean runWithExternalMockServer = true;
+
+ /**
+ * Last results:
+ * Data sent mesured in kilobytes.
+ * Avg time mesured in microsecs.
+ *
+ * NOPOutputStream:
+ * | | Runs | Avg time | Data sent |
+ * | MinimalObj Ext | 10000 | | |
+ * | MinimalObj Ser | 10000 | | |
+ * | LoggEvent Ext | 10000 | | |
+ * | LoggEvent Ser | 10000 | | |
+ *
+ * External MockServer with 45 letters-long message: on localhost
+ * (always the same message)
+ * | | Runs | Avg time | Data sent |
+ * | MinimalObj Ext | 10000 | - | - |
+ * | MinimalObj Ser | 10000 | 74 | 248 |
+ * | LoggEvent Ext | 10000 | - | - |
+ * | LoggEvent Ser | 10000 | 156 | 835 |
+ * pauseFrequency = 10 and pauseLengthInMillis = 20
+ *
+ * External MockServer with 45 letters-long message: on localhost
+ * (different message each time)
+ * | | Runs | Avg time | Data sent |
+ * | MinimalObj Ext | 10000 | | |
+ * | MinimalObj Ser | 10000 | 73 | 1139 |
+ * | LoggEvent Ext | 10000 | | |
+ * | LoggEvent Ser | 10000 | 162 | 1752 |
+ * pauseFrequency = 10 and pauseLengthInMillis = 20
+ *
+ * External MockServer with 45 letters-long message: on PIXIE
+ * (always the same message)
+ * | | Runs | Avg time | Data sent |
+ * | MinimalObj Ext | 10000 | - | - |
+ * | MinimalObj Ser | 10000 | 29 | 248 |
+ * | LoggEvent Ext | 10000 | - | - |
+ * | LoggEvent Ser | 10000 | 42 | 835 |
+ * pauseFrequency = 10 and pauseLengthInMillis = 20
+ *
+ * External MockServer with 45 letters-long message: on PIXIE
+ * (different message each time)
+ * | | Runs | Avg time | Data sent |
+ * | MinimalObj Ext | 10000 | | |
+ * | MinimalObj Ser | 10000 | 27 | 1139 |
+ * | LoggEvent Ext | 10000 | | |
+ * | LoggEvent Ser | 10000 | 44 | 1752 |
+ * pauseFrequency = 10 and pauseLengthInMillis = 20
+ *
+ */
+
+ public void setUp() throws Exception {
+ super.setUp();
+ if (runWithExternalMockServer) {
+ oos = new ObjectOutputStream(new Socket("localhost",
+ ExternalMockSocketServer.PORT).getOutputStream());
+ } else {
+ oos = new ObjectOutputStream(new NOPOutputStream());
}
-
- public void runPerfTest(Builder builder, String label) throws Exception {
- // long time1 = System.nanoTime();
-
- // Object builtObject = builder.build(1);
-
- // first run for just in time compiler
- int resetCounter = 0;
- int pauseCounter = 0;
- for (int i = 0; i < loopNumber; i++) {
- try {
- oos.writeObject(builder.build(i));
- oos.flush();
- if (++resetCounter >= resetFrequency) {
- oos.reset();
- resetCounter = 0;
- }
- if (++pauseCounter >= pauseFrequency) {
- Thread.sleep(pauseLengthInMillis);
- pauseCounter = 0;
- }
-
- } catch (IOException ex) {
- fail(ex.getMessage());
- }
+ }
+
+ public void tearDown() throws Exception {
+ super.tearDown();
+ oos.close();
+ oos = null;
+ }
+
+ public void runPerfTest(Builder builder, String label) throws Exception {
+ // long time1 = System.nanoTime();
+
+ // Object builtObject = builder.build(1);
+
+ // first run for just in time compiler
+ int resetCounter = 0;
+ int pauseCounter = 0;
+ for (int i = 0; i < loopNumber; i++) {
+ try {
+ oos.writeObject(builder.build(i));
+ oos.flush();
+ if (++resetCounter >= resetFrequency) {
+ oos.reset();
+ resetCounter = 0;
}
-
- // second run
- Long t1;
- Long t2;
- Long total = 0L;
- resetCounter = 0;
- pauseCounter = 0;
- // System.out.println("Beginning mesured run");
- for (int i = 0; i < loopNumber; i++) {
- try {
- t1 = System.nanoTime();
- oos.writeObject(builder.build(i));
- oos.flush();
- t2 = System.nanoTime();
- total += (t2 - t1);
- if (++resetCounter >= resetFrequency) {
- oos.reset();
- resetCounter = 0;
- }
- if (++pauseCounter >= pauseFrequency) {
- Thread.sleep(pauseLengthInMillis);
- pauseCounter = 0;
- }
- } catch (IOException ex) {
- fail(ex.getMessage());
- }
+ if (++pauseCounter >= pauseFrequency) {
+ Thread.sleep(pauseLengthInMillis);
+ pauseCounter = 0;
}
- total /= 1000;
- System.out.println(label + " : average time = " + total / loopNumber + " microsecs after " + loopNumber + " writes.");
-
- // long time2 = System.nanoTime();
- // System.out.println("********* -> Time needed to run the test method: " +
- // Long.toString(time2-time1));
- }
-
- // public void testWithMinimalExternalization() throws Exception {
- // Builder builder = new MinimalExtBuilder();
- // runPerfTest(builder, "Minimal object externalization");
- // }
- public void testWithMinimalSerialization() throws Exception {
- Builder builder = new MinimalSerBuilder();
- runPerfTest(builder, "Minimal object serialization");
+ } catch (IOException ex) {
+ fail(ex.getMessage());
+ }
}
- // public void testWithExternalization() throws Exception {
- // Builder builder = new LoggingEventExtBuilder();
- // runPerfTest(builder, "LoggingEvent object externalization");
- // }
-
- public void testWithSerialization() throws Exception {
- Builder builder = new TrivialLoggingEventVOBuilder();
- runPerfTest(builder, "LoggingEventVO object serialization");
+ // second run
+ Long t1;
+ Long t2;
+ Long total = 0L;
+ resetCounter = 0;
+ pauseCounter = 0;
+ // System.out.println("Beginning mesured run");
+ for (int i = 0; i < loopNumber; i++) {
+ try {
+ t1 = System.nanoTime();
+ oos.writeObject(builder.build(i));
+ oos.flush();
+ t2 = System.nanoTime();
+ total += (t2 - t1);
+ if (++resetCounter >= resetFrequency) {
+ oos.reset();
+ resetCounter = 0;
+ }
+ if (++pauseCounter >= pauseFrequency) {
+ Thread.sleep(pauseLengthInMillis);
+ pauseCounter = 0;
+ }
+ } catch (IOException ex) {
+ fail(ex.getMessage());
+ }
}
-
+ total /= 1000;
+ System.out.println(label + " : average time = " + total / loopNumber
+ + " microsecs after " + loopNumber + " writes.");
+
+ // long time2 = System.nanoTime();
+ // System.out.println("********* -> Time needed to run the test method: " +
+ // Long.toString(time2-time1));
+ }
+
+ // public void testWithMinimalExternalization() throws Exception {
+ // Builder builder = new MinimalExtBuilder();
+ // runPerfTest(builder, "Minimal object externalization");
+ // }
+
+ public void testWithMinimalSerialization() throws Exception {
+ Builder builder = new MinimalSerBuilder();
+ runPerfTest(builder, "Minimal object serialization");
+ }
+
+ // public void testWithExternalization() throws Exception {
+ // Builder builder = new LoggingEventExtBuilder();
+ // runPerfTest(builder, "LoggingEvent object externalization");
+ // }
+
+ public void testWithSerialization() throws Exception {
+ Builder builder = new TrivialLoggingEventVOBuilder();
+ runPerfTest(builder, "LoggingEventVO object serialization");
+ }
+
+
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketAppenderMessageLossTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketAppenderMessageLossTest.java
index 25d1bb1..b2a7216 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketAppenderMessageLossTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketAppenderMessageLossTest.java
@@ -1,22 +1,10 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
package ch.qos.logback.classic.net;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
+import ch.qos.logback.core.read.ListAppender;
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.util.Duration;
import org.junit.Test;
@@ -29,100 +17,100 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class SocketAppenderMessageLossTest {
- int runLen = 100;
- Duration reconnectionDelay = new Duration(1000);
+ int runLen = 100;
+ Duration reconnectionDelay = new Duration(1000);
- static final int TIMEOUT = 3000;
-
- @Test(timeout = TIMEOUT)
- public void synchronousSocketAppender() throws Exception {
+ @Test(timeout = 1000)
+ public void synchronousSocketAppender() throws Exception {
- SocketAppender socketAppender = new SocketAppender();
- socketAppender.setReconnectionDelay(reconnectionDelay);
- socketAppender.setIncludeCallerData(true);
+ SocketAppender socketAppender = new SocketAppender();
+ socketAppender.setReconnectionDelay(reconnectionDelay);
+ socketAppender.setIncludeCallerData(true);
- runTest(socketAppender);
- }
-
- @Test(timeout = TIMEOUT)
- public void smallQueueSocketAppender() throws Exception {
+ runTest(socketAppender);
+ }
- SocketAppender socketAppender = new SocketAppender();
- socketAppender.setReconnectionDelay(reconnectionDelay);
- socketAppender.setQueueSize(runLen / 10);
+ @Test(timeout = 1000)
+ public void smallQueueSocketAppender() throws Exception {
- runTest(socketAppender);
- }
+ SocketAppender socketAppender = new SocketAppender();
+ socketAppender.setReconnectionDelay(reconnectionDelay);
+ socketAppender.setQueueSize(runLen/10);
- @Test(timeout = TIMEOUT)
- public void largeQueueSocketAppender() throws Exception {
- SocketAppender socketAppender = new SocketAppender();
- socketAppender.setReconnectionDelay(reconnectionDelay);
- socketAppender.setQueueSize(runLen * 5);
+ runTest(socketAppender);
+ }
- runTest(socketAppender);
- }
+ @Test(timeout = 1000)
+ public void largeQueueSocketAppender() throws Exception {
+ SocketAppender socketAppender = new SocketAppender();
+ socketAppender.setReconnectionDelay(reconnectionDelay);
+ socketAppender.setQueueSize(runLen*5);
- // appender used to signal when the N'th event (as set in the latch) is received by the server
- // this allows us to have test which are both more robust and quicker.
- static public class ListAppenderWithLatch extends AppenderBase<ILoggingEvent> {
- public List<ILoggingEvent> list = new ArrayList<ILoggingEvent>();
- CountDownLatch latch;
+ runTest(socketAppender);
+ }
- ListAppenderWithLatch(CountDownLatch latch) {
- this.latch = latch;
- }
+ // appender used to signal when the N'th event (as set in the latch) is received by the server
+ // this allows us to have test which are both more robust and quicker.
+ static public class ListAppenderWithLatch extends AppenderBase<ILoggingEvent> {
+ public List<ILoggingEvent> list = new ArrayList<ILoggingEvent>();
+ CountDownLatch latch;
- protected void append(ILoggingEvent e) {
- list.add(e);
- latch.countDown();
- }
+ ListAppenderWithLatch(CountDownLatch latch) {
+ this.latch = latch;
}
+ protected void append(ILoggingEvent e) {
+ list.add(e);
+ latch.countDown();
+ }
+ }
- public void runTest(SocketAppender socketAppender) throws Exception {
- final int port = RandomUtil.getRandomServerPort();
- LoggerContext serverLoggerContext = new LoggerContext();
- serverLoggerContext.setName("serverLoggerContext");
+ public void runTest(SocketAppender socketAppender) throws Exception {
+ final int port = RandomUtil.getRandomServerPort();
- CountDownLatch allMessagesReceivedLatch = new CountDownLatch(runLen);
- ListAppenderWithLatch listAppender = new ListAppenderWithLatch(allMessagesReceivedLatch);
- listAppender.setContext(serverLoggerContext);
- listAppender.start();
+ LoggerContext serverLoggerContext = new LoggerContext();
+ serverLoggerContext.setName("serverLoggerContext");
- Logger serverLogger = serverLoggerContext.getLogger(getClass());
- serverLogger.setAdditive(false);
- serverLogger.addAppender(listAppender);
+ CountDownLatch allMessagesReceivedLatch = new CountDownLatch(runLen);
+ ListAppenderWithLatch listAppender = new ListAppenderWithLatch(allMessagesReceivedLatch);
+ listAppender.setContext(serverLoggerContext);
+ listAppender.start();
- LoggerContext loggerContext = new LoggerContext();
- loggerContext.setName("clientLoggerContext");
- socketAppender.setContext(loggerContext);
+ Logger serverLogger = serverLoggerContext.getLogger(getClass());
+ serverLogger.setAdditive(false);
+ serverLogger.addAppender(listAppender);
- CountDownLatch latch = new CountDownLatch(1);
- SimpleSocketServer simpleSocketServer = new SimpleSocketServer(serverLoggerContext, port);
- simpleSocketServer.start();
- simpleSocketServer.setLatch(latch);
- latch.await();
+ LoggerContext loggerContext = new LoggerContext();
+ loggerContext.setName("clientLoggerContext");
+ socketAppender.setContext(loggerContext);
- socketAppender.setPort(port);
- socketAppender.setRemoteHost("localhost");
- socketAppender.setReconnectionDelay(reconnectionDelay);
- socketAppender.start();
- assertTrue(socketAppender.isStarted());
+ CountDownLatch latch = new CountDownLatch(1);
+ SimpleSocketServer simpleSocketServer = new SimpleSocketServer(serverLoggerContext, port);
+ simpleSocketServer.start();
+ simpleSocketServer.setLatch(latch);
- Logger logger = loggerContext.getLogger(getClass());
- logger.setAdditive(false);
- logger.addAppender(socketAppender);
+ latch.await();
- for (int i = 0; i < runLen; ++i) {
- logger.info("hello");
- }
+ socketAppender.setPort(port);
+ socketAppender.setRemoteHost("localhost");
+ socketAppender.setReconnectionDelay(reconnectionDelay);
+ socketAppender.start();
+ assertTrue(socketAppender.isStarted());
- allMessagesReceivedLatch.await();
+ Logger logger = loggerContext.getLogger(getClass());
+ logger.setAdditive(false);
+ logger.addAppender(socketAppender);
- assertEquals(runLen, listAppender.list.size());
- loggerContext.stop();
- simpleSocketServer.close();
+
+ for (int i = 0; i < runLen; ++i) {
+ logger.info("hello");
}
+
+ allMessagesReceivedLatch.await();
+
+ assertEquals(runLen, listAppender.list.size());
+ loggerContext.stop();
+ simpleSocketServer.close();
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketMin.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketMin.java
index 83ca266..c297c47 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketMin.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketMin.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,88 +22,88 @@ import ch.qos.logback.classic.Logger;
public class SocketMin {
- static Logger logger = (Logger) LoggerFactory.getLogger(SocketMin.class.getName());
- static SocketAppender s;
+ static Logger logger = (Logger) LoggerFactory.getLogger(SocketMin.class
+ .getName());
+ static SocketAppender s;
- public static void main(String argv[]) {
- if (argv.length == 3) {
- init(argv[0], argv[1]);
- } else {
- usage("Wrong number of arguments.");
- }
-
- // NDC.push("some context");
- if (argv[2].equals("true")) {
- loop();
- } else {
- test();
- }
-
- s.stop();
+ public static void main(String argv[]) {
+ if (argv.length == 3) {
+ init(argv[0], argv[1]);
+ } else {
+ usage("Wrong number of arguments.");
}
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + SocketMin.class + " host port true|false");
- System.exit(1);
+ // NDC.push("some context");
+ if (argv[2].equals("true")) {
+ loop();
+ } else {
+ test();
}
- static void init(String host, String portStr) {
- Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
- BasicConfigurator bc = new BasicConfigurator();
- bc.setContext(root.getLoggerContext());
- bc.configure(root.getLoggerContext());
- try {
- int port = Integer.parseInt(portStr);
- logger.info("Creating socket appender (" + host + "," + port + ").");
- s = new SocketAppender();
- s.setRemoteHost(host);
- s.setPort(port);
- s.setName("S");
- root.addAppender(s);
- } catch (java.lang.NumberFormatException e) {
- e.printStackTrace();
- usage("Could not interpret port number [" + portStr + "].");
- } catch (Exception e) {
- System.err.println("Could not start!");
- e.printStackTrace();
- System.exit(1);
- }
- }
+ s.stop();
+ }
- static void loop() {
- Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
- InputStreamReader in = new InputStreamReader(System.in);
- System.out.println("Type 'q' to quit");
- int i;
- int k = 0;
- while (true) {
- logger.debug("Message " + k++);
- logger.info("Message " + k++);
- logger.warn("Message " + k++);
- logger.error("Message " + k++, new Exception("Just testing"));
- try {
- i = in.read();
- } catch (Exception e) {
- return;
- }
- if (i == -1)
- break;
- if (i == 'q')
- break;
- if (i == 'r') {
- System.out.println("Removing appender S");
- root.detachAppender("S");
- }
- }
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + SocketMin.class
+ + " host port true|false");
+ System.exit(1);
+ }
+
+ static void init(String host, String portStr) {
+ Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+ BasicConfigurator.configure(root.getLoggerContext());
+ try {
+ int port = Integer.parseInt(portStr);
+ logger.info("Creating socket appender (" + host + "," + port + ").");
+ s = new SocketAppender();
+ s.setRemoteHost(host);
+ s.setPort(port);
+ s.setName("S");
+ root.addAppender(s);
+ } catch (java.lang.NumberFormatException e) {
+ e.printStackTrace();
+ usage("Could not interpret port number [" + portStr + "].");
+ } catch (Exception e) {
+ System.err.println("Could not start!");
+ e.printStackTrace();
+ System.exit(1);
}
+ }
- static void test() {
- int i = 0;
- logger.debug("Message " + i++);
- logger.info("Message " + i++);
- logger.warn("Message " + i++);
- logger.error("Message " + i++);
- logger.debug("Message " + i++, new Exception("Just testing."));
+ static void loop() {
+ Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+ InputStreamReader in = new InputStreamReader(System.in);
+ System.out.println("Type 'q' to quit");
+ int i;
+ int k = 0;
+ while (true) {
+ logger.debug("Message " + k++);
+ logger.info("Message " + k++);
+ logger.warn("Message " + k++);
+ logger.error("Message " + k++, new Exception("Just testing"));
+ try {
+ i = in.read();
+ } catch (Exception e) {
+ return;
+ }
+ if (i == -1)
+ break;
+ if (i == 'q')
+ break;
+ if (i == 'r') {
+ System.out.println("Removing appender S");
+ root.detachAppender("S");
+ }
}
+ }
+
+ static void test() {
+ int i = 0;
+ logger.debug("Message " + i++);
+ logger.info("Message " + i++);
+ logger.warn("Message " + i++);
+ logger.error("Message " + i++);
+ logger.debug("Message " + i++, new Exception("Just testing."));
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketReceiverTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketReceiverTest.java
index f08727d..8feac6f 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketReceiverTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketReceiverTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -52,228 +52,238 @@ import ch.qos.logback.core.status.Status;
*/
public class SocketReceiverTest {
- private static final int DELAY = 1000;
- private static final String TEST_HOST_NAME = "NOT.A.VALID.HOST.NAME";
-
- private ServerSocket serverSocket;
- private Socket socket;
- private MockSocketFactory socketFactory = new MockSocketFactory();
- private MockSocketConnector connector;
- private MockAppender appender;
- private LoggerContext lc;
- private Logger logger;
-
- private InstrumentedSocketReceiver receiver = new InstrumentedSocketReceiver();
-
- @Before
- public void setUp() throws Exception {
- serverSocket = ServerSocketUtil.createServerSocket();
- socket = new Socket(serverSocket.getInetAddress(), serverSocket.getLocalPort());
- connector = new MockSocketConnector(socket);
-
- lc = new LoggerContext();
- lc.reset();
- receiver.setContext(lc);
- appender = new MockAppender();
- appender.start();
- logger = lc.getLogger(getClass());
- logger.addAppender(appender);
+ private static final int DELAY = 1000;
+ private static final String TEST_HOST_NAME = "NOT.A.VALID.HOST.NAME";
+
+
+ private ServerSocket serverSocket;
+ private Socket socket;
+ private MockSocketFactory socketFactory = new MockSocketFactory();
+ private MockSocketConnector connector;
+ private MockAppender appender;
+ private LoggerContext lc;
+ private Logger logger;
+
+ private InstrumentedSocketReceiver receiver =
+ new InstrumentedSocketReceiver();
+
+ @Before
+ public void setUp() throws Exception {
+ serverSocket = ServerSocketUtil.createServerSocket();
+ socket = new Socket(serverSocket.getInetAddress(),
+ serverSocket.getLocalPort());
+ connector = new MockSocketConnector(socket);
+
+ lc = new LoggerContext();
+ lc.reset();
+ receiver.setContext(lc);
+ appender = new MockAppender();
+ appender.start();
+ logger = lc.getLogger(getClass());
+ logger.addAppender(appender);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ receiver.stop();
+ ExecutorService executor = lc.getExecutorService();
+ executor.shutdownNow();
+ assertTrue(executor.awaitTermination(DELAY, TimeUnit.MILLISECONDS));
+ socket.close();
+ serverSocket.close();
+ lc.stop();
+ }
+
+ @Test
+ public void testStartNoRemoteAddress() throws Exception {
+ receiver.start();
+ assertFalse(receiver.isStarted());
+ int count = lc.getStatusManager().getCount();
+ Status status = lc.getStatusManager().getCopyOfStatusList().get(count - 1);
+ assertTrue(status.getMessage().contains("host"));
+ }
+
+ @Test
+ public void testStartNoPort() throws Exception {
+ receiver.setRemoteHost(TEST_HOST_NAME);
+ receiver.start();
+ assertFalse(receiver.isStarted());
+ int count = lc.getStatusManager().getCount();
+ Status status = lc.getStatusManager().getCopyOfStatusList().get(count - 1);
+ assertTrue(status.getMessage().contains("port"));
+ }
+
+ @Test
+ public void testStartUnknownHost() throws Exception {
+ receiver.setPort(6000);
+ receiver.setRemoteHost(TEST_HOST_NAME);
+ receiver.start();
+ assertFalse(receiver.isStarted());
+ int count = lc.getStatusManager().getCount();
+ Status status = lc.getStatusManager().getCopyOfStatusList().get(count - 1);
+ assertTrue(status.getMessage().contains("unknown host"));
+ }
+
+ @Test
+ public void testStartStop() throws Exception {
+ receiver.setRemoteHost(InetAddress.getLocalHost().getHostName());
+ receiver.setPort(6000);
+ receiver.setAcceptConnectionTimeout(DELAY / 2);
+ receiver.start();
+ assertTrue(receiver.isStarted());
+ receiver.awaitConnectorCreated(DELAY);
+ receiver.stop();
+ assertFalse(receiver.isStarted());
+ }
+
+ @Test
+ public void testServerSlowToAcceptConnection() throws Exception {
+ receiver.setRemoteHost(InetAddress.getLocalHost().getHostName());
+ receiver.setPort(6000);
+ receiver.setAcceptConnectionTimeout(DELAY / 4);
+ receiver.start();
+ assertTrue(receiver.awaitConnectorCreated(DELAY / 2));
+ // note that we don't call serverSocket.accept() here
+ // but processPriorToRemoval (in tearDown) should still clean up everything
+ }
+
+ @Test
+ public void testServerDropsConnection() throws Exception {
+ receiver.setRemoteHost(InetAddress.getLocalHost().getHostName());
+ receiver.setPort(6000);
+ receiver.start();
+ assertTrue(receiver.awaitConnectorCreated(DELAY));
+ Socket socket = serverSocket.accept();
+ socket.close();
+ }
+
+ @Test
+ public void testDispatchEventForEnabledLevel() throws Exception {
+ receiver.setRemoteHost(InetAddress.getLocalHost().getHostName());
+ receiver.setPort(6000);
+ receiver.start();
+ assertTrue(receiver.awaitConnectorCreated(DELAY));
+ Socket socket = serverSocket.accept();
+
+ ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
+
+ logger.setLevel(Level.DEBUG);
+ ILoggingEvent event = new LoggingEvent(logger.getName(), logger,
+ Level.DEBUG, "test message", null, new Object[0]);
+
+ LoggingEventVO eventVO = LoggingEventVO.build(event);
+ oos.writeObject(eventVO);
+ oos.flush();
+
+ ILoggingEvent rcvdEvent = appender.awaitAppend(DELAY);
+ assertNotNull(rcvdEvent);
+ assertEquals(event.getLoggerName(), rcvdEvent.getLoggerName());
+ assertEquals(event.getLevel(), rcvdEvent.getLevel());
+ assertEquals(event.getMessage(), rcvdEvent.getMessage());
+ }
+
+ @Test
+ public void testNoDispatchEventForDisabledLevel() throws Exception {
+ receiver.setRemoteHost(InetAddress.getLocalHost().getHostName());
+ receiver.setPort(6000);
+ receiver.start();
+ assertTrue(receiver.awaitConnectorCreated(DELAY));
+ Socket socket = serverSocket.accept();
+
+ ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
+
+ logger.setLevel(Level.INFO);
+ ILoggingEvent event = new LoggingEvent(logger.getName(), logger,
+ Level.DEBUG, "test message", null, new Object[0]);
+
+ LoggingEventVO eventVO = LoggingEventVO.build(event);
+ oos.writeObject(eventVO);
+ oos.flush();
+
+ assertNull(appender.awaitAppend(DELAY));
+ }
+
+ /**
+ * A {@link SocketReceiver} with instrumentation for unit testing.
+ */
+ private class InstrumentedSocketReceiver extends SocketReceiver {
+
+ private boolean connectorCreated;
+
+ @Override
+ protected synchronized SocketConnector newConnector(
+ InetAddress address, int port, int initialDelay, int retryDelay) {
+ connectorCreated = true;
+ notifyAll();
+ return connector;
}
- @After
- public void tearDown() throws Exception {
- receiver.stop();
- ExecutorService executor = lc.getExecutorService();
- executor.shutdownNow();
- assertTrue(executor.awaitTermination(DELAY, TimeUnit.MILLISECONDS));
- socket.close();
- serverSocket.close();
- lc.stop();
+ @Override
+ protected SocketFactory getSocketFactory() {
+ return socketFactory;
}
- @Test
- public void testStartNoRemoteAddress() throws Exception {
- receiver.start();
- assertFalse(receiver.isStarted());
- int count = lc.getStatusManager().getCount();
- Status status = lc.getStatusManager().getCopyOfStatusList().get(count - 1);
- assertTrue(status.getMessage().contains("host"));
+ public synchronized boolean awaitConnectorCreated(long delay)
+ throws InterruptedException {
+ while (!connectorCreated) {
+ wait(delay);
+ }
+ return connectorCreated;
}
- @Test
- public void testStartNoPort() throws Exception {
- receiver.setRemoteHost(TEST_HOST_NAME);
- receiver.start();
- assertFalse(receiver.isStarted());
- int count = lc.getStatusManager().getCount();
- Status status = lc.getStatusManager().getCopyOfStatusList().get(count - 1);
- assertTrue(status.getMessage().contains("port"));
+ }
+
+ /**
+ * A {@link SocketConnector} with instrumentation for unit testing.
+ */
+ private static class MockSocketConnector implements SocketConnector {
+
+ private final Socket socket;
+
+ public MockSocketConnector(Socket socket) {
+ this.socket = socket;
}
- @Test
- public void testStartUnknownHost() throws Exception {
- receiver.setPort(6000);
- receiver.setRemoteHost(TEST_HOST_NAME);
- receiver.start();
- assertFalse(receiver.isStarted());
- int count = lc.getStatusManager().getCount();
- Status status = lc.getStatusManager().getCopyOfStatusList().get(count - 1);
- assertTrue(status.getMessage().contains("unknown host"));
+ public Socket call() throws InterruptedException {
+ return socket;
}
- @Test
- public void testStartStop() throws Exception {
- receiver.setRemoteHost(InetAddress.getLocalHost().getHostName());
- receiver.setPort(6000);
- receiver.setAcceptConnectionTimeout(DELAY / 2);
- receiver.start();
- assertTrue(receiver.isStarted());
- receiver.awaitConnectorCreated(DELAY);
- receiver.stop();
- assertFalse(receiver.isStarted());
+ public void setExceptionHandler(ExceptionHandler exceptionHandler) {
}
- @Test
- public void testServerSlowToAcceptConnection() throws Exception {
- receiver.setRemoteHost(InetAddress.getLocalHost().getHostName());
- receiver.setPort(6000);
- receiver.setAcceptConnectionTimeout(DELAY / 4);
- receiver.start();
- assertTrue(receiver.awaitConnectorCreated(DELAY / 2));
- // note that we don't call serverSocket.accept() here
- // but processPriorToRemoval (in tearDown) should still clean up everything
+ public void setSocketFactory(SocketFactory socketFactory) {
}
- @Test
- public void testServerDropsConnection() throws Exception {
- receiver.setRemoteHost(InetAddress.getLocalHost().getHostName());
- receiver.setPort(6000);
- receiver.start();
- assertTrue(receiver.awaitConnectorCreated(DELAY));
- Socket socket = serverSocket.accept();
- socket.close();
- }
-
- @Test
- public void testDispatchEventForEnabledLevel() throws Exception {
- receiver.setRemoteHost(InetAddress.getLocalHost().getHostName());
- receiver.setPort(6000);
- receiver.start();
- assertTrue(receiver.awaitConnectorCreated(DELAY));
- Socket socket = serverSocket.accept();
-
- ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
-
- logger.setLevel(Level.DEBUG);
- ILoggingEvent event = new LoggingEvent(logger.getName(), logger, Level.DEBUG, "test message", null, new Object[0]);
+ }
- LoggingEventVO eventVO = LoggingEventVO.build(event);
- oos.writeObject(eventVO);
- oos.flush();
+ /**
+ * A no-op {@link SocketFactory} to support unit testing.
+ */
+ private static class MockSocketFactory extends SocketFactory {
- ILoggingEvent rcvdEvent = appender.awaitAppend(DELAY);
- assertNotNull(rcvdEvent);
- assertEquals(event.getLoggerName(), rcvdEvent.getLoggerName());
- assertEquals(event.getLevel(), rcvdEvent.getLevel());
- assertEquals(event.getMessage(), rcvdEvent.getMessage());
+ @Override
+ public Socket createSocket(InetAddress address, int port,
+ InetAddress localAddress, int localPort) throws IOException {
+ throw new UnsupportedOperationException();
}
- @Test
- public void testNoDispatchEventForDisabledLevel() throws Exception {
- receiver.setRemoteHost(InetAddress.getLocalHost().getHostName());
- receiver.setPort(6000);
- receiver.start();
- assertTrue(receiver.awaitConnectorCreated(DELAY));
- Socket socket = serverSocket.accept();
-
- ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
-
- logger.setLevel(Level.INFO);
- ILoggingEvent event = new LoggingEvent(logger.getName(), logger, Level.DEBUG, "test message", null, new Object[0]);
-
- LoggingEventVO eventVO = LoggingEventVO.build(event);
- oos.writeObject(eventVO);
- oos.flush();
-
- assertNull(appender.awaitAppend(DELAY));
+ @Override
+ public Socket createSocket(InetAddress host, int port) throws IOException {
+ throw new UnsupportedOperationException();
}
- /**
- * A {@link SocketReceiver} with instrumentation for unit testing.
- */
- private class InstrumentedSocketReceiver extends SocketReceiver {
-
- private boolean connectorCreated;
-
- @Override
- protected synchronized SocketConnector newConnector(InetAddress address, int port, int initialDelay, int retryDelay) {
- connectorCreated = true;
- notifyAll();
- return connector;
- }
-
- @Override
- protected SocketFactory getSocketFactory() {
- return socketFactory;
- }
-
- public synchronized boolean awaitConnectorCreated(long delay) throws InterruptedException {
- while (!connectorCreated) {
- wait(delay);
- }
- return connectorCreated;
- }
-
+ @Override
+ public Socket createSocket(String host, int port, InetAddress localHost,
+ int localPort) throws IOException, UnknownHostException {
+ throw new UnsupportedOperationException();
}
- /**
- * A {@link SocketConnector} with instrumentation for unit testing.
- */
- private static class MockSocketConnector implements SocketConnector {
-
- private final Socket socket;
-
- public MockSocketConnector(Socket socket) {
- this.socket = socket;
- }
-
- public Socket call() throws InterruptedException {
- return socket;
- }
-
- public void setExceptionHandler(ExceptionHandler exceptionHandler) {
- }
-
- public void setSocketFactory(SocketFactory socketFactory) {
- }
-
+ @Override
+ public Socket createSocket(String host, int port) throws IOException,
+ UnknownHostException {
+ throw new UnsupportedOperationException();
}
-
- /**
- * A no-op {@link SocketFactory} to support unit testing.
- */
- private static class MockSocketFactory extends SocketFactory {
-
- @Override
- public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Socket createSocket(InetAddress host, int port) throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
- throw new UnsupportedOperationException();
- }
-
- }
-
+
+ }
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/SyslogAppenderTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/SyslogAppenderTest.java
index 2a759d6..34a584c 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/SyslogAppenderTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/SyslogAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -33,232 +33,213 @@ import ch.qos.logback.core.recovery.RecoveryCoordinator;
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.util.StatusPrinter;
-import java.nio.charset.Charset;
-
public class SyslogAppenderTest {
- private static final String SYSLOG_PREFIX_REGEX = "<\\d{2}>\\w{3} [\\d ]\\d \\d{2}(:\\d{2}){2} [\\w.-]* ";
-
- LoggerContext lc = new LoggerContext();
- SyslogAppender sa = new SyslogAppender();
- MockSyslogServer mockServer;
- String loggerName = this.getClass().getName();
- Logger logger = lc.getLogger(loggerName);
-
- @Before
- public void setUp() throws Exception {
- lc.setName("test");
- sa.setContext(lc);
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
- public void setMockServerAndConfigure(int expectedCount, String suffixPattern) throws InterruptedException {
- int port = RandomUtil.getRandomServerPort();
-
- mockServer = new MockSyslogServer(expectedCount, port);
- mockServer.start();
- // give MockSyslogServer head start
-
- Thread.sleep(100);
-
- sa.setSyslogHost("localhost");
- sa.setFacility("MAIL");
- sa.setPort(port);
- sa.setSuffixPattern(suffixPattern);
- sa.setStackTracePattern("[%thread] foo " + CoreConstants.TAB);
- sa.start();
- assertTrue(sa.isStarted());
-
- String loggerName = this.getClass().getName();
- Logger logger = lc.getLogger(loggerName);
- logger.addAppender(sa);
+ private static final String SYSLOG_PREFIX_REGEX = "<\\d{2}>\\w{3} [\\d ]\\d \\d{2}(:\\d{2}){2} [\\w.-]* ";
- }
-
- public void setMockServerAndConfigure(int expectedCount) throws InterruptedException {
- this.setMockServerAndConfigure(expectedCount, "[%thread] %logger %msg");
- }
-
- @Test
- public void basic() throws InterruptedException {
-
- setMockServerAndConfigure(1);
- String logMsg = "hello";
- logger.debug(logMsg);
-
- // wait max 2 seconds for mock server to finish. However, it should
- // much sooner than that.
- mockServer.join(8000);
-
- assertTrue(mockServer.isFinished());
- assertEquals(1, mockServer.getMessageList().size());
- String msg = new String(mockServer.getMessageList().get(0));
-
- String threadName = Thread.currentThread().getName();
-
- String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
- assertTrue(msg.startsWith(expected));
-
- checkRegexMatch(msg, SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " " + logMsg);
-
- }
+ LoggerContext lc = new LoggerContext();
+ SyslogAppender sa = new SyslogAppender();
+ MockSyslogServer mockServer;
+ String loggerName = this.getClass().getName();
+ Logger logger = lc.getLogger(loggerName);
- @Test
- public void suffixPatternWithTag() throws InterruptedException {
- setMockServerAndConfigure(1, "test/something [%thread] %logger %msg");
- String logMsg = "hello";
- logger.debug(logMsg);
+ @Before
+ public void setUp() throws Exception {
+ lc.setName("test");
+ sa.setContext(lc);
+ }
- // wait max 2 seconds for mock server to finish. However, it should
- // much sooner than that.
- mockServer.join(8000);
+ @After
+ public void tearDown() throws Exception {
+ }
- assertTrue(mockServer.isFinished());
- assertEquals(1, mockServer.getMessageList().size());
- String msg = new String(mockServer.getMessageList().get(0));
+ public void setMockServerAndConfigure(int expectedCount, String suffixPattern)
+ throws InterruptedException {
+ int port = RandomUtil.getRandomServerPort();
- String threadName = Thread.currentThread().getName();
+ mockServer = new MockSyslogServer(expectedCount, port);
+ mockServer.start();
+ // give MockSyslogServer head start
- String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
- assertTrue(msg.startsWith(expected));
+ Thread.sleep(100);
- checkRegexMatch(msg, SYSLOG_PREFIX_REGEX + "test/something \\[" + threadName + "\\] " + loggerName + " " + logMsg);
-
- }
-
- @Test
- public void tException() throws InterruptedException {
- setMockServerAndConfigure(21);
-
- String logMsg = "hello";
- String exMsg = "just testing";
- Exception ex = new Exception(exMsg);
- logger.debug(logMsg, ex);
- StatusPrinter.print(lc);
-
- // wait max 2 seconds for mock server to finish. However, it should
- // much sooner than that.
- mockServer.join(8000);
- assertTrue(mockServer.isFinished());
-
- // message + 20 lines of stacktrace
- assertEquals(21, mockServer.getMessageList().size());
- // int i = 0;
- // for (String line: mockServer.msgList) {
- // System.out.println(i++ + ": " + line);
- // }
-
- String msg = new String(mockServer.getMessageList().get(0));
- String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
- assertTrue(msg.startsWith(expected));
-
- String threadName = Thread.currentThread().getName();
- String regex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " " + logMsg;
- checkRegexMatch(msg, regex);
-
- msg = new String(mockServer.getMessageList().get(1));
- assertTrue(msg.contains(ex.getClass().getName()));
- assertTrue(msg.contains(ex.getMessage()));
-
- msg = new String(mockServer.getMessageList().get(2));
- assertTrue(msg.startsWith(expected));
- regex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + "foo " + CoreConstants.TAB + "at ch\\.qos.*";
- checkRegexMatch(msg, regex);
- }
-
- private void checkRegexMatch(String s, String regex) {
- assertTrue("The string [" + s + "] did not match regex [" + regex + "]", s.matches(regex));
- }
-
- @Test
- public void large() throws Exception {
- setMockServerAndConfigure(2);
- StringBuilder largeBuf = new StringBuilder();
- for (int i = 0; i < 2 * 1024 * 1024; i++) {
- largeBuf.append('a');
- }
- logger.debug(largeBuf.toString());
-
- String logMsg = "hello";
- logger.debug(logMsg);
- Thread.sleep(RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN + 10);
- logger.debug(logMsg);
-
- mockServer.join(8000);
- assertTrue(mockServer.isFinished());
-
- // both messages received
- assertEquals(2, mockServer.getMessageList().size());
-
- String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
- String threadName = Thread.currentThread().getName();
-
- // large message is truncated
- final int maxMessageSize = sa.getMaxMessageSize();
- String largeMsg = new String(mockServer.getMessageList().get(0));
- assertTrue(largeMsg.startsWith(expected));
- String largeRegex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " " + "a{" + (maxMessageSize - 2000) + "," + maxMessageSize + "}";
- checkRegexMatch(largeMsg, largeRegex);
-
- String msg = new String(mockServer.getMessageList().get(1));
- assertTrue(msg.startsWith(expected));
- String regex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " " + logMsg;
- checkRegexMatch(msg, regex);
- }
-
- @Test
- public void LBCLASSIC_50() throws JoranException {
-
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
-
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- lc.reset();
- configurator.doConfigure(ClassicTestConstants.JORAN_INPUT_PREFIX + "syslog_LBCLASSIC_50.xml");
-
- org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
- logger.info("hello");
- }
-
- @Test
- public void unknownHostShouldNotCauseStopToFail() {
- // See LOGBACK-960
- sa.setSyslogHost("unknown.host");
- sa.setFacility("MAIL");
- sa.start();
- sa.stop();
- }
-
- @Test
- public void nonAsciiMessageEncoding() throws Exception {
- // See LOGBACK-732
- setMockServerAndConfigure(1);
-
- // Use a string that can be encoded in a somewhat odd encoding (ISO-8859-4) to minimize
- // the probability of the encoding test to work by accident
- String logMsg = "R\u0129ga"; // Riga spelled with the i having a tilda on top
-
- Charset ISO_8859_4 = Charset.forName("ISO-8859-4");
- sa.setCharset(ISO_8859_4);
- logger.debug(logMsg);
-
- // wait max 8 seconds for mock server to finish. However, it should
- // be done much sooner than that.
- mockServer.join(8000);
-
- assertTrue(mockServer.isFinished());
- assertEquals(1, mockServer.getMessageList().size());
- String msg = new String(mockServer.getMessageList().get(0), ISO_8859_4);
- String threadName = Thread.currentThread().getName();
-
- String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
- assertTrue(msg.startsWith(expected));
-
- System.out.println(logMsg);
- checkRegexMatch(msg, SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " " + logMsg);
+ sa.setSyslogHost("localhost");
+ sa.setFacility("MAIL");
+ sa.setPort(port);
+ sa.setSuffixPattern(suffixPattern);
+ sa.setStackTracePattern("[%thread] foo "+CoreConstants.TAB);
+ sa.start();
+ assertTrue(sa.isStarted());
+ String loggerName = this.getClass().getName();
+ Logger logger = lc.getLogger(loggerName);
+ logger.addAppender(sa);
+
+ }
+
+ public void setMockServerAndConfigure(int expectedCount)
+ throws InterruptedException {
+ this.setMockServerAndConfigure(expectedCount, "[%thread] %logger %msg");
+ }
+
+ @Test
+ public void basic() throws InterruptedException {
+
+ setMockServerAndConfigure(1);
+ String logMsg = "hello";
+ logger.debug(logMsg);
+
+ // wait max 2 seconds for mock server to finish. However, it should
+ // much sooner than that.
+ mockServer.join(8000);
+
+ assertTrue(mockServer.isFinished());
+ assertEquals(1, mockServer.getMessageList().size());
+ String msg = mockServer.getMessageList().get(0);
+
+ String threadName = Thread.currentThread().getName();
+
+ String expected = "<"
+ + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
+ assertTrue(msg.startsWith(expected));
+
+ checkRegexMatch(msg, SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " "
+ + logMsg);
+
+ }
+
+ @Test
+ public void suffixPatternWithTag() throws InterruptedException {
+ setMockServerAndConfigure(1, "test/something [%thread] %logger %msg");
+ String logMsg = "hello";
+ logger.debug(logMsg);
+
+ // wait max 2 seconds for mock server to finish. However, it should
+ // much sooner than that.
+ mockServer.join(8000);
+
+ assertTrue(mockServer.isFinished());
+ assertEquals(1, mockServer.getMessageList().size());
+ String msg = mockServer.getMessageList().get(0);
+
+ String threadName = Thread.currentThread().getName();
+
+ String expected = "<"
+ + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
+ assertTrue(msg.startsWith(expected));
+
+ checkRegexMatch(msg, SYSLOG_PREFIX_REGEX + "test/something \\[" + threadName + "\\] " + loggerName + " "
+ + logMsg);
+
+ }
+
+ @Test
+ public void tException() throws InterruptedException {
+ setMockServerAndConfigure(21);
+
+ String logMsg = "hello";
+ String exMsg = "just testing";
+ Exception ex = new Exception(exMsg);
+ logger.debug(logMsg, ex);
+ StatusPrinter.print(lc);
+
+ // wait max 2 seconds for mock server to finish. However, it should
+ // much sooner than that.
+ mockServer.join(8000);
+ assertTrue(mockServer.isFinished());
+
+ // message + 20 lines of stacktrace
+ assertEquals(21, mockServer.getMessageList().size());
+ // int i = 0;
+ // for (String line: mockServer.msgList) {
+ // System.out.println(i++ + ": " + line);
+ // }
+
+ String msg = mockServer.getMessageList().get(0);
+ String expected = "<"
+ + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
+ assertTrue(msg.startsWith(expected));
+
+ String threadName = Thread.currentThread().getName();
+ String regex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName
+ + " " + logMsg;
+ checkRegexMatch(msg, regex);
+
+ msg = mockServer.getMessageList().get(1);
+ assertTrue(msg.contains(ex.getClass().getName()));
+ assertTrue(msg.contains(ex.getMessage()));
+
+ msg = mockServer.getMessageList().get(2);
+ assertTrue(msg.startsWith(expected));
+ regex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + "foo "+CoreConstants.TAB + "at ch\\.qos.*";
+ checkRegexMatch(msg, regex);
+ }
+
+ private void checkRegexMatch(String s, String regex) {
+ assertTrue("The string [" + s + "] did not match regex [" + regex + "]", s
+ .matches(regex));
+ }
+
+ @Test
+ public void large() throws Exception {
+ setMockServerAndConfigure(2);
+ StringBuilder largeBuf = new StringBuilder();
+ for (int i = 0; i < 2 * 1024 * 1024; i++) {
+ largeBuf.append('a');
}
+ logger.debug(largeBuf.toString());
+
+ String logMsg = "hello";
+ logger.debug(logMsg);
+ Thread.sleep(RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN+10);
+ logger.debug(logMsg);
+
+ mockServer.join(8000);
+ assertTrue(mockServer.isFinished());
+
+ // both messages received
+ assertEquals(2, mockServer.getMessageList().size());
+
+ String expected = "<"
+ + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
+ String threadName = Thread.currentThread().getName();
+
+ // large message is truncated
+ final int maxMessageSize = sa.getMaxMessageSize();
+ String largeMsg = mockServer.getMessageList().get(0);
+ assertTrue(largeMsg.startsWith(expected));
+ String largeRegex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName
+ + " " + "a{" + (maxMessageSize - 2000) + "," + maxMessageSize + "}";
+ checkRegexMatch(largeMsg, largeRegex);
+
+ String msg = mockServer.getMessageList().get(1);
+ assertTrue(msg.startsWith(expected));
+ String regex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName
+ + " " + logMsg;
+ checkRegexMatch(msg, regex);
+ }
+
+ @Test
+ public void LBCLASSIC_50() throws JoranException {
+
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ lc.reset();
+ configurator.doConfigure(ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "syslog_LBCLASSIC_50.xml");
+
+ org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
+ logger.info("hello");
+ }
+
+ @Test
+ public void unknownHostShouldNotCauseStopToFail() {
+ // See LOGBACK-960
+ sa.setSyslogHost("unknown.host");
+ sa.setFacility("MAIL");
+ sa.start();
+ sa.stop();
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockAppender.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockAppender.java
index 7a18dd4..145952c 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockAppender.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,27 +30,29 @@ import ch.qos.logback.core.AppenderBase;
*/
public class MockAppender extends AppenderBase<ILoggingEvent> {
- private final Lock lock = new ReentrantLock();
- private final Condition appendCondition = lock.newCondition();
- private final BlockingQueue<ILoggingEvent> events = new LinkedBlockingQueue<ILoggingEvent>();
-
- @Override
- protected void append(ILoggingEvent eventObject) {
- lock.lock();
- try {
- events.offer(eventObject);
- appendCondition.signalAll();
- } finally {
- lock.unlock();
- }
- }
-
- public ILoggingEvent awaitAppend(long delay) throws InterruptedException {
- return events.poll(delay, TimeUnit.MILLISECONDS);
+ private final Lock lock = new ReentrantLock();
+ private final Condition appendCondition = lock.newCondition();
+ private final BlockingQueue<ILoggingEvent> events =
+ new LinkedBlockingQueue<ILoggingEvent>();
+
+ @Override
+ protected void append(ILoggingEvent eventObject) {
+ lock.lock();
+ try {
+ events.offer(eventObject);
+ appendCondition.signalAll();
}
-
- public ILoggingEvent getLastEvent() {
- return events.peek();
+ finally {
+ lock.unlock();
}
+ }
+
+ public ILoggingEvent awaitAppend(long delay) throws InterruptedException {
+ return events.poll(delay, TimeUnit.MILLISECONDS);
+ }
+
+ public ILoggingEvent getLastEvent() {
+ return events.peek();
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockObjectMessage.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockObjectMessage.java
index 4ee4978..407b8bd 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockObjectMessage.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockObjectMessage.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,216 +22,239 @@ import javax.jms.ObjectMessage;
public class MockObjectMessage implements ObjectMessage {
- Serializable object;
-
- public Serializable getObject() throws JMSException {
- return object;
- }
-
- public void setObject(Serializable object) throws JMSException {
- this.object = object;
- }
-
- public void acknowledge() throws JMSException {
-
- }
-
- public void clearBody() throws JMSException {
-
- }
-
- public void clearProperties() throws JMSException {
-
- }
-
- public boolean getBooleanProperty(String arg0) throws JMSException {
-
- return false;
- }
-
- public byte getByteProperty(String arg0) throws JMSException {
-
- return 0;
- }
-
- public double getDoubleProperty(String arg0) throws JMSException {
-
- return 0;
- }
-
- public float getFloatProperty(String arg0) throws JMSException {
-
- return 0;
- }
-
- public int getIntProperty(String arg0) throws JMSException {
-
- return 0;
- }
-
- public String getJMSCorrelationID() throws JMSException {
-
- return null;
- }
-
- public byte[] getJMSCorrelationIDAsBytes() throws JMSException {
-
- return null;
- }
-
- public int getJMSDeliveryMode() throws JMSException {
-
- return 0;
- }
-
- public Destination getJMSDestination() throws JMSException {
-
- return null;
- }
-
- public long getJMSExpiration() throws JMSException {
-
- return 0;
- }
-
- public String getJMSMessageID() throws JMSException {
-
- return null;
- }
-
- public int getJMSPriority() throws JMSException {
-
- return 0;
- }
-
- public boolean getJMSRedelivered() throws JMSException {
-
- return false;
- }
-
- public Destination getJMSReplyTo() throws JMSException {
-
- return null;
- }
-
- public long getJMSTimestamp() throws JMSException {
-
- return 0;
- }
-
- public String getJMSType() throws JMSException {
-
- return null;
- }
-
- public long getLongProperty(String arg0) throws JMSException {
-
- return 0;
- }
-
- public Object getObjectProperty(String arg0) throws JMSException {
-
- return null;
- }
-
- public Enumeration getPropertyNames() throws JMSException {
-
- return null;
- }
-
- public short getShortProperty(String arg0) throws JMSException {
-
- return 0;
- }
-
- public String getStringProperty(String arg0) throws JMSException {
-
- return null;
- }
-
- public boolean propertyExists(String arg0) throws JMSException {
-
- return false;
- }
-
- public void setBooleanProperty(String arg0, boolean arg1) throws JMSException {
-
- }
-
- public void setByteProperty(String arg0, byte arg1) throws JMSException {
-
- }
-
- public void setDoubleProperty(String arg0, double arg1) throws JMSException {
-
- }
-
- public void setFloatProperty(String arg0, float arg1) throws JMSException {
-
- }
-
- public void setIntProperty(String arg0, int arg1) throws JMSException {
-
- }
-
- public void setJMSCorrelationID(String arg0) throws JMSException {
-
- }
-
- public void setJMSCorrelationIDAsBytes(byte[] arg0) throws JMSException {
-
- }
-
- public void setJMSDeliveryMode(int arg0) throws JMSException {
-
- }
-
- public void setJMSDestination(Destination arg0) throws JMSException {
-
- }
-
- public void setJMSExpiration(long arg0) throws JMSException {
-
- }
-
- public void setJMSMessageID(String arg0) throws JMSException {
-
- }
-
- public void setJMSPriority(int arg0) throws JMSException {
-
- }
-
- public void setJMSRedelivered(boolean arg0) throws JMSException {
-
- }
-
- public void setJMSReplyTo(Destination arg0) throws JMSException {
-
- }
-
- public void setJMSTimestamp(long arg0) throws JMSException {
-
- }
-
- public void setJMSType(String arg0) throws JMSException {
-
- }
-
- public void setLongProperty(String arg0, long arg1) throws JMSException {
-
- }
-
- public void setObjectProperty(String arg0, Object arg1) throws JMSException {
-
- }
-
- public void setShortProperty(String arg0, short arg1) throws JMSException {
-
- }
-
- public void setStringProperty(String arg0, String arg1) throws JMSException {
-
- }
+ Serializable object;
+
+ public Serializable getObject() throws JMSException {
+ return object;
+ }
+
+ public void setObject(Serializable object) throws JMSException {
+ this.object = object;
+ }
+
+ public void acknowledge() throws JMSException {
+
+
+ }
+
+ public void clearBody() throws JMSException {
+
+
+ }
+
+ public void clearProperties() throws JMSException {
+
+
+ }
+
+ public boolean getBooleanProperty(String arg0) throws JMSException {
+
+ return false;
+ }
+
+ public byte getByteProperty(String arg0) throws JMSException {
+
+ return 0;
+ }
+
+ public double getDoubleProperty(String arg0) throws JMSException {
+
+ return 0;
+ }
+
+ public float getFloatProperty(String arg0) throws JMSException {
+
+ return 0;
+ }
+
+ public int getIntProperty(String arg0) throws JMSException {
+
+ return 0;
+ }
+
+ public String getJMSCorrelationID() throws JMSException {
+
+ return null;
+ }
+
+ public byte[] getJMSCorrelationIDAsBytes() throws JMSException {
+
+ return null;
+ }
+
+ public int getJMSDeliveryMode() throws JMSException {
+
+ return 0;
+ }
+
+ public Destination getJMSDestination() throws JMSException {
+
+ return null;
+ }
+
+ public long getJMSExpiration() throws JMSException {
+
+ return 0;
+ }
+
+ public String getJMSMessageID() throws JMSException {
+
+ return null;
+ }
+
+ public int getJMSPriority() throws JMSException {
+
+ return 0;
+ }
+
+ public boolean getJMSRedelivered() throws JMSException {
+
+ return false;
+ }
+
+ public Destination getJMSReplyTo() throws JMSException {
+
+ return null;
+ }
+
+ public long getJMSTimestamp() throws JMSException {
+
+ return 0;
+ }
+
+ public String getJMSType() throws JMSException {
+
+ return null;
+ }
+
+ public long getLongProperty(String arg0) throws JMSException {
+
+ return 0;
+ }
+
+ public Object getObjectProperty(String arg0) throws JMSException {
+
+ return null;
+ }
+
+ public Enumeration getPropertyNames() throws JMSException {
+
+ return null;
+ }
+
+ public short getShortProperty(String arg0) throws JMSException {
+
+ return 0;
+ }
+
+ public String getStringProperty(String arg0) throws JMSException {
+
+ return null;
+ }
+
+ public boolean propertyExists(String arg0) throws JMSException {
+
+ return false;
+ }
+
+ public void setBooleanProperty(String arg0, boolean arg1) throws JMSException {
+
+
+ }
+
+ public void setByteProperty(String arg0, byte arg1) throws JMSException {
+
+
+ }
+
+ public void setDoubleProperty(String arg0, double arg1) throws JMSException {
+
+
+ }
+
+ public void setFloatProperty(String arg0, float arg1) throws JMSException {
+
+
+ }
+
+ public void setIntProperty(String arg0, int arg1) throws JMSException {
+
+
+ }
+
+ public void setJMSCorrelationID(String arg0) throws JMSException {
+
+
+ }
+
+ public void setJMSCorrelationIDAsBytes(byte[] arg0) throws JMSException {
+
+
+ }
+
+ public void setJMSDeliveryMode(int arg0) throws JMSException {
+
+
+ }
+
+ public void setJMSDestination(Destination arg0) throws JMSException {
+
+
+ }
+
+ public void setJMSExpiration(long arg0) throws JMSException {
+
+
+ }
+
+ public void setJMSMessageID(String arg0) throws JMSException {
+
+
+ }
+
+ public void setJMSPriority(int arg0) throws JMSException {
+
+
+ }
+
+ public void setJMSRedelivered(boolean arg0) throws JMSException {
+
+
+ }
+
+ public void setJMSReplyTo(Destination arg0) throws JMSException {
+
+
+ }
+
+ public void setJMSTimestamp(long arg0) throws JMSException {
+
+
+ }
+
+ public void setJMSType(String arg0) throws JMSException {
+
+
+ }
+
+ public void setLongProperty(String arg0, long arg1) throws JMSException {
+
+
+ }
+
+ public void setObjectProperty(String arg0, Object arg1) throws JMSException {
+
+
+ }
+
+ public void setShortProperty(String arg0, short arg1) throws JMSException {
+
+
+ }
+
+ public void setStringProperty(String arg0, String arg1) throws JMSException {
+
+
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueue.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueue.java
index 1031346..30fc4c4 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueue.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueue.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,14 +18,14 @@ import javax.jms.Queue;
public class MockQueue implements Queue {
- String name;
-
- public MockQueue(String name) {
- this.name = name;
- }
-
- public String getQueueName() throws JMSException {
- return name;
- }
+ String name;
+
+ public MockQueue(String name) {
+ this.name = name;
+ }
+
+ public String getQueueName() throws JMSException {
+ return name;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueConnection.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueConnection.java
index 3b12a1f..e0047c1 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueConnection.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueConnection.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,65 +27,70 @@ import javax.jms.Topic;
public class MockQueueConnection implements QueueConnection {
- MockQueueSession session = new MockQueueSession();
-
- public QueueSession createQueueSession(boolean arg0, int arg1) throws JMSException {
- return session;
- }
-
- public ConnectionConsumer createConnectionConsumer(Queue arg0, String arg1, ServerSessionPool arg2, int arg3) throws JMSException {
-
- return null;
- }
-
- public void close() throws JMSException {
-
- }
-
- public ConnectionConsumer createConnectionConsumer(Destination arg0, String arg1, ServerSessionPool arg2, int arg3) throws JMSException {
-
- return null;
- }
-
- public ConnectionConsumer createDurableConnectionConsumer(Topic arg0, String arg1, String arg2, ServerSessionPool arg3, int arg4) throws JMSException {
-
- return null;
- }
-
- public Session createSession(boolean arg0, int arg1) throws JMSException {
-
- return null;
- }
-
- public String getClientID() throws JMSException {
-
- return null;
- }
-
- public ExceptionListener getExceptionListener() throws JMSException {
-
- return null;
- }
-
- public ConnectionMetaData getMetaData() throws JMSException {
-
- return null;
- }
-
- public void setClientID(String arg0) throws JMSException {
-
- }
-
- public void setExceptionListener(ExceptionListener arg0) throws JMSException {
-
- }
-
- public void start() throws JMSException {
-
- }
-
- public void stop() throws JMSException {
-
- }
+ MockQueueSession session = new MockQueueSession();
+
+ public QueueSession createQueueSession(boolean arg0, int arg1) throws JMSException {
+ return session;
+ }
+
+ public ConnectionConsumer createConnectionConsumer(Queue arg0, String arg1, ServerSessionPool arg2, int arg3) throws JMSException {
+
+ return null;
+ }
+
+ public void close() throws JMSException {
+
+
+ }
+
+ public ConnectionConsumer createConnectionConsumer(Destination arg0, String arg1, ServerSessionPool arg2, int arg3) throws JMSException {
+
+ return null;
+ }
+
+ public ConnectionConsumer createDurableConnectionConsumer(Topic arg0, String arg1, String arg2, ServerSessionPool arg3, int arg4) throws JMSException {
+
+ return null;
+ }
+
+ public Session createSession(boolean arg0, int arg1) throws JMSException {
+
+ return null;
+ }
+
+ public String getClientID() throws JMSException {
+
+ return null;
+ }
+
+ public ExceptionListener getExceptionListener() throws JMSException {
+
+ return null;
+ }
+
+ public ConnectionMetaData getMetaData() throws JMSException {
+
+ return null;
+ }
+
+ public void setClientID(String arg0) throws JMSException {
+
+
+ }
+
+ public void setExceptionListener(ExceptionListener arg0) throws JMSException {
+
+
+ }
+
+ public void start() throws JMSException {
+
+
+ }
+
+ public void stop() throws JMSException {
+
+
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueConnectionFactory.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueConnectionFactory.java
index 09fd5db..12da63b 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueConnectionFactory.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueConnectionFactory.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,23 +20,23 @@ import javax.jms.QueueConnectionFactory;
public class MockQueueConnectionFactory implements QueueConnectionFactory {
- MockQueueConnection cnx = new MockQueueConnection();
+ MockQueueConnection cnx = new MockQueueConnection();
+
+ public QueueConnection createQueueConnection() throws JMSException {
+ return cnx;
+ }
- public QueueConnection createQueueConnection() throws JMSException {
- return cnx;
- }
+ public QueueConnection createQueueConnection(String user, String pass) throws JMSException {
+
+ return cnx;
+ }
- public QueueConnection createQueueConnection(String user, String pass) throws JMSException {
+ public Connection createConnection() throws JMSException {
+ return null;
+ }
- return cnx;
- }
-
- public Connection createConnection() throws JMSException {
- return null;
- }
-
- public Connection createConnection(String arg0, String arg1) throws JMSException {
- return null;
- }
+ public Connection createConnection(String arg0, String arg1) throws JMSException {
+ return null;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueSender.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueSender.java
index dc992d0..8e54b05 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueSender.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueSender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,98 +24,111 @@ import javax.jms.QueueSender;
public class MockQueueSender implements QueueSender {
- List<Message> messageList = new ArrayList<Message>();
- Queue queue;
+ List<Message> messageList = new ArrayList<Message>();
+ Queue queue;
+
+ public MockQueueSender(Queue queue) {
+ this.queue = queue;
+ }
+
+ public List<Message> getMessageList() {
+ return messageList;
+ }
+
+ public Queue getQueue() throws JMSException {
+ return queue;
+ }
- public MockQueueSender(Queue queue) {
- this.queue = queue;
- }
+ public void send(Message message) throws JMSException {
+ messageList.add(message);
+
+ }
- public List<Message> getMessageList() {
- return messageList;
- }
+ public void send(Queue arg0, Message arg1) throws JMSException {
- public Queue getQueue() throws JMSException {
- return queue;
- }
+
+ }
- public void send(Message message) throws JMSException {
- messageList.add(message);
+ public void send(Message arg0, int arg1, int arg2, long arg3) throws JMSException {
- }
+
+ }
- public void send(Queue arg0, Message arg1) throws JMSException {
+ public void send(Queue arg0, Message arg1, int arg2, int arg3, long arg4) throws JMSException {
- }
+
+ }
- public void send(Message arg0, int arg1, int arg2, long arg3) throws JMSException {
+ public void close() throws JMSException {
- }
+
+ }
- public void send(Queue arg0, Message arg1, int arg2, int arg3, long arg4) throws JMSException {
+ public int getDeliveryMode() throws JMSException {
- }
+ return 0;
+ }
- public void close() throws JMSException {
+ public Destination getDestination() throws JMSException {
- }
+ return null;
+ }
- public int getDeliveryMode() throws JMSException {
+ public boolean getDisableMessageID() throws JMSException {
- return 0;
- }
+ return false;
+ }
- public Destination getDestination() throws JMSException {
+ public boolean getDisableMessageTimestamp() throws JMSException {
- return null;
- }
+ return false;
+ }
- public boolean getDisableMessageID() throws JMSException {
+ public int getPriority() throws JMSException {
- return false;
- }
+ return 0;
+ }
- public boolean getDisableMessageTimestamp() throws JMSException {
+ public long getTimeToLive() throws JMSException {
- return false;
- }
+ return 0;
+ }
- public int getPriority() throws JMSException {
+ public void send(Destination arg0, Message arg1) throws JMSException {
- return 0;
- }
+
+ }
- public long getTimeToLive() throws JMSException {
+ public void send(Destination arg0, Message arg1, int arg2, int arg3, long arg4) throws JMSException {
- return 0;
- }
+
+ }
- public void send(Destination arg0, Message arg1) throws JMSException {
+ public void setDeliveryMode(int arg0) throws JMSException {
- }
+
+ }
- public void send(Destination arg0, Message arg1, int arg2, int arg3, long arg4) throws JMSException {
+ public void setDisableMessageID(boolean arg0) throws JMSException {
- }
+
+ }
- public void setDeliveryMode(int arg0) throws JMSException {
+ public void setDisableMessageTimestamp(boolean arg0) throws JMSException {
- }
+
+ }
- public void setDisableMessageID(boolean arg0) throws JMSException {
+ public void setPriority(int arg0) throws JMSException {
- }
+
+ }
- public void setDisableMessageTimestamp(boolean arg0) throws JMSException {
+ public void setTimeToLive(long arg0) throws JMSException {
- }
-
- public void setPriority(int arg0) throws JMSException {
-
- }
-
- public void setTimeToLive(long arg0) throws JMSException {
-
- }
+
+ }
+
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueSession.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueSession.java
index b58aec6..d073fa1 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueSession.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockQueueSession.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -38,163 +38,171 @@ import javax.jms.TopicSubscriber;
public class MockQueueSession implements QueueSession {
- public ObjectMessage createObjectMessage() throws JMSException {
- return new MockObjectMessage();
+ public ObjectMessage createObjectMessage() throws JMSException {
+ return new MockObjectMessage();
+ }
+
+ public QueueSender createSender(Queue queue) throws JMSException {
+ if (queue == null) {
+ return null;
}
+ return new MockQueueSender(queue);
+ }
- public QueueSender createSender(Queue queue) throws JMSException {
- if (queue == null) {
- return null;
- }
- return new MockQueueSender(queue);
- }
+ public QueueBrowser createBrowser(Queue arg0) throws JMSException {
- public QueueBrowser createBrowser(Queue arg0) throws JMSException {
+ return null;
+ }
- return null;
- }
+ public QueueBrowser createBrowser(Queue arg0, String arg1) throws JMSException {
- public QueueBrowser createBrowser(Queue arg0, String arg1) throws JMSException {
+ return null;
+ }
- return null;
- }
+ public Queue createQueue(String arg0) throws JMSException {
- public Queue createQueue(String arg0) throws JMSException {
+ return null;
+ }
- return null;
- }
+ public QueueReceiver createReceiver(Queue arg0) throws JMSException {
- public QueueReceiver createReceiver(Queue arg0) throws JMSException {
+ return null;
+ }
- return null;
- }
+ public QueueReceiver createReceiver(Queue arg0, String arg1) throws JMSException {
- public QueueReceiver createReceiver(Queue arg0, String arg1) throws JMSException {
+ return null;
+ }
- return null;
- }
+ public TemporaryQueue createTemporaryQueue() throws JMSException {
- public TemporaryQueue createTemporaryQueue() throws JMSException {
+ return null;
+ }
- return null;
- }
+ public void close() throws JMSException {
- public void close() throws JMSException {
+
+ }
- }
+ public void commit() throws JMSException {
- public void commit() throws JMSException {
+
+ }
- }
+ public BytesMessage createBytesMessage() throws JMSException {
- public BytesMessage createBytesMessage() throws JMSException {
+ return null;
+ }
- return null;
- }
+ public MessageConsumer createConsumer(Destination arg0) throws JMSException {
- public MessageConsumer createConsumer(Destination arg0) throws JMSException {
+ return null;
+ }
- return null;
- }
+ public MessageConsumer createConsumer(Destination arg0, String arg1) throws JMSException {
- public MessageConsumer createConsumer(Destination arg0, String arg1) throws JMSException {
+ return null;
+ }
- return null;
- }
+ public MessageConsumer createConsumer(Destination arg0, String arg1, boolean arg2) throws JMSException {
- public MessageConsumer createConsumer(Destination arg0, String arg1, boolean arg2) throws JMSException {
+ return null;
+ }
- return null;
- }
+ public TopicSubscriber createDurableSubscriber(Topic arg0, String arg1) throws JMSException {
- public TopicSubscriber createDurableSubscriber(Topic arg0, String arg1) throws JMSException {
+ return null;
+ }
- return null;
- }
+ public TopicSubscriber createDurableSubscriber(Topic arg0, String arg1, String arg2, boolean arg3) throws JMSException {
- public TopicSubscriber createDurableSubscriber(Topic arg0, String arg1, String arg2, boolean arg3) throws JMSException {
+ return null;
+ }
- return null;
- }
+ public MapMessage createMapMessage() throws JMSException {
- public MapMessage createMapMessage() throws JMSException {
+ return null;
+ }
- return null;
- }
+ public Message createMessage() throws JMSException {
- public Message createMessage() throws JMSException {
+ return null;
+ }
- return null;
- }
+ public ObjectMessage createObjectMessage(Serializable arg0) throws JMSException {
- public ObjectMessage createObjectMessage(Serializable arg0) throws JMSException {
+ return null;
+ }
- return null;
- }
-
- public MessageProducer createProducer(Destination arg0) throws JMSException {
+ public MessageProducer createProducer(Destination arg0) throws JMSException {
- return null;
- }
+ return null;
+ }
- public StreamMessage createStreamMessage() throws JMSException {
+ public StreamMessage createStreamMessage() throws JMSException {
- return null;
- }
+ return null;
+ }
- public TemporaryTopic createTemporaryTopic() throws JMSException {
+ public TemporaryTopic createTemporaryTopic() throws JMSException {
- return null;
- }
+ return null;
+ }
- public TextMessage createTextMessage() throws JMSException {
+ public TextMessage createTextMessage() throws JMSException {
- return null;
- }
+ return null;
+ }
- public TextMessage createTextMessage(String arg0) throws JMSException {
+ public TextMessage createTextMessage(String arg0) throws JMSException {
- return null;
- }
+ return null;
+ }
- public Topic createTopic(String arg0) throws JMSException {
+ public Topic createTopic(String arg0) throws JMSException {
- return null;
- }
+ return null;
+ }
- public int getAcknowledgeMode() throws JMSException {
+ public int getAcknowledgeMode() throws JMSException {
- return 0;
- }
+ return 0;
+ }
- public MessageListener getMessageListener() throws JMSException {
+ public MessageListener getMessageListener() throws JMSException {
- return null;
- }
+ return null;
+ }
- public boolean getTransacted() throws JMSException {
+ public boolean getTransacted() throws JMSException {
- return false;
- }
+ return false;
+ }
- public void recover() throws JMSException {
+ public void recover() throws JMSException {
- }
+
+ }
- public void rollback() throws JMSException {
+ public void rollback() throws JMSException {
- }
+
+ }
- public void run() {
+ public void run() {
- }
+
+ }
- public void setMessageListener(MessageListener arg0) throws JMSException {
+ public void setMessageListener(MessageListener arg0) throws JMSException {
- }
+
+ }
- public void unsubscribe(String arg0) throws JMSException {
+ public void unsubscribe(String arg0) throws JMSException {
- }
+
+ }
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockSyslogServer.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockSyslogServer.java
index 4efafdf..788b342 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockSyslogServer.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockSyslogServer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,52 +24,48 @@ import java.util.List;
*/
public class MockSyslogServer extends Thread {
- final int loopLen;
- final int port;
+ final int loopLen;
+ final int port;
+
+ List<String> msgList = new ArrayList<String>();
+ boolean finished = false;
+
+ public MockSyslogServer(int loopLen, int port) {
+ super();
+ this.loopLen = loopLen;
+ this.port = port;
+ }
- List<byte[]> msgList = new ArrayList<byte[]>();
- boolean finished = false;
+ @Override
+ public void run() {
+ //System.out.println("MockSyslogServer listening on port "+port);
+ DatagramSocket socket = null;
+ try {
+ socket = new DatagramSocket(port);
- public MockSyslogServer(int loopLen, int port) {
- super();
- this.loopLen = loopLen;
- this.port = port;
- }
-
- @Override
- public void run() {
- // System.out.println("MockSyslogServer listening on port "+port);
- DatagramSocket socket = null;
- try {
- socket = new DatagramSocket(port);
-
- for (int i = 0; i < loopLen; i++) {
- byte[] buf = new byte[65536];
- DatagramPacket packet = new DatagramPacket(buf, buf.length);
- // System.out.println("Waiting for message");
- socket.receive(packet);
- byte[] out = new byte[packet.getLength()];
- System.arraycopy(buf, 0, out, 0, out.length);
- msgList.add(out);
- }
- } catch (Exception se) {
- se.printStackTrace();
- } finally {
- if (socket != null) {
- try {
- socket.close();
- } catch (Exception e) {
- }
- }
- }
- finished = true;
- }
-
- public boolean isFinished() {
- return finished;
- }
-
- public List<byte[]> getMessageList() {
- return msgList;
+ for (int i = 0; i < loopLen; i++) {
+ byte[] buf = new byte[65536];
+ DatagramPacket packet = new DatagramPacket(buf, buf.length);
+ //System.out.println("Waiting for message");
+ socket.receive(packet);
+ String msg = new String(buf, 0, packet.getLength());
+ msgList.add(msg);
+ }
+ } catch (Exception se) {
+ se.printStackTrace();
+ } finally {
+ if(socket != null) {
+ try {socket.close();} catch(Exception e) {}
+ }
}
+ finished = true;
+ }
+
+ public boolean isFinished() {
+ return finished;
+ }
+
+ public List<String> getMessageList() {
+ return msgList;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopic.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopic.java
index 9d404a3..1a7439e 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopic.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopic.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,14 +18,14 @@ import javax.jms.Topic;
public class MockTopic implements Topic {
- String name;
-
- public MockTopic(String name) {
- this.name = name;
- }
-
- public String getTopicName() throws JMSException {
- return name;
- }
+ String name;
+
+ public MockTopic(String name) {
+ this.name = name;
+ }
+
+ public String getTopicName() throws JMSException {
+ return name;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicConnection.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicConnection.java
index 533afe6..422a2f0 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicConnection.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicConnection.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,65 +26,70 @@ import javax.jms.TopicSession;
public class MockTopicConnection implements TopicConnection {
- MockTopicSession session = new MockTopicSession();
-
- public TopicSession createTopicSession(boolean arg0, int arg1) throws JMSException {
- return session;
- }
-
- public ConnectionConsumer createConnectionConsumer(Topic arg0, String arg1, ServerSessionPool arg2, int arg3) throws JMSException {
-
- return null;
- }
-
- public ConnectionConsumer createDurableConnectionConsumer(Topic arg0, String arg1, String arg2, ServerSessionPool arg3, int arg4) throws JMSException {
-
- return null;
- }
-
- public void close() throws JMSException {
-
- }
-
- public ConnectionConsumer createConnectionConsumer(Destination arg0, String arg1, ServerSessionPool arg2, int arg3) throws JMSException {
-
- return null;
- }
-
- public Session createSession(boolean arg0, int arg1) throws JMSException {
-
- return null;
- }
-
- public String getClientID() throws JMSException {
-
- return null;
- }
-
- public ExceptionListener getExceptionListener() throws JMSException {
-
- return null;
- }
-
- public ConnectionMetaData getMetaData() throws JMSException {
-
- return null;
- }
-
- public void setClientID(String arg0) throws JMSException {
-
- }
-
- public void setExceptionListener(ExceptionListener arg0) throws JMSException {
-
- }
-
- public void start() throws JMSException {
-
- }
-
- public void stop() throws JMSException {
-
- }
+ MockTopicSession session = new MockTopicSession();
+
+ public TopicSession createTopicSession(boolean arg0, int arg1) throws JMSException {
+ return session;
+ }
+
+ public ConnectionConsumer createConnectionConsumer(Topic arg0, String arg1, ServerSessionPool arg2, int arg3) throws JMSException {
+
+ return null;
+ }
+
+ public ConnectionConsumer createDurableConnectionConsumer(Topic arg0, String arg1, String arg2, ServerSessionPool arg3, int arg4) throws JMSException {
+
+ return null;
+ }
+
+ public void close() throws JMSException {
+
+
+ }
+
+ public ConnectionConsumer createConnectionConsumer(Destination arg0, String arg1, ServerSessionPool arg2, int arg3) throws JMSException {
+
+ return null;
+ }
+
+ public Session createSession(boolean arg0, int arg1) throws JMSException {
+
+ return null;
+ }
+
+ public String getClientID() throws JMSException {
+
+ return null;
+ }
+
+ public ExceptionListener getExceptionListener() throws JMSException {
+
+ return null;
+ }
+
+ public ConnectionMetaData getMetaData() throws JMSException {
+
+ return null;
+ }
+
+ public void setClientID(String arg0) throws JMSException {
+
+
+ }
+
+ public void setExceptionListener(ExceptionListener arg0) throws JMSException {
+
+
+ }
+
+ public void start() throws JMSException {
+
+
+ }
+
+ public void stop() throws JMSException {
+
+
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicConnectionFactory.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicConnectionFactory.java
index 6b2ca5a..c8edf3d 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicConnectionFactory.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicConnectionFactory.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,23 +20,23 @@ import javax.jms.TopicConnectionFactory;
public class MockTopicConnectionFactory implements TopicConnectionFactory {
- MockTopicConnection cnx = new MockTopicConnection();
+ MockTopicConnection cnx = new MockTopicConnection();
+
+ public TopicConnection createTopicConnection() throws JMSException {
+ return cnx;
+ }
- public TopicConnection createTopicConnection() throws JMSException {
- return cnx;
- }
+ public TopicConnection createTopicConnection(String user, String pass) throws JMSException {
+
+ return cnx;
+ }
- public TopicConnection createTopicConnection(String user, String pass) throws JMSException {
+ public Connection createConnection() throws JMSException {
+ return null;
+ }
- return cnx;
- }
-
- public Connection createConnection() throws JMSException {
- return null;
- }
-
- public Connection createConnection(String arg0, String arg1) throws JMSException {
- return null;
- }
+ public Connection createConnection(String arg0, String arg1) throws JMSException {
+ return null;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicPublisher.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicPublisher.java
index 55e5928..da5363f 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicPublisher.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicPublisher.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,105 +24,117 @@ import javax.jms.TopicPublisher;
public class MockTopicPublisher implements TopicPublisher {
- List<Message> messageList = new ArrayList<Message>();
- Topic topic;
-
- public MockTopicPublisher(Topic topic) {
- this.topic = topic;
- }
-
- public void publish(Message message) throws JMSException {
- messageList.add(message);
- }
-
- public List<Message> getMessageList() {
- return messageList;
- }
-
- public Topic getTopic() throws JMSException {
- return topic;
- }
-
- public void publish(Message arg0, int arg1, int arg2, long arg3) throws JMSException {
-
- }
-
- public void publish(Topic arg0, Message arg1, int arg2, int arg3, long arg4) throws JMSException {
-
- }
-
- public void publish(Topic arg0, Message arg1) throws JMSException {
-
- }
-
- public void close() throws JMSException {
-
- }
-
- public int getDeliveryMode() throws JMSException {
-
- return 0;
- }
-
- public Destination getDestination() throws JMSException {
-
- return null;
- }
-
- public boolean getDisableMessageID() throws JMSException {
-
- return false;
- }
-
- public boolean getDisableMessageTimestamp() throws JMSException {
-
- return false;
- }
-
- public int getPriority() throws JMSException {
-
- return 0;
- }
-
- public long getTimeToLive() throws JMSException {
-
- return 0;
- }
-
- public void send(Destination arg0, Message arg1, int arg2, int arg3, long arg4) throws JMSException {
-
- }
-
- public void send(Destination arg0, Message arg1) throws JMSException {
-
- }
-
- public void send(Message arg0, int arg1, int arg2, long arg3) throws JMSException {
-
- }
-
- public void send(Message arg0) throws JMSException {
-
- }
-
- public void setDeliveryMode(int arg0) throws JMSException {
-
- }
-
- public void setDisableMessageID(boolean arg0) throws JMSException {
-
- }
-
- public void setDisableMessageTimestamp(boolean arg0) throws JMSException {
-
- }
-
- public void setPriority(int arg0) throws JMSException {
-
- }
-
- public void setTimeToLive(long arg0) throws JMSException {
-
- }
+ List<Message> messageList = new ArrayList<Message>();
+ Topic topic;
+
+ public MockTopicPublisher(Topic topic) {
+ this.topic = topic;
+ }
+
+ public void publish(Message message) throws JMSException {
+ messageList.add(message);
+ }
+
+ public List<Message> getMessageList() {
+ return messageList;
+ }
+
+ public Topic getTopic() throws JMSException {
+ return topic;
+ }
+
+ public void publish(Message arg0, int arg1, int arg2, long arg3) throws JMSException {
+
+ }
+
+ public void publish(Topic arg0, Message arg1, int arg2, int arg3, long arg4) throws JMSException {
+
+
+ }
+
+ public void publish(Topic arg0, Message arg1) throws JMSException {
+
+
+ }
+
+ public void close() throws JMSException {
+
+
+ }
+
+ public int getDeliveryMode() throws JMSException {
+
+ return 0;
+ }
+
+ public Destination getDestination() throws JMSException {
+
+ return null;
+ }
+
+ public boolean getDisableMessageID() throws JMSException {
+
+ return false;
+ }
+
+ public boolean getDisableMessageTimestamp() throws JMSException {
+
+ return false;
+ }
+
+ public int getPriority() throws JMSException {
+
+ return 0;
+ }
+
+ public long getTimeToLive() throws JMSException {
+
+ return 0;
+ }
+
+ public void send(Destination arg0, Message arg1, int arg2, int arg3, long arg4) throws JMSException {
+
+
+ }
+
+ public void send(Destination arg0, Message arg1) throws JMSException {
+
+
+ }
+
+ public void send(Message arg0, int arg1, int arg2, long arg3) throws JMSException {
+
+
+ }
+
+ public void send(Message arg0) throws JMSException {
+
+
+ }
+
+ public void setDeliveryMode(int arg0) throws JMSException {
+
+
+ }
+
+ public void setDisableMessageID(boolean arg0) throws JMSException {
+
+
+ }
+
+ public void setDisableMessageTimestamp(boolean arg0) throws JMSException {
+
+
+ }
+
+ public void setPriority(int arg0) throws JMSException {
+
+
+ }
+
+ public void setTimeToLive(long arg0) throws JMSException {
+
+
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicSession.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicSession.java
index 24b6f2c..898a8b5 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicSession.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/mock/MockTopicSession.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -37,157 +37,162 @@ import javax.jms.TopicSubscriber;
public class MockTopicSession implements TopicSession {
- public ObjectMessage createObjectMessage() throws JMSException {
- return new MockObjectMessage();
- }
-
- public TopicPublisher createPublisher(Topic topic) throws JMSException {
- if (topic == null) {
- return null;
- }
- return new MockTopicPublisher(topic);
- }
-
- public TopicSubscriber createDurableSubscriber(Topic arg0, String arg1) throws JMSException {
- return null;
- }
-
- public TopicSubscriber createDurableSubscriber(Topic arg0, String arg1, String arg2, boolean arg3) throws JMSException {
- return null;
- }
-
- public TopicSubscriber createSubscriber(Topic arg0) throws JMSException {
- return null;
- }
-
- public TopicSubscriber createSubscriber(Topic arg0, String arg1, boolean arg2) throws JMSException {
- return null;
- }
-
- public TemporaryTopic createTemporaryTopic() throws JMSException {
- return null;
- }
-
- public Topic createTopic(String arg0) throws JMSException {
- return null;
- }
-
- public void unsubscribe(String arg0) throws JMSException {
-
- }
-
- public void close() throws JMSException {
-
- }
-
- public void commit() throws JMSException {
-
- }
-
- public QueueBrowser createBrowser(Queue arg0) throws JMSException {
-
- return null;
- }
-
- public QueueBrowser createBrowser(Queue arg0, String arg1) throws JMSException {
-
- return null;
- }
-
- public BytesMessage createBytesMessage() throws JMSException {
-
- return null;
- }
-
- public MessageConsumer createConsumer(Destination arg0) throws JMSException {
-
- return null;
- }
-
- public MessageConsumer createConsumer(Destination arg0, String arg1) throws JMSException {
-
- return null;
- }
-
- public MessageConsumer createConsumer(Destination arg0, String arg1, boolean arg2) throws JMSException {
-
- return null;
- }
-
- public MapMessage createMapMessage() throws JMSException {
-
- return null;
- }
-
- public Message createMessage() throws JMSException {
-
- return null;
- }
-
- public ObjectMessage createObjectMessage(Serializable arg0) throws JMSException {
-
- return null;
- }
-
- public MessageProducer createProducer(Destination arg0) throws JMSException {
-
- return null;
- }
-
- public Queue createQueue(String arg0) throws JMSException {
-
- return null;
- }
-
- public StreamMessage createStreamMessage() throws JMSException {
-
- return null;
- }
-
- public TemporaryQueue createTemporaryQueue() throws JMSException {
-
- return null;
- }
-
- public TextMessage createTextMessage() throws JMSException {
-
- return null;
- }
-
- public TextMessage createTextMessage(String arg0) throws JMSException {
-
- return null;
- }
-
- public int getAcknowledgeMode() throws JMSException {
-
- return 0;
- }
-
- public MessageListener getMessageListener() throws JMSException {
-
- return null;
- }
-
- public boolean getTransacted() throws JMSException {
-
- return false;
- }
-
- public void recover() throws JMSException {
-
- }
-
- public void rollback() throws JMSException {
-
- }
-
- public void run() {
-
- }
-
- public void setMessageListener(MessageListener arg0) throws JMSException {
-
- }
+ public ObjectMessage createObjectMessage() throws JMSException {
+ return new MockObjectMessage();
+ }
+
+ public TopicPublisher createPublisher(Topic topic) throws JMSException {
+ if (topic == null) {
+ return null;
+ }
+ return new MockTopicPublisher(topic);
+ }
+
+
+ public TopicSubscriber createDurableSubscriber(Topic arg0, String arg1) throws JMSException {
+ return null;
+ }
+
+ public TopicSubscriber createDurableSubscriber(Topic arg0, String arg1, String arg2, boolean arg3) throws JMSException {
+ return null;
+ }
+
+ public TopicSubscriber createSubscriber(Topic arg0) throws JMSException {
+ return null;
+ }
+
+ public TopicSubscriber createSubscriber(Topic arg0, String arg1, boolean arg2) throws JMSException {
+ return null;
+ }
+
+ public TemporaryTopic createTemporaryTopic() throws JMSException {
+ return null;
+ }
+
+ public Topic createTopic(String arg0) throws JMSException {
+ return null;
+ }
+
+ public void unsubscribe(String arg0) throws JMSException {
+
+ }
+
+ public void close() throws JMSException {
+
+ }
+
+ public void commit() throws JMSException {
+
+ }
+
+ public QueueBrowser createBrowser(Queue arg0) throws JMSException {
+
+ return null;
+ }
+
+ public QueueBrowser createBrowser(Queue arg0, String arg1) throws JMSException {
+
+ return null;
+ }
+
+ public BytesMessage createBytesMessage() throws JMSException {
+
+ return null;
+ }
+
+ public MessageConsumer createConsumer(Destination arg0) throws JMSException {
+
+ return null;
+ }
+
+ public MessageConsumer createConsumer(Destination arg0, String arg1) throws JMSException {
+
+ return null;
+ }
+
+ public MessageConsumer createConsumer(Destination arg0, String arg1, boolean arg2) throws JMSException {
+
+ return null;
+ }
+
+ public MapMessage createMapMessage() throws JMSException {
+
+ return null;
+ }
+
+ public Message createMessage() throws JMSException {
+
+ return null;
+ }
+
+ public ObjectMessage createObjectMessage(Serializable arg0) throws JMSException {
+
+ return null;
+ }
+
+ public MessageProducer createProducer(Destination arg0) throws JMSException {
+
+ return null;
+ }
+
+ public Queue createQueue(String arg0) throws JMSException {
+
+ return null;
+ }
+
+ public StreamMessage createStreamMessage() throws JMSException {
+
+ return null;
+ }
+
+ public TemporaryQueue createTemporaryQueue() throws JMSException {
+
+ return null;
+ }
+
+ public TextMessage createTextMessage() throws JMSException {
+
+ return null;
+ }
+
+ public TextMessage createTextMessage(String arg0) throws JMSException {
+
+ return null;
+ }
+
+ public int getAcknowledgeMode() throws JMSException {
+
+ return 0;
+ }
+
+ public MessageListener getMessageListener() throws JMSException {
+
+ return null;
+ }
+
+ public boolean getTransacted() throws JMSException {
+
+ return false;
+ }
+
+ public void recover() throws JMSException {
+
+
+ }
+
+ public void rollback() throws JMSException {
+
+
+ }
+
+ public void run() {
+
+
+ }
+
+ public void setMessageListener(MessageListener arg0) throws JMSException {
+
+
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/server/InstrumentedServerSocketReceiver.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/server/InstrumentedServerSocketReceiver.java
index f2c6ea6..64dc1c5 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/server/InstrumentedServerSocketReceiver.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/server/InstrumentedServerSocketReceiver.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,63 +26,71 @@ import ch.qos.logback.classic.net.server.ServerSocketReceiver;
import ch.qos.logback.core.net.server.ServerListener;
import ch.qos.logback.core.net.server.ServerRunner;
+
/**
* A {@link ServerSocketReceiver} with instrumentation for unit testing.
*
* @author Carl Harris
*/
public class InstrumentedServerSocketReceiver extends ServerSocketReceiver {
-
- private final ServerSocket serverSocket;
- private final ServerListener<RemoteAppenderClient> listener;
- private final ServerRunner<RemoteAppenderClient> runner;
-
- private ServerListener lastListener;
-
- public InstrumentedServerSocketReceiver(ServerSocket serverSocket) {
- this(serverSocket, new RemoteAppenderServerListener(serverSocket), null);
- }
-
- public InstrumentedServerSocketReceiver(ServerSocket serverSocket, ServerListener<RemoteAppenderClient> listener, ServerRunner<RemoteAppenderClient> runner) {
- this.serverSocket = serverSocket;
- this.listener = listener;
- this.runner = runner;
- }
-
- @Override
- protected ServerSocketFactory getServerSocketFactory() throws Exception {
- return new ServerSocketFactory() {
-
- @Override
- public ServerSocket createServerSocket(int port) throws IOException {
- return serverSocket;
- }
-
- @Override
- public ServerSocket createServerSocket(int port, int backlog) throws IOException {
- return serverSocket;
- }
-
- @Override
- public ServerSocket createServerSocket(int port, int backlog, InetAddress ifAddress) throws IOException {
- return serverSocket;
- }
- };
- }
-
- @Override
- protected ServerRunner createServerRunner(ServerListener<RemoteAppenderClient> listener, Executor executor) {
- lastListener = listener;
- return runner != null ? runner : super.createServerRunner(listener, executor);
- }
-
- @Override
- protected ServerListener<RemoteAppenderClient> createServerListener(ServerSocket socket) {
- return listener;
- }
-
- public ServerListener getLastListener() {
- return lastListener;
- }
+
+ private final ServerSocket serverSocket;
+ private final ServerListener<RemoteAppenderClient> listener;
+ private final ServerRunner<RemoteAppenderClient> runner;
+
+ private ServerListener lastListener;
+
+ public InstrumentedServerSocketReceiver(ServerSocket serverSocket) {
+ this(serverSocket, new RemoteAppenderServerListener(serverSocket), null);
+ }
+
+ public InstrumentedServerSocketReceiver(ServerSocket serverSocket,
+ ServerListener<RemoteAppenderClient> listener,
+ ServerRunner<RemoteAppenderClient> runner) {
+ this.serverSocket = serverSocket;
+ this.listener = listener;
+ this.runner = runner;
+ }
+
+ @Override
+ protected ServerSocketFactory getServerSocketFactory() throws Exception {
+ return new ServerSocketFactory() {
+
+ @Override
+ public ServerSocket createServerSocket(int port) throws IOException {
+ return serverSocket;
+ }
+
+ @Override
+ public ServerSocket createServerSocket(int port, int backlog)
+ throws IOException {
+ return serverSocket;
+ }
+
+ @Override
+ public ServerSocket createServerSocket(int port, int backlog,
+ InetAddress ifAddress) throws IOException {
+ return serverSocket;
+ }
+ };
+ }
+
+ @Override
+ protected ServerRunner createServerRunner(
+ ServerListener<RemoteAppenderClient> listener,
+ Executor executor) {
+ lastListener = listener;
+ return runner != null ? runner : super.createServerRunner(listener, executor);
+ }
+
+ @Override
+ protected ServerListener<RemoteAppenderClient> createServerListener(
+ ServerSocket socket) {
+ return listener;
+ }
+
+ public ServerListener getLastListener() {
+ return lastListener;
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/server/MockSSLConfiguration.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/server/MockSSLConfiguration.java
index b353fb0..2c39b27 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/server/MockSSLConfiguration.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/server/MockSSLConfiguration.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -32,17 +32,19 @@ import ch.qos.logback.core.spi.ContextAware;
*/
class MockSSLConfiguration extends SSLConfiguration {
- private boolean contextCreated;
-
- @Override
- public SSLContext createContext(ContextAware context) throws NoSuchProviderException, NoSuchAlgorithmException, KeyManagementException,
- UnrecoverableKeyException, KeyStoreException, CertificateException {
- contextCreated = true;
- return super.createContext(context);
- }
-
- public boolean isContextCreated() {
- return contextCreated;
- }
+ private boolean contextCreated;
+
+ @Override
+ public SSLContext createContext(ContextAware context)
+ throws NoSuchProviderException, NoSuchAlgorithmException,
+ KeyManagementException, UnrecoverableKeyException, KeyStoreException,
+ CertificateException {
+ contextCreated = true;
+ return super.createContext(context);
+ }
+
+ public boolean isContextCreated() {
+ return contextCreated;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/server/MockSSLParametersConfiguration.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/server/MockSSLParametersConfiguration.java
index 2c3d13d..fe6ba5e 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/server/MockSSLParametersConfiguration.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/server/MockSSLParametersConfiguration.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,16 +24,16 @@ import ch.qos.logback.core.net.ssl.SSLParametersConfiguration;
*/
class MockSSLParametersConfiguration extends SSLParametersConfiguration {
- private boolean contextInjected;
-
- @Override
- public void setContext(Context context) {
- contextInjected = true;
- super.setContext(context);
- }
-
- public boolean isContextInjected() {
- return contextInjected;
- }
+ private boolean contextInjected;
+
+ @Override
+ public void setContext(Context context) {
+ contextInjected = true;
+ super.setContext(context);
+ }
+ public boolean isContextInjected() {
+ return contextInjected;
+ }
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/server/RemoteAppenderStreamClientTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/server/RemoteAppenderStreamClientTest.java
index 8989f69..9276ae0 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/server/RemoteAppenderStreamClientTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/server/RemoteAppenderStreamClientTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -39,53 +39,54 @@ import ch.qos.logback.classic.spi.LoggingEventVO;
*/
public class RemoteAppenderStreamClientTest {
- private MockAppender appender;
- private Logger logger;
- private LoggingEvent event;
- private RemoteAppenderStreamClient client;
-
- @Before
- public void setUp() throws Exception {
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
-
- appender = new MockAppender();
- appender.start();
-
- logger = lc.getLogger(getClass());
- logger.addAppender(appender);
-
- event = new LoggingEvent(logger.getName(), logger, Level.DEBUG, "test message", null, new Object[0]);
-
- LoggingEventVO eventVO = LoggingEventVO.build(event);
-
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(bos);
- oos.writeObject(eventVO);
- oos.close();
-
- ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
- client = new RemoteAppenderStreamClient("some client ID", bis);
- client.setLoggerContext(lc);
- }
-
- @Test
- public void testWithEnabledLevel() throws Exception {
- logger.setLevel(Level.DEBUG);
- client.run();
- client.close();
-
- ILoggingEvent rcvdEvent = appender.getLastEvent();
- assertEquals(event.getLoggerName(), rcvdEvent.getLoggerName());
- assertEquals(event.getLevel(), rcvdEvent.getLevel());
- assertEquals(event.getMessage(), rcvdEvent.getMessage());
- }
-
- @Test
- public void testWithDisabledLevel() throws Exception {
- logger.setLevel(Level.INFO);
- client.run();
- client.close();
- assertNull(appender.getLastEvent());
- }
+ private MockAppender appender;
+ private Logger logger;
+ private LoggingEvent event;
+ private RemoteAppenderStreamClient client;
+
+ @Before
+ public void setUp() throws Exception {
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+
+ appender = new MockAppender();
+ appender.start();
+
+ logger = lc.getLogger(getClass());
+ logger.addAppender(appender);
+
+ event = new LoggingEvent(logger.getName(), logger,
+ Level.DEBUG, "test message", null, new Object[0]);
+
+ LoggingEventVO eventVO = LoggingEventVO.build(event);
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+ oos.writeObject(eventVO);
+ oos.close();
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ client = new RemoteAppenderStreamClient("some client ID", bis);
+ client.setLoggerContext(lc);
+ }
+
+ @Test
+ public void testWithEnabledLevel() throws Exception {
+ logger.setLevel(Level.DEBUG);
+ client.run();
+ client.close();
+
+ ILoggingEvent rcvdEvent = appender.getLastEvent();
+ assertEquals(event.getLoggerName(), rcvdEvent.getLoggerName());
+ assertEquals(event.getLevel(), rcvdEvent.getLevel());
+ assertEquals(event.getMessage(), rcvdEvent.getMessage());
+ }
+
+ @Test
+ public void testWithDisabledLevel() throws Exception {
+ logger.setLevel(Level.INFO);
+ client.run();
+ client.close();
+ assertNull(appender.getLastEvent());
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/server/SSLServerSocketReceiverTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/server/SSLServerSocketReceiverTest.java
index ddddba7..0ab1c63 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/server/SSLServerSocketReceiverTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/server/SSLServerSocketReceiverTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,27 +30,28 @@ import ch.qos.logback.core.net.mock.MockContext;
*/
public class SSLServerSocketReceiverTest {
- private MockContext context = new MockContext();
-
- private MockSSLConfiguration ssl = new MockSSLConfiguration();
-
- private MockSSLParametersConfiguration parameters = new MockSSLParametersConfiguration();
-
- private SSLServerSocketReceiver receiver = new SSLServerSocketReceiver();
-
- @Before
- public void setUp() throws Exception {
- receiver.setContext(context);
- receiver.setSsl(ssl);
- ssl.setParameters(parameters);
- }
-
- @Test
- public void testGetServerSocketFactory() throws Exception {
- ServerSocketFactory socketFactory = receiver.getServerSocketFactory();
- assertNotNull(socketFactory);
- assertTrue(ssl.isContextCreated());
- assertTrue(parameters.isContextInjected());
- }
+ private MockContext context = new MockContext();
+
+ private MockSSLConfiguration ssl = new MockSSLConfiguration();
+
+ private MockSSLParametersConfiguration parameters =
+ new MockSSLParametersConfiguration();
+
+ private SSLServerSocketReceiver receiver = new SSLServerSocketReceiver();
+
+ @Before
+ public void setUp() throws Exception {
+ receiver.setContext(context);
+ receiver.setSsl(ssl);
+ ssl.setParameters(parameters);
+ }
+
+ @Test
+ public void testGetServerSocketFactory() throws Exception {
+ ServerSocketFactory socketFactory = receiver.getServerSocketFactory();
+ assertNotNull(socketFactory);
+ assertTrue(ssl.isContextCreated());
+ assertTrue(parameters.isContextInjected());
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/server/ServerSocketReceiverFunctionalTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/server/ServerSocketReceiverFunctionalTest.java
index 5d8624e..b3bc5dd 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/server/ServerSocketReceiverFunctionalTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/server/ServerSocketReceiverFunctionalTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -46,66 +46,69 @@ import ch.qos.logback.core.net.server.ServerSocketUtil;
*/
public class ServerSocketReceiverFunctionalTest {
- private static final int EVENT_COUNT = 10;
- private static final int SHUTDOWN_DELAY = 10000;
-
- private MockAppender appender;
- private Logger logger;
- private ServerSocket serverSocket;
- private InstrumentedServerSocketReceiver receiver;
- private LoggerContext lc;
-
- @Before
- public void setUp() throws Exception {
- lc = new LoggerContext();
-
- appender = new MockAppender();
- appender.start();
-
- logger = lc.getLogger(getClass());
- logger.addAppender(appender);
-
- serverSocket = ServerSocketUtil.createServerSocket();
-
- receiver = new InstrumentedServerSocketReceiver(serverSocket);
-
- receiver.setContext(lc);
- receiver.start();
+ private static final int EVENT_COUNT = 10;
+ private static final int SHUTDOWN_DELAY = 10000;
+
+ private MockAppender appender;
+ private Logger logger;
+ private ServerSocket serverSocket;
+ private InstrumentedServerSocketReceiver receiver;
+ private LoggerContext lc;
+
+ @Before
+ public void setUp() throws Exception {
+ lc = new LoggerContext();
+
+ appender = new MockAppender();
+ appender.start();
+
+ logger = lc.getLogger(getClass());
+ logger.addAppender(appender);
+
+ serverSocket = ServerSocketUtil.createServerSocket();
+
+ receiver = new InstrumentedServerSocketReceiver(serverSocket);
+
+ receiver.setContext(lc);
+ receiver.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ receiver.stop();
+ ExecutorService executor = lc.getExecutorService();
+ executor.shutdownNow();
+ executor.awaitTermination(SHUTDOWN_DELAY, TimeUnit.MILLISECONDS);
+ assertTrue(executor.isTerminated());
+ }
+
+ @Test
+ public void testLogEventFromClient() throws Exception {
+ ILoggingEvent event = new LoggingEvent(logger.getName(), logger,
+ Level.DEBUG, "test message", null, new Object[0]);
+ Socket socket = new Socket(InetAddress.getLocalHost(),
+ serverSocket.getLocalPort());
+
+ try {
+ LoggingEventVO eventVO = LoggingEventVO.build(event);
+
+ ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
+ for (int i = 0; i < EVENT_COUNT; i++) {
+ oos.writeObject(eventVO);
+ }
+
+ oos.writeObject(eventVO);
+ oos.flush();
}
-
- @After
- public void tearDown() throws Exception {
- receiver.stop();
- ExecutorService executor = lc.getExecutorService();
- executor.shutdownNow();
- executor.awaitTermination(SHUTDOWN_DELAY, TimeUnit.MILLISECONDS);
- assertTrue(executor.isTerminated());
- }
-
- @Test
- public void testLogEventFromClient() throws Exception {
- ILoggingEvent event = new LoggingEvent(logger.getName(), logger, Level.DEBUG, "test message", null, new Object[0]);
- Socket socket = new Socket(InetAddress.getLocalHost(), serverSocket.getLocalPort());
-
- try {
- LoggingEventVO eventVO = LoggingEventVO.build(event);
-
- ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
- for (int i = 0; i < EVENT_COUNT; i++) {
- oos.writeObject(eventVO);
- }
-
- oos.writeObject(eventVO);
- oos.flush();
- } finally {
- socket.close();
- }
-
- ILoggingEvent rcvdEvent = appender.awaitAppend(SHUTDOWN_DELAY);
- assertNotNull(rcvdEvent);
- assertEquals(event.getLoggerName(), rcvdEvent.getLoggerName());
- assertEquals(event.getLevel(), rcvdEvent.getLevel());
- assertEquals(event.getMessage(), rcvdEvent.getMessage());
+ finally {
+ socket.close();
}
+
+ ILoggingEvent rcvdEvent = appender.awaitAppend(SHUTDOWN_DELAY);
+ assertNotNull(rcvdEvent);
+ assertEquals(event.getLoggerName(), rcvdEvent.getLoggerName());
+ assertEquals(event.getLevel(), rcvdEvent.getLevel());
+ assertEquals(event.getMessage(), rcvdEvent.getMessage());
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/server/ServerSocketReceiverTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/server/ServerSocketReceiverTest.java
index e62aba0..f4d4ceb 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/server/ServerSocketReceiverTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/server/ServerSocketReceiverTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -40,64 +40,66 @@ import ch.qos.logback.core.status.Status;
*/
public class ServerSocketReceiverTest {
- private MockContext context = new MockContext();
-
- private MockServerRunner<RemoteAppenderClient> runner = new MockServerRunner<RemoteAppenderClient>();
-
- private MockServerListener<RemoteAppenderClient> listener = new MockServerListener<RemoteAppenderClient>();
-
- private ServerSocket serverSocket;
- private InstrumentedServerSocketReceiver receiver;
-
- @Before
- public void setUp() throws Exception {
- serverSocket = ServerSocketUtil.createServerSocket();
- receiver = new InstrumentedServerSocketReceiver(serverSocket, listener, runner);
- receiver.setContext(context);
- }
-
- @After
- public void tearDown() throws Exception {
- serverSocket.close();
- }
-
- @Test
- public void testStartStop() throws Exception {
- receiver.start();
- assertTrue(runner.isContextInjected());
- assertTrue(runner.isRunning());
- assertSame(listener, receiver.getLastListener());
-
- receiver.stop();
- assertFalse(runner.isRunning());
- }
-
- @Test
- public void testStartWhenAlreadyStarted() throws Exception {
- receiver.start();
- receiver.start();
- assertEquals(1, runner.getStartCount());
- }
-
- @Test
- public void testStopThrowsException() throws Exception {
- receiver.start();
- assertTrue(receiver.isStarted());
- IOException ex = new IOException("test exception");
- runner.setStopException(ex);
- receiver.stop();
-
- Status status = context.getLastStatus();
- assertNotNull(status);
- assertTrue(status instanceof ErrorStatus);
- assertTrue(status.getMessage().contains(ex.getMessage()));
- assertSame(ex, status.getThrowable());
- }
-
- @Test
- public void testStopWhenNotStarted() throws Exception {
- receiver.stop();
- assertEquals(0, runner.getStartCount());
- }
+ private MockContext context = new MockContext();
+
+ private MockServerRunner<RemoteAppenderClient> runner =
+ new MockServerRunner<RemoteAppenderClient>();
+
+ private MockServerListener<RemoteAppenderClient> listener =
+ new MockServerListener<RemoteAppenderClient>();
+
+ private ServerSocket serverSocket;
+ private InstrumentedServerSocketReceiver receiver;
+
+ @Before
+ public void setUp() throws Exception {
+ serverSocket = ServerSocketUtil.createServerSocket();
+ receiver = new InstrumentedServerSocketReceiver(serverSocket, listener, runner);
+ receiver.setContext(context);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ serverSocket.close();
+ }
+
+ @Test
+ public void testStartStop() throws Exception {
+ receiver.start();
+ assertTrue(runner.isContextInjected());
+ assertTrue(runner.isRunning());
+ assertSame(listener, receiver.getLastListener());
+
+ receiver.stop();
+ assertFalse(runner.isRunning());
+ }
+
+ @Test
+ public void testStartWhenAlreadyStarted() throws Exception {
+ receiver.start();
+ receiver.start();
+ assertEquals(1, runner.getStartCount());
+ }
+
+ @Test
+ public void testStopThrowsException() throws Exception {
+ receiver.start();
+ assertTrue(receiver.isStarted());
+ IOException ex = new IOException("test exception");
+ runner.setStopException(ex);
+ receiver.stop();
+
+ Status status = context.getLastStatus();
+ assertNotNull(status);
+ assertTrue(status instanceof ErrorStatus);
+ assertTrue(status.getMessage().contains(ex.getMessage()));
+ assertSame(ex, status.getThrowable());
+ }
+
+ @Test
+ public void testStopWhenNotStarted() throws Exception {
+ receiver.stop();
+ assertEquals(0, runner.getStartCount());
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/Builder.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/Builder.java
index b49c910..b07038b 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/Builder.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/Builder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,10 +15,10 @@ package ch.qos.logback.classic.net.testObjectBuilders;
public interface Builder<E> {
- // 45 characters message
- String MSG_PREFIX = "aaaaabbbbbcccccdddddaaaaabbbbbcccccdddddaaaa";
+ // 45 characters message
+ String MSG_PREFIX = "aaaaabbbbbcccccdddddaaaaabbbbbcccccdddddaaaa";
- // final String MSG_PREFIX = "a";
+ // final String MSG_PREFIX = "a";
- E build(int i);
+ E build(int i);
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/LoggingEventBuilderInContext.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/LoggingEventBuilderInContext.java
index 9c170f5..df194d8 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/LoggingEventBuilderInContext.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/LoggingEventBuilderInContext.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,19 +21,21 @@ import ch.qos.logback.classic.spi.LoggingEvent;
public class LoggingEventBuilderInContext implements Builder<ILoggingEvent> {
- LoggerContext loggerContext;
- Logger logger;
- String fqcn;
- public LoggingEventBuilderInContext(LoggerContext loggerContext, String loggerName, String fqcn) {
- this.loggerContext = loggerContext;
- logger = loggerContext.getLogger(loggerName);
- this.fqcn = fqcn;
- }
+ LoggerContext loggerContext;
+ Logger logger;
+ String fqcn;
+ public LoggingEventBuilderInContext(LoggerContext loggerContext, String loggerName, String fqcn) {
+ this.loggerContext = loggerContext;
+ logger = loggerContext.getLogger(loggerName);
+ this.fqcn = fqcn;
+ }
- public ILoggingEvent build(int i) {
- LoggingEvent le = new LoggingEvent(fqcn, logger, Level.DEBUG, "hello " + i, null, null);
- return le;
- }
+
+ public ILoggingEvent build(int i) {
+ LoggingEvent le = new LoggingEvent(fqcn, logger, Level.DEBUG, "hello " + i,
+ null, null);
+ return le;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/LoggingEventWithParametersBuilder.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/LoggingEventWithParametersBuilder.java
index 468d974..2161c36 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/LoggingEventWithParametersBuilder.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/LoggingEventWithParametersBuilder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,30 +20,30 @@ import ch.qos.logback.classic.spi.LoggingEvent;
public class LoggingEventWithParametersBuilder implements Builder<LoggingEvent> {
- final String MSG = "aaaaabbbbbcccc {} cdddddaaaaabbbbbcccccdddddaaaa {}";
+ final String MSG = "aaaaabbbbbcccc {} cdddddaaaaabbbbbcccccdddddaaaa {}";
- LoggerContext loggerContext = new LoggerContext();
- private Logger logger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
+ LoggerContext loggerContext = new LoggerContext();
+ private Logger logger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
- public LoggingEvent build(int i) {
+ public LoggingEvent build(int i) {
- LoggingEvent le = new LoggingEvent();
- le.setTimeStamp(System.currentTimeMillis());
+ LoggingEvent le = new LoggingEvent();
+ le.setTimeStamp(System.currentTimeMillis());
- Object[] aa = new Object[] { i, "HELLO WORLD [========== ]" + i };
+ Object[] aa = new Object[] { i, "HELLO WORLD [========== ]" + i };
- le.setArgumentArray(aa);
- String msg = MSG + i;
- le.setMessage(msg);
+ le.setArgumentArray(aa);
+ String msg = MSG + i;
+ le.setMessage(msg);
- // compute formatted message
- // this forces le.formmatedMessage to be set (this is the whole point of the
- // exercise)
- le.getFormattedMessage();
- le.setLevel(Level.DEBUG);
- le.setLoggerName(logger.getName());
- le.setLoggerContextRemoteView(loggerContext.getLoggerContextRemoteView());
- le.setThreadName("threadName");
- return le;
- }
+ // compute formatted message
+ // this forces le.formmatedMessage to be set (this is the whole point of the
+ // exercise)
+ le.getFormattedMessage();
+ le.setLevel(Level.DEBUG);
+ le.setLoggerName(logger.getName());
+ le.setLoggerContextRemoteView(loggerContext.getLoggerContextRemoteView());
+ le.setThreadName("threadName");
+ return le;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/MinimalSerBuilder.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/MinimalSerBuilder.java
index 0ebb5d9..04bffb8 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/MinimalSerBuilder.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/MinimalSerBuilder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,21 +15,22 @@ package ch.qos.logback.classic.net.testObjectBuilders;
import java.io.Serializable;
-public class MinimalSerBuilder implements Builder {
- public Object build(int i) {
- return new MinimalSer(i);
- }
+public class MinimalSerBuilder implements Builder{
+
+ public Object build(int i) {
+ return new MinimalSer(i);
+ }
}
class MinimalSer implements Serializable {
- private static final long serialVersionUID = 2807646397580899815L;
+ private static final long serialVersionUID = 2807646397580899815L;
- String message;
+ String message;
- public MinimalSer(int i) {
- message = Builder.MSG_PREFIX;
- }
+ public MinimalSer(int i) {
+ message = Builder.MSG_PREFIX;
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/TrivialLoggingEventBuilder.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/TrivialLoggingEventBuilder.java
index c81bb4a..08c7694 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/TrivialLoggingEventBuilder.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/TrivialLoggingEventBuilder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,18 +20,18 @@ import ch.qos.logback.classic.spi.LoggingEvent;
public class TrivialLoggingEventBuilder implements Builder {
- LoggerContext loggerContext = new LoggerContext();
+ LoggerContext loggerContext = new LoggerContext();
- private Logger logger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
+ private Logger logger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
- public Object build(int i) {
- LoggingEvent le = new LoggingEvent();
- le.setTimeStamp(System.currentTimeMillis());
- le.setLevel(Level.DEBUG);
- le.setLoggerName(logger.getName());
- le.setLoggerContextRemoteView(loggerContext.getLoggerContextRemoteView());
- le.setMessage(MSG_PREFIX);
- le.setThreadName("threadName");
- return le;
- }
+ public Object build(int i) {
+ LoggingEvent le = new LoggingEvent();
+ le.setTimeStamp(System.currentTimeMillis());
+ le.setLevel(Level.DEBUG);
+ le.setLoggerName(logger.getName());
+ le.setLoggerContextRemoteView(loggerContext.getLoggerContextRemoteView());
+ le.setMessage(MSG_PREFIX);
+ le.setThreadName("threadName");
+ return le;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/TrivialLoggingEventVOBuilder.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/TrivialLoggingEventVOBuilder.java
index 8fc894f..5d7901c 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/TrivialLoggingEventVOBuilder.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/testObjectBuilders/TrivialLoggingEventVOBuilder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,11 +21,11 @@ import ch.qos.logback.classic.spi.LoggingEventVO;
*/
public class TrivialLoggingEventVOBuilder implements Builder {
- public Object build(int i) {
- TrivialLoggingEventBuilder loggingEventBuilder = new TrivialLoggingEventBuilder();
- LoggingEvent event = (LoggingEvent) loggingEventBuilder.build(i);
+ public Object build(int i) {
+ TrivialLoggingEventBuilder loggingEventBuilder = new TrivialLoggingEventBuilder();
+ LoggingEvent event = (LoggingEvent) loggingEventBuilder.build(i);
- return LoggingEventVO.build(event);
- }
+ return LoggingEventVO.build(event);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ConverterTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ConverterTest.java
index 90d0b65..e34f4f8 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ConverterTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ConverterTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,10 @@
*/
package ch.qos.logback.classic.pattern;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import java.util.ArrayList;
import java.util.List;
@@ -33,369 +37,351 @@ import ch.qos.logback.core.net.SyslogConstants;
import ch.qos.logback.core.pattern.DynamicConverter;
import ch.qos.logback.core.pattern.FormatInfo;
-import static org.junit.Assert.*;
-import static org.hamcrest.CoreMatchers.*;
-
public class ConverterTest {
- LoggerContext lc = new LoggerContext();
- Logger logger = lc.getLogger(ConverterTest.class);
- LoggingEvent le;
- List<String> optionList = new ArrayList<String>();
-
- // The LoggingEvent is massaged with an FCQN of FormattingConverter. This
- // forces the returned caller information to match the caller stack for this
- // this particular test.
- LoggingEvent makeLoggingEvent(Exception ex) {
- return new LoggingEvent(ch.qos.logback.core.pattern.FormattingConverter.class.getName(), logger, Level.INFO, "Some message", ex, null);
- }
-
- Exception getException(String msg, Exception cause) {
- return new Exception(msg, cause);
- }
-
- @Before
- public void setUp() throws Exception {
- Exception rootEx = getException("Innermost", null);
- Exception nestedEx = getException("Nested", rootEx);
-
- Exception ex = new Exception("Bogus exception", nestedEx);
-
- le = makeLoggingEvent(ex);
- }
-
- @Test
- public void testLineOfCaller() {
- {
- DynamicConverter<ILoggingEvent> converter = new LineOfCallerConverter();
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- // the number below should be the line number of the previous line
- assertEquals("72", buf.toString());
- }
- }
-
- @Test
- public void testLevel() {
- {
- DynamicConverter<ILoggingEvent> converter = new LevelConverter();
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- assertEquals("INFO", buf.toString());
- }
- {
- DynamicConverter<ILoggingEvent> converter = new LevelConverter();
- converter.setFormattingInfo(new FormatInfo(1, 1, true, false));
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- assertEquals("I", buf.toString());
- }
- }
-
- @Test
- public void testThread() {
- DynamicConverter<ILoggingEvent> converter = new ThreadConverter();
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- System.out.println(buf.toString());
- String regex = ClassicTestConstants.NAKED_MAIN_REGEX;
- assertTrue(buf.toString().matches(regex));
+ LoggerContext lc = new LoggerContext();
+ Logger logger = lc.getLogger(ConverterTest.class);
+ LoggingEvent le;
+ List<String> optionList = new ArrayList<String>();
+
+ // The LoggingEvent is massaged with an FCQN of FormattingConverter. This
+ // forces the returned caller information to match the caller stack for this
+ // this particular test.
+ LoggingEvent makeLoggingEvent(Exception ex) {
+ return new LoggingEvent(
+ ch.qos.logback.core.pattern.FormattingConverter.class.getName(),
+ logger, Level.INFO, "Some message", ex, null);
+ }
+
+ Exception getException(String msg, Exception cause) {
+ return new Exception(msg, cause);
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ Exception rootEx = getException("Innermost", null);
+ Exception nestedEx = getException("Nested", rootEx);
+
+ Exception ex = new Exception("Bogus exception", nestedEx);
+
+ le = makeLoggingEvent(ex);
+ }
+
+ @Test
+ public void testLineOfCaller() {
+ {
+ DynamicConverter<ILoggingEvent> converter = new LineOfCallerConverter();
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
+ // the number below should be the line number of the previous line
+ assertEquals("75", buf.toString());
}
-
- @Test
- public void testMessage() {
- DynamicConverter<ILoggingEvent> converter = new MessageConverter();
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- assertEquals("Some message", buf.toString());
+ }
+
+ @Test
+ public void testLevel() {
+ {
+ DynamicConverter<ILoggingEvent> converter = new LevelConverter();
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
+ assertEquals("INFO", buf.toString());
}
-
- @Test
- public void testLineSeparator() {
- DynamicConverter<ILoggingEvent> converter = new LineSeparatorConverter();
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- assertEquals(CoreConstants.LINE_SEPARATOR, buf.toString());
+ {
+ DynamicConverter<ILoggingEvent> converter = new LevelConverter();
+ converter.setFormattingInfo(new FormatInfo(1, 1, true, false));
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
+ assertEquals("I", buf.toString());
}
-
- @Test
- public void testException() {
- {
- DynamicConverter<ILoggingEvent> converter = new ThrowableProxyConverter();
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- }
-
- {
- DynamicConverter<ILoggingEvent> converter = new ThrowableProxyConverter();
- this.optionList.add("3");
- converter.setOptionList(this.optionList);
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- }
+ }
+
+ @Test
+ public void testThread() {
+ DynamicConverter<ILoggingEvent> converter = new ThreadConverter();
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
+ System.out.println(buf.toString());
+ String regex = ClassicTestConstants.NAKED_MAIN_REGEX;
+ assertTrue(buf.toString().matches(regex));
+ }
+
+ @Test
+ public void testMessage() {
+ DynamicConverter<ILoggingEvent> converter = new MessageConverter();
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
+ assertEquals("Some message", buf.toString());
+ }
+
+ @Test
+ public void testLineSeparator() {
+ DynamicConverter<ILoggingEvent> converter = new LineSeparatorConverter();
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
+ assertEquals(CoreConstants.LINE_SEPARATOR, buf.toString());
+ }
+
+ @Test
+ public void testException() {
+ {
+ DynamicConverter<ILoggingEvent> converter = new ThrowableProxyConverter();
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
}
- @Test
- public void testLogger() {
- {
- ClassicConverter converter = new LoggerConverter();
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- assertEquals(this.getClass().getName(), buf.toString());
- }
-
- {
- ClassicConverter converter = new LoggerConverter();
- this.optionList.add("20");
- converter.setOptionList(this.optionList);
- converter.start();
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- assertEquals("c.q.l.c.p.ConverterTest", buf.toString());
- }
-
- {
- DynamicConverter<ILoggingEvent> converter = new LoggerConverter();
- this.optionList.clear();
- this.optionList.add("0");
- converter.setOptionList(this.optionList);
- converter.start();
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- assertEquals("ConverterTest", buf.toString());
- }
+ {
+ DynamicConverter<ILoggingEvent> converter = new ThrowableProxyConverter();
+ this.optionList.add("3");
+ converter.setOptionList(this.optionList);
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
}
-
- @Test
- public void testVeryLongLoggerName() {
- ClassicConverter converter = new LoggerConverter();
- this.optionList.add("5");
- converter.setOptionList(this.optionList);
- converter.start();
- StringBuilder buf = new StringBuilder();
-
- char c = 'a';
- int extraParts = 3;
- int totalParts = ClassicConstants.MAX_DOTS + extraParts;
- StringBuilder loggerNameBuf = new StringBuilder();
- StringBuilder witness = new StringBuilder();
-
- for (int i = 0; i < totalParts; i++) {
- loggerNameBuf.append(c).append(c).append(c);
- if (i < ClassicConstants.MAX_DOTS) {
- witness.append(c);
- } else {
- witness.append(c).append(c).append(c);
- }
- loggerNameBuf.append('.');
- witness.append('.');
- }
- loggerNameBuf.append("zzzzzz");
- witness.append("zzzzzz");
-
- le.setLoggerName(loggerNameBuf.toString());
- converter.write(buf, le);
- assertEquals(witness.toString(), buf.toString());
+ }
+
+ @Test
+ public void testLogger() {
+ {
+ ClassicConverter converter = new LoggerConverter();
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
+ assertEquals(this.getClass().getName(), buf.toString());
}
- @Test
- public void testClass() {
- DynamicConverter<ILoggingEvent> converter = new ClassOfCallerConverter();
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- assertEquals(this.getClass().getName(), buf.toString());
+ {
+ ClassicConverter converter = new LoggerConverter();
+ this.optionList.add("20");
+ converter.setOptionList(this.optionList);
+ converter.start();
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
+ assertEquals("c.q.l.c.p.ConverterTest", buf.toString());
}
- @Test
- public void testMethodOfCaller() {
- DynamicConverter<ILoggingEvent> converter = new MethodOfCallerConverter();
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- assertEquals("testMethodOfCaller", buf.toString());
+ {
+ DynamicConverter<ILoggingEvent> converter = new LoggerConverter();
+ this.optionList.clear();
+ this.optionList.add("0");
+ converter.setOptionList(this.optionList);
+ converter.start();
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
+ assertEquals("ConverterTest", buf.toString());
}
-
- @Test
- public void testFileOfCaller() {
- DynamicConverter<ILoggingEvent> converter = new FileOfCallerConverter();
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- assertEquals("ConverterTest.java", buf.toString());
+ }
+
+ @Test
+ public void testVeryLongLoggerName() {
+ ClassicConverter converter = new LoggerConverter();
+ this.optionList.add("5");
+ converter.setOptionList(this.optionList);
+ converter.start();
+ StringBuilder buf = new StringBuilder();
+
+ char c = 'a';
+ int extraParts = 3;
+ int totalParts = ClassicConstants.MAX_DOTS + extraParts;
+ StringBuilder loggerNameBuf = new StringBuilder();
+ StringBuilder witness = new StringBuilder();
+
+ for(int i = 0; i < totalParts ; i++) {
+ loggerNameBuf.append(c).append(c).append(c);
+ if(i < ClassicConstants.MAX_DOTS) {
+ witness.append(c);
+ } else {
+ witness.append(c).append(c).append(c);
+ }
+ loggerNameBuf.append('.');
+ witness.append('.');
}
-
- @Test
- public void testCallerData() {
- {
- DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
- converter.start();
-
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- if (buf.length() < 10) {
- fail("buf is too short");
- }
- }
-
- {
- DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
- this.optionList.add("2");
- this.optionList.add("XXX");
- converter.setOptionList(this.optionList);
- converter.start();
-
- StringBuilder buf = new StringBuilder();
- LoggingEvent event = makeLoggingEvent(null);
- event.setMarker(MarkerFactory.getMarker("XXX"));
- converter.write(buf, event);
- if (buf.length() < 10) {
- fail("buf is too short");
- }
- }
-
- {
- DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
- this.optionList.clear();
- this.optionList.add("2");
- this.optionList.add("XXX");
- this.optionList.add("*");
- converter.setOptionList(this.optionList);
- converter.start();
-
- StringBuilder buf = new StringBuilder();
- LoggingEvent event = makeLoggingEvent(null);
- event.setMarker(MarkerFactory.getMarker("YYY"));
- converter.write(buf, event);
- if (buf.length() < 10) {
- fail("buf is too short");
- }
- }
- {
- DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
- this.optionList.clear();
- this.optionList.add("2");
- this.optionList.add("XXX");
- this.optionList.add("+");
- converter.setOptionList(this.optionList);
- converter.start();
-
- StringBuilder buf = new StringBuilder();
- LoggingEvent event = makeLoggingEvent(null);
- event.setMarker(MarkerFactory.getMarker("YYY"));
- converter.write(buf, event);
- if (buf.length() < 10) {
- fail("buf is too short");
- }
- }
-
- {
- DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
- this.optionList.clear();
- this.optionList.add("2");
- this.optionList.add("XXX");
- this.optionList.add("*");
- converter.setOptionList(this.optionList);
- converter.start();
-
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- if (buf.length() < 10) {
- fail("buf is too short");
- }
- // System.out.println(buf);
- }
-
- {
- DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
- this.optionList.clear();
- this.optionList.add("4..5");
- converter.setOptionList(this.optionList);
- converter.start();
-
- StringBuilder buf = new StringBuilder();
- converter.write(buf, le);
- assertTrue("buf is too short", buf.length() >= 10);
-
- String expected = "Caller+4\t at java.lang.reflect.Method.invoke(";
- String actual = buf.toString().substring(0, expected.length());
- assertThat(actual, is(expected));
- }
+ loggerNameBuf.append("zzzzzz");
+ witness.append("zzzzzz");
+
+ le.setLoggerName(loggerNameBuf.toString());
+ converter.write(buf, le);
+ assertEquals(witness.toString(), buf.toString());
+ }
+
+ @Test
+ public void testClass() {
+ DynamicConverter<ILoggingEvent> converter = new ClassOfCallerConverter();
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
+ assertEquals(this.getClass().getName(), buf.toString());
+ }
+
+ @Test
+ public void testMethodOfCaller() {
+ DynamicConverter<ILoggingEvent> converter = new MethodOfCallerConverter();
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
+ assertEquals("testMethodOfCaller", buf.toString());
+ }
+
+ @Test
+ public void testFileOfCaller() {
+ DynamicConverter<ILoggingEvent> converter = new FileOfCallerConverter();
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
+ assertEquals("ConverterTest.java", buf.toString());
+ }
+
+ @Test
+ public void testCallerData() {
+ {
+ DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
+ converter.start();
+
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
+ if (buf.length() < 10) {
+ fail("buf is too short");
+ }
}
- @Test
- public void testRelativeTime() throws Exception {
- DynamicConverter<ILoggingEvent> converter = new RelativeTimeConverter();
- StringBuilder buf0 = new StringBuilder();
- StringBuilder buf1 = new StringBuilder();
- long timestamp = System.currentTimeMillis();
- LoggingEvent e0 = makeLoggingEvent(null);
- e0.setTimeStamp(timestamp);
- LoggingEvent e1 = makeLoggingEvent(null);
- e1.setTimeStamp(timestamp);
- converter.write(buf0, e0);
- converter.write(buf1, e1);
- assertEquals(buf0.toString(), buf1.toString());
+ {
+ DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
+ this.optionList.add("2");
+ this.optionList.add("XXX");
+ converter.setOptionList(this.optionList);
+ converter.start();
+
+ StringBuilder buf = new StringBuilder();
+ LoggingEvent event = makeLoggingEvent(null);
+ event.setMarker(MarkerFactory.getMarker("XXX"));
+ converter.write(buf, event);
+ if (buf.length() < 10) {
+ fail("buf is too short");
+ }
}
- @Test
- public void testSyslogStart() throws Exception {
- DynamicConverter<ILoggingEvent> converter = new SyslogStartConverter();
- this.optionList.clear();
- this.optionList.add("MAIL");
- converter.setOptionList(this.optionList);
- converter.start();
-
- ILoggingEvent event = makeLoggingEvent(null);
-
- StringBuilder buf = new StringBuilder();
- converter.write(buf, event);
-
- String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.INFO_SEVERITY) + ">";
- assertTrue(buf.toString().startsWith(expected));
+ {
+ DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
+ this.optionList.clear();
+ this.optionList.add("2");
+ this.optionList.add("XXX");
+ this.optionList.add("*");
+ converter.setOptionList(this.optionList);
+ converter.start();
+
+ StringBuilder buf = new StringBuilder();
+ LoggingEvent event = makeLoggingEvent(null);
+ event.setMarker(MarkerFactory.getMarker("YYY"));
+ converter.write(buf, event);
+ if (buf.length() < 10) {
+ fail("buf is too short");
+ }
}
-
- @Test
- public void testMDCConverter() throws Exception {
- MDC.clear();
- MDC.put("someKey", "someValue");
- MDCConverter converter = new MDCConverter();
- this.optionList.clear();
- this.optionList.add("someKey");
- converter.setOptionList(optionList);
- converter.start();
-
- ILoggingEvent event = makeLoggingEvent(null);
-
- String result = converter.convert(event);
- assertEquals("someValue", result);
+ {
+ DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
+ this.optionList.clear();
+ this.optionList.add("2");
+ this.optionList.add("XXX");
+ this.optionList.add("+");
+ converter.setOptionList(this.optionList);
+ converter.start();
+
+ StringBuilder buf = new StringBuilder();
+ LoggingEvent event = makeLoggingEvent(null);
+ event.setMarker(MarkerFactory.getMarker("YYY"));
+ converter.write(buf, event);
+ if (buf.length() < 10) {
+ fail("buf is too short");
+ }
}
- @Test
- public void contextNameConverter() {
- ClassicConverter converter = new ContextNameConverter();
- // see http://jira.qos.ch/browse/LBCLASSIC-149
- LoggerContext lcOther = new LoggerContext();
- lcOther.setName("another");
- converter.setContext(lcOther);
-
- lc.setName("aValue");
- ILoggingEvent event = makeLoggingEvent(null);
-
- String result = converter.convert(event);
- assertEquals("aValue", result);
+ {
+ DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
+ this.optionList.clear();
+ this.optionList.add("2");
+ this.optionList.add("XXX");
+ this.optionList.add("*");
+ converter.setOptionList(this.optionList);
+ converter.start();
+
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, le);
+ if (buf.length() < 10) {
+ fail("buf is too short");
+ }
+ // System.out.println(buf);
}
- @Test
- public void contextProperty() {
- PropertyConverter converter = new PropertyConverter();
- converter.setContext(lc);
- List<String> ol = new ArrayList<String>();
- ol.add("k");
- converter.setOptionList(ol);
- converter.start();
- lc.setName("aValue");
- lc.putProperty("k", "v");
- ILoggingEvent event = makeLoggingEvent(null);
-
- String result = converter.convert(event);
- assertEquals("v", result);
- }
+ }
+
+ @Test
+ public void testRelativeTime() throws Exception {
+ DynamicConverter<ILoggingEvent> converter = new RelativeTimeConverter();
+ StringBuilder buf0 = new StringBuilder();
+ StringBuilder buf1 = new StringBuilder();
+ ILoggingEvent e0 = makeLoggingEvent(null);
+ ILoggingEvent e1 = makeLoggingEvent(null);
+ converter.write(buf0, e0);
+ converter.write(buf1, e1);
+ assertEquals(buf0.toString(), buf1.toString());
+ }
+
+ @Test
+ public void testSyslogStart() throws Exception {
+ DynamicConverter<ILoggingEvent> converter = new SyslogStartConverter();
+ this.optionList.clear();
+ this.optionList.add("MAIL");
+ converter.setOptionList(this.optionList);
+ converter.start();
+
+ ILoggingEvent event = makeLoggingEvent(null);
+
+ StringBuilder buf = new StringBuilder();
+ converter.write(buf, event);
+
+ String expected = "<"
+ + (SyslogConstants.LOG_MAIL + SyslogConstants.INFO_SEVERITY) + ">";
+ assertTrue(buf.toString().startsWith(expected));
+ }
+
+ @Test
+ public void testMDCConverter() throws Exception {
+ MDC.clear();
+ MDC.put("someKey", "someValue");
+ MDCConverter converter = new MDCConverter();
+ this.optionList.clear();
+ this.optionList.add("someKey");
+ converter.setOptionList(optionList);
+ converter.start();
+
+ ILoggingEvent event = makeLoggingEvent(null);
+
+ String result = converter.convert(event);
+ assertEquals("someValue", result);
+ }
+
+ @Test
+ public void contextNameConverter() {
+ ClassicConverter converter = new ContextNameConverter();
+ // see http://jira.qos.ch/browse/LBCLASSIC-149
+ LoggerContext lcOther = new LoggerContext();
+ lcOther.setName("another");
+ converter.setContext(lcOther);
+
+ lc.setName("aValue");
+ ILoggingEvent event = makeLoggingEvent(null);
+
+ String result = converter.convert(event);
+ assertEquals("aValue", result);
+ }
+
+ @Test
+ public void contextProperty() {
+ PropertyConverter converter = new PropertyConverter();
+ converter.setContext(lc);
+ List<String> ol = new ArrayList<String>();
+ ol.add("k");
+ converter.setOptionList(ol);
+ converter.start();
+ lc.setName("aValue");
+ lc.putProperty("k", "v");
+ ILoggingEvent event = makeLoggingEvent(null);
+
+ String result = converter.convert(event);
+ assertEquals("v", result);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ExtendedThrowableProxyConverterTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ExtendedThrowableProxyConverterTest.java
index 1a714ee..bf5ed27 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ExtendedThrowableProxyConverterTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ExtendedThrowableProxyConverterTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,7 +14,7 @@
package ch.qos.logback.classic.pattern;
import static org.junit.Assert.assertEquals;
-import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertTrue;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -34,72 +34,73 @@ import ch.qos.logback.classic.spi.LoggingEvent;
public class ExtendedThrowableProxyConverterTest {
- LoggerContext lc = new LoggerContext();
- ExtendedThrowableProxyConverter etpc = new ExtendedThrowableProxyConverter();
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
-
- @Before
- public void setUp() throws Exception {
- lc.setPackagingDataEnabled(true);
- etpc.setContext(lc);
- etpc.start();
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
- private ILoggingEvent createLoggingEvent(Throwable t) {
- return new LoggingEvent(this.getClass().getName(), lc.getLogger(Logger.ROOT_LOGGER_NAME), Level.DEBUG, "test message", t, null);
- }
-
- @Test
- public void integration() {
- PatternLayout pl = new PatternLayout();
- pl.setContext(lc);
- pl.setPattern("%m%n%xEx");
- pl.start();
- ILoggingEvent e = createLoggingEvent(new Exception("x"));
- String res = pl.doLayout(e);
-
- // make sure that at least some package data was output
- Pattern p = Pattern.compile("\\s*at .*?\\[.*?\\]");
- Matcher m = p.matcher(res);
- int i = 0;
- while (m.find()) {
- i++;
- }
- assertThat(i).isGreaterThan(5);
+ LoggerContext lc = new LoggerContext();
+ ExtendedThrowableProxyConverter etpc = new ExtendedThrowableProxyConverter();
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+
+ @Before
+ public void setUp() throws Exception {
+ etpc.setContext(lc);
+ etpc.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ private ILoggingEvent createLoggingEvent(Throwable t) {
+ return new LoggingEvent(this.getClass().getName(), lc
+ .getLogger(Logger.ROOT_LOGGER_NAME), Level.DEBUG, "test message", t,
+ null);
+ }
+
+ @Test
+ public void integration() {
+ PatternLayout pl = new PatternLayout();
+ pl.setContext(lc);
+ pl.setPattern("%m%n");
+ pl.start();
+ ILoggingEvent e = createLoggingEvent(new Exception("x"));
+ String res = pl.doLayout(e);
+
+ // make sure that at least some package data was output
+ Pattern p = Pattern.compile("\\s*at .*?\\[.*?\\]");
+ Matcher m = p.matcher(res);
+ int i = 0;
+ while(m.find()) {
+ i++;
}
-
- @Test
- public void smoke() {
- Exception t = new Exception("smoke");
- verify(t);
- }
-
- @Test
- public void nested() {
- Throwable t = makeNestedException(1);
- verify(t);
- }
-
- void verify(Throwable t) {
- t.printStackTrace(pw);
-
- ILoggingEvent le = createLoggingEvent(t);
- String result = etpc.convert(le);
- result = result.replace("common frames omitted", "more");
- result = result.replaceAll(" ~?\\[.*\\]", "");
- assertEquals(sw.toString(), result);
- }
-
- Throwable makeNestedException(int level) {
- if (level == 0) {
- return new Exception("nesting level=" + level);
- }
- Throwable cause = makeNestedException(level - 1);
- return new Exception("nesting level =" + level, cause);
+ assertTrue(i+ " should be larger than 5", i > 5);
+ }
+
+ @Test
+ public void smoke() {
+ Exception t = new Exception("smoke");
+ verify(t);
+ }
+
+ @Test
+ public void nested() {
+ Throwable t = makeNestedException(1);
+ verify(t);
+ }
+
+ void verify(Throwable t) {
+ t.printStackTrace(pw);
+
+ ILoggingEvent le = createLoggingEvent(t);
+ String result = etpc.convert(le);
+ result = result.replace("common frames omitted", "more");
+ result = result.replaceAll(" ~?\\[.*\\]", "");
+ assertEquals(sw.toString(), result);
+ }
+
+ Throwable makeNestedException(int level) {
+ if (level == 0) {
+ return new Exception("nesting level=" + level);
}
+ Throwable cause = makeNestedException(level - 1);
+ return new Exception("nesting level =" + level, cause);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/MDCConverterTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/MDCConverterTest.java
index 640f8ac..6326005 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/MDCConverterTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/MDCConverterTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,48 +31,50 @@ import ch.qos.logback.core.util.SystemInfo;
public class MDCConverterTest {
- LoggerContext lc;
- MDCConverter converter;
- int diff = RandomUtil.getPositiveInt();
+ LoggerContext lc;
+ MDCConverter converter;
+ int diff = RandomUtil.getPositiveInt();
- @Before
- public void setUp() throws Exception {
- lc = new LoggerContext();
- converter = new MDCConverter();
- converter.start();
- MDC.clear();
- }
+ @Before
+ public void setUp() throws Exception {
+ lc = new LoggerContext();
+ converter = new MDCConverter();
+ converter.start();
+ MDC.clear();
+ }
- @After
- public void tearDown() throws Exception {
- lc = null;
- converter.stop();
- converter = null;
- MDC.clear();
- }
+ @After
+ public void tearDown() throws Exception {
+ lc = null;
+ converter.stop();
+ converter = null;
+ MDC.clear();
+ }
- @Test
- public void testConvertWithOneEntry() {
- String k = "MDCConverterTest_k" + diff;
- String v = "MDCConverterTest_v" + diff;
+ @Test
+ public void testConvertWithOneEntry() {
+ String k = "MDCConverterTest_k"+diff;
+ String v = "MDCConverterTest_v"+diff;
- MDC.put(k, v);
- ILoggingEvent le = createLoggingEvent();
- String result = converter.convert(le);
- assertEquals(k + "=" + v, result);
- }
+ MDC.put(k, v);
+ ILoggingEvent le = createLoggingEvent();
+ String result = converter.convert(le);
+ assertEquals(k+"="+v, result);
+ }
- @Test
- public void testConvertWithMultipleEntries() {
- MDC.put("testKey", "testValue");
- MDC.put("testKey2", "testValue2");
- ILoggingEvent le = createLoggingEvent();
- String result = converter.convert(le);
- boolean isConform = result.matches("testKey2?=testValue2?, testKey2?=testValue2?");
- assertTrue(result + " is not conform", isConform);
- }
+ @Test
+ public void testConvertWithMultipleEntries() {
+ MDC.put("testKey", "testValue");
+ MDC.put("testKey2", "testValue2");
+ ILoggingEvent le = createLoggingEvent();
+ String result = converter.convert(le);
+ boolean isConform = result.matches("testKey2?=testValue2?, testKey2?=testValue2?");
+ assertTrue(result + " is not conform", isConform);
+ }
- private ILoggingEvent createLoggingEvent() {
- return new LoggingEvent(this.getClass().getName(), lc.getLogger(Logger.ROOT_LOGGER_NAME), Level.DEBUG, "test message", null, null);
- }
+ private ILoggingEvent createLoggingEvent() {
+ return new LoggingEvent(this.getClass().getName(), lc
+ .getLogger(Logger.ROOT_LOGGER_NAME), Level.DEBUG, "test message", null,
+ null);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/MarkerConverterTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/MarkerConverterTest.java
index ac6ae27..e4e9891 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/MarkerConverterTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/MarkerConverterTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,65 +29,66 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;
public class MarkerConverterTest {
-
- LoggerContext lc;
- MarkerConverter converter;
- // use a different facotry for each test so that they are independent
- IMarkerFactory markerFactory = new BasicMarkerFactory();
-
- @Before
- public void setUp() throws Exception {
- lc = new LoggerContext();
- converter = new MarkerConverter();
- converter.start();
- }
-
- @After
- public void tearDown() throws Exception {
- lc = null;
- converter.stop();
- converter = null;
- }
-
- @Test
- public void testWithNullMarker() {
- String result = converter.convert(createLoggingEvent(null));
- assertEquals("", result);
- }
-
- @Test
- public void testWithMarker() {
- String name = "test";
- Marker marker = markerFactory.getMarker(name);
- String result = converter.convert(createLoggingEvent(marker));
- assertEquals(name, result);
- }
-
- @Test
- public void testWithOneChildMarker() {
- Marker marker = markerFactory.getMarker("test");
- marker.add(markerFactory.getMarker("child"));
-
- String result = converter.convert(createLoggingEvent(marker));
-
- assertEquals("test [ child ]", result);
- }
-
- @Test
- public void testWithSeveralChildMarker() {
- Marker marker = markerFactory.getMarker("testParent");
- marker.add(markerFactory.getMarker("child1"));
- marker.add(markerFactory.getMarker("child2"));
- marker.add(markerFactory.getMarker("child3"));
-
- String result = converter.convert(createLoggingEvent(marker));
-
- assertEquals("testParent [ child1, child2, child3 ]", result);
- }
-
- private ILoggingEvent createLoggingEvent(Marker marker) {
- LoggingEvent le = new LoggingEvent(this.getClass().getName(), lc.getLogger(Logger.ROOT_LOGGER_NAME), Level.DEBUG, "test message", null, null);
- le.setMarker(marker);
- return le;
- }
+
+ LoggerContext lc;
+ MarkerConverter converter;
+ // use a different facotry for each test so that they are independent
+ IMarkerFactory markerFactory = new BasicMarkerFactory();
+
+ @Before
+ public void setUp() throws Exception {
+ lc = new LoggerContext();
+ converter = new MarkerConverter();
+ converter.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ lc = null;
+ converter.stop();
+ converter = null;
+ }
+
+ @Test
+ public void testWithNullMarker() {
+ String result = converter.convert(createLoggingEvent(null));
+ assertEquals("", result);
+ }
+
+ @Test
+ public void testWithMarker() {
+ String name = "test";
+ Marker marker = markerFactory.getMarker(name);
+ String result = converter.convert(createLoggingEvent(marker));
+ assertEquals(name, result);
+ }
+
+ @Test
+ public void testWithOneChildMarker() {
+ Marker marker = markerFactory.getMarker("test");
+ marker.add(markerFactory.getMarker("child"));
+
+ String result = converter.convert(createLoggingEvent(marker));
+
+ assertEquals("test [ child ]", result);
+ }
+
+ @Test
+ public void testWithSeveralChildMarker() {
+ Marker marker = markerFactory.getMarker("testParent");
+ marker.add(markerFactory.getMarker("child1"));
+ marker.add(markerFactory.getMarker("child2"));
+ marker.add(markerFactory.getMarker("child3"));
+
+ String result = converter.convert(createLoggingEvent(marker));
+
+ assertEquals("testParent [ child1, child2, child3 ]", result);
+ }
+
+ private ILoggingEvent createLoggingEvent(Marker marker) {
+ LoggingEvent le = new LoggingEvent(this.getClass().getName(), lc.getLogger(Logger.ROOT_LOGGER_NAME),
+ Level.DEBUG, "test message", null, null);
+ le.setMarker(marker);
+ return le;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/PackageTest.java
index be42ea6..55dd9af 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,8 +18,11 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ ConverterTest.class, TargetLengthBasedClassNameAbbreviatorTest.class, MDCConverterTest.class, MarkerConverterTest.class,
- ExtendedThrowableProxyConverterTest.class, ThrowableProxyConverterTest.class, RootCauseFirstThrowableProxyConverterTest.class })
+ at SuiteClasses({ConverterTest.class,
+ TargetLengthBasedClassNameAbbreviatorTest.class, MDCConverterTest.class,
+ MarkerConverterTest.class, ExtendedThrowableProxyConverterTest.class,
+ ThrowableProxyConverterTest.class,
+ RootCauseFirstThrowableProxyConverterTest.class})
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverterTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverterTest.java
index e43862f..e99cf13 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverterTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/RootCauseFirstThrowableProxyConverterTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,9 +28,9 @@ import java.io.StringWriter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import static ch.qos.logback.classic.util.TestHelper.makeNestedException;
-import static ch.qos.logback.classic.util.TestHelper.positionOf;
-import static org.assertj.core.api.Assertions.assertThat;
+import static ch.qos.logback.classic.util.TeztHelper.makeNestedException;
+import static ch.qos.logback.classic.util.TeztHelper.positionOf;
+import static org.fest.assertions.Assertions.assertThat;
/**
* @author Tomasz Nurkiewicz
@@ -38,75 +38,80 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
public class RootCauseFirstThrowableProxyConverterTest {
- private LoggerContext context = new LoggerContext();
- private ThrowableProxyConverter converter = new RootCauseFirstThrowableProxyConverter();
- private StringWriter stringWriter = new StringWriter();
- private PrintWriter printWriter = new PrintWriter(stringWriter);
-
- @Before
- public void setUp() throws Exception {
- converter.setContext(context);
- converter.start();
- }
-
- private ILoggingEvent createLoggingEvent(Throwable t) {
- return new LoggingEvent(this.getClass().getName(), context.getLogger(Logger.ROOT_LOGGER_NAME), Level.DEBUG, "test message", t, null);
- }
-
- @Test
- public void integration() {
- // given
- context.setPackagingDataEnabled(true);
- PatternLayout pl = new PatternLayout();
- pl.setContext(context);
- pl.setPattern("%m%rEx%n");
- pl.start();
-
- // when
- ILoggingEvent e = createLoggingEvent(new Exception("x"));
- String result = pl.doLayout(e);
-
- // then
- // make sure that at least some package data was output
- Pattern p = Pattern.compile("\\s*at .*?\\[.*?\\]");
- Matcher m = p.matcher(result);
- int i = 0;
- while (m.find()) {
- i++;
- }
- assertThat(i).isGreaterThan(5);
- }
-
- @Test
- public void smoke() {
- // given
- Exception exception = new Exception("smoke");
- exception.printStackTrace(printWriter);
-
- // when
- ILoggingEvent le = createLoggingEvent(exception);
- String result = converter.convert(le);
-
- // then
- result = result.replace("common frames omitted", "more");
- result = result.replaceAll(" ~?\\[.*\\]", "");
- assertThat(result).isEqualTo(stringWriter.toString());
- }
-
- @Test
- public void nested() {
- // given
- Throwable nestedException = makeNestedException(2);
- nestedException.printStackTrace(printWriter);
-
- // when
- ILoggingEvent le = createLoggingEvent(nestedException);
- String result = converter.convert(le);
-
- // then
- assertThat(result).startsWith("java.lang.Exception: nesting level=0");
- assertThat(positionOf("nesting level=0").in(result)).isLessThan(positionOf("nesting level =1").in(result));
- assertThat(positionOf("nesting level =1").in(result)).isLessThan(positionOf("nesting level =2").in(result));
+ private LoggerContext context = new LoggerContext();
+ private ThrowableProxyConverter converter = new RootCauseFirstThrowableProxyConverter();
+ private StringWriter stringWriter = new StringWriter();
+ private PrintWriter printWriter = new PrintWriter(stringWriter);
+
+ @Before
+ public void setUp() throws Exception {
+ converter.setContext(context);
+ converter.start();
+ }
+
+ private ILoggingEvent createLoggingEvent(Throwable t) {
+ return new LoggingEvent(this.getClass().getName(), context
+ .getLogger(Logger.ROOT_LOGGER_NAME), Level.DEBUG, "test message", t,
+ null);
+ }
+
+ @Test
+ public void integration() {
+ //given
+ PatternLayout pl = new PatternLayout();
+ pl.setContext(context);
+ pl.setPattern("%m%rEx%n");
+ pl.start();
+
+ //when
+ ILoggingEvent e = createLoggingEvent(new Exception("x"));
+ String result = pl.doLayout(e);
+
+ //then
+ // make sure that at least some package data was output
+ Pattern p = Pattern.compile("\\s*at .*?\\[.*?\\]");
+ Matcher m = p.matcher(result);
+ int i = 0;
+ while(m.find()) {
+ i++;
}
+ assertThat(i).isGreaterThan(5);
+ }
+
+ @Test
+ public void smoke() {
+ //given
+ Exception exception = new Exception("smoke");
+ exception.printStackTrace(printWriter);
+
+ //when
+ ILoggingEvent le = createLoggingEvent(exception);
+ String result = converter.convert(le);
+
+ //then
+ result = result.replace("common frames omitted", "more");
+ result = result.replaceAll(" ~?\\[.*\\]", "");
+ assertThat(result).isEqualTo(stringWriter.toString());
+ }
+
+ @Test
+ public void nested() {
+ //given
+ Throwable nestedException = makeNestedException(2);
+ nestedException.printStackTrace(printWriter);
+
+ //when
+ ILoggingEvent le = createLoggingEvent(nestedException);
+ String result = converter.convert(le);
+
+ //then
+ assertThat(result).startsWith("java.lang.Exception: nesting level=0");
+ assertThat(
+ positionOf("nesting level=0").in(result)).isLessThan(
+ positionOf("nesting level =1").in(result));
+ assertThat(
+ positionOf("nesting level =1").in(result)).isLessThan(
+ positionOf("nesting level =2").in(result));
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/SyslogStartConverterTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/SyslogStartConverterTest.java
index b21820e..64d749a 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/SyslogStartConverterTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/SyslogStartConverterTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2014, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -32,102 +32,104 @@ import static org.junit.Assert.assertEquals;
public class SyslogStartConverterTest {
- private LoggerContext lc;
- private SyslogStartConverter converter;
- private final String HOSTNAME = findHostname();
- private final Calendar calendar = Calendar.getInstance(Locale.US);
-
- @Before
- public void setUp() throws Exception {
- lc = new LoggerContext();
- converter = new SyslogStartConverter();
- converter.setOptionList(Arrays.asList("local7"));
- converter.start();
+ private LoggerContext lc;
+ private SyslogStartConverter converter;
+ private final String HOSTNAME = findHostname();
+ private final Calendar calendar = Calendar.getInstance(Locale.US);
+
+ @Before
+ public void setUp() throws Exception {
+ lc = new LoggerContext();
+ converter = new SyslogStartConverter();
+ converter.setOptionList(Arrays.asList("local7"));
+ converter.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ lc = null;
+ converter.stop();
+ converter = null;
+ }
+
+ @Test
+ public void datesLessThanTen() {
+ // RFC 3164, section 4.1.2:
+ // If the day of the month is less than 10, then it MUST be represented as
+ // a space and then the number. For example, the 7th day of August would be
+ // represented as "Aug 7", with two spaces between the "g" and the "7".
+ LoggingEvent le = createLoggingEvent();
+ calendar.set(2012, Calendar.AUGUST, 7, 13, 15, 0);
+ le.setTimeStamp(calendar.getTimeInMillis());
+ assertEquals("<191>Aug 7 13:15:00 " + HOSTNAME + " ", converter.convert(le));
+ }
+
+ @Test
+ public void datesGreaterThanTen() {
+ LoggingEvent le = createLoggingEvent();
+ calendar.set(2012, Calendar.OCTOBER, 11, 22, 14, 15);
+ le.setTimeStamp(calendar.getTimeInMillis());
+ assertEquals("<191>Oct 11 22:14:15 " + HOSTNAME + " ", converter.convert(le));
+ }
+
+ @Test
+ public void multipleConversions() {
+ LoggingEvent le = createLoggingEvent();
+ calendar.set(2012, Calendar.OCTOBER, 11, 22, 14, 15);
+ le.setTimeStamp(calendar.getTimeInMillis());
+ assertEquals("<191>Oct 11 22:14:15 " + HOSTNAME + " ", converter.convert(le));
+ assertEquals("<191>Oct 11 22:14:15 " + HOSTNAME + " ", converter.convert(le));
+
+ calendar.set(2012, Calendar.OCTOBER, 11, 22, 14, 16);
+ le.setTimeStamp(calendar.getTimeInMillis());
+ assertEquals("<191>Oct 11 22:14:16 " + HOSTNAME + " ", converter.convert(le));
+ }
+
+ @Test
+ public void ignoreDefaultLocale() {
+ Locale originalDefaultLocale = Locale.getDefault();
+ Locale.setDefault(Locale.TRADITIONAL_CHINESE);
+
+ try {
+ converter.start();
+
+ LoggingEvent le = createLoggingEvent();
+ calendar.set(2012, Calendar.OCTOBER, 11, 22, 14, 15);
+ le.setTimeStamp(calendar.getTimeInMillis());
+ String result = converter.convert(le);
+ assertEquals("<191>Oct 11 22:14:15 " + HOSTNAME + " ", result);
+ } finally {
+ Locale.setDefault(originalDefaultLocale);
}
-
- @After
- public void tearDown() throws Exception {
- lc = null;
- converter.stop();
- converter = null;
- }
-
- @Test
- public void datesLessThanTen() {
- // RFC 3164, section 4.1.2:
- // If the day of the month is less than 10, then it MUST be represented as
- // a space and then the number. For example, the 7th day of August would be
- // represented as "Aug 7", with two spaces between the "g" and the "7".
- LoggingEvent le = createLoggingEvent();
- calendar.set(2012, Calendar.AUGUST, 7, 13, 15, 0);
- le.setTimeStamp(calendar.getTimeInMillis());
- assertEquals("<191>Aug 7 13:15:00 " + HOSTNAME + " ", converter.convert(le));
- }
-
- @Test
- public void datesGreaterThanTen() {
- LoggingEvent le = createLoggingEvent();
- calendar.set(2012, Calendar.OCTOBER, 11, 22, 14, 15);
- le.setTimeStamp(calendar.getTimeInMillis());
- assertEquals("<191>Oct 11 22:14:15 " + HOSTNAME + " ", converter.convert(le));
- }
-
- @Test
- public void multipleConversions() {
- LoggingEvent le = createLoggingEvent();
- calendar.set(2012, Calendar.OCTOBER, 11, 22, 14, 15);
- le.setTimeStamp(calendar.getTimeInMillis());
- assertEquals("<191>Oct 11 22:14:15 " + HOSTNAME + " ", converter.convert(le));
- assertEquals("<191>Oct 11 22:14:15 " + HOSTNAME + " ", converter.convert(le));
-
- calendar.set(2012, Calendar.OCTOBER, 11, 22, 14, 16);
- le.setTimeStamp(calendar.getTimeInMillis());
- assertEquals("<191>Oct 11 22:14:16 " + HOSTNAME + " ", converter.convert(le));
+ }
+
+ @Test
+ @Ignore
+ public void hostnameShouldNotIncludeDomain() throws Exception {
+ // RFC 3164, section 4.1.2:
+ // The Domain Name MUST NOT be included in the HOSTNAME field.
+ String host = HOSTNAME;
+ final int firstPeriod = host.indexOf(".");
+ if (firstPeriod != -1) {
+ host = host.substring(0, firstPeriod);
}
-
- @Test
- public void ignoreDefaultLocale() {
- Locale originalDefaultLocale = Locale.getDefault();
- Locale.setDefault(Locale.TRADITIONAL_CHINESE);
-
- try {
- converter.start();
-
- LoggingEvent le = createLoggingEvent();
- calendar.set(2012, Calendar.OCTOBER, 11, 22, 14, 15);
- le.setTimeStamp(calendar.getTimeInMillis());
- String result = converter.convert(le);
- assertEquals("<191>Oct 11 22:14:15 " + HOSTNAME + " ", result);
- } finally {
- Locale.setDefault(originalDefaultLocale);
- }
- }
-
- @Test
- @Ignore
- public void hostnameShouldNotIncludeDomain() throws Exception {
- // RFC 3164, section 4.1.2:
- // The Domain Name MUST NOT be included in the HOSTNAME field.
- String host = HOSTNAME;
- final int firstPeriod = host.indexOf(".");
- if (firstPeriod != -1) {
- host = host.substring(0, firstPeriod);
- }
- LoggingEvent le = createLoggingEvent();
- calendar.set(2012, Calendar.OCTOBER, 11, 22, 14, 15);
- le.setTimeStamp(calendar.getTimeInMillis());
- assertEquals("<191>Oct 11 22:14:15 " + host + " ", converter.convert(le));
- }
-
- private LoggingEvent createLoggingEvent() {
- return new LoggingEvent(this.getClass().getName(), lc.getLogger(Logger.ROOT_LOGGER_NAME), Level.DEBUG, "test message", null, null);
- }
-
- private static String findHostname() {
- try {
- return InetAddress.getLocalHost().getHostName();
- } catch (UnknownHostException e) {
- return "UNKNOWN_LOCALHOST";
- }
+ LoggingEvent le = createLoggingEvent();
+ calendar.set(2012, Calendar.OCTOBER, 11, 22, 14, 15);
+ le.setTimeStamp(calendar.getTimeInMillis());
+ assertEquals("<191>Oct 11 22:14:15 " + host + " ", converter.convert(le));
+ }
+
+ private LoggingEvent createLoggingEvent() {
+ return new LoggingEvent(this.getClass().getName(), lc
+ .getLogger(Logger.ROOT_LOGGER_NAME), Level.DEBUG, "test message", null,
+ null);
+ }
+
+ private static String findHostname() {
+ try {
+ return InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException e) {
+ return "UNKNOWN_LOCALHOST";
}
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/TargetLengthBasedClassNameAbbreviatorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/TargetLengthBasedClassNameAbbreviatorTest.java
index bc2c813..841a305 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/TargetLengthBasedClassNameAbbreviatorTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/TargetLengthBasedClassNameAbbreviatorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,131 +19,131 @@ import org.junit.Test;
import ch.qos.logback.classic.pattern.TargetLengthBasedClassNameAbbreviator;
-public class TargetLengthBasedClassNameAbbreviatorTest {
+public class TargetLengthBasedClassNameAbbreviatorTest {
- @Test
- public void testShortName() {
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(100);
- String name = "hello";
- assertEquals(name, abbreviator.abbreviate(name));
- }
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(100);
- String name = "hello.world";
- assertEquals(name, abbreviator.abbreviate(name));
- }
- }
- @Test
- public void testNoDot() {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
- String name = "hello";
- assertEquals(name, abbreviator.abbreviate(name));
+ @Test
+ public void testShortName() {
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(100);
+ String name = "hello";
+ assertEquals(name, abbreviator.abbreviate(name));
}
-
- @Test
- public void testOneDot() {
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
- String name = "hello.world";
- assertEquals("h.world", abbreviator.abbreviate(name));
- }
-
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
- String name = "h.world";
- assertEquals("h.world", abbreviator.abbreviate(name));
- }
-
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
- String name = ".world";
- assertEquals(".world", abbreviator.abbreviate(name));
- }
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(100);
+ String name = "hello.world";
+ assertEquals(name, abbreviator.abbreviate(name));
}
-
- @Test
- public void testTwoDot() {
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
- String name = "com.logback.Foobar";
- assertEquals("c.l.Foobar", abbreviator.abbreviate(name));
- }
-
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
- String name = "c.logback.Foobar";
- assertEquals("c.l.Foobar", abbreviator.abbreviate(name));
- }
-
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
- String name = "c..Foobar";
- assertEquals("c..Foobar", abbreviator.abbreviate(name));
- }
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
- String name = "..Foobar";
- assertEquals("..Foobar", abbreviator.abbreviate(name));
- }
+ }
+
+ @Test
+ public void testNoDot() {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
+ String name = "hello";
+ assertEquals(name, abbreviator.abbreviate(name));
+ }
+
+ @Test
+ public void testOneDot() {
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
+ String name = "hello.world";
+ assertEquals("h.world", abbreviator.abbreviate(name));
}
- @Test
- public void test3Dot() {
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
- String name = "com.logback.xyz.Foobar";
- assertEquals("c.l.x.Foobar", abbreviator.abbreviate(name));
- }
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(13);
- String name = "com.logback.xyz.Foobar";
- assertEquals("c.l.x.Foobar", abbreviator.abbreviate(name));
- }
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(14);
- String name = "com.logback.xyz.Foobar";
- assertEquals("c.l.xyz.Foobar", abbreviator.abbreviate(name));
- }
-
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(15);
- String name = "com.logback.alligator.Foobar";
- assertEquals("c.l.a.Foobar", abbreviator.abbreviate(name));
- }
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
+ String name = "h.world";
+ assertEquals("h.world", abbreviator.abbreviate(name));
}
- @Test
- public void testXDot() {
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(21);
- String name = "com.logback.wombat.alligator.Foobar";
- assertEquals("c.l.w.a.Foobar", abbreviator.abbreviate(name));
- }
-
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(22);
- String name = "com.logback.wombat.alligator.Foobar";
- assertEquals("c.l.w.alligator.Foobar", abbreviator.abbreviate(name));
- }
-
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
- String name = "com.logback.wombat.alligator.tomato.Foobar";
- assertEquals("c.l.w.a.t.Foobar", abbreviator.abbreviate(name));
- }
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
+ String name = ".world";
+ assertEquals(".world", abbreviator.abbreviate(name));
+ }
+ }
+
+ @Test
+ public void testTwoDot() {
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
+ String name = "com.logback.Foobar";
+ assertEquals("c.l.Foobar", abbreviator.abbreviate(name));
+ }
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(21);
- String name = "com.logback.wombat.alligator.tomato.Foobar";
- assertEquals("c.l.w.a.tomato.Foobar", abbreviator.abbreviate(name));
- }
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
+ String name = "c.logback.Foobar";
+ assertEquals("c.l.Foobar", abbreviator.abbreviate(name));
+ }
- {
- TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(29);
- String name = "com.logback.wombat.alligator.tomato.Foobar";
- assertEquals("c.l.w.alligator.tomato.Foobar", abbreviator.abbreviate(name));
- }
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
+ String name = "c..Foobar";
+ assertEquals("c..Foobar", abbreviator.abbreviate(name));
+ }
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
+ String name = "..Foobar";
+ assertEquals("..Foobar", abbreviator.abbreviate(name));
+ }
+ }
+
+ @Test
+ public void test3Dot() {
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
+ String name = "com.logback.xyz.Foobar";
+ assertEquals("c.l.x.Foobar", abbreviator.abbreviate(name));
+ }
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(13);
+ String name = "com.logback.xyz.Foobar";
+ assertEquals("c.l.x.Foobar", abbreviator.abbreviate(name));
+ }
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(14);
+ String name = "com.logback.xyz.Foobar";
+ assertEquals("c.l.xyz.Foobar", abbreviator.abbreviate(name));
+ }
+
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(15);
+ String name = "com.logback.alligator.Foobar";
+ assertEquals("c.l.a.Foobar", abbreviator.abbreviate(name));
+ }
+ }
+ @Test
+ public void testXDot() {
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(21);
+ String name = "com.logback.wombat.alligator.Foobar";
+ assertEquals("c.l.w.a.Foobar", abbreviator.abbreviate(name));
+ }
+
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(22);
+ String name = "com.logback.wombat.alligator.Foobar";
+ assertEquals("c.l.w.alligator.Foobar", abbreviator.abbreviate(name));
+ }
+
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
+ String name = "com.logback.wombat.alligator.tomato.Foobar";
+ assertEquals("c.l.w.a.t.Foobar", abbreviator.abbreviate(name));
+ }
+
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(21);
+ String name = "com.logback.wombat.alligator.tomato.Foobar";
+ assertEquals("c.l.w.a.tomato.Foobar", abbreviator.abbreviate(name));
+ }
+
+ {
+ TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(29);
+ String name = "com.logback.wombat.alligator.tomato.Foobar";
+ assertEquals("c.l.w.alligator.tomato.Foobar", abbreviator.abbreviate(name));
}
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ThrowableProxyConverterTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ThrowableProxyConverterTest.java
index 80f1f50..10b1031 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ThrowableProxyConverterTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/pattern/ThrowableProxyConverterTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,7 +21,6 @@ import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
-import ch.qos.logback.core.CoreConstants;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -31,196 +30,145 @@ import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;
-import ch.qos.logback.classic.util.TestHelper;
+import ch.qos.logback.classic.util.TeztHelper;
-import static ch.qos.logback.classic.util.TestHelper.addSuppressed;
-import static org.assertj.core.api.Assertions.assertThat;
+import static ch.qos.logback.classic.util.TeztHelper.addSuppressed;
import static org.junit.Assert.*;
import static org.junit.Assume.assumeTrue;
public class ThrowableProxyConverterTest {
- LoggerContext lc = new LoggerContext();
- ThrowableProxyConverter tpc = new ThrowableProxyConverter();
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
-
- @Before
- public void setUp() throws Exception {
- tpc.setContext(lc);
- tpc.start();
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
- private ILoggingEvent createLoggingEvent(Throwable t) {
- return new LoggingEvent(this.getClass().getName(), lc.getLogger(Logger.ROOT_LOGGER_NAME), Level.DEBUG, "test message", t, null);
- }
-
- @Test
- public void suppressed() throws InvocationTargetException, IllegalAccessException {
- assumeTrue(TestHelper.suppressedSupported()); // only execute on Java 7, would work anyway but doesn't make
- // sense.
- Exception ex = null;
- try {
- someMethod();
- } catch (Exception e) {
- Exception fooException = new Exception("Foo");
- Exception barException = new Exception("Bar");
- addSuppressed(e, fooException);
- addSuppressed(e, barException);
- ex = e;
- }
- verify(ex);
- }
-
- @Test
- public void suppressedWithCause() throws InvocationTargetException, IllegalAccessException {
- assumeTrue(TestHelper.suppressedSupported()); // only execute on Java 7, would work anyway but doesn't make
- // sense.
- Exception ex = null;
- try {
- someMethod();
- } catch (Exception e) {
- ex = new Exception("Wrapper", e);
- Exception fooException = new Exception("Foo");
- Exception barException = new Exception("Bar");
- addSuppressed(ex, fooException);
- addSuppressed(e, barException);
- }
- verify(ex);
- }
-
- @Test
- public void suppressedWithSuppressed() throws Exception {
- assumeTrue(TestHelper.suppressedSupported()); // only execute on Java 7, would work anyway but doesn't make
- // sense.
- Exception ex = null;
- try {
- someMethod();
- } catch (Exception e) {
- ex = new Exception("Wrapper", e);
- Exception fooException = new Exception("Foo");
- Exception barException = new Exception("Bar");
- addSuppressed(barException, fooException);
- addSuppressed(e, barException);
- }
- verify(ex);
- }
-
- @Test
- public void smoke() {
- Exception t = new Exception("smoke");
- verify(t);
- }
-
- @Test
- public void nested() {
- Throwable t = TestHelper.makeNestedException(1);
- verify(t);
- }
-
- @Test
- public void withArgumentOfOne() throws Exception {
- final Throwable t = TestHelper.makeNestedException(0);
- t.printStackTrace(pw);
- final ILoggingEvent le = createLoggingEvent(t);
-
- final List<String> optionList = Arrays.asList("1");
- tpc.setOptionList(optionList);
- tpc.start();
-
- final String result = tpc.convert(le);
-
- final BufferedReader reader = new BufferedReader(new StringReader(result));
- assertTrue(reader.readLine().contains(t.getMessage()));
- assertNotNull(reader.readLine());
- assertNull("Unexpected line in stack trace", reader.readLine());
+ LoggerContext lc = new LoggerContext();
+ ThrowableProxyConverter tpc = new ThrowableProxyConverter();
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+
+ @Before
+ public void setUp() throws Exception {
+ tpc.setContext(lc);
+ tpc.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ private ILoggingEvent createLoggingEvent(Throwable t) {
+ return new LoggingEvent(this.getClass().getName(), lc
+ .getLogger(Logger.ROOT_LOGGER_NAME), Level.DEBUG, "test message", t,
+ null);
+ }
+
+ @Test
+ public void suppressed() throws InvocationTargetException, IllegalAccessException
+ {
+ assumeTrue(TeztHelper.suppressedSupported()); // only execute on Java 7, would work anyway but doesn't make sense.
+ Exception ex = null;
+ try {
+ someMethod();
+ } catch (Exception e) {
+ Exception fooException = new Exception("Foo");
+ Exception barException = new Exception("Bar");
+ addSuppressed(e, fooException);
+ addSuppressed(e, barException);
+ ex = e;
}
-
- @Test
- public void withShortArgument() throws Exception {
- final Throwable t = TestHelper.makeNestedException(0);
- t.printStackTrace(pw);
- final ILoggingEvent le = createLoggingEvent(t);
-
- final List<String> options = Arrays.asList("short");
- tpc.setOptionList(options);
- tpc.start();
-
- final String result = tpc.convert(le);
-
- final BufferedReader reader = new BufferedReader(new StringReader(result));
- assertTrue(reader.readLine().contains(t.getMessage()));
- assertNotNull(reader.readLine());
- assertNull("Unexpected line in stack trace", reader.readLine());
- }
-
- @Test
- public void skipSelectedLine() throws Exception {
- String nameOfContainingMethod = "skipSelectedLine";
- // given
- final Throwable t = TestHelper.makeNestedException(0);
- t.printStackTrace(pw);
- final ILoggingEvent le = createLoggingEvent(t);
- tpc.setOptionList(Arrays.asList("full", nameOfContainingMethod));
- tpc.start();
-
- // when
- final String result = tpc.convert(le);
-
- // then
- assertThat(result).doesNotContain(nameOfContainingMethod);
-
+ verify(ex);
+ }
+
+ @Test
+ public void suppressedWithCause() throws InvocationTargetException, IllegalAccessException
+ {
+ assumeTrue(TeztHelper.suppressedSupported()); // only execute on Java 7, would work anyway but doesn't make sense.
+ Exception ex = null;
+ try {
+ someMethod();
+ } catch (Exception e) {
+ ex=new Exception("Wrapper", e);
+ Exception fooException = new Exception("Foo");
+ Exception barException = new Exception("Bar");
+ addSuppressed(ex, fooException);
+ addSuppressed(e, barException);
}
-
- @Test
- public void skipMultipleLines() throws Exception {
- String nameOfContainingMethod = "skipMultipleLines";
- // given
- final Throwable t = TestHelper.makeNestedException(0);
- t.printStackTrace(pw);
- final ILoggingEvent le = createLoggingEvent(t);
- tpc.setOptionList(Arrays.asList("full", nameOfContainingMethod, "junit"));
- tpc.start();
-
- // when
- final String result = tpc.convert(le);
-
- // then
- assertThat(result).doesNotContain(nameOfContainingMethod).doesNotContain("junit");
- }
-
- @Test
- public void shouldLimitTotalLinesExcludingSkipped() throws Exception {
- // given
- final Throwable t = TestHelper.makeNestedException(0);
- t.printStackTrace(pw);
- final ILoggingEvent le = createLoggingEvent(t);
- tpc.setOptionList(Arrays.asList("3", "shouldLimitTotalLinesExcludingSkipped"));
- tpc.start();
-
- // when
- final String result = tpc.convert(le);
-
- // then
- String[] lines = result.split(CoreConstants.LINE_SEPARATOR);
- assertThat(lines).hasSize(3 + 1);
- }
-
- void someMethod() throws Exception {
- throw new Exception("someMethod");
- }
-
- void verify(Throwable t) {
- t.printStackTrace(pw);
-
- ILoggingEvent le = createLoggingEvent(t);
- String result = tpc.convert(le);
- System.out.println(result);
- result = result.replace("common frames omitted", "more");
- assertEquals(sw.toString(), result);
+ verify(ex);
+ }
+
+ @Test
+ public void suppressedWithSuppressed() throws Exception
+ {
+ assumeTrue(TeztHelper.suppressedSupported()); // only execute on Java 7, would work anyway but doesn't make sense.
+ Exception ex = null;
+ try {
+ someMethod();
+ } catch (Exception e) {
+ ex=new Exception("Wrapper", e);
+ Exception fooException = new Exception("Foo");
+ Exception barException = new Exception("Bar");
+ addSuppressed(barException, fooException);
+ addSuppressed(e, barException);
}
+ verify(ex);
+ }
+
+ @Test
+ public void smoke() {
+ Exception t = new Exception("smoke");
+ verify(t);
+ }
+
+ @Test
+ public void nested() {
+ Throwable t = TeztHelper.makeNestedException(1);
+ verify(t);
+ }
+
+ @Test
+ public void withArgumentOfOne() throws Exception {
+ final Throwable t = TeztHelper.makeNestedException(0);
+ t.printStackTrace(pw);
+ final ILoggingEvent le = createLoggingEvent(t);
+
+ final List<String> optionList = Arrays.asList("1");
+ tpc.setOptionList(optionList);
+ tpc.start();
+
+ final String result = tpc.convert(le);
+
+ final BufferedReader reader = new BufferedReader(new StringReader(result));
+ assertTrue(reader.readLine().contains(t.getMessage()));
+ assertNotNull(reader.readLine());
+ assertNull("Unexpected line in stack trace", reader.readLine());
+ }
+
+ @Test
+ public void withShortArgument() throws Exception {
+ final Throwable t = TeztHelper.makeNestedException(0);
+ t.printStackTrace(pw);
+ final ILoggingEvent le = createLoggingEvent(t);
+
+ final List<String> options = Arrays.asList("short");
+ tpc.setOptionList(options);
+ tpc.start();
+
+ final String result = tpc.convert(le);
+
+ final BufferedReader reader = new BufferedReader(new StringReader(result));
+ assertTrue(reader.readLine().contains(t.getMessage()));
+ assertNotNull(reader.readLine());
+ assertNull("Unexpected line in stack trace", reader.readLine());
+ }
+
+ void someMethod() throws Exception {
+ throw new Exception("someMethod");
+ }
+
+ void verify(Throwable t) {
+ t.printStackTrace(pw);
+
+ ILoggingEvent le = createLoggingEvent(t);
+ String result = tpc.convert(le);
+ System.out.println(result);
+ result = result.replace("common frames omitted", "more");
+ assertEquals(sw.toString(), result);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/rolling/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/rolling/PackageTest.java
index c6c4053..85adfab 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/rolling/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/rolling/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ UniqueFileTest.class, TimeBasedRollingWithConfigFileTest.class })
+ at SuiteClasses( { UniqueFileTest.class, TimeBasedRollingWithConfigFileTest.class })
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/rolling/TimeBasedRollingWithConfigFileTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/rolling/TimeBasedRollingWithConfigFileTest.java
index a85ab98..79a2882 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/rolling/TimeBasedRollingWithConfigFileTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/rolling/TimeBasedRollingWithConfigFileTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,11 +13,11 @@
*/
package ch.qos.logback.classic.rolling;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.Date;
+import ch.qos.logback.core.util.StatusPrinter;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -27,208 +27,165 @@ import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.ScaffoldingForRollingTests;
import ch.qos.logback.core.rolling.TimeBasedFileNamingAndTriggeringPolicy;
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
-import ch.qos.logback.core.status.Status;
import ch.qos.logback.core.status.StatusChecker;
-import ch.qos.logback.core.util.StatusPrinter;
-
-public class TimeBasedRollingWithConfigFileTest extends ScaffoldingForRollingTests {
-
- LoggerContext lc = new LoggerContext();
- StatusChecker statusChecker = new StatusChecker(lc);
- Logger logger = lc.getLogger(this.getClass());
- int fileSize = 0;
- int fileIndexCounter = -1;
- int sizeThreshold;
-
- @Before
- @Override
- public void setUp() {
- lc.setName("test");
- super.setUp();
- lc.putProperty("randomOutputDir", randomOutputDir);
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
- void loadConfig(String confifFile) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(lc);
- jc.doConfigure(confifFile);
- currentTime = System.currentTimeMillis();
- recomputeRolloverThreshold(currentTime);
- }
-
- @Test
- public void basic() throws Exception {
- String testId = "basic";
- lc.putProperty("testId", testId);
- loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml");
- statusChecker.assertIsErrorFree();
-
- Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
-
- expectedFilenameList.add(randomOutputDir + "z" + testId);
- RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING");
-
- TimeBasedRollingPolicy<ILoggingEvent> tprp = (TimeBasedRollingPolicy<ILoggingEvent>) rfa.getTriggeringPolicy();
- TimeBasedFileNamingAndTriggeringPolicy<ILoggingEvent> tbnatp = tprp.getTimeBasedFileNamingAndTriggeringPolicy();
-
- String prefix = "Hello---";
- int runLength = 4;
- for (int i = 0; i < runLength; i++) {
- logger.debug(prefix + i);
- addExpectedFileNamedIfItsTime_ByDate(randomOutputDir, testId, false);
- incCurrentTime(500);
- tbnatp.setCurrentTime(currentTime);
- }
-
- existenceCheck(expectedFilenameList);
- sortedContentCheck(randomOutputDir, runLength, prefix);
+public class TimeBasedRollingWithConfigFileTest extends
+ ScaffoldingForRollingTests {
+
+ LoggerContext lc = new LoggerContext();
+ StatusChecker statusChecker = new StatusChecker(lc);
+ Logger logger = lc.getLogger(this.getClass());
+ int fileSize = 0;
+ int fileIndexCounter = -1;
+ int sizeThreshold;
+
+ @Before
+ @Override
+ public void setUp() {
+ lc.setName("test");
+ super.setUp();
+ lc.putProperty("randomOutputDir", randomOutputDir);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ void loadConfig(String confifFile) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(lc);
+ jc.doConfigure(confifFile);
+ currentTime = System.currentTimeMillis();
+ recomputeRolloverThreshold(currentTime);
+ }
+
+ @Test
+ public void basic() throws Exception {
+ String testId = "basic";
+ lc.putProperty("testId", testId);
+ loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId
+ + ".xml");
+ statusChecker.assertIsErrorFree();
+
+ Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+
+ expectedFilenameList.add(randomOutputDir + "z" + testId);
+
+ RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root
+ .getAppender("ROLLING");
+
+ TimeBasedRollingPolicy tprp = (TimeBasedRollingPolicy<ILoggingEvent>) rfa
+ .getTriggeringPolicy();
+ TimeBasedFileNamingAndTriggeringPolicy tbnatp = tprp
+ .getTimeBasedFileNamingAndTriggeringPolicy();
+
+ String prefix = "Hello---";
+ int runLength = 4;
+ for (int i = 0; i < runLength; i++) {
+ logger.debug(prefix + i);
+ addExpectedFileNamedIfItsTime_ByDate(randomOutputDir, testId, false);
+ incCurrentTime(500);
+ tbnatp.setCurrentTime(currentTime);
}
- @Test
- public void depratedSizeAndTimeBasedFNATPWarning() throws Exception {
- String testId = "depratedSizeAndTimeBasedFNATPWarning";
- lc.putProperty("testId", testId);
- loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml");
- StatusPrinter.print(lc);
- statusChecker.assertContainsMatch(Status.WARN, CoreConstants.SIZE_AND_TIME_BASED_FNATP_IS_DEPRECATED);
- }
-
- @Test
- public void timeAndSize() throws Exception {
- String testId = "timeAndSize";
- lc.putProperty("testId", testId);
- String prefix = "Hello-----";
-
- // the number of times the log file will be written to before time based
- // roll-over occurs
- int approxWritesPerPeriod = 64;
- sizeThreshold = prefix.length() * approxWritesPerPeriod;
- lc.putProperty("sizeThreshold", "" + sizeThreshold);
- loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml");
-
- StatusPrinter.print(lc);
- // Test http://jira.qos.ch/browse/LOGBACK-1236
- statusChecker.assertNoMatch(CoreConstants.SIZE_AND_TIME_BASED_FNATP_IS_DEPRECATED);
-
- Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
-
- expectedFilenameList.add(randomOutputDir + "z" + testId);
-
- RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING");
-
- statusChecker.assertIsErrorFree();
-
- TimeBasedRollingPolicy<ILoggingEvent> tprp = (TimeBasedRollingPolicy<ILoggingEvent>) rfa.getTriggeringPolicy();
- TimeBasedFileNamingAndTriggeringPolicy<ILoggingEvent> tbnatp = tprp.getTimeBasedFileNamingAndTriggeringPolicy();
-
- int timeIncrement = 1000 / approxWritesPerPeriod;
- int runLength = approxWritesPerPeriod * 3;
- for (int i = 0; i < runLength; i++) {
- String msg = prefix + i;
- logger.debug(msg);
- addExpectedFileNamedIfItsTime(testId, msg, false);
- incCurrentTime(timeIncrement);
- tbnatp.setCurrentTime(currentTime);
- }
-
- sortedContentCheck(randomOutputDir, runLength, prefix);
- int eCount = existenceCount(expectedFilenameList);
- // for various reasons, it is extremely difficult to have the files
- // match exactly the expected archive files. Thus, we aim for
- // an approximate match
- assertTrue("exitenceCount=" + eCount + ", expectedFilenameList.size=" + expectedFilenameList.size(),
- eCount >= 4 && eCount > expectedFilenameList.size() / 2);
+ existenceCheck(expectedFilenameList);
+ sortedContentCheck(randomOutputDir, runLength, prefix);
+ }
+
+ @Test
+ public void timeAndSize() throws Exception {
+ String testId = "timeAndSize";
+ lc.putProperty("testId", testId);
+ String prefix = "Hello-----";
+
+ // the number of times the log file will be written to before time based
+ // roll-over occurs
+ int approxWritesPerPeriod = 64;
+ sizeThreshold = prefix.length() * approxWritesPerPeriod;
+ lc.putProperty("sizeThreshold", "" + sizeThreshold);
+ loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId
+ + ".xml");
+ Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+
+ expectedFilenameList.add(randomOutputDir + "z" + testId);
+
+ RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root
+ .getAppender("ROLLING");
+
+ statusChecker.assertIsErrorFree();
+
+ TimeBasedRollingPolicy tprp = (TimeBasedRollingPolicy<ILoggingEvent>) rfa
+ .getTriggeringPolicy();
+ TimeBasedFileNamingAndTriggeringPolicy tbnatp = tprp
+ .getTimeBasedFileNamingAndTriggeringPolicy();
+
+ int timeIncrement = 1000 / approxWritesPerPeriod;
+ int runLength = approxWritesPerPeriod * 3;
+ for (int i = 0; i < runLength; i++) {
+ String msg = prefix + i;
+ logger.debug(msg);
+ addExpectedFileNamedIfItsTime(testId, msg, false);
+ incCurrentTime(timeIncrement);
+ tbnatp.setCurrentTime(currentTime);
}
- @Test
- public void timeAndSizeWithoutIntegerToken() throws Exception {
- String testId = "timeAndSizeWithoutIntegerToken";
- loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml");
- Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- expectedFilenameList.add(randomOutputDir + "z" + testId);
- RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING");
- StatusPrinter.print(lc);
-
- statusChecker.assertContainsMatch("Missing integer token");
- assertFalse(rfa.isStarted());
+ sortedContentCheck(randomOutputDir, runLength, prefix);
+ int eCount = existenceCount(expectedFilenameList);
+ // for various reasons, it is extremely difficult to have the files
+ // match exactly the expected archive files. Thus, we aim for
+ // an approximate match
+ assertTrue("exitenceCount=" + eCount + ", expectedFilenameList.size="
+ + expectedFilenameList.size(), eCount >= 4
+ && eCount > expectedFilenameList.size() / 2);
+ }
+
+ void addExpectedFileNamedIfItsTime(String testId, String msg,
+ boolean gzExtension) {
+ fileSize += msg.getBytes().length;
+
+ if (passThresholdTime(nextRolloverThreshold)) {
+ fileIndexCounter = 0;
+ fileSize = 0;
+ addExpectedFileName(testId, getDateOfPreviousPeriodsStart(),
+ fileIndexCounter, gzExtension);
+ recomputeRolloverThreshold(currentTime);
+ return;
}
-
- // see also LOGBACK-1176
- @Test
- public void timeAndSizeWithoutMaxFileSize() throws Exception {
- String testId = "timeAndSizeWithoutMaxFileSize";
- loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml");
- Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- //expectedFilenameList.add(randomOutputDir + "z" + testId);
- RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING");
-
-
- //statusChecker.assertContainsMatch("Missing integer token");
- assertFalse(rfa.isStarted());
- StatusPrinter.print(lc);
+ // windows can delay file size changes, so we only allow for
+ // fileIndexCounter 0 and 1
+ if ((fileIndexCounter < 1) && fileSize > sizeThreshold) {
+ addExpectedFileName(testId, getDateOfPreviousPeriodsStart(),
+ ++fileIndexCounter, gzExtension);
+ fileSize = -1;
+ return;
}
+ }
- @Test
- public void totalSizeCapSmallerThanMaxFileSize() throws Exception {
- String testId = "totalSizeCapSmallerThanMaxFileSize";
- lc.putProperty("testId", testId);
- loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml");
- Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- //expectedFilenameList.add(randomOutputDir + "z" + testId);
- RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING");
-
- statusChecker.assertContainsMatch("totalSizeCap of \\[\\d* \\w*\\] is smaller than maxFileSize \\[\\d* \\w*\\] which is non-sensical");
- assertFalse(rfa.isStarted());
-
- }
+ void addExpectedFileName(String testId, Date date, int fileIndexCounter,
+ boolean gzExtension) {
- void addExpectedFileNamedIfItsTime(String testId, String msg, boolean gzExtension) {
- fileSize += msg.getBytes().length;
-
- if (passThresholdTime(nextRolloverThreshold)) {
- fileIndexCounter = 0;
- fileSize = 0;
- addExpectedFileName(testId, getDateOfPreviousPeriodsStart(), fileIndexCounter, gzExtension);
- recomputeRolloverThreshold(currentTime);
- return;
- }
-
- // windows can delay file size changes, so we only allow for
- // fileIndexCounter 0 and 1
- if ((fileIndexCounter < 1) && fileSize > sizeThreshold) {
- addExpectedFileName(testId, getDateOfPreviousPeriodsStart(), ++fileIndexCounter, gzExtension);
- fileSize = -1;
- return;
- }
+ String fn = randomOutputDir + testId + "-" + SDF.format(date) + "."
+ + fileIndexCounter;
+ System.out.println("Adding " + fn);
+ if (gzExtension) {
+ fn += ".gz";
}
-
- void addExpectedFileName(String testId, Date date, int fileIndexCounter, boolean gzExtension) {
-
- String fn = randomOutputDir + testId + "-" + SDF.format(date) + "." + fileIndexCounter;
- System.out.println("Adding " + fn);
- if (gzExtension) {
- fn += ".gz";
- }
- expectedFilenameList.add(fn);
- }
-
- @Override
- protected void addExpectedFileNamedIfItsTime_ByDate(String outputDir, String testId, boolean gzExtension) {
- if (passThresholdTime(nextRolloverThreshold)) {
- addExpectedFileName_ByDate(outputDir, testId, getDateOfPreviousPeriodsStart(), gzExtension);
- recomputeRolloverThreshold(currentTime);
- }
+ expectedFilenameList.add(fn);
+ }
+
+ @Override
+ protected void addExpectedFileNamedIfItsTime_ByDate(String outputDir, String testId,
+ boolean gzExtension) {
+ if (passThresholdTime(nextRolloverThreshold)) {
+ addExpectedFileName_ByDate(outputDir, testId, getDateOfPreviousPeriodsStart(),
+ gzExtension);
+ recomputeRolloverThreshold(currentTime);
}
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/rolling/UniqueFileTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/rolling/UniqueFileTest.java
index b2efc83..e2a1d42 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/rolling/UniqueFileTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/rolling/UniqueFileTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,8 +13,10 @@
*/
package ch.qos.logback.classic.rolling;
-import org.junit.After;
-import org.junit.Before;
+import static org.junit.Assert.assertTrue;
+
+import ch.qos.logback.core.util.CachingDateFormatter;
+import ch.qos.logback.core.util.StatusPrinter;
import org.junit.Test;
import ch.qos.logback.classic.ClassicTestConstants;
@@ -24,8 +26,6 @@ import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.rolling.ScaffoldingForRollingTests;
import ch.qos.logback.core.status.StatusChecker;
-import ch.qos.logback.core.testUtil.RandomUtil;
-import ch.qos.logback.core.util.CachingDateFormatter;
import ch.qos.logback.core.util.CoreTestConstants;
/**
@@ -36,41 +36,29 @@ import ch.qos.logback.core.util.CoreTestConstants;
*
*/
public class UniqueFileTest {
- static String UNIK_DIFF = "UNIK_DIFF";
-
- LoggerContext lc = new LoggerContext();
- StatusChecker sc = new StatusChecker(lc);
- Logger logger = lc.getLogger(this.getClass());
- int diff = RandomUtil.getPositiveInt() % 1000;
- String diffAsStr = Integer.toString(diff);
-
- @Before
- public void setUp() {
- System.setProperty(UNIK_DIFF, diffAsStr);
- }
- @After
- public void tearDown() {
- System.clearProperty(UNIK_DIFF);
- }
+ LoggerContext lc = new LoggerContext();
+ StatusChecker sc = new StatusChecker(lc);
+ Logger logger = lc.getLogger(this.getClass());
- void loadConfig(String confifFile) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(lc);
- jc.doConfigure(confifFile);
- }
- @Test
- public void basic() throws Exception {
- loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "unique.xml");
- CachingDateFormatter sdf = new CachingDateFormatter("yyyyMMdd'T'HHmm");
- String timestamp = sdf.format(System.currentTimeMillis());
+ void loadConfig(String confifFile) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(lc);
+ jc.doConfigure(confifFile);
+ }
- sc.assertIsErrorFree();
+ @Test
+ public void basic() throws Exception {
+ loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "unique.xml");
+ CachingDateFormatter sdf = new CachingDateFormatter("yyyyMMdd'T'HHmmss");
+ String timestamp = sdf.format(System.currentTimeMillis());
- Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- root.info("hello");
+ sc.assertIsErrorFree();
- ScaffoldingForRollingTests.existenceCheck(CoreTestConstants.OUTPUT_DIR_PREFIX + "UNIK_" + timestamp + diffAsStr + "log.txt");
- }
+ Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+ root.info("hello");
+
+ ScaffoldingForRollingTests.existenceCheck(CoreTestConstants.OUTPUT_DIR_PREFIX+"TS_"+timestamp+"log.txt");
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/selector/ContextDetachingSCLTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/selector/ContextDetachingSCLTest.java
index 0280ed8..8c6c0f1 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/selector/ContextDetachingSCLTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/selector/ContextDetachingSCLTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,61 +28,62 @@ import ch.qos.logback.classic.util.MockInitialContextFactory;
import org.slf4j.LoggerFactoryFriend;
import org.slf4j.impl.StaticLoggerBinderFriend;
-public class ContextDetachingSCLTest {
-
- static String INITIAL_CONTEXT_KEY = "java.naming.factory.initial";
-
- ContextDetachingSCL contextDetachingSCL;
-
- @Before
- public void setUp() throws Exception {
-
- System.setProperty(ClassicConstants.LOGBACK_CONTEXT_SELECTOR, "JNDI");
-
- contextDetachingSCL = new ContextDetachingSCL();
-
- MockInitialContextFactory.initialize();
- MockInitialContext mic = MockInitialContextFactory.getContext();
- mic.map.put(ClassicConstants.JNDI_CONTEXT_NAME, "toto");
-
- // The property must be set after we setup the Mock
- System.setProperty(INITIAL_CONTEXT_KEY, MockInitialContextFactory.class.getName());
-
- // reinitialize the LoggerFactory, These reset methods are reserved for internal use
- StaticLoggerBinderFriend.reset();
- LoggerFactoryFriend.reset();
-
- // this call will create the context "toto"
- LoggerFactory.getLogger(ContextDetachingSCLTest.class);
- }
-
- @After
- public void tearDown() throws Exception {
- System.clearProperty(INITIAL_CONTEXT_KEY);
- // reinitialize the LoggerFactory, These resets method are reserved for internal use
- StaticLoggerBinderFriend.reset();
- LoggerFactoryFriend.reset();
- }
-
- @Test
- public void testDetach() {
- ContextJNDISelector selector = (ContextJNDISelector) ContextSelectorStaticBinder.getSingleton().getContextSelector();
- contextDetachingSCL.contextDestroyed(null);
- assertEquals(0, selector.getCount());
- }
-
- @Test
- public void testDetachWithMissingContext() {
- MockInitialContext mic = MockInitialContextFactory.getContext();
- mic.map.put(ClassicConstants.JNDI_CONTEXT_NAME, "tata");
- ContextJNDISelector selector = (ContextJNDISelector) ContextSelectorStaticBinder.getSingleton().getContextSelector();
- assertEquals("tata", selector.getLoggerContext().getName());
-
- mic.map.put(ClassicConstants.JNDI_CONTEXT_NAME, "titi");
- assertEquals("titi", selector.getLoggerContext().getName());
- contextDetachingSCL.contextDestroyed(null);
-
- assertEquals(2, selector.getCount());
- }
-
+public class ContextDetachingSCLTest {
+
+ static String INITIAL_CONTEXT_KEY = "java.naming.factory.initial";
+
+ ContextDetachingSCL contextDetachingSCL;
+
+ @Before
+ public void setUp() throws Exception {
+
+ System.setProperty(ClassicConstants.LOGBACK_CONTEXT_SELECTOR, "JNDI");
+
+ contextDetachingSCL = new ContextDetachingSCL();
+
+ MockInitialContextFactory.initialize();
+ MockInitialContext mic = MockInitialContextFactory.getContext();
+ mic.map.put(ClassicConstants.JNDI_CONTEXT_NAME, "toto");
+
+ //The property must be set after we setup the Mock
+ System.setProperty(INITIAL_CONTEXT_KEY, MockInitialContextFactory.class.getName());
+
+ // reinitialize the LoggerFactory, These reset methods are reserved for internal use
+ StaticLoggerBinderFriend.reset();
+ LoggerFactoryFriend.reset();
+
+ //this call will create the context "toto"
+ LoggerFactory.getLogger(ContextDetachingSCLTest.class);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ System.clearProperty(INITIAL_CONTEXT_KEY);
+ // reinitialize the LoggerFactory, These resets method are reserved for internal use
+ StaticLoggerBinderFriend.reset();
+ LoggerFactoryFriend.reset();
+ }
+
+ @Test
+ public void testDetach() {
+ ContextJNDISelector selector = (ContextJNDISelector) ContextSelectorStaticBinder.getSingleton().getContextSelector();
+ contextDetachingSCL.contextDestroyed(null);
+ assertEquals(0, selector.getCount());
+ }
+
+
+ @Test
+ public void testDetachWithMissingContext() {
+ MockInitialContext mic = MockInitialContextFactory.getContext();
+ mic.map.put(ClassicConstants.JNDI_CONTEXT_NAME, "tata");
+ ContextJNDISelector selector = (ContextJNDISelector) ContextSelectorStaticBinder.getSingleton().getContextSelector();
+ assertEquals("tata", selector.getLoggerContext().getName());
+
+ mic.map.put(ClassicConstants.JNDI_CONTEXT_NAME, "titi");
+ assertEquals("titi", selector.getLoggerContext().getName());
+ contextDetachingSCL.contextDestroyed(null);
+
+ assertEquals(2, selector.getCount());
+ }
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/selector/ContextJNDISelectorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/selector/ContextJNDISelectorTest.java
index 16fdbc0..4f4f7fd 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/selector/ContextJNDISelectorTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/selector/ContextJNDISelectorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,62 +27,62 @@ import ch.qos.logback.classic.util.MockInitialContext;
import ch.qos.logback.classic.util.MockInitialContextFactory;
import ch.qos.logback.core.Context;
-public class ContextJNDISelectorTest {
-
- static String INITIAL_CONTEXT_KEY = "java.naming.factory.initial";
-
- @Before
- public void setUp() throws Exception {
-
- System.setProperty(ClassicConstants.LOGBACK_CONTEXT_SELECTOR, "JNDI");
- StaticLoggerBinderFriend.reset();
-
- MockInitialContextFactory.initialize();
- MockInitialContext mic = MockInitialContextFactory.getContext();
- mic.map.put(ClassicConstants.JNDI_CONTEXT_NAME, "toto");
-
- // The property must be set after we setup the Mock
- System.setProperty(INITIAL_CONTEXT_KEY, MockInitialContextFactory.class.getName());
-
- // this call will create the context "toto"
- LoggerFactory.getLogger(ContextDetachingSCLTest.class);
- }
-
- @After
- public void tearDown() throws Exception {
- System.clearProperty(INITIAL_CONTEXT_KEY);
- }
-
- @Test
- public void testGetExistingContext() {
- ContextSelector selector = ContextSelectorStaticBinder.getSingleton().getContextSelector();
- Context context = selector.getLoggerContext();
- assertEquals("toto", context.getName());
- }
-
- @Test
- public void testCreateContext() {
- MockInitialContext mic = MockInitialContextFactory.getContext();
- mic.map.put(ClassicConstants.JNDI_CONTEXT_NAME, "tata");
-
- LoggerFactory.getLogger(ContextDetachingSCLTest.class);
-
- ContextJNDISelector selector = (ContextJNDISelector) ContextSelectorStaticBinder.getSingleton().getContextSelector();
- Context context = selector.getLoggerContext();
- assertEquals("tata", context.getName());
- System.out.println(selector.getContextNames());
- assertEquals(2, selector.getCount());
- }
-
- @Test
- public void defaultContext() {
- MockInitialContext mic = MockInitialContextFactory.getContext();
- mic.map.put(ClassicConstants.JNDI_CONTEXT_NAME, null);
-
- ContextJNDISelector selector = (ContextJNDISelector) ContextSelectorStaticBinder.getSingleton().getContextSelector();
- Context context = selector.getLoggerContext();
-
- assertEquals("default", context.getName());
- }
-
+public class ContextJNDISelectorTest {
+
+ static String INITIAL_CONTEXT_KEY = "java.naming.factory.initial";
+
+ @Before
+ public void setUp() throws Exception {
+
+ System.setProperty(ClassicConstants.LOGBACK_CONTEXT_SELECTOR, "JNDI");
+ StaticLoggerBinderFriend.reset();
+
+ MockInitialContextFactory.initialize();
+ MockInitialContext mic = MockInitialContextFactory.getContext();
+ mic.map.put(ClassicConstants.JNDI_CONTEXT_NAME, "toto");
+
+ //The property must be set after we setup the Mock
+ System.setProperty(INITIAL_CONTEXT_KEY, MockInitialContextFactory.class.getName());
+
+ //this call will create the context "toto"
+ LoggerFactory.getLogger(ContextDetachingSCLTest.class);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ System.clearProperty(INITIAL_CONTEXT_KEY);
+ }
+
+ @Test
+ public void testGetExistingContext() {
+ ContextSelector selector = ContextSelectorStaticBinder.getSingleton().getContextSelector();
+ Context context = selector.getLoggerContext();
+ assertEquals("toto", context.getName());
+ }
+
+ @Test
+ public void testCreateContext() {
+ MockInitialContext mic = MockInitialContextFactory.getContext();
+ mic.map.put(ClassicConstants.JNDI_CONTEXT_NAME, "tata");
+
+ LoggerFactory.getLogger(ContextDetachingSCLTest.class);
+
+ ContextJNDISelector selector = (ContextJNDISelector)ContextSelectorStaticBinder.getSingleton().getContextSelector();
+ Context context = selector.getLoggerContext();
+ assertEquals("tata", context.getName());
+ System.out.println(selector.getContextNames());
+ assertEquals(2, selector.getCount());
+ }
+
+ @Test
+ public void defaultContext() {
+ MockInitialContext mic = MockInitialContextFactory.getContext();
+ mic.map.put(ClassicConstants.JNDI_CONTEXT_NAME, null);
+
+ ContextJNDISelector selector = (ContextJNDISelector)ContextSelectorStaticBinder.getSingleton().getContextSelector();
+ Context context = selector.getLoggerContext();
+
+ assertEquals("default", context.getName());
+ }
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/selector/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/selector/PackageTest.java
index ed108f8..a1e1962 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/selector/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/selector/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ ContextJNDISelectorTest.class, ContextDetachingSCLTest.class })
-public class PackageTest {
+ at SuiteClasses({ContextJNDISelectorTest.class, ContextDetachingSCLTest.class})
+public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/sift/MDCBasedDiscriminatorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/sift/MDCBasedDiscriminatorTest.java
index 42e3e15..ff92277 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/sift/MDCBasedDiscriminatorTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/sift/MDCBasedDiscriminatorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,50 +31,49 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class MDCBasedDiscriminatorTest {
- static String DEFAULT_VAL = "DEFAULT_VAL";
+ static String DEFAULT_VAL = "DEFAULT_VAL";
- MDCBasedDiscriminator discriminator = new MDCBasedDiscriminator();
- LoggerContext context = new LoggerContext();
- Logger logger = context.getLogger(this.getClass());
+ MDCBasedDiscriminator discriminator = new MDCBasedDiscriminator();
+ LoggerContext context = new LoggerContext();
+ Logger logger = context.getLogger(this.getClass());
- int diff = RandomUtil.getPositiveInt();
- String key = "MDCBasedDiscriminatorTest_key" + diff;
- String value = "MDCBasedDiscriminatorTest_val" + diff;
- LoggingEvent event;
+ int diff = RandomUtil.getPositiveInt();
+ String key = "MDCBasedDiscriminatorTest_key" + diff;
+ String value = "MDCBasedDiscriminatorTest_val" + diff;
+ LoggingEvent event;
- @Before
- public void setUp() {
- MDC.clear();
- discriminator.setContext(context);
- discriminator.setKey(key);
- discriminator.setDefaultValue(DEFAULT_VAL);
- discriminator.start();
- assertTrue(discriminator.isStarted());
- }
+ @Before
+ public void setUp() {
+ discriminator.setContext(context);
+ discriminator.setKey(key);
+ discriminator.setDefaultValue(DEFAULT_VAL);
+ discriminator.start();
+ assertTrue(discriminator.isStarted());
+ }
- @After
- public void teaDown() {
- MDC.clear();
- }
+ @After
+ public void teaDown() {
+ MDC.clear();
+ }
- @Test
- public void smoke() {
- MDC.put(key, value);
- event = new LoggingEvent("a", logger, Level.DEBUG, "", null, null);
+ @Test
+ public void smoke() {
+ MDC.put(key, value);
+ event = new LoggingEvent("a", logger, Level.DEBUG, "", null, null);
- String discriminatorValue = discriminator.getDiscriminatingValue(event);
- assertEquals(value, discriminatorValue);
- }
+ String discriminatorValue = discriminator.getDiscriminatingValue(event);
+ assertEquals(value, discriminatorValue);
+ }
- @Test
- public void nullMDC() {
- event = new LoggingEvent("a", logger, Level.DEBUG, "", null, null);
- assertEquals(new HashMap(), event.getMDCPropertyMap());
- String discriminatorValue = discriminator.getDiscriminatingValue(event);
- assertEquals(DEFAULT_VAL, discriminatorValue);
- }
+ @Test
+ public void nullMDC() {
+ event = new LoggingEvent("a", logger, Level.DEBUG, "", null, null);
+ assertEquals(new HashMap(), event.getMDCPropertyMap());
+ String discriminatorValue = discriminator.getDiscriminatingValue(event);
+ assertEquals(DEFAULT_VAL, discriminatorValue);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/sift/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/sift/PackageTest.java
index 4f722f5..d530188 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/sift/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/sift/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ MDCBasedDiscriminatorTest.class, SiftingAppenderTest.class })
-public class PackageTest {
+ at SuiteClasses({MDCBasedDiscriminatorTest.class, SiftingAppenderTest.class})
+public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java
index ff06171..e7ee029 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,41 +13,14 @@
*/
package ch.qos.logback.classic.sift;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static ch.qos.logback.core.util.CoreTestConstants.OUTPUT_DIR_PREFIX;
-import static org.assertj.core.api.Assertions.*;
-
-import java.util.List;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.slf4j.MDC;
-
-import ch.qos.logback.classic.ClassicConstants;
-import ch.qos.logback.classic.ClassicTestConstants;
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
+import ch.qos.logback.classic.*;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.Appender;
-import ch.qos.logback.core.Context;
-import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.helpers.NOPAppender;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.read.ListAppender;
-import ch.qos.logback.core.rolling.RollingFileAppender;
-import ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP;
-import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
-import ch.qos.logback.core.sift.AppenderFactory;
import ch.qos.logback.core.sift.AppenderTracker;
import ch.qos.logback.core.spi.AbstractComponentTracker;
import ch.qos.logback.core.spi.ComponentTracker;
@@ -55,344 +28,245 @@ import ch.qos.logback.core.status.ErrorStatus;
import ch.qos.logback.core.status.StatusChecker;
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.testUtil.StringListAppender;
-import ch.qos.logback.core.util.CoreTestConstants;
-import ch.qos.logback.core.util.FileSize;
import ch.qos.logback.core.util.StatusPrinter;
+import org.junit.Test;
+import org.slf4j.MDC;
-public class SiftingAppenderTest {
-
- static String SIFT_FOLDER_PREFIX = ClassicTestConstants.JORAN_INPUT_PREFIX + "sift/";
-
- LoggerContext loggerContext = new LoggerContext();
- Logger logger = loggerContext.getLogger(this.getClass().getName());
- Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
- StatusChecker statusChecker = new StatusChecker(loggerContext);
- int diff = RandomUtil.getPositiveInt();
- String randomOutputDir = OUTPUT_DIR_PREFIX + diff + "/";
- int now = 0;
-
- protected void configure(String file) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(loggerContext);
- jc.doConfigure(file);
- }
-
- @Before
- public void setUp() {
- MDC.clear();
- }
-
- @After
- public void tearDown() {
- MDC.clear();
- }
-
- @Test
- public void unsetDefaultValueProperty() throws JoranException {
- configure(SIFT_FOLDER_PREFIX + "unsetDefaultValueProperty.xml");
- logger.debug("hello");
- SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
- assertFalse(sa.isStarted());
- }
-
- @Test
- public void smoke() throws JoranException {
- configure(SIFT_FOLDER_PREFIX + "smoke.xml");
- logger.debug("smoke");
- Appender<ILoggingEvent> appender = getAppenderTracker().find("smokeDefault");
- assertNotNull(appender);
- ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) appender;
- List<ILoggingEvent> eventList = listAppender.list;
- assertEquals(1, listAppender.list.size());
- assertEquals("smoke", eventList.get(0).getMessage());
- }
-
- private AppenderTracker<ILoggingEvent> getAppenderTracker() {
- SiftingAppender ha = (SiftingAppender) root.getAppender("SIFT");
- return ha.getAppenderTracker();
- }
-
- @Test
- public void zeroNesting() throws JoranException {
- configure(SIFT_FOLDER_PREFIX + "zeroNesting.xml");
- logger.debug("hello");
- logger.debug("hello");
- logger.debug("hello");
- logger.debug("hello");
- logger.debug("hello");
-
- Appender<ILoggingEvent> nopa = getAppenderTracker().find("zeroDefault");
- assertNotNull(nopa);
- assertThat(nopa).isInstanceOf(NOPAppender.class);
- StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
-
- statusChecker.assertContainsMatch(ErrorStatus.ERROR, "No nested appenders found");
- }
-
- @Test
- public void multipleNesting() throws JoranException {
- configure(SIFT_FOLDER_PREFIX + "multipleNesting.xml");
- logger.debug("hello");
- logger.debug("hello");
- logger.debug("hello");
-
- Appender<ILoggingEvent> listAppender = getAppenderTracker().find("multipleDefault");
- StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
-
- assertNotNull(listAppender);
- statusChecker.assertContainsMatch(ErrorStatus.ERROR, "Only and only one appender can be nested");
- }
-
- @Test
- public void defaultLayoutRule() throws JoranException {
- configure(SIFT_FOLDER_PREFIX + "defaultLayoutRule.xml");
- logger.debug("hello");
- SiftingAppender ha = (SiftingAppender) root.getAppender("SIFT");
- StringListAppender<ILoggingEvent> listAppender = (StringListAppender<ILoggingEvent>) ha.getAppenderTracker().find("default");
-
- assertNotNull(listAppender);
- List<String> strList = listAppender.strList;
- assertEquals(1, strList.size());
- assertEquals("DEBUG hello", strList.get(0));
- }
-
- @Test
- public void fileAppenderCollision() throws JoranException, InterruptedException {
- loggerContext.putProperty("DIR_PREFIX", randomOutputDir);
- String key = "collision";
- configure(SIFT_FOLDER_PREFIX + "fileAppender.xml");
- SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
-
- long timestamp = System.currentTimeMillis();
-
- MDC.put(key, "A-"+diff);
- logNewEventViaSiftingAppender(sa, timestamp);
- FileAppender<ILoggingEvent> fileAppenderA = (FileAppender<ILoggingEvent>) sa.getAppenderTracker().find("A-"+diff);
- assertNotNull(fileAppenderA);
- assertTrue(fileAppenderA.isStarted());
- timestamp += ComponentTracker.DEFAULT_TIMEOUT + 1;
- MDC.put(key, "B-"+diff);
- logNewEventViaSiftingAppender(sa, timestamp);
- assertFalse(fileAppenderA.isStarted());
-
- MDC.put(key, "A-"+diff);
- timestamp += 1;
- logNewEventViaSiftingAppender(sa, timestamp);
- FileAppender<ILoggingEvent> fileAppenderA_2 = (FileAppender<ILoggingEvent>) sa.getAppenderTracker().find("A-"+diff);
- assertTrue(fileAppenderA_2.isStarted());
-
- }
-
- private void logNewEventViaSiftingAppender(SiftingAppender sa, long timestamp) {
- LoggingEvent le = new LoggingEvent("x", logger, Level.INFO, "hello", null, null);
- le.setTimeStamp(timestamp + ComponentTracker.DEFAULT_TIMEOUT + 1);
- sa.doAppend(le);
- }
-
- @Test
- public void testWholeCycle() throws JoranException {
- String mdcKey = "cycle";
- configure(SIFT_FOLDER_PREFIX + "completeCycle.xml");
- MDC.put(mdcKey, "a");
- logger.debug("smoke");
- long timestamp = System.currentTimeMillis();
- SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
- ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) sa.getAppenderTracker().find("a");
- assertNotNull(listAppender);
- List<ILoggingEvent> eventList = listAppender.list;
- assertEquals(1, listAppender.list.size());
- assertEquals("smoke", eventList.get(0).getMessage());
-
- MDC.remove(mdcKey);
- logNewEventViaSiftingAppender(sa, timestamp);
- assertFalse(listAppender.isStarted());
- assertEquals(1, sa.getAppenderTracker().allKeys().size());
- assertTrue(sa.getAppenderTracker().allKeys().contains("cycleDefault"));
- }
-
- @Test
- public void sessionFinalizationShouldCauseLingering() throws JoranException {
- String mdcKey = "linger";
- String mdcVal = "session" + diff;
- configure(SIFT_FOLDER_PREFIX + "lingering.xml");
- MDC.put(mdcKey, mdcVal);
- logger.debug("linger 1");
- logger.debug(ClassicConstants.FINALIZE_SESSION_MARKER, "linger 2");
- long now = System.currentTimeMillis();
- SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
- AppenderTracker<ILoggingEvent> tracker = sa.getAppenderTracker();
-
- assertEquals(1, tracker.allKeys().size());
- Appender<ILoggingEvent> appender = tracker.find(mdcVal);
- assertTrue(appender.isStarted());
-
- tracker.removeStaleComponents(now + AppenderTracker.LINGERING_TIMEOUT + 1);
- // previously lingering appenders should be closed upon timeout
- assertFalse(appender.isStarted());
- // and they should be gone
- assertEquals(0, tracker.allKeys().size());
- }
-
- @Test
- public void localPropertiesShouldBeVisible() throws JoranException {
- String mdcKey = "localProperty";
- String mdcVal = "" + diff;
- String msg = "localPropertiesShouldBeVisible";
- String prefix = "Y";
- configure(SIFT_FOLDER_PREFIX + "propertyPropagation.xml");
- MDC.put(mdcKey, mdcVal);
- logger.debug(msg);
- SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
- StringListAppender<ILoggingEvent> listAppender = (StringListAppender<ILoggingEvent>) sa.getAppenderTracker().find(mdcVal);
- assertNotNull(listAppender);
- List<String> strList = listAppender.strList;
- assertEquals(1, listAppender.strList.size());
- assertEquals(prefix + msg, strList.get(0));
- }
+import java.util.List;
- @Test
- public void propertyDefinedWithinSiftElementShouldBeVisible() throws JoranException {
- String mdcKey = "propertyDefinedWithinSift";
- String mdcVal = "" + diff;
- String msg = "propertyDefinedWithinSiftElementShouldBeVisible";
- String prefix = "Y";
- configure(SIFT_FOLDER_PREFIX + "propertyDefinedInSiftElement.xml");
- MDC.put(mdcKey, mdcVal);
- logger.debug(msg);
- SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
- StringListAppender<ILoggingEvent> listAppender = (StringListAppender<ILoggingEvent>) sa.getAppenderTracker().find(mdcVal);
- assertNotNull(listAppender);
- List<String> strList = listAppender.strList;
- assertEquals(1, listAppender.strList.size());
- assertEquals(prefix + msg, strList.get(0));
- }
+import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
- @Test
- public void compositePropertyShouldCombineWithinAndWithoutSiftElement() throws JoranException {
- String mdcKey = "compositeProperty";
- String mdcVal = "" + diff;
- String msg = "compositePropertyShouldCombineWithinAndWithoutSiftElement";
- String prefix = "composite";
- configure(SIFT_FOLDER_PREFIX + "compositeProperty.xml");
- MDC.put(mdcKey, mdcVal);
- logger.debug(msg);
- SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
- StringListAppender<ILoggingEvent> listAppender = (StringListAppender<ILoggingEvent>) sa.getAppenderTracker().find(mdcVal);
- assertNotNull(listAppender);
- List<String> strList = listAppender.strList;
- assertEquals(1, listAppender.strList.size());
- assertEquals(prefix + msg, strList.get(0));
- }
+public class SiftingAppenderTest {
- @Test
- public void maxAppendersCountPropertyShouldBeHonored() throws JoranException {
- configure(SIFT_FOLDER_PREFIX + "maxAppenderCount.xml");
- int max = 5;
- SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
- String mdcKey = "max";
- for (int i = 0; i <= max; i++) {
- MDC.put(mdcKey, "" + (diff + i));
- LoggingEvent event = new LoggingEvent("", logger, Level.DEBUG, "max" + i, null, null);
- event.setTimeStamp(now);
- sa.doAppend(event);
- now += AbstractComponentTracker.WAIT_BETWEEN_SUCCESSIVE_REMOVAL_ITERATIONS;
- }
- AppenderTracker<ILoggingEvent> tracker = sa.getAppenderTracker();
- assertEquals(max, tracker.allKeys().size());
- assertNull(tracker.find("" + (diff + 0)));
- for (int i = 1; i <= max; i++) {
- assertNotNull(tracker.find("" + (diff + i)));
- }
+ static String SIFT_FOLDER_PREFIX = ClassicTestConstants.JORAN_INPUT_PREFIX + "sift/";
+
+ LoggerContext loggerContext = new LoggerContext();
+ Logger logger = loggerContext.getLogger(this.getClass().getName());
+ Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
+ StatusChecker statusChecker = new StatusChecker(loggerContext);
+ int diff = RandomUtil.getPositiveInt();
+ int now = 0;
+
+ protected void configure(String file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ jc.doConfigure(file);
+ }
+
+ @Test
+ public void unsetDefaultValueProperty() throws JoranException {
+ configure(SIFT_FOLDER_PREFIX + "unsetDefaultValueProperty.xml");
+ logger.debug("hello");
+ SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
+ assertFalse(sa.isStarted());
+ }
+
+ @Test
+ public void smoke() throws JoranException {
+ configure(SIFT_FOLDER_PREFIX + "smoke.xml");
+ logger.debug("smoke");
+ Appender<ILoggingEvent> appender = getAppenderTracker().find("smokeDefault");
+ assertNotNull(appender);
+ ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) appender;
+ List<ILoggingEvent> eventList = listAppender.list;
+ assertEquals(1, listAppender.list.size());
+ assertEquals("smoke", eventList.get(0).getMessage());
+ }
+
+ private AppenderTracker<ILoggingEvent> getAppenderTracker() {
+ SiftingAppender ha = (SiftingAppender) root.getAppender("SIFT");
+ return ha.getAppenderTracker();
+ }
+
+ @Test
+ public void zeroNesting() throws JoranException {
+ configure(SIFT_FOLDER_PREFIX + "zeroNesting.xml");
+ logger.debug("hello");
+ logger.debug("hello");
+ logger.debug("hello");
+ logger.debug("hello");
+ logger.debug("hello");
+ SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
+
+ Appender<ILoggingEvent> appender = getAppenderTracker().find("zeroDefault");
+ assertNotNull(appender);
+ NOPAppender<ILoggingEvent> nopa = (NOPAppender<ILoggingEvent>) appender;
+ StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
+
+ statusChecker.assertContainsMatch(ErrorStatus.ERROR, "No nested appenders found");
+ }
+
+ @Test
+ public void multipleNesting() throws JoranException {
+ configure(SIFT_FOLDER_PREFIX + "multipleNesting.xml");
+ logger.debug("hello");
+ logger.debug("hello");
+ logger.debug("hello");
+
+ Appender<ILoggingEvent> listAppender = getAppenderTracker().find("multipleDefault");
+ StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
+
+ assertNotNull(listAppender);
+ statusChecker.assertContainsMatch(ErrorStatus.ERROR,
+ "Only and only one appender can be nested");
+ }
+
+ @Test
+ public void defaultLayoutRule() throws JoranException {
+ configure(SIFT_FOLDER_PREFIX + "defaultLayoutRule.xml");
+ logger.debug("hello");
+ SiftingAppender ha = (SiftingAppender) root.getAppender("SIFT");
+ StringListAppender<ILoggingEvent> listAppender = (StringListAppender<ILoggingEvent>) ha
+ .getAppenderTracker().find("default");
+
+ assertNotNull(listAppender);
+ List<String> strList = listAppender.strList;
+ assertEquals(1, strList.size());
+ assertEquals("DEBUG hello", strList.get(0));
+ }
+
+ @Test
+ public void testWholeCycle() throws JoranException {
+ String mdcKey = "cycle";
+ configure(SIFT_FOLDER_PREFIX + "completeCycle.xml");
+ MDC.put(mdcKey, "a");
+ logger.debug("smoke");
+ long timestamp = System.currentTimeMillis();
+ SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
+ ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>)
+ sa.getAppenderTracker().find("a");
+ assertNotNull(listAppender);
+ List<ILoggingEvent> eventList = listAppender.list;
+ assertEquals(1, listAppender.list.size());
+ assertEquals("smoke", eventList.get(0).getMessage());
+
+ MDC.remove(mdcKey);
+ LoggingEvent le = new LoggingEvent("x", logger, Level.INFO, "hello", null,
+ null);
+ le.setTimeStamp(timestamp + ComponentTracker.DEFAULT_TIMEOUT + 1);
+ sa.doAppend(le);
+ assertFalse(listAppender.isStarted());
+ assertEquals(1, sa.getAppenderTracker().allKeys().size());
+ assertTrue(sa.getAppenderTracker().allKeys().contains("cycleDefault"));
+ }
+
+ @Test
+ public void sessionFinalizationShouldCauseLingering() throws JoranException {
+ String mdcKey = "linger";
+ String mdcVal = "session" + diff;
+ configure(SIFT_FOLDER_PREFIX + "lingering.xml");
+ MDC.put(mdcKey, mdcVal);
+ logger.debug("linger 1");
+ logger.debug(ClassicConstants.FINALIZE_SESSION_MARKER, "linger 2");
+ long now = System.currentTimeMillis();
+ SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
+ AppenderTracker<ILoggingEvent> tracker = sa.getAppenderTracker();
+
+ assertEquals(1, tracker.allKeys().size());
+ Appender<ILoggingEvent> appender = tracker.find(mdcVal);
+ assertTrue(appender.isStarted());
+
+ tracker.removeStaleComponents(now + AppenderTracker.LINGERING_TIMEOUT + 1);
+ // previously lingering appenders should be closed upon timeout
+ assertFalse(appender.isStarted());
+ // and they should be gone
+ assertEquals(0, tracker.allKeys().size());
+ }
+
+ @Test
+ public void localPropertiesShouldBeVisible() throws JoranException {
+ String mdcKey = "localProperty";
+ String mdcVal = "" + diff;
+ String msg = "localPropertiesShouldBeVisible";
+ String prefix = "Y";
+ configure(SIFT_FOLDER_PREFIX + "propertyPropagation.xml");
+ MDC.put(mdcKey, mdcVal);
+ logger.debug(msg);
+ SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
+ StringListAppender<ILoggingEvent> listAppender = (StringListAppender<ILoggingEvent>) sa
+ .getAppenderTracker().find(mdcVal);
+ assertNotNull(listAppender);
+ List<String> strList = listAppender.strList;
+ assertEquals(1, listAppender.strList.size());
+ assertEquals(prefix + msg, strList.get(0));
+ }
+
+ @Test
+ public void propertyDefinedWithinSiftElementShouldBeVisible() throws JoranException {
+ String mdcKey = "propertyDefinedWithinSift";
+ String mdcVal = "" + diff;
+ String msg = "propertyDefinedWithinSiftElementShouldBeVisible";
+ String prefix = "Y";
+ configure(SIFT_FOLDER_PREFIX + "propertyDefinedInSiftElement.xml");
+ MDC.put(mdcKey, mdcVal);
+ logger.debug(msg);
+ SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
+ StringListAppender<ILoggingEvent> listAppender = (StringListAppender<ILoggingEvent>) sa
+ .getAppenderTracker().find(mdcVal);
+ assertNotNull(listAppender);
+ List<String> strList = listAppender.strList;
+ assertEquals(1, listAppender.strList.size());
+ assertEquals(prefix + msg, strList.get(0));
+ }
+
+ @Test
+ public void compositePropertyShouldCombineWithinAndWithoutSiftElement() throws JoranException {
+ String mdcKey = "compositeProperty";
+ String mdcVal = "" + diff;
+ String msg = "compositePropertyShouldCombineWithinAndWithoutSiftElement";
+ String prefix = "composite";
+ configure(SIFT_FOLDER_PREFIX + "compositeProperty.xml");
+ MDC.put(mdcKey, mdcVal);
+ logger.debug(msg);
+ SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
+ StringListAppender<ILoggingEvent> listAppender = (StringListAppender<ILoggingEvent>) sa
+ .getAppenderTracker().find(mdcVal);
+ assertNotNull(listAppender);
+ List<String> strList = listAppender.strList;
+ assertEquals(1, listAppender.strList.size());
+ assertEquals(prefix + msg, strList.get(0));
+ }
+
+ @Test
+ public void maxAppendersCountPropertyShouldBeHonored() throws JoranException {
+ configure(SIFT_FOLDER_PREFIX + "maxAppenderCount.xml");
+ int max = 5;
+ SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
+ String mdcKey = "max";
+ for(int i = 0; i <= max; i++) {
+ MDC.put(mdcKey, "" + (diff + i));
+ LoggingEvent event = new LoggingEvent("", logger, Level.DEBUG, "max"+i, null, null);
+ event.setTimeStamp(now);
+ sa.doAppend(event);
+ now += AbstractComponentTracker.WAIT_BETWEEN_SUCCESSIVE_REMOVAL_ITERATIONS;
}
-
- @Test
- public void timeoutPropertyShouldBeHonored() throws JoranException, InterruptedException {
- configure(SIFT_FOLDER_PREFIX + "timeout.xml");
- long timeout = 30 * 1000;
- SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
-
- LoggingEvent event = new LoggingEvent("", logger, Level.DEBUG, "timeout", null, null);
- event.setTimeStamp(now);
- sa.doAppend(event);
-
- AppenderTracker<ILoggingEvent> tracker = sa.getAppenderTracker();
-
- assertEquals(1, tracker.getComponentCount());
-
- now += timeout + 1;
- tracker.removeStaleComponents(now);
- assertEquals(0, tracker.getComponentCount());
- statusChecker.assertIsErrorFree();
+ AppenderTracker<ILoggingEvent> tracker = sa.getAppenderTracker();
+ assertEquals(max, tracker.allKeys().size());
+ assertNull(tracker.find("" + (diff + 0)));
+ for(int i = 1; i <= max; i++) {
+ assertNotNull(tracker.find("" + (diff + i)));
}
+ }
- // LOGBACK-1127
- @Ignore
- @Test
- public void programmicSiftingAppender() {
-
- SiftingAppender connectorAppender = new SiftingAppender();
- connectorAppender.setContext(loggerContext);
- connectorAppender.setName("SIFTING_APPENDER");
-
- MDCBasedDiscriminator discriminator = new MDCBasedDiscriminator();
- discriminator.setKey("SKEY");
- discriminator.setDefaultValue("DEF_KEY");
- discriminator.start();
- connectorAppender.setDiscriminator(discriminator);
-
- connectorAppender.setAppenderFactory(new AppenderFactory<ILoggingEvent>() {
-
- @Override
- public Appender<ILoggingEvent> buildAppender(Context context, String discriminatingValue) throws JoranException {
+ @Test
+ public void timeoutPropertyShouldBeHonored() throws JoranException, InterruptedException {
+ configure(SIFT_FOLDER_PREFIX + "timeout.xml");
+ long timeout = 30*1000;
+ SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
- RollingFileAppender<ILoggingEvent> appender = new RollingFileAppender<ILoggingEvent>();
- appender.setName("ROLLING_APPENDER_" + discriminatingValue);
- appender.setContext(context);
- appender.setFile("/var/logs/active_" + discriminatingValue + ".log");
+ LoggingEvent event = new LoggingEvent("", logger, Level.DEBUG, "timeout", null, null);
+ event.setTimeStamp(now);
+ sa.doAppend(event);
- TimeBasedRollingPolicy<ILoggingEvent> policy = new TimeBasedRollingPolicy<ILoggingEvent>();
- policy.setContext(context);
- policy.setMaxHistory(365);
- policy.setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "/logback1127/" + discriminatingValue + "_%d{yyyy_MM_dd}_%i.log");
- policy.setParent(appender);
- policy.setCleanHistoryOnStart(true);
+ AppenderTracker<ILoggingEvent> tracker = sa.getAppenderTracker();
- SizeAndTimeBasedFNATP<ILoggingEvent> innerpolicy = new SizeAndTimeBasedFNATP<ILoggingEvent>();
- innerpolicy.setContext(context);
- innerpolicy.setMaxFileSize(FileSize.valueOf("5KB"));
- innerpolicy.setTimeBasedRollingPolicy(policy);
+ assertEquals(1, tracker.getComponentCount());
- policy.setTimeBasedFileNamingAndTriggeringPolicy(innerpolicy);
- policy.start();
- appender.setRollingPolicy(policy);
+ now += timeout+1;
+ tracker.removeStaleComponents(now);
+ assertEquals(0, tracker.getComponentCount());
+ statusChecker.assertIsErrorFree();
+ }
- PatternLayoutEncoder pl = new PatternLayoutEncoder();
- pl.setContext(context);
- pl.setPattern("%d{yyyy/MM/dd'T'HH:mm:ss} %-5level - %msg\n");
-
- pl.start();
- appender.setEncoder(pl);
-
- appender.start();
- return appender;
- }
- });
- connectorAppender.start();
-
- ch.qos.logback.classic.Logger logger = loggerContext.getLogger("org.test");
- logger.addAppender(connectorAppender);
- logger.setLevel(Level.DEBUG);
- logger.setAdditive(false);
-
- MDC.put("SKEY", "K1");
- logger.info("bla1");
- MDC.clear();
-
- MDC.put("SKEY", "K2");
- logger.info("bla2");
- MDC.clear();
-
- StatusPrinter.print(loggerContext);
-
- }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/BasicContextListener.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/BasicContextListener.java
index 654b111..7020b5d 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/BasicContextListener.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/BasicContextListener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,47 +19,42 @@ import ch.qos.logback.classic.LoggerContext;
public class BasicContextListener implements LoggerContextListener {
- enum UpdateType {
- NONE, START, RESET, STOP, LEVEL_CHANGE
- };
-
- UpdateType updateType = UpdateType.NONE;
- LoggerContext context;
- Logger logger;
- Level level;
-
- boolean resetResistant;
-
- public void setResetResistant(boolean resetResistant) {
- this.resetResistant = resetResistant;
- }
-
- public void onReset(LoggerContext context) {
- updateType = UpdateType.RESET;
- this.context = context;
-
- }
-
- public void onStart(LoggerContext context) {
- updateType = UpdateType.START;
- ;
- this.context = context;
- }
-
- public void onStop(LoggerContext context) {
- updateType = UpdateType.STOP;
- ;
- this.context = context;
- }
-
- public boolean isResetResistant() {
- return resetResistant;
- }
-
- public void onLevelChange(Logger logger, Level level) {
- updateType = UpdateType.LEVEL_CHANGE;
- this.logger = logger;
- this.level = level;
- }
-
+ enum UpdateType { NONE, START, RESET, STOP , LEVEL_CHANGE};
+
+ UpdateType updateType = UpdateType.NONE;
+ LoggerContext context;
+ Logger logger;
+ Level level;
+
+ boolean resetResistant;
+
+ public void setResetResistant(boolean resetResistant) {
+ this.resetResistant = resetResistant;
+ }
+
+ public void onReset(LoggerContext context) {
+ updateType = UpdateType.RESET;
+ this.context = context;
+
+ }
+ public void onStart(LoggerContext context) {
+ updateType = UpdateType.START;;
+ this.context = context;
+ }
+
+ public void onStop(LoggerContext context) {
+ updateType = UpdateType.STOP;;
+ this.context = context;
+ }
+
+ public boolean isResetResistant() {
+ return resetResistant;
+ }
+
+ public void onLevelChange(Logger logger, Level level) {
+ updateType = UpdateType.LEVEL_CHANGE;
+ this.logger = logger;
+ this.level = level;
+ }
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/BogusClassLoader.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/BogusClassLoader.java
index 596934d..18fd8a9 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/BogusClassLoader.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/BogusClassLoader.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,28 +24,29 @@ import java.net.URLClassLoader;
*/
public class BogusClassLoader extends URLClassLoader {
- public BogusClassLoader(URL[] urls) {
- super(urls);
- }
+ public BogusClassLoader(URL[] urls) {
+ super(urls);
+ }
- public BogusClassLoader(URL[] urls, ClassLoader parent) {
- super(urls, parent);
- }
+ public BogusClassLoader(URL[] urls, ClassLoader parent) {
+ super(urls, parent);
+ }
- public Class<?> loadClass(String name) throws ClassNotFoundException {
- return loadClass(name, false);
- }
+ public Class<?> loadClass(String name) throws ClassNotFoundException {
+ return loadClass(name, false);
+ }
- /**
- * Throw NoClassDefFoundError if the requested class contains the string
- * "Bogus". Otherwise, delegate to super-class.
- */
- protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ /**
+ * Throw NoClassDefFoundError if the requested class contains the string
+ * "Bogus". Otherwise, delegate to super-class.
+ */
+ protected Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
- if (name.contains("Bogus")) {
- throw new NoClassDefFoundError();
- }
-
- return super.loadClass(name, resolve);
+ if (name.contains("Bogus")) {
+ throw new NoClassDefFoundError();
}
+
+ return super.loadClass(name, resolve);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/CPDCSpecial.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/CPDCSpecial.java
index eeb5498..0876778 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/CPDCSpecial.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/CPDCSpecial.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,10 +15,10 @@ package ch.qos.logback.classic.spi;
public interface CPDCSpecial {
- void doTest();
+ void doTest();
- Throwable getThrowable();
+ Throwable getThrowable();
- IThrowableProxy getThrowableProxy();
+ IThrowableProxy getThrowableProxy();
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/CallerDataTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/CallerDataTest.java
index 3527b13..4d9e49e 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/CallerDataTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/CallerDataTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,29 +19,30 @@ import static org.junit.Assert.assertTrue;
import org.junit.Test;
-public class CallerDataTest {
+public class CallerDataTest {
- @Test
- public void testBasic() {
- Throwable t = new Throwable();
- StackTraceElement[] steArray = t.getStackTrace();
-
- StackTraceElement[] cda = CallerData.extract(t, CallerDataTest.class.getName(), 50, null);
- assertNotNull(cda);
- assertTrue(cda.length > 0);
- assertEquals(steArray.length - 1, cda.length);
- }
-
- /**
- * This test verifies that in case caller data cannot be
- * extracted, CallerData.extract does not throw an exception
- *
- */
- @Test
- public void testDeferredProcessing() {
- StackTraceElement[] cda = CallerData.extract(new Throwable(), "com.inexistent.foo", 10, null);
- assertNotNull(cda);
- assertEquals(0, cda.length);
- }
+ @Test
+ public void testBasic() {
+ Throwable t = new Throwable();
+ StackTraceElement[] steArray = t.getStackTrace();
+
+ StackTraceElement[] cda = CallerData.extract(t, CallerDataTest.class.getName(), 50, null);
+ assertNotNull(cda);
+ assertTrue(cda.length > 0);
+ assertEquals(steArray.length - 1, cda.length);
+ }
+
+ /**
+ * This test verifies that in case caller data cannot be
+ * extracted, CallerData.extract does not throw an exception
+ *
+ */
+ @Test
+ public void testDeferredProcessing() {
+ StackTraceElement[] cda = CallerData.extract(new Throwable(), "com.inexistent.foo", 10, null);
+ assertNotNull(cda);
+ assertEquals(0, cda.length);
+ }
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/ContextListenerTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/ContextListenerTest.java
index b3eac4a..a482b49 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/ContextListenerTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/ContextListenerTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,59 +25,59 @@ import ch.qos.logback.classic.spi.BasicContextListener.UpdateType;
public class ContextListenerTest {
- LoggerContext context;
- BasicContextListener listener;
+ LoggerContext context;
+ BasicContextListener listener;
- @Before
- public void setUp() throws Exception {
- context = new LoggerContext();
- listener = new BasicContextListener();
- context.addListener(listener);
- }
+ @Before
+ public void setUp() throws Exception {
+ context = new LoggerContext();
+ listener = new BasicContextListener();
+ context.addListener(listener);
+ }
- @Test
- public void testNotifyOnReset() {
- context.reset();
- assertEquals(UpdateType.RESET, listener.updateType);
- assertEquals(listener.context, context);
- }
+ @Test
+ public void testNotifyOnReset() {
+ context.reset();
+ assertEquals(UpdateType.RESET, listener.updateType);
+ assertEquals(listener.context, context);
+ }
- @Test
- public void testNotifyOnStopResistant() {
- listener.setResetResistant(true);
- context.stop();
- assertEquals(UpdateType.STOP, listener.updateType);
- assertEquals(listener.context, context);
- }
+ @Test
+ public void testNotifyOnStopResistant() {
+ listener.setResetResistant(true);
+ context.stop();
+ assertEquals(UpdateType.STOP, listener.updateType);
+ assertEquals(listener.context, context);
+ }
- @Test
- public void testNotifyOnStopNotResistant() {
- context.stop();
- assertEquals(UpdateType.RESET, listener.updateType);
- assertEquals(listener.context, context);
- }
+ @Test
+ public void testNotifyOnStopNotResistant() {
+ context.stop();
+ assertEquals(UpdateType.RESET, listener.updateType);
+ assertEquals(listener.context, context);
+ }
- @Test
- public void testNotifyOnStart() {
- context.start();
- assertEquals(UpdateType.START, listener.updateType);
- assertEquals(listener.context, context);
- }
+ @Test
+ public void testNotifyOnStart() {
+ context.start();
+ assertEquals(UpdateType.START, listener.updateType);
+ assertEquals(listener.context, context);
+ }
- void checkLevelChange(String loggerName, Level level) {
- Logger logger = context.getLogger(loggerName);
- logger.setLevel(level);
+ void checkLevelChange(String loggerName, Level level) {
+ Logger logger = context.getLogger(loggerName);
+ logger.setLevel(level);
- assertEquals(UpdateType.LEVEL_CHANGE, listener.updateType);
- assertEquals(listener.logger, logger);
- assertEquals(listener.level, level);
+ assertEquals(UpdateType.LEVEL_CHANGE, listener.updateType);
+ assertEquals(listener.logger, logger);
+ assertEquals(listener.level, level);
- }
+ }
- @Test
- public void testLevelChange() {
- checkLevelChange("a", Level.INFO);
- checkLevelChange("a.b", Level.ERROR);
- checkLevelChange("a.b.c", Level.DEBUG);
- }
+ @Test
+ public void testLevelChange() {
+ checkLevelChange("a", Level.INFO);
+ checkLevelChange("a.b", Level.ERROR);
+ checkLevelChange("a.b.c", Level.DEBUG);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/DummyThrowableProxy.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/DummyThrowableProxy.java
index 35ff9a4..070fec0 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/DummyThrowableProxy.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/DummyThrowableProxy.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,59 +14,52 @@
package ch.qos.logback.classic.spi;
public class DummyThrowableProxy implements IThrowableProxy {
+
+ private String className;
+ private String message;
+ private int commonFramesCount;
+ private StackTraceElementProxy[] stackTraceElementProxyArray;
+ private IThrowableProxy cause;
+ private IThrowableProxy[] suppressed;
- private String className;
- private String message;
- private int commonFramesCount;
- private StackTraceElementProxy[] stackTraceElementProxyArray;
- private IThrowableProxy cause;
- private IThrowableProxy[] suppressed;
+ public String getClassName() {
+ return className;
+ }
+ public void setClassName(String className) {
+ this.className = className;
+ }
+ public String getMessage() {
+ return message;
+ }
+ public void setMessage(String message) {
+ this.message = message;
+ }
+ public int getCommonFrames() {
+ return commonFramesCount;
+ }
+ public void setCommonFramesCount(int commonFramesCount) {
+ this.commonFramesCount = commonFramesCount;
+ }
- public String getClassName() {
- return className;
- }
+ public StackTraceElementProxy[] getStackTraceElementProxyArray() {
+ return stackTraceElementProxyArray;
+ }
+ public void setStackTraceElementProxyArray(
+ StackTraceElementProxy[] stackTraceElementProxyArray) {
+ this.stackTraceElementProxyArray = stackTraceElementProxyArray;
+ }
+ public IThrowableProxy getCause() {
+ return cause;
+ }
+ public void setCause(IThrowableProxy cause) {
+ this.cause = cause;
+ }
- public void setClassName(String className) {
- this.className = className;
- }
+ public IThrowableProxy[] getSuppressed() {
+ return suppressed;
+ }
- public String getMessage() {
- return message;
- }
-
- public void setMessage(String message) {
- this.message = message;
- }
-
- public int getCommonFrames() {
- return commonFramesCount;
- }
-
- public void setCommonFramesCount(int commonFramesCount) {
- this.commonFramesCount = commonFramesCount;
- }
-
- public StackTraceElementProxy[] getStackTraceElementProxyArray() {
- return stackTraceElementProxyArray;
- }
-
- public void setStackTraceElementProxyArray(StackTraceElementProxy[] stackTraceElementProxyArray) {
- this.stackTraceElementProxyArray = stackTraceElementProxyArray;
- }
-
- public IThrowableProxy getCause() {
- return cause;
- }
-
- public void setCause(IThrowableProxy cause) {
- this.cause = cause;
- }
-
- public IThrowableProxy[] getSuppressed() {
- return suppressed;
- }
-
- public void setSuppressed(IThrowableProxy[] suppressed) {
- this.suppressed = suppressed;
- }
+ public void setSuppressed(IThrowableProxy[] suppressed) {
+ this.suppressed = suppressed;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/LocalFirstClassLoader.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/LocalFirstClassLoader.java
index 7fcc481..ce022a1 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/LocalFirstClassLoader.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/LocalFirstClassLoader.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,55 +24,56 @@ import java.net.URLClassLoader;
*/
public class LocalFirstClassLoader extends URLClassLoader {
- public LocalFirstClassLoader(URL[] urls) {
- super(urls);
- }
-
- public LocalFirstClassLoader(URL[] urls, ClassLoader parent) {
- super(urls, parent);
- }
+ public LocalFirstClassLoader(URL[] urls) {
+ super(urls);
+ }
- public void addURL(URL url) {
- super.addURL(url);
- }
+ public LocalFirstClassLoader(URL[] urls, ClassLoader parent) {
+ super(urls, parent);
+ }
- public Class<?> loadClass(String name) throws ClassNotFoundException {
- return loadClass(name, false);
- }
+ public void addURL(URL url) {
+ super.addURL(url);
+ }
- /**
- * We override the parent-first behavior established by java.lang.Classloader.
- *
- * The implementation is surprisingly straightforward.
- */
- protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ public Class<?> loadClass(String name) throws ClassNotFoundException {
+ return loadClass(name, false);
+ }
- // First, check if the class has already been loaded
- Class c = findLoadedClass(name);
+ /**
+ * We override the parent-first behavior established by java.lang.Classloader.
+ *
+ * The implementation is surprisingly straightforward.
+ */
+ protected Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
- // if not loaded, search the local (child) resources
- if (c == null) {
- try {
- c = findClass(name);
- } catch (ClassNotFoundException cnfe) {
- // ignore
- }
- }
+ // First, check if the class has already been loaded
+ Class c = findLoadedClass(name);
- // if we could not find it, delegate to parent
- // Note that we don't attempt to catch any ClassNotFoundException
- if (c == null) {
- if (getParent() != null) {
- c = getParent().loadClass(name);
- } else {
- c = getSystemClassLoader().loadClass(name);
- }
- }
+ // if not loaded, search the local (child) resources
+ if (c == null) {
+ try {
+ c = findClass(name);
+ } catch (ClassNotFoundException cnfe) {
+ // ignore
+ }
+ }
- if (resolve) {
- resolveClass(c);
- }
+ // if we could not find it, delegate to parent
+ // Note that we don't attempt to catch any ClassNotFoundException
+ if (c == null) {
+ if (getParent() != null) {
+ c = getParent().loadClass(name);
+ } else {
+ c = getSystemClassLoader().loadClass(name);
+ }
+ }
- return c;
+ if (resolve) {
+ resolveClass(c);
}
+
+ return c;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggerComparatorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggerComparatorTest.java
index 9ad9c0a..54673d3 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggerComparatorTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggerComparatorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,29 +20,32 @@ import static org.junit.Assert.*;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
-public class LoggerComparatorTest {
-
- LoggerComparator comparator = new LoggerComparator();
- LoggerContext lc = new LoggerContext();
-
- Logger root = lc.getLogger("root");
- Logger a = lc.getLogger("a");
- Logger b = lc.getLogger("b");
-
- @Before
- public void setUp() throws Exception {
-
- }
+public class LoggerComparatorTest {
- @Test
- public void testSmoke() {
- assertEquals(0, comparator.compare(a, a));
- assertEquals(-1, comparator.compare(a, b));
- assertEquals(1, comparator.compare(b, a));
- assertEquals(-1, comparator.compare(root, a));
- // following two tests failed before bug #127 was fixed
- assertEquals(1, comparator.compare(a, root));
- assertEquals(0, comparator.compare(root, root));
- }
+ LoggerComparator comparator = new LoggerComparator();
+ LoggerContext lc = new LoggerContext();
+
+ Logger root = lc.getLogger("root");
+
+ Logger a = lc.getLogger("a");
+ Logger b = lc.getLogger("b");
+
+ @Before
+ public void setUp() throws Exception {
+
+ }
+
+
+
+ @Test
+ public void testSmoke() {
+ assertEquals(0, comparator.compare(a, a));
+ assertEquals(-1, comparator.compare(a, b));
+ assertEquals(1, comparator.compare(b, a));
+ assertEquals(-1, comparator.compare(root, a));
+ // following two tests failed before bug #127 was fixed
+ assertEquals(1, comparator.compare(a, root));
+ assertEquals(0, comparator.compare(root, root));
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggingEventSerializationPerfTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggingEventSerializationPerfTest.java
index 3b9a0ec..23cd6fa 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggingEventSerializationPerfTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggingEventSerializationPerfTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -47,90 +47,95 @@ import ch.qos.logback.core.CoreConstants;
public class LoggingEventSerializationPerfTest {
- static int LOOP_LEN = 10 * 1000;
-
- NOPOutputStream noos = new NOPOutputStream();
- ObjectOutputStream oos;
+ static int LOOP_LEN = 10 * 1000;
+
+ NOPOutputStream noos = new NOPOutputStream();
+ ObjectOutputStream oos;
+
+ @Before
+ public void setUp() throws Exception {
+ MDC.clear();
+ oos = new ObjectOutputStream(noos);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ double doLoop(Builder builder, int loopLen) {
+ long start = System.nanoTime();
+ int resetCounter = 0;
+ for (int i = 0; i < loopLen; i++) {
+ try {
+ ILoggingEvent le = (ILoggingEvent) builder.build(i);
+ oos.writeObject(LoggingEventVO.build(le));
+
+ oos.flush();
+ if (++resetCounter >= CoreConstants.OOS_RESET_FREQUENCY) {
+ oos.reset();
+ resetCounter = 0;
+ }
- @Before
- public void setUp() throws Exception {
- MDC.clear();
- oos = new ObjectOutputStream(noos);
+ } catch (IOException ex) {
+ fail(ex.getMessage());
+ }
}
-
- @After
- public void tearDown() throws Exception {
+ long end = System.nanoTime();
+ return (end - start) / (1.0d * loopLen);
+ }
+
+ @Test
+ public void testPerformance() {
+ if (EnvUtilForTests.isLinux()) {
+ return;
}
+ TrivialLoggingEventBuilder builder = new TrivialLoggingEventBuilder();
- double doLoop(Builder builder, int loopLen) {
- long start = System.nanoTime();
- int resetCounter = 0;
- for (int i = 0; i < loopLen; i++) {
- try {
- ILoggingEvent le = (ILoggingEvent) builder.build(i);
- oos.writeObject(LoggingEventVO.build(le));
-
- oos.flush();
- if (++resetCounter >= CoreConstants.OOS_RESET_FREQUENCY) {
- oos.reset();
- resetCounter = 0;
- }
-
- } catch (IOException ex) {
- fail(ex.getMessage());
- }
- }
- long end = System.nanoTime();
- return (end - start) / (1.0d * loopLen);
+ for (int i = 0; i < 3; i++) {
+ doLoop(builder, LOOP_LEN);
+ noos.reset();
}
-
- @Test
- public void testPerformance() {
- if (EnvUtilForTests.isLinux()) {
- return;
- }
- TrivialLoggingEventBuilder builder = new TrivialLoggingEventBuilder();
-
- for (int i = 0; i < 3; i++) {
- doLoop(builder, LOOP_LEN);
- noos.reset();
- }
- double rt = doLoop(builder, LOOP_LEN);
- System.out.println("average time per logging event " + rt + " nanoseconds");
-
- long averageSize = (long) (noos.size() / (LOOP_LEN));
- System.out.println("noos size " + noos.size() + " average size=" + averageSize);
- double averageSizeLimit = 62.1;
-
- assertTrue("average size " + averageSize + " should be less than " + averageSizeLimit, averageSizeLimit > averageSize);
-
- // the reference was computed on Orion (Ceki's computer)
- long referencePerf = 5000;
- BogoPerf.assertDuration(rt, referencePerf, CoreConstants.REFERENCE_BIPS);
+ double rt = doLoop(builder, LOOP_LEN);
+ System.out
+ .println("average time per logging event " + rt + " nanoseconds");
+
+ long averageSize = (long) (noos.size() / (LOOP_LEN));
+ System.out.println("noos size " + noos.size() + " average size="
+ + averageSize);
+ double averageSizeLimit = 62.1;
+
+ assertTrue("average size " + averageSize + " should be less than "
+ + averageSizeLimit, averageSizeLimit > averageSize);
+
+ // the reference was computed on Orion (Ceki's computer)
+ long referencePerf = 5000;
+ BogoPerf.assertDuration(rt, referencePerf, CoreConstants.REFERENCE_BIPS);
+ }
+
+ @Test
+ public void testPerformanceWithParameters() {
+ if (EnvUtilForTests.isLinux()) {
+ return;
}
+ LoggingEventWithParametersBuilder builder = new LoggingEventWithParametersBuilder();
- @Test
- public void testPerformanceWithParameters() {
- if (EnvUtilForTests.isLinux()) {
- return;
- }
- LoggingEventWithParametersBuilder builder = new LoggingEventWithParametersBuilder();
-
- // warm up
- for (int i = 0; i < 3; i++) {
- doLoop(builder, LOOP_LEN);
- noos.reset();
- }
- double rt = doLoop(builder, LOOP_LEN);
- long averageSize = (long) (noos.size() / (LOOP_LEN));
+ // warm up
+ for (int i = 0; i < 3; i++) {
+ doLoop(builder, LOOP_LEN);
+ noos.reset();
+ }
+ double rt = doLoop(builder, LOOP_LEN);
+ long averageSize = (long) (noos.size() / (LOOP_LEN));
- System.out.println("noos size " + noos.size() + " average size=" + averageSize);
+ System.out.println("noos size " + noos.size() + " average size="
+ + averageSize);
- double averageSizeLimit = 160;
- assertTrue("averageSize " + averageSize + " should be less than " + averageSizeLimit, averageSizeLimit > averageSize);
+ double averageSizeLimit = 160;
+ assertTrue("averageSize " + averageSize + " should be less than "
+ + averageSizeLimit, averageSizeLimit > averageSize);
- // the reference was computed on Orion (Ceki's computer)
- long referencePerf = 7000;
- BogoPerf.assertDuration(rt, referencePerf, CoreConstants.REFERENCE_BIPS);
- }
+ // the reference was computed on Orion (Ceki's computer)
+ long referencePerf = 7000;
+ BogoPerf.assertDuration(rt, referencePerf, CoreConstants.REFERENCE_BIPS);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggingEventSerializationTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggingEventSerializationTest.java
index 3167538..ba6cad1 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggingEventSerializationTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggingEventSerializationTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -38,174 +38,179 @@ import ch.qos.logback.core.spi.PreSerializationTransformer;
public class LoggingEventSerializationTest {
- LoggerContext lc;
- Logger logger;
-
- ByteArrayOutputStream bos;
- ObjectOutputStream oos;
- ObjectInputStream inputStream;
- PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer();
-
- @Before
- public void setUp() throws Exception {
- lc = new LoggerContext();
- lc.setName("testContext");
- logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
- // create the byte output stream
- bos = new ByteArrayOutputStream();
- oos = new ObjectOutputStream(bos);
- }
-
- @After
- public void tearDown() throws Exception {
- lc = null;
- logger = null;
- oos.close();
- }
-
- @Test
- public void smoke() throws Exception {
- ILoggingEvent event = createLoggingEvent();
- ILoggingEvent remoteEvent = writeAndRead(event);
- checkForEquality(event, remoteEvent);
- }
-
- @Test
- public void context() throws Exception {
- lc.putProperty("testKey", "testValue");
- ILoggingEvent event = createLoggingEvent();
- ILoggingEvent remoteEvent = writeAndRead(event);
- checkForEquality(event, remoteEvent);
-
- assertNotNull(remoteEvent.getLoggerName());
- assertEquals(Logger.ROOT_LOGGER_NAME, remoteEvent.getLoggerName());
-
- LoggerContextVO loggerContextRemoteView = remoteEvent.getLoggerContextVO();
- assertNotNull(loggerContextRemoteView);
- assertEquals("testContext", loggerContextRemoteView.getName());
- Map<String, String> props = loggerContextRemoteView.getPropertyMap();
- assertNotNull(props);
- assertEquals("testValue", props.get("testKey"));
- }
-
- @Test
- public void MDC() throws Exception {
- MDC.put("key", "testValue");
- ILoggingEvent event = createLoggingEvent();
- ILoggingEvent remoteEvent = writeAndRead(event);
- checkForEquality(event, remoteEvent);
- Map<String, String> MDCPropertyMap = remoteEvent.getMDCPropertyMap();
- assertEquals("testValue", MDCPropertyMap.get("key"));
- }
-
- @Test
- public void updatedMDC() throws Exception {
- MDC.put("key", "testValue");
- ILoggingEvent event1 = createLoggingEvent();
- Serializable s1 = pst.transform(event1);
- oos.writeObject(s1);
-
- MDC.put("key", "updatedTestValue");
- ILoggingEvent event2 = createLoggingEvent();
- Serializable s2 = pst.transform(event2);
- oos.writeObject(s2);
-
- // create the input stream based on the ouput stream
- ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
- inputStream = new ObjectInputStream(bis);
-
- // skip over one object
- inputStream.readObject();
- ILoggingEvent remoteEvent2 = (ILoggingEvent) inputStream.readObject();
-
- // We observe the second logging event. It should provide us with
- // the updated MDC property.
- Map<String, String> MDCPropertyMap = remoteEvent2.getMDCPropertyMap();
- assertEquals("updatedTestValue", MDCPropertyMap.get("key"));
- }
-
- @Test
- public void nonSerializableParameters() throws Exception {
- LoggingEvent event = createLoggingEvent();
- LuckyCharms lucky0 = new LuckyCharms(0);
- event.setArgumentArray(new Object[] { lucky0, null });
- ILoggingEvent remoteEvent = writeAndRead(event);
- checkForEquality(event, remoteEvent);
-
- Object[] aa = remoteEvent.getArgumentArray();
- assertNotNull(aa);
- assertEquals(2, aa.length);
- assertEquals("LC(0)", aa[0]);
- assertNull(aa[1]);
- }
-
- @Test
- public void _Throwable() throws Exception {
- LoggingEvent event = createLoggingEvent();
- Throwable throwable = new Throwable("just testing");
- ThrowableProxy tp = new ThrowableProxy(throwable);
- event.setThrowableProxy(tp);
- ILoggingEvent remoteEvent = writeAndRead(event);
- checkForEquality(event, remoteEvent);
- }
-
- @Test
- public void extendendeThrowable() throws Exception {
- LoggingEvent event = createLoggingEvent();
- Throwable throwable = new Throwable("just testing");
- ThrowableProxy tp = new ThrowableProxy(throwable);
- event.setThrowableProxy(tp);
- tp.calculatePackagingData();
-
- ILoggingEvent remoteEvent = writeAndRead(event);
- checkForEquality(event, remoteEvent);
- }
-
- @Test
- public void serializeLargeArgs() throws Exception {
-
- StringBuilder buffer = new StringBuilder();
- for (int i = 0; i < 100000; i++) {
- buffer.append("X");
- }
- String largeString = buffer.toString();
- Object[] argArray = new Object[] { new LuckyCharms(2), largeString };
-
- LoggingEvent event = createLoggingEvent();
- event.setArgumentArray(argArray);
-
- ILoggingEvent remoteEvent = writeAndRead(event);
- checkForEquality(event, remoteEvent);
- Object[] aa = remoteEvent.getArgumentArray();
- assertNotNull(aa);
- assertEquals(2, aa.length);
- String stringBack = (String) aa[1];
- assertEquals(largeString, stringBack);
- }
-
- private LoggingEvent createLoggingEvent() {
- return new LoggingEvent(this.getClass().getName(), logger, Level.DEBUG, "test message", null, null);
- }
-
- private void checkForEquality(ILoggingEvent original, ILoggingEvent afterSerialization) {
- assertEquals(original.getLevel(), afterSerialization.getLevel());
- assertEquals(original.getFormattedMessage(), afterSerialization.getFormattedMessage());
- assertEquals(original.getMessage(), afterSerialization.getMessage());
-
- System.out.println();
-
- ThrowableProxyVO witness = ThrowableProxyVO.build(original.getThrowableProxy());
- assertEquals(witness, afterSerialization.getThrowableProxy());
-
- }
-
- private ILoggingEvent writeAndRead(ILoggingEvent event) throws IOException, ClassNotFoundException {
- Serializable ser = pst.transform(event);
- oos.writeObject(ser);
- ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
- inputStream = new ObjectInputStream(bis);
-
- return (ILoggingEvent) inputStream.readObject();
+ LoggerContext lc;
+ Logger logger;
+
+ ByteArrayOutputStream bos;
+ ObjectOutputStream oos;
+ ObjectInputStream inputStream;
+ PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer();
+
+ @Before
+ public void setUp() throws Exception {
+ lc = new LoggerContext();
+ lc.setName("testContext");
+ logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
+ // create the byte output stream
+ bos = new ByteArrayOutputStream();
+ oos = new ObjectOutputStream(bos);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ lc = null;
+ logger = null;
+ oos.close();
+ }
+
+ @Test
+ public void smoke() throws Exception {
+ ILoggingEvent event = createLoggingEvent();
+ ILoggingEvent remoteEvent = writeAndRead(event);
+ checkForEquality(event, remoteEvent);
+ }
+
+ @Test
+ public void context() throws Exception {
+ lc.putProperty("testKey", "testValue");
+ ILoggingEvent event = createLoggingEvent();
+ ILoggingEvent remoteEvent = writeAndRead(event);
+ checkForEquality(event, remoteEvent);
+
+ assertNotNull(remoteEvent.getLoggerName());
+ assertEquals(Logger.ROOT_LOGGER_NAME, remoteEvent.getLoggerName());
+
+ LoggerContextVO loggerContextRemoteView = remoteEvent.getLoggerContextVO();
+ assertNotNull(loggerContextRemoteView);
+ assertEquals("testContext", loggerContextRemoteView.getName());
+ Map<String, String> props = loggerContextRemoteView.getPropertyMap();
+ assertNotNull(props);
+ assertEquals("testValue", props.get("testKey"));
+ }
+
+ @Test
+ public void MDC() throws Exception {
+ MDC.put("key", "testValue");
+ ILoggingEvent event = createLoggingEvent();
+ ILoggingEvent remoteEvent = writeAndRead(event);
+ checkForEquality(event, remoteEvent);
+ Map<String, String> MDCPropertyMap = remoteEvent.getMDCPropertyMap();
+ assertEquals("testValue", MDCPropertyMap.get("key"));
+ }
+
+ @Test
+ public void updatedMDC() throws Exception {
+ MDC.put("key", "testValue");
+ ILoggingEvent event1 = createLoggingEvent();
+ Serializable s1 = pst.transform(event1);
+ oos.writeObject(s1);
+
+ MDC.put("key", "updatedTestValue");
+ ILoggingEvent event2 = createLoggingEvent();
+ Serializable s2 = pst.transform(event2);
+ oos.writeObject(s2);
+
+ // create the input stream based on the ouput stream
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ inputStream = new ObjectInputStream(bis);
+
+ // skip over one object
+ inputStream.readObject();
+ ILoggingEvent remoteEvent2 = (ILoggingEvent) inputStream.readObject();
+
+ // We observe the second logging event. It should provide us with
+ // the updated MDC property.
+ Map<String, String> MDCPropertyMap = remoteEvent2.getMDCPropertyMap();
+ assertEquals("updatedTestValue", MDCPropertyMap.get("key"));
+ }
+
+ @Test
+ public void nonSerializableParameters() throws Exception {
+ LoggingEvent event = createLoggingEvent();
+ LuckyCharms lucky0 = new LuckyCharms(0);
+ event.setArgumentArray(new Object[] { lucky0, null });
+ ILoggingEvent remoteEvent = writeAndRead(event);
+ checkForEquality(event, remoteEvent);
+
+ Object[] aa = remoteEvent.getArgumentArray();
+ assertNotNull(aa);
+ assertEquals(2, aa.length);
+ assertEquals("LC(0)", aa[0]);
+ assertNull(aa[1]);
+ }
+
+ @Test
+ public void _Throwable() throws Exception {
+ LoggingEvent event = createLoggingEvent();
+ Throwable throwable = new Throwable("just testing");
+ ThrowableProxy tp = new ThrowableProxy(throwable);
+ event.setThrowableProxy(tp);
+ ILoggingEvent remoteEvent = writeAndRead(event);
+ checkForEquality(event, remoteEvent);
+ }
+
+ @Test
+ public void extendendeThrowable() throws Exception {
+ LoggingEvent event = createLoggingEvent();
+ Throwable throwable = new Throwable("just testing");
+ ThrowableProxy tp = new ThrowableProxy(throwable);
+ event.setThrowableProxy(tp);
+ tp.calculatePackagingData();
+
+ ILoggingEvent remoteEvent = writeAndRead(event);
+ checkForEquality(event, remoteEvent);
+ }
+
+ @Test
+ public void serializeLargeArgs() throws Exception {
+
+ StringBuilder buffer = new StringBuilder();
+ for (int i = 0; i < 100000; i++) {
+ buffer.append("X");
}
+ String largeString = buffer.toString();
+ Object[] argArray = new Object[] { new LuckyCharms(2), largeString };
+
+ LoggingEvent event = createLoggingEvent();
+ event.setArgumentArray(argArray);
+
+ ILoggingEvent remoteEvent = writeAndRead(event);
+ checkForEquality(event, remoteEvent);
+ Object[] aa = remoteEvent.getArgumentArray();
+ assertNotNull(aa);
+ assertEquals(2, aa.length);
+ String stringBack = (String) aa[1];
+ assertEquals(largeString, stringBack);
+ }
+
+ private LoggingEvent createLoggingEvent() {
+ return new LoggingEvent(this.getClass().getName(), logger,
+ Level.DEBUG, "test message", null, null);
+ }
+
+ private void checkForEquality(ILoggingEvent original,
+ ILoggingEvent afterSerialization) {
+ assertEquals(original.getLevel(), afterSerialization.getLevel());
+ assertEquals(original.getFormattedMessage(), afterSerialization
+ .getFormattedMessage());
+ assertEquals(original.getMessage(), afterSerialization.getMessage());
+
+ System.out.println();
+
+ ThrowableProxyVO witness = ThrowableProxyVO.build(original
+ .getThrowableProxy());
+ assertEquals(witness, afterSerialization.getThrowableProxy());
+
+ }
+
+ private ILoggingEvent writeAndRead(ILoggingEvent event) throws IOException,
+ ClassNotFoundException {
+ Serializable ser = pst.transform(event);
+ oos.writeObject(ser);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ inputStream = new ObjectInputStream(bis);
+
+ return (ILoggingEvent) inputStream.readObject();
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggingEventTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggingEventTest.java
index bcbc206..e8b3d70 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggingEventTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/LoggingEventTest.java
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
package ch.qos.logback.classic.spi;
import ch.qos.logback.classic.Level;
@@ -24,52 +11,55 @@ import static org.junit.Assert.assertEquals;
public class LoggingEventTest {
- LoggerContext loggerContext = new LoggerContext();
- Logger logger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
+ LoggerContext loggerContext = new LoggerContext();
+ Logger logger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
- @Before
- public void setUp() {
- }
+ @Before
+ public void setUp() {
+ }
- @Test
- public void testFormattingOneArg() {
- String message = "x={}";
- Throwable throwable = null;
- Object[] argArray = new Object[] { 12 };
- LoggingEvent event = new LoggingEvent("", logger, Level.INFO, message, throwable, argArray);
- assertNull(event.formattedMessage);
- assertEquals("x=12", event.getFormattedMessage());
- }
+ @Test
+ public void testFormattingOneArg() {
+ String message = "x={}";
+ Throwable throwable = null;
+ Object[] argArray = new Object[] {12};
- @Test
- public void testFormattingTwoArg() {
- String message = "{}-{}";
- Throwable throwable = null;
- Object[] argArray = new Object[] { 12, 13 };
- LoggingEvent event = new LoggingEvent("", logger, Level.INFO, message, throwable, argArray);
+ LoggingEvent event = new LoggingEvent("", logger, Level.INFO, message, throwable, argArray);
+ assertNull(event.formattedMessage);
+ assertEquals("x=12", event.getFormattedMessage());
+ }
- assertNull(event.formattedMessage);
- assertEquals("12-13", event.getFormattedMessage());
- }
- @Test
- public void testNoFormattingWithArgs() {
- String message = "testNoFormatting";
- Throwable throwable = null;
- Object[] argArray = new Object[] { 12, 13 };
- LoggingEvent event = new LoggingEvent("", logger, Level.INFO, message, throwable, argArray);
- assertNull(event.formattedMessage);
- assertEquals(message, event.getFormattedMessage());
- }
+ @Test
+ public void testFormattingTwoArg() {
+ String message = "{}-{}";
+ Throwable throwable = null;
+ Object[] argArray = new Object[] {12, 13};
+ LoggingEvent event = new LoggingEvent("", logger, Level.INFO, message, throwable, argArray);
- @Test
- public void testNoFormattingWithoutArgs() {
- String message = "testNoFormatting";
- Throwable throwable = null;
- Object[] argArray = null;
- LoggingEvent event = new LoggingEvent("", logger, Level.INFO, message, throwable, argArray);
- assertNull(event.formattedMessage);
- assertEquals(message, event.getFormattedMessage());
- }
+ assertNull(event.formattedMessage);
+ assertEquals("12-13", event.getFormattedMessage());
+ }
+
+
+ @Test
+ public void testNoFormattingWithArgs() {
+ String message = "testNoFormatting";
+ Throwable throwable = null;
+ Object[] argArray = new Object[] {12, 13};
+ LoggingEvent event = new LoggingEvent("", logger, Level.INFO, message, throwable, argArray);
+ assertNull(event.formattedMessage);
+ assertEquals(message, event.getFormattedMessage());
+ }
+
+ @Test
+ public void testNoFormattingWithoutArgs() {
+ String message = "testNoFormatting";
+ Throwable throwable = null;
+ Object[] argArray = null;
+ LoggingEvent event = new LoggingEvent("", logger, Level.INFO, message, throwable, argArray);
+ assertNull(event.formattedMessage);
+ assertEquals(message, event.getFormattedMessage());
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/LuckyCharms.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/LuckyCharms.java
index 51e600e..47740ea 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/LuckyCharms.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/LuckyCharms.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,14 +15,14 @@ package ch.qos.logback.classic.spi;
// non serializable object
public class LuckyCharms {
- int id;
-
- LuckyCharms(int id) {
- this.id = id;
- }
-
- @Override
- public String toString() {
- return "LC(" + id + ")";
- }
+ int id;
+
+ LuckyCharms(int id) {
+ this.id= id;
+ }
+
+ @Override
+ public String toString() {
+ return "LC("+id+")";
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/PackageTest.java
index c953f54..59efd02 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,7 +18,9 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ ContextListenerTest.class, CallerDataTest.class, LoggerComparatorTest.class, LoggingEventTest.class, LoggingEventSerializationTest.class,
- LoggingEventSerializationPerfTest.class, ThrowableProxyTest.class, PackagingDataCalculatorTest.class })
-public class PackageTest {
+ at SuiteClasses( { ContextListenerTest.class, CallerDataTest.class,
+ LoggerComparatorTest.class, LoggingEventTest.class, LoggingEventSerializationTest.class,
+ LoggingEventSerializationPerfTest.class, ThrowableProxyTest.class,
+ PackagingDataCalculatorTest.class })
+public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/PackagingDataCalculatorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/PackagingDataCalculatorTest.java
index 39701cf..e9fc075 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/PackagingDataCalculatorTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/PackagingDataCalculatorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,103 +20,107 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
-import org.junit.Ignore;
import org.junit.Test;
-import ch.qos.logback.classic.util.TestHelper;
+import ch.qos.logback.classic.util.TeztHelper;
import ch.qos.logback.core.util.SystemInfo;
public class PackagingDataCalculatorTest {
- public void verify(ThrowableProxy tp) {
- for (StackTraceElementProxy step : tp.getStackTraceElementProxyArray()) {
- if (step != null) {
- assertNotNull(step.getClassPackagingData());
- }
- }
+ public void verify(ThrowableProxy tp) {
+ for (StackTraceElementProxy step : tp.getStackTraceElementProxyArray()) {
+ if (step != null) {
+ assertNotNull(step.getClassPackagingData());
+ }
}
-
- @Test
- public void smoke() throws Exception {
- Throwable t = new Throwable("x");
- ThrowableProxy tp = new ThrowableProxy(t);
- PackagingDataCalculator pdc = tp.getPackagingDataCalculator();
- pdc.calculate(tp);
- verify(tp);
- tp.fullDump();
- }
-
- @Test
- public void nested() throws Exception {
- Throwable t = TestHelper.makeNestedException(3);
- ThrowableProxy tp = new ThrowableProxy(t);
+ }
+
+ @Test
+ public void smoke() throws Exception {
+ Throwable t = new Throwable("x");
+ ThrowableProxy tp = new ThrowableProxy(t);
+ PackagingDataCalculator pdc = tp.getPackagingDataCalculator();
+ pdc.calculate(tp);
+ verify(tp);
+ tp.fullDump();
+ }
+
+ @Test
+ public void nested() throws Exception {
+ Throwable t = TeztHelper.makeNestedException(3);
+ ThrowableProxy tp = new ThrowableProxy(t);
+ PackagingDataCalculator pdc = tp.getPackagingDataCalculator();
+ pdc.calculate(tp);
+ verify(tp);
+ }
+
+ public void doCalculateClassPackagingData(
+ boolean withClassPackagingCalculation) {
+ try {
+ throw new Exception("testing");
+ } catch (Throwable e) {
+ ThrowableProxy tp = new ThrowableProxy(e);
+ if (withClassPackagingCalculation) {
PackagingDataCalculator pdc = tp.getPackagingDataCalculator();
pdc.calculate(tp);
- verify(tp);
- }
-
- public void doCalculateClassPackagingData(boolean withClassPackagingCalculation) {
- try {
- throw new Exception("testing");
- } catch (Throwable e) {
- ThrowableProxy tp = new ThrowableProxy(e);
- if (withClassPackagingCalculation) {
- PackagingDataCalculator pdc = tp.getPackagingDataCalculator();
- pdc.calculate(tp);
- }
- }
+ }
}
+ }
- double loop(int len, boolean withClassPackagingCalculation) {
- long start = System.nanoTime();
- for (int i = 0; i < len; i++) {
- doCalculateClassPackagingData(withClassPackagingCalculation);
- }
- return (1.0 * System.nanoTime() - start) / len / 1000;
+ double loop(int len, boolean withClassPackagingCalculation) {
+ long start = System.nanoTime();
+ for (int i = 0; i < len; i++) {
+ doCalculateClassPackagingData(withClassPackagingCalculation);
}
+ return (1.0 * System.nanoTime() - start) / len / 1000;
+ }
- @Ignore
- @Test
- public void perfTest() {
- int len = 1000;
- loop(len, false);
- loop(len, true);
-
- double d0 = loop(len, false);
- System.out.println("without packaging info " + d0 + " microseconds");
+ @Test
+ public void perfTest() {
+ int len = 1000;
+ loop(len, false);
+ loop(len, true);
- double d1 = loop(len, true);
- System.out.println("with packaging info " + d1 + " microseconds");
+ double d0 = loop(len, false);
+ System.out.println("without packaging info " + d0 + " microseconds");
- int slackFactor = 8;
- if (!SystemInfo.getJavaVendor().contains("Sun")) {
- // be more lenient with other JDKs
- slackFactor = 15;
- }
- assertTrue("computing class packaging data (" + d1 + ") should have been less than " + slackFactor
- + " times the time it takes to process an exception " + (d0 * slackFactor), d0 * slackFactor > d1);
-
- }
-
- private ClassLoader makeBogusClassLoader() throws MalformedURLException {
- ClassLoader currentClassLoader = this.getClass().getClassLoader();
- return new BogusClassLoader(new URL[] {}, currentClassLoader);
- }
-
- @Test
- // Test http://jira.qos.ch/browse/LBCLASSIC-125
- public void noClassDefFoundError_LBCLASSIC_125Test() throws MalformedURLException {
- ClassLoader cl = (URLClassLoader) makeBogusClassLoader();
- Thread.currentThread().setContextClassLoader(cl);
- Throwable t = new Throwable("x");
- ThrowableProxy tp = new ThrowableProxy(t);
- StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
- StackTraceElement bogusSTE = new StackTraceElement("com.Bogus", "myMethod", "myFile", 12);
- stepArray[0] = new StackTraceElementProxy(bogusSTE);
- PackagingDataCalculator pdc = tp.getPackagingDataCalculator();
- // NoClassDefFoundError should be caught
- pdc.calculate(tp);
+ double d1 = loop(len, true);
+ System.out.println("with packaging info " + d1 + " microseconds");
+ int slackFactor = 8;
+ if (!SystemInfo.getJavaVendor().contains("Sun")) {
+ // be more lenient with other JDKs
+ slackFactor = 15;
}
+ assertTrue("computing class packaging data (" + d1
+ + ") should have been less than " + slackFactor
+ + " times the time it takes to process an exception "
+ + (d0 * slackFactor), d0 * slackFactor > d1);
+
+ }
+
+ private ClassLoader makeBogusClassLoader() throws MalformedURLException {
+ ClassLoader currentClassLoader = this.getClass().getClassLoader();
+ return new BogusClassLoader(new URL[] {},
+ currentClassLoader);
+ }
+
+ @Test
+ // Test http://jira.qos.ch/browse/LBCLASSIC-125
+ public void noClassDefFoundError_LBCLASSIC_125Test()
+ throws MalformedURLException {
+ ClassLoader cl = (URLClassLoader) makeBogusClassLoader();
+ Thread.currentThread().setContextClassLoader(cl);
+ Throwable t = new Throwable("x");
+ ThrowableProxy tp = new ThrowableProxy(t);
+ StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
+ StackTraceElement bogusSTE = new StackTraceElement("com.Bogus", "myMethod",
+ "myFile", 12);
+ stepArray[0] = new StackTraceElementProxy(bogusSTE);
+ PackagingDataCalculator pdc = tp.getPackagingDataCalculator();
+ // NoClassDefFoundError should be caught
+ pdc.calculate(tp);
+
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/PubLoggingEventVO.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/PubLoggingEventVO.java
index 8fb4384..d84e7cc 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/PubLoggingEventVO.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/PubLoggingEventVO.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,206 +31,209 @@ import ch.qos.logback.classic.Level;
*/
public class PubLoggingEventVO implements ILoggingEvent, Serializable {
- private static final long serialVersionUID = -3385765861078946218L;
+ private static final long serialVersionUID = -3385765861078946218L;
- private static final int NULL_ARGUMENT_ARRAY = -1;
- private static final String NULL_ARGUMENT_ARRAY_ELEMENT = "NULL_ARGUMENT_ARRAY_ELEMENT";
+ private static final int NULL_ARGUMENT_ARRAY = -1;
+ private static final String NULL_ARGUMENT_ARRAY_ELEMENT = "NULL_ARGUMENT_ARRAY_ELEMENT";
- public String threadName;
- public String loggerName;
- public LoggerContextVO loggerContextVO;
+ public String threadName;
+ public String loggerName;
+ public LoggerContextVO loggerContextVO;
- public transient Level level;
- public String message;
+ public transient Level level;
+ public String message;
- private transient String formattedMessage;
+ private transient String formattedMessage;
- public Object[] argumentArray;
+ public Object[] argumentArray;
- public IThrowableProxy throwableProxy;
- public StackTraceElement[] callerDataArray;
- public Marker marker;
- public Map<String, String> mdcPropertyMap;
- public long timeStamp;
+ public IThrowableProxy throwableProxy;
+ public StackTraceElement[] callerDataArray;
+ public Marker marker;
+ public Map<String, String> mdcPropertyMap;
+ public long timeStamp;
- public String getThreadName() {
- return threadName;
- }
-
- public LoggerContextVO getLoggerContextVO() {
- return loggerContextVO;
- }
-
- public String getLoggerName() {
- return loggerName;
- }
+ public String getThreadName() {
+ return threadName;
+ }
- public Level getLevel() {
- return level;
- }
+ public LoggerContextVO getLoggerContextVO() {
+ return loggerContextVO;
+ }
- public String getMessage() {
- return message;
- }
+ public String getLoggerName() {
+ return loggerName;
+ }
- public String getFormattedMessage() {
- if (formattedMessage != null) {
- return formattedMessage;
- }
+ public Level getLevel() {
+ return level;
+ }
- if (argumentArray != null) {
- formattedMessage = MessageFormatter.arrayFormat(message, argumentArray).getMessage();
- } else {
- formattedMessage = message;
- }
+ public String getMessage() {
+ return message;
+ }
- return formattedMessage;
+ public String getFormattedMessage() {
+ if (formattedMessage != null) {
+ return formattedMessage;
}
- public Object[] getArgumentArray() {
- return argumentArray;
+ if (argumentArray != null) {
+ formattedMessage = MessageFormatter.arrayFormat(message, argumentArray)
+ .getMessage();
+ } else {
+ formattedMessage = message;
}
- public IThrowableProxy getThrowableProxy() {
- return throwableProxy;
- }
+ return formattedMessage;
+ }
- public StackTraceElement[] getCallerData() {
- return callerDataArray;
- }
+ public Object[] getArgumentArray() {
+ return argumentArray;
+ }
- public boolean hasCallerData() {
- return callerDataArray != null;
- }
+ public IThrowableProxy getThrowableProxy() {
+ return throwableProxy;
+ }
- public Marker getMarker() {
- return marker;
- }
+ public StackTraceElement[] getCallerData() {
+ return callerDataArray;
+ }
- public long getTimeStamp() {
- return timeStamp;
- }
+ public boolean hasCallerData() {
+ return callerDataArray != null;
+ }
- public long getContextBirthTime() {
- return loggerContextVO.getBirthTime();
- }
+ public Marker getMarker() {
+ return marker;
+ }
- public LoggerContextVO getContextLoggerRemoteView() {
- return loggerContextVO;
- }
+ public long getTimeStamp() {
+ return timeStamp;
+ }
- public Map<String, String> getMDCPropertyMap() {
- return mdcPropertyMap;
- }
+ public long getContextBirthTime() {
+ return loggerContextVO.getBirthTime();
+ }
- public Map<String, String> getMdc() {
- return mdcPropertyMap;
- }
+ public LoggerContextVO getContextLoggerRemoteView() {
+ return loggerContextVO;
+ }
- public void prepareForDeferredProcessing() {
- }
+ public Map<String, String> getMDCPropertyMap() {
+ return mdcPropertyMap;
+ }
- private void writeObject(ObjectOutputStream out) throws IOException {
- out.defaultWriteObject();
- out.writeInt(level.levelInt);
- if (argumentArray != null) {
- int len = argumentArray.length;
- out.writeInt(len);
- for (int i = 0; i < argumentArray.length; i++) {
- if (argumentArray[i] != null) {
- out.writeObject(argumentArray[i].toString());
- } else {
- out.writeObject(NULL_ARGUMENT_ARRAY_ELEMENT);
- }
- }
- } else {
- out.writeInt(NULL_ARGUMENT_ARRAY);
- }
+ public Map<String, String> getMdc() {
+ return mdcPropertyMap;
+ }
- }
+ public void prepareForDeferredProcessing() {
+ }
- private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
- in.defaultReadObject();
- int levelInt = in.readInt();
- level = Level.toLevel(levelInt);
-
- int argArrayLen = in.readInt();
- if (argArrayLen != NULL_ARGUMENT_ARRAY) {
- argumentArray = new String[argArrayLen];
- for (int i = 0; i < argArrayLen; i++) {
- Object val = in.readObject();
- if (!NULL_ARGUMENT_ARRAY_ELEMENT.equals(val)) {
- argumentArray[i] = val;
- }
- }
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ out.writeInt(level.levelInt);
+ if (argumentArray != null) {
+ int len = argumentArray.length;
+ out.writeInt(len);
+ for (int i = 0; i < argumentArray.length; i++) {
+ if (argumentArray[i] != null) {
+ out.writeObject(argumentArray[i].toString());
+ } else {
+ out.writeObject(NULL_ARGUMENT_ARRAY_ELEMENT);
}
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((message == null) ? 0 : message.hashCode());
- result = prime * result + ((threadName == null) ? 0 : threadName.hashCode());
- result = prime * result + (int) (timeStamp ^ (timeStamp >>> 32));
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final PubLoggingEventVO other = (PubLoggingEventVO) obj;
- if (message == null) {
- if (other.message != null)
- return false;
- } else if (!message.equals(other.message))
- return false;
-
- if (loggerName == null) {
- if (other.loggerName != null)
- return false;
- } else if (!loggerName.equals(other.loggerName))
- return false;
-
- if (threadName == null) {
- if (other.threadName != null)
- return false;
- } else if (!threadName.equals(other.threadName))
- return false;
- if (timeStamp != other.timeStamp)
- return false;
-
- if (marker == null) {
- if (other.marker != null)
- return false;
- } else if (!marker.equals(other.marker))
- return false;
-
- if (mdcPropertyMap == null) {
- if (other.mdcPropertyMap != null)
- return false;
- } else if (!mdcPropertyMap.equals(other.mdcPropertyMap))
- return false;
- return true;
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(timeStamp);
- sb.append(" ");
- sb.append(level);
- sb.append(" [");
- sb.append(threadName);
- sb.append("] ");
- sb.append(loggerName);
- sb.append(" - ");
- sb.append(getFormattedMessage());
- return sb.toString();
- }
+ }
+ } else {
+ out.writeInt(NULL_ARGUMENT_ARRAY);
+ }
+
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException,
+ ClassNotFoundException {
+ in.defaultReadObject();
+ int levelInt = in.readInt();
+ level = Level.toLevel(levelInt);
+
+ int argArrayLen = in.readInt();
+ if (argArrayLen != NULL_ARGUMENT_ARRAY) {
+ argumentArray = new String[argArrayLen];
+ for (int i = 0; i < argArrayLen; i++) {
+ Object val = in.readObject();
+ if (!NULL_ARGUMENT_ARRAY_ELEMENT.equals(val)) {
+ argumentArray[i] = val;
+ }
+ }
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((message == null) ? 0 : message.hashCode());
+ result = prime * result
+ + ((threadName == null) ? 0 : threadName.hashCode());
+ result = prime * result + (int) (timeStamp ^ (timeStamp >>> 32));
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final PubLoggingEventVO other = (PubLoggingEventVO) obj;
+ if (message == null) {
+ if (other.message != null)
+ return false;
+ } else if (!message.equals(other.message))
+ return false;
+
+ if (loggerName == null) {
+ if (other.loggerName != null)
+ return false;
+ } else if (!loggerName.equals(other.loggerName))
+ return false;
+
+ if (threadName == null) {
+ if (other.threadName != null)
+ return false;
+ } else if (!threadName.equals(other.threadName))
+ return false;
+ if (timeStamp != other.timeStamp)
+ return false;
+
+ if (marker == null) {
+ if (other.marker != null)
+ return false;
+ } else if (!marker.equals(other.marker))
+ return false;
+
+ if (mdcPropertyMap == null) {
+ if (other.mdcPropertyMap != null)
+ return false;
+ } else if (!mdcPropertyMap.equals(other.mdcPropertyMap))
+ return false;
+ return true;
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(timeStamp);
+ sb.append(" ");
+ sb.append(level);
+ sb.append(" [");
+ sb.append(threadName);
+ sb.append("] ");
+ sb.append(loggerName);
+ sb.append(" - ");
+ sb.append(getFormattedMessage());
+ return sb.toString();
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/ThrowableProxyTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/ThrowableProxyTest.java
index dba9efd..bd3f40d 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/ThrowableProxyTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/ThrowableProxyTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,7 +13,7 @@
*/
package ch.qos.logback.classic.spi;
-import static ch.qos.logback.classic.util.TestHelper.addSuppressed;
+import static ch.qos.logback.classic.util.TeztHelper.addSuppressed;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeNotNull;
import static org.junit.Assume.assumeTrue;
@@ -23,160 +23,160 @@ import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import ch.qos.logback.classic.util.TestHelper;
+import ch.qos.logback.classic.util.TeztHelper;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class ThrowableProxyTest {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
- @Before
- public void setUp() throws Exception {
- }
+ @Before
+ public void setUp() throws Exception {
+ }
- @After
- public void tearDown() throws Exception {
- }
+ @After
+ public void tearDown() throws Exception {
+ }
- public void verify(Throwable t) {
- t.printStackTrace(pw);
+ public void verify(Throwable t) {
+ t.printStackTrace(pw);
- IThrowableProxy tp = new ThrowableProxy(t);
+ IThrowableProxy tp = new ThrowableProxy(t);
- String result = ThrowableProxyUtil.asString(tp);
- result = result.replace("common frames omitted", "more");
+ String result = ThrowableProxyUtil.asString(tp);
+ result = result.replace("common frames omitted", "more");
- String expected = sw.toString();
+ String expected = sw.toString();
- System.out.println("========expected");
- System.out.println(expected);
+ System.out.println("========expected");
+ System.out.println(expected);
- System.out.println("========result");
- System.out.println(result);
+ System.out.println("========result");
+ System.out.println(result);
- assertEquals(expected, result);
- }
+ assertEquals(expected, result);
+ }
- @Test
- public void smoke() {
- Exception e = new Exception("smoke");
- verify(e);
- }
+ @Test
+ public void smoke() {
+ Exception e = new Exception("smoke");
+ verify(e);
+ }
- @Test
- public void nested() {
- Exception w = null;
- try {
- someMethod();
- } catch (Exception e) {
- w = new Exception("wrapping", e);
- }
- verify(w);
+ @Test
+ public void nested() {
+ Exception w = null;
+ try {
+ someMethod();
+ } catch (Exception e) {
+ w = new Exception("wrapping", e);
}
-
- @Test
- public void suppressed() throws InvocationTargetException, IllegalAccessException {
- assumeTrue(TestHelper.suppressedSupported()); // only execute on Java 7, would work anyway but doesn't make
- // sense.
- Exception ex = null;
- try {
- someMethod();
- } catch (Exception e) {
- Exception fooException = new Exception("Foo");
- Exception barException = new Exception("Bar");
- addSuppressed(e, fooException);
- addSuppressed(e, barException);
- ex = e;
- }
- verify(ex);
+ verify(w);
+ }
+
+ @Test
+ public void suppressed() throws InvocationTargetException, IllegalAccessException
+ {
+ assumeTrue(TeztHelper.suppressedSupported()); // only execute on Java 7, would work anyway but doesn't make sense.
+ Exception ex = null;
+ try {
+ someMethod();
+ } catch (Exception e) {
+ Exception fooException = new Exception("Foo");
+ Exception barException = new Exception("Bar");
+ addSuppressed(e, fooException);
+ addSuppressed(e, barException);
+ ex = e;
}
-
- @Test
- public void suppressedWithCause() throws InvocationTargetException, IllegalAccessException {
- assumeTrue(TestHelper.suppressedSupported()); // only execute on Java 7, would work anyway but doesn't make
- // sense.
- Exception ex = null;
- try {
- someMethod();
- } catch (Exception e) {
- ex = new Exception("Wrapper", e);
- Exception fooException = new Exception("Foo");
- Exception barException = new Exception("Bar");
- addSuppressed(ex, fooException);
- addSuppressed(e, barException);
- }
- verify(ex);
+ verify(ex);
+ }
+
+ @Test
+ public void suppressedWithCause() throws InvocationTargetException, IllegalAccessException
+ {
+ assumeTrue(TeztHelper.suppressedSupported()); // only execute on Java 7, would work anyway but doesn't make sense.
+ Exception ex = null;
+ try {
+ someMethod();
+ } catch (Exception e) {
+ ex=new Exception("Wrapper", e);
+ Exception fooException = new Exception("Foo");
+ Exception barException = new Exception("Bar");
+ addSuppressed(ex, fooException);
+ addSuppressed(e, barException);
}
-
- @Test
- public void suppressedWithSuppressed() throws Exception {
- assumeTrue(TestHelper.suppressedSupported()); // only execute on Java 7, would work anyway but doesn't make
- // sense.
- Exception ex = null;
- try {
- someMethod();
- } catch (Exception e) {
- ex = new Exception("Wrapper", e);
- Exception fooException = new Exception("Foo");
- Exception barException = new Exception("Bar");
- addSuppressed(barException, fooException);
- addSuppressed(e, barException);
- }
- verify(ex);
+ verify(ex);
+ }
+
+ @Test
+ public void suppressedWithSuppressed() throws Exception
+ {
+ assumeTrue(TeztHelper.suppressedSupported()); // only execute on Java 7, would work anyway but doesn't make sense.
+ Exception ex = null;
+ try {
+ someMethod();
+ } catch (Exception e) {
+ ex=new Exception("Wrapper", e);
+ Exception fooException = new Exception("Foo");
+ Exception barException = new Exception("Bar");
+ addSuppressed(barException, fooException);
+ addSuppressed(e, barException);
}
-
- // see also http://jira.qos.ch/browse/LBCLASSIC-216
- @Test
- public void nullSTE() {
- Throwable t = new Exception("someMethodWithNullException") {
- @Override
- public StackTraceElement[] getStackTrace() {
- return null;
- }
- };
- // we can't test output as Throwable.printStackTrace method uses
- // the private getOurStackTrace method instead of getStackTrace
-
- // tests ThrowableProxyUtil.steArrayToStepArray
- new ThrowableProxy(t);
-
- // tests ThrowableProxyUtil.findNumberOfCommonFrames
- Exception top = new Exception("top", t);
- new ThrowableProxy(top);
+ verify(ex);
+ }
+
+ // see also http://jira.qos.ch/browse/LBCLASSIC-216
+ @Test
+ public void nullSTE() {
+ Throwable t = new Exception("someMethodWithNullException") {
+ @Override
+ public StackTraceElement[] getStackTrace() {
+ return null;
+ }
+ };
+ // we can't test output as Throwable.printStackTrace method uses
+ // the private getOurStackTrace method instead of getStackTrace
+
+ // tests ThrowableProxyUtil.steArrayToStepArray
+ new ThrowableProxy(t);
+
+ // tests ThrowableProxyUtil.findNumberOfCommonFrames
+ Exception top = new Exception("top", t);
+ new ThrowableProxy(top);
+ }
+
+ @Test
+ public void multiNested() {
+ Exception w = null;
+ try {
+ someOtherMethod();
+ } catch (Exception e) {
+ w = new Exception("wrapping", e);
}
-
- @Test
- public void multiNested() {
- Exception w = null;
- try {
- someOtherMethod();
- } catch (Exception e) {
- w = new Exception("wrapping", e);
- }
- verify(w);
- }
-
- void someMethod() throws Exception {
- throw new Exception("someMethod");
- }
-
- void someMethodWithNullException() throws Exception {
- throw new Exception("someMethodWithNullException") {
- @Override
- public StackTraceElement[] getStackTrace() {
- return null;
- }
- };
- }
-
- void someOtherMethod() throws Exception {
- try {
- someMethod();
- } catch (Exception e) {
- throw new Exception("someOtherMethod", e);
- }
+ verify(w);
+ }
+
+ void someMethod() throws Exception {
+ throw new Exception("someMethod");
+ }
+
+ void someMethodWithNullException() throws Exception {
+ throw new Exception("someMethodWithNullException") {
+ @Override
+ public StackTraceElement[] getStackTrace() {
+ return null;
+ }
+ };
+ }
+
+ void someOtherMethod() throws Exception {
+ try {
+ someMethod();
+ } catch (Exception e) {
+ throw new Exception("someOtherMethod", e);
}
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/special/CPDCSpecialImpl.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/special/CPDCSpecialImpl.java
index 57ca4cc..8693f07 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/special/CPDCSpecialImpl.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/special/CPDCSpecialImpl.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,27 +18,28 @@ import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.PackagingDataCalculator;
import ch.qos.logback.classic.spi.ThrowableProxy;
-public class CPDCSpecialImpl implements CPDCSpecial {
-
- Throwable throwable;
- IThrowableProxy throwableProxy;
-
- public void doTest() {
- nesting();
- }
- private void nesting() {
- throwable = new Throwable("x");
- throwableProxy = new ThrowableProxy(throwable);
- PackagingDataCalculator pdc = new PackagingDataCalculator();
- pdc.calculate(throwableProxy);
- }
-
- public Throwable getThrowable() {
- return throwable;
- }
+public class CPDCSpecialImpl implements CPDCSpecial {
- public IThrowableProxy getThrowableProxy() {
- return throwableProxy;
- }
+
+ Throwable throwable;
+ IThrowableProxy throwableProxy;
+
+ public void doTest() {
+ nesting();
+ }
+
+ private void nesting() {
+ throwable = new Throwable("x");
+ throwableProxy = new ThrowableProxy(throwable);
+ PackagingDataCalculator pdc = new PackagingDataCalculator();
+ pdc.calculate(throwableProxy);
+ }
+
+ public Throwable getThrowable() {
+ return throwable;
+ }
+ public IThrowableProxy getThrowableProxy() {
+ return throwableProxy;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/testUtil/SampleConverter.java b/logback-classic/src/test/java/ch/qos/logback/classic/testUtil/SampleConverter.java
index 29180e2..0783561 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/testUtil/SampleConverter.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/testUtil/SampleConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,11 +18,11 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
public class SampleConverter extends ClassicConverter {
- static public final String SAMPLE_STR = "sample";
-
- @Override
- public String convert(ILoggingEvent event) {
- return SAMPLE_STR;
- }
+ static public final String SAMPLE_STR = "sample";
+
+ @Override
+ public String convert(ILoggingEvent event) {
+ return SAMPLE_STR;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/DebugUsersTurboFilter.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/DebugUsersTurboFilter.java
index 786def7..75c810e 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/DebugUsersTurboFilter.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/DebugUsersTurboFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -37,27 +37,27 @@ import ch.qos.logback.core.spi.FilterReply;
*/
public class DebugUsersTurboFilter extends TurboFilter {
- List<String> userList = new ArrayList<String>();
-
- @Override
- public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
- if (!level.equals(Level.DEBUG)) {
- return FilterReply.NEUTRAL;
- }
- String user = MDC.get(ClassicConstants.USER_MDC_KEY);
- if (user != null && userList.contains(user)) {
- return FilterReply.ACCEPT;
- }
- return FilterReply.NEUTRAL;
- }
-
- public void addUser(String user) {
- userList.add(user);
- }
-
- // test in BasicJoranTest only, to be removed asap.
- public List<String> getUsers() {
- return userList;
+ List<String> userList = new ArrayList<String>();
+
+ @Override
+ public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
+ if (!level.equals(Level.DEBUG)) {
+ return FilterReply.NEUTRAL;
+ }
+ String user = MDC.get(ClassicConstants.USER_MDC_KEY);
+ if (user != null && userList.contains(user)) {
+ return FilterReply.ACCEPT;
}
+ return FilterReply.NEUTRAL;
+ }
+
+ public void addUser(String user) {
+ userList.add(user);
+ }
+
+ //test in BasicJoranTest only, to be removed asap.
+ public List<String> getUsers() {
+ return userList;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/DuplicateMessageFilterTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/DuplicateMessageFilterTest.java
index 32242d9..86fa230 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/DuplicateMessageFilterTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/DuplicateMessageFilterTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,57 +21,69 @@ import ch.qos.logback.core.spi.FilterReply;
public class DuplicateMessageFilterTest {
- @Test
- public void smoke() {
- DuplicateMessageFilter dmf = new DuplicateMessageFilter();
- dmf.setAllowedRepetitions(0);
- dmf.start();
- assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "x", null, null));
- assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "y", null, null));
- assertEquals(FilterReply.DENY, dmf.decide(null, null, null, "x", null, null));
- assertEquals(FilterReply.DENY, dmf.decide(null, null, null, "y", null, null));
- }
+ @Test
+ public void smoke() {
+ DuplicateMessageFilter dmf = new DuplicateMessageFilter();
+ dmf.setAllowedRepetitions(0);
+ dmf.start();
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "x", null,
+ null));
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "y", null,
+ null));
+ assertEquals(FilterReply.DENY, dmf
+ .decide(null, null, null, "x", null, null));
+ assertEquals(FilterReply.DENY, dmf
+ .decide(null, null, null, "y", null, null));
+ }
- @Test
- public void memoryLoss() {
- DuplicateMessageFilter dmf = new DuplicateMessageFilter();
- dmf.setAllowedRepetitions(1);
- dmf.setCacheSize(1);
- dmf.start();
- assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "a", null, null));
- assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "b", null, null));
- assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "a", null, null));
- }
+ @Test
+ public void memoryLoss() {
+ DuplicateMessageFilter dmf = new DuplicateMessageFilter();
+ dmf.setAllowedRepetitions(1);
+ dmf.setCacheSize(1);
+ dmf.start();
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "a", null,
+ null));
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "b", null,
+ null));
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "a", null,
+ null));
+ }
- @Test
- public void many() {
- DuplicateMessageFilter dmf = new DuplicateMessageFilter();
- dmf.setAllowedRepetitions(0);
- int cacheSize = 10;
- int margin = 2;
- dmf.setCacheSize(cacheSize);
- dmf.start();
- for (int i = 0; i < cacheSize + margin; i++) {
- assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "a" + i, null, null));
- }
- for (int i = cacheSize - 1; i >= margin; i--) {
- assertEquals(FilterReply.DENY, dmf.decide(null, null, null, "a" + i, null, null));
- }
- for (int i = margin - 1; i >= 0; i--) {
- assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "a" + i, null, null));
- }
+ @Test
+ public void many() {
+ DuplicateMessageFilter dmf = new DuplicateMessageFilter();
+ dmf.setAllowedRepetitions(0);
+ int cacheSize = 10;
+ int margin = 2;
+ dmf.setCacheSize(cacheSize);
+ dmf.start();
+ for (int i = 0; i < cacheSize + margin; i++) {
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "a" + i,
+ null, null));
}
-
- @Test
- // isXXXEnabled invokes decide with a null format
- // http://jira.qos.ch/browse/LBCLASSIC-134
- public void nullFormat() {
- DuplicateMessageFilter dmf = new DuplicateMessageFilter();
- dmf.setAllowedRepetitions(0);
- dmf.setCacheSize(10);
- dmf.start();
- assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, null, null, null));
- assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, null, null, null));
+ for (int i = cacheSize - 1; i >= margin; i--) {
+ assertEquals(FilterReply.DENY, dmf.decide(null, null, null, "a" + i,
+ null, null));
}
+ for (int i = margin - 1; i >= 0; i--) {
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "a" + i,
+ null, null));
+ }
+ }
+
+ @Test
+ // isXXXEnabled invokes decide with a null format
+ // http://jira.qos.ch/browse/LBCLASSIC-134
+ public void nullFormat() {
+ DuplicateMessageFilter dmf = new DuplicateMessageFilter();
+ dmf.setAllowedRepetitions(0);
+ dmf.setCacheSize(10);
+ dmf.start();
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, null, null,
+ null));
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, null, null,
+ null));
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/LRUMessageCacheTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/LRUMessageCacheTest.java
index f7e6e18..2f2b4d3 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/LRUMessageCacheTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/LRUMessageCacheTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,23 +19,23 @@ import org.junit.Test;
public class LRUMessageCacheTest {
- @Test
- public void testEldestEntriesRemoval() {
- final LRUMessageCache cache = new LRUMessageCache(2);
- Assert.assertEquals(0, cache.getMessageCountAndThenIncrement("0"));
- Assert.assertEquals(1, cache.getMessageCountAndThenIncrement("0"));
- Assert.assertEquals(0, cache.getMessageCountAndThenIncrement("1"));
- Assert.assertEquals(1, cache.getMessageCountAndThenIncrement("1"));
- // 0 entry should have been removed.
- Assert.assertEquals(0, cache.getMessageCountAndThenIncrement("2"));
- // So it is expected a returned value of 0 instead of 2.
- // 1 entry should have been removed.
- Assert.assertEquals(0, cache.getMessageCountAndThenIncrement("0"));
- // So it is expected a returned value of 0 instead of 2.
- // 2 entry should have been removed.
- Assert.assertEquals(0, cache.getMessageCountAndThenIncrement("1"));
- // So it is expected a returned value of 0 instead of 2.
- Assert.assertEquals(0, cache.getMessageCountAndThenIncrement("2"));
- }
+ @Test
+ public void testEldestEntriesRemoval() {
+ final LRUMessageCache cache = new LRUMessageCache(2);
+ Assert.assertEquals(0, cache.getMessageCountAndThenIncrement("0"));
+ Assert.assertEquals(1, cache.getMessageCountAndThenIncrement("0"));
+ Assert.assertEquals(0, cache.getMessageCountAndThenIncrement("1"));
+ Assert.assertEquals(1, cache.getMessageCountAndThenIncrement("1"));
+ // 0 entry should have been removed.
+ Assert.assertEquals(0, cache.getMessageCountAndThenIncrement("2"));
+ // So it is expected a returned value of 0 instead of 2.
+ // 1 entry should have been removed.
+ Assert.assertEquals(0, cache.getMessageCountAndThenIncrement("0"));
+ // So it is expected a returned value of 0 instead of 2.
+ // 2 entry should have been removed.
+ Assert.assertEquals(0, cache.getMessageCountAndThenIncrement("1"));
+ // So it is expected a returned value of 0 instead of 2.
+ Assert.assertEquals(0, cache.getMessageCountAndThenIncrement("2"));
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/MarkerFilterTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/MarkerFilterTest.java
index d073cb0..d05be40 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/MarkerFilterTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/MarkerFilterTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,51 +25,53 @@ import ch.qos.logback.core.spi.FilterReply;
public class MarkerFilterTest {
- static String TOTO = "TOTO";
- static String COMPOSITE = "COMPOSITE";
-
- Marker totoMarker = MarkerFactory.getMarker(TOTO);
-
- @Test
- public void testNoMarker() {
- MarkerFilter mkt = new MarkerFilter();
- mkt.start();
- assertFalse(mkt.isStarted());
- assertEquals(FilterReply.NEUTRAL, mkt.decide(totoMarker, null, null, null, null, null));
- assertEquals(FilterReply.NEUTRAL, mkt.decide(null, null, null, null, null, null));
-
- }
-
- @Test
- public void testBasic() {
- MarkerFilter mkt = new MarkerFilter();
- mkt.setMarker(TOTO);
- mkt.setOnMatch("ACCEPT");
- mkt.setOnMismatch("DENY");
-
- mkt.start();
- assertTrue(mkt.isStarted());
- assertEquals(FilterReply.DENY, mkt.decide(null, null, null, null, null, null));
- assertEquals(FilterReply.ACCEPT, mkt.decide(totoMarker, null, null, null, null, null));
- }
-
- @Test
- public void testComposite() {
- String compositeMarkerName = COMPOSITE;
- Marker compositeMarker = MarkerFactory.getMarker(compositeMarkerName);
- compositeMarker.add(totoMarker);
-
- MarkerFilter mkt = new MarkerFilter();
- mkt.setMarker(TOTO);
- mkt.setOnMatch("ACCEPT");
- mkt.setOnMismatch("DENY");
-
- mkt.start();
-
- assertTrue(mkt.isStarted());
- assertEquals(FilterReply.DENY, mkt.decide(null, null, null, null, null, null));
- assertEquals(FilterReply.ACCEPT, mkt.decide(totoMarker, null, null, null, null, null));
- assertEquals(FilterReply.ACCEPT, mkt.decide(compositeMarker, null, null, null, null, null));
- }
+ static String TOTO = "TOTO";
+ static String COMPOSITE = "COMPOSITE";
+
+ Marker totoMarker = MarkerFactory.getMarker(TOTO);
+
+
+ @Test
+ public void testNoMarker() {
+ MarkerFilter mkt = new MarkerFilter();
+ mkt.start();
+ assertFalse(mkt.isStarted());
+ assertEquals(FilterReply.NEUTRAL, mkt.decide(totoMarker, null, null, null, null, null));
+ assertEquals(FilterReply.NEUTRAL, mkt.decide(null, null, null, null, null, null));
+
+ }
+
+
+ @Test
+ public void testBasic() {
+ MarkerFilter mkt = new MarkerFilter();
+ mkt.setMarker(TOTO);
+ mkt.setOnMatch("ACCEPT");
+ mkt.setOnMismatch("DENY");
+
+ mkt.start();
+ assertTrue(mkt.isStarted());
+ assertEquals(FilterReply.DENY, mkt.decide(null, null, null, null, null, null));
+ assertEquals(FilterReply.ACCEPT, mkt.decide(totoMarker, null, null, null, null, null));
+ }
+
+ @Test
+ public void testComposite() {
+ String compositeMarkerName = COMPOSITE;
+ Marker compositeMarker = MarkerFactory.getMarker(compositeMarkerName);
+ compositeMarker.add(totoMarker);
+
+ MarkerFilter mkt = new MarkerFilter();
+ mkt.setMarker(TOTO);
+ mkt.setOnMatch("ACCEPT");
+ mkt.setOnMismatch("DENY");
+
+ mkt.start();
+
+ assertTrue(mkt.isStarted());
+ assertEquals(FilterReply.DENY, mkt.decide(null, null, null, null, null, null));
+ assertEquals(FilterReply.ACCEPT, mkt.decide(totoMarker, null, null, null, null, null));
+ assertEquals(FilterReply.ACCEPT, mkt.decide(compositeMarker, null, null, null, null, null));
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/NOPTurboFilter.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/NOPTurboFilter.java
index 0ea686e..f292e80 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/NOPTurboFilter.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/NOPTurboFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,10 +21,11 @@ import ch.qos.logback.core.spi.FilterReply;
public class NOPTurboFilter extends TurboFilter {
- @Override
- public FilterReply decide(final Marker marker, final Logger logger, final Level level, final String format, final Object[] params, final Throwable t) {
-
- return FilterReply.NEUTRAL;
- }
+ @Override
+ public FilterReply decide(final Marker marker, final Logger logger, final Level level, final String format,
+ final Object[] params, final Throwable t) {
+
+ return FilterReply.NEUTRAL;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/PackageTest.java
index efc3336..ff2af0e 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,7 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ ReconfigureOnChangeTest.class, MarkerFilterTest.class, DuplicateMessageFilterTest.class })
+ at SuiteClasses( { ReconfigureOnChangeTest.class, MarkerFilterTest.class,
+ DuplicateMessageFilterTest.class })
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
index c326db6..8c69f37 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -48,383 +48,401 @@ import java.util.concurrent.TimeUnit;
import static org.junit.Assert.*;
- at Ignore
public class ReconfigureOnChangeTest {
- final static int THREAD_COUNT = 5;
- final static int LOOP_LEN = 1000 * 1000;
+ final static int THREAD_COUNT = 5;
+ final static int LOOP_LEN = 1000 * 1000;
- int diff = RandomUtil.getPositiveInt();
+ int diff = RandomUtil.getPositiveInt();
- // the space in the file name mandated by
- // http://jira.qos.ch/browse/LBCORE-119
- final static String SCAN1_FILE_AS_STR = ClassicTestConstants.INPUT_PREFIX + "turbo/scan 1.xml";
+ // the space in the file name mandated by
+ // http://jira.qos.ch/browse/LBCORE-119
+ final static String SCAN1_FILE_AS_STR = ClassicTestConstants.INPUT_PREFIX
+ + "turbo/scan 1.xml";
- final static String G_SCAN1_FILE_AS_STR = ClassicTestConstants.INPUT_PREFIX + "turbo/scan 1.groovy";
+ final static String G_SCAN1_FILE_AS_STR = ClassicTestConstants.INPUT_PREFIX
+ + "turbo/scan 1.groovy";
- final static String SCAN_LOGBACK_474_FILE_AS_STR = ClassicTestConstants.INPUT_PREFIX + "turbo/scan_logback_474.xml";
+ final static String SCAN_LOGBACK_474_FILE_AS_STR = ClassicTestConstants.INPUT_PREFIX
+ + "turbo/scan_logback_474.xml";
- final static String INCLUSION_SCAN_TOPLEVEL0_AS_STR = ClassicTestConstants.INPUT_PREFIX + "turbo/inclusion/topLevel0.xml";
+ final static String INCLUSION_SCAN_TOPLEVEL0_AS_STR = ClassicTestConstants.INPUT_PREFIX
+ + "turbo/inclusion/topLevel0.xml";
- final static String INCLUSION_SCAN_TOP_BY_RESOURCE_AS_STR = ClassicTestConstants.INPUT_PREFIX + "turbo/inclusion/topByResource.xml";
+ final static String INCLUSION_SCAN_TOP_BY_RESOURCE_AS_STR = ClassicTestConstants.INPUT_PREFIX
+ + "turbo/inclusion/topByResource.xml";
- final static String INCLUSION_SCAN_INNER0_AS_STR = ClassicTestConstants.INPUT_PREFIX + "turbo/inclusion/inner0.xml";
+ final static String INCLUSION_SCAN_INNER0_AS_STR = ClassicTestConstants.INPUT_PREFIX
+ + "turbo/inclusion/inner0.xml";
- final static String INCLUSION_SCAN_INNER1_AS_STR = "target/test-classes/asResource/inner1.xml";
+ final static String INCLUSION_SCAN_INNER1_AS_STR = "target/test-classes/asResource/inner1.xml";
- // it actually takes time for Windows to propagate file modification changes
- // values below 100 milliseconds can be problematic the same propagation
- // latency occurs in Linux but is even larger (>600 ms)
- // final static int DEFAULT_SLEEP_BETWEEN_UPDATES = 60;
+ // it actually takes time for Windows to propagate file modification changes
+ // values below 100 milliseconds can be problematic the same propagation
+ // latency occurs in Linux but is even larger (>600 ms)
+ // final static int DEFAULT_SLEEP_BETWEEN_UPDATES = 60;
- int sleepBetweenUpdates = 100;
+ int sleepBetweenUpdates = 100;
- LoggerContext loggerContext = new LoggerContext();
- Logger logger = loggerContext.getLogger(this.getClass());
- ExecutorService executorService = loggerContext.getExecutorService();
+ LoggerContext loggerContext = new LoggerContext();
+ Logger logger = loggerContext.getLogger(this.getClass());
+ ExecutorService executorService = loggerContext.getExecutorService();
- StatusChecker checker = new StatusChecker(loggerContext);
- AbstractMultiThreadedHarness harness;
+ StatusChecker checker = new StatusChecker(loggerContext);
+ AbstractMultiThreadedHarness harness;
- ThreadPoolExecutor executor = (ThreadPoolExecutor) loggerContext.getExecutorService();
+ ThreadPoolExecutor executor = (ThreadPoolExecutor) loggerContext.getExecutorService();
- int expectedResets = 2;
+ int expectedResets = 2;
- @BeforeClass
- static public void classSetup() {
- FileTestUtil.makeTestOutputDir();
- }
+ @BeforeClass
+ static public void classSetup() {
+ FileTestUtil.makeTestOutputDir();
+ }
- @Before
- public void setUp() {
- harness = new WaitOnExecutionMultiThreadedHarness(executor, expectedResets);
- }
+ @Before
+ public void setUp() {
+ harness = new WaitOnExecutionMultiThreadedHarness(executor, expectedResets);
+ }
- @After
- public void tearDown() {
- }
+ @After
+ public void tearDown() {
+ }
- void configure(File file) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(loggerContext);
- jc.doConfigure(file);
- }
+ void configure(File file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ jc.doConfigure(file);
+ }
- void configure(InputStream is) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(loggerContext);
- jc.doConfigure(is);
- }
+ void configure(InputStream is) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ jc.doConfigure(is);
+ }
- void gConfigure(File file) throws JoranException {
- GafferConfigurator gc = new GafferConfigurator(loggerContext);
- gc.run(file);
- }
+ void gConfigure(File file) throws JoranException {
+ GafferConfigurator gc = new GafferConfigurator(loggerContext);
+ gc.run(file);
+ }
- RunnableWithCounterAndDone[] buildRunnableArray(File configFile, UpdateType updateType) {
- RunnableWithCounterAndDone[] rArray = new RunnableWithCounterAndDone[THREAD_COUNT];
- rArray[0] = new Updater(configFile, updateType);
- for (int i = 1; i < THREAD_COUNT; i++) {
- rArray[i] = new LoggingRunnable(logger);
- }
- return rArray;
+ RunnableWithCounterAndDone[] buildRunnableArray(File configFile, UpdateType updateType) {
+ RunnableWithCounterAndDone[] rArray = new RunnableWithCounterAndDone[THREAD_COUNT];
+ rArray[0] = new Updater(configFile, updateType);
+ for (int i = 1; i < THREAD_COUNT; i++) {
+ rArray[i] = new LoggingRunnable(logger);
}
+ return rArray;
+ }
+
+ // Tests whether ConfigurationAction is installing ReconfigureOnChangeFilter
+ @Test
+ public void installFilter() throws JoranException, IOException, InterruptedException {
+ File file = new File(SCAN1_FILE_AS_STR);
+ configure(file);
+ List<File> fileList = getConfigurationFileList(loggerContext);
+ assertThatListContainsFile(fileList, file);
+ assertThatFirstFilterIsROCF();
+ StatusPrinter.print(loggerContext);
+ }
+
+
+ @Test
+ public void gafferInstallFilter() throws JoranException, IOException, InterruptedException {
+ File file = new File(G_SCAN1_FILE_AS_STR);
+ gConfigure(file);
+ List<File> fileList = getConfigurationFileList(loggerContext);
+ assertThatListContainsFile(fileList, file);
+ assertThatFirstFilterIsROCF();
+
+ rocfDetachReconfigurationToNewThreadAndAwaitTermination();
+
+ fileList = getConfigurationFileList(loggerContext);
+ assertThatListContainsFile(fileList, file);
+ assertThatFirstFilterIsROCF();
+
+ // check that rcof filter installed on two occasions
+ assertEquals(2, checker.matchCount("Will scan for changes in"));
+ }
+
+ private void rocfDetachReconfigurationToNewThreadAndAwaitTermination() throws InterruptedException {
+ ReconfigureOnChangeFilter reconfigureOnChangeFilter = (ReconfigureOnChangeFilter) getFirstTurboFilter();
+ reconfigureOnChangeFilter.detachReconfigurationToNewThread();
+ executorService.shutdown();
+ executorService.awaitTermination(1000, TimeUnit.MILLISECONDS);
+ }
+
+ List<File> getConfigurationFileList(LoggerContext context) {
+ ConfigurationWatchList configurationWatchList = ConfigurationWatchListUtil.getConfigurationWatchList(loggerContext);
+ return configurationWatchList.getCopyOfFileWatchList();
+ }
+
+ @Test(timeout = 4000L)
+ public void scanWithFileInclusion() throws JoranException, IOException, InterruptedException {
+ File topLevelFile = new File(INCLUSION_SCAN_TOPLEVEL0_AS_STR);
+ File innerFile = new File(INCLUSION_SCAN_INNER0_AS_STR);
+ configure(topLevelFile);
+ List<File> fileList = getConfigurationFileList(loggerContext);
+ assertThatListContainsFile(fileList, topLevelFile);
+ assertThatListContainsFile(fileList, innerFile);
+ }
+
+ @Test(timeout = 4000L)
+ public void scanWithResourceInclusion() throws JoranException, IOException, InterruptedException {
+ File topLevelFile = new File(INCLUSION_SCAN_TOP_BY_RESOURCE_AS_STR);
+ File innerFile = new File(INCLUSION_SCAN_INNER1_AS_STR);
+ configure(topLevelFile);
+
+ List<File> fileList = getConfigurationFileList(loggerContext);
+ assertThatListContainsFile(fileList, topLevelFile);
+ assertThatListContainsFile(fileList, innerFile);
+ }
+
+ // See also http://jira.qos.ch/browse/LOGBACK-338
+ @Test
+ public void includeScanViaInputStreamSuppliedConfigFile() throws IOException, JoranException, InterruptedException {
+ String configurationStr = "<configuration scan=\"true\" scanPeriod=\"50 millisecond\"><include resource=\"asResource/inner1.xml\"/></configuration>";
+ configure(new ByteArrayInputStream(configurationStr.getBytes("UTF-8")));
+
+ ConfigurationWatchList configurationWatchList = ConfigurationWatchListUtil.getConfigurationWatchList(loggerContext);
+ assertNull(configurationWatchList.getMainURL());
+
+ ReconfigureOnChangeFilter reconfigureOnChangeFilter = (ReconfigureOnChangeFilter) getFirstTurboFilter();
+ // without a top level file, reconfigureOnChangeFilter should not start
+ assertFalse(reconfigureOnChangeFilter.isStarted());
+ }
+
+ @Test(timeout = 4000L)
+ public void fallbackToSafe() throws IOException, JoranException, InterruptedException {
+ String path = CoreTestConstants.OUTPUT_DIR_PREFIX + "reconfigureOnChangeConfig_fallbackToSafe-" + diff + ".xml";
+ File topLevelFile = new File(path);
+ writeToFile(topLevelFile, "<configuration scan=\"true\" scanPeriod=\"50 millisecond\"><root level=\"ERROR\"/></configuration> ");
+ configure(topLevelFile);
+
+ writeToFile(topLevelFile, "<configuration scan=\"true\" scanPeriod=\"50 millisecond\">\n" +
+ " <root></configuration>");
+
+ rocfDetachReconfigurationToNewThreadAndAwaitTermination();
+
+ checker.assertContainsMatch(Status.WARN, "Falling back to previously registered safe configuration.");
+ checker.assertContainsMatch(Status.INFO, "Re-registering previous fallback configuration once more");
+
+ assertThatFirstFilterIsROCF();
+ }
+
+ @Test(timeout = 4000L)
+ public void fallbackToSafeWithIncludedFile() throws IOException, JoranException, InterruptedException {
+ String topLevelFileAsStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "reconfigureOnChangeConfig_top-" + diff + ".xml";
+ String innerFileAsStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "reconfigureOnChangeConfig_inner-" + diff + ".xml";
+ File topLevelFile = new File(topLevelFileAsStr);
+ writeToFile(topLevelFile, "<configuration scan=\"true\" scanPeriod=\"50 millisecond\"><include file=\"" + innerFileAsStr + "\"/></configuration> ");
+
+ File innerFile = new File(innerFileAsStr);
+ writeToFile(innerFile, "<included><root level=\"ERROR\"/></included> ");
+ configure(topLevelFile);
+ writeToFile(innerFile, "<included>\n<root>\n</included>");
+ rocfDetachReconfigurationToNewThreadAndAwaitTermination();
+
+ checker.assertContainsMatch(Status.WARN, "Falling back to previously registered safe configuration.");
+ checker.assertContainsMatch(Status.INFO, "Re-registering previous fallback configuration once more");
- // Tests whether ConfigurationAction is installing ReconfigureOnChangeFilter
- @Test
- public void installFilter() throws JoranException, IOException, InterruptedException {
- File file = new File(SCAN1_FILE_AS_STR);
- configure(file);
- List<File> fileList = getConfigurationFileList(loggerContext);
- assertThatListContainsFile(fileList, file);
- assertThatFirstFilterIsROCF();
- StatusPrinter.print(loggerContext);
- }
+ assertThatFirstFilterIsROCF();
+ }
+
+
+ // check for deadlocks
+ @Test(timeout = 4000L)
+ public void scan_LOGBACK_474() throws JoranException, IOException,
+ InterruptedException {
+ File file = new File(SCAN_LOGBACK_474_FILE_AS_STR);
+ configure(file);
+
+ RunnableWithCounterAndDone[] runnableArray = buildRunnableArray(file, UpdateType.TOUCH);
+ harness.execute(runnableArray);
+
+ loggerContext.getStatusManager().add(
+ new InfoStatus("end of execution ", this));
+
+ verify(expectedResets);
+ }
+
+
+ private void assertThatListContainsFile(List<File> fileList, File file) {
+ // conversion to absolute file seems to work nicely
+ assertTrue(fileList.contains(file.getAbsoluteFile()));
+ }
- @Test
- public void gafferInstallFilter() throws JoranException, IOException, InterruptedException {
- File file = new File(G_SCAN1_FILE_AS_STR);
- gConfigure(file);
- List<File> fileList = getConfigurationFileList(loggerContext);
- assertThatListContainsFile(fileList, file);
- assertThatFirstFilterIsROCF();
+ private TurboFilter getFirstTurboFilter() {
+ TurboFilterList turboFilterList = loggerContext.getTurboFilterList();
+ return turboFilterList.get(0);
+ }
- rocfDetachReconfigurationToNewThreadAndAwaitTermination();
- fileList = getConfigurationFileList(loggerContext);
- assertThatListContainsFile(fileList, file);
- assertThatFirstFilterIsROCF();
+ private void assertThatFirstFilterIsROCF() {
+ assertTrue(getFirstTurboFilter() instanceof ReconfigureOnChangeFilter);
+ }
- // check that rcof filter installed on two occasions
- assertEquals(2, checker.matchCount("Will scan for changes in"));
- }
- private void rocfDetachReconfigurationToNewThreadAndAwaitTermination() throws InterruptedException {
- ReconfigureOnChangeFilter reconfigureOnChangeFilter = (ReconfigureOnChangeFilter) getFirstTurboFilter();
- reconfigureOnChangeFilter.detachReconfigurationToNewThread();
- executorService.shutdown();
- executorService.awaitTermination(1000, TimeUnit.MILLISECONDS);
+ private void verify(int expected) {
+ StatusChecker checker = new StatusChecker(loggerContext);
+ //StatusPrinter.print(loggerContext);
+ checker.assertIsErrorFree();
+
+ int effectiveResets = checker
+ .matchCount(CoreConstants.RESET_MSG_PREFIX);
+
+ String failMsg = "effective=" + effectiveResets + ", expected="
+ + expected;
+
+ // there might be more effective resets than the expected amount
+ // since the harness may be sleeping while a reset occurs
+ assertTrue(failMsg, expected <= effectiveResets && (expected + 2) >= effectiveResets);
+
+ }
+
+ ReconfigureOnChangeFilter initROCF() throws MalformedURLException {
+ ReconfigureOnChangeFilter rocf = new ReconfigureOnChangeFilter();
+ rocf.setContext(loggerContext);
+ File file = new File(SCAN1_FILE_AS_STR);
+ ConfigurationWatchListUtil.setMainWatchURL(loggerContext, file.toURI().toURL());
+ rocf.start();
+ return rocf;
+ }
+
+ @Test
+ @Ignore
+ public void directPerfTest() throws MalformedURLException {
+ if (EnvUtilForTests.isLinux()) {
+ // for some reason this test does not pass on Linux (AMD 64 bit,
+ // Dual Core Opteron 170)
+ return;
}
- List<File> getConfigurationFileList(LoggerContext context) {
- ConfigurationWatchList configurationWatchList = ConfigurationWatchListUtil.getConfigurationWatchList(loggerContext);
- return configurationWatchList.getCopyOfFileWatchList();
- }
+ ReconfigureOnChangeFilter rocf = initROCF();
+ assertTrue(rocf.isStarted());
- @Test(timeout = 4000L)
- public void scanWithFileInclusion() throws JoranException, IOException, InterruptedException {
- File topLevelFile = new File(INCLUSION_SCAN_TOPLEVEL0_AS_STR);
- File innerFile = new File(INCLUSION_SCAN_INNER0_AS_STR);
- configure(topLevelFile);
- List<File> fileList = getConfigurationFileList(loggerContext);
- assertThatListContainsFile(fileList, topLevelFile);
- assertThatListContainsFile(fileList, innerFile);
+ for (int i = 0; i < 30; i++) {
+ directLoop(rocf);
}
-
- @Test(timeout = 4000L)
- public void scanWithResourceInclusion() throws JoranException, IOException, InterruptedException {
- File topLevelFile = new File(INCLUSION_SCAN_TOP_BY_RESOURCE_AS_STR);
- File innerFile = new File(INCLUSION_SCAN_INNER1_AS_STR);
- configure(topLevelFile);
-
- List<File> fileList = getConfigurationFileList(loggerContext);
- assertThatListContainsFile(fileList, topLevelFile);
- assertThatListContainsFile(fileList, innerFile);
+ double avg = directLoop(rocf);
+ System.out.println("directPerfTest: " + avg);
+ }
+
+ public double directLoop(ReconfigureOnChangeFilter rocf) {
+ long start = System.nanoTime();
+ for (int i = 0; i < LOOP_LEN; i++) {
+ rocf.decide(null, logger, Level.DEBUG, " ", null, null);
}
-
- // See also http://jira.qos.ch/browse/LOGBACK-338
- @Test
- public void includeScanViaInputStreamSuppliedConfigFile() throws IOException, JoranException, InterruptedException {
- String configurationStr = "<configuration scan=\"true\" scanPeriod=\"50 millisecond\"><include resource=\"asResource/inner1.xml\"/></configuration>";
- configure(new ByteArrayInputStream(configurationStr.getBytes("UTF-8")));
-
- ConfigurationWatchList configurationWatchList = ConfigurationWatchListUtil.getConfigurationWatchList(loggerContext);
- assertNull(configurationWatchList.getMainURL());
-
- ReconfigureOnChangeFilter reconfigureOnChangeFilter = (ReconfigureOnChangeFilter) getFirstTurboFilter();
- // without a top level file, reconfigureOnChangeFilter should not start
- assertFalse(reconfigureOnChangeFilter.isStarted());
+ long end = System.nanoTime();
+ return (end - start) / (1.0d * LOOP_LEN);
+ }
+
+ @Ignore
+ @Test
+ public void indirectPerfTest() throws MalformedURLException {
+ if (EnvUtilForTests.isLinux()) {
+ // for some reason this test does not pass on Linux (AMD 64 bit,
+ // Dual Core
+ // Opteron 170)
+ return;
}
- @Test(timeout = 4000L)
- public void fallbackToSafe() throws IOException, JoranException, InterruptedException {
- String path = CoreTestConstants.OUTPUT_DIR_PREFIX + "reconfigureOnChangeConfig_fallbackToSafe-" + diff + ".xml";
- File topLevelFile = new File(path);
- writeToFile(topLevelFile, "<configuration scan=\"true\" scanPeriod=\"50 millisecond\"><root level=\"ERROR\"/></configuration> ");
- configure(topLevelFile);
-
- writeToFile(topLevelFile, "<configuration scan=\"true\" scanPeriod=\"50 millisecond\">\n" + " <root></configuration>");
-
- rocfDetachReconfigurationToNewThreadAndAwaitTermination();
-
- checker.assertContainsMatch(Status.WARN, "Falling back to previously registered safe configuration.");
- checker.assertContainsMatch(Status.INFO, "Re-registering previous fallback configuration once more");
-
- assertThatFirstFilterIsROCF();
- }
-
- @Test(timeout = 4000L)
- public void fallbackToSafeWithIncludedFile() throws IOException, JoranException, InterruptedException {
- String topLevelFileAsStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "reconfigureOnChangeConfig_top-" + diff + ".xml";
- String innerFileAsStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "reconfigureOnChangeConfig_inner-" + diff + ".xml";
- File topLevelFile = new File(topLevelFileAsStr);
- writeToFile(topLevelFile, "<configuration scan=\"true\" scanPeriod=\"50 millisecond\"><include file=\"" + innerFileAsStr + "\"/></configuration> ");
-
- File innerFile = new File(innerFileAsStr);
- writeToFile(innerFile, "<included><root level=\"ERROR\"/></included> ");
- configure(topLevelFile);
- writeToFile(innerFile, "<included>\n<root>\n</included>");
- rocfDetachReconfigurationToNewThreadAndAwaitTermination();
-
- checker.assertContainsMatch(Status.WARN, "Falling back to previously registered safe configuration.");
- checker.assertContainsMatch(Status.INFO, "Re-registering previous fallback configuration once more");
-
- assertThatFirstFilterIsROCF();
+ ReconfigureOnChangeFilter rocf = initROCF();
+ assertTrue(rocf.isStarted());
+ loggerContext.addTurboFilter(rocf);
+ logger.setLevel(Level.ERROR);
+
+ indirectLoop();
+ double avg = indirectLoop();
+ System.out.println(avg);
+ // the reference was computed on Orion (Ceki's computer)
+ long referencePerf = 68;
+ BogoPerf.assertDuration(avg, referencePerf, CoreConstants.REFERENCE_BIPS);
+ }
+
+ void addInfo(String msg, Object o) {
+ loggerContext.getStatusManager().add(new InfoStatus(msg, o));
+ }
+
+ public double indirectLoop() {
+ long start = System.nanoTime();
+ for (int i = 0; i < LOOP_LEN; i++) {
+ logger.debug("hello");
}
+ long end = System.nanoTime();
+ return (end - start) / (1.0d * LOOP_LEN);
+ }
- // check for deadlocks
- @Test(timeout = 4000L)
- public void scan_LOGBACK_474() throws JoranException, IOException, InterruptedException {
- File file = new File(SCAN_LOGBACK_474_FILE_AS_STR);
- configure(file);
-
- RunnableWithCounterAndDone[] runnableArray = buildRunnableArray(file, UpdateType.TOUCH);
- harness.execute(runnableArray);
+ enum UpdateType {TOUCH, MALFORMED, MALFORMED_INNER}
- loggerContext.getStatusManager().add(new InfoStatus("end of execution ", this));
-
- verify(expectedResets);
- }
+ void writeToFile(File file, String contents) throws IOException {
+ FileWriter fw = new FileWriter(file);
+ fw.write(contents);
+ fw.close();
+ }
- private void assertThatListContainsFile(List<File> fileList, File file) {
- // conversion to absolute file seems to work nicely
- assertTrue(fileList.contains(file.getAbsoluteFile()));
- }
+ class Updater extends RunnableWithCounterAndDone {
+ File configFile;
+ UpdateType updateType;
- private TurboFilter getFirstTurboFilter() {
- TurboFilterList turboFilterList = loggerContext.getTurboFilterList();
- return turboFilterList.get(0);
+ Updater(File configFile, UpdateType updateType) {
+ this.configFile = configFile;
+ this.updateType = updateType;
}
- private void assertThatFirstFilterIsROCF() {
- assertTrue(getFirstTurboFilter() instanceof ReconfigureOnChangeFilter);
+ Updater(File configFile) {
+ this(configFile, UpdateType.TOUCH);
}
- private void verify(int expected) {
- StatusChecker checker = new StatusChecker(loggerContext);
- // StatusPrinter.print(loggerContext);
- checker.assertIsErrorFree();
-
- int effectiveResets = checker.matchCount(CoreConstants.RESET_MSG_PREFIX);
-
- String failMsg = "effective=" + effectiveResets + ", expected=" + expected;
-
- // there might be more effective resets than the expected amount
- // since the harness may be sleeping while a reset occurs
- assertTrue(failMsg, expected <= effectiveResets && (expected + 2) >= effectiveResets);
-
- }
-
- ReconfigureOnChangeFilter initROCF() throws MalformedURLException {
- ReconfigureOnChangeFilter rocf = new ReconfigureOnChangeFilter();
- rocf.setContext(loggerContext);
- File file = new File(SCAN1_FILE_AS_STR);
- ConfigurationWatchListUtil.setMainWatchURL(loggerContext, file.toURI().toURL());
- rocf.start();
- return rocf;
- }
-
- @Test
- @Ignore
- public void directPerfTest() throws MalformedURLException {
- if (EnvUtilForTests.isLinux()) {
- // for some reason this test does not pass on Linux (AMD 64 bit,
- // Dual Core Opteron 170)
- return;
- }
-
- ReconfigureOnChangeFilter rocf = initROCF();
- assertTrue(rocf.isStarted());
-
- for (int i = 0; i < 30; i++) {
- directLoop(rocf);
+ public void run() {
+ while (!isDone()) {
+ try {
+ Thread.sleep(sleepBetweenUpdates);
+ } catch (InterruptedException e) {
}
- double avg = directLoop(rocf);
- System.out.println("directPerfTest: " + avg);
- }
-
- public double directLoop(ReconfigureOnChangeFilter rocf) {
- long start = System.nanoTime();
- for (int i = 0; i < LOOP_LEN; i++) {
- rocf.decide(null, logger, Level.DEBUG, " ", null, null);
+ if (isDone()) {
+ return;
}
- long end = System.nanoTime();
- return (end - start) / (1.0d * LOOP_LEN);
- }
-
- @Ignore
- @Test
- public void indirectPerfTest() throws MalformedURLException {
- if (EnvUtilForTests.isLinux()) {
- // for some reason this test does not pass on Linux (AMD 64 bit,
- // Dual Core
- // Opteron 170)
- return;
+ counter++;
+ ReconfigureOnChangeTest.this.addInfo("***settting last modified", this);
+ switch (updateType) {
+ case TOUCH:
+ touchFile();
+ break;
+ case MALFORMED:
+ try {
+ malformedUpdate();
+ } catch (IOException e) {
+ e.printStackTrace();
+ fail("malformedUpdate failed");
+ }
+ break;
+ case MALFORMED_INNER:
+ try {
+ malformedInnerUpdate();
+ } catch (IOException e) {
+ e.printStackTrace();
+ fail("malformedInnerUpdate failed");
+ }
}
-
- ReconfigureOnChangeFilter rocf = initROCF();
- assertTrue(rocf.isStarted());
- loggerContext.addTurboFilter(rocf);
- logger.setLevel(Level.ERROR);
-
- indirectLoop();
- double avg = indirectLoop();
- System.out.println(avg);
- // the reference was computed on Orion (Ceki's computer)
- long referencePerf = 68;
- BogoPerf.assertDuration(avg, referencePerf, CoreConstants.REFERENCE_BIPS);
- }
-
- void addInfo(String msg, Object o) {
- loggerContext.getStatusManager().add(new InfoStatus(msg, o));
+ }
}
- public double indirectLoop() {
- long start = System.nanoTime();
- for (int i = 0; i < LOOP_LEN; i++) {
- logger.debug("hello");
- }
- long end = System.nanoTime();
- return (end - start) / (1.0d * LOOP_LEN);
+ private void malformedUpdate() throws IOException {
+ writeToFile(configFile, "<configuration scan=\"true\" scanPeriod=\"50 millisecond\">\n" +
+ " <root level=\"ERROR\">\n" +
+ "</configuration>");
}
- enum UpdateType {
- TOUCH, MALFORMED, MALFORMED_INNER
+ private void malformedInnerUpdate() throws IOException {
+ writeToFile(configFile, "<included>\n" +
+ " <root>\n" +
+ "</included>");
}
- void writeToFile(File file, String contents) throws IOException {
- FileWriter fw = new FileWriter(file);
- fw.write(contents);
- fw.close();
+ void touchFile() {
+ configFile.setLastModified(System.currentTimeMillis());
}
+ }
- class Updater extends RunnableWithCounterAndDone {
- File configFile;
- UpdateType updateType;
-
- Updater(File configFile, UpdateType updateType) {
- this.configFile = configFile;
- this.updateType = updateType;
- }
-
- Updater(File configFile) {
- this(configFile, UpdateType.TOUCH);
- }
-
- public void run() {
- while (!isDone()) {
- try {
- Thread.sleep(sleepBetweenUpdates);
- } catch (InterruptedException e) {
- }
- if (isDone()) {
- return;
- }
- counter++;
- ReconfigureOnChangeTest.this.addInfo("***settting last modified", this);
- switch (updateType) {
- case TOUCH:
- touchFile();
- break;
- case MALFORMED:
- try {
- malformedUpdate();
- } catch (IOException e) {
- e.printStackTrace();
- fail("malformedUpdate failed");
- }
- break;
- case MALFORMED_INNER:
- try {
- malformedInnerUpdate();
- } catch (IOException e) {
- e.printStackTrace();
- fail("malformedInnerUpdate failed");
- }
- }
- }
- }
-
- private void malformedUpdate() throws IOException {
- writeToFile(configFile, "<configuration scan=\"true\" scanPeriod=\"50 millisecond\">\n" + " <root level=\"ERROR\">\n" + "</configuration>");
- }
-
- private void malformedInnerUpdate() throws IOException {
- writeToFile(configFile, "<included>\n" + " <root>\n" + "</included>");
- }
-
- void touchFile() {
- configFile.setLastModified(System.currentTimeMillis());
- }
- }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigurePerf.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigurePerf.java
index f922ebb..241548a 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigurePerf.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigurePerf.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -32,64 +32,65 @@ import ch.qos.logback.core.joran.spi.JoranException;
@Ignore
public class ReconfigurePerf {
- final static int THREAD_COUNT = 500;
- // final static int LOOP_LEN = 1000 * 1000;
+ final static int THREAD_COUNT = 500;
+ //final static int LOOP_LEN = 1000 * 1000;
- // the space in the file name mandated by
- // http://jira.qos.ch/browse/LBCORE-119
- final static String CONF_FILE_AS_STR = ClassicTestConstants.INPUT_PREFIX + "turbo/scan_perf.xml";
+ // the space in the file name mandated by
+ // http://jira.qos.ch/browse/LBCORE-119
+ final static String CONF_FILE_AS_STR = ClassicTestConstants.INPUT_PREFIX
+ + "turbo/scan_perf.xml";
- // it actually takes time for Windows to propagate file modification changes
- // values below 100 milliseconds can be problematic the same propagation
- // latency occurs in Linux but is even larger (>600 ms)
- final static int DEFAULT_SLEEP_BETWEEN_UPDATES = 110;
+ // it actually takes time for Windows to propagate file modification changes
+ // values below 100 milliseconds can be problematic the same propagation
+ // latency occurs in Linux but is even larger (>600 ms)
+ final static int DEFAULT_SLEEP_BETWEEN_UPDATES = 110;
- int sleepBetweenUpdates = DEFAULT_SLEEP_BETWEEN_UPDATES;
+ int sleepBetweenUpdates = DEFAULT_SLEEP_BETWEEN_UPDATES;
- static int numberOfCycles = 100;
- static int totalTestDuration;
+ static int numberOfCycles = 100;
+ static int totalTestDuration;
- LoggerContext loggerContext = new LoggerContext();
- Logger logger = loggerContext.getLogger(this.getClass());
- MultiThreadedHarness harness;
+ LoggerContext loggerContext = new LoggerContext();
+ Logger logger = loggerContext.getLogger(this.getClass());
+ MultiThreadedHarness harness;
- @Before
- public void setUp() {
- // take into account propagation latency occurs on Linux
- if (EnvUtilForTests.isLinux()) {
- sleepBetweenUpdates = 850;
- totalTestDuration = sleepBetweenUpdates * numberOfCycles;
- } else {
- totalTestDuration = sleepBetweenUpdates * numberOfCycles * 2;
- }
- harness = new MultiThreadedHarness(totalTestDuration);
+ @Before
+ public void setUp() {
+ // take into account propagation latency occurs on Linux
+ if (EnvUtilForTests.isLinux()) {
+ sleepBetweenUpdates = 850;
+ totalTestDuration = sleepBetweenUpdates * numberOfCycles;
+ } else {
+ totalTestDuration = sleepBetweenUpdates * numberOfCycles * 2;
}
+ harness = new MultiThreadedHarness(totalTestDuration);
+ }
- void configure(File file) throws JoranException {
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(loggerContext);
- jc.doConfigure(file);
- }
+ void configure(File file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ jc.doConfigure(file);
+ }
- RunnableWithCounterAndDone[] buildRunnableArray() {
- RunnableWithCounterAndDone[] rArray = new RunnableWithCounterAndDone[THREAD_COUNT];
- for (int i = 0; i < THREAD_COUNT; i++) {
- rArray[i] = new LoggingRunnable(logger);
- }
- return rArray;
+ RunnableWithCounterAndDone[] buildRunnableArray() {
+ RunnableWithCounterAndDone[] rArray = new RunnableWithCounterAndDone[THREAD_COUNT];
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ rArray[i] = new LoggingRunnable(logger);
}
+ return rArray;
+ }
- // Tests whether ConfigurationAction is installing ReconfigureOnChangeFilter
- @Test
- public void scan1() throws JoranException, IOException, InterruptedException {
- File file = new File(CONF_FILE_AS_STR);
- configure(file);
- System.out.println("Running scan1()");
- doRun();
- }
+ // Tests whether ConfigurationAction is installing ReconfigureOnChangeFilter
+ @Test
+ public void scan1() throws JoranException, IOException, InterruptedException {
+ File file = new File(CONF_FILE_AS_STR);
+ configure(file);
+ System.out.println("Running scan1()");
+ doRun();
+ }
- void doRun() throws InterruptedException {
- RunnableWithCounterAndDone[] runnableArray = buildRunnableArray();
- harness.execute(runnableArray);
- }
+ void doRun() throws InterruptedException {
+ RunnableWithCounterAndDone[] runnableArray = buildRunnableArray();
+ harness.execute(runnableArray);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/Event.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/Event.java
index 976105b..f459785 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/Event.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/Event.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,19 +15,19 @@ package ch.qos.logback.classic.turbo.lru;
public class Event<K> {
- final public boolean put;
- final public K k;
-
- public Event(boolean put, K k) {
- this.put = put;
- this.k = k;
- }
-
- public String toString() {
- if (put) {
- return "Event: put, " + k;
- } else {
- return "Event: get, " + k;
- }
+ final public boolean put;
+ final public K k;
+
+ public Event(boolean put, K k) {
+ this.put = put;
+ this.k = k;
+ }
+
+ public String toString() {
+ if(put) {
+ return "Event: put, "+k;
+ } else {
+ return "Event: get, "+k;
}
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/LRUCache.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/LRUCache.java
index 63388f9..5dc53d1 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/LRUCache.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/LRUCache.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,25 +27,25 @@ import java.util.Map;
* @param <V>
*/
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
- private static final long serialVersionUID = -6592964689843698200L;
+ private static final long serialVersionUID = -6592964689843698200L;
- final int cacheSize;
+ final int cacheSize;
- public LRUCache(int cacheSize) {
- super((int) (cacheSize * (4.0f / 3)), 0.75f, true);
- if (cacheSize < 1) {
- throw new IllegalArgumentException("Cache size cannnot be smaller than 1");
- }
- this.cacheSize = cacheSize;
- }
-
- protected boolean removeEldestEntry(Map.Entry eldest) {
- return (size() > cacheSize);
- }
-
- List<K> keyList() {
- ArrayList<K> al = new ArrayList<K>();
- al.addAll(keySet());
- return al;
- }
+ public LRUCache(int cacheSize) {
+ super((int) (cacheSize*(4.0f/3)), 0.75f, true);
+ if(cacheSize < 1) {
+ throw new IllegalArgumentException("Cache size cannnot be smaller than 1");
+ }
+ this.cacheSize = cacheSize;
+ }
+
+ protected boolean removeEldestEntry(Map.Entry eldest) {
+ return (size() > cacheSize);
+ }
+
+ List<K> keyList() {
+ ArrayList<K> al = new ArrayList<K>();
+ al.addAll(keySet());
+ return al;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/LRUCacheTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/LRUCacheTest.java
index b6bd94e..f367301 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/LRUCacheTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/LRUCacheTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,97 +24,99 @@ import org.junit.Test;
@Ignore
public class LRUCacheTest {
- @Test
- public void smoke() {
-
- LRUCache<String, String> cache = new LRUCache<String, String>(2);
- cache.put("a", "a");
- cache.put("b", "b");
- cache.put("c", "c");
- List<String> witness = new LinkedList<String>();
- witness.add("b");
- witness.add("c");
- assertEquals(witness, cache.keyList());
+ @Test
+ public void smoke() {
+
+ LRUCache<String, String> cache = new LRUCache<String, String>(2);
+ cache.put("a", "a");
+ cache.put("b", "b");
+ cache.put("c", "c");
+ List<String> witness = new LinkedList<String>();
+ witness.add("b");
+ witness.add("c");
+ assertEquals(witness, cache.keyList());
+ }
+
+ @Test
+ public void typicalScenarioTest() {
+ int simulationLen = 1000 * 10;
+ int cacheSize = 100;
+ int worldSize = 1000;
+ doScenario(simulationLen, cacheSize, worldSize);
+ }
+
+ @Test
+ public void scenarioCoverageTest() {
+ int simulationLen = 1000 * 10;
+
+ int[] cacheSizes = new int[] { 1, 10, 100};
+ // tests with large worldSizes are slow because with a large
+ // world size the probability of a cache miss is high.
+ int[] worldSizes = new int[] { 1, 10, 100 };
+
+ for (int i = 0; i < cacheSizes.length; i++) {
+ for (int j = 0; j < worldSizes.length; j++) {
+ doScenario(simulationLen, cacheSizes[i], worldSizes[j]);
+ }
}
-
- @Test
- public void typicalScenarioTest() {
- int simulationLen = 1000 * 10;
- int cacheSize = 100;
- int worldSize = 1000;
- doScenario(simulationLen, cacheSize, worldSize);
+ }
+
+ void doScenario(int simulationLen, int cacheSize, int worldSize) {
+ int get2PutRatio = 10;
+ Simulator simulator = new Simulator(worldSize, get2PutRatio, false);
+ List<Event> scenario = simulator.generateScenario(simulationLen);
+ LRUCache<String, String> lruCache = new LRUCache<String, String>(cacheSize);
+ T_LRUCache<String> tlruCache = new T_LRUCache<String>(cacheSize);
+ long start = System.nanoTime();
+ simulator.simulate(scenario, lruCache, tlruCache);
+ //assertEquals(tlruCache.keyList(), lruCache.keyList());
+ long end = System.nanoTime();
+ System.out.println("cacheSize=" + cacheSize + ", worldSize=" + worldSize
+ + ", elapsed time=" + ((end - start) / (1000 * 1000)) + " in millis");
+ }
+
+
+
+ @Test
+ @Ignore // slow test that is known to pass
+ public void multiThreadedScenario() throws InterruptedException {
+ int cacheSize = 100;
+ int worldSize = cacheSize*2;
+ LRUCache<String, String> lruCache = new LRUCache<String, String>(cacheSize);
+ T_LRUCache<String> tlruCache = new T_LRUCache<String>(cacheSize);
+ SimulatorRunnable[] simulatorArray = new SimulatorRunnable[5];
+ for(int i = 0; i < simulatorArray.length; i++) {
+ simulatorArray[i] = new SimulatorRunnable(lruCache, tlruCache, worldSize);
}
-
- @Test
- public void scenarioCoverageTest() {
- int simulationLen = 1000 * 10;
-
- int[] cacheSizes = new int[] { 1, 10, 100 };
- // tests with large worldSizes are slow because with a large
- // world size the probability of a cache miss is high.
- int[] worldSizes = new int[] { 1, 10, 100 };
-
- for (int i = 0; i < cacheSizes.length; i++) {
- for (int j = 0; j < worldSizes.length; j++) {
- doScenario(simulationLen, cacheSizes[i], worldSizes[j]);
- }
- }
+ for(int i = 0; i < simulatorArray.length; i++) {
+ simulatorArray[i].start();
}
-
- void doScenario(int simulationLen, int cacheSize, int worldSize) {
- int get2PutRatio = 10;
- Simulator simulator = new Simulator(worldSize, get2PutRatio, false);
- List<Event> scenario = simulator.generateScenario(simulationLen);
- LRUCache<String, String> lruCache = new LRUCache<String, String>(cacheSize);
- T_LRUCache<String> tlruCache = new T_LRUCache<String>(cacheSize);
- long start = System.nanoTime();
- simulator.simulate(scenario, lruCache, tlruCache);
- // assertEquals(tlruCache.keyList(), lruCache.keyList());
- long end = System.nanoTime();
- System.out.println("cacheSize=" + cacheSize + ", worldSize=" + worldSize + ", elapsed time=" + ((end - start) / (1000 * 1000)) + " in millis");
+ for(int i = 0; i < simulatorArray.length; i++) {
+ simulatorArray[i].join();
}
-
- @Test
- @Ignore
- // slow test that is known to pass
- public void multiThreadedScenario() throws InterruptedException {
- int cacheSize = 100;
- int worldSize = cacheSize * 2;
- LRUCache<String, String> lruCache = new LRUCache<String, String>(cacheSize);
- T_LRUCache<String> tlruCache = new T_LRUCache<String>(cacheSize);
- SimulatorRunnable[] simulatorArray = new SimulatorRunnable[5];
- for (int i = 0; i < simulatorArray.length; i++) {
- simulatorArray[i] = new SimulatorRunnable(lruCache, tlruCache, worldSize);
- }
- for (int i = 0; i < simulatorArray.length; i++) {
- simulatorArray[i].start();
- }
- for (int i = 0; i < simulatorArray.length; i++) {
- simulatorArray[i].join();
- }
- assertEquals(tlruCache.keyList(), lruCache.keyList());
+ assertEquals(tlruCache.keyList(), lruCache.keyList());
+ }
+
+ private class SimulatorRunnable extends Thread {
+
+ LRUCache<String, String> lruCache;
+ T_LRUCache<String> tlruCache;
+ int worldSize;
+
+ SimulatorRunnable(LRUCache<String, String> lruCache, T_LRUCache<String> tlruCache, int worldSize) {
+ this.lruCache = lruCache;
+ this.tlruCache = tlruCache;
+ this.worldSize = worldSize;
}
-
- private class SimulatorRunnable extends Thread {
-
- LRUCache<String, String> lruCache;
- T_LRUCache<String> tlruCache;
- int worldSize;
-
- SimulatorRunnable(LRUCache<String, String> lruCache, T_LRUCache<String> tlruCache, int worldSize) {
- this.lruCache = lruCache;
- this.tlruCache = tlruCache;
- this.worldSize = worldSize;
- }
-
- public void run() {
- int get2PutRatio = 10;
- int simulationLen = 1000 * 50;
- Simulator simulator = new Simulator(worldSize, get2PutRatio, true);
- List<Event> scenario = simulator.generateScenario(simulationLen);
- simulator.simulate(scenario, lruCache, tlruCache);
- System.out.println("done");
- }
+
+ public void run() {
+ int get2PutRatio = 10;
+ int simulationLen = 1000*50;
+ Simulator simulator = new Simulator(worldSize, get2PutRatio, true);
+ List<Event> scenario = simulator.generateScenario(simulationLen);
+ simulator.simulate(scenario, lruCache, tlruCache);
+ System.out.println("done");
}
-
+ }
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/Simulator.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/Simulator.java
index d3a0ae4..72bb879 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/Simulator.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/Simulator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,68 +21,69 @@ import java.util.Random;
public class Simulator {
- Random random;
+ Random random;
- int worldSize;
- int get2PutRatio;
- boolean multiThreaded;
+ int worldSize;
+ int get2PutRatio;
+ boolean multiThreaded;
- public Simulator(int worldSize, int get2PutRatio, boolean multiThreaded) {
- this.worldSize = worldSize;
- this.get2PutRatio = get2PutRatio;
- long seed = System.nanoTime();
- // System.out.println("seed is "+seed);
- random = new Random(seed);
- this.multiThreaded = multiThreaded;
- }
+ public Simulator(int worldSize, int get2PutRatio, boolean multiThreaded) {
+ this.worldSize = worldSize;
+ this.get2PutRatio = get2PutRatio;
+ long seed = System.nanoTime();
+ // System.out.println("seed is "+seed);
+ random = new Random(seed);
+ this.multiThreaded = multiThreaded;
+ }
- public List<Event> generateScenario(int len) {
- List<Event> scenario = new ArrayList<Event>();
+ public List<Event> generateScenario(int len) {
+ List<Event> scenario = new ArrayList<Event>();
- for (int i = 0; i < len; i++) {
+ for (int i = 0; i < len; i++) {
- int r = random.nextInt(get2PutRatio);
- boolean put = false;
- if (r == 0) {
- put = true;
- }
- r = random.nextInt(worldSize);
- Event<String> e = new Event<String>(put, String.valueOf(r));
- scenario.add(e);
- }
- return scenario;
+ int r = random.nextInt(get2PutRatio);
+ boolean put = false;
+ if (r == 0) {
+ put = true;
+ }
+ r = random.nextInt(worldSize);
+ Event<String> e = new Event<String>(put, String.valueOf(r));
+ scenario.add(e);
}
+ return scenario;
+ }
- public void simulate(List<Event> scenario, LRUCache<String, String> lruCache, T_LRUCache<String> tlruCache) {
- for (Event<String> e : scenario) {
- if (e.put) {
- lruCache.put(e.k, e.k);
- tlruCache.put(e.k);
- } else {
- String r0 = lruCache.get(e.k);
- String r1 = tlruCache.get(e.k);
- if (!multiThreaded) {
- // if the simulation is used in a multi-threaded
- // context, then the state of lruCache may be different than
- // that of tlruCache. In single threaded mode, they should
- // return the same values all the time
- if (r0 != null) {
- assertEquals(r0, e.k);
- }
- assertEquals(r0, r1);
- }
- }
+ public void simulate(List<Event> scenario, LRUCache<String, String> lruCache,
+ T_LRUCache<String> tlruCache) {
+ for (Event<String> e : scenario) {
+ if (e.put) {
+ lruCache.put(e.k, e.k);
+ tlruCache.put(e.k);
+ } else {
+ String r0 = lruCache.get(e.k);
+ String r1 = tlruCache.get(e.k);
+ if (!multiThreaded) {
+ // if the simulation is used in a multi-threaded
+ // context, then the state of lruCache may be different than
+ // that of tlruCache. In single threaded mode, they should
+ // return the same values all the time
+ if (r0 != null) {
+ assertEquals(r0, e.k);
+ }
+ assertEquals(r0, r1);
}
+ }
}
+ }
- // void compareAndDumpIfDifferent(LRUCache<String, String> lruCache,
- // T_LRUCache<String> tlruCache) {
- // lruCache.dump();
- // tlruCache.dump();
- // if(!lruCache.keyList().equals(tlruCache.ketList())) {
- // lruCache.dump();
- // tlruCache.dump();
- // throw new AssertionFailedError("s");
- // }
- // }
+ // void compareAndDumpIfDifferent(LRUCache<String, String> lruCache,
+ // T_LRUCache<String> tlruCache) {
+ // lruCache.dump();
+ // tlruCache.dump();
+ // if(!lruCache.keyList().equals(tlruCache.ketList())) {
+ // lruCache.dump();
+ // tlruCache.dump();
+ // throw new AssertionFailedError("s");
+ // }
+ // }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/T_Entry.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/T_Entry.java
index 42059f5..dd9bcf3 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/T_Entry.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/T_Entry.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,32 +15,31 @@ package ch.qos.logback.classic.turbo.lru;
public class T_Entry<K> implements Comparable {
- K k;
- long sequenceNumber;
+ K k;
+ long sequenceNumber;
- T_Entry(K k, long sn) {
- this.k = k;
- this.sequenceNumber = sn;
- }
-
- public int compareTo(Object o) {
- if (!(o instanceof T_Entry)) {
- throw new IllegalArgumentException("arguments must be of type " + T_Entry.class);
- }
+ T_Entry(K k, long sn) {
+ this.k = k;
+ this.sequenceNumber = sn;
+ }
- T_Entry other = (T_Entry) o;
- if (sequenceNumber > other.sequenceNumber) {
- return 1;
- }
- if (sequenceNumber == other.sequenceNumber) {
- return 0;
- }
- return -1;
+ public int compareTo(Object o) {
+ if(!(o instanceof T_Entry)) {
+ throw new IllegalArgumentException("arguments must be of type "+T_Entry.class);
}
-
- @Override
- public String toString() {
- return "(" + k + "," + sequenceNumber + ")";
- // return "("+k+")";
+
+ T_Entry other = (T_Entry) o;
+ if(sequenceNumber > other.sequenceNumber) {
+ return 1;
+ }
+ if(sequenceNumber == other.sequenceNumber) {
+ return 0;
}
+ return -1;
+ }
+ @Override
+ public String toString() {
+ return "("+k+","+sequenceNumber+")";
+ //return "("+k+")";
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/T_LRUCache.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/T_LRUCache.java
index 514754f..23fdfd6 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/T_LRUCache.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/T_LRUCache.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,67 +26,69 @@ import java.util.List;
*/
public class T_LRUCache<K> {
- int sequenceNumber;
- final int cacheSize;
- List<T_Entry<K>> cacheList = new LinkedList<T_Entry<K>>();
+ int sequenceNumber;
+ final int cacheSize;
+ List<T_Entry<K>> cacheList = new LinkedList<T_Entry<K>>();
- public T_LRUCache(int size) {
- this.cacheSize = size;
- }
+ public T_LRUCache(int size) {
+ this.cacheSize = size;
+ }
- @SuppressWarnings("unchecked")
- synchronized public void put(K k) {
- sequenceNumber++;
- T_Entry<K> te = getEntry(k);
- if (te != null) {
- te.sequenceNumber = sequenceNumber;
- } else {
- te = new T_Entry<K>(k, sequenceNumber);
- cacheList.add(te);
- }
- Collections.sort(cacheList);
- while (cacheList.size() > cacheSize) {
- cacheList.remove(0);
- }
+ @SuppressWarnings("unchecked")
+ synchronized public void put(K k) {
+ sequenceNumber++;
+ T_Entry<K> te = getEntry(k);
+ if (te != null) {
+ te.sequenceNumber = sequenceNumber;
+ } else {
+ te = new T_Entry<K>(k, sequenceNumber);
+ cacheList.add(te);
+ }
+ Collections.sort(cacheList);
+ while(cacheList.size() > cacheSize) {
+ cacheList.remove(0);
}
+ }
- @SuppressWarnings("unchecked")
- synchronized public K get(K k) {
- T_Entry<K> te = getEntry(k);
- if (te == null) {
- return null;
- } else {
- te.sequenceNumber = ++sequenceNumber;
- Collections.sort(cacheList);
- return te.k;
- }
+ @SuppressWarnings("unchecked")
+ synchronized public K get(K k) {
+ T_Entry<K> te = getEntry(k);
+ if (te == null) {
+ return null;
+ } else {
+ te.sequenceNumber = ++sequenceNumber;
+ Collections.sort(cacheList);
+ return te.k;
}
+ }
- synchronized public List<K> keyList() {
- List<K> keyList = new ArrayList<K>();
- for (T_Entry<K> e : cacheList) {
- keyList.add(e.k);
- }
- return keyList;
+ synchronized public List<K> keyList() {
+ List<K> keyList = new ArrayList<K>();
+ for (T_Entry<K> e : cacheList) {
+ keyList.add(e.k);
}
+ return keyList;
+ }
- private T_Entry<K> getEntry(K k) {
- for (int i = 0; i < cacheList.size(); i++) {
- T_Entry<K> te = cacheList.get(i);
- if (te.k.equals(k)) {
- return te;
- }
- }
- return null;
+ private T_Entry<K> getEntry(K k) {
+ for (int i = 0; i < cacheList.size(); i++) {
+ T_Entry<K> te = cacheList.get(i);
+ if (te.k.equals(k)) {
+ return te;
+ }
}
+ return null;
+ }
- public void dump() {
- System.out.print("T:");
- for (T_Entry<K> te : cacheList) {
- // System.out.print(te.toString()+"->");
- System.out.print(te.k + ", ");
- }
- System.out.println();
+
+ public void dump() {
+ System.out.print("T:");
+ for (T_Entry<K> te : cacheList) {
+ //System.out.print(te.toString()+"->");
+ System.out.print(te.k+", ");
}
+ System.out.println();
+ }
}
+
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/X_LRUCache.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/X_LRUCache.java
index e06df30..33572fa 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/X_LRUCache.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/lru/X_LRUCache.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,25 +27,25 @@ import java.util.Map;
* @param <V>
*/
public class X_LRUCache<K, V> extends LinkedHashMap<K, V> {
- private static final long serialVersionUID = -6592964689843698200L;
+ private static final long serialVersionUID = -6592964689843698200L;
- final int cacheSize;
+ final int cacheSize;
- public X_LRUCache(int cacheSize) {
- super((int) (cacheSize * (4.0f / 3)), 0.75f, true);
- if (cacheSize < 1) {
- throw new IllegalArgumentException("Cache size cannnot be smaller than 1");
- }
- this.cacheSize = cacheSize;
- }
-
- protected boolean removeEldestEntry(Map.Entry eldest) {
- return (size() > cacheSize);
- }
-
- List<K> keyList() {
- ArrayList<K> al = new ArrayList<K>();
- al.addAll(keySet());
- return al;
- }
+ public X_LRUCache(int cacheSize) {
+ super((int) (cacheSize*(4.0f/3)), 0.75f, true);
+ if(cacheSize < 1) {
+ throw new IllegalArgumentException("Cache size cannnot be smaller than 1");
+ }
+ this.cacheSize = cacheSize;
+ }
+
+ protected boolean removeEldestEntry(Map.Entry eldest) {
+ return (size() > cacheSize);
+ }
+
+ List<K> keyList() {
+ ArrayList<K> al = new ArrayList<K>();
+ al.addAll(keySet());
+ return al;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/util/ContextInitializerAutoConfigTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/util/ContextInitializerAutoConfigTest.java
index 52ca1b9..c294c6c 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/util/ContextInitializerAutoConfigTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/util/ContextInitializerAutoConfigTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,48 +13,46 @@
*/
package ch.qos.logback.classic.util;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.ConsoleAppender;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.LoggerFactory;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.Appender;
-import ch.qos.logback.core.ConsoleAppender;
-import ch.qos.logback.core.CoreConstants;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
public class ContextInitializerAutoConfigTest {
- org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
- Logger root = (Logger) LoggerFactory.getLogger("root");
-
- @Before
- public void setUp() throws Exception {
- logger.debug("Hello-didily-odily");
- }
-
- @After
- public void tearDown() throws Exception {
- System.clearProperty(ContextInitializer.CONFIG_FILE_PROPERTY);
- System.clearProperty(CoreConstants.STATUS_LISTENER_CLASS);
- }
-
- @Test
- @Ignore
- // this test works only if logback-test.xml or logback.xml files are on the classpath.
- // However, this is something we try to avoid in order to simplify the life
- // of users trying to follows the manual and logback-examples from an IDE
- public void autoconfig() {
- LoggerContext iLoggerFactory = (LoggerContext) LoggerFactory.getILoggerFactory();
- iLoggerFactory.reset();
- Appender<ILoggingEvent> appender = root.getAppender("STDOUT");
- assertNotNull(appender);
- assertTrue(appender instanceof ConsoleAppender);
- }
+ org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
+ Logger root = (Logger) LoggerFactory.getLogger("root");
+
+ @Before
+ public void setUp() throws Exception {
+ logger.debug("Hello-didily-odily");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ System.clearProperty(ContextInitializer.CONFIG_FILE_PROPERTY);
+ System.clearProperty(ContextInitializer.STATUS_LISTENER_CLASS);
+ }
+
+ @Test
+ @Ignore
+ // this test works only if logback-test.xml or logback.xml files are on the classpath.
+ // However, this is something we try to avoid in order to simplify the life
+ // of users trying to follows the manual and logback-examples from an IDE
+ public void autoconfig() {
+ LoggerContext iLoggerFactory = (LoggerContext) LoggerFactory.getILoggerFactory();
+ iLoggerFactory.reset();
+ Appender<ILoggingEvent> appender = root.getAppender("STDOUT");
+ assertNotNull(appender);
+ assertTrue(appender instanceof ConsoleAppender);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/util/ContextInitializerTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/util/ContextInitializerTest.java
index 27df043..b96b728 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/util/ContextInitializerTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/util/ContextInitializerTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,26 +13,23 @@
*/
package ch.qos.logback.classic.util;
-import static org.junit.Assert.assertEquals;
+
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
-import java.io.IOException;
-import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
-import java.util.Enumeration;
import java.util.List;
-import java.util.Vector;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.ClassicTestConstants;
import ch.qos.logback.classic.Logger;
@@ -45,204 +42,118 @@ import ch.qos.logback.core.LogbackException;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.status.StatusListener;
import ch.qos.logback.core.status.TrivialStatusListener;
+import sun.security.jca.ProviderList;
import ch.qos.logback.core.util.Loader;
public class ContextInitializerTest {
- LoggerContext loggerContext = new LoggerContext();
- Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
-
- @Before
- public void setUp() throws Exception {
- }
-
- @After
- public void tearDown() throws Exception {
- System.clearProperty(ContextInitializer.CONFIG_FILE_PROPERTY);
- System.clearProperty(CoreConstants.STATUS_LISTENER_CLASS);
- MockConfigurator.context = null;
- }
-
- @Test
- @Ignore
- // this test works only if logback-test.xml or logback.xml files are on the classpath.
- // However, this is something we try to avoid in order to simplify the life
- // of users trying to follow the manual and logback-examples from an IDE
- public void reset() throws JoranException {
- {
- new ContextInitializer(loggerContext).autoConfig();
- Appender<ILoggingEvent> appender = root.getAppender("STDOUT");
- assertNotNull(appender);
- assertTrue(appender instanceof ConsoleAppender);
- }
- {
- loggerContext.stop();
- Appender<ILoggingEvent> appender = root.getAppender("STDOUT");
- assertNull(appender);
- }
- }
-
- @Test
- public void autoConfigFromSystemProperties() throws JoranException {
- doAutoConfigFromSystemProperties(ClassicTestConstants.INPUT_PREFIX + "autoConfig.xml");
- doAutoConfigFromSystemProperties("autoConfigAsResource.xml");
- // test passing a URL. note the relative path syntax with file:src/test/...
- doAutoConfigFromSystemProperties("file:" + ClassicTestConstants.INPUT_PREFIX + "autoConfig.xml");
- }
-
- public void doAutoConfigFromSystemProperties(String val) throws JoranException {
- // lc.reset();
- System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY, val);
- new ContextInitializer(loggerContext).autoConfig();
- Appender<ILoggingEvent> appender = root.getAppender("AUTO_BY_SYSTEM_PROPERTY");
- assertNotNull(appender);
- }
-
- @Test
- public void autoConfigFromServiceLoaderJDK6andAbove() throws Exception {
- assumeTrue(!isJDK5());
- setupMockServiceLoader();
- assertNull(MockConfigurator.context);
- new ContextInitializer(loggerContext).autoConfig();
- assertNotNull(MockConfigurator.context);
- assertSame(loggerContext, MockConfigurator.context);
- }
-
- @Test
- public void autoConfigFromServiceLoaderJDK5() throws Exception {
- assumeTrue(isJDK5());
- setupMockServiceLoader();
- assertNull(MockConfigurator.context);
- new ContextInitializer(loggerContext).autoConfig();
- assertNull(MockConfigurator.context);
- }
-
- @Test
- public void autoStatusListener() throws JoranException {
- System.setProperty(CoreConstants.STATUS_LISTENER_CLASS, TrivialStatusListener.class.getName());
- List<StatusListener> statusListenerList = loggerContext.getStatusManager().getCopyOfStatusListenerList();
- assertEquals(0, statusListenerList.size());
- doAutoConfigFromSystemProperties(ClassicTestConstants.INPUT_PREFIX + "autoConfig.xml");
- statusListenerList = loggerContext.getStatusManager().getCopyOfStatusListenerList();
- assertTrue(statusListenerList.size() + " should be 1", statusListenerList.size() == 1);
- // LOGBACK-767
- TrivialStatusListener tsl = (TrivialStatusListener) statusListenerList.get(0);
- assertTrue("expecting at least one event in list", tsl.list.size() > 0);
- }
-
- @Test
- public void autoOnConsoleStatusListener() throws JoranException {
- System.setProperty(CoreConstants.STATUS_LISTENER_CLASS, CoreConstants.SYSOUT);
- List<StatusListener> sll = loggerContext.getStatusManager().getCopyOfStatusListenerList();
- assertEquals(0, sll.size());
- doAutoConfigFromSystemProperties(ClassicTestConstants.INPUT_PREFIX + "autoConfig.xml");
- sll = loggerContext.getStatusManager().getCopyOfStatusListenerList();
- assertTrue(sll.size() + " should be 1", sll.size() == 1);
+ LoggerContext loggerContext = new LoggerContext();
+ Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ System.clearProperty(ContextInitializer.CONFIG_FILE_PROPERTY);
+ System.clearProperty(ContextInitializer.STATUS_LISTENER_CLASS);
+ }
+
+
+ @Test
+ @Ignore
+ // this test works only if logback-test.xml or logback.xml files are on the classpath.
+ // However, this is something we try to avoid in order to simplify the life
+ // of users trying to follow the manual and logback-examples from an IDE
+ public void reset() throws JoranException {
+ {
+ new ContextInitializer(loggerContext).autoConfig();
+ Appender appender = root.getAppender("STDOUT");
+ assertNotNull(appender);
+ assertTrue(appender instanceof ConsoleAppender);
}
-
- @Test
- public void shouldConfigureFromXmlFile() throws MalformedURLException, JoranException {
- LoggerContext loggerContext = new LoggerContext();
- ContextInitializer initializer = new ContextInitializer(loggerContext);
- assertNull(loggerContext.getObject(CoreConstants.SAFE_JORAN_CONFIGURATION));
-
- URL configurationFileUrl = Loader.getResource("BOO_logback-test.xml", Thread.currentThread().getContextClassLoader());
- initializer.configureByResource(configurationFileUrl);
-
- assertNotNull(loggerContext.getObject(CoreConstants.SAFE_JORAN_CONFIGURATION));
- }
-
- @Test
- public void shouldConfigureFromGroovyScript() throws MalformedURLException, JoranException {
- LoggerContext loggerContext = new LoggerContext();
- ContextInitializer initializer = new ContextInitializer(loggerContext);
- assertNull(loggerContext.getObject(CoreConstants.CONFIGURATION_WATCH_LIST));
-
- URL configurationFileUrl = Loader.getResource("test.groovy", Thread.currentThread().getContextClassLoader());
- initializer.configureByResource(configurationFileUrl);
-
- assertNotNull(loggerContext.getObject(CoreConstants.CONFIGURATION_WATCH_LIST));
- }
-
- @Test
- public void shouldThrowExceptionIfUnexpectedConfigurationFileExtension() throws JoranException {
- LoggerContext loggerContext = new LoggerContext();
- ContextInitializer initializer = new ContextInitializer(loggerContext);
-
- URL configurationFileUrl = Loader.getResource("README.txt", Thread.currentThread().getContextClassLoader());
- try {
- initializer.configureByResource(configurationFileUrl);
- fail("Should throw LogbackException");
- } catch (LogbackException expectedException) {
- // pass
- }
- }
-
- private static boolean isJDK5() {
- String ver = System.getProperty("java.version");
- boolean jdk5 = ver.startsWith("1.5.") || ver.equals("1.5");
- return jdk5;
+ {
+ loggerContext.stop();
+ Appender<ILoggingEvent> appender = root.getAppender("STDOUT");
+ assertNull(appender);
}
+ }
+
+ @Test
+ public void autoConfigFromSystemProperties() throws JoranException {
+ doAutoConfigFromSystemProperties(ClassicTestConstants.INPUT_PREFIX + "autoConfig.xml");
+ doAutoConfigFromSystemProperties("autoConfigAsResource.xml");
+ // test passing a URL. note the relative path syntax with file:src/test/...
+ doAutoConfigFromSystemProperties("file:"+ClassicTestConstants.INPUT_PREFIX + "autoConfig.xml");
+ }
+
+ public void doAutoConfigFromSystemProperties(String val) throws JoranException {
+ //lc.reset();
+ System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY, val);
+ new ContextInitializer(loggerContext).autoConfig();
+ Appender<ILoggingEvent> appender = root.getAppender("AUTO_BY_SYSTEM_PROPERTY");
+ assertNotNull(appender);
+ }
+
+ @Test
+ public void autoStatusListener() throws JoranException {
+ System.setProperty(ContextInitializer.STATUS_LISTENER_CLASS, TrivialStatusListener.class.getName());
+ List<StatusListener> statusListenerList = loggerContext.getStatusManager().getCopyOfStatusListenerList();
+ assertEquals(0, statusListenerList.size());
+ doAutoConfigFromSystemProperties(ClassicTestConstants.INPUT_PREFIX + "autoConfig.xml");
+ statusListenerList = loggerContext.getStatusManager().getCopyOfStatusListenerList();
+ assertTrue(statusListenerList.size() +" should be 1", statusListenerList.size() == 1);
+ // LOGBACK-767
+ TrivialStatusListener tsl = (TrivialStatusListener) statusListenerList.get(0);
+ assertTrue("expecting at least one event in list", tsl.list.size() > 0);
+ }
+
+ @Test
+ public void autoOnConsoleStatusListener() throws JoranException {
+ System.setProperty(ContextInitializer.STATUS_LISTENER_CLASS, ContextInitializer.SYSOUT);
+ List<StatusListener> sll = loggerContext.getStatusManager().getCopyOfStatusListenerList();
+ assertEquals(0, sll.size());
+ doAutoConfigFromSystemProperties(ClassicTestConstants.INPUT_PREFIX + "autoConfig.xml");
+ sll = loggerContext.getStatusManager().getCopyOfStatusListenerList();
+ assertTrue(sll.size() +" should be 1", sll.size() == 1);
+ }
+
+ @Test
+ public void shouldConfigureFromXmlFile() throws MalformedURLException, JoranException {
+ LoggerContext loggerContext = new LoggerContext();
+ ContextInitializer initializer = new ContextInitializer(loggerContext);
+ assertNull(loggerContext.getObject(CoreConstants.SAFE_JORAN_CONFIGURATION));
- private void setupMockServiceLoader() {
- final ClassLoader realLoader = EnvUtil.class.getClassLoader();
- EnvUtil.testServiceLoaderClassLoader = new WrappedClassLoader(realLoader) {
-
- @Override
- public Enumeration<URL> getResources(String name) throws IOException {
- final Enumeration<URL> r;
- if (name.endsWith("META-INF/services/ch.qos.logback.classic.spi.Configurator")) {
- Vector<URL> vs = new Vector<URL>();
- URL u = super.getResource("FAKE_META_INF_SERVICES_ch_qos_logback_classic_spi_Configurator");
- vs.add(u);
- return vs.elements();
- } else {
- r = super.getResources(name);
- }
- return r;
- }
- };
- }
-
- static class WrappedClassLoader extends ClassLoader {
- final ClassLoader delegate;
-
- public WrappedClassLoader(ClassLoader delegate) {
- super();
- this.delegate = delegate;
- }
-
- public Class<?> loadClass(String name) throws ClassNotFoundException {
- return delegate.loadClass(name);
- }
-
- public URL getResource(String name) {
- return delegate.getResource(name);
- }
-
- public Enumeration<URL> getResources(String name) throws IOException {
- return delegate.getResources(name);
- }
+ URL configurationFileUrl = Loader.getResource("BOO_logback-test.xml", Thread.currentThread().getContextClassLoader());
+ initializer.configureByResource(configurationFileUrl);
- public InputStream getResourceAsStream(String name) {
- return delegate.getResourceAsStream(name);
- }
+ assertNotNull(loggerContext.getObject(CoreConstants.SAFE_JORAN_CONFIGURATION));
+ }
- public void setDefaultAssertionStatus(boolean enabled) {
- delegate.setDefaultAssertionStatus(enabled);
- }
+ @Test
+ public void shouldConfigureFromGroovyScript() throws MalformedURLException, JoranException {
+ LoggerContext loggerContext = new LoggerContext();
+ ContextInitializer initializer = new ContextInitializer(loggerContext);
+ assertNull(loggerContext.getObject(CoreConstants.CONFIGURATION_WATCH_LIST));
- public void setPackageAssertionStatus(String packageName, boolean enabled) {
- delegate.setPackageAssertionStatus(packageName, enabled);
- }
+ URL configurationFileUrl = Loader.getResource("test.groovy", Thread.currentThread().getContextClassLoader());
+ initializer.configureByResource(configurationFileUrl);
- public void setClassAssertionStatus(String className, boolean enabled) {
- delegate.setClassAssertionStatus(className, enabled);
- }
+ assertNotNull(loggerContext.getObject(CoreConstants.CONFIGURATION_WATCH_LIST));
+ }
- public void clearAssertionStatus() {
- delegate.clearAssertionStatus();
- }
+ @Test
+ public void shouldThrowExceptionIfUnexpectedConfigurationFileExtension() throws JoranException {
+ LoggerContext loggerContext = new LoggerContext();
+ ContextInitializer initializer = new ContextInitializer(loggerContext);
+
+ URL configurationFileUrl = Loader.getResource("README.txt", Thread.currentThread().getContextClassLoader());
+ try {
+ initializer.configureByResource(configurationFileUrl);
+ fail("Should throw LogbackException");
+ } catch (LogbackException expectedException) {
+ // pass
}
-
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/util/InitializationIntegrationTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/util/InitializationIntegrationTest.java
index 89c717b..2f2a27c 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/util/InitializationIntegrationTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/util/InitializationIntegrationTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,15 +23,15 @@ import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertNotNull;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class InitializationIntegrationTest {
- @Test
- public void smoke() {
- Logger logger = (Logger) LoggerFactory.getLogger(this.getClass());
- Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
- ListAppender la = (ListAppender) root.getAppender("LIST");
- assertNotNull(la);
- }
+ @Test
+ public void smoke() {
+ Logger logger = (Logger) LoggerFactory.getLogger(this.getClass());
+ Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+ ListAppender la = (ListAppender) root.getAppender("LIST");
+ assertNotNull(la);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/util/LevelToSyslogSeverityTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/util/LevelToSyslogSeverityTest.java
index 7bbf739..0fa6e46 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/util/LevelToSyslogSeverityTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/util/LevelToSyslogSeverityTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,25 +24,30 @@ import ch.qos.logback.core.net.SyslogConstants;
public class LevelToSyslogSeverityTest {
- @Test
- public void smoke() {
+ @Test
+ public void smoke() {
- assertEquals(SyslogConstants.DEBUG_SEVERITY, LevelToSyslogSeverity.convert(createEventOfLevel(Level.TRACE)));
+ assertEquals(SyslogConstants.DEBUG_SEVERITY, LevelToSyslogSeverity
+ .convert(createEventOfLevel(Level.TRACE)));
- assertEquals(SyslogConstants.DEBUG_SEVERITY, LevelToSyslogSeverity.convert(createEventOfLevel(Level.DEBUG)));
+ assertEquals(SyslogConstants.DEBUG_SEVERITY, LevelToSyslogSeverity
+ .convert(createEventOfLevel(Level.DEBUG)));
- assertEquals(SyslogConstants.INFO_SEVERITY, LevelToSyslogSeverity.convert(createEventOfLevel(Level.INFO)));
+ assertEquals(SyslogConstants.INFO_SEVERITY, LevelToSyslogSeverity
+ .convert(createEventOfLevel(Level.INFO)));
- assertEquals(SyslogConstants.WARNING_SEVERITY, LevelToSyslogSeverity.convert(createEventOfLevel(Level.WARN)));
+ assertEquals(SyslogConstants.WARNING_SEVERITY, LevelToSyslogSeverity
+ .convert(createEventOfLevel(Level.WARN)));
- assertEquals(SyslogConstants.ERROR_SEVERITY, LevelToSyslogSeverity.convert(createEventOfLevel(Level.ERROR)));
+ assertEquals(SyslogConstants.ERROR_SEVERITY, LevelToSyslogSeverity
+ .convert(createEventOfLevel(Level.ERROR)));
- }
+ }
- ILoggingEvent createEventOfLevel(Level level) {
- LoggingEvent event = new LoggingEvent();
- event.setLevel(level);
- return event;
- }
+ ILoggingEvent createEventOfLevel(Level level) {
+ LoggingEvent event = new LoggingEvent();
+ event.setLevel(level);
+ return event;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/util/LogbackMDCAdapterTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/util/LogbackMDCAdapterTest.java
index 13c58a8..b0211e0 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/util/LogbackMDCAdapterTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/util/LogbackMDCAdapterTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,7 +16,6 @@ package ch.qos.logback.classic.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.util.HashMap;
@@ -28,226 +27,218 @@ import ch.qos.logback.core.testUtil.RandomUtil;
public class LogbackMDCAdapterTest {
- final static String A_SUFFIX = "A_SUFFIX";
- final static String B_SUFFIX = "B_SUFFIX";
-
- int diff = RandomUtil.getPositiveInt();
-
- private final LogbackMDCAdapter mdcAdapter = new LogbackMDCAdapter();
-
- /**
- * Test that CopyOnInheritThreadLocal does not barf when the
- * MDC hashmap is null
- *
- * @throws InterruptedException
- */
- @Test
- public void LOGBACK_442() throws InterruptedException {
- Map<String, String> parentHM = getMapFromMDCAdapter(mdcAdapter);
- assertNull(parentHM);
-
- ChildThreadForMDCAdapter childThread = new ChildThreadForMDCAdapter(mdcAdapter);
- childThread.start();
- childThread.join();
- assertTrue(childThread.successul);
- assertNull(childThread.childHM);
+ final static String A_SUFFIX = "A_SUFFIX";
+ final static String B_SUFFIX = "B_SUFFIX";
+
+ int diff = RandomUtil.getPositiveInt();
+
+ private final LogbackMDCAdapter mdcAdapter = new LogbackMDCAdapter();
+
+
+ /**
+ * Test that CopyOnInheritThreadLocal does not barf when the
+ * MDC hashmap is null
+ *
+ * @throws InterruptedException
+ */
+ @Test
+ public void lbclassic77Test() throws InterruptedException {
+ Map<String, String> parentHM = getMapFromMDCAdapter(mdcAdapter);
+ assertNull(parentHM);
+
+ ChildThreadForMDCAdapter childThread = new ChildThreadForMDCAdapter(mdcAdapter);
+ childThread.start();
+ childThread.join();
+ assertTrue(childThread.successul);
+ assertNull(childThread.childHM);
+ }
+
+ @Test
+ public void removeForNullKeyTest() {
+ mdcAdapter.remove(null);
+ }
+
+ @Test
+ public void removeInexistentKey() {
+ mdcAdapter.remove("abcdlw0");
+ }
+
+
+ @Test
+ public void sequenceWithGet() {
+ mdcAdapter.put("k0", "v0");
+ Map<String, String> map0 = mdcAdapter.copyOnInheritThreadLocal.get();
+ mdcAdapter.get("k0"); // point 0
+ mdcAdapter.put("k0", "v1");
+ // verify that map0 is that in point 0
+ assertEquals("v0", map0.get("k0"));
+ }
+
+ @Test
+ public void sequenceWithGetPropertyMap() {
+ mdcAdapter.put("k0", "v0");
+ Map<String, String> map0 = mdcAdapter.getPropertyMap(); // point 0
+ mdcAdapter.put("k0", "v1");
+ // verify that map0 is that in point 0
+ assertEquals("v0", map0.get("k0"));
+ }
+
+ // =================================================
+
+ /**
+ * Test that LogbackMDCAdapter copies its hashmap when a child
+ * thread inherits it.
+ *
+ * @throws InterruptedException
+ */
+ @Test
+ public void copyOnInheritenceTest() throws InterruptedException {
+ CountDownLatch countDownLatch = new CountDownLatch(1);
+ String firstKey = "x" + diff;
+ String secondKey = "o" + diff;
+ mdcAdapter.put(firstKey, firstKey + A_SUFFIX);
+
+ ChildThread childThread = new ChildThread(mdcAdapter, firstKey, secondKey, countDownLatch);
+ childThread.start();
+ countDownLatch.await();
+ mdcAdapter.put(firstKey, firstKey + B_SUFFIX);
+ childThread.join();
+
+ assertNull(mdcAdapter.get(secondKey));
+ assertTrue(childThread.successful);
+
+ Map<String, String> parentHM = getMapFromMDCAdapter(mdcAdapter);
+ assertTrue(parentHM != childThread.childHM);
+
+ HashMap<String, String> parentHMWitness = new HashMap<String, String>();
+ parentHMWitness.put(firstKey, firstKey + B_SUFFIX);
+ assertEquals(parentHMWitness, parentHM);
+
+ HashMap<String, String> childHMWitness = new HashMap<String, String>();
+ childHMWitness.put(firstKey, firstKey + A_SUFFIX);
+ childHMWitness.put(secondKey, secondKey + A_SUFFIX);
+ assertEquals(childHMWitness, childThread.childHM);
+
+ }
+
+ // see also http://jira.qos.ch/browse/LBCLASSIC-253
+ @Test
+ public void clearOnChildThreadShouldNotAffectParent() throws InterruptedException {
+ String firstKey = "x" + diff;
+ String secondKey = "o" + diff;
+
+ mdcAdapter.put(firstKey, firstKey + A_SUFFIX);
+ assertEquals(firstKey + A_SUFFIX, mdcAdapter.get(firstKey));
+
+ Thread clearer = new ChildThread(mdcAdapter, firstKey, secondKey) {
+ @Override
+ public void run() {
+ mdcAdapter.clear();
+ assertNull(mdcAdapter.get(firstKey));
+ }
+ };
+
+ clearer.start();
+ clearer.join();
+
+ assertEquals(firstKey + A_SUFFIX, mdcAdapter.get(firstKey));
+ }
+
+ // see http://jira.qos.ch/browse/LBCLASSIC-289
+ // this test used to fail without synchronization code in LogbackMDCAdapter
+ @Test
+ public void nearSimultaneousPutsShouldNotCauseConcurrentModificationException() throws InterruptedException {
+ // For the weirdest reason, modifications to mdcAdapter must be done
+ // before the definition anonymous ChildThread class below. Otherwise, the
+ // map in the child thread, the one contained in mdcAdapter.copyOnInheritThreadLocal,
+ // is null. How strange is that?
+
+ // let the map have lots of elements so that copying it takes time
+ for (int i = 0; i < 2048; i++) {
+ mdcAdapter.put("k" + i, "v" + i);
}
- @Test
- public void removeForNullKeyTest() {
- mdcAdapter.remove(null);
- }
-
- @Test
- public void removeInexistentKey() {
- mdcAdapter.remove("abcdlw0");
- }
+ ChildThread childThread = new ChildThread(mdcAdapter, null, null) {
+ @Override
+ public void run() {
+ for (int i = 0; i < 16; i++) {
+ mdcAdapter.put("ck" + i, "cv" + i);
+ Thread.yield();
+ }
+ successful = true;
+ }
+ };
- @Test
- public void sequenceWithGet() {
- mdcAdapter.put("k0", "v0");
- Map<String, String> map0 = mdcAdapter.copyOnThreadLocal.get();
- mdcAdapter.get("k0");
- mdcAdapter.put("k1", "v1"); // no map copy required
- // verify that map0 is the same instance and that value was updated
- assertSame(map0, mdcAdapter.copyOnThreadLocal.get());
+ childThread.start();
+ Thread.sleep(1);
+ for (int i = 0; i < 16; i++) {
+ mdcAdapter.put("K" + i, "V" + i);
}
+ childThread.join();
+ assertTrue(childThread.successful);
+ }
- @Test
- public void sequenceWithGetPropertyMap() {
- mdcAdapter.put("k0", "v0");
- Map<String, String> map0 = mdcAdapter.getPropertyMap(); // point 0
- mdcAdapter.put("k0", "v1"); // new map should be created
- // verify that map0 is that in point 0
- assertEquals("v0", map0.get("k0"));
- }
- @Test
- public void sequenceWithCopyContextMap() {
- mdcAdapter.put("k0", "v0");
- Map<String, String> map0 = mdcAdapter.copyOnThreadLocal.get();
- mdcAdapter.getCopyOfContextMap();
- mdcAdapter.put("k1", "v1"); // no map copy required
+ Map<String, String> getMapFromMDCAdapter(LogbackMDCAdapter lma) {
+ InheritableThreadLocal<Map<String, String>> copyOnInheritThreadLocal = lma.copyOnInheritThreadLocal;
+ return copyOnInheritThreadLocal.get();
+ }
- // verify that map0 is the same instance and that value was updated
- assertSame(map0, mdcAdapter.copyOnThreadLocal.get());
- }
+ // ========================== various thread classes
+ class ChildThreadForMDCAdapter extends Thread {
- // =================================================
-
- /**
- * Test that LogbackMDCAdapter does not copy its hashmap when a child
- * thread inherits it.
- *
- * @throws InterruptedException
- */
- @Test
- public void noCopyOnInheritenceTest() throws InterruptedException {
- CountDownLatch countDownLatch = new CountDownLatch(1);
- String firstKey = "x" + diff;
- String secondKey = "o" + diff;
- mdcAdapter.put(firstKey, firstKey + A_SUFFIX);
-
- ChildThread childThread = new ChildThread(mdcAdapter, firstKey, secondKey, countDownLatch);
- childThread.start();
- countDownLatch.await();
- mdcAdapter.put(firstKey, firstKey + B_SUFFIX);
- childThread.join();
-
- assertNull(mdcAdapter.get(secondKey));
- assertTrue(childThread.successful);
-
- Map<String, String> parentHM = getMapFromMDCAdapter(mdcAdapter);
- assertTrue(parentHM != childThread.childHM);
-
- HashMap<String, String> parentHMWitness = new HashMap<String, String>();
- parentHMWitness.put(firstKey, firstKey + B_SUFFIX);
- assertEquals(parentHMWitness, parentHM);
-
- HashMap<String, String> childHMWitness = new HashMap<String, String>();
- childHMWitness.put(secondKey, secondKey + A_SUFFIX);
- assertEquals(childHMWitness, childThread.childHM);
+ LogbackMDCAdapter logbackMDCAdapter;
+ boolean successul;
+ Map<String, String> childHM;
+ ChildThreadForMDCAdapter(LogbackMDCAdapter logbackMDCAdapter) {
+ this.logbackMDCAdapter = logbackMDCAdapter;
}
- // see also http://jira.qos.ch/browse/LBCLASSIC-253
- @Test
- public void clearOnChildThreadShouldNotAffectParent() throws InterruptedException {
- String firstKey = "x" + diff;
- String secondKey = "o" + diff;
-
- mdcAdapter.put(firstKey, firstKey + A_SUFFIX);
- assertEquals(firstKey + A_SUFFIX, mdcAdapter.get(firstKey));
+ @Override
+ public void run() {
+ childHM = getMapFromMDCAdapter(logbackMDCAdapter);
+ logbackMDCAdapter.get("");
+ successul = true;
+ }
+ }
- Thread clearer = new ChildThread(mdcAdapter, firstKey, secondKey) {
- @Override
- public void run() {
- mdcAdapter.clear();
- assertNull(mdcAdapter.get(firstKey));
- }
- };
- clearer.start();
- clearer.join();
+ class ChildThread extends Thread {
- assertEquals(firstKey + A_SUFFIX, mdcAdapter.get(firstKey));
- }
+ LogbackMDCAdapter logbackMDCAdapter;
+ String firstKey;
+ String secondKey;
+ boolean successful;
+ Map<String, String> childHM;
+ CountDownLatch countDownLatch;
- // see http://jira.qos.ch/browse/LBCLASSIC-289
- // this test used to fail without synchronization code in LogbackMDCAdapter
- @Test
- public void nearSimultaneousPutsShouldNotCauseConcurrentModificationException() throws InterruptedException {
- // For the weirdest reason, modifications to mdcAdapter must be done
- // before the definition anonymous ChildThread class below. Otherwise, the
- // map in the child thread, the one contained in mdcAdapter.copyOnInheritThreadLocal,
- // is null. How strange is that?
-
- // let the map have lots of elements so that copying it takes time
- for (int i = 0; i < 2048; i++) {
- mdcAdapter.put("k" + i, "v" + i);
- }
-
- ChildThread childThread = new ChildThread(mdcAdapter, null, null) {
- @Override
- public void run() {
- for (int i = 0; i < 16; i++) {
- mdcAdapter.put("ck" + i, "cv" + i);
- Thread.yield();
- }
- successful = true;
- }
- };
-
- childThread.start();
- Thread.sleep(1);
- for (int i = 0; i < 16; i++) {
- mdcAdapter.put("K" + i, "V" + i);
- }
- childThread.join();
- assertTrue(childThread.successful);
+ ChildThread(LogbackMDCAdapter logbackMDCAdapter) {
+ this(logbackMDCAdapter, null, null);
}
- Map<String, String> getMapFromMDCAdapter(LogbackMDCAdapter lma) {
- ThreadLocal<Map<String, String>> copyOnThreadLocal = lma.copyOnThreadLocal;
- return copyOnThreadLocal.get();
+ ChildThread(LogbackMDCAdapter logbackMDCAdapter, String firstKey, String secondKey) {
+ this(logbackMDCAdapter, firstKey, secondKey, null);
}
- // ========================== various thread classes
- class ChildThreadForMDCAdapter extends Thread {
-
- LogbackMDCAdapter logbackMDCAdapter;
- boolean successul;
- Map<String, String> childHM;
-
- ChildThreadForMDCAdapter(LogbackMDCAdapter logbackMDCAdapter) {
- this.logbackMDCAdapter = logbackMDCAdapter;
- }
-
- @Override
- public void run() {
- childHM = getMapFromMDCAdapter(logbackMDCAdapter);
- logbackMDCAdapter.get("");
- successul = true;
- }
+ ChildThread(LogbackMDCAdapter logbackMDCAdapter, String firstKey, String secondKey, CountDownLatch countDownLatch) {
+ super("chil");
+ this.logbackMDCAdapter = logbackMDCAdapter;
+ this.firstKey = firstKey;
+ this.secondKey = secondKey;
+ this.countDownLatch = countDownLatch;
}
- class ChildThread extends Thread {
-
- LogbackMDCAdapter logbackMDCAdapter;
- String firstKey;
- String secondKey;
- boolean successful;
- Map<String, String> childHM;
- CountDownLatch countDownLatch;
-
- ChildThread(LogbackMDCAdapter logbackMDCAdapter) {
- this(logbackMDCAdapter, null, null);
- }
-
- ChildThread(LogbackMDCAdapter logbackMDCAdapter, String firstKey, String secondKey) {
- this(logbackMDCAdapter, firstKey, secondKey, null);
- }
-
- ChildThread(LogbackMDCAdapter logbackMDCAdapter, String firstKey, String secondKey, CountDownLatch countDownLatch) {
- super("chil");
- this.logbackMDCAdapter = logbackMDCAdapter;
- this.firstKey = firstKey;
- this.secondKey = secondKey;
- this.countDownLatch = countDownLatch;
- }
-
- @Override
- public void run() {
- logbackMDCAdapter.put(secondKey, secondKey + A_SUFFIX);
- assertNull(logbackMDCAdapter.get(firstKey));
- if (countDownLatch != null)
- countDownLatch.countDown();
- assertNotNull(logbackMDCAdapter.get(secondKey));
- assertEquals(secondKey + A_SUFFIX, logbackMDCAdapter.get(secondKey));
-
- successful = true;
- childHM = getMapFromMDCAdapter(logbackMDCAdapter);
- }
+ @Override
+ public void run() {
+ logbackMDCAdapter.put(secondKey, secondKey + A_SUFFIX);
+ assertNotNull(logbackMDCAdapter.get(firstKey));
+ assertEquals(firstKey + A_SUFFIX, logbackMDCAdapter.get(firstKey));
+ if (countDownLatch != null) countDownLatch.countDown();
+ assertEquals(secondKey + A_SUFFIX, logbackMDCAdapter.get(secondKey));
+ successful = true;
+ childHM = getMapFromMDCAdapter(logbackMDCAdapter);
}
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/util/LoggerNameUtilTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/util/LoggerNameUtilTest.java
index 11ba0fe..d64ffdc 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/util/LoggerNameUtilTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/util/LoggerNameUtilTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,80 +22,81 @@ import static org.junit.Assert.assertEquals;
public class LoggerNameUtilTest {
- @Test
- public void smoke0() {
- List<String> witnessList = new ArrayList<String>();
- witnessList.add("a");
- witnessList.add("b");
- witnessList.add("c");
- List<String> partList = LoggerNameUtil.computeNameParts("a.b.c");
- assertEquals(witnessList, partList);
- }
-
- @Test
- public void smoke1() {
- List<String> witnessList = new ArrayList<String>();
- witnessList.add("com");
- witnessList.add("foo");
- witnessList.add("Bar");
- List<String> partList = LoggerNameUtil.computeNameParts("com.foo.Bar");
- assertEquals(witnessList, partList);
- }
-
- @Test
- public void emptyStringShouldReturnAListContainingOneEmptyString() {
- List<String> witnessList = new ArrayList<String>();
- witnessList.add("");
- List<String> partList = LoggerNameUtil.computeNameParts("");
- assertEquals(witnessList, partList);
- }
-
- @Test
- public void dotAtLastPositionShouldReturnAListWithAnEmptyStringAsLastElement() {
- List<String> witnessList = new ArrayList<String>();
- witnessList.add("com");
- witnessList.add("foo");
- witnessList.add("");
-
- List<String> partList = LoggerNameUtil.computeNameParts("com.foo.");
- assertEquals(witnessList, partList);
- }
-
- @Test
- public void supportNestedClasses() {
- List<String> witnessList = new ArrayList<String>();
- witnessList.add("com");
- witnessList.add("foo");
- witnessList.add("Bar");
- witnessList.add("Nested");
-
- List<String> partList = LoggerNameUtil.computeNameParts("com.foo.Bar$Nested");
- assertEquals(witnessList, partList);
- }
-
- @Test
- public void supportNestedClassesWithNestedDot() {
- // LOGBACK-384
- List<String> witnessList = new ArrayList<String>();
- witnessList.add("com");
- witnessList.add("foo");
- witnessList.add("Bar");
- witnessList.add("Nested");
- witnessList.add("dot");
-
- List<String> partList = LoggerNameUtil.computeNameParts("com.foo.Bar$Nested.dot");
- assertEquals(witnessList, partList);
- }
-
- @Test
- public void supportNestedClassesAtBeginning() {
- List<String> witnessList = new ArrayList<String>();
- witnessList.add("foo");
- witnessList.add("Nested");
- witnessList.add("bar");
-
- List<String> partList = LoggerNameUtil.computeNameParts("foo$Nested.bar");
- assertEquals(witnessList, partList);
- }
+
+ @Test
+ public void smoke0() {
+ List<String> witnessList = new ArrayList<String>();
+ witnessList.add("a");
+ witnessList.add("b");
+ witnessList.add("c");
+ List<String> partList = LoggerNameUtil.computeNameParts("a.b.c");
+ assertEquals(witnessList, partList);
+ }
+
+ @Test
+ public void smoke1() {
+ List<String> witnessList = new ArrayList<String>();
+ witnessList.add("com");
+ witnessList.add("foo");
+ witnessList.add("Bar");
+ List<String> partList = LoggerNameUtil.computeNameParts("com.foo.Bar");
+ assertEquals(witnessList, partList);
+ }
+
+ @Test
+ public void emptyStringShouldReturnAListContainingOneEmptyString() {
+ List<String> witnessList = new ArrayList<String>();
+ witnessList.add("");
+ List<String> partList = LoggerNameUtil.computeNameParts("");
+ assertEquals(witnessList, partList);
+ }
+
+ @Test
+ public void dotAtLastPositionShouldReturnAListWithAnEmptyStringAsLastElement() {
+ List<String> witnessList = new ArrayList<String>();
+ witnessList.add("com");
+ witnessList.add("foo");
+ witnessList.add("");
+
+ List<String> partList = LoggerNameUtil.computeNameParts("com.foo.");
+ assertEquals(witnessList, partList);
+ }
+
+ @Test
+ public void supportNestedClasses() {
+ List<String> witnessList = new ArrayList<String>();
+ witnessList.add("com");
+ witnessList.add("foo");
+ witnessList.add("Bar");
+ witnessList.add("Nested");
+
+ List<String> partList = LoggerNameUtil.computeNameParts("com.foo.Bar$Nested");
+ assertEquals(witnessList, partList);
+ }
+
+ @Test
+ public void supportNestedClassesWithNestedDot() {
+ //LOGBACK-384
+ List<String> witnessList = new ArrayList<String>();
+ witnessList.add("com");
+ witnessList.add("foo");
+ witnessList.add("Bar");
+ witnessList.add("Nested");
+ witnessList.add("dot");
+
+ List<String> partList = LoggerNameUtil.computeNameParts("com.foo.Bar$Nested.dot");
+ assertEquals(witnessList, partList);
+ }
+
+ @Test
+ public void supportNestedClassesAtBeginning() {
+ List<String> witnessList = new ArrayList<String>();
+ witnessList.add("foo");
+ witnessList.add("Nested");
+ witnessList.add("bar");
+
+ List<String> partList = LoggerNameUtil.computeNameParts("foo$Nested.bar");
+ assertEquals(witnessList, partList);
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/util/MockConfigurator.java b/logback-classic/src/test/java/ch/qos/logback/classic/util/MockConfigurator.java
deleted file mode 100644
index 89e9e46..0000000
--- a/logback-classic/src/test/java/ch/qos/logback/classic/util/MockConfigurator.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.classic.util;
-
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.spi.Configurator;
-import ch.qos.logback.core.spi.ContextAwareBase;
-
-public class MockConfigurator extends ContextAwareBase implements Configurator {
-
- static LoggerContext context = null;
-
- public void configure(LoggerContext loggerContext) {
- context = loggerContext;
- }
-}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/util/MockInitialContext.java b/logback-classic/src/test/java/ch/qos/logback/classic/util/MockInitialContext.java
index 7f77077..4637eb9 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/util/MockInitialContext.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/util/MockInitialContext.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,19 +21,19 @@ import javax.naming.NamingException;
public class MockInitialContext extends InitialContext {
- public Map<String, Object> map = new HashMap<String, Object>();
+ public Map<String, Object> map = new HashMap<String, Object>();
- public MockInitialContext() throws NamingException {
- super();
- }
-
- @Override
- public Object lookup(String name) throws NamingException {
- if (name == null) {
- return null;
- }
+ public MockInitialContext() throws NamingException {
+ super();
+ }
- return map.get(name);
+ @Override
+ public Object lookup(String name) throws NamingException {
+ if (name == null) {
+ return null;
}
+ return map.get(name);
+ }
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/util/MockInitialContextFactory.java b/logback-classic/src/test/java/ch/qos/logback/classic/util/MockInitialContextFactory.java
index 9d869d4..6e1d17b 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/util/MockInitialContextFactory.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/util/MockInitialContextFactory.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,28 +19,30 @@ import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;
-public class MockInitialContextFactory implements InitialContextFactory {
- static MockInitialContext mic;
-
- static {
- System.out.println("MockInitialContextFactory static called");
- initialize();
- }
-
- public static void initialize() {
- try {
- mic = new MockInitialContext();
- } catch (NamingException e) {
- e.printStackTrace();
- }
- }
-
- public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
- return mic;
- }
- public static MockInitialContext getContext() {
- return mic;
+public class MockInitialContextFactory implements InitialContextFactory {
+ static MockInitialContext mic;
+
+ static {
+ System.out.println("MockInitialContextFactory static called");
+ initialize();
+ }
+
+ public static void initialize() {
+ try {
+ mic = new MockInitialContext();
+ } catch (NamingException e) {
+ e.printStackTrace();
}
+ }
+
+ public Context getInitialContext(Hashtable<?, ?> environment)
+ throws NamingException {
+ return mic;
+ }
+
+ public static MockInitialContext getContext() {
+ return mic;
+ }
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/util/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/util/PackageTest.java
index a8afd31..0ff9b35 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/util/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/util/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,11 +13,14 @@
*/
package ch.qos.logback.classic.util;
+
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ ContextInitializerTest.class, ContextInitializerAutoConfigTest.class, LogbackMDCAdapterTest.class, LevelToSyslogSeverityTest.class })
+ at SuiteClasses({ContextInitializerTest.class, ContextInitializerAutoConfigTest.class,
+ LogbackMDCAdapterTest.class, LevelToSyslogSeverityTest.class})
+
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/util/TestHelper.java b/logback-classic/src/test/java/ch/qos/logback/classic/util/TestHelper.java
deleted file mode 100644
index 8abc399..0000000
--- a/logback-classic/src/test/java/ch/qos/logback/classic/util/TestHelper.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.classic.util;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-public class TestHelper {
-
- private static final Method ADD_SUPPRESSED_METHOD;
-
- static {
- Method method = null;
- try {
- method = Throwable.class.getMethod("addSuppressed", Throwable.class);
- } catch (NoSuchMethodException e) {
- // ignore, will get thrown in Java < 7
- }
- ADD_SUPPRESSED_METHOD = method;
- }
-
- public static boolean suppressedSupported() {
- return ADD_SUPPRESSED_METHOD != null;
- }
-
- public static void addSuppressed(Throwable outer, Throwable suppressed) throws InvocationTargetException, IllegalAccessException {
- if (suppressedSupported()) {
- ADD_SUPPRESSED_METHOD.invoke(outer, suppressed);
- }
- }
-
- static public Throwable makeNestedException(int level) {
- if (level == 0) {
- return new Exception("nesting level=" + level);
- }
- Throwable cause = makeNestedException(level - 1);
- return new Exception("nesting level =" + level, cause);
- }
-
- /**
- * Usage:
- * <pre>
- * String s = "123";
- * positionOf("1").in(s) < positionOf("3").in(s)
- * </pre>
- *
- * @param pattern Plain text to be found
- * @return StringPosition fluent interface
- */
- public static StringPosition positionOf(String pattern) {
- return new StringPosition(pattern);
- }
-
- public static class StringPosition {
- private final String pattern;
-
- public StringPosition(String pattern) {
- this.pattern = pattern;
- }
-
- public int in(String s) {
- final int position = s.indexOf(pattern);
- if (position < 0)
- throw new IllegalArgumentException("String '" + pattern + "' not found in: '" + s + "'");
- return position;
- }
-
- }
-
-}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/util/TeztHelper.java b/logback-classic/src/test/java/ch/qos/logback/classic/util/TeztHelper.java
new file mode 100644
index 0000000..b659511
--- /dev/null
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/util/TeztHelper.java
@@ -0,0 +1,81 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.util;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class TeztHelper {
+
+ private static final Method ADD_SUPPRESSED_METHOD;
+
+ static {
+ Method method = null;
+ try {
+ method = Throwable.class.getMethod("addSuppressed", Throwable.class);
+ } catch (NoSuchMethodException e) {
+ // ignore, will get thrown in Java < 7
+ }
+ ADD_SUPPRESSED_METHOD = method;
+ }
+
+ public static boolean suppressedSupported() {
+ return ADD_SUPPRESSED_METHOD != null;
+ }
+
+ public static void addSuppressed(Throwable outer, Throwable suppressed) throws InvocationTargetException, IllegalAccessException {
+ if(suppressedSupported()) {
+ ADD_SUPPRESSED_METHOD.invoke(outer, suppressed);
+ }
+ }
+
+ static public Throwable makeNestedException(int level) {
+ if (level == 0) {
+ return new Exception("nesting level=" + level);
+ }
+ Throwable cause = makeNestedException(level - 1);
+ return new Exception("nesting level =" + level, cause);
+ }
+
+ /**
+ * Usage:
+ * <pre>
+ * String s = "123";
+ * positionOf("1").in(s) < positionOf("3").in(s)
+ * </pre>
+ *
+ * @param pattern Plain text to be found
+ * @return StringPosition fluent interface
+ */
+ public static StringPosition positionOf(String pattern) {
+ return new StringPosition(pattern);
+ }
+
+ public static class StringPosition {
+ private final String pattern;
+
+ public StringPosition(String pattern) {
+ this.pattern = pattern;
+ }
+
+ public int in(String s) {
+ final int position = s.indexOf(pattern);
+ if(position < 0)
+ throw new IllegalArgumentException("String '" + pattern + "' not found in: '" + s + "'");
+ return position;
+ }
+
+ }
+
+}
diff --git a/logback-classic/src/test/java/integrator/Activator.java b/logback-classic/src/test/java/integrator/Activator.java
index df5ce0d..14a658e 100644
--- a/logback-classic/src/test/java/integrator/Activator.java
+++ b/logback-classic/src/test/java/integrator/Activator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,38 +31,39 @@ import ch.qos.logback.core.util.StatusPrinter;
*/
public class Activator implements BundleActivator {
- private BundleContext m_context = null;
+ private BundleContext m_context = null;
- public void start(BundleContext context) {
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
-
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- // the context was probably already configured by default configuration
- // rules
- lc.reset();
- configurator.doConfigure("src/test/input/osgi/simple.xml");
- } catch (JoranException je) {
- je.printStackTrace();
- }
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
-
- Logger logger = LoggerFactory.getLogger(this.getClass());
- logger.info("Activator.start()");
- m_context = context;
+ public void start(BundleContext context) {
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+
+ try {
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ // the context was probably already configured by default configuration
+ // rules
+ lc.reset();
+ configurator.doConfigure("src/test/input/osgi/simple.xml");
+ } catch (JoranException je) {
+ je.printStackTrace();
}
+ StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
- public void stop(BundleContext context) {
- m_context = null;
- Logger logger = LoggerFactory.getLogger(this.getClass());
- logger.info("Activator.stop");
- }
+
+ Logger logger = LoggerFactory.getLogger(this.getClass());
+ logger.info("Activator.start()");
+ m_context = context;
+ }
+
+ public void stop(BundleContext context) {
+ m_context = null;
+ Logger logger = LoggerFactory.getLogger(this.getClass());
+ logger.info("Activator.stop");
+ }
- public Bundle[] getBundles() {
- if (m_context != null) {
- return m_context.getBundles();
- }
- return null;
+ public Bundle[] getBundles() {
+ if (m_context != null) {
+ return m_context.getBundles();
}
+ return null;
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/org/dummy/DummyLBAppender.java b/logback-classic/src/test/java/org/dummy/DummyLBAppender.java
index ef75bc5..ec5b0ab 100644
--- a/logback-classic/src/test/java/org/dummy/DummyLBAppender.java
+++ b/logback-classic/src/test/java/org/dummy/DummyLBAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,24 +22,24 @@ import ch.qos.logback.core.AppenderBase;
public class DummyLBAppender extends AppenderBase<ILoggingEvent> {
- public List<ILoggingEvent> list = new ArrayList<ILoggingEvent>();
- public List<String> stringList = new ArrayList<String>();
-
- PatternLayout layout;
-
- DummyLBAppender() {
- this(null);
- }
-
- DummyLBAppender(PatternLayout layout) {
- this.layout = layout;
- }
-
- protected void append(ILoggingEvent e) {
- list.add(e);
- if (layout != null) {
- String s = layout.doLayout(e);
- stringList.add(s);
- }
+ public List<ILoggingEvent> list = new ArrayList<ILoggingEvent>();
+ public List<String> stringList = new ArrayList<String>();
+
+ PatternLayout layout;
+
+ DummyLBAppender() {
+ this(null);
+ }
+
+ DummyLBAppender(PatternLayout layout) {
+ this.layout = layout;
+ }
+
+ protected void append(ILoggingEvent e) {
+ list.add(e);
+ if(layout != null) {
+ String s = layout.doLayout(e);
+ stringList.add(s);
}
+ }
}
diff --git a/logback-classic/src/test/java/org/dummy/Log4jInvocation.java b/logback-classic/src/test/java/org/dummy/Log4jInvocation.java
index c19511b..1d72ce5 100644
--- a/logback-classic/src/test/java/org/dummy/Log4jInvocation.java
+++ b/logback-classic/src/test/java/org/dummy/Log4jInvocation.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -33,58 +33,59 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
*/
public class Log4jInvocation {
- static final String HELLO = "Hello";
-
- DummyLBAppender listAppender;
- LoggerContext lc;
- ch.qos.logback.classic.Logger rootLogger;
-
- @Before
- public void fixture() {
- lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- lc.reset();
-
- listAppender = new DummyLBAppender();
- listAppender.setContext(lc);
- listAppender.start();
- rootLogger = lc.getLogger("root");
- rootLogger.addAppender(listAppender);
- }
-
- @Test
- public void basic() {
- assertEquals(0, listAppender.list.size());
-
- Logger logger = Logger.getLogger("basic-test");
- logger.debug(HELLO);
-
- assertEquals(1, listAppender.list.size());
- ILoggingEvent event = (ILoggingEvent) listAppender.list.get(0);
- assertEquals(HELLO, event.getMessage());
- }
-
- @Test
- public void callerData() {
- assertEquals(0, listAppender.list.size());
-
- PatternLayout pl = new PatternLayout();
- pl.setPattern("%-5level [%class] %logger - %msg");
- pl.setContext(lc);
- pl.start();
- listAppender.layout = pl;
-
- Logger logger = Logger.getLogger("basic-test");
- logger.trace("none");
- assertEquals(0, listAppender.list.size());
-
- rootLogger.setLevel(Level.TRACE);
- logger.trace(HELLO);
- assertEquals(1, listAppender.list.size());
-
- ILoggingEvent event = (ILoggingEvent) listAppender.list.get(0);
- assertEquals(HELLO, event.getMessage());
-
- assertEquals(1, listAppender.stringList.size());
- assertEquals("TRACE [" + Log4jInvocation.class.getName() + "] basic-test - Hello", listAppender.stringList.get(0));
- }
+ static final String HELLO = "Hello";
+
+ DummyLBAppender listAppender;
+ LoggerContext lc;
+ ch.qos.logback.classic.Logger rootLogger;
+
+ @Before
+ public void fixture() {
+ lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ lc.reset();
+
+ listAppender = new DummyLBAppender();
+ listAppender.setContext(lc);
+ listAppender.start();
+ rootLogger = lc.getLogger("root");
+ rootLogger.addAppender(listAppender);
+ }
+
+ @Test
+ public void basic() {
+ assertEquals(0, listAppender.list.size());
+
+ Logger logger = Logger.getLogger("basic-test");
+ logger.debug(HELLO);
+
+ assertEquals(1, listAppender.list.size());
+ ILoggingEvent event = (ILoggingEvent) listAppender.list.get(0);
+ assertEquals(HELLO, event.getMessage());
+ }
+
+ @Test
+ public void callerData() {
+ assertEquals(0, listAppender.list.size());
+
+ PatternLayout pl = new PatternLayout();
+ pl.setPattern("%-5level [%class] %logger - %msg");
+ pl.setContext(lc);
+ pl.start();
+ listAppender.layout = pl;
+
+ Logger logger = Logger.getLogger("basic-test");
+ logger.trace("none");
+ assertEquals(0, listAppender.list.size());
+
+ rootLogger.setLevel(Level.TRACE);
+ logger.trace(HELLO);
+ assertEquals(1, listAppender.list.size());
+
+ ILoggingEvent event = (ILoggingEvent) listAppender.list.get(0);
+ assertEquals(HELLO, event.getMessage());
+
+ assertEquals(1, listAppender.stringList.size());
+ assertEquals("TRACE [" + Log4jInvocation.class.getName()
+ + "] basic-test - Hello", listAppender.stringList.get(0));
+ }
}
diff --git a/logback-classic/src/test/java/org/slf4j/LoggerFactoryFriend.java b/logback-classic/src/test/java/org/slf4j/LoggerFactoryFriend.java
index 166b4d7..d50cf85 100644
--- a/logback-classic/src/test/java/org/slf4j/LoggerFactoryFriend.java
+++ b/logback-classic/src/test/java/org/slf4j/LoggerFactoryFriend.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,7 +14,7 @@
package org.slf4j;
public class LoggerFactoryFriend {
- static public void reset() {
- LoggerFactory.reset();
- }
+ static public void reset() {
+ LoggerFactory.reset();
+ }
}
diff --git a/logback-classic/src/test/java/org/slf4j/impl/InitializationOutputTest.java b/logback-classic/src/test/java/org/slf4j/impl/InitializationOutputTest.java
index ad506d3..ed3d335 100644
--- a/logback-classic/src/test/java/org/slf4j/impl/InitializationOutputTest.java
+++ b/logback-classic/src/test/java/org/slf4j/impl/InitializationOutputTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,11 +15,9 @@ package org.slf4j.impl;
import ch.qos.logback.classic.ClassicTestConstants;
import ch.qos.logback.classic.util.ContextInitializer;
-import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.status.NopStatusListener;
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.util.TeeOutputStream;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -27,45 +25,47 @@ import org.junit.Test;
import java.io.PrintStream;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class InitializationOutputTest {
- int diff = RandomUtil.getPositiveInt();
+ int diff = RandomUtil.getPositiveInt();
+
+ TeeOutputStream tee;
+ PrintStream original;
- TeeOutputStream tee;
- PrintStream original;
+ @Before
+ public void setUp() {
+ original = System.out;
+ // tee will output bytes on System out but it will also
+ // collect them so that the output can be compared against
+ // some expected output data
- @Before
- public void setUp() {
- original = System.out;
- // tee will output bytes on System out but it will also
- // collect them so that the output can be compared against
- // some expected output data
+ // keep the console quiet
+ tee = new TeeOutputStream(null);
- // keep the console quiet
- tee = new TeeOutputStream(null);
+ // redirect System.out to tee
+ System.setOut(new PrintStream(tee));
+ }
- // redirect System.out to tee
- System.setOut(new PrintStream(tee));
- }
+ @After
+ public void tearDown() {
+ System.setOut(original);
+ System.clearProperty(ContextInitializer.CONFIG_FILE_PROPERTY);
+ System.clearProperty(ContextInitializer.STATUS_LISTENER_CLASS);
+ }
- @After
- public void tearDown() {
- System.setOut(original);
- System.clearProperty(ContextInitializer.CONFIG_FILE_PROPERTY);
- System.clearProperty(CoreConstants.STATUS_LISTENER_CLASS);
- }
- @Test
- public void noOutputIfContextHasAStatusListener() {
- System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY, ClassicTestConstants.INPUT_PREFIX + "issue/logback292.xml");
- System.setProperty(CoreConstants.STATUS_LISTENER_CLASS, NopStatusListener.class.getName());
+ @Test
+ public void noOutputIfContextHasAStatusListener() {
+ System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY, ClassicTestConstants.INPUT_PREFIX + "issue/logback292.xml");
+ System.setProperty(ContextInitializer.STATUS_LISTENER_CLASS, NopStatusListener.class.getName());
- StaticLoggerBinderFriend.reset();
- assertEquals(0, tee.baos.size());
- }
+ StaticLoggerBinderFriend.reset();
+ assertEquals(0, tee.baos.size());
+ }
}
diff --git a/logback-classic/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java b/logback-classic/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java
deleted file mode 100644
index 6d6d887..0000000
--- a/logback-classic/src/test/java/org/slf4j/impl/MultithreadedInitializationTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package org.slf4j.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.BrokenBarrierException;
-import java.util.concurrent.CyclicBarrier;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.LoggerFactoryFriend;
-
-import ch.qos.logback.classic.ClassicTestConstants;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.classic.util.ContextInitializer;
-import ch.qos.logback.core.read.ListAppender;
-
-public class MultithreadedInitializationTest {
-
- final static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2;
- private static AtomicLong EVENT_COUNT = new AtomicLong(0);
- final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
-
- int diff = new Random().nextInt(10000);
- String loggerName = "org.slf4j.impl.MultithreadedInitializationTest";
-
- @Before
- public void setUp() throws Exception {
- System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY, ClassicTestConstants.INPUT_PREFIX + "listAppender.xml");
- LoggerFactoryFriend.reset();
- }
-
- @After
- public void tearDown() throws Exception {
- System.clearProperty(ContextInitializer.CONFIG_FILE_PROPERTY);
- }
-
- @Test
- public void multiThreadedInitialization() throws InterruptedException, BrokenBarrierException {
- LoggerAccessingThread[] accessors = harness();
-
- for (LoggerAccessingThread accessor : accessors) {
- EVENT_COUNT.getAndIncrement();
- accessor.logger.info("post harness");
- }
-
- Logger logger = LoggerFactory.getLogger(loggerName + ".slowInitialization-" + diff);
- logger.info("hello");
- EVENT_COUNT.getAndIncrement();
-
- List<ILoggingEvent> events = getRecordedEvents();
- assertEquals(EVENT_COUNT.get(), events.size());
- }
-
- private List<ILoggingEvent> getRecordedEvents() {
- ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
-
- ListAppender<ILoggingEvent> la = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
- assertNotNull(la);
- return la.list;
- }
-
- private static LoggerAccessingThread[] harness() throws InterruptedException, BrokenBarrierException {
- LoggerAccessingThread[] threads = new LoggerAccessingThread[THREAD_COUNT];
- final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
- for (int i = 0; i < THREAD_COUNT; i++) {
- threads[i] = new LoggerAccessingThread(barrier, i);
- threads[i].start();
- }
-
- barrier.await();
- for (int i = 0; i < THREAD_COUNT; i++) {
- threads[i].join();
- }
- return threads;
- }
-
- static class LoggerAccessingThread extends Thread {
- final CyclicBarrier barrier;
- Logger logger;
- int count;
-
- LoggerAccessingThread(CyclicBarrier barrier, int count) {
- this.barrier = barrier;
- this.count = count;
- }
-
- public void run() {
- try {
- barrier.await();
- } catch (Exception e) {
- e.printStackTrace();
- }
- logger = LoggerFactory.getLogger(this.getClass().getName() + "-" + count);
- logger.info("in run method");
- EVENT_COUNT.getAndIncrement();
- }
- };
-
-}
diff --git a/logback-classic/src/test/java/org/slf4j/impl/PackageTest.java b/logback-classic/src/test/java/org/slf4j/impl/PackageTest.java
index e78d733..9c718e2 100644
--- a/logback-classic/src/test/java/org/slf4j/impl/PackageTest.java
+++ b/logback-classic/src/test/java/org/slf4j/impl/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,7 +20,7 @@ import org.junit.runners.Suite.SuiteClasses;
import ch.qos.logback.classic.LoggerPerfTest;
@RunWith(Suite.class)
- at SuiteClasses({ RecursiveInitializationTest.class, LoggerPerfTest.class, InitializationOutputTest.class })
+ at SuiteClasses( { RecursiveInitializationTest.class, LoggerPerfTest.class, InitializationOutputTest.class})
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/org/slf4j/impl/RecursiveInitializationTest.java b/logback-classic/src/test/java/org/slf4j/impl/RecursiveInitializationTest.java
index e27ad9d..1b8afc5 100644
--- a/logback-classic/src/test/java/org/slf4j/impl/RecursiveInitializationTest.java
+++ b/logback-classic/src/test/java/org/slf4j/impl/RecursiveInitializationTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,29 +31,33 @@ import ch.qos.logback.core.util.StatusPrinter;
public class RecursiveInitializationTest {
- int diff = RandomUtil.getPositiveInt();
-
- @Before
- public void setUp() throws Exception {
- System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY, "recursiveInit.xml");
- StaticLoggerBinderFriend.reset();
- LoggerFactoryFriend.reset();
- }
-
- @After
- public void tearDown() throws Exception {
- System.clearProperty(ContextInitializer.CONFIG_FILE_PROPERTY);
- }
-
- @Test
- public void recursiveLogbackInitialization() {
- Logger logger = LoggerFactory.getLogger("RecursiveInitializationTest" + diff);
- logger.info("RecursiveInitializationTest");
-
- LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
- StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
- StatusChecker statusChecker = new StatusChecker(loggerContext);
- assertEquals("Was expecting no errors", Status.WARN, statusChecker.getHighestLevel(0));
- }
+ int diff = RandomUtil.getPositiveInt();
+
+ @Before
+ public void setUp() throws Exception {
+ System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY,
+ "recursiveInit.xml");
+ StaticLoggerBinderFriend.reset();
+ LoggerFactoryFriend.reset();
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ System.clearProperty(ContextInitializer.CONFIG_FILE_PROPERTY);
+ }
+
+ @Test
+ public void recursiveLogbackInitialization() {
+ Logger logger = LoggerFactory.getLogger("RecursiveInitializationTest"
+ + diff);
+ logger.info("RecursiveInitializationTest");
+
+ LoggerContext loggerContext = (LoggerContext) LoggerFactory
+ .getILoggerFactory();
+ StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
+ StatusChecker statusChecker = new StatusChecker(loggerContext);
+ assertEquals("Was expecting no errors", Status.WARN, statusChecker.getHighestLevel(0));
+ }
}
diff --git a/logback-classic/src/test/java/org/slf4j/impl/RecursiveLBAppender.java b/logback-classic/src/test/java/org/slf4j/impl/RecursiveLBAppender.java
index b1f7724..15785c5 100644
--- a/logback-classic/src/test/java/org/slf4j/impl/RecursiveLBAppender.java
+++ b/logback-classic/src/test/java/org/slf4j/impl/RecursiveLBAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,32 +26,32 @@ import ch.qos.logback.core.testUtil.RandomUtil;
public class RecursiveLBAppender extends AppenderBase<ILoggingEvent> {
- public List<ILoggingEvent> list = new ArrayList<ILoggingEvent>();
- public List<String> stringList = new ArrayList<String>();
-
- PatternLayout layout;
-
- public RecursiveLBAppender() {
- this(null);
- }
-
- public RecursiveLBAppender(PatternLayout layout) {
- this.layout = layout;
- }
-
- @Override
- public void start() {
- int diff = RandomUtil.getPositiveInt();
- Logger logger = LoggerFactory.getLogger("ResursiveLBAppender" + diff);
- logger.info("testing");
- super.start();
- }
-
- protected void append(ILoggingEvent e) {
- list.add(e);
- if (layout != null) {
- String s = layout.doLayout(e);
- stringList.add(s);
- }
+ public List<ILoggingEvent> list = new ArrayList<ILoggingEvent>();
+ public List<String> stringList = new ArrayList<String>();
+
+ PatternLayout layout;
+
+ public RecursiveLBAppender() {
+ this(null);
+ }
+
+ public RecursiveLBAppender(PatternLayout layout) {
+ this.layout = layout;
+ }
+
+ @Override
+ public void start() {
+ int diff = RandomUtil.getPositiveInt();
+ Logger logger = LoggerFactory.getLogger("ResursiveLBAppender"+diff);
+ logger.info("testing");
+ super.start();
+ }
+
+ protected void append(ILoggingEvent e) {
+ list.add(e);
+ if(layout != null) {
+ String s = layout.doLayout(e);
+ stringList.add(s);
}
+ }
}
diff --git a/logback-classic/src/test/java/org/slf4j/impl/StaticLoggerBinderFriend.java b/logback-classic/src/test/java/org/slf4j/impl/StaticLoggerBinderFriend.java
index 1891d9e..3831d42 100644
--- a/logback-classic/src/test/java/org/slf4j/impl/StaticLoggerBinderFriend.java
+++ b/logback-classic/src/test/java/org/slf4j/impl/StaticLoggerBinderFriend.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,9 +21,9 @@ package org.slf4j.impl;
*
*/
public class StaticLoggerBinderFriend {
-
- static public void reset() {
- StaticLoggerBinder.reset();
- }
+
+ static public void reset() {
+ StaticLoggerBinder.reset();
+ }
}
diff --git a/logback-classic/src/test/java/org/slf4j/test_osgi/BundleTest.java b/logback-classic/src/test/java/org/slf4j/test_osgi/BundleTest.java
index 64f83b4..4a0c3b9 100644
--- a/logback-classic/src/test/java/org/slf4j/test_osgi/BundleTest.java
+++ b/logback-classic/src/test/java/org/slf4j/test_osgi/BundleTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,30 +19,30 @@ import junit.framework.TestCase;
public class BundleTest extends TestCase {
- FrameworkErrorListener fel = new FrameworkErrorListener();
- CheckingBundleListener mbl = new CheckingBundleListener();
-
- FelixHost felixHost = new FelixHost(fel, mbl);
-
- protected void setUp() throws Exception {
- super.setUp();
- felixHost.doLaunch();
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- felixHost.stop();
- }
-
- public void testSmoke() {
- System.out.println("===========" + new File(".").getAbsolutePath());
- mbl.dumpAll();
- // check that the bundle was installed
- assertTrue(mbl.exists("iBundle"));
- if (fel.errorList.size() != 0) {
- fel.dumpAll();
- }
- // check that no errors occured
- assertEquals(0, fel.errorList.size());
+ FrameworkErrorListener fel = new FrameworkErrorListener();
+ CheckingBundleListener mbl = new CheckingBundleListener();
+
+ FelixHost felixHost = new FelixHost(fel, mbl);
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ felixHost.doLaunch();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ felixHost.stop();
+ }
+
+ public void testSmoke() {
+ System.out.println("==========="+new File(".").getAbsolutePath());
+ mbl.dumpAll();
+ // check that the bundle was installed
+ assertTrue(mbl.exists("iBundle"));
+ if(fel.errorList.size() != 0) {
+ fel.dumpAll();
}
+ // check that no errors occured
+ assertEquals(0, fel.errorList.size());
+ }
}
diff --git a/logback-classic/src/test/java/org/slf4j/test_osgi/CheckingBundleListener.java b/logback-classic/src/test/java/org/slf4j/test_osgi/CheckingBundleListener.java
index fe9a961..b1c71da 100644
--- a/logback-classic/src/test/java/org/slf4j/test_osgi/CheckingBundleListener.java
+++ b/logback-classic/src/test/java/org/slf4j/test_osgi/CheckingBundleListener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,35 +22,36 @@ import org.osgi.framework.BundleListener;
public class CheckingBundleListener implements BundleListener {
- List eventList = new ArrayList();
+ List eventList = new ArrayList();
- @SuppressWarnings("unchecked")
- public void bundleChanged(BundleEvent be) {
- eventList.add(be);
- }
+ @SuppressWarnings("unchecked")
+ public void bundleChanged(BundleEvent be) {
+ eventList.add(be);
+ }
- private void dump(BundleEvent be) {
- System.out.println("BE:" + ", source " + be.getSource() + ", bundle=" + be.getBundle() + ", type=" + be.getType());
+ private void dump(BundleEvent be) {
+ System.out.println("BE:" + ", source " + be.getSource() + ", bundle="
+ + be.getBundle() + ", type=" + be.getType());
- }
+ }
- public void dumpAll() {
- for (int i = 0; i < eventList.size(); i++) {
- BundleEvent fe = (BundleEvent) eventList.get(i);
- dump(fe);
- }
+ public void dumpAll() {
+ for (int i = 0; i < eventList.size(); i++) {
+ BundleEvent fe = (BundleEvent) eventList.get(i);
+ dump(fe);
}
-
- boolean exists(String bundleName) {
- for (int i = 0; i < eventList.size(); i++) {
- BundleEvent fe = (BundleEvent) eventList.get(i);
- Bundle b = fe.getBundle();
- System.out.println("===[" + b + "]");
- if (bundleName.equals(b.getSymbolicName())) {
- return true;
- }
- }
- return false;
+ }
+
+ boolean exists(String bundleName) {
+ for (int i = 0; i < eventList.size(); i++) {
+ BundleEvent fe = (BundleEvent) eventList.get(i);
+ Bundle b = fe.getBundle();
+ System.out.println("===["+b+"]");
+ if (bundleName.equals(b.getSymbolicName())) {
+ return true;
+ }
}
+ return false;
+ }
}
diff --git a/logback-classic/src/test/java/org/slf4j/test_osgi/FelixHost.java b/logback-classic/src/test/java/org/slf4j/test_osgi/FelixHost.java
index 44b2ded..f535aa6 100644
--- a/logback-classic/src/test/java/org/slf4j/test_osgi/FelixHost.java
+++ b/logback-classic/src/test/java/org/slf4j/test_osgi/FelixHost.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,80 +31,89 @@ import org.osgi.framework.Constants;
* Runs a hosted version of Felix for testing purposes. Any bundle errors are
* reported via the FrameworkListener passed to the constructor.
*
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class FelixHost {
- private Felix felix = null;
-
- Properties otherProps = new Properties();
-
- final FrameworkErrorListener frameworkErrorListener;
- final CheckingBundleListener myBundleListener;
-
- public FelixHost(FrameworkErrorListener frameworkErrorListener, CheckingBundleListener myBundleListener) {
- this.frameworkErrorListener = frameworkErrorListener;
- this.myBundleListener = myBundleListener;
- }
-
- @SuppressWarnings("unchecked")
- public void doLaunch() {
- // Create a case-insensitive configuration property map.
- Map configMap = new StringMap(false);
- // Configure the Felix instance to be embedded.
- // configMap.put(FelixConstants.EMBEDDED_EXECUTION_PROP, "true");
- // Add core OSGi packages to be exported from the class path
- // via the system bundle.
- configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES, "org.osgi.framework; version=1.3.0," + "org.osgi.service.packageadmin; version=1.2.0,"
- + "org.osgi.service.startlevel; version=1.0.0," + "org.osgi.service.url; version=1.0.0");
-
- configMap.put(Constants.FRAMEWORK_STORAGE_CLEAN, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);
-
- // Explicitly specify the directory to use for caching bundles.
- // configMap.put(BundleCache.CACHE_PROFILE_DIR_PROP, "cache");
-
- try {
- // Create host activator;
-
- List list = new ArrayList();
-
- // list.add(new HostActivator());
- configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "org.xml.sax, org.xml.sax.helpers, javax.xml.parsers, javax.naming");
- configMap.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list);
- configMap.put("felix.log.level", "4");
-
- // Now create an instance of the framework with
- // our configuration properties and activator.
- felix = new Felix(configMap);
- felix.init();
-
- // otherProps.put(Constants.FRAMEWORK_STORAGE, "bundles");
-
- otherProps.put(AutoProcessor.AUTO_DEPLOY_DIR_PROPERY, AutoProcessor.AUTO_DEPLOY_DIR_VALUE);
- otherProps.put(AutoProcessor.AUTO_DEPLOY_ACTION_PROPERY, AutoProcessor.AUTO_DEPLOY_START_VALUE + "," + AutoProcessor.AUTO_DEPLOY_INSTALL_VALUE);
-
- BundleContext felixBudleContext = felix.getBundleContext();
-
- AutoProcessor.process(otherProps, felixBudleContext);
- // listen to errors
- felixBudleContext.addFrameworkListener(frameworkErrorListener);
- felixBudleContext.addBundleListener(myBundleListener);
- // Now start Felix instance.
- felix.start();
- System.out.println("felix started");
-
- } catch (Exception ex) {
- ex.printStackTrace();
- }
+ private Felix felix = null;
+
+ Properties otherProps = new Properties();
+
+ final FrameworkErrorListener frameworkErrorListener;
+ final CheckingBundleListener myBundleListener;
+
+ public FelixHost(FrameworkErrorListener frameworkErrorListener,
+ CheckingBundleListener myBundleListener) {
+ this.frameworkErrorListener = frameworkErrorListener;
+ this.myBundleListener = myBundleListener;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void doLaunch() {
+ // Create a case-insensitive configuration property map.
+ Map configMap = new StringMap(false);
+ // Configure the Felix instance to be embedded.
+ // configMap.put(FelixConstants.EMBEDDED_EXECUTION_PROP, "true");
+ // Add core OSGi packages to be exported from the class path
+ // via the system bundle.
+ configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES,
+ "org.osgi.framework; version=1.3.0,"
+ + "org.osgi.service.packageadmin; version=1.2.0,"
+ + "org.osgi.service.startlevel; version=1.0.0,"
+ + "org.osgi.service.url; version=1.0.0");
+
+ configMap.put(Constants.FRAMEWORK_STORAGE_CLEAN,
+ Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);
+
+ // Explicitly specify the directory to use for caching bundles.
+ // configMap.put(BundleCache.CACHE_PROFILE_DIR_PROP, "cache");
+
+ try {
+ // Create host activator;
+
+ List list = new ArrayList();
+
+ // list.add(new HostActivator());
+ configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA,
+ "org.xml.sax, org.xml.sax.helpers, javax.xml.parsers, javax.naming");
+ configMap.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list);
+ configMap.put("felix.log.level", "4");
+
+ // Now create an instance of the framework with
+ // our configuration properties and activator.
+ felix = new Felix(configMap);
+ felix.init();
+
+ // otherProps.put(Constants.FRAMEWORK_STORAGE, "bundles");
+
+ otherProps.put(AutoProcessor.AUTO_DEPLOY_DIR_PROPERY,
+ AutoProcessor.AUTO_DEPLOY_DIR_VALUE);
+ otherProps.put(AutoProcessor.AUTO_DEPLOY_ACTION_PROPERY,
+ AutoProcessor.AUTO_DEPLOY_START_VALUE + ","
+ + AutoProcessor.AUTO_DEPLOY_INSTALL_VALUE);
+
+ BundleContext felixBudleContext = felix.getBundleContext();
+
+ AutoProcessor.process(otherProps, felixBudleContext);
+ // listen to errors
+ felixBudleContext.addFrameworkListener(frameworkErrorListener);
+ felixBudleContext.addBundleListener(myBundleListener);
+ // Now start Felix instance.
+ felix.start();
+ System.out.println("felix started");
+
+ } catch (Exception ex) {
+ ex.printStackTrace();
}
+ }
- public void stop() throws BundleException {
- felix.stop();
- }
+ public void stop() throws BundleException {
+ felix.stop();
+ }
- public Bundle[] getInstalledBundles() {
- // Use the system bundle activator to gain external
- // access to the set of installed bundles.
- return null;// m_activator.getBundles();
- }
+ public Bundle[] getInstalledBundles() {
+ // Use the system bundle activator to gain external
+ // access to the set of installed bundles.
+ return null;// m_activator.getBundles();
+ }
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/org/slf4j/test_osgi/FrameworkErrorListener.java b/logback-classic/src/test/java/org/slf4j/test_osgi/FrameworkErrorListener.java
index a1c9370..3dd1f28 100644
--- a/logback-classic/src/test/java/org/slf4j/test_osgi/FrameworkErrorListener.java
+++ b/logback-classic/src/test/java/org/slf4j/test_osgi/FrameworkErrorListener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,31 +21,32 @@ import org.osgi.framework.FrameworkListener;
public class FrameworkErrorListener implements FrameworkListener {
- public List errorList = new ArrayList();
-
- @SuppressWarnings("unchecked")
- public void frameworkEvent(FrameworkEvent fe) {
- if (fe.getType() == FrameworkEvent.ERROR) {
- errorList.add(fe);
- }
+ public List errorList = new ArrayList();
+
+ @SuppressWarnings("unchecked")
+ public void frameworkEvent(FrameworkEvent fe) {
+ if (fe.getType() == FrameworkEvent.ERROR) {
+ errorList.add(fe);
}
-
- private void dump(FrameworkEvent fe) {
- Throwable t = fe.getThrowable();
- String tString = null;
- if (t != null) {
- tString = t.toString();
- }
- System.out.println("Framework ERROR:" + ", source " + fe.getSource() + ", bundle=" + fe.getBundle() + ", ex=" + tString);
- if (t != null) {
- t.printStackTrace();
- }
+ }
+
+ private void dump(FrameworkEvent fe) {
+ Throwable t = fe.getThrowable();
+ String tString = null;
+ if (t != null) {
+ tString = t.toString();
+ }
+ System.out.println("Framework ERROR:" + ", source " + fe.getSource()
+ + ", bundle=" + fe.getBundle() + ", ex=" + tString);
+ if(t != null) {
+ t.printStackTrace();
}
+ }
- public void dumpAll() {
- for (int i = 0; i < errorList.size(); i++) {
- FrameworkEvent fe = (FrameworkEvent) errorList.get(i);
- dump(fe);
- }
+ public void dumpAll() {
+ for(int i = 0; i < errorList.size(); i++) {
+ FrameworkEvent fe = (FrameworkEvent) errorList.get(i);
+ dump(fe);
}
+ }
}
diff --git a/logback-classic/src/test/resources/FAKE_META_INF_SERVICES_ch_qos_logback_classic_spi_Configurator b/logback-classic/src/test/resources/FAKE_META_INF_SERVICES_ch_qos_logback_classic_spi_Configurator
deleted file mode 100644
index 8288f36..0000000
--- a/logback-classic/src/test/resources/FAKE_META_INF_SERVICES_ch_qos_logback_classic_spi_Configurator
+++ /dev/null
@@ -1 +0,0 @@
-ch.qos.logback.classic.util.MockConfigurator
\ No newline at end of file
diff --git a/logback-classic/src/test/resources/META-INF/services/DISABLED-ch.qos.logback.classic.spi.Configurator b/logback-classic/src/test/resources/META-INF/services/DISABLED-ch.qos.logback.classic.spi.Configurator
deleted file mode 100644
index a7883e3..0000000
--- a/logback-classic/src/test/resources/META-INF/services/DISABLED-ch.qos.logback.classic.spi.Configurator
+++ /dev/null
@@ -1 +0,0 @@
-ch.qos.logback.classic.BasicConfigurator
\ No newline at end of file
diff --git a/logback-classic/src/test/resources/README.txt b/logback-classic/src/test/resources/README.txt
index 3619d1d..dc94bfa 100644
--- a/logback-classic/src/test/resources/README.txt
+++ b/logback-classic/src/test/resources/README.txt
@@ -1,5 +1,5 @@
-Few test cases InitializationTest require the presence of logback.xml or logback-test.xml
+Few test cases InitializationTest requite the presence of logback.xml or logback-test.xml
to be present in the classpath. However, this conflict with the logback-examples module.
In particular, when users attempt to follow the manual by importing the project in an IDE
such as Eclipse.
\ No newline at end of file
diff --git a/logback-classic/src/test/resources/recursiveInit.xml b/logback-classic/src/test/resources/recursiveInit.xml
index 05600ae..2c5aad4 100644
--- a/logback-classic/src/test/resources/recursiveInit.xml
+++ b/logback-classic/src/test/resources/recursiveInit.xml
@@ -12,6 +12,6 @@
<root level="DEBUG" >
<appender-ref ref="STDOUT" />
- <appender-ref ref="RECURSIVE" />
+ <appender-ref ref="RECURSIVE" />
</root>
</configuration>
\ No newline at end of file
diff --git a/logback-classic/src/test/resources/test.groovy b/logback-classic/src/test/resources/test.groovy
index 6b1b516..01ae2cd 100644
--- a/logback-classic/src/test/resources/test.groovy
+++ b/logback-classic/src/test/resources/test.groovy
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
import ch.qos.logback.core.ConsoleAppender
import ch.qos.logback.core.encoder.LayoutWrappingEncoder
import ch.qos.logback.classic.PatternLayout
diff --git a/logback-core/pom.xml b/logback-core/pom.xml
index d98aa8f..26e0693 100644
--- a/logback-core/pom.xml
+++ b/logback-core/pom.xml
@@ -1,13 +1,13 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-parent</artifactId>
- <version>1.1.9</version>
+ <version>1.1.2</version>
</parent>
<artifactId>logback-core</artifactId>
@@ -15,6 +15,24 @@
<name>Logback Core Module</name>
<description>logback-core module</description>
+ <url>http://logback.qos.ch</url>
+
+ <properties>
+ <!--<scala.version>2.9.1</scala.version>-->
+ </properties>
+
+ <licenses>
+ <license>
+ <name>Eclipse Public License - v 1.0</name>
+ <url>http://www.eclipse.org/legal/epl-v10.html</url>
+ </license>
+
+ <license>
+ <name>GNU Lesser General Public License</name>
+ <url>http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</url>
+ </license>
+ </licenses>
+
<dependencies>
<dependency>
<groupId>org.codehaus.janino</groupId>
@@ -22,11 +40,13 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
+
<dependency>
<groupId>org.fusesource.jansi</groupId>
<artifactId>jansi</artifactId>
<optional>true</optional>
</dependency>
+
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
@@ -39,36 +59,42 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
+
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
- <version>1.9.5</version>
+ <version>1.9.0</version>
<scope>test</scope>
</dependency>
+
+
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
- <dependency>
- <groupId>joda-time</groupId>
- <artifactId>joda-time</artifactId>
- <scope>test</scope>
- </dependency>
+
+ <!--<dependency>-->
+ <!--<groupId>org.scala-lang</groupId>-->
+ <!--<artifactId>scala-library</artifactId>-->
+ <!--<version>${scala.version}</version>-->
+ <!--<scope>test</scope>-->
+ <!--</dependency>-->
+
</dependencies>
+
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
+ <version>${maven-surefire-plugin.version}</version>
<configuration>
- <forkCount>1C</forkCount>
- <reuseForks>true</reuseForks>
- <parallel>classes</parallel>
- <threadCount>20</threadCount>
+ <forkMode>once</forkMode>
<reportFormat>plain</reportFormat>
+ <!--<parallel>classes</parallel>-->
<trimStackTrace>false</trimStackTrace>
<excludes>
<exclude>**/All*Test.java</exclude>
@@ -79,9 +105,11 @@
</excludes>
</configuration>
</plugin>
+
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
+ <version>${maven-jar-plugin.version}</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF
@@ -99,6 +127,7 @@
</execution>
</executions>
</plugin>
+
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
@@ -123,7 +152,7 @@
org.codehaus.commons.compiler;resolution:=optional,
*
</Import-Package>
- <Bundle-RequiredExecutionEnvironment>JavaSE-1.6
+ <Bundle-RequiredExecutionEnvironment>J2SE-1.5
</Bundle-RequiredExecutionEnvironment>
</instructions>
</configuration>
diff --git a/logback-core/src/main/java/ch/qos/logback/core/Appender.java b/logback-core/src/main/java/ch/qos/logback/core/Appender.java
index e229b41..6f28a8f 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/Appender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/Appender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -12,30 +12,31 @@
* as published by the Free Software Foundation.
*/
package ch.qos.logback.core;
-
+
import ch.qos.logback.core.spi.ContextAware;
import ch.qos.logback.core.spi.FilterAttachable;
import ch.qos.logback.core.spi.LifeCycle;
+
public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachable<E> {
- /**
- * Get the name of this appender. The name uniquely identifies the appender.
- */
- String getName();
-
- /**
- * This is where an appender accomplishes its work. Note that the argument
- * is of type Object.
- * @param event
- */
- void doAppend(E event) throws LogbackException;
+ /**
+ * Get the name of this appender. The name uniquely identifies the appender.
+ */
+ String getName();
- /**
- * Set the name of this appender. The name is used by other components to
- * identify this appender.
- *
- */
- void setName(String name);
+ /**
+ * This is where an appender accomplishes its work. Note that the argument
+ * is of type Object.
+ * @param event
+ */
+ void doAppend(E event) throws LogbackException;
+ /**
+ * Set the name of this appender. The name is used by other components to
+ * identify this appender.
+ *
+ */
+ void setName(String name);
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java
index 51ae397..23ede8e 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,106 +29,109 @@ import ch.qos.logback.core.status.WarnStatus;
*
* @author Ceki Gülcü
*/
-abstract public class AppenderBase<E> extends ContextAwareBase implements Appender<E> {
+abstract public class AppenderBase<E> extends ContextAwareBase implements
+ Appender<E> {
- protected volatile boolean started = false;
+ protected boolean started = false;
- /**
- * The guard prevents an appender from repeatedly calling its own doAppend
- * method.
- */
- private boolean guard = false;
+ /**
+ * The guard prevents an appender from repeatedly calling its own doAppend
+ * method.
+ */
+ private boolean guard = false;
- /**
- * Appenders are named.
- */
- protected String name;
+ /**
+ * Appenders are named.
+ */
+ protected String name;
- private FilterAttachableImpl<E> fai = new FilterAttachableImpl<E>();
+ private FilterAttachableImpl<E> fai = new FilterAttachableImpl<E>();
- public String getName() {
- return name;
- }
+ public String getName() {
+ return name;
+ }
- private int statusRepeatCount = 0;
- private int exceptionCount = 0;
+ private int statusRepeatCount = 0;
+ private int exceptionCount = 0;
- static final int ALLOWED_REPEATS = 5;
+ static final int ALLOWED_REPEATS = 5;
- public synchronized void doAppend(E eventObject) {
- // WARNING: The guard check MUST be the first statement in the
- // doAppend() method.
+ public synchronized void doAppend(E eventObject) {
+ // WARNING: The guard check MUST be the first statement in the
+ // doAppend() method.
- // prevent re-entry.
- if (guard) {
- return;
- }
+ // prevent re-entry.
+ if (guard) {
+ return;
+ }
+
+ try {
+ guard = true;
- try {
- guard = true;
-
- if (!this.started) {
- if (statusRepeatCount++ < ALLOWED_REPEATS) {
- addStatus(new WarnStatus("Attempted to append to non started appender [" + name + "].", this));
- }
- return;
- }
-
- if (getFilterChainDecision(eventObject) == FilterReply.DENY) {
- return;
- }
-
- // ok, we now invoke derived class' implementation of append
- this.append(eventObject);
-
- } catch (Exception e) {
- if (exceptionCount++ < ALLOWED_REPEATS) {
- addError("Appender [" + name + "] failed to append.", e);
- }
- } finally {
- guard = false;
+ if (!this.started) {
+ if (statusRepeatCount++ < ALLOWED_REPEATS) {
+ addStatus(new WarnStatus(
+ "Attempted to append to non started appender [" + name + "].",
+ this));
}
+ return;
+ }
+
+ if (getFilterChainDecision(eventObject) == FilterReply.DENY) {
+ return;
+ }
+
+ // ok, we now invoke derived class' implementation of append
+ this.append(eventObject);
+
+ } catch (Exception e) {
+ if (exceptionCount++ < ALLOWED_REPEATS) {
+ addError("Appender [" + name + "] failed to append.", e);
+ }
+ } finally {
+ guard = false;
}
+ }
- abstract protected void append(E eventObject);
+ abstract protected void append(E eventObject);
- /**
- * Set the name of this appender.
- */
- public void setName(String name) {
- this.name = name;
- }
+ /**
+ * Set the name of this appender.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
- public void start() {
- started = true;
- }
+ public void start() {
+ started = true;
+ }
- public void stop() {
- started = false;
- }
+ public void stop() {
+ started = false;
+ }
- public boolean isStarted() {
- return started;
- }
+ public boolean isStarted() {
+ return started;
+ }
- public String toString() {
- return this.getClass().getName() + "[" + name + "]";
- }
+ public String toString() {
+ return this.getClass().getName() + "[" + name + "]";
+ }
- public void addFilter(Filter<E> newFilter) {
- fai.addFilter(newFilter);
- }
+ public void addFilter(Filter<E> newFilter) {
+ fai.addFilter(newFilter);
+ }
- public void clearAllFilters() {
- fai.clearAllFilters();
- }
+ public void clearAllFilters() {
+ fai.clearAllFilters();
+ }
- public List<Filter<E>> getCopyOfAttachedFiltersList() {
- return fai.getCopyOfAttachedFiltersList();
- }
+ public List<Filter<E>> getCopyOfAttachedFiltersList() {
+ return fai.getCopyOfAttachedFiltersList();
+ }
- public FilterReply getFilterChainDecision(E event) {
- return fai.getFilterChainDecision(event);
- }
+ public FilterReply getFilterChainDecision(E event) {
+ return fai.getFilterChainDecision(event);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/AsyncAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/AsyncAppenderBase.java
index a129bb3..64b9b2a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/AsyncAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/AsyncAppenderBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -38,244 +38,203 @@ import java.util.concurrent.BlockingQueue;
*/
public class AsyncAppenderBase<E> extends UnsynchronizedAppenderBase<E> implements AppenderAttachable<E> {
- AppenderAttachableImpl<E> aai = new AppenderAttachableImpl<E>();
- BlockingQueue<E> blockingQueue;
-
- /**
- * The default buffer size.
- */
- public static final int DEFAULT_QUEUE_SIZE = 256;
- int queueSize = DEFAULT_QUEUE_SIZE;
-
- int appenderCount = 0;
-
- static final int UNDEFINED = -1;
- int discardingThreshold = UNDEFINED;
- boolean neverBlock = false;
-
- Worker worker = new Worker();
-
- /**
- * The default maximum queue flush time allowed during appender stop. If the
- * worker takes longer than this time it will exit, discarding any remaining
- * items in the queue
- */
- public static final int DEFAULT_MAX_FLUSH_TIME = 1000;
- int maxFlushTime = DEFAULT_MAX_FLUSH_TIME;
-
- /**
- * Is the eventObject passed as parameter discardable? The base class's implementation of this method always returns
- * 'false' but sub-classes may (and do) override this method.
- * <p/>
- * <p>Note that only if the buffer is nearly full are events discarded. Otherwise, when the buffer is "not full"
- * all events are logged.
- *
- * @param eventObject
- * @return - true if the event can be discarded, false otherwise
- */
- protected boolean isDiscardable(E eventObject) {
- return false;
- }
-
- /**
- * Pre-process the event prior to queueing. The base class does no pre-processing but sub-classes can
- * override this behavior.
- *
- * @param eventObject
- */
- protected void preprocess(E eventObject) {
- }
-
- @Override
- public void start() {
- if (isStarted())
- return;
- if (appenderCount == 0) {
- addError("No attached appenders found.");
- return;
- }
- if (queueSize < 1) {
- addError("Invalid queue size [" + queueSize + "]");
- return;
- }
- blockingQueue = new ArrayBlockingQueue<E>(queueSize);
-
- if (discardingThreshold == UNDEFINED)
- discardingThreshold = queueSize / 5;
- addInfo("Setting discardingThreshold to " + discardingThreshold);
- worker.setDaemon(true);
- worker.setName("AsyncAppender-Worker-" + getName());
- // make sure this instance is marked as "started" before staring the worker Thread
- super.start();
- worker.start();
- }
-
- @Override
- public void stop() {
- if (!isStarted())
- return;
+ AppenderAttachableImpl<E> aai = new AppenderAttachableImpl<E>();
+ BlockingQueue<E> blockingQueue;
+
+ /**
+ * The default buffer size.
+ */
+ public static final int DEFAULT_QUEUE_SIZE = 256;
+ int queueSize = DEFAULT_QUEUE_SIZE;
+
+ int appenderCount = 0;
+
+ static final int UNDEFINED = -1;
+ int discardingThreshold = UNDEFINED;
+
+ Worker worker = new Worker();
+
+ /**
+ * Is the eventObject passed as parameter discardable? The base class's implementation of this method always returns
+ * 'false' but sub-classes may (and do) override this method.
+ * <p/>
+ * <p>Note that only if the buffer is nearly full are events discarded. Otherwise, when the buffer is "not full"
+ * all events are logged.
+ *
+ * @param eventObject
+ * @return - true if the event can be discarded, false otherwise
+ */
+ protected boolean isDiscardable(E eventObject) {
+ return false;
+ }
+
+
+ /**
+ * Pre-process the event prior to queueing. The base class does no pre-processing but sub-classes can
+ * override this behavior.
+ *
+ * @param eventObject
+ */
+ protected void preprocess(E eventObject) {
+ }
+
+
+ @Override
+ public void start() {
+ if (appenderCount == 0) {
+ addError("No attached appenders found.");
+ return;
+ }
+ if (queueSize < 1) {
+ addError("Invalid queue size [" + queueSize + "]");
+ return;
+ }
+ blockingQueue = new ArrayBlockingQueue<E>(queueSize);
+
+ if (discardingThreshold == UNDEFINED)
+ discardingThreshold = queueSize / 5;
+ addInfo("Setting discardingThreshold to " + discardingThreshold);
+ worker.setDaemon(true);
+ worker.setName("AsyncAppender-Worker-" + worker.getName());
+ // make sure this instance is marked as "started" before staring the worker Thread
+ super.start();
+ worker.start();
+ }
+
+ @Override
+ public void stop() {
+ if (!isStarted())
+ return;
+
+ // mark this appender as stopped so that Worker can also processPriorToRemoval if it is invoking aii.appendLoopOnAppenders
+ // and sub-appenders consume the interruption
+ super.stop();
+
+ // interrupt the worker thread so that it can terminate. Note that the interruption can be consumed
+ // by sub-appenders
+ worker.interrupt();
+ try {
+ worker.join(1000);
+ } catch (InterruptedException e) {
+ addError("Failed to join worker thread", e);
+ }
+ }
+
+
+ @Override
+ protected void append(E eventObject) {
+ if (isQueueBelowDiscardingThreshold() && isDiscardable(eventObject)) {
+ return;
+ }
+ preprocess(eventObject);
+ put(eventObject);
+ }
+
+ private boolean isQueueBelowDiscardingThreshold() {
+ return (blockingQueue.remainingCapacity() < discardingThreshold);
+ }
+
+ private void put(E eventObject) {
+ try {
+ blockingQueue.put(eventObject);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ public int getQueueSize() {
+ return queueSize;
+ }
+
+ public void setQueueSize(int queueSize) {
+ this.queueSize = queueSize;
+ }
+
+ public int getDiscardingThreshold() {
+ return discardingThreshold;
+ }
+
+ public void setDiscardingThreshold(int discardingThreshold) {
+ this.discardingThreshold = discardingThreshold;
+ }
+
+ /**
+ * Returns the number of elements currently in the blocking queue.
+ *
+ * @return number of elements currently in the queue.
+ */
+ public int getNumberOfElementsInQueue() {
+ return blockingQueue.size();
+ }
+
+ /**
+ * The remaining capacity available in the blocking queue.
+ *
+ * @return the remaining capacity
+ * @see {@link java.util.concurrent.BlockingQueue#remainingCapacity()}
+ */
+ public int getRemainingCapacity() {
+ return blockingQueue.remainingCapacity();
+ }
+
+
+
+ public void addAppender(Appender<E> newAppender) {
+ if (appenderCount == 0) {
+ appenderCount++;
+ addInfo("Attaching appender named ["+newAppender.getName()+"] to AsyncAppender.");
+ aai.addAppender(newAppender);
+ } else {
+ addWarn("One and only one appender may be attached to AsyncAppender.");
+ addWarn("Ignoring additional appender named [" + newAppender.getName() + "]");
+ }
+ }
+
+ public Iterator<Appender<E>> iteratorForAppenders() {
+ return aai.iteratorForAppenders();
+ }
+
+ public Appender<E> getAppender(String name) {
+ return aai.getAppender(name);
+ }
+
+ public boolean isAttached(Appender<E> eAppender) {
+ return aai.isAttached(eAppender);
+ }
+
+ public void detachAndStopAllAppenders() {
+ aai.detachAndStopAllAppenders();
+ }
+
+ public boolean detachAppender(Appender<E> eAppender) {
+ return aai.detachAppender(eAppender);
+ }
+
+ public boolean detachAppender(String name) {
+ return aai.detachAppender(name);
+ }
+
+ class Worker extends Thread {
- // mark this appender as stopped so that Worker can also processPriorToRemoval if it is invoking
- // aii.appendLoopOnAppenders
- // and sub-appenders consume the interruption
- super.stop();
+ public void run() {
+ AsyncAppenderBase<E> parent = AsyncAppenderBase.this;
+ AppenderAttachableImpl<E> aai = parent.aai;
- // interrupt the worker thread so that it can terminate. Note that the interruption can be consumed
- // by sub-appenders
- worker.interrupt();
+ // loop while the parent is started
+ while (parent.isStarted()) {
try {
- worker.join(maxFlushTime);
-
- // check to see if the thread ended and if not add a warning message
- if (worker.isAlive()) {
- addWarn("Max queue flush timeout (" + maxFlushTime + " ms) exceeded. Approximately " + blockingQueue.size()
- + " queued events were possibly discarded.");
- } else {
- addInfo("Queue flush finished successfully within timeout.");
- }
-
- } catch (InterruptedException e) {
- addError("Failed to join worker thread. " + blockingQueue.size() + " queued events may be discarded.", e);
+ E e = parent.blockingQueue.take();
+ aai.appendLoopOnAppenders(e);
+ } catch (InterruptedException ie) {
+ break;
}
- }
+ }
- @Override
- protected void append(E eventObject) {
- if (isQueueBelowDiscardingThreshold() && isDiscardable(eventObject)) {
- return;
- }
- preprocess(eventObject);
- put(eventObject);
- }
+ addInfo("Worker thread will flush remaining events before exiting. ");
+ for (E e : parent.blockingQueue) {
+ aai.appendLoopOnAppenders(e);
+ }
- private boolean isQueueBelowDiscardingThreshold() {
- return (blockingQueue.remainingCapacity() < discardingThreshold);
- }
-
- private void put(E eventObject) {
- if (neverBlock) {
- blockingQueue.offer(eventObject);
- } else {
- try {
- blockingQueue.put(eventObject);
- } catch (InterruptedException e) {
- // Interruption of current thread when in doAppend method should not be consumed
- // by AsyncAppender
- Thread.currentThread().interrupt();
- }
- }
- }
-
- public int getQueueSize() {
- return queueSize;
- }
-
- public void setQueueSize(int queueSize) {
- this.queueSize = queueSize;
- }
-
- public int getDiscardingThreshold() {
- return discardingThreshold;
- }
-
- public void setDiscardingThreshold(int discardingThreshold) {
- this.discardingThreshold = discardingThreshold;
- }
-
- public int getMaxFlushTime() {
- return maxFlushTime;
- }
-
- public void setMaxFlushTime(int maxFlushTime) {
- this.maxFlushTime = maxFlushTime;
- }
-
- /**
- * Returns the number of elements currently in the blocking queue.
- *
- * @return number of elements currently in the queue.
- */
- public int getNumberOfElementsInQueue() {
- return blockingQueue.size();
- }
-
- public void setNeverBlock(boolean neverBlock) {
- this.neverBlock = neverBlock;
- }
-
- public boolean isNeverBlock() {
- return neverBlock;
- }
-
- /**
- * The remaining capacity available in the blocking queue.
- *
- * @return the remaining capacity
- * @see {@link java.util.concurrent.BlockingQueue#remainingCapacity()}
- */
- public int getRemainingCapacity() {
- return blockingQueue.remainingCapacity();
- }
-
- public void addAppender(Appender<E> newAppender) {
- if (appenderCount == 0) {
- appenderCount++;
- addInfo("Attaching appender named [" + newAppender.getName() + "] to AsyncAppender.");
- aai.addAppender(newAppender);
- } else {
- addWarn("One and only one appender may be attached to AsyncAppender.");
- addWarn("Ignoring additional appender named [" + newAppender.getName() + "]");
- }
- }
-
- public Iterator<Appender<E>> iteratorForAppenders() {
- return aai.iteratorForAppenders();
- }
-
- public Appender<E> getAppender(String name) {
- return aai.getAppender(name);
- }
-
- public boolean isAttached(Appender<E> eAppender) {
- return aai.isAttached(eAppender);
- }
-
- public void detachAndStopAllAppenders() {
- aai.detachAndStopAllAppenders();
- }
-
- public boolean detachAppender(Appender<E> eAppender) {
- return aai.detachAppender(eAppender);
- }
-
- public boolean detachAppender(String name) {
- return aai.detachAppender(name);
- }
-
- class Worker extends Thread {
-
- public void run() {
- AsyncAppenderBase<E> parent = AsyncAppenderBase.this;
- AppenderAttachableImpl<E> aai = parent.aai;
-
- // loop while the parent is started
- while (parent.isStarted()) {
- try {
- E e = parent.blockingQueue.take();
- aai.appendLoopOnAppenders(e);
- } catch (InterruptedException ie) {
- break;
- }
- }
-
- addInfo("Worker thread will flush remaining events before exiting. ");
-
- for (E e : parent.blockingQueue) {
- aai.appendLoopOnAppenders(e);
- parent.blockingQueue.remove(e);
- }
-
- aai.detachAndStopAllAppenders();
- }
+ aai.detachAndStopAllAppenders();
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/BasicStatusManager.java b/logback-core/src/main/java/ch/qos/logback/core/BasicStatusManager.java
index 28acbf9..b80dcba 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/BasicStatusManager.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/BasicStatusManager.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,127 +18,109 @@ import java.util.List;
import ch.qos.logback.core.helpers.CyclicBuffer;
import ch.qos.logback.core.spi.LogbackLock;
-import ch.qos.logback.core.status.OnConsoleStatusListener;
import ch.qos.logback.core.status.Status;
import ch.qos.logback.core.status.StatusListener;
import ch.qos.logback.core.status.StatusManager;
public class BasicStatusManager implements StatusManager {
- public static final int MAX_HEADER_COUNT = 150;
- public static final int TAIL_SIZE = 150;
-
- int count = 0;
-
- // protected access was requested in http://jira.qos.ch/browse/LBCORE-36
- final protected List<Status> statusList = new ArrayList<Status>();
- final protected CyclicBuffer<Status> tailBuffer = new CyclicBuffer<Status>(TAIL_SIZE);
- final protected LogbackLock statusListLock = new LogbackLock();
-
- int level = Status.INFO;
-
- // protected access was requested in http://jira.qos.ch/browse/LBCORE-36
- final protected List<StatusListener> statusListenerList = new ArrayList<StatusListener>();
- final protected LogbackLock statusListenerListLock = new LogbackLock();
-
- // Note on synchronization
- // This class contains two separate locks statusListLock and
- // statusListenerListLock guarding respectively the statusList+tailBuffer and
- // statusListenerList fields. The locks are used internally
- // without cycles. They are exposed to derived classes which should be careful
- // not to create deadlock cycles.
-
- /**
- * Add a new status object.
- *
- * @param newStatus
- * the status message to add
- */
- public void add(Status newStatus) {
- // LBCORE-72: fire event before the count check
- fireStatusAddEvent(newStatus);
-
- count++;
- if (newStatus.getLevel() > level) {
- level = newStatus.getLevel();
- }
-
- synchronized (statusListLock) {
- if (statusList.size() < MAX_HEADER_COUNT) {
- statusList.add(newStatus);
- } else {
- tailBuffer.add(newStatus);
- }
- }
-
+ public static final int MAX_HEADER_COUNT = 150;
+ public static final int TAIL_SIZE = 150;
+
+ int count = 0;
+
+ // protected access was requested in http://jira.qos.ch/browse/LBCORE-36
+ final protected List<Status> statusList = new ArrayList<Status>();
+ final protected CyclicBuffer<Status> tailBuffer = new CyclicBuffer<Status>(
+ TAIL_SIZE);
+ final protected LogbackLock statusListLock = new LogbackLock();
+
+ int level = Status.INFO;
+
+ // protected access was requested in http://jira.qos.ch/browse/LBCORE-36
+ final protected List<StatusListener> statusListenerList = new ArrayList<StatusListener>();
+ final protected LogbackLock statusListenerListLock = new LogbackLock();
+
+ // Note on synchronization
+ // This class contains two separate locks statusListLock and
+ // statusListenerListLock guarding respectively the statusList+tailBuffer and
+ // statusListenerList fields. The locks are used internally
+ // without cycles. They are exposed to derived classes which should be careful
+ // not to create deadlock cycles.
+
+ /**
+ * Add a new status object.
+ *
+ * @param newStatus
+ * the status message to add
+ */
+ public void add(Status newStatus) {
+ // LBCORE-72: fire event before the count check
+ fireStatusAddEvent(newStatus);
+
+ count++;
+ if (newStatus.getLevel() > level) {
+ level = newStatus.getLevel();
}
- public List<Status> getCopyOfStatusList() {
- synchronized (statusListLock) {
- List<Status> tList = new ArrayList<Status>(statusList);
- tList.addAll(tailBuffer.asList());
- return tList;
- }
+ synchronized (statusListLock) {
+ if (statusList.size() < MAX_HEADER_COUNT) {
+ statusList.add(newStatus);
+ } else {
+ tailBuffer.add(newStatus);
+ }
}
- private void fireStatusAddEvent(Status status) {
- synchronized (statusListenerListLock) {
- for (StatusListener sl : statusListenerList) {
- sl.addStatusEvent(status);
- }
- }
- }
+ }
- public void clear() {
- synchronized (statusListLock) {
- count = 0;
- statusList.clear();
- tailBuffer.clear();
- }
+ public List<Status> getCopyOfStatusList() {
+ synchronized (statusListLock) {
+ List<Status> tList = new ArrayList<Status>(statusList);
+ tList.addAll(tailBuffer.asList());
+ return tList;
}
+ }
- public int getLevel() {
- return level;
+ private void fireStatusAddEvent(Status status) {
+ synchronized (statusListenerListLock) {
+ for (StatusListener sl : statusListenerList) {
+ sl.addStatusEvent(status);
+ }
}
+ }
- public int getCount() {
- return count;
+ public void clear() {
+ synchronized (statusListLock) {
+ count = 0;
+ statusList.clear();
+ tailBuffer.clear();
}
+ }
- /**
- * This implementation does not allow duplicate installations of OnConsoleStatusListener
- * @param listener
- */
- public boolean add(StatusListener listener) {
- synchronized (statusListenerListLock) {
- if (listener instanceof OnConsoleStatusListener) {
- boolean alreadyPresent = checkForPresence(statusListenerList, listener.getClass());
- if (alreadyPresent)
- return false;
- }
- statusListenerList.add(listener);
- }
- return true;
- }
+ public int getLevel() {
+ return level;
+ }
+
+ public int getCount() {
+ return count;
+ }
- private boolean checkForPresence(List<StatusListener> statusListenerList, Class<?> aClass) {
- for (StatusListener e : statusListenerList) {
- if (e.getClass() == aClass)
- return true;
- }
- return false;
+ public void add(StatusListener listener) {
+ synchronized (statusListenerListLock) {
+ statusListenerList.add(listener);
}
+ }
- public void remove(StatusListener listener) {
- synchronized (statusListenerListLock) {
- statusListenerList.remove(listener);
- }
+ public void remove(StatusListener listener) {
+ synchronized (statusListenerListLock) {
+ statusListenerList.remove(listener);
}
+ }
- public List<StatusListener> getCopyOfStatusListenerList() {
- synchronized (statusListenerListLock) {
- return new ArrayList<StatusListener>(statusListenerList);
- }
+ public List<StatusListener> getCopyOfStatusListenerList() {
+ synchronized (statusListenerListLock) {
+ return new ArrayList<StatusListener>(statusListenerList);
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/ConsoleAppender.java b/logback-core/src/main/java/ch/qos/logback/core/ConsoleAppender.java
index cd0fa19..19a9e4e 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/ConsoleAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/ConsoleAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,14 +13,18 @@
*/
package ch.qos.logback.core;
+import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import ch.qos.logback.core.joran.spi.ConsoleTarget;
import ch.qos.logback.core.status.Status;
import ch.qos.logback.core.status.WarnStatus;
+import ch.qos.logback.core.util.DynamicClassLoadingException;
import ch.qos.logback.core.util.EnvUtil;
+import ch.qos.logback.core.util.IncompatibleClassException;
import ch.qos.logback.core.util.OptionHelper;
+import org.fusesource.jansi.WindowsAnsiOutputStream;
/**
* ConsoleAppender appends log events to <code>System.out</code> or
@@ -37,78 +41,80 @@ import ch.qos.logback.core.util.OptionHelper;
public class ConsoleAppender<E> extends OutputStreamAppender<E> {
- protected ConsoleTarget target = ConsoleTarget.SystemOut;
- protected boolean withJansi = false;
+ protected ConsoleTarget target = ConsoleTarget.SystemOut;
+ protected boolean withJansi = false;
- private final static String WindowsAnsiOutputStream_CLASS_NAME = "org.fusesource.jansi.WindowsAnsiOutputStream";
+ private final static String WindowsAnsiOutputStream_CLASS_NAME = "org.fusesource.jansi.WindowsAnsiOutputStream";
- /**
- * Sets the value of the <b>Target</b> option. Recognized values are
- * "System.out" and "System.err". Any other value will be ignored.
- */
- public void setTarget(String value) {
- ConsoleTarget t = ConsoleTarget.findByName(value.trim());
- if (t == null) {
- targetWarn(value);
- } else {
- target = t;
- }
+ /**
+ * Sets the value of the <b>Target</b> option. Recognized values are
+ * "System.out" and "System.err". Any other value will be ignored.
+ */
+ public void setTarget(String value) {
+ ConsoleTarget t = ConsoleTarget.findByName(value.trim());
+ if (t == null) {
+ targetWarn(value);
+ } else {
+ target = t;
}
+ }
- /**
- * Returns the current value of the <b>target</b> property. The default value
- * of the option is "System.out".
- * <p/>
- * See also {@link #setTarget}.
- */
- public String getTarget() {
- return target.getName();
- }
+ /**
+ * Returns the current value of the <b>target</b> property. The default value
+ * of the option is "System.out".
+ * <p/>
+ * See also {@link #setTarget}.
+ */
+ public String getTarget() {
+ return target.getName();
+ }
- private void targetWarn(String val) {
- Status status = new WarnStatus("[" + val + "] should be one of " + Arrays.toString(ConsoleTarget.values()), this);
- status.add(new WarnStatus("Using previously set target, System.out by default.", this));
- addStatus(status);
- }
+ private void targetWarn(String val) {
+ Status status = new WarnStatus("[" + val + "] should be one of "
+ + Arrays.toString(ConsoleTarget.values()), this);
+ status.add(new WarnStatus(
+ "Using previously set target, System.out by default.", this));
+ addStatus(status);
+ }
- @Override
- public void start() {
- OutputStream targetStream = target.getStream();
- // enable jansi only on Windows and only if withJansi set to true
- if (EnvUtil.isWindows() && withJansi) {
- targetStream = getTargetStreamForWindows(targetStream);
- }
- setOutputStream(targetStream);
- super.start();
+ @Override
+ public void start() {
+ OutputStream targetStream = target.getStream();
+ // enable jansi only on Windows and only if withJansi set to true
+ if (EnvUtil.isWindows() && withJansi) {
+ targetStream = getTargetStreamForWindows(targetStream);
}
+ setOutputStream(targetStream);
+ super.start();
+ }
- private OutputStream getTargetStreamForWindows(OutputStream targetStream) {
- try {
- addInfo("Enabling JANSI WindowsAnsiOutputStream for the console.");
- Object windowsAnsiOutputStream = OptionHelper.instantiateByClassNameAndParameter(WindowsAnsiOutputStream_CLASS_NAME, Object.class, context,
- OutputStream.class, targetStream);
- return (OutputStream) windowsAnsiOutputStream;
- } catch (Exception e) {
- addWarn("Failed to create WindowsAnsiOutputStream. Falling back on the default stream.", e);
- }
- return targetStream;
+ private OutputStream getTargetStreamForWindows(OutputStream targetStream) {
+ try {
+ addInfo("Enabling JANSI WindowsAnsiOutputStream for the console.");
+ Object windowsAnsiOutputStream = OptionHelper.instantiateByClassNameAndParameter(WindowsAnsiOutputStream_CLASS_NAME, Object.class, context,
+ OutputStream.class, targetStream);
+ return (OutputStream) windowsAnsiOutputStream;
+ } catch (Exception e) {
+ addWarn("Failed to create WindowsAnsiOutputStream. Falling back on the default stream.", e);
}
+ return targetStream;
+ }
- /**
- * @return
- */
- public boolean isWithJansi() {
- return withJansi;
- }
+ /**
+ * @return
+ */
+ public boolean isWithJansi() {
+ return withJansi;
+ }
- /**
- * If true, this appender will output to a stream which
- *
- * @param withJansi
- * @since 1.0.5
- */
- public void setWithJansi(boolean withJansi) {
- this.withJansi = withJansi;
- }
+ /**
+ * If true, this appender will output to a stream which
+ *
+ * @param withJansi
+ * @since 1.0.5
+ */
+ public void setWithJansi(boolean withJansi) {
+ this.withJansi = withJansi;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/Context.java b/logback-core/src/main/java/ch/qos/logback/core/Context.java
index 7796275..de972cd 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/Context.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/Context.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,8 +15,6 @@ package ch.qos.logback.core;
import java.util.Map;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
import ch.qos.logback.core.spi.LifeCycle;
import ch.qos.logback.core.spi.PropertyContainer;
@@ -30,113 +28,101 @@ import ch.qos.logback.core.status.StatusManager;
*/
public interface Context extends PropertyContainer {
- /**
- * Return the StatusManager instance in use.
- *
- * @return the {@link StatusManager} instance in use.
- */
- StatusManager getStatusManager();
-
- /**
- * A Context can act as a store for various objects used by LOGBack
- * components.
- *
- * @return The object stored under 'key'.
- */
- Object getObject(String key);
-
- /**
- * Store an object under 'key'. If no object can be found, null is returned.
- *
- * @param key
- * @param value
- */
- void putObject(String key, Object value);
-
- /**
- * Get all the properties for this context as a Map. Note that the returned
- * cop might be a copy not the original. Thus, modifying the returned Map will
- * have no effect (on the original.)
- *
- * @return
- */
- // public Map<String, String> getPropertyMap();
- /**
- * Get the property of this context.
- */
- String getProperty(String key);
-
- /**
- * Set a property of this context.
- */
- void putProperty(String key, String value);
-
- /**
- * Get a copy of the property map
- * @return
- * @since 0.9.20
- */
- Map<String, String> getCopyOfPropertyMap();
-
- /**
- * Contexts are named objects.
- *
- * @return the name for this context
- */
- String getName();
-
- /**
- * The name of the context can be set only once.
- *
- * @param name
- */
- void setName(String name);
-
- /**
- * The time at which this context was created, expressed in
- * millisecond elapsed since the epoch (1.1.1970).
- *
- * @return The time as measured when this class was created.
- */
- long getBirthTime();
-
- /**
- * Object used for synchronization purposes.
- * INTENDED FOR INTERNAL USAGE.
- */
- Object getConfigurationLock();
-
-
- /**
- * Returns the ScheduledExecutorService for this context.
- * @return
- * @since 1.1.7
- */
- // Apparently ScheduledThreadPoolExecutor has limitation where a task cannot be submitted from
- // within a running task. ThreadPoolExecutor does not have this limitation.
- // This causes tests failures in SocketReceiverTest.testDispatchEventForEnabledLevel and
- // ServerSocketReceiverFunctionalTest.testLogEventFromClient.
- ScheduledExecutorService getScheduledExecutorService();
-
- /**
- * Every context has an ExecutorService which be invoked to execute certain
- * tasks in a separate thread.
- *
- * @return the executor for this context.
- * @since 1.0.0
- * @deprecated use {@link#getScheduledExecutorService()} instead
- */
- ExecutorService getExecutorService();
- /**
- * Register a component that participates in the context's life cycle.
- * <p>
- * All components registered via this method will be stopped and removed
- * from the context when the context is reset.
- *
- * @param component the subject component
- */
- void register(LifeCycle component);
-
- void addScheduledFuture(ScheduledFuture<?> scheduledFuture);
-
+ /**
+ * Return the StatusManager instance in use.
+ *
+ * @return the {@link StatusManager} instance in use.
+ */
+ StatusManager getStatusManager();
+
+ /**
+ * A Context can act as a store for various objects used by LOGBack
+ * components.
+ *
+ * @return The object stored under 'key'.
+ */
+ Object getObject(String key);
+
+ /**
+ * Store an object under 'key'. If no object can be found, null is returned.
+ *
+ * @param key
+ * @param value
+ */
+ void putObject(String key, Object value);
+
+ /**
+ * Get all the properties for this context as a Map. Note that the returned
+ * cop might be a copy not the original. Thus, modifying the returned Map will
+ * have no effect (on the original.)
+ *
+ * @return
+ */
+ // public Map<String, String> getPropertyMap();
+ /**
+ * Get the property of this context.
+ */
+ String getProperty(String key);
+
+ /**
+ * Set a property of this context.
+ */
+ void putProperty(String key, String value);
+
+
+ /**
+ * Get a copy of the property map
+ * @return
+ * @since 0.9.20
+ */
+ Map<String, String> getCopyOfPropertyMap();
+
+ /**
+ * Contexts are named objects.
+ *
+ * @return the name for this context
+ */
+ String getName();
+
+ /**
+ * The name of the context can be set only once.
+ *
+ * @param name
+ */
+ void setName(String name);
+
+ /**
+ * The time at which this context was created, expressed in
+ * millisecond elapsed since the epoch (1.1.1970).
+ *
+ * @return The time as measured when this class was created.
+ */
+ long getBirthTime();
+
+ /**
+ * Object used for synchronization purposes.
+ * INTENDED FOR INTERNAL USAGE.
+ */
+ Object getConfigurationLock();
+
+
+ /**
+ * Every context has an ExecutorService which be invoked to execute certain
+ * tasks in a separate thread.
+ *
+ * @return the executor for this context.
+ * @since 1.0.0
+ */
+ ExecutorService getExecutorService();
+
+ /**
+ * Register a component that participates in the context's life cycle.
+ * <p>
+ * All components registered via this method will be stopped and removed
+ * from the context when the context is reset.
+ *
+ * @param component the subject component
+ */
+ void register(LifeCycle component);
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/ContextBase.java b/logback-core/src/main/java/ch/qos/logback/core/ContextBase.java
index 8c586f1..04ee24a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/ContextBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/ContextBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,18 +14,11 @@
package ch.qos.logback.core;
import static ch.qos.logback.core.CoreConstants.CONTEXT_NAME_KEY;
-import static ch.qos.logback.core.CoreConstants.FA_FILENAME_COLLISION_MAP;
-import static ch.qos.logback.core.CoreConstants.RFA_FILENAME_PATTERN_COLLISION_MAP;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import ch.qos.logback.core.rolling.helper.FileNamePattern;
import ch.qos.logback.core.spi.LifeCycle;
import ch.qos.logback.core.spi.LogbackLock;
import ch.qos.logback.core.status.StatusManager;
@@ -33,222 +26,176 @@ import ch.qos.logback.core.util.ExecutorServiceUtil;
public class ContextBase implements Context, LifeCycle {
- private long birthTime = System.currentTimeMillis();
-
- private String name;
- private StatusManager sm = new BasicStatusManager();
- // TODO propertyMap should be observable so that we can be notified
- // when it changes so that a new instance of propertyMap can be
- // serialized. For the time being, we ignore this shortcoming.
- Map<String, String> propertyMap = new HashMap<String, String>();
- Map<String, Object> objectMap = new HashMap<String, Object>();
-
- LogbackLock configurationLock = new LogbackLock();
-
- private ScheduledExecutorService scheduledExecutorService;
- protected List<ScheduledFuture<?>> scheduledFutures = new ArrayList<ScheduledFuture<?>>(1);
- private LifeCycleManager lifeCycleManager;
- private boolean started;
-
- public ContextBase() {
- initCollisionMaps();
- }
-
- public StatusManager getStatusManager() {
- return sm;
- }
-
- /**
- * Set the {@link StatusManager} for this context. Note that by default this
- * context is initialized with a {@link BasicStatusManager}. A null value for
- * the 'statusManager' argument is not allowed.
- * <p/>
- * <p> A malicious attacker can set the status manager to a dummy instance,
- * disabling internal error reporting.
- *
- * @param statusManager the new status manager
- */
- public void setStatusManager(StatusManager statusManager) {
- // this method was added in response to http://jira.qos.ch/browse/LBCORE-35
- if (statusManager == null) {
- throw new IllegalArgumentException("null StatusManager not allowed");
+ private long birthTime = System.currentTimeMillis();
+
+ private String name;
+ private StatusManager sm = new BasicStatusManager();
+ // TODO propertyMap should be observable so that we can be notified
+ // when it changes so that a new instance of propertyMap can be
+ // serialized. For the time being, we ignore this shortcoming.
+ Map<String, String> propertyMap = new HashMap<String, String>();
+ Map<String, Object> objectMap = new HashMap<String, Object>();
+
+ LogbackLock configurationLock = new LogbackLock();
+
+ private volatile ExecutorService executorService;
+ private LifeCycleManager lifeCycleManager;
+ private boolean started;
+
+ public StatusManager getStatusManager() {
+ return sm;
+ }
+
+ /**
+ * Set the {@link StatusManager} for this context. Note that by default this
+ * context is initialized with a {@link BasicStatusManager}. A null value for
+ * the 'statusManager' argument is not allowed.
+ * <p/>
+ * <p> A malicious attacker can set the status manager to a dummy instance,
+ * disabling internal error reporting.
+ *
+ * @param statusManager the new status manager
+ */
+ public void setStatusManager(StatusManager statusManager) {
+ // this method was added in response to http://jira.qos.ch/browse/LBCORE-35
+ if (statusManager == null) {
+ throw new IllegalArgumentException("null StatusManager not allowed");
+ }
+ this.sm = statusManager;
+ }
+
+ public Map<String, String> getCopyOfPropertyMap() {
+ return new HashMap<String, String>(propertyMap);
+ }
+
+ public void putProperty(String key, String val) {
+ this.propertyMap.put(key, val);
+ }
+
+ /**
+ * Given a key, return the corresponding property value. If invoked with
+ * the special key "CONTEXT_NAME", the name of the context is returned.
+ *
+ * @param key
+ * @return
+ */
+ public String getProperty(String key) {
+ if (CONTEXT_NAME_KEY.equals(key))
+ return getName();
+
+ return (String) this.propertyMap.get(key);
+ }
+
+ public Object getObject(String key) {
+ return objectMap.get(key);
+ }
+
+ public void putObject(String key, Object value) {
+ objectMap.put(key, value);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void start() {
+ // We'd like to create the executor service here, but we can't;
+ // ContextBase has not always implemented LifeCycle and there are *many*
+ // uses (mostly in tests) that would need to be modified.
+ started = true;
+ }
+
+ public void stop() {
+ // We don't check "started" here, because the executor service uses
+ // lazy initialization, rather than being created in the start method
+ stopExecutorService();
+ started = false;
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ /**
+ * Clear the internal objectMap and all properties.
+ */
+ public void reset() {
+ getLifeCycleManager().reset();
+ propertyMap.clear();
+ objectMap.clear();
+ }
+
+ /**
+ * The context name can be set only if it is not already set, or if the
+ * current name is the default context name, namely "default", or if the
+ * current name and the old name are the same.
+ *
+ * @throws IllegalStateException if the context already has a name, other than "default".
+ */
+ public void setName(String name) throws IllegalStateException {
+ if (name != null && name.equals(this.name)) {
+ return; // idempotent naming
+ }
+ if (this.name == null
+ || CoreConstants.DEFAULT_CONTEXT_NAME.equals(this.name)) {
+ this.name = name;
+ } else {
+ throw new IllegalStateException("Context has been already given a name");
+ }
+ }
+
+ public long getBirthTime() {
+ return birthTime;
+ }
+
+ public Object getConfigurationLock() {
+ return configurationLock;
+ }
+
+ public ExecutorService getExecutorService() {
+ if (executorService == null) {
+ synchronized (this) {
+ if (executorService == null) {
+ executorService = ExecutorServiceUtil.newExecutorService();
}
- this.sm = statusManager;
- }
-
- public Map<String, String> getCopyOfPropertyMap() {
- return new HashMap<String, String>(propertyMap);
- }
-
- public void putProperty(String key, String val) {
- this.propertyMap.put(key, val);
- }
-
- protected void initCollisionMaps() {
- putObject(FA_FILENAME_COLLISION_MAP, new HashMap<String, String>());
- putObject(RFA_FILENAME_PATTERN_COLLISION_MAP, new HashMap<String, FileNamePattern>());
- }
-
- /**
- * Given a key, return the corresponding property value. If invoked with
- * the special key "CONTEXT_NAME", the name of the context is returned.
- *
- * @param key
- * @return
- */
- public String getProperty(String key) {
- if (CONTEXT_NAME_KEY.equals(key))
- return getName();
-
- return (String) this.propertyMap.get(key);
- }
-
- public Object getObject(String key) {
- return objectMap.get(key);
- }
-
- public void putObject(String key, Object value) {
- objectMap.put(key, value);
- }
-
- public void removeObject(String key) {
- objectMap.remove(key);
- }
-
- public String getName() {
- return name;
- }
-
- public void start() {
- // We'd like to create the executor service here, but we can't;
- // ContextBase has not always implemented LifeCycle and there are *many*
- // uses (mostly in tests) that would need to be modified.
- started = true;
- }
-
- public void stop() {
- // We don't check "started" here, because the executor service uses
- // lazy initialization, rather than being created in the start method
- stopExecutorService();
-
- started = false;
- }
-
- public boolean isStarted() {
- return started;
- }
-
- /**
- * Clear the internal objectMap and all properties. Removes registered
- * shutdown hook
- */
- public void reset() {
-
- removeShutdownHook();
- getLifeCycleManager().reset();
- propertyMap.clear();
- objectMap.clear();
- }
-
- /**
- * The context name can be set only if it is not already set, or if the
- * current name is the default context name, namely "default", or if the
- * current name and the old name are the same.
- *
- * @throws IllegalStateException if the context already has a name, other than "default".
- */
- public void setName(String name) throws IllegalStateException {
- if (name != null && name.equals(this.name)) {
- return; // idempotent naming
- }
- if (this.name == null || CoreConstants.DEFAULT_CONTEXT_NAME.equals(this.name)) {
- this.name = name;
- } else {
- throw new IllegalStateException("Context has been already given a name");
- }
- }
-
- public long getBirthTime() {
- return birthTime;
- }
-
- public Object getConfigurationLock() {
- return configurationLock;
- }
-
- @Override
- /**
- * @deprecated
- */
- public synchronized ExecutorService getExecutorService() {
- return getScheduledExecutorService();
- }
-
- @Override
- public synchronized ScheduledExecutorService getScheduledExecutorService() {
- if (scheduledExecutorService == null) {
- scheduledExecutorService = ExecutorServiceUtil.newScheduledExecutorService();
- }
- return scheduledExecutorService;
- }
-
- private synchronized void stopExecutorService() {
- if (scheduledExecutorService != null) {
- ExecutorServiceUtil.shutdown(scheduledExecutorService);
- scheduledExecutorService = null;
- }
- }
-
- private void removeShutdownHook() {
- Thread hook = (Thread) getObject(CoreConstants.SHUTDOWN_HOOK_THREAD);
- if (hook != null) {
- removeObject(CoreConstants.SHUTDOWN_HOOK_THREAD);
- try {
- Runtime.getRuntime().removeShutdownHook(hook);
- } catch (IllegalStateException e) {
- // if JVM is already shutting down, ISE is thrown
- // no need to do anything else
- }
- }
- }
-
- public void register(LifeCycle component) {
- getLifeCycleManager().register(component);
- }
-
- /**
- * Gets the life cycle manager for this context.
- * <p>
- * The default implementation lazily initializes an instance of
- * {@link LifeCycleManager}. Subclasses may override to provide a custom
- * manager implementation, but must take care to return the same manager
- * object for each call to this method.
- * <p>
- * This is exposed primarily to support instrumentation for unit testing.
- *
- * @return manager object
- */
- synchronized LifeCycleManager getLifeCycleManager() {
- if (lifeCycleManager == null) {
- lifeCycleManager = new LifeCycleManager();
- }
- return lifeCycleManager;
- }
-
- @Override
- public String toString() {
- return name;
- }
-
- @Override
- public void addScheduledFuture(ScheduledFuture<?> scheduledFuture) {
- scheduledFutures.add(scheduledFuture);
- }
-
- public List<ScheduledFuture<?>> getScheduledFutures() {
- return new ArrayList<ScheduledFuture<?>>(scheduledFutures);
- }
-
-
+ }
+ }
+ return executorService;
+ }
+
+ private synchronized void stopExecutorService() {
+ if (executorService != null) {
+ ExecutorServiceUtil.shutdown(executorService);
+ executorService = null;
+ }
+ }
+
+ public void register(LifeCycle component) {
+ getLifeCycleManager().register(component);
+ }
+
+ /**
+ * Gets the life cycle manager for this context.
+ * <p>
+ * The default implementation lazily initializes an instance of
+ * {@link LifeCycleManager}. Subclasses may override to provide a custom
+ * manager implementation, but must take care to return the same manager
+ * object for each call to this method.
+ * <p>
+ * This is exposed primarily to support instrumentation for unit testing.
+ *
+ * @return manager object
+ */
+ synchronized LifeCycleManager getLifeCycleManager() {
+ if (lifeCycleManager == null) {
+ lifeCycleManager = new LifeCycleManager();
+ }
+ return lifeCycleManager;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java b/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java
index bb315da..996cce3 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,192 +13,166 @@
*/
package ch.qos.logback.core;
+import ch.qos.logback.core.util.EnvUtil;
public class CoreConstants {
- final public static String STATUS_LISTENER_CLASS = "logback.statusListenerClass";
- final public static String SYSOUT = "SYSOUT";
-
- /**
- * Number of idle threads to retain in a context's executor service.
- */
- public static final int CORE_POOL_SIZE = 0;
-
- // Apparently ScheduledThreadPoolExecutor has limitation where a task cannot be submitted from
- // within a running task unless the pool has worker threads already available. ThreadPoolExecutor
- // does not have this limitation.
- // This causes tests failures in SocketReceiverTest.testDispatchEventForEnabledLevel and
- // ServerSocketReceiverFunctionalTest.testLogEventFromClient.
- // We thus set a pool size > 0 for tests to pass.
- public static final int SCHEDULED_EXECUTOR_POOL_SIZE = 8;
-
-
- /**
- * Maximum number of threads to allow in a context's executor service.
- */
- // if you need a different MAX_POOL_SIZE, please file create a jira issue
- // asking to make MAX_POOL_SIZE a parameter.
- public static final int MAX_POOL_SIZE = 32;
-
- // Note that the line.separator property can be looked up even by
- // applets.
- public static final String LINE_SEPARATOR = System.getProperty("line.separator");
- public static final int LINE_SEPARATOR_LEN = LINE_SEPARATOR.length();
-
- public static final String CODES_URL = "http://logback.qos.ch/codes.html";
- public static final String MANUAL_URL_PREFIX = "http://logback.qos.ch/manual/";
- public static final String MORE_INFO_PREFIX = "For more information, please visit ";
-
- /**
- * The default context name.
- */
- public static final String DEFAULT_CONTEXT_NAME = "default";
- /**
- * Customized pattern conversion rules are stored under this key in the
- * {@link Context} object store.
- */
- public static final String PATTERN_RULE_REGISTRY = "PATTERN_RULE_REGISTRY";
-
- public static final String ISO8601_STR = "ISO8601";
- public static final String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS";
- public static final String DAILY_DATE_PATTERN = "yyyy-MM-dd";
-
- /**
- * Time format used in Common Log Format
- */
- public static final String CLF_DATE_PATTERN = "dd/MMM/yyyy:HH:mm:ss Z";
-
- /**
- * The key used in locating the evaluator map in context's object map.
- */
- public static final String EVALUATOR_MAP = "EVALUATOR_MAP";
-
- /**
- * Key used to locate a collision map for FileAppender instances in context's object map.
- *
- * The collision map consists of enties of the type (appender name, File option)
- */
- public static final String FA_FILENAME_COLLISION_MAP = "FA_FILENAME_COLLISION_MAP";
-
- /**
- * Key used to locate a collision map for RollingFileAppender instances in context's object map.
- *
- * The collision map consists of entities of the type (appender name, FileNamePattern option)
- */
- public static final String RFA_FILENAME_PATTERN_COLLISION_MAP = "RFA_FILENAME_PATTERN_COLLISION_MAP";
-
- /**
- * By convention, we assume that the static method named "valueOf" taking
- * a string argument can restore a given object from its string
- * representation.
- */
- public static final String VALUE_OF = "valueOf";
-
- /**
- * An empty string.
- */
- public static final String EMPTY_STRING = "";
-
- /**
- * An empty string array.
- */
- public static final String[] EMPTY_STRING_ARRAY = new String[] {};
-
- /**
- * An empty Class array.
- */
- public static final Class<?>[] EMPTY_CLASS_ARRAY = new Class[] {};
- public static final String CAUSED_BY = "Caused by: ";
- public static final String SUPPRESSED = "Suppressed: ";
- public static final String WRAPPED_BY = "Wrapped by: ";
-
- public static final char PERCENT_CHAR = '%';
- public static final char LEFT_PARENTHESIS_CHAR = '(';
- public static final char RIGHT_PARENTHESIS_CHAR = ')';
-
- public static final char ESCAPE_CHAR = '\\';
- public static final char CURLY_LEFT = '{';
- public static final char CURLY_RIGHT = '}';
- public static final char COMMA_CHAR = ',';
- public static final char DOUBLE_QUOTE_CHAR = '"';
- public static final char SINGLE_QUOTE_CHAR = '\'';
- public static final char COLON_CHAR = ':';
- public static final char DASH_CHAR = '-';
- public static final String DEFAULT_VALUE_SEPARATOR = ":-";
-
- /**
- * Number of rows before in an HTML table before,
- * we close the table and create a new one
- */
- public static final int TABLE_ROW_LIMIT = 10000;
-
- // reset the ObjectOutputStream every OOS_RESET_FREQUENCY calls
- // this avoid serious memory leaks
- public static final int OOS_RESET_FREQUENCY = 70;
-
- /**
- * The reference bogo instructions per second on
- * Ceki's machine (Orion)
- */
- public static long REFERENCE_BIPS = 9000;
-
- // the max number of times an error should be reported
- public static final int MAX_ERROR_COUNT = 4;
-
- public static final char DOT = '.';
- public static final char TAB = '\t';
- public static final char DOLLAR = '$';
-
- public static final String SEE_FNP_NOT_SET = "See also "+CODES_URL+"#tbr_fnp_not_set";
- public static final String SEE_MISSING_INTEGER_TOKEN = "See also "+CODES_URL+"#sat_missing_integer_token";
-
- public static final String CONFIGURATION_WATCH_LIST = "CONFIGURATION_WATCH_LIST";
- public static final String CONFIGURATION_WATCH_LIST_RESET_X = "CONFIGURATION_WATCH_LIST_RESET";
-
- public static final String SAFE_JORAN_CONFIGURATION = "SAFE_JORAN_CONFIGURATION";
- public static final String XML_PARSING = "XML_PARSING";
-
- // Context Object name for the shutdown hook
- public static final String SHUTDOWN_HOOK_THREAD = "SHUTDOWN_HOOK";
-
- /**
- * The key under which the local host name is registered in the logger
- * context.
- */
- public static final String HOSTNAME_KEY = "HOSTNAME";
-
- /**
- * The key under which the current context name is registered in the logger
- * context.
- */
- public static final String CONTEXT_NAME_KEY = "CONTEXT_NAME";
-
- public static final int BYTES_PER_INT = 4;
- public static final long MILLIS_IN_ONE_SECOND = 1000;
- public static final long MILLIS_IN_ONE_MINUTE = MILLIS_IN_ONE_SECOND * 60;
- public static final long MILLIS_IN_ONE_HOUR = MILLIS_IN_ONE_MINUTE * 60;
- public static final long MILLIS_IN_ONE_DAY = MILLIS_IN_ONE_HOUR * 24;
- public static final long MILLIS_IN_ONE_WEEK = MILLIS_IN_ONE_DAY * 7;
-
- /**
- * The number of seconds to wait for compression jobs to finish.
- */
- public static final int SECONDS_TO_WAIT_FOR_COMPRESSION_JOBS = 30;
-
- public static final String CONTEXT_SCOPE_VALUE = "context";
-
- public static final String RESET_MSG_PREFIX = "Will reset and reconfigure context ";
-
- public static final String JNDI_COMP_PREFIX = "java:comp/env";
-
- public static final String UNDEFINED_PROPERTY_SUFFIX = "_IS_UNDEFINED";
-
- public static final String LEFT_ACCOLADE = new String(new char[] { CURLY_LEFT });
- public static final String RIGHT_ACCOLADE = new String(new char[] { CURLY_RIGHT });
- public static final long UNBOUNDED_TOTAL_SIZE_CAP = 0;
- public static final int UNBOUND_HISTORY = 0;
-
- public static final String RECONFIGURE_ON_CHANGE_TASK = "RECONFIGURE_ON_CHANGE_TASK";
- public static final String SIZE_AND_TIME_BASED_FNATP_IS_DEPRECATED = "SizeAndTimeBasedFNATP is deprecated. Use SizeAndTimeBasedRollingPolicy instead";
+ /**
+ * Number of idle threads to retain in a context's executor service.
+ */
+ // CORE_POOL_SIZE must be 1 for JDK 1.5. For JDK 1.6 or higher it's set to 0
+ // so that there are no idle threads
+ public static final int CORE_POOL_SIZE = EnvUtil.isJDK5() ? 1 : 0;
+
+ /**
+ * Maximum number of threads to allow in a context's executor service.
+ */
+ // if you need a different MAX_POOL_SIZE, please file create a jira issue
+ // asking to make MAX_POOL_SIZE a parameter.
+ public static final int MAX_POOL_SIZE = 32;
+
+ // Note that the line.separator property can be looked up even by
+ // applets.
+ public static final String LINE_SEPARATOR = System.getProperty("line.separator");
+ public static final int LINE_SEPARATOR_LEN = LINE_SEPARATOR.length();
+
+
+ public static final String CODES_URL = "http://logback.qos.ch/codes.html";
+ /**
+ * The default context name.
+ */
+ public static final String DEFAULT_CONTEXT_NAME = "default";
+ /**
+ * Customized pattern conversion rules are stored under this key in the
+ * {@link Context} object store.
+ */
+ public static final String PATTERN_RULE_REGISTRY = "PATTERN_RULE_REGISTRY";
+
+ public static final String ISO8601_STR = "ISO8601";
+ public static final String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS";
+ public static final String DAILY_DATE_PATTERN = "yyyy-MM-dd";
+
+ /**
+ * Time format used in Common Log Format
+ */
+ public static final String CLF_DATE_PATTERN = "dd/MMM/yyyy:HH:mm:ss Z";
+
+ /**
+ * The key used in locating the evaluator map in context's object map.
+ */
+ public static final String EVALUATOR_MAP = "EVALUATOR_MAP";
+
+ /**
+ * By convention, we assume that the static method named "valueOf" taking
+ * a string argument can restore a given object from its string
+ * representation.
+ */
+ public static final String VALUE_OF = "valueOf";
+
+ /**
+ * An empty string.
+ */
+ public static final String EMPTY_STRING = "";
+
+ /**
+ * An empty string array.
+ */
+ public static final String[] EMPTY_STRING_ARRAY = new String[]{};
+
+ /**
+ * An empty Class array.
+ */
+ public static final Class<?>[] EMPTY_CLASS_ARRAY = new Class[]{};
+ public static final String CAUSED_BY = "Caused by: ";
+ public static final String SUPPRESSED = "Suppressed: ";
+ public static final String WRAPPED_BY = "Wrapped by: ";
+
+ public static final char PERCENT_CHAR = '%';
+ public static final char LEFT_PARENTHESIS_CHAR = '(';
+ public static final char RIGHT_PARENTHESIS_CHAR = ')';
+
+ public static final char ESCAPE_CHAR = '\\';
+ public static final char CURLY_LEFT = '{';
+ public static final char CURLY_RIGHT = '}';
+ public static final char COMMA_CHAR = ',';
+ public static final char DOUBLE_QUOTE_CHAR = '"';
+ public static final char SINGLE_QUOTE_CHAR = '\'';
+ public static final char COLON_CHAR = ':';
+ public static final char DASH_CHAR = '-';
+ public static final String DEFAULT_VALUE_SEPARATOR = ":-";
+
+
+ /**
+ * Number of rows before in an HTML table before,
+ * we close the table and create a new one
+ */
+ public static final int TABLE_ROW_LIMIT = 10000;
+
+
+ // reset the ObjectOutputStream every OOS_RESET_FREQUENCY calls
+ // this avoid serious memory leaks
+ public static final int OOS_RESET_FREQUENCY = 70;
+
+ /**
+ * The reference bogo instructions per second on
+ * Ceki's machine (Orion)
+ */
+ public static long REFERENCE_BIPS = 9000;
+
+
+ // the max number of times an error should be reported
+ public static final int MAX_ERROR_COUNT = 4;
+
+
+ public static final char DOT = '.';
+ public static final char TAB = '\t';
+ public static final char DOLLAR = '$';
+
+ public static final String SEE_FNP_NOT_SET = "See also http://logback.qos.ch/codes.html#tbr_fnp_not_set";
+
+ public static final String CONFIGURATION_WATCH_LIST = "CONFIGURATION_WATCH_LIST";
+ public static final String CONFIGURATION_WATCH_LIST_RESET = "CONFIGURATION_WATCH_LIST_RESET";
+
+ public static final String SAFE_JORAN_CONFIGURATION = "SAFE_JORAN_CONFIGURATION";
+ public static final String XML_PARSING = "XML_PARSING";
+
+
+
+ /**
+ * The key under which the local host name is registered in the logger
+ * context.
+ */
+ public static final String HOSTNAME_KEY = "HOSTNAME";
+
+ /**
+ * The key under which the current context name is registered in the logger
+ * context.
+ */
+ public static final String CONTEXT_NAME_KEY = "CONTEXT_NAME";
+
+
+ public static final int BYTES_PER_INT = 4;
+ public static final int MILLIS_IN_ONE_SECOND = 1000;
+ public static final int MILLIS_IN_ONE_MINUTE = MILLIS_IN_ONE_SECOND*60;
+ public static final int MILLIS_IN_ONE_HOUR = MILLIS_IN_ONE_MINUTE*60;
+ public static final int MILLIS_IN_ONE_DAY = MILLIS_IN_ONE_HOUR*24;
+ public static final int MILLIS_IN_ONE_WEEK = MILLIS_IN_ONE_DAY*7;
+
+ /**
+ * The number of seconds to wait for compression jobs to finish.
+ */
+ public static final int SECONDS_TO_WAIT_FOR_COMPRESSION_JOBS = 30;
+
+ public static final String CONTEXT_SCOPE_VALUE = "context";
+
+ public static final String RESET_MSG_PREFIX = "Will reset and reconfigure context ";
+
+
+ public static final String JNDI_COMP_PREFIX = "java:comp/env";
+
+ public static final String UNDEFINED_PROPERTY_SUFFIX = "_IS_UNDEFINED";
+
+ public static final String LEFT_ACCOLADE = new String(new char[] {CURLY_LEFT});
+ public static final String RIGHT_ACCOLADE = new String(new char[] {CURLY_RIGHT});
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/FileAppender.java b/logback-core/src/main/java/ch/qos/logback/core/FileAppender.java
index 9851aa0..3f6c116 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/FileAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/FileAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,18 +13,12 @@
*/
package ch.qos.logback.core;
-import static ch.qos.logback.core.CoreConstants.CODES_URL;
-import static ch.qos.logback.core.CoreConstants.MORE_INFO_PREFIX;
-
import java.io.File;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
-import java.util.Map;
-import java.util.Map.Entry;
import ch.qos.logback.core.recovery.ResilientFileOutputStream;
-import ch.qos.logback.core.util.ContextUtil;
import ch.qos.logback.core.util.FileUtil;
/**
@@ -37,236 +31,182 @@ import ch.qos.logback.core.util.FileUtil;
*/
public class FileAppender<E> extends OutputStreamAppender<E> {
- static protected String COLLISION_WITH_EARLIER_APPENDER_URL = CODES_URL + "#earlier_fa_collision";
-
- /**
- * Append to or truncate the file? The default value for this variable is
- * <code>true</code>, meaning that by default a <code>FileAppender</code> will
- * append to an existing file and not truncate it.
- */
- protected boolean append = true;
-
- /**
- * The name of the active log file.
- */
- protected String fileName = null;
-
- private boolean prudent = false;
-
- /**
- * The <b>File</b> property takes a string value which should be the name of
- * the file to append to.
- */
- public void setFile(String file) {
- if (file == null) {
- fileName = file;
- } else {
- // Trim spaces from both ends. The users probably does not want
- // trailing spaces in file names.
- fileName = file.trim();
- }
- }
-
- /**
- * Returns the value of the <b>Append</b> property.
- */
- public boolean isAppend() {
- return append;
- }
-
- /**
- * This method is used by derived classes to obtain the raw file property.
- * Regular users should not be calling this method.
- *
- * @return the value of the file property
- */
- final public String rawFileProperty() {
- return fileName;
- }
-
- /**
- * Returns the value of the <b>File</b> property.
- *
- * <p>
- * This method may be overridden by derived classes.
- *
- */
- public String getFile() {
- return fileName;
- }
-
- /**
- * If the value of <b>File</b> is not <code>null</code>, then
- * {@link #openFile} is called with the values of <b>File</b> and
- * <b>Append</b> properties.
- */
- public void start() {
- int errors = 0;
- if (getFile() != null) {
- addInfo("File property is set to [" + fileName + "]");
-
- if (prudent) {
- if (!isAppend()) {
- setAppend(true);
- addWarn("Setting \"Append\" property to true on account of \"Prudent\" mode");
- }
- }
-
- if (checkForFileCollisionInPreviousFileAppenders()) {
- addError("Collisions detected with FileAppender/RollingAppender instances defined earlier. Aborting.");
- addError(MORE_INFO_PREFIX + COLLISION_WITH_EARLIER_APPENDER_URL);
- errors++;
- } else {
- // file should be opened only if collision free
- try {
- openFile(getFile());
- } catch (java.io.IOException e) {
- errors++;
- addError("openFile(" + fileName + "," + append + ") call failed.", e);
- }
- }
- } else {
- errors++;
- addError("\"File\" property not set for appender named [" + name + "].");
- }
- if (errors == 0) {
- super.start();
- }
- }
-
- @Override
- public void stop() {
- super.stop();
-
- Map<String, String> map = ContextUtil.getFilenameCollisionMap(context);
- if (map == null || getName() == null)
- return;
-
- map.remove(getName());
+ /**
+ * Append to or truncate the file? The default value for this variable is
+ * <code>true</code>, meaning that by default a <code>FileAppender</code> will
+ * append to an existing file and not truncate it.
+ */
+ protected boolean append = true;
+
+ /**
+ * The name of the active log file.
+ */
+ protected String fileName = null;
+
+ private boolean prudent = false;
+
+ /**
+ * The <b>File</b> property takes a string value which should be the name of
+ * the file to append to.
+ */
+ public void setFile(String file) {
+ if (file == null) {
+ fileName = file;
+ } else {
+ // Trim spaces from both ends. The users probably does not want
+ // trailing spaces in file names.
+ fileName = file.trim();
}
-
- protected boolean checkForFileCollisionInPreviousFileAppenders() {
- boolean collisionsDetected = false;
- if (fileName == null) {
- return false;
- }
- @SuppressWarnings("unchecked")
- Map<String, String> map = (Map<String, String>) context.getObject(CoreConstants.FA_FILENAME_COLLISION_MAP);
- if (map == null) {
- return collisionsDetected;
+ }
+
+ /**
+ * Returns the value of the <b>Append</b> property.
+ */
+ public boolean isAppend() {
+ return append;
+ }
+
+ /**
+ * This method is used by derived classes to obtain the raw file property.
+ * Regular users should not be calling this method.
+ *
+ * @return the value of the file property
+ */
+ final public String rawFileProperty() {
+ return fileName;
+ }
+
+ /**
+ * Returns the value of the <b>File</b> property.
+ *
+ * <p>
+ * This method may be overridden by derived classes.
+ *
+ */
+ public String getFile() {
+ return fileName;
+ }
+
+ /**
+ * If the value of <b>File</b> is not <code>null</code>, then
+ * {@link #openFile} is called with the values of <b>File</b> and
+ * <b>Append</b> properties.
+ */
+ public void start() {
+ int errors = 0;
+ if (getFile() != null) {
+ addInfo("File property is set to [" + fileName + "]");
+
+ if (prudent) {
+ if (!isAppend()) {
+ setAppend(true);
+ addWarn("Setting \"Append\" property to true on account of \"Prudent\" mode");
}
- for (Entry<String, String> entry : map.entrySet()) {
- if (fileName.equals(entry.getValue())) {
- addErrorForCollision("File", entry.getValue(), entry.getKey());
- collisionsDetected = true;
- }
- }
- if (name != null) {
- map.put(getName(), fileName);
- }
- return collisionsDetected;
+ }
+
+ try {
+ openFile(getFile());
+ } catch (java.io.IOException e) {
+ errors++;
+ addError("openFile(" + fileName + "," + append + ") call failed.", e);
+ }
+ } else {
+ errors++;
+ addError("\"File\" property not set for appender named [" + name + "].");
}
-
- protected void addErrorForCollision(String optionName, String optionValue, String appenderName) {
- addError("'" + optionName + "' option has the same value \"" + optionValue + "\" as that given for appender [" + appenderName + "] defined earlier.");
+ if (errors == 0) {
+ super.start();
}
-
- /**
- * <p>
- * Sets and <i>opens</i> the file where the log output will go. The specified
- * file must be writable.
- *
- * <p>
- * If there was already an opened file, then the previous file is closed
- * first.
- *
- * <p>
- * <b>Do not use this method directly. To configure a FileAppender or one of
- * its subclasses, set its properties one by one and then call start().</b>
- *
- * @param file_name
- * The path to the log file.
- */
- public void openFile(String file_name) throws IOException {
- lock.lock();
- try {
- File file = new File(file_name);
- boolean result = FileUtil.createMissingParentDirectories(file);
- if (!result) {
- addError("Failed to create parent directories for [" + file.getAbsolutePath() + "]");
- }
-
- ResilientFileOutputStream resilientFos = new ResilientFileOutputStream(file, append);
- resilientFos.setContext(context);
- setOutputStream(resilientFos);
- } finally {
- lock.unlock();
+ }
+
+ /**
+ * <p>
+ * Sets and <i>opens</i> the file where the log output will go. The specified
+ * file must be writable.
+ *
+ * <p>
+ * If there was already an opened file, then the previous file is closed
+ * first.
+ *
+ * <p>
+ * <b>Do not use this method directly. To configure a FileAppender or one of
+ * its subclasses, set its properties one by one and then call start().</b>
+ *
+ * @param file_name
+ * The path to the log file.
+ */
+ public void openFile(String file_name) throws IOException {
+ lock.lock();
+ try {
+ File file = new File(file_name);
+ if (FileUtil.isParentDirectoryCreationRequired(file)) {
+ boolean result = FileUtil.createMissingParentDirectories(file);
+ if (!result) {
+ addError("Failed to create parent directories for ["
+ + file.getAbsolutePath() + "]");
}
+ }
+
+ ResilientFileOutputStream resilientFos = new ResilientFileOutputStream(
+ file, append);
+ resilientFos.setContext(context);
+ setOutputStream(resilientFos);
+ } finally {
+ lock.unlock();
}
-
- /**
- * @see #setPrudent(boolean)
- *
- * @return true if in prudent mode
- */
- public boolean isPrudent() {
- return prudent;
+ }
+
+ /**
+ * @see #setPrudent(boolean)
+ *
+ * @return true if in prudent mode
+ */
+ public boolean isPrudent() {
+ return prudent;
+ }
+
+ /**
+ * When prudent is set to true, file appenders from multiple JVMs can safely
+ * write to the same file.
+ *
+ * @param prudent
+ */
+ public void setPrudent(boolean prudent) {
+ this.prudent = prudent;
+ }
+
+ public void setAppend(boolean append) {
+ this.append = append;
+ }
+
+ private void safeWrite(E event) throws IOException {
+ ResilientFileOutputStream resilientFOS = (ResilientFileOutputStream) getOutputStream();
+ FileChannel fileChannel = resilientFOS.getChannel();
+ if (fileChannel == null) {
+ return;
}
-
- /**
- * When prudent is set to true, file appenders from multiple JVMs can safely
- * write to the same file.
- *
- * @param prudent
- */
- public void setPrudent(boolean prudent) {
- this.prudent = prudent;
+ FileLock fileLock = null;
+ try {
+ fileLock = fileChannel.lock();
+ long position = fileChannel.position();
+ long size = fileChannel.size();
+ if (size != position) {
+ fileChannel.position(size);
+ }
+ super.writeOut(event);
+ } finally {
+ if (fileLock != null) {
+ fileLock.release();
+ }
}
-
- public void setAppend(boolean append) {
- this.append = append;
- }
-
- private void safeWrite(E event) throws IOException {
- ResilientFileOutputStream resilientFOS = (ResilientFileOutputStream) getOutputStream();
- FileChannel fileChannel = resilientFOS.getChannel();
- if (fileChannel == null) {
- return;
- }
-
- // Clear any current interrupt (see LOGBACK-875)
- boolean interrupted = Thread.interrupted();
-
- FileLock fileLock = null;
- try {
- fileLock = fileChannel.lock();
- long position = fileChannel.position();
- long size = fileChannel.size();
- if (size != position) {
- fileChannel.position(size);
- }
- super.writeOut(event);
- } catch (IOException e) {
- // Mainly to catch FileLockInterruptionExceptions (see LOGBACK-875)
- resilientFOS.postIOFailure(e);
- } finally {
- if (fileLock != null && fileLock.isValid()) {
- fileLock.release();
- }
-
- // Re-interrupt if we started in an interrupted state (see LOGBACK-875)
- if (interrupted) {
- Thread.currentThread().interrupt();
- }
- }
- }
-
- @Override
- protected void writeOut(E event) throws IOException {
- if (prudent) {
- safeWrite(event);
- } else {
- super.writeOut(event);
- }
+ }
+
+ @Override
+ protected void writeOut(E event) throws IOException {
+ if (prudent) {
+ safeWrite(event);
+ } else {
+ super.writeOut(event);
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/Layout.java b/logback-core/src/main/java/ch/qos/logback/core/Layout.java
index 925b924..50e1087 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/Layout.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/Layout.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,54 +17,54 @@ import ch.qos.logback.core.spi.ContextAware;
import ch.qos.logback.core.spi.LifeCycle;
public interface Layout<E> extends ContextAware, LifeCycle {
+
+ /**
+ * Transform an event (of type Object) and return it as a String after
+ * appropriate formatting.
+ *
+ * <p>Taking in an object and returning a String is the least sophisticated
+ * way of formatting events. However, it is remarkably CPU-effective.
+ * </p>
+ *
+ * @param event The event to format
+ * @return the event formatted as a String
+ */
+ String doLayout(E event);
+
+ /**
+ * Return the file header for this layout. The returned value may be null.
+ * @return The header.
+ */
+ String getFileHeader();
- /**
- * Transform an event (of type Object) and return it as a String after
- * appropriate formatting.
- *
- * <p>Taking in an object and returning a String is the least sophisticated
- * way of formatting events. However, it is remarkably CPU-effective.
- * </p>
- *
- * @param event The event to format
- * @return the event formatted as a String
- */
- String doLayout(E event);
-
- /**
- * Return the file header for this layout. The returned value may be null.
- * @return The header.
- */
- String getFileHeader();
-
- /**
- * Return the header of the logging event formatting. The returned value
- * may be null.
- *
- * @return The header.
- */
- String getPresentationHeader();
-
- /**
- * Return the footer of the logging event formatting. The returned value
- * may be null.
- *
- * @return The footer.
- */
-
- String getPresentationFooter();
-
- /**
- * Return the file footer for this layout. The returned value may be null.
- * @return The footer.
- */
- String getFileFooter();
-
- /**
- * Returns the content type as appropriate for the implementation.
- *
- * @return
- */
- String getContentType();
+ /**
+ * Return the header of the logging event formatting. The returned value
+ * may be null.
+ *
+ * @return The header.
+ */
+ String getPresentationHeader();
+ /**
+ * Return the footer of the logging event formatting. The returned value
+ * may be null.
+ *
+ * @return The footer.
+ */
+
+ String getPresentationFooter();
+
+ /**
+ * Return the file footer for this layout. The returned value may be null.
+ * @return The footer.
+ */
+ String getFileFooter();
+
+ /**
+ * Returns the content type as appropriate for the implementation.
+ *
+ * @return
+ */
+ String getContentType();
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/LayoutBase.java b/logback-core/src/main/java/ch/qos/logback/core/LayoutBase.java
index 1a7301c..daf1885 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/LayoutBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/LayoutBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,68 +15,68 @@ package ch.qos.logback.core;
import ch.qos.logback.core.spi.ContextAwareBase;
-abstract public class LayoutBase<E> extends ContextAwareBase implements Layout<E> {
-
- protected boolean started;
-
- String fileHeader;
- String fileFooter;
- String presentationHeader;
- String presentationFooter;
-
- public void setContext(Context context) {
- this.context = context;
- }
-
- public Context getContext() {
- return this.context;
- }
-
- public void start() {
- started = true;
- }
-
- public void stop() {
- started = false;
- }
-
- public boolean isStarted() {
- return started;
- }
-
- public String getFileHeader() {
- return fileHeader;
- }
-
- public String getPresentationHeader() {
- return presentationHeader;
- }
-
- public String getPresentationFooter() {
- return presentationFooter;
- }
-
- public String getFileFooter() {
- return fileFooter;
- }
-
- public String getContentType() {
- return "text/plain";
- }
-
- public void setFileHeader(String header) {
- this.fileHeader = header;
- }
-
- public void setFileFooter(String footer) {
- this.fileFooter = footer;
- }
-
- public void setPresentationHeader(String header) {
- this.presentationHeader = header;
- }
-
- public void setPresentationFooter(String footer) {
- this.presentationFooter = footer;
- }
+abstract public class LayoutBase<E> extends ContextAwareBase implements Layout<E> {
+
+ protected boolean started;
+
+ String fileHeader;
+ String fileFooter;
+ String presentationHeader;
+ String presentationFooter;
+
+ public void setContext(Context context) {
+ this.context = context;
+ }
+
+ public Context getContext() {
+ return this.context;
+ }
+
+ public void start() {
+ started = true;
+ }
+
+ public void stop() {
+ started = false;
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public String getFileHeader() {
+ return fileHeader;
+ }
+
+ public String getPresentationHeader() {
+ return presentationHeader;
+ }
+
+ public String getPresentationFooter() {
+ return presentationFooter;
+ }
+
+ public String getFileFooter() {
+ return fileFooter;
+ }
+
+ public String getContentType() {
+ return "text/plain";
+ }
+
+ public void setFileHeader(String header) {
+ this.fileHeader = header;
+ }
+
+ public void setFileFooter(String footer) {
+ this.fileFooter = footer;
+ }
+
+ public void setPresentationHeader(String header) {
+ this.presentationHeader = header;
+ }
+
+ public void setPresentationFooter(String footer) {
+ this.presentationFooter = footer;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/LifeCycleManager.java b/logback-core/src/main/java/ch/qos/logback/core/LifeCycleManager.java
index d4d198b..10a3ac4 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/LifeCycleManager.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/LifeCycleManager.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2011, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -11,6 +11,7 @@
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
+
package ch.qos.logback.core;
import java.util.HashSet;
@@ -27,29 +28,29 @@ import ch.qos.logback.core.spi.LifeCycle;
*/
public class LifeCycleManager {
- private final Set<LifeCycle> components = new HashSet<LifeCycle>();
-
- /**
- * Registers a component with this manager.
- * <p>
- * @param component the component whose life cycle is to be managed
- */
- public void register(LifeCycle component) {
- components.add(component);
+ private final Set<LifeCycle> components = new HashSet<LifeCycle>();
+
+ /**
+ * Registers a component with this manager.
+ * <p>
+ * @param component the component whose life cycle is to be managed
+ */
+ public void register(LifeCycle component) {
+ components.add(component);
+ }
+
+ /**
+ * Resets this manager.
+ * <p>
+ * All registered components are stopped and removed from the manager.
+ */
+ public void reset() {
+ for (LifeCycle component : components) {
+ if (component.isStarted()) {
+ component.stop();
+ }
}
-
- /**
- * Resets this manager.
- * <p>
- * All registered components are stopped and removed from the manager.
- */
- public void reset() {
- for (LifeCycle component : components) {
- if (component.isStarted()) {
- component.stop();
- }
- }
- components.clear();
- }
-
+ components.clear();
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/LogbackException.java b/logback-core/src/main/java/ch/qos/logback/core/LogbackException.java
index 5e13523..f713085 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/LogbackException.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/LogbackException.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,14 +15,15 @@ package ch.qos.logback.core;
public class LogbackException extends RuntimeException {
- private static final long serialVersionUID = -799956346239073266L;
-
- public LogbackException(String msg) {
- super(msg);
- }
-
- public LogbackException(String msg, Throwable nested) {
- super(msg, nested);
- }
+ private static final long serialVersionUID = -799956346239073266L;
+ public LogbackException(String msg) {
+ super(msg);
+ }
+
+
+ public LogbackException(String msg, Throwable nested) {
+ super(msg, nested);
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/OutputStreamAppender.java b/logback-core/src/main/java/ch/qos/logback/core/OutputStreamAppender.java
index 93518cb..e2c8a6f 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/OutputStreamAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/OutputStreamAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -35,198 +35,205 @@ import ch.qos.logback.core.status.ErrorStatus;
*/
public class OutputStreamAppender<E> extends UnsynchronizedAppenderBase<E> {
- /**
- * It is the encoder which is ultimately responsible for writing the event to
- * an {@link OutputStream}.
- */
- protected Encoder<E> encoder;
-
- /**
- * All synchronization in this class is done via the lock object.
- */
- protected final ReentrantLock lock = new ReentrantLock(true);
-
- /**
- * This is the {@link OutputStream outputStream} where output will be written.
- */
- private OutputStream outputStream;
-
- /**
- * The underlying output stream used by this appender.
- *
- * @return
- */
- public OutputStream getOutputStream() {
- return outputStream;
+
+ /**
+ * It is the encoder which is ultimately responsible for writing the event to
+ * an {@link OutputStream}.
+ */
+ protected Encoder<E> encoder;
+
+ /**
+ * All synchronization in this class is done via the lock object.
+ */
+ protected final ReentrantLock lock = new ReentrantLock(true);
+
+ /**
+ * This is the {@link OutputStream outputStream} where output will be written.
+ */
+ private OutputStream outputStream;
+
+ /**
+ * The underlying output stream used by this appender.
+ *
+ * @return
+ */
+ public OutputStream getOutputStream() {
+ return outputStream;
+ }
+
+ /**
+ * Checks that requires parameters are set and if everything is in order,
+ * activates this appender.
+ */
+ public void start() {
+ int errors = 0;
+ if (this.encoder == null) {
+ addStatus(new ErrorStatus("No encoder set for the appender named \""
+ + name + "\".", this));
+ errors++;
}
- /**
- * Checks that requires parameters are set and if everything is in order,
- * activates this appender.
- */
- public void start() {
- int errors = 0;
- if (this.encoder == null) {
- addStatus(new ErrorStatus("No encoder set for the appender named \"" + name + "\".", this));
- errors++;
- }
-
- if (this.outputStream == null) {
- addStatus(new ErrorStatus("No output stream set for the appender named \"" + name + "\".", this));
- errors++;
- }
- // only error free appenders should be activated
- if (errors == 0) {
- super.start();
- }
+ if (this.outputStream == null) {
+ addStatus(new ErrorStatus(
+ "No output stream set for the appender named \"" + name + "\".", this));
+ errors++;
}
-
- public void setLayout(Layout<E> layout) {
- addWarn("This appender no longer admits a layout as a sub-component, set an encoder instead.");
- addWarn("To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.");
- addWarn("See also " + CODES_URL + "#layoutInsteadOfEncoder for details");
- LayoutWrappingEncoder<E> lwe = new LayoutWrappingEncoder<E>();
- lwe.setLayout(layout);
- lwe.setContext(context);
- this.encoder = lwe;
- }
-
- @Override
- protected void append(E eventObject) {
- if (!isStarted()) {
- return;
- }
-
- subAppend(eventObject);
+ // only error free appenders should be activated
+ if (errors == 0) {
+ super.start();
}
-
- /**
- * Stop this appender instance. The underlying stream or writer is also
- * closed.
- *
- * <p>
- * Stopped appenders cannot be reused.
- */
- public void stop() {
- lock.lock();
- try {
- closeOutputStream();
- super.stop();
- } finally {
- lock.unlock();
- }
+ }
+
+ public void setLayout(Layout<E> layout) {
+ addWarn("This appender no longer admits a layout as a sub-component, set an encoder instead.");
+ addWarn("To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.");
+ addWarn("See also "+CODES_URL+"#layoutInsteadOfEncoder for details");
+ LayoutWrappingEncoder<E> lwe = new LayoutWrappingEncoder<E>();
+ lwe.setLayout(layout);
+ lwe.setContext(context);
+ this.encoder = lwe;
+ }
+
+ @Override
+ protected void append(E eventObject) {
+ if (!isStarted()) {
+ return;
}
- /**
- * Close the underlying {@link OutputStream}.
- */
- protected void closeOutputStream() {
- if (this.outputStream != null) {
- try {
- // before closing we have to output out layout's footer
- encoderClose();
- this.outputStream.close();
- this.outputStream = null;
- } catch (IOException e) {
- addStatus(new ErrorStatus("Could not close output stream for OutputStreamAppender.", this, e));
- }
- }
+ subAppend(eventObject);
+ }
+
+ /**
+ * Stop this appender instance. The underlying stream or writer is also
+ * closed.
+ *
+ * <p>
+ * Stopped appenders cannot be reused.
+ */
+ public void stop() {
+ lock.lock();
+ try {
+ closeOutputStream();
+ super.stop();
+ } finally {
+ lock.unlock();
}
-
- void encoderInit() {
- if (encoder != null && this.outputStream != null) {
- try {
- encoder.init(outputStream);
- } catch (IOException ioe) {
- this.started = false;
- addStatus(new ErrorStatus("Failed to initialize encoder for appender named [" + name + "].", this, ioe));
- }
- }
+ }
+
+ /**
+ * Close the underlying {@link OutputStream}.
+ */
+ protected void closeOutputStream() {
+ if (this.outputStream != null) {
+ try {
+ // before closing we have to output out layout's footer
+ encoderClose();
+ this.outputStream.close();
+ this.outputStream = null;
+ } catch (IOException e) {
+ addStatus(new ErrorStatus(
+ "Could not close output stream for OutputStreamAppender.", this, e));
+ }
}
-
- void encoderClose() {
- if (encoder != null && this.outputStream != null) {
- try {
- encoder.close();
- } catch (IOException ioe) {
- this.started = false;
- addStatus(new ErrorStatus("Failed to write footer for appender named [" + name + "].", this, ioe));
- }
- }
+ }
+
+ void encoderInit() {
+ if (encoder != null && this.outputStream != null) {
+ try {
+ encoder.init(outputStream);
+ } catch (IOException ioe) {
+ this.started = false;
+ addStatus(new ErrorStatus(
+ "Failed to initialize encoder for appender named [" + name + "].",
+ this, ioe));
+ }
}
-
- /**
- * <p>
- * Sets the @link OutputStream} where the log output will go. The specified
- * <code>OutputStream</code> must be opened by the user and be writable. The
- * <code>OutputStream</code> will be closed when the appender instance is
- * closed.
- *
- * @param outputStream
- * An already opened OutputStream.
- */
- public void setOutputStream(OutputStream outputStream) {
- lock.lock();
- try {
- // close any previously opened output stream
- closeOutputStream();
-
- this.outputStream = outputStream;
- if (encoder == null) {
- addWarn("Encoder has not been set. Cannot invoke its init method.");
- return;
- }
-
- encoderInit();
- } finally {
- lock.unlock();
- }
+ }
+
+ void encoderClose() {
+ if (encoder != null && this.outputStream != null) {
+ try {
+ encoder.close();
+ } catch (IOException ioe) {
+ this.started = false;
+ addStatus(new ErrorStatus("Failed to write footer for appender named ["
+ + name + "].", this, ioe));
+ }
}
-
- protected void writeOut(E event) throws IOException {
- this.encoder.doEncode(event);
+ }
+
+ /**
+ * <p>
+ * Sets the @link OutputStream} where the log output will go. The specified
+ * <code>OutputStream</code> must be opened by the user and be writable. The
+ * <code>OutputStream</code> will be closed when the appender instance is
+ * closed.
+ *
+ * @param outputStream
+ * An already opened OutputStream.
+ */
+ public void setOutputStream(OutputStream outputStream) {
+ lock.lock();
+ try {
+ // close any previously opened output stream
+ closeOutputStream();
+
+ this.outputStream = outputStream;
+ if (encoder == null) {
+ addWarn("Encoder has not been set. Cannot invoke its init method.");
+ return;
+ }
+
+ encoderInit();
+ } finally {
+ lock.unlock();
}
-
- /**
- * Actual writing occurs here.
- * <p>
- * Most subclasses of <code>WriterAppender</code> will need to override this
- * method.
- *
- * @since 0.9.0
- */
- protected void subAppend(E event) {
- if (!isStarted()) {
- return;
- }
- try {
- // this step avoids LBCLASSIC-139
- if (event instanceof DeferredProcessingAware) {
- ((DeferredProcessingAware) event).prepareForDeferredProcessing();
- }
- // the synchronization prevents the OutputStream from being closed while we
- // are writing. It also prevents multiple threads from entering the same
- // converter. Converters assume that they are in a synchronized block.
- lock.lock();
- try {
- writeOut(event);
- } finally {
- lock.unlock();
- }
- } catch (IOException ioe) {
- // as soon as an exception occurs, move to non-started state
- // and add a single ErrorStatus to the SM.
- this.started = false;
- addStatus(new ErrorStatus("IO failure in appender", this, ioe));
- }
+ }
+
+ protected void writeOut(E event) throws IOException {
+ this.encoder.doEncode(event);
+ }
+
+ /**
+ * Actual writing occurs here.
+ * <p>
+ * Most subclasses of <code>WriterAppender</code> will need to override this
+ * method.
+ *
+ * @since 0.9.0
+ */
+ protected void subAppend(E event) {
+ if (!isStarted()) {
+ return;
}
-
- public Encoder<E> getEncoder() {
- return encoder;
+ try {
+ // this step avoids LBCLASSIC-139
+ if (event instanceof DeferredProcessingAware) {
+ ((DeferredProcessingAware) event).prepareForDeferredProcessing();
+ }
+ // the synchronization prevents the OutputStream from being closed while we
+ // are writing. It also prevents multiple threads from entering the same
+ // converter. Converters assume that they are in a synchronized block.
+ lock.lock();
+ try {
+ writeOut(event);
+ } finally {
+ lock.unlock();
+ }
+ } catch (IOException ioe) {
+ // as soon as an exception occurs, move to non-started state
+ // and add a single ErrorStatus to the SM.
+ this.started = false;
+ addStatus(new ErrorStatus("IO failure in appender", this, ioe));
}
+ }
- public void setEncoder(Encoder<E> encoder) {
- this.encoder = encoder;
- }
+ public Encoder<E> getEncoder() {
+ return encoder;
+ }
+ public void setEncoder(Encoder<E> encoder) {
+ this.encoder = encoder;
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/PropertyDefinerBase.java b/logback-core/src/main/java/ch/qos/logback/core/PropertyDefinerBase.java
index 76d884b..12c1345 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/PropertyDefinerBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/PropertyDefinerBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,8 +23,8 @@ import ch.qos.logback.core.spi.PropertyDefiner;
*/
public abstract class PropertyDefinerBase extends ContextAwareBase implements PropertyDefiner {
- static protected String booleanAsStr(boolean bool) {
- return bool ? Boolean.TRUE.toString() : Boolean.FALSE.toString();
- }
+ static protected String booleanAsStr(boolean bool) {
+ return bool ? Boolean.TRUE.toString() : Boolean.FALSE.toString();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java
index b90be5b..cb83088 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,108 +28,112 @@ import ch.qos.logback.core.status.WarnStatus;
* @author Ceki Gülcü
* @author Ralph Goers
*/
-abstract public class UnsynchronizedAppenderBase<E> extends ContextAwareBase implements Appender<E> {
+abstract public class UnsynchronizedAppenderBase<E> extends ContextAwareBase implements
+ Appender<E> {
- protected boolean started = false;
+ protected boolean started = false;
- // using a ThreadLocal instead of a boolean add 75 nanoseconds per
- // doAppend invocation. This is tolerable as doAppend takes at least a few microseconds
- // on a real appender
- /**
- * The guard prevents an appender from repeatedly calling its own doAppend
- * method.
- */
- private ThreadLocal<Boolean> guard = new ThreadLocal<Boolean>();
+ // using a ThreadLocal instead of a boolean add 75 nanoseconds per
+ // doAppend invocation. This is tolerable as doAppend takes at least a few microseconds
+ // on a real appender
+ /**
+ * The guard prevents an appender from repeatedly calling its own doAppend
+ * method.
+ */
+ private ThreadLocal<Boolean> guard = new ThreadLocal<Boolean>();
- /**
- * Appenders are named.
- */
- protected String name;
- private FilterAttachableImpl<E> fai = new FilterAttachableImpl<E>();
+ /**
+ * Appenders are named.
+ */
+ protected String name;
- public String getName() {
- return name;
- }
+ private FilterAttachableImpl<E> fai = new FilterAttachableImpl<E>();
- private int statusRepeatCount = 0;
- private int exceptionCount = 0;
+ public String getName() {
+ return name;
+ }
- static final int ALLOWED_REPEATS = 3;
+ private int statusRepeatCount = 0;
+ private int exceptionCount = 0;
- public void doAppend(E eventObject) {
- // WARNING: The guard check MUST be the first statement in the
- // doAppend() method.
+ static final int ALLOWED_REPEATS = 3;
- // prevent re-entry.
- if (Boolean.TRUE.equals(guard.get())) {
- return;
- }
+ public void doAppend(E eventObject) {
+ // WARNING: The guard check MUST be the first statement in the
+ // doAppend() method.
+
+ // prevent re-entry.
+ if (Boolean.TRUE.equals(guard.get())) {
+ return;
+ }
+
+ try {
+ guard.set(Boolean.TRUE);
- try {
- guard.set(Boolean.TRUE);
-
- if (!this.started) {
- if (statusRepeatCount++ < ALLOWED_REPEATS) {
- addStatus(new WarnStatus("Attempted to append to non started appender [" + name + "].", this));
- }
- return;
- }
-
- if (getFilterChainDecision(eventObject) == FilterReply.DENY) {
- return;
- }
-
- // ok, we now invoke derived class' implementation of append
- this.append(eventObject);
-
- } catch (Exception e) {
- if (exceptionCount++ < ALLOWED_REPEATS) {
- addError("Appender [" + name + "] failed to append.", e);
- }
- } finally {
- guard.set(Boolean.FALSE);
+ if (!this.started) {
+ if (statusRepeatCount++ < ALLOWED_REPEATS) {
+ addStatus(new WarnStatus(
+ "Attempted to append to non started appender [" + name + "].",
+ this));
}
+ return;
+ }
+
+ if (getFilterChainDecision(eventObject) == FilterReply.DENY) {
+ return;
+ }
+
+ // ok, we now invoke derived class' implementation of append
+ this.append(eventObject);
+
+ } catch (Exception e) {
+ if (exceptionCount++ < ALLOWED_REPEATS) {
+ addError("Appender [" + name + "] failed to append.", e);
+ }
+ } finally {
+ guard.set(Boolean.FALSE);
}
+ }
- abstract protected void append(E eventObject);
+ abstract protected void append(E eventObject);
- /**
- * Set the name of this appender.
- */
- public void setName(String name) {
- this.name = name;
- }
+ /**
+ * Set the name of this appender.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
- public void start() {
- started = true;
- }
+ public void start() {
+ started = true;
+ }
- public void stop() {
- started = false;
- }
+ public void stop() {
+ started = false;
+ }
- public boolean isStarted() {
- return started;
- }
+ public boolean isStarted() {
+ return started;
+ }
- public String toString() {
- return this.getClass().getName() + "[" + name + "]";
- }
+ public String toString() {
+ return this.getClass().getName() + "[" + name + "]";
+ }
- public void addFilter(Filter<E> newFilter) {
- fai.addFilter(newFilter);
- }
+ public void addFilter(Filter<E> newFilter) {
+ fai.addFilter(newFilter);
+ }
- public void clearAllFilters() {
- fai.clearAllFilters();
- }
+ public void clearAllFilters() {
+ fai.clearAllFilters();
+ }
- public List<Filter<E>> getCopyOfAttachedFiltersList() {
- return fai.getCopyOfAttachedFiltersList();
- }
+ public List<Filter<E>> getCopyOfAttachedFiltersList() {
+ return fai.getCopyOfAttachedFiltersList();
+ }
- public FilterReply getFilterChainDecision(E event) {
- return fai.getFilterChainDecision(event);
- }
+ public FilterReply getFilterChainDecision(E event) {
+ return fai.getFilterChainDecision(event);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/boolex/EvaluationException.java b/logback-core/src/main/java/ch/qos/logback/core/boolex/EvaluationException.java
index ab90dd5..541e46c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/boolex/EvaluationException.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/boolex/EvaluationException.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,18 +20,18 @@ package ch.qos.logback.core.boolex;
*/
public class EvaluationException extends Exception {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 1L;
- public EvaluationException(String msg) {
- super(msg);
- }
+ public EvaluationException(String msg) {
+ super(msg);
+ }
- public EvaluationException(String msg, Throwable cause) {
- super(msg, cause);
- }
+ public EvaluationException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
- public EvaluationException(Throwable cause) {
- super(cause);
- }
+ public EvaluationException(Throwable cause) {
+ super(cause);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/boolex/EventEvaluator.java b/logback-core/src/main/java/ch/qos/logback/core/boolex/EventEvaluator.java
index ca3cb73..b2c3e66 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/boolex/EventEvaluator.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/boolex/EventEvaluator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,33 +28,33 @@ import ch.qos.logback.core.spi.LifeCycle;
public interface EventEvaluator<E> extends ContextAware, LifeCycle {
- /**
- * Evaluates whether the event passed as parameter matches some user-specified
- * criteria.
- *
- * <p>
- * The <code>Evaluator</code> is free to evaluate the event as it pleases. In
- * particular, the evaluation results <em>may</em> depend on previous events.
- *
- * @param event
- * The event to evaluate
- * @return true if there is a match, false otherwise.
- * @throws NullPointerException
- * can be thrown in presence of null values
- * @throws EvaluationException
- * may be thrown during faulty evaluation
- */
- boolean evaluate(E event) throws NullPointerException, EvaluationException;
+ /**
+ * Evaluates whether the event passed as parameter matches some user-specified
+ * criteria.
+ *
+ * <p>
+ * The <code>Evaluator</code> is free to evaluate the event as it pleases. In
+ * particular, the evaluation results <em>may</em> depend on previous events.
+ *
+ * @param event
+ * The event to evaluate
+ * @return true if there is a match, false otherwise.
+ * @throws NullPointerException
+ * can be thrown in presence of null values
+ * @throws EvaluationException
+ * may be thrown during faulty evaluation
+ */
+ boolean evaluate(E event) throws NullPointerException, EvaluationException;
- /**
- * Evaluators are named entities.
- *
- * @return The name of this evaluator.
- */
- String getName();
+ /**
+ * Evaluators are named entities.
+ *
+ * @return The name of this evaluator.
+ */
+ String getName();
- /**
- * Evaluators are named entities.
- */
- void setName(String name);
+ /**
+ * Evaluators are named entities.
+ */
+ void setName(String name);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/boolex/EventEvaluatorBase.java b/logback-core/src/main/java/ch/qos/logback/core/boolex/EventEvaluatorBase.java
index 12e1d2e..2d0c548 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/boolex/EventEvaluatorBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/boolex/EventEvaluatorBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,32 +15,33 @@ package ch.qos.logback.core.boolex;
import ch.qos.logback.core.spi.ContextAwareBase;
-abstract public class EventEvaluatorBase<E> extends ContextAwareBase implements EventEvaluator<E> {
+abstract public class EventEvaluatorBase<E> extends ContextAwareBase implements
+ EventEvaluator<E> {
- String name;
- boolean started;
+ String name;
+ boolean started;
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- if (this.name != null) {
- throw new IllegalStateException("name has been already set");
- }
- this.name = name;
- }
-
- public boolean isStarted() {
- return started;
- }
-
- public void start() {
- started = true;
- }
+ public String getName() {
+ return name;
+ }
- public void stop() {
- started = false;
+ public void setName(String name) {
+ if (this.name != null) {
+ throw new IllegalStateException("name has been already set");
}
+ this.name = name;
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public void start() {
+ started = true;
+ }
+
+ public void stop() {
+ started = false;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/boolex/JaninoEventEvaluatorBase.java b/logback-core/src/main/java/ch/qos/logback/core/boolex/JaninoEventEvaluatorBase.java
index 55629bf..dcb68f3 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/boolex/JaninoEventEvaluatorBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/boolex/JaninoEventEvaluatorBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,69 +27,73 @@ import org.codehaus.janino.ScriptEvaluator;
*/
abstract public class JaninoEventEvaluatorBase<E> extends EventEvaluatorBase<E> {
- static Class<?> EXPRESSION_TYPE = boolean.class;
- static Class<?>[] THROWN_EXCEPTIONS = new Class[1];
+ static Class<?> EXPRESSION_TYPE = boolean.class;
+ static Class<?>[] THROWN_EXCEPTIONS = new Class[1];
- static public final int ERROR_THRESHOLD = 4;
- static {
- THROWN_EXCEPTIONS[0] = EvaluationException.class;
- }
+ static public final int ERROR_THRESHOLD = 4;
+ static {
+ THROWN_EXCEPTIONS[0] = EvaluationException.class;
+ }
- private String expression;
+ private String expression;
- ScriptEvaluator scriptEvaluator;
- private int errorCount = 0;
+ ScriptEvaluator scriptEvaluator;
+ private int errorCount = 0;
- abstract protected String getDecoratedExpression();
+ abstract protected String getDecoratedExpression();
- abstract protected String[] getParameterNames();
+ abstract protected String[] getParameterNames();
- abstract protected Class<?>[] getParameterTypes();
+ abstract protected Class<?>[] getParameterTypes();
- abstract protected Object[] getParameterValues(E event);
+ abstract protected Object[] getParameterValues(E event);
- protected List<Matcher> matcherList = new ArrayList<Matcher>();
+ protected List<Matcher> matcherList = new ArrayList<Matcher>();
- @Override
- public void start() {
- try {
- assert context != null;
- scriptEvaluator = new ScriptEvaluator(getDecoratedExpression(), EXPRESSION_TYPE, getParameterNames(), getParameterTypes(), THROWN_EXCEPTIONS);
- super.start();
- } catch (Exception e) {
- addError("Could not start evaluator with expression [" + expression + "]", e);
- }
+ @Override
+ public void start() {
+ try {
+ assert context != null;
+ scriptEvaluator = new ScriptEvaluator(getDecoratedExpression(), EXPRESSION_TYPE,
+ getParameterNames(), getParameterTypes(), THROWN_EXCEPTIONS);
+ super.start();
+ } catch (Exception e) {
+ addError(
+ "Could not start evaluator with expression [" + expression + "]", e);
}
+ }
- public boolean evaluate(E event) throws EvaluationException {
- if (!isStarted()) {
- throw new IllegalStateException("Evaluator [" + name + "] was called in stopped state");
- }
- try {
- Boolean result = (Boolean) scriptEvaluator.evaluate(getParameterValues(event));
- return result.booleanValue();
- } catch (Exception ex) {
- errorCount++;
- if (errorCount >= ERROR_THRESHOLD) {
- stop();
- }
- throw new EvaluationException("Evaluator [" + name + "] caused an exception", ex);
- }
+ public boolean evaluate(E event) throws EvaluationException {
+ if (!isStarted()) {
+ throw new IllegalStateException("Evaluator [" + name
+ + "] was called in stopped state");
}
-
- public String getExpression() {
- return expression;
+ try {
+ Boolean result = (Boolean) scriptEvaluator.evaluate(getParameterValues(event));
+ return result.booleanValue();
+ } catch (Exception ex) {
+ errorCount++;
+ if (errorCount >= ERROR_THRESHOLD) {
+ stop();
+ }
+ throw new EvaluationException("Evaluator [" + name
+ + "] caused an exception", ex);
}
+ }
- public void setExpression(String expression) {
- this.expression = expression;
- }
+ public String getExpression() {
+ return expression;
+ }
- public void addMatcher(Matcher matcher) {
- matcherList.add(matcher);
- }
+ public void setExpression(String expression) {
+ this.expression = expression;
+ }
- public List<Matcher> getMatcherList() {
- return matcherList;
- }
+ public void addMatcher(Matcher matcher) {
+ matcherList.add(matcher);
+ }
+
+ public List<Matcher> getMatcherList() {
+ return matcherList;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/boolex/Matcher.java b/logback-core/src/main/java/ch/qos/logback/core/boolex/Matcher.java
index ddea9a8..59a83a5 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/boolex/Matcher.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/boolex/Matcher.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,105 +21,105 @@ import ch.qos.logback.core.spi.LifeCycle;
public class Matcher extends ContextAwareBase implements LifeCycle {
- private String regex;
- private String name;
- private boolean caseSensitive = true;
- private boolean canonEq = false;
- private boolean unicodeCase = false;
+ private String regex;
+ private String name;
+ private boolean caseSensitive = true;
+ private boolean canonEq = false;
+ private boolean unicodeCase = false;
- private boolean start = false;
- private Pattern pattern;
+ private boolean start = false;
+ private Pattern pattern;
- public String getRegex() {
- return regex;
- }
+ public String getRegex() {
+ return regex;
+ }
- public void setRegex(String regex) {
- this.regex = regex;
- }
+ public void setRegex(String regex) {
+ this.regex = regex;
+ }
- public void start() {
- if (name == null) {
- addError("All Matcher objects must be named");
- return;
- }
- try {
- int code = 0;
- if (!caseSensitive) {
- code |= Pattern.CASE_INSENSITIVE;
- }
- if (canonEq) {
- code |= Pattern.CANON_EQ;
- }
- if (unicodeCase) {
- code |= Pattern.UNICODE_CASE;
- }
-
- // code |= Pattern.DOTALL;
-
- pattern = Pattern.compile(regex, code);
- start = true;
- } catch (PatternSyntaxException pse) {
- addError("Failed to compile regex [" + regex + "]", pse);
- }
+ public void start() {
+ if(name == null) {
+ addError("All Matcher objects must be named");
+ return;
}
-
- public void stop() {
- start = false;
+ try {
+ int code = 0;
+ if(!caseSensitive) {
+ code |= Pattern.CASE_INSENSITIVE;
+ }
+ if(canonEq) {
+ code |= Pattern.CANON_EQ;
+ }
+ if(unicodeCase) {
+ code |= Pattern.UNICODE_CASE;
+ }
+
+ //code |= Pattern.DOTALL;
+
+ pattern = Pattern.compile(regex, code);
+ start = true;
+ } catch (PatternSyntaxException pse) {
+ addError("Failed to compile regex [" + regex + "]", pse);
}
-
- public boolean isStarted() {
- return start;
+ }
+
+ public void stop() {
+ start = false;
+ }
+
+ public boolean isStarted() {
+ return start;
+ }
+
+ //However, this method does
+ //not require that the entire region (of the input) be matched.
+
+ /**
+ * Checks whether the input matches the regular expression.
+ *
+ * @param input
+ * @return
+ * @throws EvaluationException
+ */
+ public boolean matches(String input) throws EvaluationException {
+ if(start) {
+ java.util.regex.Matcher matcher = pattern.matcher(input);
+ return matcher.find();
+ } else {
+ throw new EvaluationException("Matcher ["+regex+"] not started");
}
+ }
- // However, this method does
- // not require that the entire region (of the input) be matched.
-
- /**
- * Checks whether the input matches the regular expression.
- *
- * @param input
- * @return
- * @throws EvaluationException
- */
- public boolean matches(String input) throws EvaluationException {
- if (start) {
- java.util.regex.Matcher matcher = pattern.matcher(input);
- return matcher.find();
- } else {
- throw new EvaluationException("Matcher [" + regex + "] not started");
- }
- }
-
- public boolean isCanonEq() {
- return canonEq;
- }
+ public boolean isCanonEq() {
+ return canonEq;
+ }
- public void setCanonEq(boolean canonEq) {
- this.canonEq = canonEq;
- }
+ public void setCanonEq(boolean canonEq) {
+ this.canonEq = canonEq;
+ }
- public boolean isCaseSensitive() {
- return caseSensitive;
- }
+ public boolean isCaseSensitive() {
+ return caseSensitive;
+ }
- public void setCaseSensitive(boolean caseSensitive) {
- this.caseSensitive = caseSensitive;
- }
+ public void setCaseSensitive(boolean caseSensitive) {
+ this.caseSensitive = caseSensitive;
+ }
- public boolean isUnicodeCase() {
- return unicodeCase;
- }
+ public boolean isUnicodeCase() {
+ return unicodeCase;
+ }
- public void setUnicodeCase(boolean unicodeCase) {
- this.unicodeCase = unicodeCase;
- }
+ public void setUnicodeCase(boolean unicodeCase) {
+ this.unicodeCase = unicodeCase;
+ }
- public String getName() {
- return name;
- }
+ public String getName() {
+ return name;
+ }
- public void setName(String name) {
- this.name = name;
- }
+ public void setName(String name) {
+ this.name = name;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/BindDataSourceToJNDIAction.java b/logback-core/src/main/java/ch/qos/logback/core/db/BindDataSourceToJNDIAction.java
index f5b7eac..3712e9a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/BindDataSourceToJNDIAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/BindDataSourceToJNDIAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.db;
+
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
@@ -22,70 +23,67 @@ import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.joran.util.PropertySetter;
-import ch.qos.logback.core.joran.util.beans.BeanDescriptionCache;
import ch.qos.logback.core.util.OptionHelper;
/**
- *
+ *
* @author Ceki Gulcu
*
*/
public class BindDataSourceToJNDIAction extends Action {
-
- static final String DATA_SOURCE_CLASS = "dataSourceClass";
- static final String URL = "url";
- static final String USER = "user";
- static final String PASSWORD = "password";
- private final BeanDescriptionCache beanDescriptionCache;
-
- public BindDataSourceToJNDIAction(BeanDescriptionCache beanDescriptionCache) {
- this.beanDescriptionCache = beanDescriptionCache;
- }
-
- /**
- * Instantiates an a data source and bind it to JNDI
- * Most of the required parameters are placed in the ec.substitutionProperties
- */
- public void begin(InterpretationContext ec, String localName, Attributes attributes) {
- String dsClassName = ec.getProperty(DATA_SOURCE_CLASS);
-
- if (OptionHelper.isEmpty(dsClassName)) {
- addWarn("dsClassName is a required parameter");
- ec.addError("dsClassName is a required parameter");
-
- return;
- }
-
- String urlStr = ec.getProperty(URL);
- String userStr = ec.getProperty(USER);
- String passwordStr = ec.getProperty(PASSWORD);
-
- try {
- DataSource ds = (DataSource) OptionHelper.instantiateByClassName(dsClassName, DataSource.class, context);
-
- PropertySetter setter = new PropertySetter(beanDescriptionCache,ds);
- setter.setContext(context);
-
- if (!OptionHelper.isEmpty(urlStr)) {
- setter.setProperty("url", urlStr);
- }
-
- if (!OptionHelper.isEmpty(userStr)) {
- setter.setProperty("user", userStr);
- }
-
- if (!OptionHelper.isEmpty(passwordStr)) {
- setter.setProperty("password", passwordStr);
- }
-
- Context ctx = new InitialContext();
- ctx.rebind("dataSource", ds);
- } catch (Exception oops) {
- addError("Could not bind datasource. Reported error follows.", oops);
- ec.addError("Could not not bind datasource of type [" + dsClassName + "].");
- }
+
+ static final String DATA_SOURCE_CLASS = "dataSourceClass";
+ static final String URL = "url";
+ static final String USER = "user";
+ static final String PASSWORD = "password";
+
+ /**
+ * Instantiates an a data source and bind it to JNDI
+ * Most of the required parameters are placed in the ec.substitutionProperties
+ */
+ public void begin(
+ InterpretationContext ec, String localName, Attributes attributes) {
+ String dsClassName = ec.getProperty(DATA_SOURCE_CLASS);
+
+ if (OptionHelper.isEmpty(dsClassName)) {
+ addWarn("dsClassName is a required parameter");
+ ec.addError("dsClassName is a required parameter");
+
+ return;
}
- public void end(InterpretationContext ec, String name) {
+ String urlStr = ec.getProperty(URL);
+ String userStr = ec.getProperty(USER);
+ String passwordStr = ec.getProperty(PASSWORD);
+
+ try {
+ DataSource ds =
+ (DataSource) OptionHelper.instantiateByClassName(dsClassName, DataSource.class, context);
+
+ PropertySetter setter = new PropertySetter(ds);
+ setter.setContext(context);
+
+ if (!OptionHelper.isEmpty(urlStr)) {
+ setter.setProperty("url", urlStr);
+ }
+
+ if (!OptionHelper.isEmpty(userStr)) {
+ setter.setProperty("user", userStr);
+ }
+
+ if (!OptionHelper.isEmpty(passwordStr)) {
+ setter.setProperty("password", passwordStr);
+ }
+
+ Context ctx = new InitialContext();
+ ctx.rebind("dataSource", ds);
+ } catch (Exception oops) {
+ addError(
+ "Could not bind datasource. Reported error follows.", oops);
+ ec.addError("Could not not bind datasource of type [" + dsClassName + "].");
}
+ }
+
+ public void end(InterpretationContext ec, String name) {
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSource.java b/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSource.java
index 4e27cc6..0bfa5e5 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSource.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSource.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -12,13 +12,13 @@
* as published by the Free Software Foundation.
*/
package ch.qos.logback.core.db;
-
import java.sql.Connection;
import java.sql.SQLException;
import ch.qos.logback.core.db.dialect.SQLDialectCode;
import ch.qos.logback.core.spi.LifeCycle;
+
/**
* The <id>ConnectionSource</id> interface provides a pluggable means of
* transparently obtaining JDBC {@link java.sql.Connection}s for logback classes
@@ -31,31 +31,31 @@ import ch.qos.logback.core.spi.LifeCycle;
*/
public interface ConnectionSource extends LifeCycle {
- /**
- * Obtain a {@link java.sql.Connection} for use. The client is
- * responsible for closing the {@link java.sql.Connection} when it is no
- * longer required.
- *
- * @throws SQLException if a {@link java.sql.Connection} could not be
- * obtained
- */
- Connection getConnection() throws SQLException;
-
- /**
- * Get the SQL dialect that should be used for this connection. Note that the
- * dialect is not needed if the JDBC driver supports the getGeneratedKeys
- * method.
- */
- SQLDialectCode getSQLDialectCode();
-
- /**
- * If the connection supports the JDBC 3.0 getGeneratedKeys method, then
- * we do not need any specific dialect support.
- */
- boolean supportsGetGeneratedKeys();
+ /**
+ * Obtain a {@link java.sql.Connection} for use. The client is
+ * responsible for closing the {@link java.sql.Connection} when it is no
+ * longer required.
+ *
+ * @throws SQLException if a {@link java.sql.Connection} could not be
+ * obtained
+ */
+ Connection getConnection() throws SQLException;
- /**
- * If the connection does not support batch updates, we will avoid using them.
- */
- boolean supportsBatchUpdates();
+ /**
+ * Get the SQL dialect that should be used for this connection. Note that the
+ * dialect is not needed if the JDBC driver supports the getGeneratedKeys
+ * method.
+ */
+ SQLDialectCode getSQLDialectCode();
+
+ /**
+ * If the connection supports the JDBC 3.0 getGeneratedKeys method, then
+ * we do not need any specific dialect support.
+ */
+ boolean supportsGetGeneratedKeys();
+
+ /**
+ * If the connection does not support batch updates, we will avoid using them.
+ */
+ boolean supportsBatchUpdates();
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSourceBase.java b/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSourceBase.java
index 021806b..8534746 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSourceBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/ConnectionSourceBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,108 +21,111 @@ import ch.qos.logback.core.db.dialect.DBUtil;
import ch.qos.logback.core.db.dialect.SQLDialectCode;
import ch.qos.logback.core.spi.ContextAwareBase;
+
/**
* @author Ceki Gülcü
*/
public abstract class ConnectionSourceBase extends ContextAwareBase implements ConnectionSource {
-
- private boolean started;
-
- private String user = null;
- private String password = null;
-
- // initially we have an unknown dialect
- private SQLDialectCode dialectCode = SQLDialectCode.UNKNOWN_DIALECT;
- private boolean supportsGetGeneratedKeys = false;
- private boolean supportsBatchUpdates = false;
-
- /**
- * Learn relevant information about this connection source.
- *
- */
- public void discoverConnectionProperties() {
- Connection connection = null;
- try {
- connection = getConnection();
- if (connection == null) {
- addWarn("Could not get a connection");
- return;
- }
- DatabaseMetaData meta = connection.getMetaData();
- DBUtil util = new DBUtil();
- util.setContext(getContext());
- supportsGetGeneratedKeys = util.supportsGetGeneratedKeys(meta);
- supportsBatchUpdates = util.supportsBatchUpdates(meta);
- dialectCode = DBUtil.discoverSQLDialect(meta);
- addInfo("Driver name=" + meta.getDriverName());
- addInfo("Driver version=" + meta.getDriverVersion());
- addInfo("supportsGetGeneratedKeys=" + supportsGetGeneratedKeys);
-
- } catch (SQLException se) {
- addWarn("Could not discover the dialect to use.", se);
- } finally {
- DBHelper.closeConnection(connection);
- }
- }
-
- /**
- * Does this connection support the JDBC Connection.getGeneratedKeys method?
- */
- public final boolean supportsGetGeneratedKeys() {
- return supportsGetGeneratedKeys;
- }
-
- public final SQLDialectCode getSQLDialectCode() {
- return dialectCode;
- }
-
- /**
- * Get the password for this connection source.
- */
- public final String getPassword() {
- return password;
- }
-
- /**
- * Sets the password.
- * @param password The password to set
- */
- public final void setPassword(final String password) {
- this.password = password;
- }
-
- /**
- * Get the user for this connection source.
- */
- public final String getUser() {
- return user;
+
+ private boolean started;
+
+ private String user = null;
+ private String password = null;
+
+ // initially we have an unknown dialect
+ private SQLDialectCode dialectCode = SQLDialectCode.UNKNOWN_DIALECT;
+ private boolean supportsGetGeneratedKeys = false;
+ private boolean supportsBatchUpdates = false;
+
+
+ /**
+ * Learn relevant information about this connection source.
+ *
+ */
+ public void discoverConnectionProperties() {
+ Connection connection = null;
+ try {
+ connection = getConnection();
+ if (connection == null) {
+ addWarn("Could not get a connection");
+ return;
+ }
+ DatabaseMetaData meta = connection.getMetaData();
+ DBUtil util = new DBUtil();
+ util.setContext(getContext());
+ supportsGetGeneratedKeys = util.supportsGetGeneratedKeys(meta);
+ supportsBatchUpdates = util.supportsBatchUpdates(meta);
+ dialectCode = DBUtil.discoverSQLDialect(meta);
+ addInfo("Driver name="+meta.getDriverName());
+ addInfo("Driver version="+meta.getDriverVersion());
+ addInfo("supportsGetGeneratedKeys="+supportsGetGeneratedKeys);
+
+ } catch (SQLException se) {
+ addWarn("Could not discover the dialect to use.", se);
+ } finally {
+ DBHelper.closeConnection(connection);
}
-
- /**
- * Sets the username.
- * @param username The username to set
- */
- public final void setUser(final String username) {
- this.user = username;
- }
-
- /**
- * Does this connection support batch updates?
- */
- public final boolean supportsBatchUpdates() {
- return supportsBatchUpdates;
- }
-
- public boolean isStarted() {
- return started;
- }
-
- public void start() {
- started = true;
- }
-
- public void stop() {
- started = false;
- }
-
+ }
+
+ /**
+ * Does this connection support the JDBC Connection.getGeneratedKeys method?
+ */
+ public final boolean supportsGetGeneratedKeys() {
+ return supportsGetGeneratedKeys;
+ }
+
+ public final SQLDialectCode getSQLDialectCode() {
+ return dialectCode;
+ }
+
+ /**
+ * Get the password for this connection source.
+ */
+ public final String getPassword() {
+ return password;
+ }
+
+ /**
+ * Sets the password.
+ * @param password The password to set
+ */
+ public final void setPassword(final String password) {
+ this.password = password;
+ }
+
+ /**
+ * Get the user for this connection source.
+ */
+ public final String getUser() {
+ return user;
+ }
+
+ /**
+ * Sets the username.
+ * @param username The username to set
+ */
+ public final void setUser(final String username) {
+ this.user = username;
+ }
+
+ /**
+ * Does this connection support batch updates?
+ */
+ public final boolean supportsBatchUpdates() {
+ return supportsBatchUpdates;
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public void start() {
+ started = true;
+ }
+
+ public void stop() {
+ started = false;
+ }
+
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/DBAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/db/DBAppenderBase.java
index 51dd586..c849af4 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/DBAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/DBAppenderBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -33,138 +33,147 @@ import ch.qos.logback.core.db.dialect.SQLDialectCode;
*/
public abstract class DBAppenderBase<E> extends UnsynchronizedAppenderBase<E> {
- protected ConnectionSource connectionSource;
- protected boolean cnxSupportsGetGeneratedKeys = false;
- protected boolean cnxSupportsBatchUpdates = false;
- protected SQLDialect sqlDialect;
+ protected ConnectionSource connectionSource;
+ protected boolean cnxSupportsGetGeneratedKeys = false;
+ protected boolean cnxSupportsBatchUpdates = false;
+ protected SQLDialect sqlDialect;
- protected abstract Method getGeneratedKeysMethod();
+ protected abstract Method getGeneratedKeysMethod();
- protected abstract String getInsertSQL();
+ protected abstract String getInsertSQL();
- @Override
- public void start() {
+ @Override
+ public void start() {
- if (connectionSource == null) {
- throw new IllegalStateException("DBAppender cannot function without a connection source");
- }
-
- sqlDialect = DBUtil.getDialectFromCode(connectionSource.getSQLDialectCode());
- if (getGeneratedKeysMethod() != null) {
- cnxSupportsGetGeneratedKeys = connectionSource.supportsGetGeneratedKeys();
- } else {
- cnxSupportsGetGeneratedKeys = false;
- }
- cnxSupportsBatchUpdates = connectionSource.supportsBatchUpdates();
- if (!cnxSupportsGetGeneratedKeys && (sqlDialect == null)) {
- throw new IllegalStateException(
- "DBAppender cannot function if the JDBC driver does not support getGeneratedKeys method *and* without a specific SQL dialect");
- }
-
- // all nice and dandy on the eastern front
- super.start();
+ if (connectionSource == null) {
+ throw new IllegalStateException(
+ "DBAppender cannot function without a connection source");
}
- /**
- * @return Returns the connectionSource.
- */
- public ConnectionSource getConnectionSource() {
- return connectionSource;
+ sqlDialect = DBUtil
+ .getDialectFromCode(connectionSource.getSQLDialectCode());
+ if (getGeneratedKeysMethod() != null) {
+ cnxSupportsGetGeneratedKeys = connectionSource.supportsGetGeneratedKeys();
+ } else {
+ cnxSupportsGetGeneratedKeys = false;
}
-
- /**
- * @param connectionSource
- * The connectionSource to set.
- */
- public void setConnectionSource(ConnectionSource connectionSource) {
- this.connectionSource = connectionSource;
+ cnxSupportsBatchUpdates = connectionSource.supportsBatchUpdates();
+ if (!cnxSupportsGetGeneratedKeys && (sqlDialect == null)) {
+ throw new IllegalStateException(
+ "DBAppender cannot function if the JDBC driver does not support getGeneratedKeys method *and* without a specific SQL dialect");
}
- @Override
- public void append(E eventObject) {
- Connection connection = null;
- PreparedStatement insertStatement = null;
- try {
- connection = connectionSource.getConnection();
- connection.setAutoCommit(false);
-
- if (cnxSupportsGetGeneratedKeys) {
- String EVENT_ID_COL_NAME = "EVENT_ID";
- // see
- if (connectionSource.getSQLDialectCode() == SQLDialectCode.POSTGRES_DIALECT) {
- EVENT_ID_COL_NAME = EVENT_ID_COL_NAME.toLowerCase();
- }
- insertStatement = connection.prepareStatement(getInsertSQL(), new String[] { EVENT_ID_COL_NAME });
- } else {
- insertStatement = connection.prepareStatement(getInsertSQL());
- }
-
- long eventId;
- // inserting an event and getting the result must be exclusive
- synchronized (this) {
- subAppend(eventObject, connection, insertStatement);
- eventId = selectEventId(insertStatement, connection);
- }
- secondarySubAppend(eventObject, connection, eventId);
-
- connection.commit();
- } catch (Throwable sqle) {
- addError("problem appending event", sqle);
- } finally {
- DBHelper.closeStatement(insertStatement);
- DBHelper.closeConnection(connection);
+ // all nice and dandy on the eastern front
+ super.start();
+ }
+
+ /**
+ * @return Returns the connectionSource.
+ */
+ public ConnectionSource getConnectionSource() {
+ return connectionSource;
+ }
+
+ /**
+ * @param connectionSource
+ * The connectionSource to set.
+ */
+ public void setConnectionSource(ConnectionSource connectionSource) {
+ this.connectionSource = connectionSource;
+ }
+
+ @Override
+ public void append(E eventObject) {
+ Connection connection = null;
+ PreparedStatement insertStatement = null;
+ try {
+ connection = connectionSource.getConnection();
+ connection.setAutoCommit(false);
+
+ if (cnxSupportsGetGeneratedKeys) {
+ String EVENT_ID_COL_NAME = "EVENT_ID";
+ // see
+ if (connectionSource.getSQLDialectCode() == SQLDialectCode.POSTGRES_DIALECT) {
+ EVENT_ID_COL_NAME = EVENT_ID_COL_NAME.toLowerCase();
}
+ insertStatement = connection.prepareStatement(getInsertSQL(),
+ new String[] { EVENT_ID_COL_NAME });
+ } else {
+ insertStatement = connection.prepareStatement(getInsertSQL());
+ }
+
+ long eventId;
+ // inserting an event and getting the result must be exclusive
+ synchronized (this) {
+ subAppend(eventObject, connection, insertStatement);
+ eventId = selectEventId(insertStatement, connection);
+ }
+ secondarySubAppend(eventObject, connection, eventId);
+
+ connection.commit();
+ } catch (Throwable sqle) {
+ addError("problem appending event", sqle);
+ } finally {
+ DBHelper.closeStatement(insertStatement);
+ DBHelper.closeConnection(connection);
}
+ }
- protected abstract void subAppend(E eventObject, Connection connection, PreparedStatement statement) throws Throwable;
+ protected abstract void subAppend(E eventObject, Connection connection,
+ PreparedStatement statement) throws Throwable;
- protected abstract void secondarySubAppend(E eventObject, Connection connection, long eventId) throws Throwable;
+ protected abstract void secondarySubAppend(E eventObject, Connection connection,
+ long eventId) throws Throwable;
- protected long selectEventId(PreparedStatement insertStatement, Connection connection) throws SQLException, InvocationTargetException {
- ResultSet rs = null;
- Statement idStatement = null;
+ protected long selectEventId(PreparedStatement insertStatement,
+ Connection connection) throws SQLException, InvocationTargetException {
+ ResultSet rs = null;
+ Statement idStatement = null;
+ try {
+ boolean gotGeneratedKeys = false;
+ if (cnxSupportsGetGeneratedKeys) {
try {
- boolean gotGeneratedKeys = false;
- if (cnxSupportsGetGeneratedKeys) {
- try {
- rs = (ResultSet) getGeneratedKeysMethod().invoke(insertStatement, (Object[]) null);
- gotGeneratedKeys = true;
- } catch (InvocationTargetException ex) {
- Throwable target = ex.getTargetException();
- if (target instanceof SQLException) {
- throw (SQLException) target;
- }
- throw ex;
- } catch (IllegalAccessException ex) {
- addWarn("IllegalAccessException invoking PreparedStatement.getGeneratedKeys", ex);
- }
- }
-
- if (!gotGeneratedKeys) {
- idStatement = connection.createStatement();
- idStatement.setMaxRows(1);
- String selectInsertIdStr = sqlDialect.getSelectInsertId();
- rs = idStatement.executeQuery(selectInsertIdStr);
- }
-
- // A ResultSet cursor is initially positioned before the first row;
- // the first call to the method next makes the first row the current row
- rs.next();
- long eventId = rs.getLong(1);
- return eventId;
- } finally {
- if (rs != null) {
- try {
- rs.close();
- } catch (SQLException e) {
- }
- }
- DBHelper.closeStatement(idStatement);
+ rs = (ResultSet) getGeneratedKeysMethod().invoke(insertStatement,
+ (Object[]) null);
+ gotGeneratedKeys = true;
+ } catch (InvocationTargetException ex) {
+ Throwable target = ex.getTargetException();
+ if (target instanceof SQLException) {
+ throw (SQLException) target;
+ }
+ throw ex;
+ } catch (IllegalAccessException ex) {
+ addWarn(
+ "IllegalAccessException invoking PreparedStatement.getGeneratedKeys",
+ ex);
}
+ }
+
+ if (!gotGeneratedKeys) {
+ idStatement = connection.createStatement();
+ idStatement.setMaxRows(1);
+ String selectInsertIdStr = sqlDialect.getSelectInsertId();
+ rs = idStatement.executeQuery(selectInsertIdStr);
+ }
+
+ // A ResultSet cursor is initially positioned before the first row;
+ // the first call to the method next makes the first row the current row
+ rs.next();
+ long eventId = rs.getLong(1);
+ return eventId;
+ } finally {
+ if (rs!=null) {
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ }
+ }
+ DBHelper.closeStatement(idStatement);
}
+ }
- @Override
- public void stop() {
- super.stop();
- }
+ @Override
+ public void stop() {
+ super.stop();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/DBHelper.java b/logback-core/src/main/java/ch/qos/logback/core/db/DBHelper.java
index dfec7b7..cf79925 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/DBHelper.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/DBHelper.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,23 +23,23 @@ import java.sql.Statement;
*/
public class DBHelper {
- static public void closeConnection(Connection connection) {
- if (connection != null) {
- try {
- connection.close();
- } catch (SQLException sqle) {
- // static utility classes should not log without an explicit repository
- // reference
- }
- }
+ static public void closeConnection(Connection connection) {
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (SQLException sqle) {
+ // static utility classes should not log without an explicit repository
+ // reference
+ }
}
+ }
- public static void closeStatement(Statement statement) {
- if (statement != null) {
- try {
- statement.close();
- } catch (SQLException sqle) {
- }
- }
+ public static void closeStatement(Statement statement) {
+ if (statement != null) {
+ try {
+ statement.close();
+ } catch (SQLException sqle) {
+ }
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/DataSourceConnectionSource.java b/logback-core/src/main/java/ch/qos/logback/core/db/DataSourceConnectionSource.java
index 1ef548b..bfd35ec 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/DataSourceConnectionSource.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/DataSourceConnectionSource.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -34,42 +34,43 @@ import ch.qos.logback.core.db.dialect.SQLDialectCode;
*/
public class DataSourceConnectionSource extends ConnectionSourceBase {
- private DataSource dataSource;
+ private DataSource dataSource;
- @Override
- public void start() {
- if (dataSource == null) {
- addWarn("WARNING: No data source specified");
- } else {
- discoverConnectionProperties();
- if (!supportsGetGeneratedKeys() && getSQLDialectCode() == SQLDialectCode.UNKNOWN_DIALECT) {
- addWarn("Connection does not support GetGeneratedKey method and could not discover the dialect.");
- }
- }
- super.start();
+ @Override
+ public void start() {
+ if (dataSource == null) {
+ addWarn("WARNING: No data source specified");
+ } else {
+ discoverConnectionProperties();
+ if (!supportsGetGeneratedKeys()
+ && getSQLDialectCode() == SQLDialectCode.UNKNOWN_DIALECT) {
+ addWarn("Connection does not support GetGeneratedKey method and could not discover the dialect.");
+ }
}
+ super.start();
+ }
- /**
- * @see ch.qos.logback.core.db.ConnectionSource#getConnection()
- */
- public Connection getConnection() throws SQLException {
- if (dataSource == null) {
- addError("WARNING: No data source specified");
- return null;
- }
-
- if (getUser() == null) {
- return dataSource.getConnection();
- } else {
- return dataSource.getConnection(getUser(), getPassword());
- }
+ /**
+ * @see ch.qos.logback.core.db.ConnectionSource#getConnection()
+ */
+ public Connection getConnection() throws SQLException {
+ if (dataSource == null) {
+ addError("WARNING: No data source specified");
+ return null;
}
- public DataSource getDataSource() {
- return dataSource;
+ if (getUser() == null) {
+ return dataSource.getConnection();
+ } else {
+ return dataSource.getConnection(getUser(), getPassword());
}
+ }
- public void setDataSource(DataSource dataSource) {
- this.dataSource = dataSource;
- }
+ public DataSource getDataSource() {
+ return dataSource;
+ }
+
+ public void setDataSource(DataSource dataSource) {
+ this.dataSource = dataSource;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/DriverManagerConnectionSource.java b/logback-core/src/main/java/ch/qos/logback/core/db/DriverManagerConnectionSource.java
index 71e84af..2cf8b3a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/DriverManagerConnectionSource.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/DriverManagerConnectionSource.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,68 +28,68 @@ import java.sql.SQLException;
* @author <a href="mailto:rdecampo at twcny.rr.com">Ray DeCampo</a>
*/
public class DriverManagerConnectionSource extends ConnectionSourceBase {
- private String driverClass = null;
- private String url = null;
+ private String driverClass = null;
+ private String url = null;
- public void start() {
- try {
- if (driverClass != null) {
- Class.forName(driverClass);
- discoverConnectionProperties();
- } else {
- addError("WARNING: No JDBC driver specified for logback DriverManagerConnectionSource.");
- }
- } catch (final ClassNotFoundException cnfe) {
- addError("Could not load JDBC driver class: " + driverClass, cnfe);
- }
+ public void start() {
+ try {
+ if (driverClass != null) {
+ Class.forName(driverClass);
+ discoverConnectionProperties();
+ } else {
+ addError("WARNING: No JDBC driver specified for logback DriverManagerConnectionSource.");
+ }
+ } catch (final ClassNotFoundException cnfe) {
+ addError("Could not load JDBC driver class: " + driverClass, cnfe);
}
+ }
- /**
- * @see ch.qos.logback.core.db.ConnectionSource#getConnection()
- */
- public Connection getConnection() throws SQLException {
- if (getUser() == null) {
- return DriverManager.getConnection(url);
- } else {
- return DriverManager.getConnection(url, getUser(), getPassword());
- }
+ /**
+ * @see ch.qos.logback.core.db.ConnectionSource#getConnection()
+ */
+ public Connection getConnection() throws SQLException {
+ if (getUser() == null) {
+ return DriverManager.getConnection(url);
+ } else {
+ return DriverManager.getConnection(url, getUser(), getPassword());
}
+ }
- /**
- * Returns the url.
- *
- * @return String
- */
- public String getUrl() {
- return url;
- }
+ /**
+ * Returns the url.
+ *
+ * @return String
+ */
+ public String getUrl() {
+ return url;
+ }
- /**
- * Sets the url.
- *
- * @param url
- * The url to set
- */
- public void setUrl(String url) {
- this.url = url;
- }
+ /**
+ * Sets the url.
+ *
+ * @param url
+ * The url to set
+ */
+ public void setUrl(String url) {
+ this.url = url;
+ }
- /**
- * Returns the name of the driver class.
- *
- * @return String
- */
- public String getDriverClass() {
- return driverClass;
- }
+ /**
+ * Returns the name of the driver class.
+ *
+ * @return String
+ */
+ public String getDriverClass() {
+ return driverClass;
+ }
- /**
- * Sets the driver class.
- *
- * @param driverClass
- * The driver class to set
- */
- public void setDriverClass(String driverClass) {
- this.driverClass = driverClass;
- }
+ /**
+ * Sets the driver class.
+ *
+ * @param driverClass
+ * The driver class to set
+ */
+ public void setDriverClass(String driverClass) {
+ this.driverClass = driverClass;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/JNDIConnectionSource.java b/logback-core/src/main/java/ch/qos/logback/core/db/JNDIConnectionSource.java
index b96c381..cea885d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/JNDIConnectionSource.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/JNDIConnectionSource.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -40,70 +40,74 @@ import javax.sql.DataSource;
* @author <a href="mailto:rdecampo at twcny.rr.com">Ray DeCampo</a>
*/
public class JNDIConnectionSource extends ConnectionSourceBase {
- private String jndiLocation = null;
- private DataSource dataSource = null;
+ private String jndiLocation = null;
+ private DataSource dataSource = null;
- public void start() {
- if (jndiLocation == null) {
- addError("No JNDI location specified for JNDIConnectionSource.");
- }
- discoverConnectionProperties();
+ public void start() {
+ if (jndiLocation == null) {
+ addError("No JNDI location specified for JNDIConnectionSource.");
}
+ discoverConnectionProperties();
+ }
- public Connection getConnection() throws SQLException {
- Connection conn = null;
- try {
- if (dataSource == null) {
- dataSource = lookupDataSource();
- }
- if (getUser() != null) {
- addWarn("Ignoring property [user] with value [" + getUser() + "] for obtaining a connection from a DataSource.");
- }
- conn = dataSource.getConnection();
- } catch (final NamingException ne) {
- addError("Error while getting data source", ne);
- throw new SQLException("NamingException while looking up DataSource: " + ne.getMessage());
- } catch (final ClassCastException cce) {
- addError("ClassCastException while looking up DataSource.", cce);
- throw new SQLException("ClassCastException while looking up DataSource: " + cce.getMessage());
- }
- return conn;
+ public Connection getConnection() throws SQLException {
+ Connection conn = null;
+ try {
+ if (dataSource == null) {
+ dataSource = lookupDataSource();
+ }
+ if(getUser() != null) {
+ addWarn("Ignoring property [user] with value ["+getUser()+"] for obtaining a connection from a DataSource.");
+ }
+ conn = dataSource.getConnection();
+ } catch (final NamingException ne) {
+ addError("Error while getting data source", ne);
+ throw new SQLException("NamingException while looking up DataSource: "
+ + ne.getMessage());
+ } catch (final ClassCastException cce) {
+ addError("ClassCastException while looking up DataSource.", cce);
+ throw new SQLException("ClassCastException while looking up DataSource: "
+ + cce.getMessage());
}
- /**
- * Returns the jndiLocation.
- *
- * @return String
- */
- public String getJndiLocation() {
- return jndiLocation;
- }
+ return conn;
+ }
- /**
- * Sets the jndiLocation.
- *
- * @param jndiLocation
- * The jndiLocation to set
- */
- public void setJndiLocation(String jndiLocation) {
- this.jndiLocation = jndiLocation;
- }
+ /**
+ * Returns the jndiLocation.
+ *
+ * @return String
+ */
+ public String getJndiLocation() {
+ return jndiLocation;
+ }
+
+ /**
+ * Sets the jndiLocation.
+ *
+ * @param jndiLocation
+ * The jndiLocation to set
+ */
+ public void setJndiLocation(String jndiLocation) {
+ this.jndiLocation = jndiLocation;
+ }
- private DataSource lookupDataSource() throws NamingException, SQLException {
- addInfo("Looking up [" + jndiLocation + "] in JNDI");
- DataSource ds;
- Context initialContext = new InitialContext();
- Object obj = initialContext.lookup(jndiLocation);
+ private DataSource lookupDataSource() throws NamingException, SQLException {
+ addInfo("Looking up ["+jndiLocation+"] in JNDI");
+ DataSource ds;
+ Context initialContext = new InitialContext();
+ Object obj = initialContext.lookup(jndiLocation);
- // PortableRemoteObject was introduced in JDK 1.3. We won't use it.
- // ds = (DataSource)PortableRemoteObject.narrow(obj, DataSource.class);
- ds = (DataSource) obj;
+ // PortableRemoteObject was introduced in JDK 1.3. We won't use it.
+ // ds = (DataSource)PortableRemoteObject.narrow(obj, DataSource.class);
+ ds = (DataSource) obj;
- if (ds == null) {
- throw new SQLException("Failed to obtain data source from JNDI location " + jndiLocation);
- } else {
- return ds;
- }
+ if (ds == null) {
+ throw new SQLException("Failed to obtain data source from JNDI location "
+ + jndiLocation);
+ } else {
+ return ds;
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/DBUtil.java b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/DBUtil.java
index c13fda9..dd6d6b6 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/DBUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/DBUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,116 +24,118 @@ import ch.qos.logback.core.spi.ContextAwareBase;
*
*/
public class DBUtil extends ContextAwareBase {
- private static final String POSTGRES_PART = "postgresql";
- private static final String MYSQL_PART = "mysql";
- private static final String ORACLE_PART = "oracle";
- // private static final String MSSQL_PART = "mssqlserver4";
- private static final String MSSQL_PART = "microsoft";
- private static final String HSQL_PART = "hsql";
- private static final String H2_PART = "h2";
- private static final String SYBASE_SQLANY_PART = "sql anywhere";
- private static final String SQLITE_PART = "sqlite";
-
- public static SQLDialectCode discoverSQLDialect(DatabaseMetaData meta) {
- SQLDialectCode dialectCode = SQLDialectCode.UNKNOWN_DIALECT;
-
- try {
-
- String dbName = meta.getDatabaseProductName().toLowerCase();
-
- if (dbName.indexOf(POSTGRES_PART) != -1) {
- return SQLDialectCode.POSTGRES_DIALECT;
- } else if (dbName.indexOf(MYSQL_PART) != -1) {
- return SQLDialectCode.MYSQL_DIALECT;
- } else if (dbName.indexOf(ORACLE_PART) != -1) {
- return SQLDialectCode.ORACLE_DIALECT;
- } else if (dbName.indexOf(MSSQL_PART) != -1) {
- return SQLDialectCode.MSSQL_DIALECT;
- } else if (dbName.indexOf(HSQL_PART) != -1) {
- return SQLDialectCode.HSQL_DIALECT;
- } else if (dbName.indexOf(H2_PART) != -1) {
- return SQLDialectCode.H2_DIALECT;
- } else if (dbName.indexOf(SYBASE_SQLANY_PART) != -1) {
- return SQLDialectCode.SYBASE_SQLANYWHERE_DIALECT;
- } else if (dbName.indexOf(SQLITE_PART) != -1) {
- return SQLDialectCode.SQLITE_DIALECT;
- } else {
- return SQLDialectCode.UNKNOWN_DIALECT;
- }
- } catch (SQLException sqle) {
- // we can't do much here
- }
-
- return dialectCode;
+ private static final String POSTGRES_PART = "postgresql";
+ private static final String MYSQL_PART = "mysql";
+ private static final String ORACLE_PART = "oracle";
+ // private static final String MSSQL_PART = "mssqlserver4";
+ private static final String MSSQL_PART = "microsoft";
+ private static final String HSQL_PART = "hsql";
+ private static final String H2_PART = "h2";
+ private static final String SYBASE_SQLANY_PART = "sql anywhere";
+ private static final String SQLITE_PART = "sqlite";
+
+ public static SQLDialectCode discoverSQLDialect(DatabaseMetaData meta) {
+ SQLDialectCode dialectCode = SQLDialectCode.UNKNOWN_DIALECT;
+
+ try {
+
+ String dbName = meta.getDatabaseProductName().toLowerCase();
+
+ if (dbName.indexOf(POSTGRES_PART) != -1) {
+ return SQLDialectCode.POSTGRES_DIALECT;
+ } else if (dbName.indexOf(MYSQL_PART) != -1) {
+ return SQLDialectCode.MYSQL_DIALECT;
+ } else if (dbName.indexOf(ORACLE_PART) != -1) {
+ return SQLDialectCode.ORACLE_DIALECT;
+ } else if (dbName.indexOf(MSSQL_PART) != -1) {
+ return SQLDialectCode.MSSQL_DIALECT;
+ } else if (dbName.indexOf(HSQL_PART) != -1) {
+ return SQLDialectCode.HSQL_DIALECT;
+ } else if (dbName.indexOf(H2_PART) != -1) {
+ return SQLDialectCode.H2_DIALECT;
+ } else if (dbName.indexOf(SYBASE_SQLANY_PART) != -1) {
+ return SQLDialectCode.SYBASE_SQLANYWHERE_DIALECT;
+ } else if (dbName.indexOf(SQLITE_PART) != -1) {
+ return SQLDialectCode.SQLITE_DIALECT;
+ } else {
+ return SQLDialectCode.UNKNOWN_DIALECT;
+ }
+ } catch (SQLException sqle) {
+ // we can't do much here
}
- public static SQLDialect getDialectFromCode(SQLDialectCode sqlDialectType) {
- SQLDialect sqlDialect = null;
-
- switch (sqlDialectType) {
- case POSTGRES_DIALECT:
- sqlDialect = new PostgreSQLDialect();
- break;
-
- case MYSQL_DIALECT:
- sqlDialect = new MySQLDialect();
- break;
-
- case ORACLE_DIALECT:
- sqlDialect = new OracleDialect();
- break;
-
- case MSSQL_DIALECT:
- sqlDialect = new MsSQLDialect();
- break;
-
- case HSQL_DIALECT:
- sqlDialect = new HSQLDBDialect();
- break;
-
- case H2_DIALECT:
- sqlDialect = new H2Dialect();
- break;
-
- case SYBASE_SQLANYWHERE_DIALECT:
- sqlDialect = new SybaseSqlAnywhereDialect();
- break;
-
- case SQLITE_DIALECT:
- sqlDialect = new SQLiteDialect();
- break;
- }
- return sqlDialect;
+ return dialectCode;
+ }
+
+ public static SQLDialect getDialectFromCode(SQLDialectCode sqlDialectType) {
+ SQLDialect sqlDialect = null;
+
+ switch (sqlDialectType) {
+ case POSTGRES_DIALECT:
+ sqlDialect = new PostgreSQLDialect();
+ break;
+
+ case MYSQL_DIALECT:
+ sqlDialect = new MySQLDialect();
+ break;
+
+ case ORACLE_DIALECT:
+ sqlDialect = new OracleDialect();
+ break;
+
+ case MSSQL_DIALECT:
+ sqlDialect = new MsSQLDialect();
+ break;
+
+ case HSQL_DIALECT:
+ sqlDialect = new HSQLDBDialect();
+ break;
+
+ case H2_DIALECT:
+ sqlDialect = new H2Dialect();
+ break;
+
+ case SYBASE_SQLANYWHERE_DIALECT:
+ sqlDialect = new SybaseSqlAnywhereDialect();
+ break;
+
+ case SQLITE_DIALECT:
+ sqlDialect = new SQLiteDialect();
+ break;
}
-
- /**
- * This method handles cases where the
- * {@link DatabaseMetaData#supportsGetGeneratedKeys} method is missing in the
- * JDBC driver implementation.
- */
- public boolean supportsGetGeneratedKeys(DatabaseMetaData meta) {
- try {
- //
- // invoking JDBC 1.4 method by reflection
- //
- return ((Boolean) DatabaseMetaData.class.getMethod("supportsGetGeneratedKeys", (Class[]) null).invoke(meta, (Object[]) null)).booleanValue();
- } catch (Throwable e) {
- addInfo("Could not call supportsGetGeneratedKeys method. This may be recoverable");
- return false;
- }
+ return sqlDialect;
+ }
+
+ /**
+ * This method handles cases where the
+ * {@link DatabaseMetaData#supportsGetGeneratedKeys} method is missing in the
+ * JDBC driver implementation.
+ */
+ public boolean supportsGetGeneratedKeys(DatabaseMetaData meta) {
+ try {
+ //
+ // invoking JDBC 1.4 method by reflection
+ //
+ return ((Boolean) DatabaseMetaData.class.getMethod(
+ "supportsGetGeneratedKeys", (Class[]) null).invoke(meta,
+ (Object[]) null)).booleanValue();
+ } catch (Throwable e) {
+ addInfo("Could not call supportsGetGeneratedKeys method. This may be recoverable");
+ return false;
}
-
- /**
- * This method handles cases where the
- * {@link DatabaseMetaData#supportsBatchUpdates} method is missing in the JDBC
- * driver implementation.
- */
- public boolean supportsBatchUpdates(DatabaseMetaData meta) {
- try {
- return meta.supportsBatchUpdates();
- } catch (Throwable e) {
- addInfo("Missing DatabaseMetaData.supportsBatchUpdates method.");
- return false;
- }
+ }
+
+ /**
+ * This method handles cases where the
+ * {@link DatabaseMetaData#supportsBatchUpdates} method is missing in the JDBC
+ * driver implementation.
+ */
+ public boolean supportsBatchUpdates(DatabaseMetaData meta) {
+ try {
+ return meta.supportsBatchUpdates();
+ } catch (Throwable e) {
+ addInfo("Missing DatabaseMetaData.supportsBatchUpdates method.");
+ return false;
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/H2Dialect.java b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/H2Dialect.java
index 2b4375a..0d877d7 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/H2Dialect.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/H2Dialect.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,10 +19,10 @@ package ch.qos.logback.core.db.dialect;
* @author Ceki Gülcü
*/
public class H2Dialect implements SQLDialect {
- public static final String SELECT_CURRVAL = "CALL IDENTITY()";
-
- public String getSelectInsertId() {
- return SELECT_CURRVAL;
- }
+ public static final String SELECT_CURRVAL = "CALL IDENTITY()";
+ public String getSelectInsertId() {
+ return SELECT_CURRVAL;
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/HSQLDBDialect.java b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/HSQLDBDialect.java
index 8567b11..e4e39dc 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/HSQLDBDialect.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/HSQLDBDialect.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,10 +19,10 @@ package ch.qos.logback.core.db.dialect;
* @author Ceki Gülcü
*/
public class HSQLDBDialect implements SQLDialect {
- public static final String SELECT_CURRVAL = "CALL IDENTITY()";
-
- public String getSelectInsertId() {
- return SELECT_CURRVAL;
- }
+ public static final String SELECT_CURRVAL = "CALL IDENTITY()";
+ public String getSelectInsertId() {
+ return SELECT_CURRVAL;
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MsSQLDialect.java b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MsSQLDialect.java
index 11e7b4a..fa9076d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MsSQLDialect.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MsSQLDialect.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -11,7 +11,7 @@
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
-package ch.qos.logback.core.db.dialect;
+package ch.qos.logback.core.db.dialect;
/**
* The MS SQL Server dialect is untested.
@@ -20,11 +20,11 @@ package ch.qos.logback.core.db.dialect;
* the getGeneratedKeys method introduced in JDBC 3.0 specification.
*
* @author James Stauffer
-*/
-public class MsSQLDialect implements SQLDialect {
- public static final String SELECT_CURRVAL = "SELECT @@identity id";
+*/
+public class MsSQLDialect implements SQLDialect {
+ public static final String SELECT_CURRVAL = "SELECT @@identity id";
- public String getSelectInsertId() {
- return SELECT_CURRVAL;
- }
+ public String getSelectInsertId() {
+ return SELECT_CURRVAL;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MySQLDialect.java b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MySQLDialect.java
index a8ea754..e5a9a2f 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MySQLDialect.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/MySQLDialect.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,9 +20,9 @@ package ch.qos.logback.core.db.dialect;
*
*/
public class MySQLDialect implements SQLDialect {
- public static final String SELECT_LAST_INSERT_ID = "SELECT LAST_INSERT_ID()";
-
- public String getSelectInsertId() {
- return SELECT_LAST_INSERT_ID;
- }
+ public static final String SELECT_LAST_INSERT_ID = "SELECT LAST_INSERT_ID()";
+
+ public String getSelectInsertId() {
+ return SELECT_LAST_INSERT_ID;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/OracleDialect.java b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/OracleDialect.java
index 122dfef..a726296 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/OracleDialect.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/OracleDialect.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,10 +20,10 @@ package ch.qos.logback.core.db.dialect;
* @author Ceki Gülcü
*/
public class OracleDialect implements SQLDialect {
- public static final String SELECT_CURRVAL = "SELECT logging_event_id_seq.currval from dual";
+ public static final String SELECT_CURRVAL = "SELECT logging_event_id_seq.currval from dual";
- public String getSelectInsertId() {
- return SELECT_CURRVAL;
- }
+ public String getSelectInsertId() {
+ return SELECT_CURRVAL;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/PostgreSQLDialect.java b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/PostgreSQLDialect.java
index 5503fa9..7502cbf 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/PostgreSQLDialect.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/PostgreSQLDialect.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,15 +13,17 @@
*/
package ch.qos.logback.core.db.dialect;
+
/**
*
* @author ceki
*
*/
-public class PostgreSQLDialect implements SQLDialect {
- public static final String SELECT_CURRVAL = "SELECT currval('logging_event_id_seq')";
+public class PostgreSQLDialect
+ implements SQLDialect {
+ public static final String SELECT_CURRVAL = "SELECT currval('logging_event_id_seq')";
- public String getSelectInsertId() {
- return SELECT_CURRVAL;
- }
+ public String getSelectInsertId() {
+ return SELECT_CURRVAL;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialect.java b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialect.java
index ef19f89..b95d8f0 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialect.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialect.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,9 +14,9 @@
package ch.qos.logback.core.db.dialect;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*
*/
public interface SQLDialect {
- String getSelectInsertId();
+ String getSelectInsertId();
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialectCode.java b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialectCode.java
index 8fb3f93..c96ed4d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialectCode.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialectCode.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,5 +14,13 @@
package ch.qos.logback.core.db.dialect;
public enum SQLDialectCode {
- UNKNOWN_DIALECT, POSTGRES_DIALECT, MYSQL_DIALECT, ORACLE_DIALECT, MSSQL_DIALECT, HSQL_DIALECT, H2_DIALECT, SYBASE_SQLANYWHERE_DIALECT, SQLITE_DIALECT;
+ UNKNOWN_DIALECT,
+ POSTGRES_DIALECT,
+ MYSQL_DIALECT,
+ ORACLE_DIALECT,
+ MSSQL_DIALECT,
+ HSQL_DIALECT,
+ H2_DIALECT,
+ SYBASE_SQLANYWHERE_DIALECT,
+ SQLITE_DIALECT;
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLiteDialect.java b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLiteDialect.java
index 64baf12..0970490 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLiteDialect.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLiteDialect.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,9 +22,10 @@ package ch.qos.logback.core.db.dialect;
* @author Anthony Trinh
*/
public class SQLiteDialect implements SQLDialect {
- public static final String SELECT_CURRVAL = "SELECT last_insert_rowid();";
+ public static final String SELECT_CURRVAL = "SELECT last_insert_rowid();";
- public String getSelectInsertId() {
- return SELECT_CURRVAL;
- }
+ public String getSelectInsertId() {
+ return SELECT_CURRVAL;
+ }
}
+
diff --git a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SybaseSqlAnywhereDialect.java b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SybaseSqlAnywhereDialect.java
index cd61031..4551a60 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SybaseSqlAnywhereDialect.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/db/dialect/SybaseSqlAnywhereDialect.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,19 +15,19 @@ package ch.qos.logback.core.db.dialect;
public class SybaseSqlAnywhereDialect implements SQLDialect {
- /**
- * The Sybase SQLAnywhere Dialect
- *
- * Note that the dialect is not needed if your JDBC driver supports
- * the getGeneratedKeys method introduced in JDBC 3.0 specification.
- *
- * @author Michael Lynch
- */
+ /**
+ * The Sybase SQLAnywhere Dialect
+ *
+ * Note that the dialect is not needed if your JDBC driver supports
+ * the getGeneratedKeys method introduced in JDBC 3.0 specification.
+ *
+ * @author Michael Lynch
+ */
- public static final String SELECT_CURRVAL = "SELECT @@identity id";
+ public static final String SELECT_CURRVAL = "SELECT @@identity id";
- public String getSelectInsertId() {
- return SELECT_CURRVAL;
- }
+ public String getSelectInsertId() {
+ return SELECT_CURRVAL;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/ByteArrayUtil.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/ByteArrayUtil.java
index 6f4de17..f21d554 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/encoder/ByteArrayUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/ByteArrayUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,53 +17,53 @@ import java.io.ByteArrayOutputStream;
public class ByteArrayUtil {
- // big-endian
- static void writeInt(byte[] byteArray, int offset, int i) {
- for (int j = 0; j < 4; j++) {
- int shift = 24 - j * 8;
- byteArray[offset + j] = (byte) (i >>> shift);
- }
+ // big-endian
+ static void writeInt(byte[] byteArray, int offset, int i) {
+ for (int j = 0; j < 4; j++) {
+ int shift = 24 - j * 8;
+ byteArray[offset + j] = (byte) (i >>> shift);
}
+ }
- static void writeInt(ByteArrayOutputStream baos, int i) {
- for (int j = 0; j < 4; j++) {
- int shift = 24 - j * 8;
- baos.write((byte) (i >>> shift));
- }
+ static void writeInt(ByteArrayOutputStream baos, int i) {
+ for (int j = 0; j < 4; j++) {
+ int shift = 24 - j * 8;
+ baos.write((byte) (i >>> shift));
}
-
- // big-endian
- static int readInt(byte[] byteArray, int offset) {
- int i = 0;
- for (int j = 0; j < 4; j++) {
- int shift = 24 - j * 8;
- i += (byteArray[offset + j] & 0xFF) << shift;
- }
- return i;
+ }
+
+ // big-endian
+ static int readInt(byte[] byteArray, int offset) {
+ int i = 0;
+ for (int j = 0; j < 4; j++) {
+ int shift = 24 - j * 8;
+ i += (byteArray[offset + j] & 0xFF) << shift;
}
-
- static public String toHexString(byte[] ba) {
- StringBuilder sbuf = new StringBuilder();
- for (byte b : ba) {
- String s = Integer.toHexString((int) (b & 0xff));
- if (s.length() == 1) {
- sbuf.append('0');
- }
- sbuf.append(s);
- }
- return sbuf.toString();
+ return i;
+ }
+
+ static public String toHexString(byte[] ba) {
+ StringBuilder sbuf = new StringBuilder();
+ for(byte b: ba) {
+ String s = Integer.toHexString( (int)(b & 0xff));
+ if(s.length() == 1) {
+ sbuf.append('0');
+ }
+ sbuf.append(s);
}
+ return sbuf.toString();
+ }
- static public byte[] hexStringToByteArray(String s) {
- int len = s.length();
- byte[] ba = new byte[len / 2];
+ static public byte[] hexStringToByteArray(String s) {
+ int len = s.length();
+ byte[] ba = new byte[len/2];
- for (int i = 0; i < ba.length; i++) {
- int j = i * 2;
- int t = Integer.parseInt(s.substring(j, j + 2), 16);
- byte b = (byte) (t & 0xFF);
- ba[i] = b;
- }
- return ba;
+ for(int i = 0; i < ba.length; i++) {
+ int j = i*2;
+ int t = Integer.parseInt(s.substring(j, j+2), 16);
+ byte b = (byte) (t & 0xFF);
+ ba[i] = b;
}
+ return ba;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/EchoEncoder.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/EchoEncoder.java
index 2dd6374..9a3f6e9 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/encoder/EchoEncoder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/EchoEncoder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,28 +20,28 @@ import ch.qos.logback.core.CoreConstants;
public class EchoEncoder<E> extends EncoderBase<E> {
- String fileHeader;
- String fileFooter;
+ String fileHeader;
+ String fileFooter;
- public void doEncode(E event) throws IOException {
- String val = event + CoreConstants.LINE_SEPARATOR;
- outputStream.write(val.getBytes());
- // necessary if ResilientFileOutputStream is buffered
- outputStream.flush();
- }
+ public void doEncode(E event) throws IOException {
+ String val = event + CoreConstants.LINE_SEPARATOR;
+ outputStream.write(val.getBytes());
+ // necessary if ResilientFileOutputStream is buffered
+ outputStream.flush();
+ }
- public void close() throws IOException {
- if (fileFooter == null) {
- return;
- }
- outputStream.write(fileFooter.getBytes());
+ public void close() throws IOException {
+ if (fileFooter == null) {
+ return;
}
+ outputStream.write(fileFooter.getBytes());
+ }
- public void init(OutputStream os) throws IOException {
- super.init(os);
- if (fileHeader == null) {
- return;
- }
- outputStream.write(fileHeader.getBytes());
+ public void init(OutputStream os) throws IOException {
+ super.init(os);
+ if (fileHeader == null) {
+ return;
}
+ outputStream.write(fileHeader.getBytes());
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/Encoder.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/Encoder.java
index aab1834..681d361 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/encoder/Encoder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/Encoder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,7 +27,7 @@ import ch.qos.logback.core.spi.LifeCycle;
*
*
* @author Ceki Gülcü
- * @author Joern Huxhorn
+ * @author Joen Huxhorn
* @author Maarten Bosteels
*
* @param <E>
@@ -36,33 +36,33 @@ import ch.qos.logback.core.spi.LifeCycle;
*/
public interface Encoder<E> extends ContextAware, LifeCycle {
- /**
- * This method is called when the owning appender starts or whenever output
- * needs to be directed to a new OutputStream, for instance as a result of a
- * rollover. Implementing encoders should at the very least remember the
- * OutputStream passed as argument and use it in future operations.
- *
- * @param os
- * @throws IOException
- */
- void init(OutputStream os) throws IOException;
+ /**
+ * This method is called when the owning appender starts or whenever output
+ * needs to be directed to a new OutputStream, for instance as a result of a
+ * rollover. Implementing encoders should at the very least remember the
+ * OutputStream passed as argument and use it in future operations.
+ *
+ * @param os
+ * @throws IOException
+ */
+ void init(OutputStream os) throws IOException;
- /**
- * Encode and write an event to the appropriate {@link OutputStream}.
- * Implementations are free to differ writing out of the encoded event and
- * instead write in batches.
- *
- * @param event
- * @throws IOException
- */
- void doEncode(E event) throws IOException;
+ /**
+ * Encode and write an event to the appropriate {@link OutputStream}.
+ * Implementations are free to differ writing out of the encoded event and
+ * instead write in batches.
+ *
+ * @param event
+ * @throws IOException
+ */
+ void doEncode(E event) throws IOException;
- /**
- * This method is called prior to the closing of the underling
- * {@link OutputStream}. Implementations MUST not close the underlying
- * {@link OutputStream} which is the responsibility of the owning appender.
- *
- * @throws IOException
- */
- void close() throws IOException;
+ /**
+ * This method is called prior to the closing of the underling
+ * {@link OutputStream}. Implementations MUST not close the underlying
+ * {@link OutputStream} which is the responsibility of the owning appender.
+ *
+ * @throws IOException
+ */
+ void close() throws IOException;
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/EncoderBase.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/EncoderBase.java
index 94d75d1..f70209d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/encoder/EncoderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/EncoderBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,23 +20,24 @@ import ch.qos.logback.core.spi.ContextAwareBase;
abstract public class EncoderBase<E> extends ContextAwareBase implements Encoder<E> {
- protected boolean started;
+ protected boolean started;
+
+ protected OutputStream outputStream;
+
+ public void init(OutputStream os) throws IOException {
+ this.outputStream = os;
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public void start() {
+ started = true;
+ }
+
+ public void stop() {
+ started = false;
+ }
+}
- protected OutputStream outputStream;
-
- public void init(OutputStream os) throws IOException {
- this.outputStream = os;
- }
-
- public boolean isStarted() {
- return started;
- }
-
- public void start() {
- started = true;
- }
-
- public void stop() {
- started = false;
- }
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/EventObjectInputStream.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/EventObjectInputStream.java
index 22130a0..0742798 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/encoder/EventObjectInputStream.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/EventObjectInputStream.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -32,125 +32,128 @@ import java.util.List;
*/
public class EventObjectInputStream<E> extends InputStream {
- NonClosableInputStream ncis;
- List<E> buffer = new ArrayList<E>();
+ NonClosableInputStream ncis;
+ List<E> buffer = new ArrayList<E>();
- int index = 0;
+ int index = 0;
- EventObjectInputStream(InputStream is) throws IOException {
- this.ncis = new NonClosableInputStream(is);
- }
+ EventObjectInputStream(InputStream is) throws IOException {
+ this.ncis = new NonClosableInputStream(is);
+ }
- @Override
- public int read() throws IOException {
- throw new UnsupportedOperationException("Only the readEvent method is supported.");
- }
+ @Override
+ public int read() throws IOException {
+ throw new UnsupportedOperationException(
+ "Only the readEvent method is supported.");
+ }
- /**
- * Returns the number of bytes available
- */
- public int available() throws IOException {
- return ncis.available();
- }
+ /**
+ * Returns the number of bytes available
+ */
+ public int available() throws IOException {
+ return ncis.available();
+ }
- public E readEvent() throws IOException {
-
- E event = getFromBuffer();
- if (event != null) {
- return event;
- }
-
- internalReset();
- int count = readHeader();
- if (count == -1) {
- return null;
- }
- readPayload(count);
- readFooter(count);
- return getFromBuffer();
- }
+ public E readEvent() throws IOException {
- private void internalReset() {
- index = 0;
- buffer.clear();
+ E event = getFromBuffer();
+ if (event != null) {
+ return event;
}
- E getFromBuffer() {
- if (index >= buffer.size()) {
- return null;
- }
- return buffer.get(this.index++);
+ internalReset();
+ int count = readHeader();
+ if(count == -1) {
+ return null;
}
-
- int readHeader() throws IOException {
- byte[] headerBA = new byte[4 * BYTES_PER_INT];
- // System.out.println("available="+ncis.available());
- int bytesRead = ncis.read(headerBA);
- if (bytesRead == -1) {
- return -1;
- }
- // System.out.println("**bytesRead="+bytesRead);
-
- // System.out.println(ByteArrayUtil.toHexString(headerBA));
-
- int offset = 0;
- int startPebble = ByteArrayUtil.readInt(headerBA, offset);
- if (startPebble != START_PEBBLE) {
- throw new IllegalStateException("Does not look like data created by ObjectStreamEncoder");
- }
- offset += BYTES_PER_INT;
- int count = ByteArrayUtil.readInt(headerBA, offset);
- offset += BYTES_PER_INT;
- int endPointer = ByteArrayUtil.readInt(headerBA, offset);
- offset += BYTES_PER_INT;
- int checksum = ByteArrayUtil.readInt(headerBA, offset);
- if (checksum != (START_PEBBLE ^ count)) {
- throw new IllegalStateException("Invalid checksum");
- }
- return count;
+ readPayload(count);
+ readFooter(count);
+ return getFromBuffer();
+ }
+
+ private void internalReset() {
+ index = 0;
+ buffer.clear();
+ }
+
+ E getFromBuffer() {
+ if (index >= buffer.size()) {
+ return null;
}
-
- @SuppressWarnings("unchecked")
- E readEvents(ObjectInputStream ois) throws IOException {
- E e = null;
- try {
- e = (E) ois.readObject();
- buffer.add(e);
- } catch (ClassNotFoundException e1) {
- // FIXME Auto-generated catch block
- e1.printStackTrace();
- }
- return e;
+ return buffer.get(this.index++);
+ }
+
+ int readHeader() throws IOException {
+ byte[] headerBA = new byte[4 * BYTES_PER_INT];
+ //System.out.println("available="+ncis.available());
+ int bytesRead = ncis.read(headerBA);
+ if(bytesRead == -1) {
+ return -1;
}
-
- void readFooter(int count) throws IOException {
- byte[] headerBA = new byte[2 * BYTES_PER_INT];
- ncis.read(headerBA);
-
- int offset = 0;
- int stopPebble = ByteArrayUtil.readInt(headerBA, offset);
- if (stopPebble != STOP_PEBBLE) {
- throw new IllegalStateException("Looks like a corrupt stream");
- }
- offset += BYTES_PER_INT;
- int checksum = ByteArrayUtil.readInt(headerBA, offset);
- if (checksum != (STOP_PEBBLE ^ count)) {
- throw new IllegalStateException("Invalid checksum");
- }
+ //System.out.println("**bytesRead="+bytesRead);
+
+ //System.out.println(ByteArrayUtil.toHexString(headerBA));
+
+ int offset = 0;
+ int startPebble = ByteArrayUtil.readInt(headerBA, offset);
+ if (startPebble != START_PEBBLE) {
+ throw new IllegalStateException(
+ "Does not look like data created by ObjectStreamEncoder");
}
-
- void readPayload(int count) throws IOException {
- List<E> eventList = new ArrayList<E>(count);
- ObjectInputStream ois = new ObjectInputStream(ncis);
- for (int i = 0; i < count; i++) {
- E e = (E) readEvents(ois);
- eventList.add(e);
- }
- ois.close();
+ offset += BYTES_PER_INT;
+ int count = ByteArrayUtil.readInt(headerBA, offset);
+ offset += BYTES_PER_INT;
+ int endPointer = ByteArrayUtil.readInt(headerBA, offset);
+ offset += BYTES_PER_INT;
+ int checksum = ByteArrayUtil.readInt(headerBA, offset);
+ if (checksum != (START_PEBBLE ^ count)) {
+ throw new IllegalStateException("Invalid checksum");
}
-
- public void close() throws IOException {
- ncis.realClose();
+ return count;
+ }
+
+ @SuppressWarnings("unchecked")
+ E readEvents(ObjectInputStream ois) throws IOException {
+ E e = null;
+ try {
+ e = (E) ois.readObject();
+ buffer.add(e);
+ } catch (ClassNotFoundException e1) {
+ // FIXME Auto-generated catch block
+ e1.printStackTrace();
+ }
+ return e;
+ }
+
+ void readFooter(int count) throws IOException {
+ byte[] headerBA = new byte[2 * BYTES_PER_INT];
+ ncis.read(headerBA);
+
+ int offset = 0;
+ int stopPebble = ByteArrayUtil.readInt(headerBA, offset);
+ if (stopPebble != STOP_PEBBLE) {
+ throw new IllegalStateException(
+ "Looks like a corrupt stream");
}
+ offset += BYTES_PER_INT;
+ int checksum = ByteArrayUtil.readInt(headerBA, offset);
+ if (checksum != (STOP_PEBBLE ^ count)) {
+ throw new IllegalStateException("Invalid checksum");
+ }
+ }
+
+ void readPayload(int count) throws IOException {
+ List<E> eventList = new ArrayList<E>(count);
+ ObjectInputStream ois = new ObjectInputStream(ncis);
+ for (int i = 0; i < count; i++) {
+ E e = (E) readEvents(ois);
+ eventList.add(e);
+ }
+ ois.close();
+ }
+
+ public void close() throws IOException {
+ ncis.realClose();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/LayoutWrappingEncoder.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/LayoutWrappingEncoder.java
index d5d262f..89dd836 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/encoder/LayoutWrappingEncoder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/LayoutWrappingEncoder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,138 +23,142 @@ import ch.qos.logback.core.Layout;
public class LayoutWrappingEncoder<E> extends EncoderBase<E> {
- protected Layout<E> layout;
-
- /**
- * The charset to use when converting a String into bytes.
- * <p/>
- * By default this property has the value
- * <code>null</null> which corresponds to
- * the system's default charset.
- */
- private Charset charset;
-
- private boolean immediateFlush = true;
-
- /**
- * Sets the immediateFlush option. The default value for immediateFlush is 'true'. If set to true,
- * the doEncode() method will immediately flush the underlying OutputStream. Although immediate flushing
- * is safer, it also significantly degrades logging throughput.
- *
- * @since 1.0.3
- */
- public void setImmediateFlush(boolean immediateFlush) {
- this.immediateFlush = immediateFlush;
- }
-
- public boolean isImmediateFlush() {
- return immediateFlush;
- }
-
- public Layout<E> getLayout() {
- return layout;
- }
-
- public void setLayout(Layout<E> layout) {
- this.layout = layout;
- }
-
- public Charset getCharset() {
- return charset;
- }
-
- /**
- * Set the charset to use when converting the string returned by the layout
- * into bytes.
- * <p/>
- * By default this property has the value
- * <code>null</null> which corresponds to
- * the system's default charset.
- *
- * @param charset
- */
- public void setCharset(Charset charset) {
- this.charset = charset;
- }
-
- public void init(OutputStream os) throws IOException {
- super.init(os);
- writeHeader();
- }
-
- void writeHeader() throws IOException {
- if (layout != null && (outputStream != null)) {
- StringBuilder sb = new StringBuilder();
- appendIfNotNull(sb, layout.getFileHeader());
- appendIfNotNull(sb, layout.getPresentationHeader());
- if (sb.length() > 0) {
- sb.append(CoreConstants.LINE_SEPARATOR);
- // If at least one of file header or presentation header were not
- // null, then append a line separator.
- // This should be useful in most cases and should not hurt.
- outputStream.write(convertToBytes(sb.toString()));
- outputStream.flush();
- }
- }
- }
-
- public void close() throws IOException {
- writeFooter();
- }
-
- void writeFooter() throws IOException {
- if (layout != null && outputStream != null) {
- StringBuilder sb = new StringBuilder();
- appendIfNotNull(sb, layout.getPresentationFooter());
- appendIfNotNull(sb, layout.getFileFooter());
- if (sb.length() > 0) {
- outputStream.write(convertToBytes(sb.toString()));
- outputStream.flush();
- }
- }
- }
-
- private byte[] convertToBytes(String s) {
- if (charset == null) {
- return s.getBytes();
- } else {
- try {
- return s.getBytes(charset.name());
- } catch (UnsupportedEncodingException e) {
- throw new IllegalStateException("An existing charset cannot possibly be unsupported.");
- }
- }
- }
-
- public void doEncode(E event) throws IOException {
- String txt = layout.doLayout(event);
- outputStream.write(convertToBytes(txt));
- if (immediateFlush)
- outputStream.flush();
- }
-
- public boolean isStarted() {
- return false;
- }
-
- public void start() {
- started = true;
- }
-
- public void stop() {
- started = false;
- if (outputStream != null) {
- try {
- outputStream.flush();
- } catch (IOException e) {
- }
- }
- }
-
- private void appendIfNotNull(StringBuilder sb, String s) {
- if (s != null) {
- sb.append(s);
- }
- }
+ protected Layout<E> layout;
+
+ /**
+ * The charset to use when converting a String into bytes.
+ * <p/>
+ * By default this property has the value
+ * <code>null</null> which corresponds to
+ * the system's default charset.
+ */
+ private Charset charset;
+
+ private boolean immediateFlush = true;
+
+
+ /**
+ * Sets the immediateFlush option. The default value for immediateFlush is 'true'. If set to true,
+ * the doEncode() method will immediately flush the underlying OutputStream. Although immediate flushing
+ * is safer, it also significantly degrades logging throughput.
+ *
+ * @since 1.0.3
+ */
+ public void setImmediateFlush(boolean immediateFlush) {
+ this.immediateFlush = immediateFlush;
+ }
+
+
+ public boolean isImmediateFlush() {
+ return immediateFlush;
+ }
+
+
+ public Layout<E> getLayout() {
+ return layout;
+ }
+
+ public void setLayout(Layout<E> layout) {
+ this.layout = layout;
+ }
+
+ public Charset getCharset() {
+ return charset;
+ }
+
+ /**
+ * Set the charset to use when converting the string returned by the layout
+ * into bytes.
+ * <p/>
+ * By default this property has the value
+ * <code>null</null> which corresponds to
+ * the system's default charset.
+ *
+ * @param charset
+ */
+ public void setCharset(Charset charset) {
+ this.charset = charset;
+ }
+
+ public void init(OutputStream os) throws IOException {
+ super.init(os);
+ writeHeader();
+ }
+
+ void writeHeader() throws IOException {
+ if (layout != null && (outputStream != null)) {
+ StringBuilder sb = new StringBuilder();
+ appendIfNotNull(sb, layout.getFileHeader());
+ appendIfNotNull(sb, layout.getPresentationHeader());
+ if (sb.length() > 0) {
+ sb.append(CoreConstants.LINE_SEPARATOR);
+ // If at least one of file header or presentation header were not
+ // null, then append a line separator.
+ // This should be useful in most cases and should not hurt.
+ outputStream.write(convertToBytes(sb.toString()));
+ outputStream.flush();
+ }
+ }
+ }
+
+ public void close() throws IOException {
+ writeFooter();
+ }
+
+ void writeFooter() throws IOException {
+ if (layout != null && outputStream != null) {
+ StringBuilder sb = new StringBuilder();
+ appendIfNotNull(sb, layout.getPresentationFooter());
+ appendIfNotNull(sb, layout.getFileFooter());
+ if (sb.length() > 0) {
+ outputStream.write(convertToBytes(sb.toString()));
+ outputStream.flush();
+ }
+ }
+ }
+
+ private byte[] convertToBytes(String s) {
+ if (charset == null) {
+ return s.getBytes();
+ } else {
+ try {
+ return s.getBytes(charset.name());
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalStateException(
+ "An existing charset cannot possibly be unsupported.");
+ }
+ }
+ }
+
+ public void doEncode(E event) throws IOException {
+ String txt = layout.doLayout(event);
+ outputStream.write(convertToBytes(txt));
+ if (immediateFlush)
+ outputStream.flush();
+ }
+
+ public boolean isStarted() {
+ return false;
+ }
+
+ public void start() {
+ started = true;
+ }
+
+ public void stop() {
+ started = false;
+ if(outputStream != null) {
+ try {
+ outputStream.flush();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ private void appendIfNotNull(StringBuilder sb, String s) {
+ if (s != null) {
+ sb.append(s);
+ }
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/NonClosableInputStream.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/NonClosableInputStream.java
index 1997153..9d89874 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/encoder/NonClosableInputStream.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/NonClosableInputStream.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,20 +19,20 @@ import java.io.InputStream;
public class NonClosableInputStream extends FilterInputStream {
- NonClosableInputStream(InputStream is) {
- super(is);
- }
+ NonClosableInputStream(InputStream is) {
+ super(is);
+ }
- /**
- * The whole point of this input stream is to ignore invocations to close()
- */
- @Override
- public void close() {
+ /**
+ * The whole point of this input stream is to ignore invocations to close()
+ */
+ @Override
+ public void close() {
- }
+ }
- public void realClose() throws IOException {
- super.close();
- }
+ public void realClose() throws IOException {
+ super.close();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/ObjectStreamEncoder.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/ObjectStreamEncoder.java
index 6feb994..3c6907d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/encoder/ObjectStreamEncoder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/ObjectStreamEncoder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,65 +31,64 @@ import ch.qos.logback.core.CoreConstants;
*/
public class ObjectStreamEncoder<E> extends EncoderBase<E> {
- static public final int START_PEBBLE = 1853421169;
- static public final int STOP_PEBBLE = 640373619;
+ static public final int START_PEBBLE = 1853421169;
+ static public final int STOP_PEBBLE = 640373619;
- private int MAX_BUFFER_SIZE = 100;
+ private int MAX_BUFFER_SIZE = 100;
- List<E> bufferList = new ArrayList<E>(MAX_BUFFER_SIZE);
+ List<E> bufferList = new ArrayList<E>(MAX_BUFFER_SIZE);
- public void doEncode(E event) throws IOException {
- bufferList.add(event);
- if (bufferList.size() == MAX_BUFFER_SIZE) {
- writeBuffer();
- }
+ public void doEncode(E event) throws IOException {
+ bufferList.add(event);
+ if (bufferList.size() == MAX_BUFFER_SIZE) {
+ writeBuffer();
}
-
- void writeHeader(ByteArrayOutputStream baos, int bufferSize) {
- ByteArrayUtil.writeInt(baos, START_PEBBLE);
- ByteArrayUtil.writeInt(baos, bufferSize);
- ByteArrayUtil.writeInt(baos, 0);
- ByteArrayUtil.writeInt(baos, START_PEBBLE ^ bufferSize);
- }
-
- void writeFooter(ByteArrayOutputStream baos, int bufferSize) {
- ByteArrayUtil.writeInt(baos, STOP_PEBBLE);
- ByteArrayUtil.writeInt(baos, STOP_PEBBLE ^ bufferSize);
- }
-
- void writeBuffer() throws IOException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream(10000);
-
- int size = bufferList.size();
- writeHeader(baos, size);
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- for (E e : bufferList) {
- oos.writeObject(e);
- }
- bufferList.clear();
- oos.flush();
-
- writeFooter(baos, size);
-
- byte[] byteArray = baos.toByteArray();
- oos.close();
- writeEndPosition(byteArray);
- outputStream.write(byteArray);
-
- }
-
- void writeEndPosition(byte[] byteArray) {
- int offset = 2 * CoreConstants.BYTES_PER_INT;
- ByteArrayUtil.writeInt(byteArray, offset, byteArray.length - offset);
- }
-
- @Override
- public void init(OutputStream os) throws IOException {
- super.init(os);
- bufferList.clear();
- }
-
- public void close() throws IOException {
- writeBuffer();
+ }
+
+ void writeHeader(ByteArrayOutputStream baos, int bufferSize) {
+ ByteArrayUtil.writeInt(baos, START_PEBBLE);
+ ByteArrayUtil.writeInt(baos, bufferSize);
+ ByteArrayUtil.writeInt(baos, 0);
+ ByteArrayUtil.writeInt(baos, START_PEBBLE^bufferSize);
+ }
+
+ void writeFooter(ByteArrayOutputStream baos, int bufferSize) {
+ ByteArrayUtil.writeInt(baos, STOP_PEBBLE);
+ ByteArrayUtil.writeInt(baos, STOP_PEBBLE ^ bufferSize);
+ }
+ void writeBuffer() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(10000);
+
+ int size = bufferList.size();
+ writeHeader(baos, size);
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ for (E e : bufferList) {
+ oos.writeObject(e);
}
+ bufferList.clear();
+ oos.flush();
+
+ writeFooter(baos, size);
+
+ byte[] byteArray = baos.toByteArray();
+ oos.close();
+ writeEndPosition(byteArray);
+ outputStream.write(byteArray);
+
+ }
+
+ void writeEndPosition(byte[] byteArray) {
+ int offset = 2*CoreConstants.BYTES_PER_INT;
+ ByteArrayUtil.writeInt(byteArray,offset, byteArray.length-offset);
+ }
+
+ @Override
+ public void init(OutputStream os) throws IOException {
+ super.init(os);
+ bufferList.clear();
+ }
+
+ public void close() throws IOException {
+ writeBuffer();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/filter/AbstractMatcherFilter.java b/logback-core/src/main/java/ch/qos/logback/core/filter/AbstractMatcherFilter.java
index d5b430b..6446ec8 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/filter/AbstractMatcherFilter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/filter/AbstractMatcherFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,22 +17,22 @@ import ch.qos.logback.core.spi.FilterReply;
public abstract class AbstractMatcherFilter<E> extends Filter<E> {
- protected FilterReply onMatch = FilterReply.NEUTRAL;
- protected FilterReply onMismatch = FilterReply.NEUTRAL;
-
- final public void setOnMatch(FilterReply reply) {
- this.onMatch = reply;
- }
-
- final public void setOnMismatch(FilterReply reply) {
- this.onMismatch = reply;
- }
-
- final public FilterReply getOnMatch() {
- return onMatch;
- }
-
- final public FilterReply getOnMismatch() {
- return onMismatch;
- }
+ protected FilterReply onMatch = FilterReply.NEUTRAL;
+ protected FilterReply onMismatch = FilterReply.NEUTRAL;
+
+ final public void setOnMatch(FilterReply reply) {
+ this.onMatch = reply;
+ }
+
+ final public void setOnMismatch(FilterReply reply) {
+ this.onMismatch = reply;
+ }
+
+ final public FilterReply getOnMatch() {
+ return onMatch;
+ }
+
+ final public FilterReply getOnMismatch() {
+ return onMismatch;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/filter/EvaluatorFilter.java b/logback-core/src/main/java/ch/qos/logback/core/filter/EvaluatorFilter.java
index 20de1ea..5cfef86 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/filter/EvaluatorFilter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/filter/EvaluatorFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -36,41 +36,41 @@ import ch.qos.logback.core.spi.FilterReply;
*/
public class EvaluatorFilter<E> extends AbstractMatcherFilter<E> {
- EventEvaluator<E> evaluator;
+ EventEvaluator<E> evaluator;
- @Override
- public void start() {
- if (evaluator != null) {
- super.start();
- } else {
- addError("No evaluator set for filter " + this.getName());
- }
+ @Override
+ public void start() {
+ if (evaluator != null) {
+ super.start();
+ } else {
+ addError("No evaluator set for filter " + this.getName());
}
+ }
- public EventEvaluator<E> getEvaluator() {
- return evaluator;
- }
+ public EventEvaluator<E> getEvaluator() {
+ return evaluator;
+ }
- public void setEvaluator(EventEvaluator<E> evaluator) {
- this.evaluator = evaluator;
- }
+ public void setEvaluator(EventEvaluator<E> evaluator) {
+ this.evaluator = evaluator;
+ }
- public FilterReply decide(E event) {
- // let us not throw an exception
- // see also bug #17.
- if (!isStarted() || !evaluator.isStarted()) {
- return FilterReply.NEUTRAL;
- }
- try {
- if (evaluator.evaluate(event)) {
- return onMatch;
- } else {
- return onMismatch;
- }
- } catch (EvaluationException e) {
- addError("Evaluator " + evaluator.getName() + " threw an exception", e);
- return FilterReply.NEUTRAL;
- }
+ public FilterReply decide(E event) {
+ // let us not throw an exception
+ // see also bug #17.
+ if (!isStarted() || !evaluator.isStarted()) {
+ return FilterReply.NEUTRAL;
+ }
+ try {
+ if (evaluator.evaluate(event)) {
+ return onMatch;
+ } else {
+ return onMismatch;
+ }
+ } catch (EvaluationException e) {
+ addError("Evaluator " + evaluator.getName() + " threw an exception", e);
+ return FilterReply.NEUTRAL;
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/filter/Filter.java b/logback-core/src/main/java/ch/qos/logback/core/filter/Filter.java
index 1d87444..2a048ef 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/filter/Filter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/filter/Filter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,39 +30,39 @@ import ch.qos.logback.core.spi.LifeCycle;
*/
public abstract class Filter<E> extends ContextAwareBase implements LifeCycle {
- private String name;
+ private String name;
- boolean start = false;
+ boolean start = false;
- public void start() {
- this.start = true;
- }
+ public void start() {
+ this.start = true;
+ }
- public boolean isStarted() {
- return this.start;
- }
+ public boolean isStarted() {
+ return this.start;
+ }
- public void stop() {
- this.start = false;
- }
+ public void stop() {
+ this.start = false;
+ }
- /**
- * If the decision is <code>{@link FilterReply#DENY}</code>, then the event will be
- * dropped. If the decision is <code>{@link FilterReply#NEUTRAL}</code>, then the next
- * filter, if any, will be invoked. If the decision is
- * <code>{@link FilterReply#ACCEPT}</code> then the event will be logged without
- * consulting with other filters in the chain.
- *
- * @param event
- * The event to decide upon.
- */
- public abstract FilterReply decide(E event);
+ /**
+ * If the decision is <code>{@link FilterReply#DENY}</code>, then the event will be
+ * dropped. If the decision is <code>{@link FilterReply#NEUTRAL}</code>, then the next
+ * filter, if any, will be invoked. If the decision is
+ * <code>{@link FilterReply#ACCEPT}</code> then the event will be logged without
+ * consulting with other filters in the chain.
+ *
+ * @param event
+ * The event to decide upon.
+ */
+ public abstract FilterReply decide(E event);
- public String getName() {
- return name;
- }
+ public String getName() {
+ return name;
+ }
- public void setName(String name) {
- this.name = name;
- }
+ public void setName(String name) {
+ this.name = name;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/helpers/CyclicBuffer.java b/logback-core/src/main/java/ch/qos/logback/core/helpers/CyclicBuffer.java
index 4f6c151..369fa04 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/helpers/CyclicBuffer.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/helpers/CyclicBuffer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,148 +26,150 @@ import java.util.List;
*/
public class CyclicBuffer<E> {
- E[] ea;
- int first;
- int last;
- int numElems;
- int maxSize;
-
- /**
- * Instantiate a new CyclicBuffer of at most <code>maxSize</code> events.
- *
- * The <code>maxSize</code> argument must a positive integer.
- *
- * @param maxSize
- * The maximum number of elements in the buffer.
- */
- public CyclicBuffer(int maxSize) throws IllegalArgumentException {
- if (maxSize < 1) {
- throw new IllegalArgumentException("The maxSize argument (" + maxSize + ") is not a positive integer.");
- }
- init(maxSize);
+ E[] ea;
+ int first;
+ int last;
+ int numElems;
+ int maxSize;
+
+ /**
+ * Instantiate a new CyclicBuffer of at most <code>maxSize</code> events.
+ *
+ * The <code>maxSize</code> argument must a positive integer.
+ *
+ * @param maxSize
+ * The maximum number of elements in the buffer.
+ */
+ public CyclicBuffer(int maxSize) throws IllegalArgumentException {
+ if (maxSize < 1) {
+ throw new IllegalArgumentException("The maxSize argument (" + maxSize
+ + ") is not a positive integer.");
}
-
- public CyclicBuffer(CyclicBuffer<E> other) {
- this.maxSize = other.maxSize;
- ea = (E[]) new Object[maxSize];
- System.arraycopy(other.ea, 0, this.ea, 0, maxSize);
- this.last = other.last;
- this.first = other.first;
- this.numElems = other.numElems;
- }
-
- @SuppressWarnings("unchecked")
- private void init(int maxSize) {
- this.maxSize = maxSize;
- ea = (E[]) new Object[maxSize];
+ init(maxSize);
+ }
+
+ public CyclicBuffer(CyclicBuffer<E> other) {
+ this.maxSize = other.maxSize;
+ ea = (E[]) new Object[maxSize];
+ System.arraycopy(other.ea, 0, this.ea, 0, maxSize);
+ this.last = other.last;
+ this.first = other.first;
+ this.numElems = other.numElems;
+ }
+
+ @SuppressWarnings("unchecked")
+ private void init(int maxSize) {
+ this.maxSize = maxSize;
+ ea = (E[]) new Object[maxSize];
+ first = 0;
+ last = 0;
+ numElems = 0;
+ }
+
+ /**
+ * Clears the buffer and resets all attributes.
+ */
+ public void clear() {
+ init(this.maxSize);
+ }
+
+ /**
+ * Add an <code>event</code> as the last event in the buffer.
+ *
+ */
+ public void add(E event) {
+ ea[last] = event;
+ if (++last == maxSize)
+ last = 0;
+
+ if (numElems < maxSize)
+ numElems++;
+ else if (++first == maxSize)
+ first = 0;
+ }
+
+ /**
+ * Get the <i>i</i>th oldest event currently in the buffer. If <em>i</em>
+ * is outside the range 0 to the number of elements currently in the buffer,
+ * then <code>null</code> is returned.
+ */
+ public E get(int i) {
+ if (i < 0 || i >= numElems)
+ return null;
+
+ return ea[(first + i) % maxSize];
+ }
+
+ public int getMaxSize() {
+ return maxSize;
+ }
+
+ /**
+ * Get the oldest (first) element in the buffer. The oldest element is removed
+ * from the buffer.
+ */
+ public E get() {
+ E r = null;
+ if (numElems > 0) {
+ numElems--;
+ r = ea[first];
+ ea[first] = null;
+ if (++first == maxSize)
first = 0;
- last = 0;
- numElems = 0;
}
-
- /**
- * Clears the buffer and resets all attributes.
- */
- public void clear() {
- init(this.maxSize);
+ return r;
+ }
+
+ public List<E> asList() {
+ List<E> tList = new ArrayList<E>();
+ for(int i = 0; i < length(); i++) {
+ tList.add(get(i));
}
-
- /**
- * Add an <code>event</code> as the last event in the buffer.
- *
- */
- public void add(E event) {
- ea[last] = event;
- if (++last == maxSize)
- last = 0;
-
- if (numElems < maxSize)
- numElems++;
- else if (++first == maxSize)
- first = 0;
+ return tList;
+ }
+
+ /**
+ * Get the number of elements in the buffer. This number is guaranteed to be
+ * in the range 0 to <code>maxSize</code> (inclusive).
+ */
+ public int length() {
+ return numElems;
+ }
+
+ /**
+ * Resize the cyclic buffer to <code>newSize</code>.
+ *
+ * @throws IllegalArgumentException
+ * if <code>newSize</code> is negative.
+ */
+ @SuppressWarnings("unchecked")
+ public void resize(int newSize) {
+ if (newSize < 0) {
+ throw new IllegalArgumentException("Negative array size [" + newSize
+ + "] not allowed.");
}
+ if (newSize == numElems)
+ return; // nothing to do
- /**
- * Get the <i>i</i>th oldest event currently in the buffer. If <em>i</em>
- * is outside the range 0 to the number of elements currently in the buffer,
- * then <code>null</code> is returned.
- */
- public E get(int i) {
- if (i < 0 || i >= numElems)
- return null;
-
- return ea[(first + i) % maxSize];
- }
+ //
+ E[] temp = (E[]) new Object[newSize];
- public int getMaxSize() {
- return maxSize;
- }
+ int loopLen = newSize < numElems ? newSize : numElems;
- /**
- * Get the oldest (first) element in the buffer. The oldest element is removed
- * from the buffer.
- */
- public E get() {
- E r = null;
- if (numElems > 0) {
- numElems--;
- r = ea[first];
- ea[first] = null;
- if (++first == maxSize)
- first = 0;
- }
- return r;
- }
-
- public List<E> asList() {
- List<E> tList = new ArrayList<E>();
- for (int i = 0; i < length(); i++) {
- tList.add(get(i));
- }
- return tList;
- }
-
- /**
- * Get the number of elements in the buffer. This number is guaranteed to be
- * in the range 0 to <code>maxSize</code> (inclusive).
- */
- public int length() {
- return numElems;
- }
-
- /**
- * Resize the cyclic buffer to <code>newSize</code>.
- *
- * @throws IllegalArgumentException
- * if <code>newSize</code> is negative.
- */
- @SuppressWarnings("unchecked")
- public void resize(int newSize) {
- if (newSize < 0) {
- throw new IllegalArgumentException("Negative array size [" + newSize + "] not allowed.");
- }
- if (newSize == numElems)
- return; // nothing to do
-
- //
- E[] temp = (E[]) new Object[newSize];
-
- int loopLen = newSize < numElems ? newSize : numElems;
-
- for (int i = 0; i < loopLen; i++) {
- temp[i] = ea[first];
- ea[first] = null;
- if (++first == numElems)
- first = 0;
- }
- ea = temp;
+ for (int i = 0; i < loopLen; i++) {
+ temp[i] = ea[first];
+ ea[first] = null;
+ if (++first == numElems)
first = 0;
- numElems = loopLen;
- maxSize = newSize;
- if (loopLen == newSize) {
- last = 0;
- } else {
- last = loopLen;
- }
}
+ ea = temp;
+ first = 0;
+ numElems = loopLen;
+ maxSize = newSize;
+ if (loopLen == newSize) {
+ last = 0;
+ } else {
+ last = loopLen;
+ }
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/helpers/NOPAppender.java b/logback-core/src/main/java/ch/qos/logback/core/helpers/NOPAppender.java
index 578b851..49911d3 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/helpers/NOPAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/helpers/NOPAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,7 +17,7 @@ import ch.qos.logback.core.AppenderBase;
final public class NOPAppender<E> extends AppenderBase<E> {
- @Override
- protected void append(E eventObject) {
- }
+ @Override
+ protected void append(E eventObject) {
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/helpers/ThrowableToStringArray.java b/logback-core/src/main/java/ch/qos/logback/core/helpers/ThrowableToStringArray.java
index c511603..876d2bb 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/helpers/ThrowableToStringArray.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/helpers/ThrowableToStringArray.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,64 +20,67 @@ import ch.qos.logback.core.CoreConstants;
public class ThrowableToStringArray {
- public static String[] convert(Throwable t) {
- List<String> strList = new LinkedList<String>();
- extract(strList, t, null);
- return strList.toArray(new String[0]);
+ public static String[] convert(Throwable t) {
+ List<String> strList = new LinkedList<String>();
+ extract(strList, t, null);
+ return strList.toArray(new String[0]);
- }
+ }
- private static void extract(List<String> strList, Throwable t, StackTraceElement[] parentSTE) {
+ private static void extract(List<String> strList, Throwable t,
+ StackTraceElement[] parentSTE) {
- StackTraceElement[] ste = t.getStackTrace();
- final int numberOfcommonFrames = findNumberOfCommonFrames(ste, parentSTE);
+ StackTraceElement[] ste = t.getStackTrace();
+ final int numberOfcommonFrames = findNumberOfCommonFrames(ste, parentSTE);
- strList.add(formatFirstLine(t, parentSTE));
- for (int i = 0; i < (ste.length - numberOfcommonFrames); i++) {
- strList.add("\tat " + ste[i].toString());
- }
+ strList.add(formatFirstLine(t, parentSTE));
+ for (int i = 0; i < (ste.length - numberOfcommonFrames); i++) {
+ strList.add("\tat "+ste[i].toString());
+ }
- if (numberOfcommonFrames != 0) {
- strList.add("\t... " + numberOfcommonFrames + " common frames omitted");
- }
+ if (numberOfcommonFrames != 0) {
+ strList.add("\t... "+numberOfcommonFrames + " common frames omitted");
+ }
- Throwable cause = t.getCause();
- if (cause != null) {
- ThrowableToStringArray.extract(strList, cause, ste);
- }
+ Throwable cause = t.getCause();
+ if (cause != null) {
+ ThrowableToStringArray.extract(strList, cause, ste);
}
+ }
- private static String formatFirstLine(Throwable t, StackTraceElement[] parentSTE) {
- String prefix = "";
- if (parentSTE != null) {
- prefix = CoreConstants.CAUSED_BY;
- }
+ private static String formatFirstLine(Throwable t,
+ StackTraceElement[] parentSTE) {
+ String prefix = "";
+ if (parentSTE != null) {
+ prefix = CoreConstants.CAUSED_BY;
+ }
- String result = prefix + t.getClass().getName();
- if (t.getMessage() != null) {
- result += ": " + t.getMessage();
- }
- return result;
+ String result = prefix + t.getClass().getName();
+ if (t.getMessage() != null) {
+ result += ": " + t.getMessage();
}
+ return result;
+ }
- private static int findNumberOfCommonFrames(StackTraceElement[] ste, StackTraceElement[] parentSTE) {
- if (parentSTE == null) {
- return 0;
- }
+ private static int findNumberOfCommonFrames(StackTraceElement[] ste,
+ StackTraceElement[] parentSTE) {
+ if (parentSTE == null) {
+ return 0;
+ }
- int steIndex = ste.length - 1;
- int parentIndex = parentSTE.length - 1;
- int count = 0;
- while (steIndex >= 0 && parentIndex >= 0) {
- if (ste[steIndex].equals(parentSTE[parentIndex])) {
- count++;
- } else {
- break;
- }
- steIndex--;
- parentIndex--;
- }
- return count;
+ int steIndex = ste.length - 1;
+ int parentIndex = parentSTE.length - 1;
+ int count = 0;
+ while (steIndex >= 0 && parentIndex >= 0) {
+ if (ste[steIndex].equals(parentSTE[parentIndex])) {
+ count++;
+ } else {
+ break;
+ }
+ steIndex--;
+ parentIndex--;
}
+ return count;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/helpers/Transform.java b/logback-core/src/main/java/ch/qos/logback/core/helpers/Transform.java
index 8d9deb9..fb29a4b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/helpers/Transform.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/helpers/Transform.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,8 +13,6 @@
*/
package ch.qos.logback.core.helpers;
-import java.util.regex.Pattern;
-
/**
* Utility class for transforming strings.
*
@@ -22,110 +20,91 @@ import java.util.regex.Pattern;
* @author Michael A. McAngus
*/
public class Transform {
- private static final String CDATA_START = "<![CDATA[";
- private static final String CDATA_END = "]]>";
- private static final String CDATA_PSEUDO_END = "]]>";
- private static final String CDATA_EMBEDED_END = CDATA_END + CDATA_PSEUDO_END + CDATA_START;
- private static final int CDATA_END_LEN = CDATA_END.length();
- private static final Pattern UNSAFE_XML_CHARS = Pattern.compile("[\u0000-\u0008\u000b\u000c\u000e-\u001f<>&'\"]");
+ private static final String CDATA_START = "<![CDATA[";
+ private static final String CDATA_END = "]]>";
+ private static final String CDATA_PSEUDO_END = "]]>";
+ private static final String CDATA_EMBEDED_END = CDATA_END + CDATA_PSEUDO_END
+ + CDATA_START;
+ private static final int CDATA_END_LEN = CDATA_END.length();
- /**
- * This method takes a string which may contain HTML tags (ie, <b>,
- * <table>, etc) and replaces any '<','>' ... characters with
- * respective predefined entity references.
- *
- * @param input
- * The text to be converted.
- */
- public static String escapeTags(final String input) {
- if (input == null || input.length() == 0 || !UNSAFE_XML_CHARS.matcher(input).find()) {
- return input;
- }
- StringBuffer buf = new StringBuffer(input);
- return escapeTags(buf);
+ /**
+ * This method takes a string which may contain HTML tags (ie, <b>,
+ * <table>, etc) and replaces any '<' and '>' characters with
+ * respective predefined entity references.
+ *
+ * @param input
+ * The text to be converted.
+ */
+ public static String escapeTags(final String input) {
+ // if input is null or zero length or contains no < and > characters, return it as is
+ if ((input == null) || (input.length() == 0)
+ || (input.indexOf("<") == -1 && input.indexOf(">") == -1)) {
+ return input;
}
- /**
- * This method takes a StringBuilder which may contain HTML tags (ie, <b>,
- * <table>, etc) and replaces any '<' and '>' characters with
- * respective predefined entity references.
- * @param buf StringBuffer to transform
- * @return
- */
- public static String escapeTags(final StringBuffer buf) {
- for (int i = 0; i < buf.length(); i++) {
- char ch = buf.charAt(i);
- switch (ch) {
- case '\t':
- case '\n':
- case '\r':
- // These characters are below '\u0020' but are allowed:
- break;
- case '&':
- buf.replace(i, i + 1, "&");
- break;
- case '<':
- buf.replace(i, i + 1, "<");
- break;
- case '>':
- buf.replace(i, i + 1, ">");
- break;
- case '"':
- buf.replace(i, i + 1, """);
- break;
- case '\'':
- buf.replace(i, i + 1, "'");
- break;
- default:
- if (ch < '\u0020') {
- // These characters are not allowed,
- // replace them with "Object replacement character":
- buf.replace(i, i + 1, "\uFFFD");
- }
- break;
- }
- }
- return buf.toString();
- }
+ StringBuffer buf = new StringBuffer(input);
+ return escapeTags(buf);
+ }
+
- /**
- * Ensures that embedded CDEnd strings (]]>) are handled properly within
- * message, NDC and throwable tag text.
- *
- * @param output
- * Writer. The initial CDSutart (<![CDATA[) and final CDEnd (]]>) of
- * the CDATA section are the responsibility of the calling method.
- *
- * @param str
- * The String that is inserted into an existing CDATA Section.
- */
- public static void appendEscapingCDATA(StringBuilder output, String str) {
- if (str == null) {
- return;
- }
+ /**
+ * This method takes a StringBuilder which may contain HTML tags (ie, <b>,
+ * <table>, etc) and replaces any '<' and '>' characters with
+ * respective predefined entity references.
+ * @param buf StringBuffer to transform
+ * @return
+ */
+ public static String escapeTags(final StringBuffer buf) {
+ for (int i = 0; i < buf.length(); i++) {
+ char ch = buf.charAt(i);
+ if (ch == '<') {
+ buf.replace(i, i + 1, "<");
+ } else if (ch == '>') {
+ buf.replace(i, i + 1, ">");
+ }
+ }
+ return buf.toString();
+ }
+
- int end = str.indexOf(CDATA_END);
+ /**
+ * Ensures that embedded CDEnd strings (]]>) are handled properly within
+ * message, NDC and throwable tag text.
+ *
+ * @param output
+ * Writer. The initial CDSutart (<![CDATA[) and final CDEnd (]]>) of
+ * the CDATA section are the responsibility of the calling method.
+ *
+ * @param str
+ * The String that is inserted into an existing CDATA Section.
+ */
+ public static void appendEscapingCDATA(StringBuilder output, String str) {
+ if (str == null) {
+ return;
+ }
- if (end < 0) {
- output.append(str);
+ int end = str.indexOf(CDATA_END);
- return;
- }
+ if (end < 0) {
+ output.append(str);
- int start = 0;
+ return;
+ }
- while (end > -1) {
- output.append(str.substring(start, end));
- output.append(CDATA_EMBEDED_END);
- start = end + CDATA_END_LEN;
+ int start = 0;
- if (start < str.length()) {
- end = str.indexOf(CDATA_END, start);
- } else {
- return;
- }
- }
+ while (end > -1) {
+ output.append(str.substring(start, end));
+ output.append(CDATA_EMBEDED_END);
+ start = end + CDATA_END_LEN;
- output.append(str.substring(start));
+ if (start < str.length()) {
+ end = str.indexOf(CDATA_END, start);
+ } else {
+ return;
+ }
}
+
+ output.append(str.substring(start));
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/hook/DelayingShutdownHook.java b/logback-core/src/main/java/ch/qos/logback/core/hook/DelayingShutdownHook.java
deleted file mode 100644
index 2d0cc94..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/hook/DelayingShutdownHook.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.hook;
-
-import ch.qos.logback.core.util.Duration;
-
-/**
- * ShutdownHook implementation that stops the Logback context after a specified
- * delay. The default delay is 0 ms (zero).
- *
- * @author Mike Reinhold
- */
-public class DelayingShutdownHook extends ShutdownHookBase {
- /**
- * The default is no delay before shutdown.
- */
- public static final Duration DEFAULT_DELAY = Duration.buildByMilliseconds(0);
-
- /**
- * The delay in milliseconds before the ShutdownHook stops the logback context
- */
- private Duration delay = DEFAULT_DELAY;
-
- public DelayingShutdownHook() {
- }
-
- public Duration getDelay() {
- return delay;
- }
-
- /**
- * The duration to wait before shutting down the current logback context.
- *
- * @param delay
- */
- public void setDelay(Duration delay) {
- this.delay = delay;
- }
-
- public void run() {
- addInfo("Sleeping for "+delay);
- try {
- Thread.sleep(delay.getMilliseconds());
- } catch (InterruptedException e) {
- }
- super.stop();
- }
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/hook/ShutdownHook.java b/logback-core/src/main/java/ch/qos/logback/core/hook/ShutdownHook.java
deleted file mode 100644
index 9aa6a35..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/hook/ShutdownHook.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.hook;
-
-import ch.qos.logback.core.spi.ContextAware;
-
-/**
- * Interface describing a logback shutdown hook implementation
- *
- * @author Mike Reinhold
- */
-public interface ShutdownHook extends Runnable, ContextAware {
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/hook/ShutdownHookBase.java b/logback-core/src/main/java/ch/qos/logback/core/hook/ShutdownHookBase.java
deleted file mode 100644
index d04fe2a..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/hook/ShutdownHookBase.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.hook;
-
-import ch.qos.logback.core.Context;
-import ch.qos.logback.core.ContextBase;
-import ch.qos.logback.core.spi.ContextAwareBase;
-
-/**
- * Base class for classes implementing a Logback ShutdownHook via extension
- *
- * @author Mike Reinhold
- */
-public abstract class ShutdownHookBase extends ContextAwareBase implements ShutdownHook {
-
- public ShutdownHookBase() {
- }
-
- /**
- * Default method for stopping the Logback context
- */
- protected void stop() {
- addInfo("Logback context being closed via shutdown hook");
-
- Context hookContext = getContext();
- if (hookContext instanceof ContextBase) {
- ContextBase context = (ContextBase) hookContext;
- context.stop();
- }
- }
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/hook/package.html b/logback-core/src/main/java/ch/qos/logback/core/hook/package.html
deleted file mode 100644
index 4b858d8..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/hook/package.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-
-<html>
-<head>
-<title></title>
-</head>
-
-<body>
-
-<p>Contains the shutdown hook functionality of logback,
-including the interface and base class for implementing
-hooks as well as some default implementations, such as
- at link{ch.qos.logback.core.hook.DelayingShutdownHook}
-</p>
-
-</body>
-</html>
diff --git a/logback-core/src/main/java/ch/qos/logback/core/html/CssBuilder.java b/logback-core/src/main/java/ch/qos/logback/core/html/CssBuilder.java
index 3b395df..4fb759d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/html/CssBuilder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/html/CssBuilder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,6 +15,6 @@ package ch.qos.logback.core.html;
public interface CssBuilder {
- void addCss(StringBuilder sbuf);
-
+ void addCss(StringBuilder sbuf);
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/html/HTMLLayoutBase.java b/logback-core/src/main/java/ch/qos/logback/core/html/HTMLLayoutBase.java
index 87c8fa7..90c2ceb 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/html/HTMLLayoutBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/html/HTMLLayoutBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -35,225 +35,228 @@ import ch.qos.logback.core.spi.ScanException;
*/
public abstract class HTMLLayoutBase<E> extends LayoutBase<E> {
- protected String pattern;
-
- protected Converter<E> head;
-
- protected String title = "Logback Log Messages";
-
- // It is the responsibility of derived classes to set
- // this variable in their constructor to a default value.
- protected CssBuilder cssBuilder;
-
- // counter keeping track of the rows output
- protected long counter = 0;
-
- /**
- * Set the <b>ConversionPattern </b> option. This is the string which controls
- * formatting and consists of a mix of literal content and conversion
- * specifiers.
- */
- public void setPattern(String conversionPattern) {
- pattern = conversionPattern;
+ protected String pattern;
+
+ protected Converter<E> head;
+
+ protected String title = "Logback Log Messages";
+
+ //It is the responsibility of derived classes to set
+ //this variable in their constructor to a default value.
+ protected CssBuilder cssBuilder;
+
+ // counter keeping track of the rows output
+ protected long counter = 0;
+
+ /**
+ * Set the <b>ConversionPattern </b> option. This is the string which controls
+ * formatting and consists of a mix of literal content and conversion
+ * specifiers.
+ */
+ public void setPattern(String conversionPattern) {
+ pattern = conversionPattern;
+ }
+
+ /**
+ * Returns the value of the <b>ConversionPattern </b> option.
+ */
+ public String getPattern() {
+ return pattern;
+ }
+
+ public CssBuilder getCssBuilder() {
+ return cssBuilder;
+ }
+
+ public void setCssBuilder(CssBuilder cssBuilder) {
+ this.cssBuilder = cssBuilder;
+ }
+
+ /**
+ * Parses the pattern and creates the Converter linked list.
+ */
+ @Override
+ public void start() {
+ int errorCount = 0;
+
+ try {
+ Parser<E> p = new Parser<E>(pattern);
+ p.setContext(getContext());
+ Node t = p.parse();
+ this.head = p.compile(t, getEffectiveConverterMap());
+ ConverterUtil.startConverters(this.head);
+ } catch (ScanException ex) {
+ addError("Incorrect pattern found", ex);
+ errorCount++;
}
- /**
- * Returns the value of the <b>ConversionPattern </b> option.
- */
- public String getPattern() {
- return pattern;
+ if (errorCount == 0) {
+ super.started = true;
}
-
- public CssBuilder getCssBuilder() {
- return cssBuilder;
+ }
+
+ protected abstract Map<String, String> getDefaultConverterMap();
+
+
+ /**
+ * Returns a map where the default converter map is merged with the map
+ * contained in the context.
+ */
+ public Map<String, String> getEffectiveConverterMap() {
+ Map<String, String> effectiveMap = new HashMap<String, String>();
+
+ // add the least specific map fist
+ Map<String, String> defaultMap = getDefaultConverterMap();
+ if (defaultMap != null) {
+ effectiveMap.putAll(defaultMap);
}
- public void setCssBuilder(CssBuilder cssBuilder) {
- this.cssBuilder = cssBuilder;
+ // contextMap is more specific than the default map
+ Context context = getContext();
+ if (context != null) {
+ @SuppressWarnings("unchecked")
+ Map<String, String> contextMap = (Map<String, String>) context
+ .getObject(CoreConstants.PATTERN_RULE_REGISTRY);
+ if (contextMap != null) {
+ effectiveMap.putAll(contextMap);
+ }
}
-
- /**
- * Parses the pattern and creates the Converter linked list.
- */
- @Override
- public void start() {
- int errorCount = 0;
-
- try {
- Parser<E> p = new Parser<E>(pattern);
- p.setContext(getContext());
- Node t = p.parse();
- this.head = p.compile(t, getEffectiveConverterMap());
- ConverterUtil.startConverters(this.head);
- } catch (ScanException ex) {
- addError("Incorrect pattern found", ex);
- errorCount++;
- }
-
- if (errorCount == 0) {
- super.started = true;
- }
+ return effectiveMap;
+ }
+
+ /**
+ * The <b>Title </b> option takes a String value. This option sets the
+ * document title of the generated HTML document.
+ *
+ * <p>
+ * Defaults to 'Logback Log Messages'.
+ */
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ /**
+ * Returns the current value of the <b>Title </b> option.
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * Returns the content type output by this layout, i.e "text/html".
+ */
+ @Override
+ public String getContentType() {
+ return "text/html";
+ }
+
+ /**
+ * Returns appropriate HTML headers.
+ */
+ @Override
+ public String getFileHeader() {
+ StringBuilder sbuf = new StringBuilder();
+ sbuf.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"");
+ sbuf.append(" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append("<html>");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append(" <head>");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append(" <title>");
+ sbuf.append(title);
+ sbuf.append("</title>");
+ sbuf.append(LINE_SEPARATOR);
+
+ cssBuilder.addCss(sbuf);
+
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append(" </head>");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append("<body>");
+ sbuf.append(LINE_SEPARATOR);
+
+ return sbuf.toString();
+ }
+
+ public String getPresentationHeader() {
+ StringBuilder sbuf = new StringBuilder();
+ sbuf.append("<hr/>");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append("<p>Log session start time ");
+ sbuf.append(new java.util.Date());
+ sbuf.append("</p><p></p>");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append("<table cellspacing=\"0\">");
+ sbuf.append(LINE_SEPARATOR);
+
+ buildHeaderRowForTable(sbuf);
+
+ return sbuf.toString();
+ }
+
+
+ private void buildHeaderRowForTable(StringBuilder sbuf) {
+ Converter c = head;
+ String name;
+ sbuf.append("<tr class=\"header\">");
+ sbuf.append(LINE_SEPARATOR);
+ while (c != null) {
+ name = computeConverterName(c);
+ if (name == null) {
+ c = c.getNext();
+ continue;
+ }
+ sbuf.append("<td class=\"");
+ sbuf.append(computeConverterName(c));
+ sbuf.append("\">");
+ sbuf.append(computeConverterName(c));
+ sbuf.append("</td>");
+ sbuf.append(LINE_SEPARATOR);
+ c = c.getNext();
}
-
- protected abstract Map<String, String> getDefaultConverterMap();
-
- /**
- * Returns a map where the default converter map is merged with the map
- * contained in the context.
- */
- public Map<String, String> getEffectiveConverterMap() {
- Map<String, String> effectiveMap = new HashMap<String, String>();
-
- // add the least specific map fist
- Map<String, String> defaultMap = getDefaultConverterMap();
- if (defaultMap != null) {
- effectiveMap.putAll(defaultMap);
- }
-
- // contextMap is more specific than the default map
- Context context = getContext();
- if (context != null) {
- @SuppressWarnings("unchecked")
- Map<String, String> contextMap = (Map<String, String>) context.getObject(CoreConstants.PATTERN_RULE_REGISTRY);
- if (contextMap != null) {
- effectiveMap.putAll(contextMap);
- }
- }
- return effectiveMap;
- }
-
- /**
- * The <b>Title </b> option takes a String value. This option sets the
- * document title of the generated HTML document.
- *
- * <p>
- * Defaults to 'Logback Log Messages'.
- */
- public void setTitle(String title) {
- this.title = title;
- }
-
- /**
- * Returns the current value of the <b>Title </b> option.
- */
- public String getTitle() {
- return title;
- }
-
- /**
- * Returns the content type output by this layout, i.e "text/html".
- */
- @Override
- public String getContentType() {
- return "text/html";
+ sbuf.append("</tr>");
+ sbuf.append(LINE_SEPARATOR);
+ }
+
+ public String getPresentationFooter() {
+ StringBuilder sbuf = new StringBuilder();
+ sbuf.append("</table>");
+ return sbuf.toString();
+ }
+
+ /**
+ * Returns the appropriate HTML footers.
+ */
+ @Override
+ public String getFileFooter() {
+ StringBuilder sbuf = new StringBuilder();
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append("</body></html>");
+ return sbuf.toString();
+ }
+
+ protected void startNewTableIfLimitReached(StringBuilder sbuf) {
+ if (this.counter >= CoreConstants.TABLE_ROW_LIMIT) {
+ counter = 0;
+ sbuf.append("</table>");
+ sbuf.append(LINE_SEPARATOR);
+ sbuf.append("<p></p>");
+ sbuf.append("<table cellspacing=\"0\">");
+ sbuf.append(LINE_SEPARATOR);
+ buildHeaderRowForTable(sbuf);
}
-
- /**
- * Returns appropriate HTML headers.
- */
- @Override
- public String getFileHeader() {
- StringBuilder sbuf = new StringBuilder();
- sbuf.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"");
- sbuf.append(" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("<html>");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append(" <head>");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append(" <title>");
- sbuf.append(title);
- sbuf.append("</title>");
- sbuf.append(LINE_SEPARATOR);
-
- cssBuilder.addCss(sbuf);
-
- sbuf.append(LINE_SEPARATOR);
- sbuf.append(" </head>");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("<body>");
- sbuf.append(LINE_SEPARATOR);
-
- return sbuf.toString();
- }
-
- public String getPresentationHeader() {
- StringBuilder sbuf = new StringBuilder();
- sbuf.append("<hr/>");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("<p>Log session start time ");
- sbuf.append(new java.util.Date());
- sbuf.append("</p><p></p>");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("<table cellspacing=\"0\">");
- sbuf.append(LINE_SEPARATOR);
-
- buildHeaderRowForTable(sbuf);
-
- return sbuf.toString();
- }
-
- private void buildHeaderRowForTable(StringBuilder sbuf) {
- Converter c = head;
- String name;
- sbuf.append("<tr class=\"header\">");
- sbuf.append(LINE_SEPARATOR);
- while (c != null) {
- name = computeConverterName(c);
- if (name == null) {
- c = c.getNext();
- continue;
- }
- sbuf.append("<td class=\"");
- sbuf.append(computeConverterName(c));
- sbuf.append("\">");
- sbuf.append(computeConverterName(c));
- sbuf.append("</td>");
- sbuf.append(LINE_SEPARATOR);
- c = c.getNext();
- }
- sbuf.append("</tr>");
- sbuf.append(LINE_SEPARATOR);
- }
-
- public String getPresentationFooter() {
- StringBuilder sbuf = new StringBuilder();
- sbuf.append("</table>");
- return sbuf.toString();
- }
-
- /**
- * Returns the appropriate HTML footers.
- */
- @Override
- public String getFileFooter() {
- StringBuilder sbuf = new StringBuilder();
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("</body></html>");
- return sbuf.toString();
- }
-
- protected void startNewTableIfLimitReached(StringBuilder sbuf) {
- if (this.counter >= CoreConstants.TABLE_ROW_LIMIT) {
- counter = 0;
- sbuf.append("</table>");
- sbuf.append(LINE_SEPARATOR);
- sbuf.append("<p></p>");
- sbuf.append("<table cellspacing=\"0\">");
- sbuf.append(LINE_SEPARATOR);
- buildHeaderRowForTable(sbuf);
- }
- }
-
- protected String computeConverterName(Converter c) {
- String className = c.getClass().getSimpleName();
- int index = className.indexOf("Converter");
- if (index == -1) {
- return className;
- } else {
- return className.substring(0, index);
- }
+ }
+
+ protected String computeConverterName(Converter c) {
+ String className = c.getClass().getSimpleName();
+ int index = className.indexOf("Converter");
+ if (index == -1) {
+ return className;
+ } else {
+ return className.substring(0, index);
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/html/IThrowableRenderer.java b/logback-core/src/main/java/ch/qos/logback/core/html/IThrowableRenderer.java
index a539f33..1c14341 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/html/IThrowableRenderer.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/html/IThrowableRenderer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,8 +13,9 @@
*/
package ch.qos.logback.core.html;
-public interface IThrowableRenderer<E> {
-
- void render(StringBuilder sbuf, E event);
+public interface IThrowableRenderer<E> {
+
+ void render(StringBuilder sbuf, E event);
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/html/NOPThrowableRenderer.java b/logback-core/src/main/java/ch/qos/logback/core/html/NOPThrowableRenderer.java
index a8f9224..4fc48db 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/html/NOPThrowableRenderer.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/html/NOPThrowableRenderer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,10 +15,11 @@ package ch.qos.logback.core.html;
import ch.qos.logback.core.html.IThrowableRenderer;
+
public class NOPThrowableRenderer implements IThrowableRenderer {
- public void render(StringBuilder sbuf, Object event) {
- return;
- }
+ public void render(StringBuilder sbuf, Object event) {
+ return;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java b/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
index 4b98e77..7c78774 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,10 +18,8 @@ import ch.qos.logback.core.joran.event.SaxEvent;
import ch.qos.logback.core.joran.event.SaxEventRecorder;
import ch.qos.logback.core.joran.spi.*;
import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
-import ch.qos.logback.core.joran.util.beans.BeanDescriptionCache;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.status.StatusUtil;
-
import org.xml.sax.InputSource;
import java.io.File;
@@ -36,144 +34,136 @@ import static ch.qos.logback.core.CoreConstants.SAFE_JORAN_CONFIGURATION;
public abstract class GenericConfigurator extends ContextAwareBase {
- private BeanDescriptionCache beanDescriptionCache;
-
- protected Interpreter interpreter;
-
- public final void doConfigure(URL url) throws JoranException {
- InputStream in = null;
+ protected Interpreter interpreter;
+
+ public final void doConfigure(URL url) throws JoranException {
+ InputStream in = null;
+ try {
+ informContextOfURLUsedForConfiguration(getContext(), url);
+ URLConnection urlConnection = url.openConnection();
+ // per http://jira.qos.ch/browse/LBCORE-105
+ // per http://jira.qos.ch/browse/LBCORE-127
+ urlConnection.setUseCaches(false);
+
+ in = urlConnection.getInputStream();
+ doConfigure(in);
+ } catch (IOException ioe) {
+ String errMsg = "Could not open URL [" + url + "].";
+ addError(errMsg, ioe);
+ throw new JoranException(errMsg, ioe);
+ } finally {
+ if (in != null) {
try {
- informContextOfURLUsedForConfiguration(getContext(), url);
- URLConnection urlConnection = url.openConnection();
- // per http://jira.qos.ch/browse/LBCORE-105
- // per http://jira.qos.ch/browse/LBCORE-127
- urlConnection.setUseCaches(false);
-
- in = urlConnection.getInputStream();
- doConfigure(in);
+ in.close();
} catch (IOException ioe) {
- String errMsg = "Could not open URL [" + url + "].";
- addError(errMsg, ioe);
- throw new JoranException(errMsg, ioe);
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (IOException ioe) {
- String errMsg = "Could not close input stream";
- addError(errMsg, ioe);
- throw new JoranException(errMsg, ioe);
- }
- }
+ String errMsg = "Could not close input stream";
+ addError(errMsg, ioe);
+ throw new JoranException(errMsg, ioe);
}
+ }
}
-
- public final void doConfigure(String filename) throws JoranException {
- doConfigure(new File(filename));
- }
-
- public final void doConfigure(File file) throws JoranException {
- FileInputStream fis = null;
+ }
+
+ public final void doConfigure(String filename) throws JoranException {
+ doConfigure(new File(filename));
+ }
+
+ public final void doConfigure(File file) throws JoranException {
+ FileInputStream fis = null;
+ try {
+ informContextOfURLUsedForConfiguration(getContext(), file.toURI().toURL());
+ fis = new FileInputStream(file);
+ doConfigure(fis);
+ } catch (IOException ioe) {
+ String errMsg = "Could not open [" + file.getPath() + "].";
+ addError(errMsg, ioe);
+ throw new JoranException(errMsg, ioe);
+ } finally {
+ if (fis != null) {
try {
- informContextOfURLUsedForConfiguration(getContext(), file.toURI().toURL());
- fis = new FileInputStream(file);
- doConfigure(fis);
- } catch (IOException ioe) {
- String errMsg = "Could not open [" + file.getPath() + "].";
- addError(errMsg, ioe);
- throw new JoranException(errMsg, ioe);
- } finally {
- if (fis != null) {
- try {
- fis.close();
- } catch (java.io.IOException ioe) {
- String errMsg = "Could not close [" + file.getName() + "].";
- addError(errMsg, ioe);
- throw new JoranException(errMsg, ioe);
- }
- }
+ fis.close();
+ } catch (java.io.IOException ioe) {
+ String errMsg = "Could not close [" + file.getName() + "].";
+ addError(errMsg, ioe);
+ throw new JoranException(errMsg, ioe);
}
+ }
}
+ }
- public static void informContextOfURLUsedForConfiguration(Context context, URL url) {
- ConfigurationWatchListUtil.setMainWatchURL(context, url);
- }
-
- public final void doConfigure(InputStream inputStream) throws JoranException {
- doConfigure(new InputSource(inputStream));
- }
+ public static void informContextOfURLUsedForConfiguration(Context context, URL url) {
+ ConfigurationWatchListUtil.setMainWatchURL(context, url);
+ }
- protected BeanDescriptionCache getBeanDescriptionCache() {
- if (beanDescriptionCache == null) {
- beanDescriptionCache = new BeanDescriptionCache(getContext());
- }
- return beanDescriptionCache;
- }
+ public final void doConfigure(InputStream inputStream) throws JoranException {
+ doConfigure(new InputSource(inputStream));
+ }
- protected abstract void addInstanceRules(RuleStore rs);
+ protected abstract void addInstanceRules(RuleStore rs);
- protected abstract void addImplicitRules(Interpreter interpreter);
+ protected abstract void addImplicitRules(Interpreter interpreter);
- protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
+ protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
- }
+ }
- protected ElementPath initialElementPath() {
- return new ElementPath();
- }
+ protected ElementPath initialElementPath() {
+ return new ElementPath();
+ }
- protected void buildInterpreter() {
- RuleStore rs = new SimpleRuleStore(context);
- addInstanceRules(rs);
- this.interpreter = new Interpreter(context, rs, initialElementPath());
- InterpretationContext interpretationContext = interpreter.getInterpretationContext();
- interpretationContext.setContext(context);
- addImplicitRules(interpreter);
- addDefaultNestedComponentRegistryRules(interpretationContext.getDefaultNestedComponentRegistry());
- }
+ protected void buildInterpreter() {
+ RuleStore rs = new SimpleRuleStore(context);
+ addInstanceRules(rs);
+ this.interpreter = new Interpreter(context, rs, initialElementPath());
+ InterpretationContext interpretationContext = interpreter.getInterpretationContext();
+ interpretationContext.setContext(context);
+ addImplicitRules(interpreter);
+ addDefaultNestedComponentRegistryRules(interpretationContext.getDefaultNestedComponentRegistry());
+ }
- // this is the most inner form of doConfigure whereto other doConfigure
- // methods ultimately delegate
- public final void doConfigure(final InputSource inputSource) throws JoranException {
-
- long threshold = System.currentTimeMillis();
- // if (!ConfigurationWatchListUtil.wasConfigurationWatchListReset(context)) {
- // informContextOfURLUsedForConfiguration(getContext(), null);
- // }
- SaxEventRecorder recorder = new SaxEventRecorder(context);
- recorder.recordEvents(inputSource);
- doConfigure(recorder.saxEventList);
- // no exceptions a this level
- StatusUtil statusUtil = new StatusUtil(context);
- if (statusUtil.noXMLParsingErrorsOccurred(threshold)) {
- addInfo("Registering current configuration as safe fallback point");
- registerSafeConfiguration(recorder.saxEventList);
- }
- }
+ // this is the most inner form of doConfigure whereto other doConfigure
+ // methods ultimately delegate
+ public final void doConfigure(final InputSource inputSource)
+ throws JoranException {
- public void doConfigure(final List<SaxEvent> eventList) throws JoranException {
- buildInterpreter();
- // disallow simultaneous configurations of the same context
- synchronized (context.getConfigurationLock()) {
- interpreter.getEventPlayer().play(eventList);
- }
+ long threshold = System.currentTimeMillis();
+ if (!ConfigurationWatchListUtil.wasConfigurationWatchListReset(context)) {
+ informContextOfURLUsedForConfiguration(getContext(), null);
}
-
- /**
- * Register the current event list in currently in the interpreter as a safe
- * configuration point.
- *
- * @since 0.9.30
- */
- public void registerSafeConfiguration(List<SaxEvent> eventList) {
- context.putObject(SAFE_JORAN_CONFIGURATION, eventList);
+ SaxEventRecorder recorder = new SaxEventRecorder(context);
+ recorder.recordEvents(inputSource);
+ doConfigure(recorder.saxEventList);
+ // no exceptions a this level
+ StatusUtil statusUtil = new StatusUtil(context);
+ if (statusUtil.noXMLParsingErrorsOccurred(threshold)) {
+ addInfo("Registering current configuration as safe fallback point");
+ registerSafeConfiguration();
}
-
- /**
- * Recall the event list previously registered as a safe point.
- */
- @SuppressWarnings("unchecked")
- public List<SaxEvent> recallSafeConfiguration() {
- return (List<SaxEvent>) context.getObject(SAFE_JORAN_CONFIGURATION);
+ }
+
+ public void doConfigure(final List<SaxEvent> eventList)
+ throws JoranException {
+ buildInterpreter();
+ // disallow simultaneous configurations of the same context
+ synchronized (context.getConfigurationLock()) {
+ interpreter.getEventPlayer().play(eventList);
}
+ }
+
+ /**
+ * Register the current event list in currently in the interpreter as a safe
+ * configuration point.
+ *
+ * @since 0.9.30
+ */
+ public void registerSafeConfiguration() {
+ context.putObject(SAFE_JORAN_CONFIGURATION, interpreter.getEventPlayer().getCopyOfPlayerEventList());
+ }
+
+ /**
+ * Recall the event list previously registered as a safe point.
+ */
+ public List<SaxEvent> recallSafeConfiguration() {
+ return (List<SaxEvent>) context.getObject(SAFE_JORAN_CONFIGURATION);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java b/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java
index 76d31b8..9cc5c14 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,9 +14,9 @@
package ch.qos.logback.core.joran;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
-import ch.qos.logback.core.Appender;
import ch.qos.logback.core.joran.action.ActionConst;
import ch.qos.logback.core.joran.action.AppenderAction;
import ch.qos.logback.core.joran.action.AppenderRefAction;
@@ -28,7 +28,6 @@ import ch.qos.logback.core.joran.action.NestedComplexPropertyIA;
import ch.qos.logback.core.joran.action.NewRuleAction;
import ch.qos.logback.core.joran.action.ParamAction;
import ch.qos.logback.core.joran.action.PropertyAction;
-import ch.qos.logback.core.joran.action.ShutdownHookAction;
import ch.qos.logback.core.joran.action.StatusListenerAction;
import ch.qos.logback.core.joran.action.TimestampAction;
import ch.qos.logback.core.joran.spi.ElementSelector;
@@ -46,59 +45,69 @@ import ch.qos.logback.core.joran.spi.RuleStore;
* <p>
* A JoranConfiguratorBase instance should not be used more than once to
* configure a Context.
- *
+ *
* @author Ceki Gülcü
*/
-abstract public class JoranConfiguratorBase<E> extends GenericConfigurator {
-
- @Override
- protected void addInstanceRules(RuleStore rs) {
-
- // is "configuration/variable" referenced in the docs?
- rs.addRule(new ElementSelector("configuration/variable"), new PropertyAction());
- rs.addRule(new ElementSelector("configuration/property"), new PropertyAction());
-
- rs.addRule(new ElementSelector("configuration/substitutionProperty"), new PropertyAction());
-
- rs.addRule(new ElementSelector("configuration/timestamp"), new TimestampAction());
- rs.addRule(new ElementSelector("configuration/shutdownHook"), new ShutdownHookAction());
- rs.addRule(new ElementSelector("configuration/define"), new DefinePropertyAction());
-
- // the contextProperty pattern is deprecated. It is undocumented
- // and will be dropped in future versions of logback
- rs.addRule(new ElementSelector("configuration/contextProperty"), new ContextPropertyAction());
-
- rs.addRule(new ElementSelector("configuration/conversionRule"), new ConversionRuleAction());
-
- rs.addRule(new ElementSelector("configuration/statusListener"), new StatusListenerAction());
-
- rs.addRule(new ElementSelector("configuration/appender"), new AppenderAction<E>());
- rs.addRule(new ElementSelector("configuration/appender/appender-ref"), new AppenderRefAction<E>());
- rs.addRule(new ElementSelector("configuration/newRule"), new NewRuleAction());
- rs.addRule(new ElementSelector("*/param"), new ParamAction(getBeanDescriptionCache()));
- }
-
- @Override
- protected void addImplicitRules(Interpreter interpreter) {
- // The following line adds the capability to parse nested components
- NestedComplexPropertyIA nestedComplexPropertyIA = new NestedComplexPropertyIA(getBeanDescriptionCache());
- nestedComplexPropertyIA.setContext(context);
- interpreter.addImplicitAction(nestedComplexPropertyIA);
-
- NestedBasicPropertyIA nestedBasicIA = new NestedBasicPropertyIA(getBeanDescriptionCache());
- nestedBasicIA.setContext(context);
- interpreter.addImplicitAction(nestedBasicIA);
- }
-
- @Override
- protected void buildInterpreter() {
- super.buildInterpreter();
- Map<String, Object> omap = interpreter.getInterpretationContext().getObjectMap();
- omap.put(ActionConst.APPENDER_BAG, new HashMap<String, Appender<?>>());
- //omap.put(ActionConst.FILTER_CHAIN_BAG, new HashMap());
- }
-
- public InterpretationContext getInterpretationContext() {
- return interpreter.getInterpretationContext();
- }
+abstract public class JoranConfiguratorBase extends GenericConfigurator {
+
+ public List getErrorList() {
+ return null;
+ }
+
+ @Override
+ protected void addInstanceRules(RuleStore rs) {
+
+ // is "configuration/variable" referenced in the docs?
+ rs.addRule(new ElementSelector("configuration/variable"), new PropertyAction());
+ rs.addRule(new ElementSelector("configuration/property"), new PropertyAction());
+
+ rs.addRule(new ElementSelector("configuration/substitutionProperty"),
+ new PropertyAction());
+
+ rs.addRule(new ElementSelector("configuration/timestamp"), new TimestampAction());
+
+ rs.addRule(new ElementSelector("configuration/define"), new DefinePropertyAction());
+
+ // the contextProperty pattern is deprecated. It is undocumented
+ // and will be dropped in future versions of logback
+ rs.addRule(new ElementSelector("configuration/contextProperty"),
+ new ContextPropertyAction());
+
+ rs.addRule(new ElementSelector("configuration/conversionRule"),
+ new ConversionRuleAction());
+
+ rs.addRule(new ElementSelector("configuration/statusListener"),
+ new StatusListenerAction());
+
+ rs.addRule(new ElementSelector("configuration/appender"), new AppenderAction());
+ rs.addRule(new ElementSelector("configuration/appender/appender-ref"),
+ new AppenderRefAction());
+ rs.addRule(new ElementSelector("configuration/newRule"), new NewRuleAction());
+ rs.addRule(new ElementSelector("*/param"), new ParamAction());
+ }
+
+ @Override
+ protected void addImplicitRules(Interpreter interpreter) {
+ // The following line adds the capability to parse nested components
+ NestedComplexPropertyIA nestedComplexPropertyIA = new NestedComplexPropertyIA();
+ nestedComplexPropertyIA.setContext(context);
+ interpreter.addImplicitAction(nestedComplexPropertyIA);
+
+ NestedBasicPropertyIA nestedBasicIA = new NestedBasicPropertyIA();
+ nestedBasicIA.setContext(context);
+ interpreter.addImplicitAction(nestedBasicIA);
+ }
+
+ @Override
+ protected void buildInterpreter() {
+ super.buildInterpreter();
+ Map<String, Object> omap = interpreter.getInterpretationContext()
+ .getObjectMap();
+ omap.put(ActionConst.APPENDER_BAG, new HashMap());
+ omap.put(ActionConst.FILTER_CHAIN_BAG, new HashMap());
+ }
+
+ public InterpretationContext getInterpretationContext() {
+ return interpreter.getInterpretationContext();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/AbstractEventEvaluatorAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/AbstractEventEvaluatorAction.java
index db60cc9..817ae6f 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/AbstractEventEvaluatorAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/AbstractEventEvaluatorAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,93 +25,98 @@ import ch.qos.logback.core.util.OptionHelper;
abstract public class AbstractEventEvaluatorAction extends Action {
- EventEvaluator<?> evaluator;
- boolean inError = false;
-
- /**
- * Instantiates an evaluator of the given class and sets its name.
- */
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- // Let us forget about previous errors (in this instance)
- inError = false;
- evaluator = null;
-
- String className = attributes.getValue(CLASS_ATTRIBUTE);
- if (OptionHelper.isEmpty(className)) {
- className = defaultClassName();
- addInfo("Assuming default evaluator class [" + className + "]");
- }
+ EventEvaluator<?> evaluator;
+ boolean inError = false;
+
+ /**
+ * Instantiates an evaluator of the given class and sets its name.
+ */
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ // Let us forget about previous errors (in this instance)
+ inError = false;
+ evaluator = null;
+
+ String className = attributes.getValue(CLASS_ATTRIBUTE);
+ if (OptionHelper.isEmpty(className)) {
+ className = defaultClassName();
+ addInfo("Assuming default evaluator class [" + className + "]");
+ }
- if (OptionHelper.isEmpty(className)) {
- className = defaultClassName();
- inError = true;
- addError("Mandatory \"" + CLASS_ATTRIBUTE + "\" attribute not set for <evaluator>");
- return;
- }
+ if (OptionHelper.isEmpty(className)) {
+ className = defaultClassName();
+ inError = true;
+ addError("Mandatory \"" + CLASS_ATTRIBUTE
+ + "\" attribute not set for <evaluator>");
+ return;
+ }
- String evaluatorName = attributes.getValue(Action.NAME_ATTRIBUTE);
- if (OptionHelper.isEmpty(evaluatorName)) {
- inError = true;
- addError("Mandatory \"" + NAME_ATTRIBUTE + "\" attribute not set for <evaluator>");
- return;
- }
- try {
- evaluator = (EventEvaluator<?>) OptionHelper.instantiateByClassName(className, ch.qos.logback.core.boolex.EventEvaluator.class, context);
+ String evaluatorName = attributes.getValue(Action.NAME_ATTRIBUTE);
+ if (OptionHelper.isEmpty(evaluatorName)) {
+ inError = true;
+ addError("Mandatory \"" + NAME_ATTRIBUTE
+ + "\" attribute not set for <evaluator>");
+ return;
+ }
+ try {
+ evaluator = (EventEvaluator<?>) OptionHelper.instantiateByClassName(
+ className, ch.qos.logback.core.boolex.EventEvaluator.class, context);
- evaluator.setContext(this.context);
- evaluator.setName(evaluatorName);
+ evaluator.setContext(this.context);
+ evaluator.setName(evaluatorName);
- ec.pushObject(evaluator);
- addInfo("Adding evaluator named [" + evaluatorName + "] to the object stack");
+ ec.pushObject(evaluator);
+ addInfo("Adding evaluator named [" + evaluatorName
+ + "] to the object stack");
- } catch (Exception oops) {
- inError = true;
- addError("Could not create evaluator of type " + className + "].", oops);
- }
+ } catch (Exception oops) {
+ inError = true;
+ addError("Could not create evaluator of type " + className + "].", oops);
+ }
+ }
+
+ /**
+ * Returns a default class name in case the class attribute is not specified
+ *
+ * @return
+ */
+ abstract protected String defaultClassName();
+
+ /**
+ * Once the children elements are also parsed, now is the time to activate the
+ * evaluator options.
+ */
+ @SuppressWarnings("unchecked")
+ public void end(InterpretationContext ec, String e) {
+ if (inError) {
+ return;
}
- /**
- * Returns a default class name in case the class attribute is not specified
- *
- * @return
- */
- abstract protected String defaultClassName();
-
- /**
- * Once the children elements are also parsed, now is the time to activate the
- * evaluator options.
- */
- @SuppressWarnings("unchecked")
- public void end(InterpretationContext ec, String e) {
- if (inError) {
- return;
- }
+ if (evaluator instanceof LifeCycle) {
+ ((LifeCycle) evaluator).start();
+ addInfo("Starting evaluator named [" + evaluator.getName() + "]");
+ }
- if (evaluator instanceof LifeCycle) {
- ((LifeCycle) evaluator).start();
- addInfo("Starting evaluator named [" + evaluator.getName() + "]");
- }
+ Object o = ec.peekObject();
- Object o = ec.peekObject();
+ if (o != evaluator) {
+ addWarn("The object on the top the of the stack is not the evaluator pushed earlier.");
+ } else {
+ ec.popObject();
- if (o != evaluator) {
- addWarn("The object on the top the of the stack is not the evaluator pushed earlier.");
+ try {
+ Map<String, EventEvaluator<?>> evaluatorMap = (Map<String, EventEvaluator<?>>) context
+ .getObject(CoreConstants.EVALUATOR_MAP);
+ if(evaluatorMap == null) {
+ addError("Could not find EvaluatorMap");
} else {
- ec.popObject();
-
- try {
- Map<String, EventEvaluator<?>> evaluatorMap = (Map<String, EventEvaluator<?>>) context.getObject(CoreConstants.EVALUATOR_MAP);
- if (evaluatorMap == null) {
- addError("Could not find EvaluatorMap");
- } else {
- evaluatorMap.put(evaluator.getName(), evaluator);
- }
- } catch (Exception ex) {
- addError("Could not set evaluator named [" + evaluator + "].", ex);
- }
+ evaluatorMap.put(evaluator.getName(), evaluator);
}
+ } catch (Exception ex) {
+ addError("Could not set evaluator named [" + evaluator + "].", ex);
+ }
}
+ }
- public void finish(InterpretationContext ec) {
- }
+ public void finish(InterpretationContext ec) {
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java
index f0b638a..5930683 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -37,61 +37,66 @@ import ch.qos.logback.core.spi.ContextAwareBase;
*/
public abstract class Action extends ContextAwareBase {
- public static final String NAME_ATTRIBUTE = "name";
- public static final String KEY_ATTRIBUTE = "key";
- public static final String VALUE_ATTRIBUTE = "value";
- public static final String FILE_ATTRIBUTE = "file";
- public static final String CLASS_ATTRIBUTE = "class";
- public static final String PATTERN_ATTRIBUTE = "pattern";
- public static final String SCOPE_ATTRIBUTE = "scope";
+ public static final String NAME_ATTRIBUTE = "name";
+ public static final String KEY_ATTRIBUTE = "key";
+ public static final String VALUE_ATTRIBUTE = "value";
+ public static final String FILE_ATTRIBUTE = "file";
+ public static final String CLASS_ATTRIBUTE = "class";
+ public static final String PATTERN_ATTRIBUTE = "pattern";
+ public static final String SCOPE_ATTRIBUTE = "scope";
- public static final String ACTION_CLASS_ATTRIBUTE = "actionClass";
- /**
- * Called when the parser encounters an element matching a
- * {@link ch.qos.logback.core.joran.spi.ElementSelector Pattern}.
- */
- public abstract void begin(InterpretationContext ic, String name, Attributes attributes) throws ActionException;
+ public static final String ACTION_CLASS_ATTRIBUTE = "actionClass";
- /**
- * Called to pass the body (as text) contained within an element.
- * @param ic
- * @param body
- * @throws ActionException
- */
- public void body(InterpretationContext ic, String body) throws ActionException {
- // NOP
- }
+ /**
+ * Called when the parser encounters an element matching a
+ * {@link ch.qos.logback.core.joran.spi.ElementSelector Pattern}.
+ */
+ public abstract void begin(InterpretationContext ic, String name,
+ Attributes attributes) throws ActionException;
- /*
- * Called when the parser encounters an endElement event matching a {@link ch.qos.logback.core.joran.spi.Pattern
- * Pattern}.
- */
- public abstract void end(InterpretationContext ic, String name) throws ActionException;
+ /**
+ * Called to pass the body (as text) contained within an element.
+ * @param ic
+ * @param body
+ * @throws ActionException
+ */
+ public void body(InterpretationContext ic, String body)
+ throws ActionException {
+ // NOP
+ }
- public String toString() {
- return this.getClass().getName();
- }
+ /*
+ * Called when the parser encounters an endElement event matching a
+ * {@link ch.qos.logback.core.joran.spi.Pattern Pattern}.
+ */
+ public abstract void end(InterpretationContext ic, String name)
+ throws ActionException;
- protected int getColumnNumber(InterpretationContext ic) {
- Interpreter ji = ic.getJoranInterpreter();
- Locator locator = ji.getLocator();
- if (locator != null) {
- return locator.getColumnNumber();
- }
- return -1;
- }
+ public String toString() {
+ return this.getClass().getName();
+ }
- protected int getLineNumber(InterpretationContext ic) {
- Interpreter ji = ic.getJoranInterpreter();
- Locator locator = ji.getLocator();
- if (locator != null) {
- return locator.getLineNumber();
- }
- return -1;
+ protected int getColumnNumber(InterpretationContext ic) {
+ Interpreter ji = ic.getJoranInterpreter();
+ Locator locator = ji.getLocator();
+ if (locator != null) {
+ return locator.getColumnNumber();
}
+ return -1;
+ }
- protected String getLineColStr(InterpretationContext ic) {
- return "line: " + getLineNumber(ic) + ", column: " + getColumnNumber(ic);
+ protected int getLineNumber(InterpretationContext ic) {
+ Interpreter ji = ic.getJoranInterpreter();
+ Locator locator = ji.getLocator();
+ if (locator != null) {
+ return locator.getLineNumber();
}
+ return -1;
+ }
+
+ protected String getLineColStr(InterpretationContext ic) {
+ return "line: " + getLineNumber(ic) + ", column: "
+ + getColumnNumber(ic);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/ActionConst.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/ActionConst.java
index 64fee3a..079a60a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/ActionConst.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/ActionConst.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,21 +21,21 @@ package ch.qos.logback.core.joran.action;
*
*/
public abstract class ActionConst {
+
+ public static final String APPENDER_TAG = "appender";
+ public static final String REF_ATTRIBUTE = "ref";
+ public static final String ADDITIVITY_ATTRIBUTE = "additivity";
+ public static final String LEVEL_ATTRIBUTE = "level";
+ public static final String CONVERTER_CLASS_ATTRIBUTE = "converterClass";
+ public static final String CONVERSION_WORD_ATTRIBUTE = "conversionWord";
+ public static final String PATTERN_ATTRIBUTE = "pattern";
+ public static final String VALUE_ATTR = "value";
+ public static final String ACTION_CLASS_ATTRIBUTE = "actionClass";
- public static final String APPENDER_TAG = "appender";
- public static final String REF_ATTRIBUTE = "ref";
- public static final String ADDITIVITY_ATTRIBUTE = "additivity";
- public static final String LEVEL_ATTRIBUTE = "level";
- public static final String CONVERTER_CLASS_ATTRIBUTE = "converterClass";
- public static final String CONVERSION_WORD_ATTRIBUTE = "conversionWord";
- public static final String PATTERN_ATTRIBUTE = "pattern";
- public static final String VALUE_ATTR = "value";
- public static final String ACTION_CLASS_ATTRIBUTE = "actionClass";
+ public static final String INHERITED = "INHERITED";
+ public static final String NULL = "NULL";
+ static final Class<?>[] ONE_STRING_PARAM = new Class[] { String.class };
- public static final String INHERITED = "INHERITED";
- public static final String NULL = "NULL";
- static final Class<?>[] ONE_STRING_PARAM = new Class[] { String.class };
-
- public static final String APPENDER_BAG = "APPENDER_BAG";
- //public static final String FILTER_CHAIN_BAG = "FILTER_CHAIN_BAG";
+ public static final String APPENDER_BAG = "APPENDER_BAG";
+ public static final String FILTER_CHAIN_BAG = "FILTER_CHAIN_BAG";
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/ActionUtil.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/ActionUtil.java
index 0171d82..f2fef3a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/ActionUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/ActionUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,53 +21,54 @@ import ch.qos.logback.core.util.OptionHelper;
public class ActionUtil {
- public enum Scope {
- LOCAL, CONTEXT, SYSTEM
- };
+ public enum Scope {
+ LOCAL, CONTEXT, SYSTEM
+ };
- /**
- * Convert a string into a scope. Scole.LOCAL is returned by default.
- * @param scopeStr
- * @return a scope corresponding to the input string; Scope.LOCAL by default.
- */
- static public Scope stringToScope(String scopeStr) {
- if (Scope.SYSTEM.toString().equalsIgnoreCase(scopeStr))
- return Scope.SYSTEM;
- if (Scope.CONTEXT.toString().equalsIgnoreCase(scopeStr))
- return Scope.CONTEXT;
+ /**
+ * Convert a string into a scope. Scole.LOCAL is returned by default.
+ * @param scopeStr
+ * @return a scope corresponding to the input string; Scope.LOCAL by default.
+ */
+ static public Scope stringToScope(String scopeStr) {
+ if(Scope.SYSTEM.toString().equalsIgnoreCase(scopeStr))
+ return Scope.SYSTEM;
+ if(Scope.CONTEXT.toString().equalsIgnoreCase(scopeStr))
+ return Scope.CONTEXT;
- return Scope.LOCAL;
- }
+ return Scope.LOCAL;
+ }
- static public void setProperty(InterpretationContext ic, String key, String value, Scope scope) {
- switch (scope) {
- case LOCAL:
- ic.addSubstitutionProperty(key, value);
- break;
- case CONTEXT:
- ic.getContext().putProperty(key, value);
- break;
- case SYSTEM:
- OptionHelper.setSystemProperty(ic, key, value);
- }
+ static public void setProperty(InterpretationContext ic, String key, String value, Scope scope) {
+ switch (scope) {
+ case LOCAL:
+ ic.addSubstitutionProperty(key, value);
+ break;
+ case CONTEXT:
+ ic.getContext().putProperty(key, value);
+ break;
+ case SYSTEM:
+ OptionHelper.setSystemProperty(ic, key, value);
}
+ }
- /**
- * Add all the properties found in the argument named 'props' to an
- * InterpretationContext.
- */
- static public void setProperties(InterpretationContext ic, Properties props, Scope scope) {
- switch (scope) {
- case LOCAL:
- ic.addSubstitutionProperties(props);
- break;
- case CONTEXT:
- ContextUtil cu = new ContextUtil(ic.getContext());
- cu.addProperties(props);
- break;
- case SYSTEM:
- OptionHelper.setSystemProperties(ic, props);
- }
+ /**
+ * Add all the properties found in the argument named 'props' to an
+ * InterpretationContext.
+ */
+ static public void setProperties(InterpretationContext ic, Properties props,
+ Scope scope) {
+ switch (scope) {
+ case LOCAL:
+ ic.addSubstitutionProperties(props);
+ break;
+ case CONTEXT:
+ ContextUtil cu = new ContextUtil(ic.getContext());
+ cu.addProperties(props);
+ break;
+ case SYSTEM:
+ OptionHelper.setSystemProperties(ic, props);
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderAction.java
index e772f64..be6a1ef 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,78 +24,85 @@ import ch.qos.logback.core.spi.LifeCycle;
import ch.qos.logback.core.util.OptionHelper;
public class AppenderAction<E> extends Action {
- Appender<E> appender;
- private boolean inError = false;
-
- /**
- * Instantiates an appender of the given class and sets its name.
- *
- * The appender thus generated is placed in the {@link InterpretationContext}'s
- * appender bag.
- */
- @SuppressWarnings("unchecked")
- public void begin(InterpretationContext ec, String localName, Attributes attributes) throws ActionException {
- // We are just beginning, reset variables
- appender = null;
- inError = false;
-
- String className = attributes.getValue(CLASS_ATTRIBUTE);
- if (OptionHelper.isEmpty(className)) {
- addError("Missing class name for appender. Near [" + localName + "] line " + getLineNumber(ec));
- inError = true;
- return;
- }
-
- try {
- addInfo("About to instantiate appender of type [" + className + "]");
-
- appender = (Appender<E>) OptionHelper.instantiateByClassName(className, ch.qos.logback.core.Appender.class, context);
-
- appender.setContext(context);
-
- String appenderName = ec.subst(attributes.getValue(NAME_ATTRIBUTE));
-
- if (OptionHelper.isEmpty(appenderName)) {
- addWarn("No appender name given for appender of type " + className + "].");
- } else {
- appender.setName(appenderName);
- addInfo("Naming appender as [" + appenderName + "]");
- }
-
- // The execution context contains a bag which contains the appenders
- // created thus far.
- HashMap<String, Appender<E>> appenderBag = (HashMap<String, Appender<E>>) ec.getObjectMap().get(ActionConst.APPENDER_BAG);
-
- // add the appender just created to the appender bag.
- appenderBag.put(appenderName, appender);
-
- ec.pushObject(appender);
- } catch (Exception oops) {
- inError = true;
- addError("Could not create an Appender of type [" + className + "].", oops);
- throw new ActionException(oops);
- }
+ Appender<E> appender;
+ private boolean inError = false;
+
+ /**
+ * Instantiates an appender of the given class and sets its name.
+ *
+ * The appender thus generated is placed in the {@link InterpretationContext}'s
+ * appender bag.
+ */
+ @SuppressWarnings("unchecked")
+ public void begin(InterpretationContext ec, String localName,
+ Attributes attributes) throws ActionException {
+ // We are just beginning, reset variables
+ appender = null;
+ inError = false;
+
+ String className = attributes.getValue(CLASS_ATTRIBUTE);
+ if (OptionHelper.isEmpty(className)) {
+ addError("Missing class name for appender. Near [" + localName
+ + "] line " + getLineNumber(ec));
+ inError = true;
+ return;
}
- /**
- * Once the children elements are also parsed, now is the time to activate the
- * appender options.
- */
- public void end(InterpretationContext ec, String name) {
- if (inError) {
- return;
- }
-
- if (appender instanceof LifeCycle) {
- ((LifeCycle) appender).start();
- }
-
- Object o = ec.peekObject();
-
- if (o != appender) {
- addWarn("The object at the of the stack is not the appender named [" + appender.getName() + "] pushed earlier.");
- } else {
- ec.popObject();
- }
+ try {
+ addInfo("About to instantiate appender of type [" + className + "]");
+
+ appender = (Appender<E>) OptionHelper.instantiateByClassName(className,
+ ch.qos.logback.core.Appender.class, context);
+
+ appender.setContext(context);
+
+ String appenderName = ec.subst(attributes.getValue(NAME_ATTRIBUTE));
+
+ if (OptionHelper.isEmpty(appenderName)) {
+ addWarn("No appender name given for appender of type " + className
+ + "].");
+ } else {
+ appender.setName(appenderName);
+ addInfo("Naming appender as [" + appenderName + "]");
+ }
+
+ // The execution context contains a bag which contains the appenders
+ // created thus far.
+ HashMap<String, Appender<E>> appenderBag = (HashMap<String, Appender<E>>) ec.getObjectMap().get(
+ ActionConst.APPENDER_BAG);
+
+ // add the appender just created to the appender bag.
+ appenderBag.put(appenderName, appender);
+
+ ec.pushObject(appender);
+ } catch (Exception oops) {
+ inError = true;
+ addError("Could not create an Appender of type [" + className + "].",
+ oops);
+ throw new ActionException(oops);
+ }
+ }
+
+ /**
+ * Once the children elements are also parsed, now is the time to activate the
+ * appender options.
+ */
+ public void end(InterpretationContext ec, String name) {
+ if (inError) {
+ return;
+ }
+
+ if (appender instanceof LifeCycle) {
+ ((LifeCycle) appender).start();
+ }
+
+ Object o = ec.peekObject();
+
+ if (o != appender) {
+ addWarn("The object at the of the stack is not the appender named ["
+ + appender.getName() + "] pushed earlier.");
+ } else {
+ ec.popObject();
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderRefAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderRefAction.java
index 7da960d..d234dc9 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderRefAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderRefAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,56 +21,62 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.spi.AppenderAttachable;
import ch.qos.logback.core.util.OptionHelper;
+
import java.util.HashMap;
public class AppenderRefAction<E> extends Action {
- boolean inError = false;
-
- @SuppressWarnings("unchecked")
- public void begin(InterpretationContext ec, String tagName, Attributes attributes) {
- // Let us forget about previous errors (in this object)
- inError = false;
-
- // logger.debug("begin called");
-
- Object o = ec.peekObject();
+ boolean inError = false;
- if (!(o instanceof AppenderAttachable)) {
- String errMsg = "Could not find an AppenderAttachable at the top of execution stack. Near [" + tagName + "] line " + getLineNumber(ec);
- inError = true;
- addError(errMsg);
- return;
- }
+ @SuppressWarnings("unchecked")
+ public void begin(InterpretationContext ec, String tagName, Attributes attributes) {
+ // Let us forget about previous errors (in this object)
+ inError = false;
- AppenderAttachable<E> appenderAttachable = (AppenderAttachable<E>) o;
+ // logger.debug("begin called");
- String appenderName = ec.subst(attributes.getValue(ActionConst.REF_ATTRIBUTE));
+ Object o = ec.peekObject();
- if (OptionHelper.isEmpty(appenderName)) {
- // print a meaningful error message and return
- String errMsg = "Missing appender ref attribute in <appender-ref> tag.";
- inError = true;
- addError(errMsg);
+ if (!(o instanceof AppenderAttachable)) {
+ String errMsg = "Could not find an AppenderAttachable at the top of execution stack. Near ["
+ + tagName + "] line " + getLineNumber(ec);
+ inError = true;
+ addError(errMsg);
+ return;
+ }
- return;
- }
+ AppenderAttachable<E> appenderAttachable = (AppenderAttachable<E>) o;
- HashMap<String, Appender<E>> appenderBag = (HashMap<String, Appender<E>>) ec.getObjectMap().get(ActionConst.APPENDER_BAG);
- Appender<E> appender = (Appender<E>) appenderBag.get(appenderName);
+ String appenderName = ec.subst(attributes.getValue(ActionConst.REF_ATTRIBUTE));
- if (appender == null) {
- String msg = "Could not find an appender named [" + appenderName + "]. Did you define it below instead of above in the configuration file?";
- inError = true;
- addError(msg);
- addError("See " + CoreConstants.CODES_URL + "#appender_order for more details.");
- return;
- }
+ if (OptionHelper.isEmpty(appenderName)) {
+ // print a meaningful error message and return
+ String errMsg = "Missing appender ref attribute in <appender-ref> tag.";
+ inError = true;
+ addError(errMsg);
- addInfo("Attaching appender named [" + appenderName + "] to " + appenderAttachable);
- appenderAttachable.addAppender(appender);
+ return;
}
- public void end(InterpretationContext ec, String n) {
+ HashMap<String, Appender<E>> appenderBag = (HashMap<String, Appender<E>>) ec.getObjectMap().get(
+ ActionConst.APPENDER_BAG);
+ Appender<E> appender = (Appender<E>) appenderBag.get(appenderName);
+
+ if (appender == null) {
+ String msg = "Could not find an appender named [" + appenderName
+ + "]. Did you define it below instead of above in the configuration file?";
+ inError = true;
+ addError(msg);
+ addError("See " + CoreConstants.CODES_URL
+ + "#appender_order for more details.");
+ return;
}
+ addInfo("Attaching appender named [" + appenderName + "] to "
+ + appenderAttachable);
+ appenderAttachable.addAppender(appender);
+ }
+
+ public void end(InterpretationContext ec, String n) {
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/ContextPropertyAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/ContextPropertyAction.java
index ee51410..8230d7e 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/ContextPropertyAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/ContextPropertyAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,13 +23,14 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
*/
public class ContextPropertyAction extends Action {
- @Override
- public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
- addError("The [contextProperty] element has been removed. Please use [substitutionProperty] element instead");
- }
+ @Override
+ public void begin(InterpretationContext ec, String name, Attributes attributes)
+ throws ActionException {
+ addError("The [contextProperty] element has been removed. Please use [substitutionProperty] element instead");
+ }
- @Override
- public void end(InterpretationContext ec, String name) throws ActionException {
- }
+ @Override
+ public void end(InterpretationContext ec, String name) throws ActionException {
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/ConversionRuleAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/ConversionRuleAction.java
index 2575076..adea823 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/ConversionRuleAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/ConversionRuleAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,67 +16,72 @@ package ch.qos.logback.core.joran.action;
import java.util.HashMap;
import java.util.Map;
+
import org.xml.sax.Attributes;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.util.OptionHelper;
-public class ConversionRuleAction extends Action {
- boolean inError = false;
- /**
- * Instantiates an layout of the given class and sets its name.
- *
- */
- @SuppressWarnings("unchecked")
- public void begin(InterpretationContext ec, String localName, Attributes attributes) {
- // Let us forget about previous errors (in this object)
- inError = false;
- String errorMsg;
- String conversionWord = attributes.getValue(ActionConst.CONVERSION_WORD_ATTRIBUTE);
- String converterClass = attributes.getValue(ActionConst.CONVERTER_CLASS_ATTRIBUTE);
+public class ConversionRuleAction extends Action {
+ boolean inError = false;
+
+ /**
+ * Instantiates an layout of the given class and sets its name.
+ *
+ */
+ @SuppressWarnings("unchecked")
+ public void begin(InterpretationContext ec, String localName, Attributes attributes) {
+ // Let us forget about previous errors (in this object)
+ inError = false;
- if (OptionHelper.isEmpty(conversionWord)) {
- inError = true;
- errorMsg = "No 'conversionWord' attribute in <conversionRule>";
- addError(errorMsg);
+ String errorMsg;
+ String conversionWord =
+ attributes.getValue(ActionConst.CONVERSION_WORD_ATTRIBUTE);
+ String converterClass =
+ attributes.getValue(ActionConst.CONVERTER_CLASS_ATTRIBUTE);
- return;
- }
+ if (OptionHelper.isEmpty(conversionWord)) {
+ inError = true;
+ errorMsg = "No 'conversionWord' attribute in <conversionRule>";
+ addError(errorMsg);
- if (OptionHelper.isEmpty(converterClass)) {
- inError = true;
- errorMsg = "No 'converterClass' attribute in <conversionRule>";
- ec.addError(errorMsg);
+ return;
+ }
- return;
- }
+ if (OptionHelper.isEmpty(converterClass)) {
+ inError = true;
+ errorMsg = "No 'converterClass' attribute in <conversionRule>";
+ ec.addError(errorMsg);
- try {
- Map<String, String> ruleRegistry = (Map) context.getObject(CoreConstants.PATTERN_RULE_REGISTRY);
- if (ruleRegistry == null) {
- ruleRegistry = new HashMap<String, String>();
- context.putObject(CoreConstants.PATTERN_RULE_REGISTRY, ruleRegistry);
- }
- // put the new rule into the rule registry
- addInfo("registering conversion word " + conversionWord + " with class [" + converterClass + "]");
- ruleRegistry.put(conversionWord, converterClass);
- } catch (Exception oops) {
- inError = true;
- errorMsg = "Could not add conversion rule to PatternLayout.";
- addError(errorMsg);
- }
+ return;
}
- /**
- * Once the children elements are also parsed, now is the time to activate
- * the appender options.
- */
- public void end(InterpretationContext ec, String n) {
+ try {
+ Map<String, String> ruleRegistry = (Map) context.getObject(CoreConstants.PATTERN_RULE_REGISTRY);
+ if(ruleRegistry == null) {
+ ruleRegistry = new HashMap<String, String>();
+ context.putObject(CoreConstants.PATTERN_RULE_REGISTRY, ruleRegistry);
+ }
+ // put the new rule into the rule registry
+ addInfo("registering conversion word "+conversionWord+" with class ["+converterClass+"]");
+ ruleRegistry.put(conversionWord, converterClass);
+ } catch (Exception oops) {
+ inError = true;
+ errorMsg = "Could not add conversion rule to PatternLayout.";
+ addError(errorMsg);
}
+ }
- public void finish(InterpretationContext ec) {
- }
+ /**
+ * Once the children elements are also parsed, now is the time to activate
+ * the appender options.
+ */
+ public void end(InterpretationContext ec, String n) {
+ }
+
+ public void finish(InterpretationContext ec) {
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/DefinePropertyAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/DefinePropertyAction.java
index 3700ef1..ffd96b6 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/DefinePropertyAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/DefinePropertyAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,77 +30,85 @@ import org.xml.sax.Attributes;
*/
public class DefinePropertyAction extends Action {
- String scopeStr;
- Scope scope;
- String propertyName;
- PropertyDefiner definer;
- boolean inError;
+ String scopeStr;
+ Scope scope;
+ String propertyName;
+ PropertyDefiner definer;
+ boolean inError;
- public void begin(InterpretationContext ec, String localName, Attributes attributes) throws ActionException {
- // reset variables
- scopeStr = null;
- scope = null;
- propertyName = null;
- definer = null;
- inError = false;
-
- // read future property name
- propertyName = attributes.getValue(NAME_ATTRIBUTE);
- scopeStr = attributes.getValue(SCOPE_ATTRIBUTE);
-
- scope = ActionUtil.stringToScope(scopeStr);
- if (OptionHelper.isEmpty(propertyName)) {
- addError("Missing property name for property definer. Near [" + localName + "] line " + getLineNumber(ec));
- inError = true;
- return;
- }
+ public void begin(InterpretationContext ec, String localName,
+ Attributes attributes) throws ActionException {
+ // reset variables
+ scopeStr = null;
+ scope = null;
+ propertyName = null;
+ definer = null;
+ inError = false;
+
+ // read future property name
+ propertyName = attributes.getValue(NAME_ATTRIBUTE);
+ scopeStr = attributes.getValue(SCOPE_ATTRIBUTE);
+
+ scope = ActionUtil.stringToScope(scopeStr);
+ if (OptionHelper.isEmpty(propertyName)) {
+ addError("Missing property name for property definer. Near [" + localName
+ + "] line " + getLineNumber(ec));
+ inError = true;
+ return;
+ }
- // read property definer class name
- String className = attributes.getValue(CLASS_ATTRIBUTE);
- if (OptionHelper.isEmpty(className)) {
- addError("Missing class name for property definer. Near [" + localName + "] line " + getLineNumber(ec));
- inError = true;
- return;
- }
+ // read property definer class name
+ String className = attributes.getValue(CLASS_ATTRIBUTE);
+ if (OptionHelper.isEmpty(className)) {
+ addError("Missing class name for property definer. Near [" + localName
+ + "] line " + getLineNumber(ec));
+ inError = true;
+ return;
+ }
- // try to instantiate property definer
- try {
- addInfo("About to instantiate property definer of type [" + className + "]");
- definer = (PropertyDefiner) OptionHelper.instantiateByClassName(className, PropertyDefiner.class, context);
- definer.setContext(context);
- if (definer instanceof LifeCycle) {
- ((LifeCycle) definer).start();
- }
- ec.pushObject(definer);
- } catch (Exception oops) {
- inError = true;
- addError("Could not create an PropertyDefiner of type [" + className + "].", oops);
- throw new ActionException(oops);
- }
+ // try to instantiate property definer
+ try {
+ addInfo("About to instantiate property definer of type [" + className
+ + "]");
+ definer = (PropertyDefiner) OptionHelper.instantiateByClassName(
+ className, PropertyDefiner.class, context);
+ definer.setContext(context);
+ if(definer instanceof LifeCycle) {
+ ((LifeCycle) definer).start();
+ }
+ ec.pushObject(definer);
+ } catch (Exception oops) {
+ inError = true;
+ addError("Could not create an PropertyDefiner of type [" + className
+ + "].", oops);
+ throw new ActionException(oops);
}
+ }
- /**
- * Now property definer is initialized by all properties and we can put
- * property value to context
- */
- public void end(InterpretationContext ec, String name) {
- if (inError) {
- return;
- }
+ /**
+ * Now property definer is initialized by all properties and we can put
+ * property value to context
+ */
+ public void end(InterpretationContext ec, String name) {
+ if (inError) {
+ return;
+ }
- Object o = ec.peekObject();
+ Object o = ec.peekObject();
- if (o != definer) {
- addWarn("The object at the of the stack is not the property definer for property named [" + propertyName + "] pushed earlier.");
- } else {
- addInfo("Popping property definer for property named [" + propertyName + "] from the object stack");
- ec.popObject();
- // let's put defined property and value to context but only if it is
- // not null
- String propertyValue = definer.getPropertyValue();
- if (propertyValue != null) {
- ActionUtil.setProperty(ec, propertyName, propertyValue, scope);
- }
- }
+ if (o != definer) {
+ addWarn("The object at the of the stack is not the property definer for property named ["
+ + propertyName + "] pushed earlier.");
+ } else {
+ addInfo("Popping property definer for property named [" + propertyName
+ + "] from the object stack");
+ ec.popObject();
+ // let's put defined property and value to context but only if it is
+ // not null
+ String propertyValue = definer.getPropertyValue();
+ if(propertyValue != null) {
+ ActionUtil.setProperty(ec, propertyName, propertyValue, scope);
+ }
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/IADataForBasicProperty.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/IADataForBasicProperty.java
index 441b7bd..023e070 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/IADataForBasicProperty.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/IADataForBasicProperty.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,14 +22,14 @@ import ch.qos.logback.core.util.AggregationType;
* @author Ceki Gulcu
*/
class IADataForBasicProperty {
- final PropertySetter parentBean;
- final AggregationType aggregationType;
- final String propertyName;
- boolean inError;
+ final PropertySetter parentBean;
+ final AggregationType aggregationType;
+ final String propertyName;
+ boolean inError;
- IADataForBasicProperty(PropertySetter parentBean, AggregationType aggregationType, String propertyName) {
- this.parentBean = parentBean;
- this.aggregationType = aggregationType;
- this.propertyName = propertyName;
- }
+ IADataForBasicProperty(PropertySetter parentBean, AggregationType aggregationType, String propertyName) {
+ this.parentBean = parentBean;
+ this.aggregationType = aggregationType;
+ this.propertyName = propertyName;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/IADataForComplexProperty.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/IADataForComplexProperty.java
index 8292ee0..6c77452 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/IADataForComplexProperty.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/IADataForComplexProperty.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,32 +22,33 @@ import ch.qos.logback.core.util.AggregationType;
* @author Ceki
*/
public class IADataForComplexProperty {
- final PropertySetter parentBean;
- final AggregationType aggregationType;
- final String complexPropertyName;
- private Object nestedComplexProperty;
- boolean inError;
-
- public IADataForComplexProperty(PropertySetter parentBean, AggregationType aggregationType, String complexPropertyName) {
- this.parentBean = parentBean;
- this.aggregationType = aggregationType;
- this.complexPropertyName = complexPropertyName;
- }
-
- public AggregationType getAggregationType() {
- return aggregationType;
- }
-
- public Object getNestedComplexProperty() {
- return nestedComplexProperty;
- }
-
- public String getComplexPropertyName() {
- return complexPropertyName;
- }
-
- public void setNestedComplexProperty(Object nestedComplexProperty) {
- this.nestedComplexProperty = nestedComplexProperty;
- }
-
+ final PropertySetter parentBean;
+ final AggregationType aggregationType;
+ final String complexPropertyName;
+ private Object nestedComplexProperty;
+ boolean inError;
+
+ public IADataForComplexProperty(PropertySetter parentBean, AggregationType aggregationType, String complexPropertyName) {
+ this.parentBean = parentBean;
+ this.aggregationType = aggregationType;
+ this.complexPropertyName = complexPropertyName;
+ }
+
+ public AggregationType getAggregationType() {
+ return aggregationType;
+ }
+
+ public Object getNestedComplexProperty() {
+ return nestedComplexProperty;
+ }
+
+ public String getComplexPropertyName() {
+ return complexPropertyName;
+ }
+
+ public void setNestedComplexProperty(Object nestedComplexProperty) {
+ this.nestedComplexProperty = nestedComplexProperty;
+ }
+
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/ImplicitAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/ImplicitAction.java
index 77452b7..10f5bc9 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/ImplicitAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/ImplicitAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,11 +13,13 @@
*/
package ch.qos.logback.core.joran.action;
+
import ch.qos.logback.core.joran.spi.ElementPath;
import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.spi.InterpretationContext;
+
/**
* ImplcitActions are like normal (explicit) actions except that are applied
* by the parser when no other pattern applies. Since there can be many implicit
@@ -28,16 +30,18 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
* @author Ceki Gülcü
*/
public abstract class ImplicitAction extends Action {
-
- /**
- * Check whether this implicit action is appropriate in the current context.
- *
- * @param currentElementPath This pattern contains the tag name of the current
- * element being parsed at the top of the stack.
- * @param attributes The attributes of the current element to process.
- * @param ec
- * @return Whether the implicit action is applicable in the current context
- */
- public abstract boolean isApplicable(ElementPath currentElementPath, Attributes attributes, InterpretationContext ec);
-
+
+ /**
+ * Check whether this implicit action is appropriate in the current context.
+ *
+ * @param currentElementPath This pattern contains the tag name of the current
+ * element being parsed at the top of the stack.
+ * @param attributes The attributes of the current element to process.
+ * @param ec
+ * @return Whether the implicit action is applicable in the current context
+ */
+ public abstract boolean isApplicable(
+ ElementPath currentElementPath, Attributes attributes, InterpretationContext ec);
+
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java
index 2e69ed4..a657dd2 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,6 +14,7 @@
package ch.qos.logback.core.joran.action;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -21,6 +22,7 @@ import java.net.URI;
import java.net.URL;
import java.util.List;
+import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.event.SaxEvent;
@@ -28,197 +30,218 @@ import ch.qos.logback.core.joran.event.SaxEventRecorder;
import ch.qos.logback.core.joran.spi.ActionException;
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.joran.spi.JoranException;
-import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
import ch.qos.logback.core.util.Loader;
import ch.qos.logback.core.util.OptionHelper;
public class IncludeAction extends Action {
- private static final String INCLUDED_TAG = "included";
- private static final String FILE_ATTR = "file";
- private static final String URL_ATTR = "url";
- private static final String RESOURCE_ATTR = "resource";
- private static final String OPTIONAL_ATTR = "optional";
-
- private String attributeInUse;
- private boolean optional;
-
- @Override
- public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
-
- SaxEventRecorder recorder = new SaxEventRecorder(context);
-
- this.attributeInUse = null;
- this.optional = OptionHelper.toBoolean(attributes.getValue(OPTIONAL_ATTR), false);
-
- if (!checkAttributes(attributes)) {
- return;
- }
-
- InputStream in = getInputStream(ec, attributes);
-
- try {
- if (in != null) {
- parseAndRecord(in, recorder);
- // remove the <included> tag from the beginning and </included> from the end
- trimHeadAndTail(recorder);
-
- // offset = 2, because we need to get past this element as well as the end element
- ec.getJoranInterpreter().getEventPlayer().addEventsDynamically(recorder.saxEventList, 2);
- }
- } catch (JoranException e) {
- addError("Error while parsing " + attributeInUse, e);
- } finally {
- close(in);
- }
-
- }
-
- void close(InputStream in) {
- if (in != null) {
- try {
- in.close();
- } catch (IOException e) {
- }
- }
- }
-
- private boolean checkAttributes(Attributes attributes) {
- String fileAttribute = attributes.getValue(FILE_ATTR);
- String urlAttribute = attributes.getValue(URL_ATTR);
- String resourceAttribute = attributes.getValue(RESOURCE_ATTR);
-
- int count = 0;
-
- if (!OptionHelper.isEmpty(fileAttribute)) {
- count++;
- }
- if (!OptionHelper.isEmpty(urlAttribute)) {
- count++;
- }
- if (!OptionHelper.isEmpty(resourceAttribute)) {
- count++;
- }
+ private static final String INCLUDED_TAG = "included";
+ private static final String FILE_ATTR = "file";
+ private static final String URL_ATTR = "url";
+ private static final String RESOURCE_ATTR = "resource";
+ private static final String OPTIONAL_ATTR = "optional";
- if (count == 0) {
- addError("One of \"path\", \"resource\" or \"url\" attributes must be set.");
- return false;
- } else if (count > 1) {
- addError("Only one of \"file\", \"url\" or \"resource\" attributes should be set.");
- return false;
- } else if (count == 1) {
- return true;
- }
- throw new IllegalStateException("Count value [" + count + "] is not expected");
- }
+ private String attributeInUse;
+ private boolean optional;
+
+ @Override
+ public void begin(InterpretationContext ec, String name, Attributes attributes)
+ throws ActionException {
+
+ SaxEventRecorder recorder = new SaxEventRecorder(context);
- URL attributeToURL(String urlAttribute) {
- try {
- return new URL(urlAttribute);
- } catch (MalformedURLException mue) {
- String errMsg = "URL [" + urlAttribute + "] is not well formed.";
- addError(errMsg, mue);
- return null;
- }
+ this.attributeInUse = null;
+ this.optional = OptionHelper.toBoolean(attributes.getValue(OPTIONAL_ATTR), false);
+
+ if (!checkAttributes(attributes)) {
+ return;
}
- InputStream openURL(URL url) {
- try {
- return url.openStream();
- } catch (IOException e) {
- optionalWarning("Failed to open [" + url.toString() + "]");
- return null;
- }
+ InputStream in = getInputStream(ec, attributes);
+
+ try {
+ if (in != null) {
+ parseAndRecord(in, recorder);
+ // remove the <included> tag from the beginning and </included> from the end
+ trimHeadAndTail(recorder);
+
+ // offset = 2, because we need to get past this element as well as the end element
+ ec.getJoranInterpreter().getEventPlayer().addEventsDynamically(recorder.saxEventList, 2);
+ }
+ } catch (JoranException e) {
+ addError("Error while parsing " + attributeInUse, e);
+ } finally {
+ close(in);
}
- URL resourceAsURL(String resourceAttribute) {
- URL url = Loader.getResourceBySelfClassLoader(resourceAttribute);
- if (url == null) {
- optionalWarning("Could not find resource corresponding to [" + resourceAttribute + "]");
- return null;
- } else
- return url;
+ }
+
+ void close(InputStream in) {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ }
}
+ }
+
+ private boolean checkAttributes(Attributes attributes) {
+ String fileAttribute = attributes.getValue(FILE_ATTR);
+ String urlAttribute = attributes.getValue(URL_ATTR);
+ String resourceAttribute = attributes.getValue(RESOURCE_ATTR);
+
+ int count = 0;
- private void optionalWarning(String msg) {
- if (!optional) {
- addWarn(msg);
- }
+ if (!OptionHelper.isEmpty(fileAttribute)) {
+ count++;
+ }
+ if (!OptionHelper.isEmpty(urlAttribute)) {
+ count++;
+ }
+ if (!OptionHelper.isEmpty(resourceAttribute)) {
+ count++;
}
- URL filePathAsURL(String path) {
- URI uri = new File(path).toURI();
- try {
- return uri.toURL();
- } catch (MalformedURLException e) {
- // impossible to get here
- e.printStackTrace();
- return null;
- }
- }
-
- URL getInputURL(InterpretationContext ec, Attributes attributes) {
- String fileAttribute = attributes.getValue(FILE_ATTR);
- String urlAttribute = attributes.getValue(URL_ATTR);
- String resourceAttribute = attributes.getValue(RESOURCE_ATTR);
+ if (count == 0) {
+ addError("One of \"path\", \"resource\" or \"url\" attributes must be set.");
+ return false;
+ } else if (count > 1) {
+ addError("Only one of \"file\", \"url\" or \"resource\" attributes should be set.");
+ return false;
+ } else if (count == 1) {
+ return true;
+ }
+ throw new IllegalStateException("Count value [" + count
+ + "] is not expected");
+ }
+
+ private InputStream getInputStreamByFilePath(String pathToFile) {
+ try {
+ return new FileInputStream(pathToFile);
+ } catch (IOException ioe) {
+ String warningMsg = "File [" + pathToFile + "] does not exist.";
+ addWarn(warningMsg);
+ return null;
+ }
+ }
+
+ URL attributeToURL(String urlAttribute) {
+ try {
+ return new URL(urlAttribute);
+ } catch (MalformedURLException mue) {
+ String errMsg = "URL [" + urlAttribute + "] is not well formed.";
+ addError(errMsg, mue);
+ return null;
+ }
+ }
+
+ private InputStream getInputStreamByUrl(URL url) {
+ return openURL(url);
+ }
+
+ InputStream openURL(URL url) {
+ try {
+ return url.openStream();
+ } catch (IOException e) {
+ if (!optional) {
+ String errMsg = "Failed to open [" + url.toString() + "]";
+ addError(errMsg, e);
+ }
+ return null;
+ }
+ }
+
+ URL resourceAsURL(String resourceAttribute) {
+ URL url = Loader.getResourceBySelfClassLoader(resourceAttribute);
+ if (url == null) {
+ if (!optional) {
+ String errMsg = "Could not find resource corresponding to ["
+ + resourceAttribute + "]";
+ addError(errMsg);
+ }
+ return null;
+ } else
+ return url;
+ }
+
+ URL filePathAsURL(String path) {
+ URI uri = new File(path).toURI();
+ try {
+ return uri.toURL();
+ } catch (MalformedURLException e) {
+ // impossible to get here
+ e.printStackTrace();
+ return null;
+ }
+ }
- if (!OptionHelper.isEmpty(fileAttribute)) {
- this.attributeInUse = ec.subst(fileAttribute);
- return filePathAsURL(attributeInUse);
- }
+ private InputStream getInputStreamByResource(URL url) {
+ return openURL(url);
+ }
- if (!OptionHelper.isEmpty(urlAttribute)) {
- this.attributeInUse = ec.subst(urlAttribute);
- return attributeToURL(attributeInUse);
- }
+ URL getInputURL(InterpretationContext ec, Attributes attributes) {
+ String fileAttribute = attributes.getValue(FILE_ATTR);
+ String urlAttribute = attributes.getValue(URL_ATTR);
+ String resourceAttribute = attributes.getValue(RESOURCE_ATTR);
- if (!OptionHelper.isEmpty(resourceAttribute)) {
- this.attributeInUse = ec.subst(resourceAttribute);
- return resourceAsURL(attributeInUse);
- }
- // given previous checkAttributes() check we cannot reach this line
- throw new IllegalStateException("A URL stream should have been returned");
+ if (!OptionHelper.isEmpty(fileAttribute)) {
+ this.attributeInUse = ec.subst(fileAttribute);
+ return filePathAsURL(attributeInUse);
+ }
+ if (!OptionHelper.isEmpty(urlAttribute)) {
+ this.attributeInUse = ec.subst(urlAttribute);
+ return attributeToURL(attributeInUse);
}
- InputStream getInputStream(InterpretationContext ec, Attributes attributes) {
- URL inputURL = getInputURL(ec, attributes);
- if (inputURL == null)
- return null;
+ if (!OptionHelper.isEmpty(resourceAttribute)) {
+ this.attributeInUse = ec.subst(resourceAttribute);
+ return resourceAsURL(attributeInUse);
+ }
+ // given previous checkAttributes() check we cannot reach this line
+ throw new IllegalStateException("A URL stream should have been returned");
- ConfigurationWatchListUtil.addToWatchList(context, inputURL);
- return openURL(inputURL);
- }
+ }
- private void trimHeadAndTail(SaxEventRecorder recorder) {
- // Let's remove the two <included> events before
- // adding the events to the player.
+ InputStream getInputStream(InterpretationContext ec, Attributes attributes) {
+ URL inputURL = getInputURL(ec, attributes);
+ if (inputURL == null)
+ return null;
- List<SaxEvent> saxEventList = recorder.saxEventList;
+ ConfigurationWatchListUtil.addToWatchList(context, inputURL);
+ return openURL(inputURL);
+ }
- if (saxEventList.size() == 0) {
- return;
- }
+ private void trimHeadAndTail(SaxEventRecorder recorder) {
+ // Let's remove the two <included> events before
+ // adding the events to the player.
- SaxEvent first = saxEventList.get(0);
- if (first != null && first.qName.equalsIgnoreCase(INCLUDED_TAG)) {
- saxEventList.remove(0);
- }
+ List<SaxEvent> saxEventList = recorder.saxEventList;
- SaxEvent last = saxEventList.get(recorder.saxEventList.size() - 1);
- if (last != null && last.qName.equalsIgnoreCase(INCLUDED_TAG)) {
- saxEventList.remove(recorder.saxEventList.size() - 1);
- }
+ if (saxEventList.size() == 0) {
+ return;
}
- private void parseAndRecord(InputStream inputSource, SaxEventRecorder recorder) throws JoranException {
- recorder.setContext(context);
- recorder.recordEvents(inputSource);
+ SaxEvent first = saxEventList.get(0);
+ if (first != null && first.qName.equalsIgnoreCase(INCLUDED_TAG)) {
+ saxEventList.remove(0);
}
- @Override
- public void end(InterpretationContext ec, String name) throws ActionException {
- // do nothing
+ SaxEvent last = saxEventList.get(recorder.saxEventList.size() - 1);
+ if (last != null && last.qName.equalsIgnoreCase(INCLUDED_TAG)) {
+ saxEventList.remove(recorder.saxEventList.size() - 1);
}
+ }
+
+ private void parseAndRecord(InputStream inputSource, SaxEventRecorder recorder)
+ throws JoranException {
+ recorder.setContext(context);
+ recorder.recordEvents(inputSource);
+ }
+
+ @Override
+ public void end(InterpretationContext ec, String name) throws ActionException {
+ // do nothing
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/NOPAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/NOPAction.java
index 2e0deb2..e37cd86 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/NOPAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/NOPAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,7 @@ import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.InterpretationContext;
+
/**
* No operation (NOP) action that does strictly nothing.
* Setting a rule to this pattern is sometimes useful in order
@@ -26,10 +27,11 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
* @author Ceki Gülcü
*/
public class NOPAction extends Action {
+
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ }
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- }
- public void end(InterpretationContext ec, String name) {
- }
+ public void end(InterpretationContext ec, String name) {
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedBasicPropertyIA.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedBasicPropertyIA.java
index f9f11d8..aac9cdd 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedBasicPropertyIA.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedBasicPropertyIA.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,94 +16,89 @@ package ch.qos.logback.core.joran.action;
import java.util.Stack;
import ch.qos.logback.core.joran.spi.ElementPath;
-
import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.joran.util.PropertySetter;
-import ch.qos.logback.core.joran.util.beans.BeanDescriptionCache;
import ch.qos.logback.core.util.AggregationType;
/**
* This action is responsible for tying together a parent object with one of its
* <em>simple</em> properties specified as an element but for which there is
* no explicit rule.
- *
+ *
* @author Ceki Gülcü
*/
public class NestedBasicPropertyIA extends ImplicitAction {
- // We use a stack of IADataForBasicProperty objects in order to
- // support nested elements which are handled by the same NestedBasicPropertyIA instance.
- // We push a IADataForBasicProperty instance in the isApplicable method (if the
- // action is applicable) and pop it in the end() method.
- // The XML well-formedness property will guarantee that a push will eventually
- // be followed by the corresponding pop.
- Stack<IADataForBasicProperty> actionDataStack = new Stack<IADataForBasicProperty>();
- private final BeanDescriptionCache beanDescriptionCache;
+ // We use a stack of IADataForBasicProperty objects in order to
+ // support nested elements which are handled by the same NestedBasicPropertyIA instance.
+ // We push a IADataForBasicProperty instance in the isApplicable method (if the
+ // action is applicable) and pop it in the end() method.
+ // The XML well-formedness property will guarantee that a push will eventually
+ // be followed by the corresponding pop.
+ Stack<IADataForBasicProperty> actionDataStack = new Stack<IADataForBasicProperty>();
- public NestedBasicPropertyIA(BeanDescriptionCache beanDescriptionCache) {
- this.beanDescriptionCache = beanDescriptionCache;
- }
+ public boolean isApplicable(ElementPath elementPath, Attributes attributes,
+ InterpretationContext ec) {
+ // System.out.println("in NestedSimplePropertyIA.isApplicable [" + pattern +
+ // "]");
+ String nestedElementTagName = elementPath.peekLast();
- public boolean isApplicable(ElementPath elementPath, Attributes attributes, InterpretationContext ec) {
- // System.out.println("in NestedSimplePropertyIA.isApplicable [" + pattern +
- // "]");
- String nestedElementTagName = elementPath.peekLast();
-
- // no point in attempting if there is no parent object
- if (ec.isEmpty()) {
- return false;
- }
-
- Object o = ec.peekObject();
- PropertySetter parentBean = new PropertySetter(beanDescriptionCache, o);
- parentBean.setContext(context);
-
- AggregationType aggregationType = parentBean.computeAggregationType(nestedElementTagName);
-
- switch (aggregationType) {
- case NOT_FOUND:
- case AS_COMPLEX_PROPERTY:
- case AS_COMPLEX_PROPERTY_COLLECTION:
- return false;
-
- case AS_BASIC_PROPERTY:
- case AS_BASIC_PROPERTY_COLLECTION:
- IADataForBasicProperty ad = new IADataForBasicProperty(parentBean, aggregationType, nestedElementTagName);
- actionDataStack.push(ad);
- // addInfo("NestedSimplePropertyIA deemed applicable [" + pattern + "]");
- return true;
- default:
- addError("PropertySetter.canContainComponent returned " + aggregationType);
- return false;
- }
+ // no point in attempting if there is no parent object
+ if (ec.isEmpty()) {
+ return false;
}
- public void begin(InterpretationContext ec, String localName, Attributes attributes) {
- // NOP
+ Object o = ec.peekObject();
+ PropertySetter parentBean = new PropertySetter(o);
+ parentBean.setContext(context);
+
+ AggregationType aggregationType = parentBean
+ .computeAggregationType(nestedElementTagName);
+
+ switch (aggregationType) {
+ case NOT_FOUND:
+ case AS_COMPLEX_PROPERTY:
+ case AS_COMPLEX_PROPERTY_COLLECTION:
+ return false;
+
+ case AS_BASIC_PROPERTY:
+ case AS_BASIC_PROPERTY_COLLECTION:
+ IADataForBasicProperty ad = new IADataForBasicProperty(parentBean,
+ aggregationType, nestedElementTagName);
+ actionDataStack.push(ad);
+ // addInfo("NestedSimplePropertyIA deemed applicable [" + pattern + "]");
+ return true;
+ default:
+ addError("PropertySetter.canContainComponent returned " + aggregationType);
+ return false;
}
-
- public void body(InterpretationContext ec, String body) {
-
- String finalBody = ec.subst(body);
- // get the action data object pushed in isApplicable() method call
- IADataForBasicProperty actionData = (IADataForBasicProperty) actionDataStack.peek();
- switch (actionData.aggregationType) {
- case AS_BASIC_PROPERTY:
- actionData.parentBean.setProperty(actionData.propertyName, finalBody);
- break;
- case AS_BASIC_PROPERTY_COLLECTION:
- actionData.parentBean.addBasicProperty(actionData.propertyName, finalBody);
- break;
- default:
- addError("Unexpected aggregationType " + actionData.aggregationType);
- }
+ }
+
+ public void begin(InterpretationContext ec, String localName,
+ Attributes attributes) {
+ // NOP
+ }
+
+ public void body(InterpretationContext ec, String body) {
+
+ String finalBody = ec.subst(body);
+ // get the action data object pushed in isApplicable() method call
+ IADataForBasicProperty actionData = (IADataForBasicProperty) actionDataStack.peek();
+ switch (actionData.aggregationType) {
+ case AS_BASIC_PROPERTY:
+ actionData.parentBean.setProperty(actionData.propertyName, finalBody);
+ break;
+ case AS_BASIC_PROPERTY_COLLECTION:
+ actionData.parentBean
+ .addBasicProperty(actionData.propertyName, finalBody);
}
+ }
- public void end(InterpretationContext ec, String tagName) {
- // pop the action data object pushed in isApplicable() method call
- actionDataStack.pop();
- }
+ public void end(InterpretationContext ec, String tagName) {
+ // pop the action data object pushed in isApplicable() method call
+ actionDataStack.pop();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.java
index 26edc27..2689e39 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,13 +16,11 @@ package ch.qos.logback.core.joran.action;
import java.util.Stack;
import ch.qos.logback.core.joran.spi.ElementPath;
-
import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.joran.spi.NoAutoStartUtil;
import ch.qos.logback.core.joran.util.PropertySetter;
-import ch.qos.logback.core.joran.util.beans.BeanDescriptionCache;
import ch.qos.logback.core.spi.ContextAware;
import ch.qos.logback.core.spi.LifeCycle;
import ch.qos.logback.core.util.AggregationType;
@@ -32,154 +30,163 @@ import ch.qos.logback.core.util.OptionHelper;
/**
* This action is responsible for tying together a parent object with a child
* element for which there is no explicit rule.
- *
+ *
* @author Ceki Gülcü
*/
public class NestedComplexPropertyIA extends ImplicitAction {
- // actionDataStack contains ActionData instances
- // We use a stack of ActionData objects in order to support nested
- // elements which are handled by the same NestedComplexPropertyIA instance.
- // We push a ActionData instance in the isApplicable method (if the
- // action is applicable) and pop it in the end() method.
- // The XML well-formedness property will guarantee that a push will eventually
- // be followed by a corresponding pop.
- Stack<IADataForComplexProperty> actionDataStack = new Stack<IADataForComplexProperty>();
+ // actionDataStack contains ActionData instances
+ // We use a stack of ActionData objects in order to support nested
+ // elements which are handled by the same NestedComplexPropertyIA instance.
+ // We push a ActionData instance in the isApplicable method (if the
+ // action is applicable) and pop it in the end() method.
+ // The XML well-formedness property will guarantee that a push will eventually
+ // be followed by a corresponding pop.
+ Stack<IADataForComplexProperty> actionDataStack = new Stack<IADataForComplexProperty>();
- private final BeanDescriptionCache beanDescriptionCache;
+ public boolean isApplicable(ElementPath elementPath, Attributes attributes,
+ InterpretationContext ic) {
- public NestedComplexPropertyIA(BeanDescriptionCache beanDescriptionCache) {
- this.beanDescriptionCache = beanDescriptionCache;
- }
+ String nestedElementTagName = elementPath.peekLast();
- public boolean isApplicable(ElementPath elementPath, Attributes attributes, InterpretationContext ic) {
+ // calling ic.peekObject with an empty stack will throw an exception
+ if (ic.isEmpty()) {
+ return false;
+ }
- String nestedElementTagName = elementPath.peekLast();
+ Object o = ic.peekObject();
+ PropertySetter parentBean = new PropertySetter(o);
+ parentBean.setContext(context);
+
+ AggregationType aggregationType = parentBean
+ .computeAggregationType(nestedElementTagName);
+
+ switch (aggregationType) {
+ case NOT_FOUND:
+ case AS_BASIC_PROPERTY:
+ case AS_BASIC_PROPERTY_COLLECTION:
+ return false;
+
+ // we only push action data if NestComponentIA is applicable
+ case AS_COMPLEX_PROPERTY_COLLECTION:
+ case AS_COMPLEX_PROPERTY:
+ IADataForComplexProperty ad = new IADataForComplexProperty(parentBean,
+ aggregationType, nestedElementTagName);
+ actionDataStack.push(ad);
+
+ return true;
+ default:
+ addError("PropertySetter.computeAggregationType returned "
+ + aggregationType);
+ return false;
+ }
+ }
+
+ public void begin(InterpretationContext ec, String localName,
+ Attributes attributes) {
+ // LogLog.debug("in NestComponentIA begin method");
+ // get the action data object pushed in isApplicable() method call
+ IADataForComplexProperty actionData = (IADataForComplexProperty) actionDataStack
+ .peek();
+
+ String className = attributes.getValue(CLASS_ATTRIBUTE);
+ // perform variable name substitution
+ className = ec.subst(className);
+
+ Class<?> componentClass = null;
+ try {
+
+ if (!OptionHelper.isEmpty(className)) {
+ componentClass = Loader.loadClass(className, context);
+ } else {
+ // guess class name via implicit rules
+ PropertySetter parentBean = actionData.parentBean;
+ componentClass = parentBean.getClassNameViaImplicitRules(actionData
+ .getComplexPropertyName(), actionData.getAggregationType(), ec
+ .getDefaultNestedComponentRegistry());
+ }
+
+ if (componentClass == null) {
+ actionData.inError = true;
+ String errMsg = "Could not find an appropriate class for property ["
+ + localName + "]";
+ addError(errMsg);
+ return;
+ }
+
+ if (OptionHelper.isEmpty(className)) {
+ addInfo("Assuming default type [" + componentClass.getName()
+ + "] for [" + localName + "] property");
+ }
+
+ actionData.setNestedComplexProperty(componentClass.newInstance());
+
+ // pass along the repository
+ if (actionData.getNestedComplexProperty() instanceof ContextAware) {
+ ((ContextAware) actionData.getNestedComplexProperty())
+ .setContext(this.context);
+ }
+ //addInfo("Pushing component [" + localName
+ // + "] on top of the object stack.");
+ ec.pushObject(actionData.getNestedComplexProperty());
+
+ } catch (Exception oops) {
+ actionData.inError = true;
+ String msg = "Could not create component [" + localName + "] of type ["
+ + className + "]";
+ addError(msg, oops);
+ }
- // calling ic.peekObject with an empty stack will throw an exception
- if (ic.isEmpty()) {
- return false;
- }
+ }
- Object o = ic.peekObject();
- PropertySetter parentBean = new PropertySetter(beanDescriptionCache, o);
- parentBean.setContext(context);
+ public void end(InterpretationContext ec, String tagName) {
- AggregationType aggregationType = parentBean.computeAggregationType(nestedElementTagName);
+ // pop the action data object pushed in isApplicable() method call
+ // we assume that each this begin
+ IADataForComplexProperty actionData = (IADataForComplexProperty) actionDataStack
+ .pop();
- switch (aggregationType) {
- case NOT_FOUND:
- case AS_BASIC_PROPERTY:
- case AS_BASIC_PROPERTY_COLLECTION:
- return false;
+ if (actionData.inError) {
+ return;
+ }
- // we only push action data if NestComponentIA is applicable
- case AS_COMPLEX_PROPERTY_COLLECTION:
- case AS_COMPLEX_PROPERTY:
- IADataForComplexProperty ad = new IADataForComplexProperty(parentBean, aggregationType, nestedElementTagName);
- actionDataStack.push(ad);
+ PropertySetter nestedBean = new PropertySetter(actionData
+ .getNestedComplexProperty());
+ nestedBean.setContext(context);
- return true;
- default:
- addError("PropertySetter.computeAggregationType returned " + aggregationType);
- return false;
- }
+ // have the nested element point to its parent if possible
+ if (nestedBean.computeAggregationType("parent") == AggregationType.AS_COMPLEX_PROPERTY) {
+ nestedBean.setComplexProperty("parent", actionData.parentBean.getObj());
}
- public void begin(InterpretationContext ec, String localName, Attributes attributes) {
- // LogLog.debug("in NestComponentIA begin method");
- // get the action data object pushed in isApplicable() method call
- IADataForComplexProperty actionData = (IADataForComplexProperty) actionDataStack.peek();
-
- String className = attributes.getValue(CLASS_ATTRIBUTE);
- // perform variable name substitution
- className = ec.subst(className);
-
- Class<?> componentClass = null;
- try {
-
- if (!OptionHelper.isEmpty(className)) {
- componentClass = Loader.loadClass(className, context);
- } else {
- // guess class name via implicit rules
- PropertySetter parentBean = actionData.parentBean;
- componentClass = parentBean.getClassNameViaImplicitRules(actionData.getComplexPropertyName(), actionData.getAggregationType(),
- ec.getDefaultNestedComponentRegistry());
- }
-
- if (componentClass == null) {
- actionData.inError = true;
- String errMsg = "Could not find an appropriate class for property [" + localName + "]";
- addError(errMsg);
- return;
- }
-
- if (OptionHelper.isEmpty(className)) {
- addInfo("Assuming default type [" + componentClass.getName() + "] for [" + localName + "] property");
- }
-
- actionData.setNestedComplexProperty(componentClass.newInstance());
-
- // pass along the repository
- if (actionData.getNestedComplexProperty() instanceof ContextAware) {
- ((ContextAware) actionData.getNestedComplexProperty()).setContext(this.context);
- }
- // addInfo("Pushing component [" + localName
- // + "] on top of the object stack.");
- ec.pushObject(actionData.getNestedComplexProperty());
-
- } catch (Exception oops) {
- actionData.inError = true;
- String msg = "Could not create component [" + localName + "] of type [" + className + "]";
- addError(msg, oops);
- }
-
+ // start the nested complex property if it implements LifeCycle and is not
+ // marked with a @NoAutoStart annotation
+ Object nestedComplexProperty = actionData.getNestedComplexProperty();
+ if (nestedComplexProperty instanceof LifeCycle
+ && NoAutoStartUtil.notMarkedWithNoAutoStart(nestedComplexProperty)) {
+ ((LifeCycle) nestedComplexProperty).start();
}
- public void end(InterpretationContext ec, String tagName) {
-
- // pop the action data object pushed in isApplicable() method call
- // we assume that each this begin
- IADataForComplexProperty actionData = (IADataForComplexProperty) actionDataStack.pop();
-
- if (actionData.inError) {
- return;
- }
-
- PropertySetter nestedBean = new PropertySetter(beanDescriptionCache, actionData.getNestedComplexProperty());
- nestedBean.setContext(context);
-
- // have the nested element point to its parent if possible
- if (nestedBean.computeAggregationType("parent") == AggregationType.AS_COMPLEX_PROPERTY) {
- nestedBean.setComplexProperty("parent", actionData.parentBean.getObj());
- }
-
- // start the nested complex property if it implements LifeCycle and is not
- // marked with a @NoAutoStart annotation
- Object nestedComplexProperty = actionData.getNestedComplexProperty();
- if (nestedComplexProperty instanceof LifeCycle && NoAutoStartUtil.notMarkedWithNoAutoStart(nestedComplexProperty)) {
- ((LifeCycle) nestedComplexProperty).start();
- }
-
- Object o = ec.peekObject();
-
- if (o != actionData.getNestedComplexProperty()) {
- addError("The object on the top the of the stack is not the component pushed earlier.");
- } else {
- ec.popObject();
- // Now let us attach the component
- switch (actionData.aggregationType) {
- case AS_COMPLEX_PROPERTY:
- actionData.parentBean.setComplexProperty(tagName, actionData.getNestedComplexProperty());
-
- break;
- case AS_COMPLEX_PROPERTY_COLLECTION:
- actionData.parentBean.addComplexProperty(tagName, actionData.getNestedComplexProperty());
- break;
- default:
- addError("Unexpected aggregationType " + actionData.aggregationType);
- }
- }
+ Object o = ec.peekObject();
+
+ if (o != actionData.getNestedComplexProperty()) {
+ addError("The object on the top the of the stack is not the component pushed earlier.");
+ } else {
+ ec.popObject();
+ // Now let us attach the component
+ switch (actionData.aggregationType) {
+ case AS_COMPLEX_PROPERTY:
+ actionData.parentBean.setComplexProperty(tagName, actionData
+ .getNestedComplexProperty());
+
+ break;
+ case AS_COMPLEX_PROPERTY_COLLECTION:
+ actionData.parentBean.addComplexProperty(tagName, actionData
+ .getNestedComplexProperty());
+
+ break;
+ }
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/NewRuleAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/NewRuleAction.java
index 2a7fed7..d1bf060 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/NewRuleAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/NewRuleAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,50 +19,54 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.joran.spi.ElementSelector;
import ch.qos.logback.core.util.OptionHelper;
-public class NewRuleAction extends Action {
- boolean inError = false;
-
- /**
- * Instantiates an layout of the given class and sets its name.
- */
- public void begin(InterpretationContext ec, String localName, Attributes attributes) {
- // Let us forget about previous errors (in this object)
- inError = false;
- String errorMsg;
- String pattern = attributes.getValue(Action.PATTERN_ATTRIBUTE);
- String actionClass = attributes.getValue(Action.ACTION_CLASS_ATTRIBUTE);
- if (OptionHelper.isEmpty(pattern)) {
- inError = true;
- errorMsg = "No 'pattern' attribute in <newRule>";
- addError(errorMsg);
- return;
- }
+public class NewRuleAction extends Action {
+ boolean inError = false;
- if (OptionHelper.isEmpty(actionClass)) {
- inError = true;
- errorMsg = "No 'actionClass' attribute in <newRule>";
- addError(errorMsg);
- return;
- }
+ /**
+ * Instantiates an layout of the given class and sets its name.
+ */
+ public void begin(InterpretationContext ec, String localName, Attributes attributes) {
+ // Let us forget about previous errors (in this object)
+ inError = false;
+ String errorMsg;
+ String pattern = attributes.getValue(Action.PATTERN_ATTRIBUTE);
+ String actionClass = attributes.getValue(Action.ACTION_CLASS_ATTRIBUTE);
- try {
- addInfo("About to add new Joran parsing rule [" + pattern + "," + actionClass + "].");
- ec.getJoranInterpreter().getRuleStore().addRule(new ElementSelector(pattern), actionClass);
- } catch (Exception oops) {
- inError = true;
- errorMsg = "Could not add new Joran parsing rule [" + pattern + "," + actionClass + "]";
- addError(errorMsg);
- }
+ if (OptionHelper.isEmpty(pattern)) {
+ inError = true;
+ errorMsg = "No 'pattern' attribute in <newRule>";
+ addError(errorMsg);
+ return;
}
- /**
- * Once the children elements are also parsed, now is the time to activate the
- * appender options.
- */
- public void end(InterpretationContext ec, String n) {
+ if (OptionHelper.isEmpty(actionClass)) {
+ inError = true;
+ errorMsg = "No 'actionClass' attribute in <newRule>";
+ addError(errorMsg);
+ return;
}
- public void finish(InterpretationContext ec) {
+ try {
+ addInfo("About to add new Joran parsing rule [" + pattern + ","
+ + actionClass + "].");
+ ec.getJoranInterpreter().getRuleStore().addRule(new ElementSelector(pattern),
+ actionClass);
+ } catch (Exception oops) {
+ inError = true;
+ errorMsg = "Could not add new Joran parsing rule [" + pattern + ","
+ + actionClass + "]";
+ addError(errorMsg);
}
+ }
+
+ /**
+ * Once the children elements are also parsed, now is the time to activate the
+ * appender options.
+ */
+ public void end(InterpretationContext ec, String n) {
+ }
+
+ public void finish(InterpretationContext ec) {
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/ParamAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/ParamAction.java
index 7d0a896..970ad3c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/ParamAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/ParamAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,57 +13,55 @@
*/
package ch.qos.logback.core.joran.action;
+
import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.joran.util.PropertySetter;
-import ch.qos.logback.core.joran.util.beans.BeanDescriptionCache;
-public class ParamAction extends Action {
- static String NO_NAME = "No name attribute in <param> element";
- static String NO_VALUE = "No name attribute in <param> element";
- boolean inError = false;
- private final BeanDescriptionCache beanDescriptionCache;
- public ParamAction(BeanDescriptionCache beanDescriptionCache) {
- this.beanDescriptionCache=beanDescriptionCache;
- }
- public void begin(InterpretationContext ec, String localName, Attributes attributes) {
- String name = attributes.getValue(NAME_ATTRIBUTE);
- String value = attributes.getValue(VALUE_ATTRIBUTE);
+public class ParamAction extends Action {
+ static String NO_NAME = "No name attribute in <param> element";
+ static String NO_VALUE = "No name attribute in <param> element";
+ boolean inError = false;
- if (name == null) {
- inError = true;
- addError(NO_NAME);
- return;
- }
+ public void begin(
+ InterpretationContext ec, String localName, Attributes attributes) {
+ String name = attributes.getValue(NAME_ATTRIBUTE);
+ String value = attributes.getValue(VALUE_ATTRIBUTE);
- if (value == null) {
- inError = true;
- addError(NO_VALUE);
- return;
- }
+ if (name == null) {
+ inError = true;
+ addError(NO_NAME);
+ return;
+ }
- // remove both leading and trailing spaces
- value = value.trim();
+ if (value == null) {
+ inError = true;
+ addError(NO_VALUE);
+ return;
+ }
- Object o = ec.peekObject();
- PropertySetter propSetter = new PropertySetter(beanDescriptionCache,o);
- propSetter.setContext(context);
- value = ec.subst(value);
+ // remove both leading and trailing spaces
+ value = value.trim();
- // allow for variable substitution for name as well
- name = ec.subst(name);
+ Object o = ec.peekObject();
+ PropertySetter propSetter = new PropertySetter(o);
+ propSetter.setContext(context);
+ value = ec.subst(value);
- // getLogger().debug(
- // "In ParamAction setting parameter [{}] to value [{}].", name, value);
- propSetter.setProperty(name, value);
- }
+ // allow for variable substitution for name as well
+ name = ec.subst(name);
- public void end(InterpretationContext ec, String localName) {
- }
+ //getLogger().debug(
+ // "In ParamAction setting parameter [{}] to value [{}].", name, value);
+ propSetter.setProperty(name, value);
+ }
- public void finish(InterpretationContext ec) {
- }
+ public void end(InterpretationContext ec, String localName) {
+ }
+
+ public void finish(InterpretationContext ec) {
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/PropertyAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/PropertyAction.java
index ce428c5..b129586 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/PropertyAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/PropertyAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -40,102 +40,111 @@ import ch.qos.logback.core.util.OptionHelper;
*/
public class PropertyAction extends Action {
- static final String RESOURCE_ATTRIBUTE = "resource";
+ static final String RESOURCE_ATTRIBUTE = "resource";
- static String INVALID_ATTRIBUTES = "In <property> element, either the \"file\" attribute alone, or "
- + "the \"resource\" element alone, or both the \"name\" and \"value\" attributes must be set.";
- /**
- * Set a new property for the execution context by name, value pair, or adds
- * all the properties found in the given file.
- *
- */
- public void begin(InterpretationContext ec, String localName, Attributes attributes) {
+ static String INVALID_ATTRIBUTES = "In <property> element, either the \"file\" attribute alone, or "
+ + "the \"resource\" element alone, or both the \"name\" and \"value\" attributes must be set.";
- if ("substitutionProperty".equals(localName)) {
- addWarn("[substitutionProperty] element has been deprecated. Please use the [property] element instead.");
- }
-
- String name = attributes.getValue(NAME_ATTRIBUTE);
- String value = attributes.getValue(VALUE_ATTRIBUTE);
- String scopeStr = attributes.getValue(SCOPE_ATTRIBUTE);
-
- Scope scope = ActionUtil.stringToScope(scopeStr);
-
- if (checkFileAttributeSanity(attributes)) {
- String file = attributes.getValue(FILE_ATTRIBUTE);
- file = ec.subst(file);
- try {
- FileInputStream istream = new FileInputStream(file);
- loadAndSetProperties(ec, istream, scope);
- } catch (FileNotFoundException e) {
- addError("Could not find properties file [" + file + "].");
- } catch (IOException e1) {
- addError("Could not read properties file [" + file + "].", e1);
- }
- } else if (checkResourceAttributeSanity(attributes)) {
- String resource = attributes.getValue(RESOURCE_ATTRIBUTE);
- resource = ec.subst(resource);
- URL resourceURL = Loader.getResourceBySelfClassLoader(resource);
- if (resourceURL == null) {
- addError("Could not find resource [" + resource + "].");
- } else {
- try {
- InputStream istream = resourceURL.openStream();
- loadAndSetProperties(ec, istream, scope);
- } catch (IOException e) {
- addError("Could not read resource file [" + resource + "].", e);
- }
- }
- } else if (checkValueNameAttributesSanity(attributes)) {
- value = RegularEscapeUtil.basicEscape(value);
- // now remove both leading and trailing spaces
- value = value.trim();
- value = ec.subst(value);
- ActionUtil.setProperty(ec, name, value, scope);
-
- } else {
- addError(INVALID_ATTRIBUTES);
- }
- }
- void loadAndSetProperties(InterpretationContext ec, InputStream istream, Scope scope) throws IOException {
- Properties props = new Properties();
- props.load(istream);
- istream.close();
- ActionUtil.setProperties(ec, props, scope);
- }
-
- boolean checkFileAttributeSanity(Attributes attributes) {
- String file = attributes.getValue(FILE_ATTRIBUTE);
- String name = attributes.getValue(NAME_ATTRIBUTE);
- String value = attributes.getValue(VALUE_ATTRIBUTE);
- String resource = attributes.getValue(RESOURCE_ATTRIBUTE);
+ /**
+ * Set a new property for the execution context by name, value pair, or adds
+ * all the properties found in the given file.
+ *
+ */
+ public void begin(InterpretationContext ec, String localName,
+ Attributes attributes) {
- return !(OptionHelper.isEmpty(file)) && (OptionHelper.isEmpty(name) && OptionHelper.isEmpty(value) && OptionHelper.isEmpty(resource));
+ if ("substitutionProperty".equals(localName)) {
+ addWarn("[substitutionProperty] element has been deprecated. Please use the [property] element instead.");
}
- boolean checkResourceAttributeSanity(Attributes attributes) {
- String file = attributes.getValue(FILE_ATTRIBUTE);
- String name = attributes.getValue(NAME_ATTRIBUTE);
- String value = attributes.getValue(VALUE_ATTRIBUTE);
- String resource = attributes.getValue(RESOURCE_ATTRIBUTE);
-
- return !(OptionHelper.isEmpty(resource)) && (OptionHelper.isEmpty(name) && OptionHelper.isEmpty(value) && OptionHelper.isEmpty(file));
- }
-
- boolean checkValueNameAttributesSanity(Attributes attributes) {
- String file = attributes.getValue(FILE_ATTRIBUTE);
- String name = attributes.getValue(NAME_ATTRIBUTE);
- String value = attributes.getValue(VALUE_ATTRIBUTE);
- String resource = attributes.getValue(RESOURCE_ATTRIBUTE);
-
- return (!(OptionHelper.isEmpty(name) || OptionHelper.isEmpty(value)) && (OptionHelper.isEmpty(file) && OptionHelper.isEmpty(resource)));
- }
-
- public void end(InterpretationContext ec, String name) {
- }
-
- public void finish(InterpretationContext ec) {
+ String name = attributes.getValue(NAME_ATTRIBUTE);
+ String value = attributes.getValue(VALUE_ATTRIBUTE);
+ String scopeStr = attributes.getValue(SCOPE_ATTRIBUTE);
+
+ Scope scope = ActionUtil.stringToScope(scopeStr);
+
+ if (checkFileAttributeSanity(attributes)) {
+ String file = attributes.getValue(FILE_ATTRIBUTE);
+ file = ec.subst(file);
+ try {
+ FileInputStream istream = new FileInputStream(file);
+ loadAndSetProperties(ec, istream, scope);
+ } catch (FileNotFoundException e) {
+ addError("Could not find properties file [" + file + "].");
+ } catch (IOException e1) {
+ addError("Could not read properties file [" + file + "].", e1);
+ }
+ } else if (checkResourceAttributeSanity(attributes)) {
+ String resource = attributes.getValue(RESOURCE_ATTRIBUTE);
+ resource = ec.subst(resource);
+ URL resourceURL = Loader.getResourceBySelfClassLoader(resource);
+ if (resourceURL == null) {
+ addError("Could not find resource [" + resource + "].");
+ } else {
+ try {
+ InputStream istream = resourceURL.openStream();
+ loadAndSetProperties(ec, istream, scope);
+ } catch (IOException e) {
+ addError("Could not read resource file [" + resource + "].", e);
+ }
+ }
+ } else if (checkValueNameAttributesSanity(attributes)) {
+ value = RegularEscapeUtil.basicEscape(value);
+ // now remove both leading and trailing spaces
+ value = value.trim();
+ value = ec.subst(value);
+ ActionUtil.setProperty(ec, name, value, scope);
+
+ } else {
+ addError(INVALID_ATTRIBUTES);
}
+ }
+
+ void loadAndSetProperties(InterpretationContext ec, InputStream istream, Scope scope)
+ throws IOException {
+ Properties props = new Properties();
+ props.load(istream);
+ istream.close();
+ ActionUtil.setProperties(ec, props, scope);
+ }
+
+ boolean checkFileAttributeSanity(Attributes attributes) {
+ String file = attributes.getValue(FILE_ATTRIBUTE);
+ String name = attributes.getValue(NAME_ATTRIBUTE);
+ String value = attributes.getValue(VALUE_ATTRIBUTE);
+ String resource = attributes.getValue(RESOURCE_ATTRIBUTE);
+
+ return !(OptionHelper.isEmpty(file))
+ && (OptionHelper.isEmpty(name) && OptionHelper.isEmpty(value) && OptionHelper
+ .isEmpty(resource));
+ }
+
+ boolean checkResourceAttributeSanity(Attributes attributes) {
+ String file = attributes.getValue(FILE_ATTRIBUTE);
+ String name = attributes.getValue(NAME_ATTRIBUTE);
+ String value = attributes.getValue(VALUE_ATTRIBUTE);
+ String resource = attributes.getValue(RESOURCE_ATTRIBUTE);
+
+ return !(OptionHelper.isEmpty(resource))
+ && (OptionHelper.isEmpty(name) && OptionHelper.isEmpty(value) && OptionHelper
+ .isEmpty(file));
+ }
+
+ boolean checkValueNameAttributesSanity(Attributes attributes) {
+ String file = attributes.getValue(FILE_ATTRIBUTE);
+ String name = attributes.getValue(NAME_ATTRIBUTE);
+ String value = attributes.getValue(VALUE_ATTRIBUTE);
+ String resource = attributes.getValue(RESOURCE_ATTRIBUTE);
+
+ return (!(OptionHelper.isEmpty(name) || OptionHelper.isEmpty(value)) && (OptionHelper
+ .isEmpty(file) && OptionHelper.isEmpty(resource)));
+ }
+
+ public void end(InterpretationContext ec, String name) {
+ }
+
+ public void finish(InterpretationContext ec) {
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/ShutdownHookAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/ShutdownHookAction.java
deleted file mode 100644
index 80533b2..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/ShutdownHookAction.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.joran.action;
-
-import org.xml.sax.Attributes;
-
-import ch.qos.logback.core.CoreConstants;
-import ch.qos.logback.core.hook.ShutdownHookBase;
-import ch.qos.logback.core.joran.spi.ActionException;
-import ch.qos.logback.core.joran.spi.InterpretationContext;
-import ch.qos.logback.core.util.OptionHelper;
-
-/**
- * Action which handles <shutdownHook> elements in configuration files.
- *
- * @author Mike Reinhold
- */
-public class ShutdownHookAction extends Action {
-
- ShutdownHookBase hook;
- private boolean inError;
-
- /**
- * Instantiates a shutdown hook of the given class and sets its name.
- *
- * The hook thus generated is placed in the {@link InterpretationContext}'s
- * shutdown hook bag.
- */
- @Override
- public void begin(InterpretationContext ic, String name, Attributes attributes) throws ActionException {
- hook = null;
- inError = false;
-
- String className = attributes.getValue(CLASS_ATTRIBUTE);
- if (OptionHelper.isEmpty(className)) {
- addError("Missing class name for shutdown hook. Near [" + name + "] line " + getLineNumber(ic));
- inError = true;
- return;
- }
-
- try {
- addInfo("About to instantiate shutdown hook of type [" + className + "]");
-
- hook = (ShutdownHookBase) OptionHelper.instantiateByClassName(className, ShutdownHookBase.class, context);
- hook.setContext(context);
-
- ic.pushObject(hook);
- } catch (Exception e) {
- inError = true;
- addError("Could not create a shutdown hook of type [" + className + "].", e);
- throw new ActionException(e);
- }
- }
-
- /**
- * Once the children elements are also parsed, now is the time to activate the
- * shutdown hook options.
- */
- @Override
- public void end(InterpretationContext ic, String name) throws ActionException {
- if (inError) {
- return;
- }
-
- Object o = ic.peekObject();
- if (o != hook) {
- addWarn("The object at the of the stack is not the hook pushed earlier.");
- } else {
- ic.popObject();
-
- Thread hookThread = new Thread(hook, "Logback shutdown hook [" + context.getName() + "]");
-
- context.putObject(CoreConstants.SHUTDOWN_HOOK_THREAD, hookThread);
- Runtime.getRuntime().addShutdownHook(hookThread);
- }
- }
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/StatusListenerAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/StatusListenerAction.java
index f4a5d84..8d10339 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/StatusListenerAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/StatusListenerAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,59 +22,56 @@ import ch.qos.logback.core.spi.LifeCycle;
import ch.qos.logback.core.status.StatusListener;
import ch.qos.logback.core.util.OptionHelper;
-public class StatusListenerAction extends Action {
- boolean inError = false;
- Boolean effectivelyAdded = null;
- StatusListener statusListener = null;
+public class StatusListenerAction extends Action {
- public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
- inError = false;
- effectivelyAdded = null;
- String className = attributes.getValue(CLASS_ATTRIBUTE);
- if (OptionHelper.isEmpty(className)) {
- addError("Missing class name for statusListener. Near [" + name + "] line " + getLineNumber(ec));
- inError = true;
- return;
- }
- try {
- statusListener = (StatusListener) OptionHelper.instantiateByClassName(className, StatusListener.class, context);
- effectivelyAdded = ec.getContext().getStatusManager().add(statusListener);
- if (statusListener instanceof ContextAware) {
- ((ContextAware) statusListener).setContext(context);
- }
- addInfo("Added status listener of type [" + className + "]");
- ec.pushObject(statusListener);
- } catch (Exception e) {
- inError = true;
- addError("Could not create an StatusListener of type [" + className + "].", e);
- throw new ActionException(e);
- }
+ boolean inError = false;
+ StatusListener statusListener = null;
+ public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
+ inError = false;
+ String className = attributes.getValue(CLASS_ATTRIBUTE);
+ if (OptionHelper.isEmpty(className)) {
+ addError("Missing class name for statusListener. Near ["
+ + name + "] line " + getLineNumber(ec));
+ inError = true;
+ return;
}
- public void finish(InterpretationContext ec) {
+ try {
+ statusListener = (StatusListener) OptionHelper.instantiateByClassName(
+ className, StatusListener.class, context);
+ ec.getContext().getStatusManager().add(statusListener);
+ if (statusListener instanceof ContextAware) {
+ ((ContextAware) statusListener).setContext(context);
+ }
+ addInfo("Added status listener of type [" + className + "]");
+ ec.pushObject(statusListener);
+ } catch (Exception e) {
+ inError = true;
+ addError(
+ "Could not create an StatusListener of type [" + className + "].", e);
+ throw new ActionException(e);
}
- public void end(InterpretationContext ec, String e) {
- if (inError) {
- return;
- }
- if (isEffectivelyAdded() && statusListener instanceof LifeCycle) {
- ((LifeCycle) statusListener).start();
- }
- Object o = ec.peekObject();
- if (o != statusListener) {
- addWarn("The object at the of the stack is not the statusListener pushed earlier.");
- } else {
- ec.popObject();
- }
- }
+ }
- private boolean isEffectivelyAdded() {
- if (effectivelyAdded == null)
- return false;
- return effectivelyAdded;
+ public void finish(InterpretationContext ec) {
+ }
+
+ public void end(InterpretationContext ec, String e) {
+ if (inError) {
+ return;
+ }
+ if (statusListener instanceof LifeCycle) {
+ ((LifeCycle) statusListener).start();
+ }
+ Object o = ec.peekObject();
+ if (o != statusListener) {
+ addWarn("The object at the of the stack is not the statusListener pushed earlier.");
+ } else {
+ ec.popObject();
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/TimestampAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/TimestampAction.java
index 621df84..900fdfb 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/TimestampAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/TimestampAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,50 +30,54 @@ import ch.qos.logback.core.util.OptionHelper;
*
*/
public class TimestampAction extends Action {
- static String DATE_PATTERN_ATTRIBUTE = "datePattern";
- static String TIME_REFERENCE_ATTRIBUTE = "timeReference";
- static String CONTEXT_BIRTH = "contextBirth";
+ static String DATE_PATTERN_ATTRIBUTE = "datePattern";
+ static String TIME_REFERENCE_ATTRIBUTE = "timeReference";
+ static String CONTEXT_BIRTH = "contextBirth";
- boolean inError = false;
+ boolean inError = false;
- @Override
- public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
- String keyStr = attributes.getValue(KEY_ATTRIBUTE);
- if (OptionHelper.isEmpty(keyStr)) {
- addError("Attribute named [" + KEY_ATTRIBUTE + "] cannot be empty");
- inError = true;
- }
- String datePatternStr = attributes.getValue(DATE_PATTERN_ATTRIBUTE);
- if (OptionHelper.isEmpty(datePatternStr)) {
- addError("Attribute named [" + DATE_PATTERN_ATTRIBUTE + "] cannot be empty");
- inError = true;
- }
+ @Override
+ public void begin(InterpretationContext ec, String name, Attributes attributes)
+ throws ActionException {
+ String keyStr = attributes.getValue(KEY_ATTRIBUTE);
+ if (OptionHelper.isEmpty(keyStr)) {
+ addError("Attribute named [" + KEY_ATTRIBUTE + "] cannot be empty");
+ inError = true;
+ }
+ String datePatternStr = attributes.getValue(DATE_PATTERN_ATTRIBUTE);
+ if (OptionHelper.isEmpty(datePatternStr)) {
+ addError("Attribute named [" + DATE_PATTERN_ATTRIBUTE
+ + "] cannot be empty");
+ inError = true;
+ }
- String timeReferenceStr = attributes.getValue(TIME_REFERENCE_ATTRIBUTE);
- long timeReference;
- if (CONTEXT_BIRTH.equalsIgnoreCase(timeReferenceStr)) {
- addInfo("Using context birth as time reference.");
- timeReference = context.getBirthTime();
- } else {
- timeReference = System.currentTimeMillis();
- addInfo("Using current interpretation time, i.e. now, as time reference.");
- }
+ String timeReferenceStr = attributes.getValue(TIME_REFERENCE_ATTRIBUTE);
+ long timeReference;
+ if (CONTEXT_BIRTH.equalsIgnoreCase(timeReferenceStr)) {
+ addInfo("Using context birth as time reference.");
+ timeReference = context.getBirthTime();
+ } else {
+ timeReference = System.currentTimeMillis();
+ addInfo("Using current interpretation time, i.e. now, as time reference.");
+ }
- if (inError)
- return;
- String scopeStr = attributes.getValue(SCOPE_ATTRIBUTE);
- Scope scope = ActionUtil.stringToScope(scopeStr);
+ if (inError)
+ return;
- CachingDateFormatter sdf = new CachingDateFormatter(datePatternStr);
- String val = sdf.format(timeReference);
+ String scopeStr = attributes.getValue(SCOPE_ATTRIBUTE);
+ Scope scope = ActionUtil.stringToScope(scopeStr);
+
+ CachingDateFormatter sdf = new CachingDateFormatter(datePatternStr);
+ String val = sdf.format(timeReference);
- addInfo("Adding property to the context with key=\"" + keyStr + "\" and value=\"" + val + "\" to the " + scope + " scope");
- ActionUtil.setProperty(ec, keyStr, val, scope);
- }
+ addInfo("Adding property to the context with key=\"" + keyStr
+ + "\" and value=\"" + val + "\" to the " + scope + " scope");
+ ActionUtil.setProperty(ec, keyStr, val, scope);
+ }
- @Override
- public void end(InterpretationContext ec, String name) throws ActionException {
- }
+ @Override
+ public void end(InterpretationContext ec, String name) throws ActionException {
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/Condition.java b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/Condition.java
index f5bfa17..31ee094 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/Condition.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/Condition.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,5 +14,5 @@
package ch.qos.logback.core.joran.conditional;
public interface Condition {
- boolean evaluate();
+ boolean evaluate();
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ElseAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ElseAction.java
index 6b90f66..88dc585 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ElseAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ElseAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,12 +17,12 @@ import java.util.List;
import ch.qos.logback.core.joran.event.SaxEvent;
-public class ElseAction extends ThenOrElseActionBase {
+public class ElseAction extends ThenOrElseActionBase {
- @Override
- void registerEventList(IfAction ifAction, List<SaxEvent> eventList) {
- ifAction.setElseSaxEventList(eventList);
-
- }
+ @Override
+ void registerEventList(IfAction ifAction, List<SaxEvent> eventList) {
+ ifAction.setElseSaxEventList(eventList);
+
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java
index 7b3376a..48609c7 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,123 +28,128 @@ import ch.qos.logback.core.joran.spi.Interpreter;
import ch.qos.logback.core.util.OptionHelper;
public class IfAction extends Action {
- private static final String CONDITION_ATTR = "condition";
-
- public static final String MISSING_JANINO_MSG = "Could not find Janino library on the class path. Skipping conditional processing.";
- public static final String MISSING_JANINO_SEE = "See also " + CoreConstants.CODES_URL + "#ifJanino";
-
- Stack<IfState> stack = new Stack<IfState>();
-
- @Override
- public void begin(InterpretationContext ic, String name, Attributes attributes) throws ActionException {
-
- IfState state = new IfState();
- boolean emptyStack = stack.isEmpty();
- stack.push(state);
-
- if (!emptyStack) {
- return;
- }
-
- ic.pushObject(this);
- if (!EnvUtil.isJaninoAvailable()) {
- addError(MISSING_JANINO_MSG);
- addError(MISSING_JANINO_SEE);
- return;
- }
-
- state.active = true;
- Condition condition = null;
- String conditionAttribute = attributes.getValue(CONDITION_ATTR);
-
- if (!OptionHelper.isEmpty(conditionAttribute)) {
- conditionAttribute = OptionHelper.substVars(conditionAttribute, ic, context);
- PropertyEvalScriptBuilder pesb = new PropertyEvalScriptBuilder(ic);
- pesb.setContext(context);
- try {
- condition = pesb.build(conditionAttribute);
- } catch (Exception e) {
- addError("Failed to parse condition [" + conditionAttribute + "]", e);
- }
-
- if (condition != null) {
- state.boolResult = condition.evaluate();
- }
-
- }
+ private static final String CONDITION_ATTR = "condition";
+
+ public static final String MISSING_JANINO_MSG = "Could not find Janino library on the class path. Skipping conditional processing.";
+ public static final String MISSING_JANINO_SEE = "See also " + CoreConstants.CODES_URL + "#ifJanino";
+
+ Stack<IfState> stack = new Stack<IfState>();
+
+ @Override
+ public void begin(InterpretationContext ic, String name, Attributes attributes)
+ throws ActionException {
+
+ IfState state = new IfState();
+ boolean emptyStack = stack.isEmpty();
+ stack.push(state);
+
+ if(!emptyStack) {
+ return;
}
+
+ ic.pushObject(this);
+ if(!EnvUtil.isJaninoAvailable()) {
+ addError(MISSING_JANINO_MSG);
+ addError(MISSING_JANINO_SEE);
+ return;
+ }
+
+ state.active = true;
+ Condition condition = null;
+ String conditionAttribute = attributes.getValue(CONDITION_ATTR);
+
+
+ if (!OptionHelper.isEmpty(conditionAttribute)) {
+ conditionAttribute = OptionHelper.substVars(conditionAttribute, ic, context);
+ PropertyEvalScriptBuilder pesb = new PropertyEvalScriptBuilder(ic);
+ pesb.setContext(context);
+ try {
+ condition = pesb.build(conditionAttribute);
+ } catch (Exception e) {
+ addError("Failed to parse condition ["+conditionAttribute+"]", e);
+ }
+
+ if(condition!=null) {
+ state.boolResult = condition.evaluate();
+ }
+
+ }
+ }
+
- @Override
- public void end(InterpretationContext ic, String name) throws ActionException {
-
- IfState state = stack.pop();
- if (!state.active) {
- return;
- }
-
- Object o = ic.peekObject();
- if (o == null) {
- throw new IllegalStateException("Unexpected null object on stack");
- }
- if (!(o instanceof IfAction)) {
- throw new IllegalStateException("Unexpected object of type [" + o.getClass() + "] on stack");
- }
-
- if (o != this) {
- throw new IllegalStateException("IfAction different then current one on stack");
- }
- ic.popObject();
-
- if (state.boolResult == null) {
- addError("Failed to determine \"if then else\" result");
- return;
- }
-
- Interpreter interpreter = ic.getJoranInterpreter();
- List<SaxEvent> listToPlay = state.thenSaxEventList;
- if (!state.boolResult) {
- listToPlay = state.elseSaxEventList;
- }
-
- // if boolResult==false & missing else, listToPlay may be null
- if (listToPlay != null) {
- // insert past this event
- interpreter.getEventPlayer().addEventsDynamically(listToPlay, 1);
- }
+ @Override
+ public void end(InterpretationContext ic, String name) throws ActionException {
+
+ IfState state = stack.pop();
+ if(!state.active) {
+ return;
+ }
+
+
+ Object o = ic.peekObject();
+ if (o == null) {
+ throw new IllegalStateException("Unexpected null object on stack");
+ }
+ if (!(o instanceof IfAction)) {
+ throw new IllegalStateException("Unexpected object of type ["
+ + o.getClass() + "] on stack");
+ }
+ if (o != this) {
+ throw new IllegalStateException(
+ "IfAction different then current one on stack");
}
+ ic.popObject();
- public void setThenSaxEventList(List<SaxEvent> thenSaxEventList) {
- IfState state = stack.firstElement();
- if (state.active) {
- state.thenSaxEventList = thenSaxEventList;
- } else {
- throw new IllegalStateException("setThenSaxEventList() invoked on inactive IfAction");
- }
+ if (state.boolResult == null) {
+ addError("Failed to determine \"if then else\" result");
+ return;
}
- public void setElseSaxEventList(List<SaxEvent> elseSaxEventList) {
- IfState state = stack.firstElement();
- if (state.active) {
- state.elseSaxEventList = elseSaxEventList;
- } else {
- throw new IllegalStateException("setElseSaxEventList() invoked on inactive IfAction");
- }
+ Interpreter interpreter = ic.getJoranInterpreter();
+ List<SaxEvent> listToPlay = state.thenSaxEventList;
+ if (!state.boolResult) {
+ listToPlay = state.elseSaxEventList;
+ }
+ // if boolResult==false & missing else, listToPlay may be null
+ if(listToPlay != null) {
+ // insert past this event
+ interpreter.getEventPlayer().addEventsDynamically(listToPlay, 1);
}
- public boolean isActive() {
- if (stack == null)
- return false;
- if (stack.isEmpty())
- return false;
- return stack.peek().active;
+ }
+
+
+ public void setThenSaxEventList(List<SaxEvent> thenSaxEventList) {
+ IfState state = stack.firstElement();
+ if(state.active) {
+ state.thenSaxEventList = thenSaxEventList;
+ } else {
+ throw new IllegalStateException("setThenSaxEventList() invoked on inactive IfAction");
+ }
+ }
+
+ public void setElseSaxEventList(List<SaxEvent> elseSaxEventList) {
+ IfState state = stack.firstElement();
+ if(state.active) {
+ state.elseSaxEventList = elseSaxEventList;
+ } else {
+ throw new IllegalStateException("setElseSaxEventList() invoked on inactive IfAction");
}
+
+ }
+
+ public boolean isActive() {
+ if(stack == null) return false;
+ if(stack.isEmpty()) return false;
+ return stack.peek().active;
+ }
}
class IfState {
- Boolean boolResult;
- List<SaxEvent> thenSaxEventList;
- List<SaxEvent> elseSaxEventList;
- boolean active;
+ Boolean boolResult;
+ List<SaxEvent> thenSaxEventList;
+ List<SaxEvent> elseSaxEventList;
+ boolean active;
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/PropertyEvalScriptBuilder.java b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/PropertyEvalScriptBuilder.java
index 9ac7802..6b9c602 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/PropertyEvalScriptBuilder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/PropertyEvalScriptBuilder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,32 +26,36 @@ import ch.qos.logback.core.spi.ContextAwareBase;
public class PropertyEvalScriptBuilder extends ContextAwareBase {
- private static String SCRIPT_PREFIX = "" + "public boolean evaluate() { return ";
- private static String SCRIPT_SUFFIX = "" + "; }";
+ private static String SCRIPT_PREFIX = ""
+ + "public boolean evaluate() { return ";
+ private static String SCRIPT_SUFFIX = "" + "; }";
- final PropertyContainer localPropContainer;
+ final PropertyContainer localPropContainer;
- PropertyEvalScriptBuilder(PropertyContainer localPropContainer) {
- this.localPropContainer = localPropContainer;
- }
+ PropertyEvalScriptBuilder(PropertyContainer localPropContainer) {
+ this.localPropContainer = localPropContainer;
+ }
- Map<String, String> map = new HashMap<String, String>();
+ Map<String, String> map = new HashMap<String, String>();
- public Condition build(String script) throws IllegalAccessException, CompileException, InstantiationException, SecurityException, NoSuchMethodException,
- IllegalArgumentException, InvocationTargetException {
+ public Condition build(String script) throws IllegalAccessException,
+ CompileException,
+ InstantiationException,
+ SecurityException, NoSuchMethodException, IllegalArgumentException,
+ InvocationTargetException {
- ClassBodyEvaluator cbe = new ClassBodyEvaluator();
- cbe.setImplementedInterfaces(new Class[] { Condition.class });
- cbe.setExtendedClass(PropertyWrapperForScripts.class);
- cbe.setParentClassLoader(ClassBodyEvaluator.class.getClassLoader());
- cbe.cook(SCRIPT_PREFIX + script + SCRIPT_SUFFIX);
+ ClassBodyEvaluator cbe = new ClassBodyEvaluator();
+ cbe.setImplementedInterfaces(new Class[]{Condition.class});
+ cbe.setExtendedClass(PropertyWrapperForScripts.class);
+ cbe.setParentClassLoader(ClassBodyEvaluator.class.getClassLoader());
+ cbe.cook(SCRIPT_PREFIX + script + SCRIPT_SUFFIX);
- Class<?> clazz = cbe.getClazz();
- Condition instance = (Condition) clazz.newInstance();
- Method setMapMethod = clazz.getMethod("setPropertyContainers", PropertyContainer.class, PropertyContainer.class);
- setMapMethod.invoke(instance, localPropContainer, context);
+ Class<?> clazz = cbe.getClazz();
+ Condition instance = (Condition) clazz.newInstance();
+ Method setMapMethod = clazz.getMethod("setPropertyContainers", PropertyContainer.class, PropertyContainer.class);
+ setMapMethod.invoke(instance, localPropContainer, context);
- return instance;
- }
+ return instance;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/PropertyWrapperForScripts.java b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/PropertyWrapperForScripts.java
index 6d84a4e..8eb495c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/PropertyWrapperForScripts.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/PropertyWrapperForScripts.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,34 +18,34 @@ import ch.qos.logback.core.util.OptionHelper;
public class PropertyWrapperForScripts {
- PropertyContainer local;
- PropertyContainer context;
-
- // this method is invoked by reflection in PropertyEvalScriptBuilder
- public void setPropertyContainers(PropertyContainer local, PropertyContainer context) {
- this.local = local;
- this.context = context;
- }
-
- public boolean isNull(String k) {
- String val = OptionHelper.propertyLookup(k, local, context);
- return (val == null);
- }
-
- public boolean isDefined(String k) {
- String val = OptionHelper.propertyLookup(k, local, context);
- return (val != null);
- }
-
- public String p(String k) {
- return property(k);
- }
-
- public String property(String k) {
- String val = OptionHelper.propertyLookup(k, local, context);
- if (val != null)
- return val;
- else
- return "";
- }
+ PropertyContainer local;
+ PropertyContainer context;
+
+ // this method is invoked by reflection in PropertyEvalScriptBuilder
+ public void setPropertyContainers(PropertyContainer local, PropertyContainer context) {
+ this.local = local;
+ this.context = context;
+ }
+
+ public boolean isNull(String k) {
+ String val = OptionHelper.propertyLookup(k, local, context);
+ return (val == null);
+ }
+
+ public boolean isDefined(String k) {
+ String val = OptionHelper.propertyLookup(k, local, context);
+ return (val != null);
+ }
+
+ public String p(String k) {
+ return property(k);
+ }
+
+ public String property(String k) {
+ String val = OptionHelper.propertyLookup(k, local, context);
+ if(val != null)
+ return val;
+ else
+ return "";
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenAction.java
index 5853aa6..f0acd4f 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,11 +17,11 @@ import java.util.List;
import ch.qos.logback.core.joran.event.SaxEvent;
-public class ThenAction extends ThenOrElseActionBase {
+public class ThenAction extends ThenOrElseActionBase {
- @Override
- void registerEventList(IfAction ifAction, List<SaxEvent> eventList) {
- ifAction.setThenSaxEventList(eventList);
- }
+ @Override
+ void registerEventList(IfAction ifAction, List<SaxEvent> eventList) {
+ ifAction.setThenSaxEventList(eventList);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenOrElseActionBase.java b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenOrElseActionBase.java
index dca62eb..b4ca29b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenOrElseActionBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenOrElseActionBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,64 +27,62 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
abstract public class ThenOrElseActionBase extends Action {
- Stack<ThenActionState> stateStack = new Stack<ThenActionState>();
+ Stack<ThenActionState> stateStack = new Stack<ThenActionState>();
- @Override
- public void begin(InterpretationContext ic, String name, Attributes attributes) throws ActionException {
+ @Override
+ public void begin(InterpretationContext ic, String name, Attributes attributes)
+ throws ActionException {
- if (!weAreActive(ic))
- return;
+ if(!weAreActive(ic)) return;
- ThenActionState state = new ThenActionState();
- if (ic.isListenerListEmpty()) {
- ic.addInPlayListener(state);
- state.isRegistered = true;
- }
- stateStack.push(state);
+ ThenActionState state = new ThenActionState();
+ if (ic.isListenerListEmpty()) {
+ ic.addInPlayListener(state);
+ state.isRegistered = true;
}
-
- boolean weAreActive(InterpretationContext ic) {
- Object o = ic.peekObject();
- if (!(o instanceof IfAction))
- return false;
+ stateStack.push(state);
+ }
+
+ boolean weAreActive(InterpretationContext ic) {
+ Object o = ic.peekObject();
+ if(!(o instanceof IfAction)) return false;
+ IfAction ifAction = (IfAction) o;
+ return ifAction.isActive();
+ }
+
+ @Override
+ public void end(InterpretationContext ic, String name) throws ActionException {
+ if(!weAreActive(ic)) return;
+
+ ThenActionState state = stateStack.pop();
+ if (state.isRegistered) {
+ ic.removeInPlayListener(state);
+ Object o = ic.peekObject();
+ if (o instanceof IfAction) {
IfAction ifAction = (IfAction) o;
- return ifAction.isActive();
- }
-
- @Override
- public void end(InterpretationContext ic, String name) throws ActionException {
- if (!weAreActive(ic))
- return;
-
- ThenActionState state = stateStack.pop();
- if (state.isRegistered) {
- ic.removeInPlayListener(state);
- Object o = ic.peekObject();
- if (o instanceof IfAction) {
- IfAction ifAction = (IfAction) o;
- removeFirstAndLastFromList(state.eventList);
- registerEventList(ifAction, state.eventList);
- } else {
- throw new IllegalStateException("Missing IfAction on top of stack");
- }
- }
+ removeFirstAndLastFromList(state.eventList);
+ registerEventList(ifAction, state.eventList);
+ } else {
+ throw new IllegalStateException("Missing IfAction on top of stack");
+ }
}
+ }
+
+ abstract void registerEventList(IfAction ifAction, List<SaxEvent> eventList);
- abstract void registerEventList(IfAction ifAction, List<SaxEvent> eventList);
-
- void removeFirstAndLastFromList(List<SaxEvent> eventList) {
- eventList.remove(0);
- eventList.remove(eventList.size() - 1);
- }
+ void removeFirstAndLastFromList(List<SaxEvent> eventList) {
+ eventList.remove(0);
+ eventList.remove(eventList.size() - 1);
+ }
}
class ThenActionState implements InPlayListener {
- List<SaxEvent> eventList = new ArrayList<SaxEvent>();
- boolean isRegistered = false;
-
- public void inPlay(SaxEvent event) {
- eventList.add(event);
- }
+ List<SaxEvent> eventList = new ArrayList<SaxEvent>();
+ boolean isRegistered = false;
+
+ public void inPlay(SaxEvent event) {
+ eventList.add(event);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/event/BodyEvent.java b/logback-core/src/main/java/ch/qos/logback/core/joran/event/BodyEvent.java
index cfeec5d..fd2801e 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/BodyEvent.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/event/BodyEvent.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,34 +15,36 @@ package ch.qos.logback.core.joran.event;
import org.xml.sax.Locator;
+
public class BodyEvent extends SaxEvent {
- private String text;
-
- BodyEvent(String text, Locator locator) {
- super(null, null, null, locator);
- this.text = text;
- }
-
- /**
- * Always trim trailing spaces from the body text.
- *
- * @return
- */
- public String getText() {
- if (text != null) {
- return text.trim();
- }
- return text;
- }
-
- @Override
- public String toString() {
- return "BodyEvent(" + getText() + ")" + locator.getLineNumber() + "," + locator.getColumnNumber();
- }
-
- public void append(String str) {
- text += str;
- }
+ private String text;
+
+ BodyEvent(String text, Locator locator) {
+ super(null, null, null, locator);
+ this.text = text;
+ }
+
+ /**
+ * Always trim trailing spaces from the body text.
+ *
+ * @return
+ */
+ public String getText() {
+ if(text != null) {
+ return text.trim();
+ }
+ return text;
+ }
+
+ @Override
+ public String toString() {
+ return "BodyEvent(" + getText() + ")" + locator.getLineNumber() + ","
+ + locator.getColumnNumber();
+ }
+
+ public void append(String str) {
+ text += str;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/event/EndEvent.java b/logback-core/src/main/java/ch/qos/logback/core/joran/event/EndEvent.java
index 9f61c63..d98b5bd 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/EndEvent.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/event/EndEvent.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,15 +15,17 @@ package ch.qos.logback.core.joran.event;
import org.xml.sax.Locator;
+
public class EndEvent extends SaxEvent {
- EndEvent(String namespaceURI, String localName, String qName, Locator locator) {
- super(namespaceURI, localName, qName, locator);
- }
+ EndEvent(String namespaceURI, String localName, String qName, Locator locator) {
+ super(namespaceURI, localName, qName, locator);
+ }
+
+ @Override
+ public String toString() {
+ return " EndEvent("+getQName()+") ["+locator.getLineNumber()+","+locator.getColumnNumber()+"]";
+ }
- @Override
- public String toString() {
- return " EndEvent(" + getQName() + ") [" + locator.getLineNumber() + "," + locator.getColumnNumber() + "]";
- }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/event/InPlayListener.java b/logback-core/src/main/java/ch/qos/logback/core/joran/event/InPlayListener.java
index e75613d..81ec5c1 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/InPlayListener.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/event/InPlayListener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.joran.event;
+
public interface InPlayListener {
- void inPlay(SaxEvent event);
-}
+ void inPlay(SaxEvent event);
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEvent.java b/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEvent.java
index 3e4cba9..40d3e6a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEvent.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEvent.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,32 +18,32 @@ import org.xml.sax.helpers.LocatorImpl;
public class SaxEvent {
- final public String namespaceURI;
- final public String localName;
- final public String qName;
- final public Locator locator;
-
- SaxEvent(String namespaceURI, String localName, String qName, Locator locator) {
- this.namespaceURI = namespaceURI;
- this.localName = localName;
- this.qName = qName;
- // locator impl is used to take a snapshot!
- this.locator = new LocatorImpl(locator);
- }
-
- public String getLocalName() {
- return localName;
- }
-
- public Locator getLocator() {
- return locator;
- }
-
- public String getNamespaceURI() {
- return namespaceURI;
- }
-
- public String getQName() {
- return qName;
- }
+ final public String namespaceURI;
+ final public String localName;
+ final public String qName;
+ final public Locator locator;
+
+ SaxEvent(String namespaceURI, String localName, String qName, Locator locator) {
+ this.namespaceURI = namespaceURI;
+ this.localName = localName;
+ this.qName = qName;
+ // locator impl is used to take a snapshot!
+ this.locator = new LocatorImpl(locator);
+ }
+
+ public String getLocalName() {
+ return localName;
+ }
+
+ public Locator getLocator() {
+ return locator;
+ }
+
+ public String getNamespaceURI() {
+ return namespaceURI;
+ }
+
+ public String getQName() {
+ return qName;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java b/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java
index b33462b..029b88b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,8 +13,6 @@
*/
package ch.qos.logback.core.joran.event;
-import static ch.qos.logback.core.CoreConstants.XML_PARSING;
-
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -23,6 +21,10 @@ import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
+import static ch.qos.logback.core.CoreConstants.XML_PARSING;
+
+import ch.qos.logback.core.joran.spi.ElementPath;
+import ch.qos.logback.core.joran.spi.ElementSelector;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
@@ -31,7 +33,6 @@ import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import ch.qos.logback.core.Context;
-import ch.qos.logback.core.joran.spi.ElementPath;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.spi.ContextAware;
import ch.qos.logback.core.spi.ContextAwareImpl;
@@ -39,166 +40,170 @@ import ch.qos.logback.core.status.Status;
public class SaxEventRecorder extends DefaultHandler implements ContextAware {
- final ContextAwareImpl cai;
-
- public SaxEventRecorder(Context context) {
- cai = new ContextAwareImpl(context, this);
- }
-
- public List<SaxEvent> saxEventList = new ArrayList<SaxEvent>();
- Locator locator;
- ElementPath globalElementPath = new ElementPath();
-
- final public void recordEvents(InputStream inputStream) throws JoranException {
- recordEvents(new InputSource(inputStream));
- }
-
- public List<SaxEvent> recordEvents(InputSource inputSource) throws JoranException {
- SAXParser saxParser = buildSaxParser();
- try {
- saxParser.parse(inputSource, this);
- return saxEventList;
- } catch (IOException ie) {
- handleError("I/O error occurred while parsing xml file", ie);
- } catch (SAXException se) {
- // Exception added into StatusManager via Sax error handling. No need to add it again
- throw new JoranException("Problem parsing XML document. See previously reported errors.", se);
- } catch (Exception ex) {
- handleError("Unexpected exception while parsing XML document.", ex);
- }
- throw new IllegalStateException("This point can never be reached");
- }
-
- private void handleError(String errMsg, Throwable t) throws JoranException {
- addError(errMsg, t);
- throw new JoranException(errMsg, t);
- }
-
- private SAXParser buildSaxParser() throws JoranException {
- try {
- SAXParserFactory spf = SAXParserFactory.newInstance();
- spf.setValidating(false);
- spf.setNamespaceAware(true);
- return spf.newSAXParser();
- } catch (Exception pce) {
- String errMsg = "Parser configuration error occurred";
- addError(errMsg, pce);
- throw new JoranException(errMsg, pce);
- }
- }
-
- public void startDocument() {
- }
-
- public Locator getLocator() {
- return locator;
- }
-
- public void setDocumentLocator(Locator l) {
- locator = l;
- }
-
- public void startElement(String namespaceURI, String localName, String qName, Attributes atts) {
-
- String tagName = getTagName(localName, qName);
- globalElementPath.push(tagName);
- ElementPath current = globalElementPath.duplicate();
- saxEventList.add(new StartEvent(current, namespaceURI, localName, qName, atts, getLocator()));
- }
-
- public void characters(char[] ch, int start, int length) {
- String bodyStr = new String(ch, start, length);
- SaxEvent lastEvent = getLastEvent();
- if (lastEvent instanceof BodyEvent) {
- BodyEvent be = (BodyEvent) lastEvent;
- be.append(bodyStr);
- } else {
- // ignore space only text if the previous event is not a BodyEvent
- if (!isSpaceOnly(bodyStr)) {
- saxEventList.add(new BodyEvent(bodyStr, getLocator()));
- }
- }
- }
-
- boolean isSpaceOnly(String bodyStr) {
- String bodyTrimmed = bodyStr.trim();
- return (bodyTrimmed.length() == 0);
- }
-
- SaxEvent getLastEvent() {
- if (saxEventList.isEmpty()) {
- return null;
- }
- int size = saxEventList.size();
- return saxEventList.get(size - 1);
- }
-
- public void endElement(String namespaceURI, String localName, String qName) {
- saxEventList.add(new EndEvent(namespaceURI, localName, qName, getLocator()));
- globalElementPath.pop();
- }
-
- String getTagName(String localName, String qName) {
- String tagName = localName;
- if ((tagName == null) || (tagName.length() < 1)) {
- tagName = qName;
- }
- return tagName;
- }
-
- public void error(SAXParseException spe) throws SAXException {
- addError(XML_PARSING + " - Parsing error on line " + spe.getLineNumber() + " and column " + spe.getColumnNumber());
- addError(spe.toString());
-
- }
-
- public void fatalError(SAXParseException spe) throws SAXException {
- addError(XML_PARSING + " - Parsing fatal error on line " + spe.getLineNumber() + " and column " + spe.getColumnNumber());
- addError(spe.toString());
- }
-
- public void warning(SAXParseException spe) throws SAXException {
- addWarn(XML_PARSING + " - Parsing warning on line " + spe.getLineNumber() + " and column " + spe.getColumnNumber(), spe);
- }
-
- public void addError(String msg) {
- cai.addError(msg);
- }
-
- public void addError(String msg, Throwable ex) {
- cai.addError(msg, ex);
- }
-
- public void addInfo(String msg) {
- cai.addInfo(msg);
- }
-
- public void addInfo(String msg, Throwable ex) {
- cai.addInfo(msg, ex);
- }
-
- public void addStatus(Status status) {
- cai.addStatus(status);
- }
-
- public void addWarn(String msg) {
- cai.addWarn(msg);
- }
-
- public void addWarn(String msg, Throwable ex) {
- cai.addWarn(msg, ex);
- }
-
- public Context getContext() {
- return cai.getContext();
- }
-
- public void setContext(Context context) {
- cai.setContext(context);
- }
-
- public List<SaxEvent> getSaxEventList() {
- return saxEventList;
- }
+ final ContextAwareImpl cai;
+
+ public SaxEventRecorder(Context context) {
+ cai = new ContextAwareImpl(context, this);
+ }
+
+ public List<SaxEvent> saxEventList = new ArrayList<SaxEvent>();
+ Locator locator;
+ ElementPath globalElementPath = new ElementPath();
+
+ final public void recordEvents(InputStream inputStream) throws JoranException {
+ recordEvents(new InputSource(inputStream));
+ }
+
+ public List<SaxEvent> recordEvents(InputSource inputSource)
+ throws JoranException {
+ SAXParser saxParser = buildSaxParser();
+ try {
+ saxParser.parse(inputSource, this);
+ return saxEventList;
+ } catch (IOException ie) {
+ handleError("I/O error occurred while parsing xml file", ie);
+ } catch(SAXException se) {
+ // Exception added into StatusManager via Sax error handling. No need to add it again
+ throw new JoranException("Problem parsing XML document. See previously reported errors.", se);
+ } catch (Exception ex) {
+ handleError("Unexpected exception while parsing XML document.", ex);
+ }
+ throw new IllegalStateException("This point can never be reached");
+ }
+
+ private void handleError(String errMsg, Throwable t) throws JoranException {
+ addError(errMsg, t);
+ throw new JoranException(errMsg, t);
+ }
+
+ private SAXParser buildSaxParser() throws JoranException {
+ try {
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ spf.setValidating(false);
+ spf.setNamespaceAware(true);
+ return spf.newSAXParser();
+ } catch (Exception pce) {
+ String errMsg = "Parser configuration error occurred";
+ addError(errMsg, pce);
+ throw new JoranException(errMsg, pce);
+ }
+ }
+
+ public void startDocument() {
+ }
+
+ public Locator getLocator() {
+ return locator;
+ }
+
+ public void setDocumentLocator(Locator l) {
+ locator = l;
+ }
+
+ public void startElement(String namespaceURI, String localName, String qName,
+ Attributes atts) {
+
+ String tagName = getTagName(localName, qName);
+ globalElementPath.push(tagName);
+ ElementPath current = globalElementPath.duplicate();
+ saxEventList.add(new StartEvent(current, namespaceURI, localName, qName,
+ atts, getLocator()));
+ }
+
+ public void characters(char[] ch, int start, int length) {
+ String bodyStr = new String(ch, start, length);
+ SaxEvent lastEvent = getLastEvent();
+ if (lastEvent instanceof BodyEvent) {
+ BodyEvent be = (BodyEvent) lastEvent;
+ be.append(bodyStr);
+ } else {
+ // ignore space only text if the previous event is not a BodyEvent
+ if (!isSpaceOnly(bodyStr)) {
+ saxEventList.add(new BodyEvent(bodyStr, getLocator()));
+ }
+ }
+ }
+
+ boolean isSpaceOnly(String bodyStr) {
+ String bodyTrimmed = bodyStr.trim();
+ return (bodyTrimmed.length() == 0);
+ }
+
+ SaxEvent getLastEvent() {
+ if (saxEventList.isEmpty()) {
+ return null;
+ }
+ int size = saxEventList.size();
+ return saxEventList.get(size - 1);
+ }
+
+ public void endElement(String namespaceURI, String localName, String qName) {
+ saxEventList
+ .add(new EndEvent(namespaceURI, localName, qName, getLocator()));
+ globalElementPath.pop();
+ }
+
+ String getTagName(String localName, String qName) {
+ String tagName = localName;
+ if ((tagName == null) || (tagName.length() < 1)) {
+ tagName = qName;
+ }
+ return tagName;
+ }
+
+ public void error(SAXParseException spe) throws SAXException {
+ addError(XML_PARSING +" - Parsing error on line " + spe.getLineNumber() + " and column "
+ + spe.getColumnNumber(), spe);
+ }
+
+ public void fatalError(SAXParseException spe) throws SAXException {
+ addError(XML_PARSING +" - Parsing fatal error on line " + spe.getLineNumber()
+ + " and column " + spe.getColumnNumber(), spe);
+ }
+
+ public void warning(SAXParseException spe) throws SAXException {
+ addWarn(XML_PARSING +" - Parsing warning on line " + spe.getLineNumber() + " and column "
+ + spe.getColumnNumber(), spe);
+ }
+
+ public void addError(String msg) {
+ cai.addError(msg);
+ }
+
+ public void addError(String msg, Throwable ex) {
+ cai.addError(msg, ex);
+ }
+
+ public void addInfo(String msg) {
+ cai.addInfo(msg);
+ }
+
+ public void addInfo(String msg, Throwable ex) {
+ cai.addInfo(msg, ex);
+ }
+
+ public void addStatus(Status status) {
+ cai.addStatus(status);
+ }
+
+ public void addWarn(String msg) {
+ cai.addWarn(msg);
+ }
+
+ public void addWarn(String msg, Throwable ex) {
+ cai.addWarn(msg, ex);
+ }
+
+ public Context getContext() {
+ return cai.getContext();
+ }
+
+ public void setContext(Context context) {
+ cai.setContext(context);
+ }
+
+ public List<SaxEvent> getSaxEventList() {
+ return saxEventList;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/event/StartEvent.java b/logback-core/src/main/java/ch/qos/logback/core/joran/event/StartEvent.java
index 631a6ea..5069439 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/StartEvent.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/event/StartEvent.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,37 +20,25 @@ import org.xml.sax.helpers.AttributesImpl;
public class StartEvent extends SaxEvent {
- final public Attributes attributes;
- final public ElementPath elementPath;
+ final public Attributes attributes;
+ final public ElementPath elementPath;
+
+ StartEvent(ElementPath elementPath, String namespaceURI, String localName, String qName,
+ Attributes attributes, Locator locator) {
+ super(namespaceURI, localName, qName, locator);
+ // locator impl is used to take a snapshot!
+ this.attributes = new AttributesImpl(attributes);
+ this.elementPath = elementPath;
+ }
- StartEvent(ElementPath elementPath, String namespaceURI, String localName, String qName, Attributes attributes, Locator locator) {
- super(namespaceURI, localName, qName, locator);
- // locator impl is used to take a snapshot!
- this.attributes = new AttributesImpl(attributes);
- this.elementPath = elementPath;
- }
+ public Attributes getAttributes() {
+ return attributes;
+ }
- public Attributes getAttributes() {
- return attributes;
- }
-
- @Override
- public String toString() {
- StringBuilder b = new StringBuilder("StartEvent(");
- b.append(getQName());
- if(attributes != null) {
- for(int i = 0; i < attributes.getLength(); i++) {
- if(i > 0)
- b.append(' ');
- b.append(attributes.getLocalName(i)).append("=\"").append(attributes.getValue(i)).append("\"");
- }
- }
- b.append(") [");
- b.append( locator.getLineNumber());
- b.append(",");
- b.append(locator.getColumnNumber());
- b.append("]");
- return b.toString();
- }
+
+ @Override
+ public String toString() {
+ return "StartEvent("+getQName()+") ["+locator.getLineNumber()+","+locator.getColumnNumber()+"]";
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/BodyEvent.java b/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/BodyEvent.java
index d06b3be..4dc14bf 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/BodyEvent.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/BodyEvent.java
@@ -1,39 +1,28 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
package ch.qos.logback.core.joran.event.stax;
import javax.xml.stream.Location;
public class BodyEvent extends StaxEvent {
- private String text;
- BodyEvent(String text, Location location) {
- super(null, location);
- this.text = text;
- }
+ private String text;
- public String getText() {
- return text;
- }
+ BodyEvent(String text, Location location) {
+ super(null, location);
+ this.text = text;
+ }
- void append(String txt) {
- text += txt;
- }
+ public String getText() {
+ return text;
+ }
- @Override
- public String toString() {
- return "BodyEvent(" + getText() + ")" + location.getLineNumber() + "," + location.getColumnNumber();
- }
+ void append(String txt) {
+ text += txt;
+ }
+
+ @Override
+ public String toString() {
+ return "BodyEvent(" + getText() + ")" + location.getLineNumber() + ","
+ + location.getColumnNumber();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/EndEvent.java b/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/EndEvent.java
index 5712144..8699efd 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/EndEvent.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/EndEvent.java
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
package ch.qos.logback.core.joran.event.stax;
import javax.xml.stream.Location;
@@ -24,13 +11,14 @@ import javax.xml.stream.Location;
*/
public class EndEvent extends StaxEvent {
- public EndEvent(String name, Location location) {
- super(name, location);
- }
+ public EndEvent(String name, Location location) {
+ super(name, location);
+ }
+
+ @Override
+ public String toString() {
+ return "EndEvent("+getName()+") ["+location.getLineNumber()+","+location.getColumnNumber()+"]";
+ }
- @Override
- public String toString() {
- return "EndEvent(" + getName() + ") [" + location.getLineNumber() + "," + location.getColumnNumber() + "]";
- }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/StartEvent.java b/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/StartEvent.java
index f824f2d..3118480 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/StartEvent.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/StartEvent.java
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
package ch.qos.logback.core.joran.event.stax;
import ch.qos.logback.core.joran.spi.ElementPath;
@@ -23,45 +10,45 @@ import java.util.List;
public class StartEvent extends StaxEvent {
- List<Attribute> attributes;
- public ElementPath elementPath;
-
- StartEvent(ElementPath elementPath, String name, Iterator<Attribute> attributeIterator, Location location) {
- super(name, location);
- populateAttributes(attributeIterator);
- this.elementPath = elementPath;
- }
-
- private void populateAttributes(Iterator<Attribute> attributeIterator) {
- while (attributeIterator.hasNext()) {
- if (attributes == null) {
- attributes = new ArrayList<Attribute>(2);
- }
- attributes.add(attributeIterator.next());
- }
+ List<Attribute> attributes;
+ public ElementPath elementPath;
+
+ StartEvent(ElementPath elementPath, String name, Iterator<Attribute> attributeIterator, Location location) {
+ super(name, location);
+ populateAttributes(attributeIterator);
+ this.elementPath = elementPath;
+ }
+
+ private void populateAttributes(Iterator<Attribute> attributeIterator) {
+ while (attributeIterator.hasNext()) {
+ if (attributes == null) {
+ attributes = new ArrayList<Attribute>(2);
+ }
+ attributes.add(attributeIterator.next());
}
+ }
- public ElementPath getElementPath() {
- return elementPath;
- }
+ public ElementPath getElementPath() {
+ return elementPath;
+ }
- public List<Attribute> getAttributeList() {
- return attributes;
- }
+ public List<Attribute> getAttributeList() {
+ return attributes;
+ }
- Attribute getAttributeByName(String name) {
- if (attributes == null)
- return null;
+ Attribute getAttributeByName(String name) {
+ if(attributes == null)
+ return null;
- for (Attribute attr : attributes) {
- if (name.equals(attr.getName().getLocalPart()))
- return attr;
- }
- return null;
+ for(Attribute attr: attributes) {
+ if(name.equals(attr.getName().getLocalPart()))
+ return attr;
}
+ return null;
+ }
- @Override
- public String toString() {
- return "StartEvent(" + getName() + ") [" + location.getLineNumber() + "," + location.getColumnNumber() + "]";
- }
+ @Override
+ public String toString() {
+ return "StartEvent(" + getName() + ") [" + location.getLineNumber() + "," + location.getColumnNumber() + "]";
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/StaxEvent.java b/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/StaxEvent.java
index 747ba7d..1468f7b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/StaxEvent.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/StaxEvent.java
@@ -1,37 +1,25 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
package ch.qos.logback.core.joran.event.stax;
+
import javax.xml.stream.Location;
public class StaxEvent {
- final String name;
- final Location location;
+ final String name;
+ final Location location;
- StaxEvent(String name, Location location) {
- this.name = name;
- this.location = location;
+ StaxEvent(String name, Location location) {
+ this.name = name;
+ this.location = location;
- }
+ }
- public String getName() {
- return name;
- }
+ public String getName() {
+ return name;
+ }
- public Location getLocation() {
- return location;
- }
+ public Location getLocation() {
+ return location;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/StaxEventRecorder.java b/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/StaxEventRecorder.java
index c0cae22..45cd95a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/StaxEventRecorder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/StaxEventRecorder.java
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
package ch.qos.logback.core.joran.event.stax;
import ch.qos.logback.core.Context;
@@ -31,86 +18,86 @@ import java.util.List;
public class StaxEventRecorder extends ContextAwareBase {
- List<StaxEvent> eventList = new ArrayList<StaxEvent>();
- ElementPath globalElementPath = new ElementPath();
+ List<StaxEvent> eventList = new ArrayList<StaxEvent>();
+ ElementPath globalElementPath = new ElementPath();
- public StaxEventRecorder(Context context) {
- setContext(context);
- }
+ public StaxEventRecorder(Context context) {
+ setContext(context);
+ }
- public void recordEvents(InputStream inputStream) throws JoranException {
- try {
- XMLEventReader xmlEventReader = XMLInputFactory.newInstance().createXMLEventReader(inputStream);
- read(xmlEventReader);
- } catch (XMLStreamException e) {
- throw new JoranException("Problem parsing XML document. See previously reported errors.", e);
- }
+ public void recordEvents(InputStream inputStream) throws JoranException {
+ try {
+ XMLEventReader xmlEventReader = XMLInputFactory.newInstance().createXMLEventReader(inputStream);
+ read(xmlEventReader);
+ } catch (XMLStreamException e) {
+ throw new JoranException("Problem parsing XML document. See previously reported errors.", e);
}
+ }
- public List<StaxEvent> getEventList() {
- return eventList;
- }
+ public List<StaxEvent> getEventList() {
+ return eventList;
+ }
- private void read(XMLEventReader xmlEventReader) throws XMLStreamException {
- while (xmlEventReader.hasNext()) {
- XMLEvent xmlEvent = xmlEventReader.nextEvent();
- switch (xmlEvent.getEventType()) {
- case XMLEvent.START_ELEMENT:
- addStartElement(xmlEvent);
- break;
- case XMLEvent.CHARACTERS:
- addCharacters(xmlEvent);
- break;
- case XMLEvent.END_ELEMENT:
- addEndEvent(xmlEvent);
- break;
- default:
- break;
- }
- }
+ private void read(XMLEventReader xmlEventReader) throws XMLStreamException {
+ while (xmlEventReader.hasNext()) {
+ XMLEvent xmlEvent = xmlEventReader.nextEvent();
+ switch (xmlEvent.getEventType()) {
+ case XMLEvent.START_ELEMENT:
+ addStartElement(xmlEvent);
+ break;
+ case XMLEvent.CHARACTERS:
+ addCharacters(xmlEvent);
+ break;
+ case XMLEvent.END_ELEMENT:
+ addEndEvent(xmlEvent);
+ break;
+ default:
+ break;
+ }
}
+ }
- private void addStartElement(XMLEvent xmlEvent) {
- StartElement se = xmlEvent.asStartElement();
- String tagName = se.getName().getLocalPart();
- globalElementPath.push(tagName);
- ElementPath current = globalElementPath.duplicate();
- StartEvent startEvent = new StartEvent(current, tagName, se.getAttributes(), se.getLocation());
- eventList.add(startEvent);
- }
+ private void addStartElement(XMLEvent xmlEvent) {
+ StartElement se = xmlEvent.asStartElement();
+ String tagName = se.getName().getLocalPart();
+ globalElementPath.push(tagName);
+ ElementPath current = globalElementPath.duplicate();
+ StartEvent startEvent = new StartEvent(current, tagName, se.getAttributes(), se.getLocation());
+ eventList.add(startEvent);
+ }
- private void addCharacters(XMLEvent xmlEvent) {
- Characters characters = xmlEvent.asCharacters();
- StaxEvent lastEvent = getLastEvent();
+ private void addCharacters(XMLEvent xmlEvent) {
+ Characters characters = xmlEvent.asCharacters();
+ StaxEvent lastEvent = getLastEvent();
- if (lastEvent instanceof BodyEvent) {
- BodyEvent be = (BodyEvent) lastEvent;
- be.append(characters.getData());
- } else {
- // ignore space only text if the previous event is not a BodyEvent
- if (!characters.isWhiteSpace()) {
- BodyEvent bodyEvent = new BodyEvent(characters.getData(), xmlEvent.getLocation());
- eventList.add(bodyEvent);
- }
- }
+ if (lastEvent instanceof BodyEvent) {
+ BodyEvent be = (BodyEvent) lastEvent;
+ be.append(characters.getData());
+ } else {
+ // ignore space only text if the previous event is not a BodyEvent
+ if(!characters.isWhiteSpace()) {
+ BodyEvent bodyEvent = new BodyEvent(characters.getData(), xmlEvent.getLocation());
+ eventList.add(bodyEvent);
+ }
}
+ }
- private void addEndEvent(XMLEvent xmlEvent) {
- EndElement ee = xmlEvent.asEndElement();
- String tagName = ee.getName().getLocalPart();
- EndEvent endEvent = new EndEvent(tagName, ee.getLocation());
- eventList.add(endEvent);
- globalElementPath.pop();
- }
+ private void addEndEvent(XMLEvent xmlEvent) {
+ EndElement ee = xmlEvent.asEndElement();
+ String tagName = ee.getName().getLocalPart();
+ EndEvent endEvent = new EndEvent(tagName, ee.getLocation());
+ eventList.add(endEvent);
+ globalElementPath.pop();
+ }
- StaxEvent getLastEvent() {
- if (eventList.isEmpty()) {
- return null;
- }
- int size = eventList.size();
- if (size == 0)
- return null;
- return eventList.get(size - 1);
+ StaxEvent getLastEvent() {
+ if (eventList.isEmpty()) {
+ return null;
}
+ int size = eventList.size();
+ if(size == 0)
+ return null;
+ return eventList.get(size - 1);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/node/ComponentNode.java b/logback-core/src/main/java/ch/qos/logback/core/joran/node/ComponentNode.java
index d879260..fb1fa95 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/node/ComponentNode.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/node/ComponentNode.java
@@ -1,20 +1,8 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
package ch.qos.logback.core.joran.node;
+
public class ComponentNode {
- String classStr;
+ String classStr;
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ActionException.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ActionException.java
index a54f861..e51f642 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ActionException.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ActionException.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.joran.spi;
+
/**
* By throwing an exception an action can signal the Interpreter to skip
* processing of all the nested (child) elements of the element associated with
@@ -22,13 +23,14 @@ package ch.qos.logback.core.joran.spi;
*/
public class ActionException extends Exception {
- private static final long serialVersionUID = 2743349809995319806L;
+
+ private static final long serialVersionUID = 2743349809995319806L;
- public ActionException() {
- }
+ public ActionException() {
+ }
- public ActionException(final Throwable rootCause) {
- super(rootCause);
- }
+ public ActionException(final Throwable rootCause) {
+ super(rootCause);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ConfigurationWatchList.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ConfigurationWatchList.java
index f484ce6..78c0441 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ConfigurationWatchList.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ConfigurationWatchList.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.joran.spi;
+
import ch.qos.logback.core.spi.ContextAwareBase;
import java.io.File;
@@ -22,81 +23,73 @@ import java.util.ArrayList;
import java.util.List;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class ConfigurationWatchList extends ContextAwareBase {
- URL mainURL;
- List<File> fileWatchList = new ArrayList<File>();
- List<Long> lastModifiedList = new ArrayList<Long>();
+ URL mainURL;
+ List<File> fileWatchList = new ArrayList<File>();
+ List<Long> lastModifiedList = new ArrayList<Long>();
- public ConfigurationWatchList buildClone() {
- ConfigurationWatchList out = new ConfigurationWatchList();
- out.mainURL = this.mainURL;
- out.fileWatchList = new ArrayList<File>(this.fileWatchList);
- out.lastModifiedList = new ArrayList<Long>(this.lastModifiedList);
- return out;
- }
-
- public void clear() {
- this.mainURL = null;
- lastModifiedList.clear();
- fileWatchList.clear();
- }
+ public void clear() {
+ this.mainURL = null;
+ lastModifiedList.clear();
+ fileWatchList.clear();
+ }
- /**
- * The mainURL for the configuration file. Null values are allowed.
- * @param mainURL
- */
- public void setMainURL(URL mainURL) {
- // main url can be null
- this.mainURL = mainURL;
- if (mainURL != null)
- addAsFileToWatch(mainURL);
- }
+ /**
+ * The mainURL for the configuration file. Null values are allowed.
+ * @param mainURL
+ */
+ public void setMainURL(URL mainURL) {
+ // main url can be null
+ this.mainURL = mainURL;
+ if (mainURL != null)
+ addAsFileToWatch(mainURL);
+ }
- private void addAsFileToWatch(URL url) {
- File file = convertToFile(url);
- if (file != null) {
- fileWatchList.add(file);
- lastModifiedList.add(file.lastModified());
- }
+ private void addAsFileToWatch(URL url) {
+ File file = convertToFile(url);
+ if (file != null) {
+ fileWatchList.add(file);
+ lastModifiedList.add(file.lastModified());
}
+ }
- public void addToWatchList(URL url) {
- addAsFileToWatch(url);
- }
+ public void addToWatchList(URL url) {
+ addAsFileToWatch(url);
+ }
- public URL getMainURL() {
- return mainURL;
- }
+ public URL getMainURL() {
+ return mainURL;
+ }
- public List<File> getCopyOfFileWatchList() {
- return new ArrayList<File>(fileWatchList);
- }
+ public List<File> getCopyOfFileWatchList() {
+ return new ArrayList<File>(fileWatchList);
+ }
- public boolean changeDetected() {
- int len = fileWatchList.size();
- for (int i = 0; i < len; i++) {
- long lastModified = lastModifiedList.get(i);
- File file = fileWatchList.get(i);
- if (lastModified != file.lastModified()) {
- return true;
- }
- }
- return false;
- // return (lastModified != fileToScan.lastModified() && lastModified != SENTINEL);
+ public boolean changeDetected() {
+ int len = fileWatchList.size();
+ for (int i = 0; i < len; i++) {
+ long lastModified = lastModifiedList.get(i);
+ File file = fileWatchList.get(i);
+ if (lastModified != file.lastModified()) {
+ return true;
+ }
}
+ return false;
+ //return (lastModified != fileToScan.lastModified() && lastModified != SENTINEL);
+ }
- @SuppressWarnings("deprecation")
- File convertToFile(URL url) {
- String protocol = url.getProtocol();
- if ("file".equals(protocol)) {
- return new File(URLDecoder.decode(url.getFile()));
- } else {
- addInfo("URL [" + url + "] is not of type file");
- return null;
- }
+ @SuppressWarnings("deprecation")
+ File convertToFile(URL url) {
+ String protocol = url.getProtocol();
+ if ("file".equals(protocol)) {
+ return new File(URLDecoder.decode(url.getFile()));
+ } else {
+ addInfo("URL [" + url + "] is not of type file");
+ return null;
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ConsoleTarget.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ConsoleTarget.java
index 5e15f08..2c44bf4 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ConsoleTarget.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ConsoleTarget.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,77 +26,66 @@ import java.io.OutputStream;
*/
public enum ConsoleTarget {
- SystemOut("System.out", new OutputStream() {
- @Override
- public void write(int b) throws IOException {
- System.out.write(b);
- }
-
- @Override
- public void write(byte b[]) throws IOException {
- System.out.write(b);
- }
-
- @Override
- public void write(byte b[], int off, int len) throws IOException {
- System.out.write(b, off, len);
- }
-
- @Override
- public void flush() throws IOException {
- System.out.flush();
- }
- }),
-
- SystemErr("System.err", new OutputStream() {
- @Override
- public void write(int b) throws IOException {
- System.err.write(b);
- }
-
- @Override
- public void write(byte b[]) throws IOException {
- System.err.write(b);
- }
-
- @Override
- public void write(byte b[], int off, int len) throws IOException {
- System.err.write(b, off, len);
- }
-
- @Override
- public void flush() throws IOException {
- System.err.flush();
- }
- });
-
- public static ConsoleTarget findByName(String name) {
- for (ConsoleTarget target : ConsoleTarget.values()) {
- if (target.name.equalsIgnoreCase(name)) {
- return target;
- }
- }
- return null;
+ SystemOut("System.out", new OutputStream() {
+ @Override
+ public void write(int b) throws IOException {
+ System.out.write(b);
}
-
- private final String name;
- private final OutputStream stream;
-
- private ConsoleTarget(String name, OutputStream stream) {
- this.name = name;
- this.stream = stream;
+ @Override
+ public void write(byte b[]) throws IOException {
+ System.out.write(b);
}
-
- public String getName() {
- return name;
+ @Override
+ public void write(byte b[], int off, int len) throws IOException {
+ System.out.write(b, off, len);
}
-
- public OutputStream getStream() {
- return stream;
+ @Override
+ public void flush() throws IOException {
+ System.out.flush();
}
+ }),
+ SystemErr("System.err", new OutputStream() {
+ @Override
+ public void write(int b) throws IOException {
+ System.err.write(b);
+ }
+ @Override
+ public void write(byte b[]) throws IOException {
+ System.err.write(b);
+ }
+ @Override
+ public void write(byte b[], int off, int len) throws IOException {
+ System.err.write(b, off, len);
+ }
@Override
- public String toString() {
- return name;
+ public void flush() throws IOException {
+ System.err.flush();
+ }
+ });
+
+ public static ConsoleTarget findByName(String name) {
+ for (ConsoleTarget target : ConsoleTarget.values()) {
+ if (target.name.equalsIgnoreCase(name)) {
+ return target;
+ }
}
+ return null;
+ }
+
+ private final String name;
+ private final OutputStream stream;
+
+ private ConsoleTarget(String name, OutputStream stream) {
+ this.name = name;
+ this.stream = stream;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public OutputStream getStream() {
+ return stream;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/DefaultClass.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/DefaultClass.java
index aaf1892..967f60c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/DefaultClass.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/DefaultClass.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,5 +21,5 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DefaultClass {
- Class<?> value();
+ Class<?> value();
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/DefaultNestedComponentRegistry.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/DefaultNestedComponentRegistry.java
index 48cce8e..11a56bc 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/DefaultNestedComponentRegistry.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/DefaultNestedComponentRegistry.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,33 +19,35 @@ import java.util.Map;
/**
* A registry which maps a property in a host class to a default class.
*
- * @author Ceki Gülcü
+ * @author Cek Gülcü
*
*/
public class DefaultNestedComponentRegistry {
- Map<HostClassAndPropertyDouble, Class<?>> defaultComponentMap = new HashMap<HostClassAndPropertyDouble, Class<?>>();
+ Map<HostClassAndPropertyDouble, Class<?>> defaultComponentMap = new HashMap<HostClassAndPropertyDouble, Class<?>>();
- public void add(Class<?> hostClass, String propertyName, Class<?> componentClass) {
- HostClassAndPropertyDouble hpDouble = new HostClassAndPropertyDouble(hostClass, propertyName.toLowerCase());
- defaultComponentMap.put(hpDouble, componentClass);
- }
+ public void add(Class<?> hostClass, String propertyName, Class<?> componentClass) {
+ HostClassAndPropertyDouble hpDouble = new HostClassAndPropertyDouble(
+ hostClass, propertyName.toLowerCase());
+ defaultComponentMap.put(hpDouble, componentClass);
+ }
- public Class<?> findDefaultComponentType(Class<?> hostClass, String propertyName) {
- propertyName = propertyName.toLowerCase();
- while (hostClass != null) {
- Class<?> componentClass = oneShotFind(hostClass, propertyName);
- if (componentClass != null) {
- return componentClass;
- }
- hostClass = hostClass.getSuperclass();
- }
- return null;
+ public Class<?> findDefaultComponentType(Class<?> hostClass, String propertyName) {
+ propertyName = propertyName.toLowerCase();
+ while (hostClass != null) {
+ Class<?> componentClass = oneShotFind(hostClass, propertyName);
+ if (componentClass != null) {
+ return componentClass;
+ }
+ hostClass = hostClass.getSuperclass();
}
+ return null;
+ }
- private Class<?> oneShotFind(Class<?> hostClass, String propertyName) {
- HostClassAndPropertyDouble hpDouble = new HostClassAndPropertyDouble(hostClass, propertyName);
- return defaultComponentMap.get(hpDouble);
- }
+ private Class<?> oneShotFind(Class<?> hostClass, String propertyName) {
+ HostClassAndPropertyDouble hpDouble = new HostClassAndPropertyDouble(
+ hostClass, propertyName);
+ return defaultComponentMap.get(hpDouble);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ElementPath.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ElementPath.java
index 9c133d3..7a24801 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ElementPath.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ElementPath.java
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
package ch.qos.logback.core.joran.spi;
import java.util.ArrayList;
@@ -23,113 +10,113 @@ import java.util.List;
* @since 1.1.0
*/
public class ElementPath {
- // contains String instances
- ArrayList<String> partList = new ArrayList<String>();
-
- public ElementPath() {
+ // contains String instances
+ ArrayList<String> partList = new ArrayList<String>();
+
+ public ElementPath() {
+ }
+
+ public ElementPath(List<String> list) {
+ partList.addAll(list);
+ }
+
+ /**
+ * Build an elementPath from a string.
+ * <p/>
+ * Note that "/x" is considered equivalent to "x" and to "x/"
+ */
+ public ElementPath(String pathStr) {
+ if (pathStr == null) {
+ return;
}
- public ElementPath(List<String> list) {
- partList.addAll(list);
- }
+ String[] partArray = pathStr.split("/");
+ if(partArray == null) return;
- /**
- * Build an elementPath from a string.
- * <p/>
- * Note that "/x" is considered equivalent to "x" and to "x/"
- */
- public ElementPath(String pathStr) {
- if (pathStr == null) {
- return;
- }
-
- String[] partArray = pathStr.split("/");
- if (partArray == null)
- return;
-
- for (String part : partArray) {
- if (part.length() > 0) {
- partList.add(part);
- }
- }
+ for(String part: partArray) {
+ if(part.length() >0) {
+ partList.add(part);
+ }
}
-
- public ElementPath duplicate() {
- ElementPath p = new ElementPath();
- p.partList.addAll(this.partList);
- return p;
+ }
+
+ public ElementPath duplicate() {
+ ElementPath p = new ElementPath();
+ p.partList.addAll(this.partList);
+ return p;
+ }
+
+ // Joran error skipping relies on the equals method
+ @Override
+ public boolean equals(Object o) {
+ if ((o == null) || !(o instanceof ElementPath)) {
+ return false;
}
- // Joran error skipping relies on the equals method
- @Override
- public boolean equals(Object o) {
- if ((o == null) || !(o instanceof ElementPath)) {
- return false;
- }
+ ElementPath r = (ElementPath) o;
- ElementPath r = (ElementPath) o;
+ if (r.size() != size()) {
+ return false;
+ }
- if (r.size() != size()) {
- return false;
- }
+ int len = size();
- int len = size();
+ for (int i = 0; i < len; i++) {
+ if (!equalityCheck(get(i), r.get(i))) {
+ return false;
+ }
+ }
- for (int i = 0; i < len; i++) {
- if (!equalityCheck(get(i), r.get(i))) {
- return false;
- }
- }
+ // if everything matches, then the two patterns are equal
+ return true;
+ }
- // if everything matches, then the two patterns are equal
- return true;
- }
+ private boolean equalityCheck(String x, String y) {
+ return x.equalsIgnoreCase(y);
+ }
- private boolean equalityCheck(String x, String y) {
- return x.equalsIgnoreCase(y);
- }
+ public List<String> getCopyOfPartList() {
+ return new ArrayList<String>(partList);
+ }
- public List<String> getCopyOfPartList() {
- return new ArrayList<String>(partList);
- }
+ public void push(String s) {
+ partList.add(s);
+ }
- public void push(String s) {
- partList.add(s);
- }
+ public String get(int i) {
+ return (String) partList.get(i);
+ }
- public String get(int i) {
- return (String) partList.get(i);
+ public void pop() {
+ if (!partList.isEmpty()) {
+ partList.remove(partList.size() - 1);
}
-
- public void pop() {
- if (!partList.isEmpty()) {
- partList.remove(partList.size() - 1);
- }
+ }
+
+ public String peekLast() {
+ if (!partList.isEmpty()) {
+ int size = partList.size();
+ return (String) partList.get(size - 1);
+ } else {
+ return null;
}
+ }
- public String peekLast() {
- if (!partList.isEmpty()) {
- int size = partList.size();
- return (String) partList.get(size - 1);
- } else {
- return null;
- }
- }
+ public int size() {
+ return partList.size();
+ }
- public int size() {
- return partList.size();
- }
- protected String toStableString() {
- StringBuilder result = new StringBuilder();
- for (String current : partList) {
- result.append("[").append(current).append("]");
- }
- return result.toString();
+ protected String toStableString() {
+ StringBuilder result = new StringBuilder();
+ for (String current : partList) {
+ result.append("[").append(current).append("]");
}
+ return result.toString();
+ }
- @Override
- public String toString() {
- return toStableString();
- }
+ @Override
+ public String toString() {
+ return toStableString();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ElementSelector.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ElementSelector.java
index b6afb94..3f5ddaa 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ElementSelector.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ElementSelector.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,155 +27,157 @@ import java.util.List;
*/
public class ElementSelector extends ElementPath {
- public ElementSelector() {
- super();
+ public ElementSelector() {
+ super();
+ }
+
+ public ElementSelector(List<String> list) {
+ super(list);
+ }
+
+ /**
+ * Build an elementPath from a string.
+ *
+ * Note that "/x" is considered equivalent to "x" and to "x/"
+ *
+ */
+ public ElementSelector(String p) {
+ super(p);
+ }
+
+ public boolean fullPathMatch(ElementPath path) {
+ if (path.size() != size()) {
+ return false;
}
- public ElementSelector(List<String> list) {
- super(list);
+ int len = size();
+ for (int i = 0; i < len; i++) {
+ if (!equalityCheck(get(i), path.get(i))) {
+ return false;
+ }
}
-
- /**
- * Build an elementPath from a string.
- *
- * Note that "/x" is considered equivalent to "x" and to "x/"
- *
- */
- public ElementSelector(String p) {
- super(p);
+ // if everything matches, then the two patterns are equal
+ return true;
+ }
+
+ /**
+ * Returns the number of "tail" components that this pattern has in common
+ * with the pattern p passed as parameter. By "tail" components we mean the
+ * components at the end of the pattern.
+ */
+ public int getTailMatchLength(ElementPath p) {
+ if (p == null) {
+ return 0;
}
- public boolean fullPathMatch(ElementPath path) {
- if (path.size() != size()) {
- return false;
- }
-
- int len = size();
- for (int i = 0; i < len; i++) {
- if (!equalityCheck(get(i), path.get(i))) {
- return false;
- }
- }
- // if everything matches, then the two patterns are equal
- return true;
+ int lSize = this.partList.size();
+ int rSize = p.partList.size();
+
+ // no match possible for empty sets
+ if ((lSize == 0) || (rSize == 0)) {
+ return 0;
}
- /**
- * Returns the number of "tail" components that this pattern has in common
- * with the pattern p passed as parameter. By "tail" components we mean the
- * components at the end of the pattern.
- */
- public int getTailMatchLength(ElementPath p) {
- if (p == null) {
- return 0;
- }
-
- int lSize = this.partList.size();
- int rSize = p.partList.size();
-
- // no match possible for empty sets
- if ((lSize == 0) || (rSize == 0)) {
- return 0;
- }
-
- int minLen = (lSize <= rSize) ? lSize : rSize;
- int match = 0;
-
- // loop from the end to the front
- for (int i = 1; i <= minLen; i++) {
- String l = this.partList.get(lSize - i);
- String r = p.partList.get(rSize - i);
-
- if (equalityCheck(l, r)) {
- match++;
- } else {
- break;
- }
- }
- return match;
+ int minLen = (lSize <= rSize) ? lSize : rSize;
+ int match = 0;
+
+ // loop from the end to the front
+ for (int i = 1; i <= minLen; i++) {
+ String l = this.partList.get(lSize - i);
+ String r = p.partList.get(rSize - i);
+
+ if (equalityCheck(l, r)) {
+ match++;
+ } else {
+ break;
+ }
}
+ return match;
+ }
- public boolean isContainedIn(ElementPath p) {
- if (p == null) {
- return false;
- }
- return p.toStableString().contains(toStableString());
+ public boolean isContainedIn(ElementPath p) {
+ if(p == null) {
+ return false;
}
+ return p.toStableString().contains(toStableString());
+ }
+
+
+ /**
+ * Returns the number of "prefix" components that this pattern has in common
+ * with the pattern p passed as parameter. By "prefix" components we mean the
+ * components at the beginning of the pattern.
+ */
+ public int getPrefixMatchLength(ElementPath p) {
+ if (p == null) {
+ return 0;
+ }
+
+ int lSize = this.partList.size();
+ int rSize = p.partList.size();
- /**
- * Returns the number of "prefix" components that this pattern has in common
- * with the pattern p passed as parameter. By "prefix" components we mean the
- * components at the beginning of the pattern.
- */
- public int getPrefixMatchLength(ElementPath p) {
- if (p == null) {
- return 0;
- }
-
- int lSize = this.partList.size();
- int rSize = p.partList.size();
-
- // no match possible for empty sets
- if ((lSize == 0) || (rSize == 0)) {
- return 0;
- }
-
- int minLen = (lSize <= rSize) ? lSize : rSize;
- int match = 0;
-
- for (int i = 0; i < minLen; i++) {
- String l = this.partList.get(i);
- String r = p.partList.get(i);
-
- if (equalityCheck(l, r)) {
- match++;
- } else {
- break;
- }
- }
-
- return match;
+ // no match possible for empty sets
+ if ((lSize == 0) || (rSize == 0)) {
+ return 0;
}
- private boolean equalityCheck(String x, String y) {
- return x.equalsIgnoreCase(y);
+ int minLen = (lSize <= rSize) ? lSize : rSize;
+ int match = 0;
+
+ for (int i = 0; i < minLen; i++) {
+ String l = this.partList.get(i);
+ String r = p.partList.get(i);
+
+ if (equalityCheck(l, r)) {
+ match++;
+ } else {
+ break;
+ }
}
- @Override
- public boolean equals(Object o) {
- if ((o == null) || !(o instanceof ElementSelector)) {
- return false;
- }
+ return match;
+ }
+
+ private boolean equalityCheck(String x, String y) {
+ return x.equalsIgnoreCase(y);
+ }
- ElementSelector r = (ElementSelector) o;
+ @Override
+ public boolean equals(Object o) {
+ if ((o == null) || !(o instanceof ElementSelector)) {
+ return false;
+ }
- if (r.size() != size()) {
- return false;
- }
+ ElementSelector r = (ElementSelector) o;
- int len = size();
+ if (r.size() != size()) {
+ return false;
+ }
- for (int i = 0; i < len; i++) {
- if (!equalityCheck(get(i), r.get(i))) {
- return false;
- }
- }
+ int len = size();
- // if everything matches, then the two patterns are equal
- return true;
+ for (int i = 0; i < len; i++) {
+ if (!equalityCheck(get(i), r.get(i))) {
+ return false;
+ }
}
- @Override
- public int hashCode() {
- int hc = 0;
- int len = size();
-
- for (int i = 0; i < len; i++) {
- // make Pattern comparisons case insensitive
- // http://jira.qos.ch/browse/LBCORE-76
- hc ^= get(i).toLowerCase().hashCode();
- }
- return hc;
+ // if everything matches, then the two patterns are equal
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hc = 0;
+ int len = size();
+
+ for (int i = 0; i < len; i++) {
+ // make Pattern comparisons case insensitive
+ // http://jira.qos.ch/browse/LBCORE-76
+ hc ^= get(i).toLowerCase().hashCode();
}
+ return hc;
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
index af241eb..40eea88 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,49 +23,49 @@ import ch.qos.logback.core.joran.event.StartEvent;
public class EventPlayer {
- final Interpreter interpreter;
- List<SaxEvent> eventList;
- int currentIndex;
+ final Interpreter interpreter;
+ List<SaxEvent> eventList;
+ int currentIndex;
- public EventPlayer(Interpreter interpreter) {
- this.interpreter = interpreter;
- }
-
- /**
- * Return a copy of the current event list in the player.
- * @return
- * @since 0.9.20
- */
- public List<SaxEvent> getCopyOfPlayerEventList() {
- return new ArrayList<SaxEvent>(eventList);
- }
+ public EventPlayer(Interpreter interpreter) {
+ this.interpreter = interpreter;
+ }
- public void play(List<SaxEvent> aSaxEventList) {
- eventList = aSaxEventList;
- SaxEvent se;
- for (currentIndex = 0; currentIndex < eventList.size(); currentIndex++) {
- se = eventList.get(currentIndex);
-
- if (se instanceof StartEvent) {
- interpreter.startElement((StartEvent) se);
- // invoke fireInPlay after startElement processing
- interpreter.getInterpretationContext().fireInPlay(se);
- }
- if (se instanceof BodyEvent) {
- // invoke fireInPlay before characters processing
- interpreter.getInterpretationContext().fireInPlay(se);
- interpreter.characters((BodyEvent) se);
- }
- if (se instanceof EndEvent) {
- // invoke fireInPlay before endElement processing
- interpreter.getInterpretationContext().fireInPlay(se);
- interpreter.endElement((EndEvent) se);
- }
-
- }
- }
+ /**
+ * Return a copy of the current event list in the player.
+ * @return
+ * @since 0.9.20
+ */
+ public List<SaxEvent> getCopyOfPlayerEventList() {
+ return new ArrayList<SaxEvent>(eventList);
+ }
- public void addEventsDynamically(List<SaxEvent> eventList, int offset) {
- this.eventList.addAll(currentIndex + offset, eventList);
+ public void play(List<SaxEvent> aSaxEventList) {
+ eventList = aSaxEventList;
+ SaxEvent se;
+ for(currentIndex = 0; currentIndex < eventList.size(); currentIndex++) {
+ se = eventList.get(currentIndex);
+
+ if(se instanceof StartEvent) {
+ interpreter.startElement((StartEvent) se);
+ // invoke fireInPlay after startElement processing
+ interpreter.getInterpretationContext().fireInPlay(se);
+ }
+ if(se instanceof BodyEvent) {
+ // invoke fireInPlay before characters processing
+ interpreter.getInterpretationContext().fireInPlay(se);
+ interpreter.characters((BodyEvent) se);
+ }
+ if(se instanceof EndEvent) {
+ // invoke fireInPlay before endElement processing
+ interpreter.getInterpretationContext().fireInPlay(se);
+ interpreter.endElement((EndEvent) se);
+ }
+
}
+ }
+
+ public void addEventsDynamically(List<SaxEvent> eventList, int offset) {
+ this.eventList.addAll(currentIndex+offset, eventList);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/HostClassAndPropertyDouble.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/HostClassAndPropertyDouble.java
index 3b86a97..c2d2d3b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/HostClassAndPropertyDouble.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/HostClassAndPropertyDouble.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,51 +25,52 @@ package ch.qos.logback.core.joran.spi;
*/
public class HostClassAndPropertyDouble {
- final Class<?> hostClass;
- final String propertyName;
+ final Class<?> hostClass;
+ final String propertyName;
- public HostClassAndPropertyDouble(Class<?> hostClass, String propertyName) {
- this.hostClass = hostClass;
- this.propertyName = propertyName;
- }
+ public HostClassAndPropertyDouble(Class<?> hostClass, String propertyName) {
+ this.hostClass = hostClass;
+ this.propertyName = propertyName;
+ }
- public Class<?> getHostClass() {
- return hostClass;
- }
+ public Class<?> getHostClass() {
+ return hostClass;
+ }
- public String getPropertyName() {
- return propertyName;
- }
+ public String getPropertyName() {
+ return propertyName;
+ }
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((hostClass == null) ? 0 : hostClass.hashCode());
- result = prime * result + ((propertyName == null) ? 0 : propertyName.hashCode());
- return result;
- }
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((hostClass == null) ? 0 : hostClass.hashCode());
+ result = prime * result
+ + ((propertyName == null) ? 0 : propertyName.hashCode());
+ return result;
+ }
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final HostClassAndPropertyDouble other = (HostClassAndPropertyDouble) obj;
- if (hostClass == null) {
- if (other.hostClass != null)
- return false;
- } else if (!hostClass.equals(other.hostClass))
- return false;
- if (propertyName == null) {
- if (other.propertyName != null)
- return false;
- } else if (!propertyName.equals(other.propertyName))
- return false;
- return true;
- }
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final HostClassAndPropertyDouble other = (HostClassAndPropertyDouble) obj;
+ if (hostClass == null) {
+ if (other.hostClass != null)
+ return false;
+ } else if (!hostClass.equals(other.hostClass))
+ return false;
+ if (propertyName == null) {
+ if (other.propertyName != null)
+ return false;
+ } else if (!propertyName.equals(other.propertyName))
+ return false;
+ return true;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java
index 4334834..d1ee3c5 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -38,144 +38,149 @@ import ch.qos.logback.core.util.OptionHelper;
*
* @author Ceki Gülcü
*/
-public class InterpretationContext extends ContextAwareBase implements PropertyContainer {
- Stack<Object> objectStack;
- Map<String, Object> objectMap;
- Map<String, String> propertiesMap;
-
- Interpreter joranInterpreter;
- final List<InPlayListener> listenerList = new ArrayList<InPlayListener>();
- DefaultNestedComponentRegistry defaultNestedComponentRegistry = new DefaultNestedComponentRegistry();
-
- public InterpretationContext(Context context, Interpreter joranInterpreter) {
- this.context = context;
- this.joranInterpreter = joranInterpreter;
- objectStack = new Stack<Object>();
- objectMap = new HashMap<String, Object>(5);
- propertiesMap = new HashMap<String, String>(5);
- }
-
- public DefaultNestedComponentRegistry getDefaultNestedComponentRegistry() {
- return defaultNestedComponentRegistry;
- }
-
- public Map<String, String> getCopyOfPropertyMap() {
- return new HashMap<String, String>(propertiesMap);
- }
-
- void setPropertiesMap(Map<String, String> propertiesMap) {
- this.propertiesMap = propertiesMap;
- }
-
- String updateLocationInfo(String msg) {
- Locator locator = joranInterpreter.getLocator();
-
- if (locator != null) {
- return msg + locator.getLineNumber() + ":" + locator.getColumnNumber();
- } else {
- return msg;
- }
- }
-
- public Locator getLocator() {
- return joranInterpreter.getLocator();
- }
-
- public Interpreter getJoranInterpreter() {
- return joranInterpreter;
- }
-
- public Stack<Object> getObjectStack() {
- return objectStack;
- }
-
- public boolean isEmpty() {
- return objectStack.isEmpty();
- }
-
- public Object peekObject() {
- return objectStack.peek();
- }
-
- public void pushObject(Object o) {
- objectStack.push(o);
- }
-
- public Object popObject() {
- return objectStack.pop();
- }
-
- public Object getObject(int i) {
- return objectStack.get(i);
- }
-
- public Map<String, Object> getObjectMap() {
- return objectMap;
- }
-
- /**
- * Add a property to the properties of this execution context. If the property
- * exists already, it is overwritten.
- */
- public void addSubstitutionProperty(String key, String value) {
- if (key == null || value == null) {
- return;
- }
- // values with leading or trailing spaces are bad. We remove them now.
- value = value.trim();
- propertiesMap.put(key, value);
- }
-
- public void addSubstitutionProperties(Properties props) {
- if (props == null) {
- return;
- }
- for (Object keyObject : props.keySet()) {
- String key = (String) keyObject;
- String val = props.getProperty(key);
- addSubstitutionProperty(key, val);
- }
- }
-
- /**
- * If a key is found in propertiesMap then return it. Otherwise, delegate to
- * the context.
- */
- public String getProperty(String key) {
- String v = propertiesMap.get(key);
- if (v != null) {
- return v;
- } else {
- return context.getProperty(key);
- }
- }
-
- public String subst(String value) {
- if (value == null) {
- return null;
- }
- return OptionHelper.substVars(value, this, context);
- }
-
- public boolean isListenerListEmpty() {
- return listenerList.isEmpty();
- }
-
- public void addInPlayListener(InPlayListener ipl) {
- if (listenerList.contains(ipl)) {
- addWarn("InPlayListener " + ipl + " has been already registered");
- } else {
- listenerList.add(ipl);
- }
- }
-
- public boolean removeInPlayListener(InPlayListener ipl) {
- return listenerList.remove(ipl);
- }
-
- void fireInPlay(SaxEvent event) {
- for (InPlayListener ipl : listenerList) {
- ipl.inPlay(event);
- }
- }
+public class InterpretationContext extends ContextAwareBase implements
+ PropertyContainer {
+ Stack<Object> objectStack;
+ Map<String, Object> objectMap;
+ Map<String, String> propertiesMap;
+
+ Interpreter joranInterpreter;
+ final List<InPlayListener> listenerList = new ArrayList<InPlayListener>();
+ DefaultNestedComponentRegistry defaultNestedComponentRegistry = new DefaultNestedComponentRegistry();
+
+ public InterpretationContext(Context context, Interpreter joranInterpreter) {
+ this.context = context;
+ this.joranInterpreter = joranInterpreter;
+ objectStack = new Stack<Object>();
+ objectMap = new HashMap<String, Object>(5);
+ propertiesMap = new HashMap<String, String>(5);
+ }
+
+
+ public DefaultNestedComponentRegistry getDefaultNestedComponentRegistry() {
+ return defaultNestedComponentRegistry;
+ }
+
+ public Map<String, String> getCopyOfPropertyMap() {
+ return new HashMap<String, String>(propertiesMap);
+ }
+
+ void setPropertiesMap(Map<String, String> propertiesMap) {
+ this.propertiesMap = propertiesMap;
+ }
+
+ String updateLocationInfo(String msg) {
+ Locator locator = joranInterpreter.getLocator();
+
+ if (locator != null) {
+ return msg + locator.getLineNumber() + ":" + locator.getColumnNumber();
+ } else {
+ return msg;
+ }
+ }
+
+ public Locator getLocator() {
+ return joranInterpreter.getLocator();
+ }
+
+ public Interpreter getJoranInterpreter() {
+ return joranInterpreter;
+ }
+
+ public Stack<Object> getObjectStack() {
+ return objectStack;
+ }
+
+ public boolean isEmpty() {
+ return objectStack.isEmpty();
+ }
+
+ public Object peekObject() {
+ return objectStack.peek();
+ }
+
+ public void pushObject(Object o) {
+ objectStack.push(o);
+ }
+
+ public Object popObject() {
+ return objectStack.pop();
+ }
+
+ public Object getObject(int i) {
+ return objectStack.get(i);
+ }
+
+ public Map<String, Object> getObjectMap() {
+ return objectMap;
+ }
+
+ /**
+ * Add a property to the properties of this execution context. If the property
+ * exists already, it is overwritten.
+ */
+ public void addSubstitutionProperty(String key, String value) {
+ if (key == null || value == null) {
+ return;
+ }
+ // values with leading or trailing spaces are bad. We remove them now.
+ value = value.trim();
+ propertiesMap.put(key, value);
+ }
+
+ public void addSubstitutionProperties(Properties props) {
+ if (props == null) {
+ return;
+ }
+ for(Object keyObject: props.keySet()) {
+ String key = (String) keyObject;
+ String val = props.getProperty(key);
+ addSubstitutionProperty(key, val);
+ }
+ }
+
+ /**
+ * If a key is found in propertiesMap then return it. Otherwise, delegate to
+ * the context.
+ */
+ public String getProperty(String key) {
+ String v = propertiesMap.get(key);
+ if (v != null) {
+ return v;
+ } else {
+ return context.getProperty(key);
+ }
+ }
+
+ public String subst(String value) {
+ if (value == null) {
+ return null;
+ }
+ return OptionHelper.substVars(value, this, context);
+ }
+
+
+
+
+ public boolean isListenerListEmpty() {
+ return listenerList.isEmpty();
+ }
+
+ public void addInPlayListener(InPlayListener ipl) {
+ if (listenerList.contains(ipl)) {
+ addWarn("InPlayListener " + ipl + " has been already registered");
+ } else {
+ listenerList.add(ipl);
+ }
+ }
+
+ public boolean removeInPlayListener(InPlayListener ipl) {
+ return listenerList.remove(ipl);
+ }
+
+ void fireInPlay(SaxEvent event) {
+ for (InPlayListener ipl : listenerList) {
+ ipl.inPlay(event);
+ }
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
index 604450b..4de45ad 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -61,266 +61,274 @@ import ch.qos.logback.core.spi.ContextAwareImpl;
* unreliable. Last but not least, Joran is quite tiny and is expected to remain
* so.
*
- * @author Ceki Gülcü
+ * @author Ceki Gülcuü
*
*/
public class Interpreter {
- private static List<Action> EMPTY_LIST = new Vector<Action>(0);
-
- final private RuleStore ruleStore;
- final private InterpretationContext interpretationContext;
- final private ArrayList<ImplicitAction> implicitActions;
- final private CAI_WithLocatorSupport cai;
- private ElementPath elementPath;
- Locator locator;
- EventPlayer eventPlayer;
-
- /**
- * The <id>actionListStack</id> contains a list of actions that are executing
- * for the given XML element.
- *
- * A list of actions is pushed by the {link #startElement} and popped by
- * {@link #endElement}.
- *
- */
- Stack<List<Action>> actionListStack;
-
- /**
- * If the skip nested is set, then we skip all its nested elements until it is
- * set back to null at when the element's end is reached.
- */
- ElementPath skip = null;
-
- public Interpreter(Context context, RuleStore rs, ElementPath initialElementPath) {
- this.cai = new CAI_WithLocatorSupport(context, this);
- ruleStore = rs;
- interpretationContext = new InterpretationContext(context, this);
- implicitActions = new ArrayList<ImplicitAction>(3);
- this.elementPath = initialElementPath;
- actionListStack = new Stack<List<Action>>();
- eventPlayer = new EventPlayer(this);
+ private static List<Action> EMPTY_LIST = new Vector<Action>(0);
+
+ final private RuleStore ruleStore;
+ final private InterpretationContext interpretationContext;
+ final private ArrayList<ImplicitAction> implicitActions;
+ final private CAI_WithLocatorSupport cai;
+ private ElementPath elementPath;
+ Locator locator;
+ EventPlayer eventPlayer;
+
+ /**
+ * The <id>actionListStack</id> contains a list of actions that are executing
+ * for the given XML element.
+ *
+ * A list of actions is pushed by the {link #startElement} and popped by
+ * {@link #endElement}.
+ *
+ */
+ Stack<List<Action>> actionListStack;
+
+ /**
+ * If the skip nested is set, then we skip all its nested elements until it is
+ * set back to null at when the element's end is reached.
+ */
+ ElementPath skip = null;
+
+ public Interpreter(Context context, RuleStore rs, ElementPath initialElementPath) {
+ this.cai = new CAI_WithLocatorSupport(context, this);
+ ruleStore = rs;
+ interpretationContext = new InterpretationContext(context, this);
+ implicitActions = new ArrayList<ImplicitAction>(3);
+ this.elementPath = initialElementPath;
+ actionListStack = new Stack<List<Action>>();
+ eventPlayer = new EventPlayer(this);
+ }
+
+ public EventPlayer getEventPlayer() {
+ return eventPlayer;
+ }
+
+ public void setInterpretationContextPropertiesMap(
+ Map<String, String> propertiesMap) {
+ interpretationContext.setPropertiesMap(propertiesMap);
+ }
+
+ /**
+ * @deprecated replaced by {@link #getInterpretationContext()}
+ */
+ public InterpretationContext getExecutionContext() {
+ return getInterpretationContext();
+ }
+
+ public InterpretationContext getInterpretationContext() {
+ return interpretationContext;
+ }
+
+ public void startDocument() {
+ }
+
+ public void startElement(StartEvent se) {
+ setDocumentLocator(se.getLocator());
+ startElement(se.namespaceURI, se.localName, se.qName, se.attributes);
+ }
+
+ private void startElement(String namespaceURI, String localName,
+ String qName, Attributes atts) {
+
+ String tagName = getTagName(localName, qName);
+ elementPath.push(tagName);
+
+ if (skip != null) {
+ // every startElement pushes an action list
+ pushEmptyActionList();
+ return;
}
- public EventPlayer getEventPlayer() {
- return eventPlayer;
+ List<Action> applicableActionList = getApplicableActionList(elementPath, atts);
+ if (applicableActionList != null) {
+ actionListStack.add(applicableActionList);
+ callBeginAction(applicableActionList, tagName, atts);
+ } else {
+ // every startElement pushes an action list
+ pushEmptyActionList();
+ String errMsg = "no applicable action for [" + tagName
+ + "], current ElementPath is [" + elementPath + "]";
+ cai.addError(errMsg);
}
+ }
- public void setInterpretationContextPropertiesMap(Map<String, String> propertiesMap) {
- interpretationContext.setPropertiesMap(propertiesMap);
- }
+ /**
+ * This method is used to
+ */
+ private void pushEmptyActionList() {
+ actionListStack.add(EMPTY_LIST);
+ }
- /**
- * @deprecated replaced by {@link #getInterpretationContext()}
- */
- public InterpretationContext getExecutionContext() {
- return getInterpretationContext();
- }
+ public void characters(BodyEvent be) {
- public InterpretationContext getInterpretationContext() {
- return interpretationContext;
- }
-
- public void startDocument() {
- }
+ setDocumentLocator(be.locator);
- public void startElement(StartEvent se) {
- setDocumentLocator(se.getLocator());
- startElement(se.namespaceURI, se.localName, se.qName, se.attributes);
- }
+ String body = be.getText();
+ List<Action> applicableActionList = actionListStack.peek();
- private void startElement(String namespaceURI, String localName, String qName, Attributes atts) {
-
- String tagName = getTagName(localName, qName);
- elementPath.push(tagName);
-
- if (skip != null) {
- // every startElement pushes an action list
- pushEmptyActionList();
- return;
- }
-
- List<Action> applicableActionList = getApplicableActionList(elementPath, atts);
- if (applicableActionList != null) {
- actionListStack.add(applicableActionList);
- callBeginAction(applicableActionList, tagName, atts);
- } else {
- // every startElement pushes an action list
- pushEmptyActionList();
- String errMsg = "no applicable action for [" + tagName + "], current ElementPath is [" + elementPath + "]";
- cai.addError(errMsg);
- }
+ if (body != null) {
+ body = body.trim();
+ if (body.length() > 0) {
+ // System.out.println("calling body method with ["+body+ "]");
+ callBodyAction(applicableActionList, body);
+ }
}
-
- /**
- * This method is used to
- */
- private void pushEmptyActionList() {
- actionListStack.add(EMPTY_LIST);
+ }
+
+ public void endElement(EndEvent endEvent) {
+ setDocumentLocator(endEvent.locator);
+ endElement(endEvent.namespaceURI, endEvent.localName, endEvent.qName);
+ }
+
+ private void endElement(String namespaceURI, String localName, String qName) {
+ // given that an action list is always pushed for every startElement, we
+ // need
+ // to always pop for every endElement
+ List<Action> applicableActionList = (List<Action>) actionListStack.pop();
+
+ if (skip != null) {
+ if (skip.equals(elementPath)) {
+ skip = null;
+ }
+ } else if (applicableActionList != EMPTY_LIST) {
+ callEndAction(applicableActionList, getTagName(localName, qName));
}
- public void characters(BodyEvent be) {
+ // given that we always push, we must also pop the pattern
+ elementPath.pop();
+ }
- setDocumentLocator(be.locator);
+ public Locator getLocator() {
+ return locator;
+ }
- String body = be.getText();
- List<Action> applicableActionList = actionListStack.peek();
+ public void setDocumentLocator(Locator l) {
+ locator = l;
+ }
- if (body != null) {
- body = body.trim();
- if (body.length() > 0) {
- // System.out.println("calling body method with ["+body+ "]");
- callBodyAction(applicableActionList, body);
- }
- }
- }
-
- public void endElement(EndEvent endEvent) {
- setDocumentLocator(endEvent.locator);
- endElement(endEvent.namespaceURI, endEvent.localName, endEvent.qName);
- }
+ String getTagName(String localName, String qName) {
+ String tagName = localName;
- private void endElement(String namespaceURI, String localName, String qName) {
- // given that an action list is always pushed for every startElement, we
- // need
- // to always pop for every endElement
- List<Action> applicableActionList = (List<Action>) actionListStack.pop();
-
- if (skip != null) {
- if (skip.equals(elementPath)) {
- skip = null;
- }
- } else if (applicableActionList != EMPTY_LIST) {
- callEndAction(applicableActionList, getTagName(localName, qName));
- }
-
- // given that we always push, we must also pop the pattern
- elementPath.pop();
+ if ((tagName == null) || (tagName.length() < 1)) {
+ tagName = qName;
}
- public Locator getLocator() {
- return locator;
- }
+ return tagName;
+ }
- public void setDocumentLocator(Locator l) {
- locator = l;
- }
+ public void addImplicitAction(ImplicitAction ia) {
+ implicitActions.add(ia);
+ }
- String getTagName(String localName, String qName) {
- String tagName = localName;
+ /**
+ * Check if any implicit actions are applicable. As soon as an applicable
+ * action is found, it is returned. Thus, the returned list will have at most
+ * one element.
+ */
+ List<Action> lookupImplicitAction(ElementPath elementPath, Attributes attributes,
+ InterpretationContext ec) {
+ int len = implicitActions.size();
- if ((tagName == null) || (tagName.length() < 1)) {
- tagName = qName;
- }
+ for (int i = 0; i < len; i++) {
+ ImplicitAction ia = (ImplicitAction) implicitActions.get(i);
- return tagName;
- }
+ if (ia.isApplicable(elementPath, attributes, ec)) {
+ List<Action> actionList = new ArrayList<Action>(1);
+ actionList.add(ia);
- public void addImplicitAction(ImplicitAction ia) {
- implicitActions.add(ia);
+ return actionList;
+ }
}
- /**
- * Check if any implicit actions are applicable. As soon as an applicable
- * action is found, it is returned. Thus, the returned list will have at most
- * one element.
- */
- List<Action> lookupImplicitAction(ElementPath elementPath, Attributes attributes, InterpretationContext ec) {
- int len = implicitActions.size();
-
- for (int i = 0; i < len; i++) {
- ImplicitAction ia = (ImplicitAction) implicitActions.get(i);
-
- if (ia.isApplicable(elementPath, attributes, ec)) {
- List<Action> actionList = new ArrayList<Action>(1);
- actionList.add(ia);
+ return null;
+ }
- return actionList;
- }
- }
+ /**
+ * Return the list of applicable patterns for this
+ */
+ List<Action> getApplicableActionList(ElementPath elementPath, Attributes attributes) {
+ List<Action> applicableActionList = ruleStore.matchActions(elementPath);
- return null;
+ // logger.debug("set of applicable patterns: " + applicableActionList);
+ if (applicableActionList == null) {
+ applicableActionList = lookupImplicitAction(elementPath, attributes,
+ interpretationContext);
}
- /**
- * Return the list of applicable patterns for this
- */
- List<Action> getApplicableActionList(ElementPath elementPath, Attributes attributes) {
- List<Action> applicableActionList = ruleStore.matchActions(elementPath);
+ return applicableActionList;
+ }
- // logger.debug("set of applicable patterns: " + applicableActionList);
- if (applicableActionList == null) {
- applicableActionList = lookupImplicitAction(elementPath, attributes, interpretationContext);
- }
-
- return applicableActionList;
+ void callBeginAction(List<Action> applicableActionList, String tagName,
+ Attributes atts) {
+ if (applicableActionList == null) {
+ return;
}
- void callBeginAction(List<Action> applicableActionList, String tagName, Attributes atts) {
- if (applicableActionList == null) {
- return;
- }
-
- Iterator<Action> i = applicableActionList.iterator();
- while (i.hasNext()) {
- Action action = (Action) i.next();
- // now let us invoke the action. We catch and report any eventual
- // exceptions
- try {
- action.begin(interpretationContext, tagName, atts);
- } catch (ActionException e) {
- skip = elementPath.duplicate();
- cai.addError("ActionException in Action for tag [" + tagName + "]", e);
- } catch (RuntimeException e) {
- skip = elementPath.duplicate();
- cai.addError("RuntimeException in Action for tag [" + tagName + "]", e);
- }
- }
+ Iterator<Action> i = applicableActionList.iterator();
+ while (i.hasNext()) {
+ Action action = (Action) i.next();
+ // now let us invoke the action. We catch and report any eventual
+ // exceptions
+ try {
+ action.begin(interpretationContext, tagName, atts);
+ } catch (ActionException e) {
+ skip = elementPath.duplicate();
+ cai.addError("ActionException in Action for tag [" + tagName + "]", e);
+ } catch (RuntimeException e) {
+ skip = elementPath.duplicate();
+ cai.addError("RuntimeException in Action for tag [" + tagName + "]", e);
+ }
}
+ }
- private void callBodyAction(List<Action> applicableActionList, String body) {
- if (applicableActionList == null) {
- return;
- }
- Iterator<Action> i = applicableActionList.iterator();
-
- while (i.hasNext()) {
- Action action = i.next();
- try {
- action.body(interpretationContext, body);
- } catch (ActionException ae) {
- cai.addError("Exception in end() methd for action [" + action + "]", ae);
- }
- }
+ private void callBodyAction(List<Action> applicableActionList, String body) {
+ if (applicableActionList == null) {
+ return;
+ }
+ Iterator<Action> i = applicableActionList.iterator();
+
+ while (i.hasNext()) {
+ Action action = i.next();
+ try {
+ action.body(interpretationContext, body);
+ } catch (ActionException ae) {
+ cai
+ .addError("Exception in end() methd for action [" + action + "]",
+ ae);
+ }
}
+ }
- private void callEndAction(List<Action> applicableActionList, String tagName) {
- if (applicableActionList == null) {
- return;
- }
-
- // logger.debug("About to call end actions on node: [" + localName + "]");
- Iterator<Action> i = applicableActionList.iterator();
-
- while (i.hasNext()) {
- Action action = i.next();
- // now let us invoke the end method of the action. We catch and report
- // any eventual exceptions
- try {
- action.end(interpretationContext, tagName);
- } catch (ActionException ae) {
- // at this point endAction, there is no point in skipping children as
- // they have been already processed
- cai.addError("ActionException in Action for tag [" + tagName + "]", ae);
- } catch (RuntimeException e) {
- // no point in setting skip
- cai.addError("RuntimeException in Action for tag [" + tagName + "]", e);
- }
- }
+ private void callEndAction(List<Action> applicableActionList, String tagName) {
+ if (applicableActionList == null) {
+ return;
}
- public RuleStore getRuleStore() {
- return ruleStore;
+ // logger.debug("About to call end actions on node: [" + localName + "]");
+ Iterator<Action> i = applicableActionList.iterator();
+
+ while (i.hasNext()) {
+ Action action = i.next();
+ // now let us invoke the end method of the action. We catch and report
+ // any eventual exceptions
+ try {
+ action.end(interpretationContext, tagName);
+ } catch (ActionException ae) {
+ // at this point endAction, there is no point in skipping children as
+ // they have been already processed
+ cai.addError("ActionException in Action for tag [" + tagName + "]", ae);
+ } catch (RuntimeException e) {
+ // no point in setting skip
+ cai.addError("RuntimeException in Action for tag [" + tagName + "]", e);
+ }
}
+ }
+
+ public RuleStore getRuleStore() {
+ return ruleStore;
+ }
}
/**
@@ -332,18 +340,19 @@ public class Interpreter {
*/
class CAI_WithLocatorSupport extends ContextAwareImpl {
- CAI_WithLocatorSupport(Context context, Interpreter interpreter) {
- super(context, interpreter);
- }
-
- @Override
- protected Object getOrigin() {
- Interpreter i = (Interpreter) super.getOrigin();
- Locator locator = i.locator;
- if (locator != null) {
- return Interpreter.class.getName() + "@" + locator.getLineNumber() + ":" + locator.getColumnNumber();
- } else {
- return Interpreter.class.getName() + "@NA:NA";
- }
+ CAI_WithLocatorSupport(Context context, Interpreter interpreter) {
+ super(context, interpreter);
+ }
+
+ @Override
+ protected Object getOrigin() {
+ Interpreter i = (Interpreter) super.getOrigin();
+ Locator locator = i.locator;
+ if (locator != null) {
+ return Interpreter.class.getName() + "@" + locator.getLineNumber() + ":"
+ + locator.getColumnNumber();
+ } else {
+ return Interpreter.class.getName() + "@NA:NA";
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/JoranException.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/JoranException.java
index c9a7749..59cca72 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/JoranException.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/JoranException.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,13 +15,13 @@ package ch.qos.logback.core.joran.spi;
public class JoranException extends Exception {
- private static final long serialVersionUID = 1112493363728774021L;
+ private static final long serialVersionUID = 1112493363728774021L;
- public JoranException(String msg) {
- super(msg);
- }
-
- public JoranException(String msg, Throwable cause) {
- super(msg, cause);
- }
+ public JoranException(String msg) {
+ super(msg);
+ }
+
+ public JoranException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/NoAutoStart.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/NoAutoStart.java
index c86d867..6acd1e6 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/NoAutoStart.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/NoAutoStart.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/NoAutoStartUtil.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/NoAutoStartUtil.java
index 3b5d7dc..b420bd9 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/NoAutoStartUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/NoAutoStartUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,20 +15,20 @@ package ch.qos.logback.core.joran.spi;
public class NoAutoStartUtil {
- /**
- * Returns true if the class of the object 'o' passed as parameter is *not*
- * marked with the NoAutoStart annotation. Return true otherwise.
- *
- * @param o
- * @return true for classes not marked with the NoAutoStart annotation
- */
- static public boolean notMarkedWithNoAutoStart(Object o) {
- if (o == null) {
- return false;
- }
- Class<?> clazz = o.getClass();
- NoAutoStart a = clazz.getAnnotation(NoAutoStart.class);
- return a == null;
+ /**
+ * Returns true if the class of the object 'o' passed as parameter is *not*
+ * marked with the NoAutoStart annotation. Return true otherwise.
+ *
+ * @param o
+ * @return true for classes not marked with the NoAutoStart annotation
+ */
+ static public boolean notMarkedWithNoAutoStart(Object o) {
+ if (o == null) {
+ return false;
}
+ Class<?> clazz = o.getClass();
+ NoAutoStart a = clazz.getAnnotation(NoAutoStart.class);
+ return a == null;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/RuleStore.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/RuleStore.java
index 7282a27..e880061 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/RuleStore.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/RuleStore.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,28 +31,29 @@ import ch.qos.logback.core.joran.action.Action;
*/
public interface RuleStore {
- /**
- * Add a new rule, given by a pattern and a action class (String).
- *
- * @param elementSelector
- * @param actionClassStr
- * @throws ClassNotFoundException
- */
- void addRule(ElementSelector elementSelector, String actionClassStr) throws ClassNotFoundException;
+ /**
+ * Add a new rule, given by a pattern and a action class (String).
+ *
+ * @param elementSelector
+ * @param actionClassStr
+ * @throws ClassNotFoundException
+ */
+ void addRule(ElementSelector elementSelector, String actionClassStr)
+ throws ClassNotFoundException;
- /**
- * Add a new rule, given by a pattern and an action instance.
- *
- * @param elementSelector
- * @param action
- */
- void addRule(ElementSelector elementSelector, Action action);
+ /**
+ * Add a new rule, given by a pattern and an action instance.
+ *
+ * @param elementSelector
+ * @param action
+ */
+ void addRule(ElementSelector elementSelector, Action action);
- /**
- * Return a list of actions matching a pattern.
- *
- * @param elementPath the path to match for
- * @return list of matching actions
- */
- List<Action> matchActions(ElementPath elementPath);
+ /**
+ * Return a list of actions matching a pattern.
+ *
+ * @param elementPath the path to match for
+ * @return list of matching actions
+ */
+ List<Action> matchActions(ElementPath elementPath);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/SimpleRuleStore.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/SimpleRuleStore.java
index 1e9c483..aae6c1a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/SimpleRuleStore.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/SimpleRuleStore.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,177 +31,180 @@ import ch.qos.logback.core.util.OptionHelper;
*/
public class SimpleRuleStore extends ContextAwareBase implements RuleStore {
- static String KLEENE_STAR = "*";
+ static String KLEENE_STAR = "*";
+
+ // key: Pattern instance, value: ArrayList containing actions
+ HashMap<ElementSelector, List<Action>> rules = new HashMap<ElementSelector, List<Action>>();
- // key: Pattern instance, value: ArrayList containing actions
- HashMap<ElementSelector, List<Action>> rules = new HashMap<ElementSelector, List<Action>>();
+ // public SimpleRuleStore() {
+ // }
- // public SimpleRuleStore() {
- // }
+ public SimpleRuleStore(Context context) {
+ setContext(context);
+ }
- public SimpleRuleStore(Context context) {
- setContext(context);
- }
-
- /**
- * Add a new rule, i.e. a pattern, action pair to the rule store. <p> Note
- * that the added action's LoggerRepository will be set in the process.
- */
- public void addRule(ElementSelector elementSelector, Action action) {
- action.setContext(context);
-
- List<Action> a4p = rules.get(elementSelector);
+ /**
+ * Add a new rule, i.e. a pattern, action pair to the rule store. <p> Note
+ * that the added action's LoggerRepository will be set in the process.
+ */
+ public void addRule(ElementSelector elementSelector, Action action) {
+ action.setContext(context);
- if (a4p == null) {
- a4p = new ArrayList<Action>();
- rules.put(elementSelector, a4p);
- }
+ List<Action> a4p = rules.get(elementSelector);
- a4p.add(action);
+ if (a4p == null) {
+ a4p = new ArrayList<Action>();
+ rules.put(elementSelector, a4p);
}
- public void addRule(ElementSelector elementSelector, String actionClassName) {
- Action action = null;
+ a4p.add(action);
+ }
- try {
- action = (Action) OptionHelper.instantiateByClassName(actionClassName, Action.class, context);
- } catch (Exception e) {
- addError("Could not instantiate class [" + actionClassName + "]", e);
- }
- if (action != null) {
- addRule(elementSelector, action);
- }
- }
+ public void addRule(ElementSelector elementSelector, String actionClassName) {
+ Action action = null;
- // exact match has highest priority
- // if no exact match, check for suffix (tail) match, i.e matches
- // of type */x/y. Suffix match for */x/y has higher priority than match for
- // */x
- // if no suffix match, check for prefix match, i.e. matches for x/*
- // match for x/y/* has higher priority than matches for x/*
-
- public List<Action> matchActions(ElementPath elementPath) {
- List<Action> actionList;
-
- if ((actionList = fullPathMatch(elementPath)) != null) {
- return actionList;
- } else if ((actionList = suffixMatch(elementPath)) != null) {
- return actionList;
- } else if ((actionList = prefixMatch(elementPath)) != null) {
- return actionList;
- } else if ((actionList = middleMatch(elementPath)) != null) {
- return actionList;
- } else {
- return null;
- }
+ try {
+ action = (Action) OptionHelper.instantiateByClassName(actionClassName,
+ Action.class, context);
+ } catch (Exception e) {
+ addError("Could not instantiate class [" + actionClassName + "]", e);
}
-
- List<Action> fullPathMatch(ElementPath elementPath) {
- for (ElementSelector selector : rules.keySet()) {
- if (selector.fullPathMatch(elementPath))
- return rules.get(selector);
- }
- return null;
+ if (action != null) {
+ addRule(elementSelector, action);
}
-
- // Suffix matches are matches of type */x/y
- List<Action> suffixMatch(ElementPath elementPath) {
- int max = 0;
- ElementSelector longestMatchingElementSelector = null;
-
- for (ElementSelector selector : rules.keySet()) {
- if (isSuffixPattern(selector)) {
- int r = selector.getTailMatchLength(elementPath);
- if (r > max) {
- max = r;
- longestMatchingElementSelector = selector;
- }
- }
- }
-
- if (longestMatchingElementSelector != null) {
- return rules.get(longestMatchingElementSelector);
- } else {
- return null;
- }
+ }
+
+ // exact match has highest priority
+ // if no exact match, check for suffix (tail) match, i.e matches
+ // of type */x/y. Suffix match for */x/y has higher priority than match for
+ // */x
+ // if no suffix match, check for prefix match, i.e. matches for x/*
+ // match for x/y/* has higher priority than matches for x/*
+
+ public List<Action> matchActions(ElementPath elementPath) {
+ List<Action> actionList;
+
+ if ((actionList = fullPathMatch(elementPath)) != null) {
+ return actionList;
+ } else if ((actionList = suffixMatch(elementPath)) != null) {
+ return actionList;
+ } else if ((actionList = prefixMatch(elementPath)) != null) {
+ return actionList;
+ } else if ((actionList = middleMatch(elementPath)) != null) {
+ return actionList;
+ } else {
+ return null;
}
+ }
- private boolean isSuffixPattern(ElementSelector p) {
- return (p.size() > 1) && p.get(0).equals(KLEENE_STAR);
+ List<Action> fullPathMatch(ElementPath elementPath) {
+ for (ElementSelector selector : rules.keySet()) {
+ if(selector.fullPathMatch(elementPath))
+ return rules.get(selector);
}
-
- List<Action> prefixMatch(ElementPath elementPath) {
- int max = 0;
- ElementSelector longestMatchingElementSelector = null;
-
- for (ElementSelector selector : rules.keySet()) {
- String last = selector.peekLast();
- if (isKleeneStar(last)) {
- int r = selector.getPrefixMatchLength(elementPath);
- // to qualify the match length must equal p's size omitting the '*'
- if ((r == selector.size() - 1) && (r > max)) {
- max = r;
- longestMatchingElementSelector = selector;
- }
- }
+ return null;
+ }
+
+ // Suffix matches are matches of type */x/y
+ List<Action> suffixMatch(ElementPath elementPath) {
+ int max = 0;
+ ElementSelector longestMatchingElementSelector = null;
+
+ for (ElementSelector selector : rules.keySet()) {
+ if (isSuffixPattern(selector)) {
+ int r = selector.getTailMatchLength(elementPath);
+ if (r > max) {
+ max = r;
+ longestMatchingElementSelector = selector;
}
+ }
+ }
- if (longestMatchingElementSelector != null) {
- return rules.get(longestMatchingElementSelector);
- } else {
- return null;
+ if (longestMatchingElementSelector != null) {
+ return rules.get(longestMatchingElementSelector);
+ } else {
+ return null;
+ }
+ }
+
+ private boolean isSuffixPattern(ElementSelector p) {
+ return (p.size() > 1) && p.get(0).equals(KLEENE_STAR);
+ }
+
+ List<Action> prefixMatch(ElementPath elementPath) {
+ int max = 0;
+ ElementSelector longestMatchingElementSelector = null;
+
+ for (ElementSelector selector : rules.keySet()) {
+ String last = selector.peekLast();
+ if (isKleeneStar(last)) {
+ int r = selector.getPrefixMatchLength(elementPath);
+ // to qualify the match length must equal p's size omitting the '*'
+ if ((r == selector.size() - 1) && (r > max)) {
+ max = r;
+ longestMatchingElementSelector = selector;
}
+ }
}
- private boolean isKleeneStar(String last) {
- return KLEENE_STAR.equals(last);
+ if (longestMatchingElementSelector != null) {
+ return rules.get(longestMatchingElementSelector);
+ } else {
+ return null;
}
-
- List<Action> middleMatch(ElementPath path) {
-
- int max = 0;
- ElementSelector longestMatchingElementSelector = null;
-
- for (ElementSelector selector : rules.keySet()) {
- String last = selector.peekLast();
- String first = null;
- if (selector.size() > 1) {
- first = selector.get(0);
- }
- if (isKleeneStar(last) && isKleeneStar(first)) {
- List<String> copyOfPartList = selector.getCopyOfPartList();
- if (copyOfPartList.size() > 2) {
- copyOfPartList.remove(0);
- copyOfPartList.remove(copyOfPartList.size() - 1);
- }
-
- int r = 0;
- ElementSelector clone = new ElementSelector(copyOfPartList);
- if (clone.isContainedIn(path)) {
- r = clone.size();
- }
- if (r > max) {
- max = r;
- longestMatchingElementSelector = selector;
- }
- }
+ }
+
+ private boolean isKleeneStar(String last) {
+ return KLEENE_STAR.equals(last);
+ }
+
+ List<Action> middleMatch(ElementPath path) {
+
+ int max = 0;
+ ElementSelector longestMatchingElementSelector = null;
+
+ for (ElementSelector selector : rules.keySet()) {
+ String last = selector.peekLast();
+ String first = null;
+ if(selector.size() > 1) {
+ first = selector.get(0);
+ }
+ if (isKleeneStar(last) && isKleeneStar(first)) {
+ List<String> copyOfPartList = selector.getCopyOfPartList();
+ if(copyOfPartList.size() > 2) {
+ copyOfPartList.remove(0);
+ copyOfPartList.remove(copyOfPartList.size()-1);
}
-
- if (longestMatchingElementSelector != null) {
- return rules.get(longestMatchingElementSelector);
- } else {
- return null;
+
+ int r = 0;
+ ElementSelector clone = new ElementSelector(copyOfPartList);
+ if(clone.isContainedIn(path)) {
+ r = clone.size();
+ }
+ if (r > max) {
+ max = r;
+ longestMatchingElementSelector = selector;
}
+ }
}
- public String toString() {
- final String TAB = " ";
+ if (longestMatchingElementSelector != null) {
+ return rules.get(longestMatchingElementSelector);
+ } else {
+ return null;
+ }
+ }
+
- StringBuilder retValue = new StringBuilder();
+ public String toString() {
+ final String TAB = " ";
- retValue.append("SimpleRuleStore ( ").append("rules = ").append(this.rules).append(TAB).append(" )");
+ StringBuilder retValue = new StringBuilder();
- return retValue.toString();
- }
+ retValue.append("SimpleRuleStore ( ").append("rules = ").append(this.rules)
+ .append(TAB).append(" )");
+
+ return retValue.toString();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/XMLUtil.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/XMLUtil.java
index 73d2e7d..5cee08e 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/XMLUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/XMLUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,12 +18,13 @@ import java.net.URL;
import ch.qos.logback.core.status.StatusManager;
public class XMLUtil {
+
- static public final int ILL_FORMED = 1;
- static public final int UNRECOVERABLE_ERROR = 2;
-
- static public int checkIfWellFormed(URL url, StatusManager sm) {
- return 0;
- }
-
+ static public final int ILL_FORMED = 1;
+ static public final int UNRECOVERABLE_ERROR = 2;
+
+ static public int checkIfWellFormed(URL url, StatusManager sm) {
+ return 0;
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/util/ConfigurationWatchListUtil.java b/logback-core/src/main/java/ch/qos/logback/core/joran/util/ConfigurationWatchListUtil.java
index e62bba3..8c806c7 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/util/ConfigurationWatchListUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/util/ConfigurationWatchListUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,84 +24,79 @@ import ch.qos.logback.core.status.WarnStatus;
import java.net.URL;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class ConfigurationWatchListUtil {
- final static ConfigurationWatchListUtil origin = new ConfigurationWatchListUtil();
+ final static ConfigurationWatchListUtil origin = new ConfigurationWatchListUtil();
- private ConfigurationWatchListUtil() {
- }
+ private ConfigurationWatchListUtil() {
+ }
-
- public static void registerConfigurationWatchList(Context context, ConfigurationWatchList cwl) {
- context.putObject(CoreConstants.CONFIGURATION_WATCH_LIST, cwl);
- }
- public static void setMainWatchURL(Context context, URL url) {
- ConfigurationWatchList cwl = getConfigurationWatchList(context);
- if (cwl == null) {
- cwl = new ConfigurationWatchList();
- cwl.setContext(context);
- context.putObject(CoreConstants.CONFIGURATION_WATCH_LIST, cwl);
- } else {
- cwl.clear();
- }
- //setConfigurationWatchListResetFlag(context, true);
- cwl.setMainURL(url);
+ public static void setMainWatchURL(Context context, URL url) {
+ ConfigurationWatchList cwl = getConfigurationWatchList(context);
+ if (cwl == null) {
+ cwl = new ConfigurationWatchList();
+ cwl.setContext(context);
+ context.putObject(CoreConstants.CONFIGURATION_WATCH_LIST, cwl);
+ } else {
+ cwl.clear();
}
+ setConfigurationWatchListResetFlag(context, true);
+ cwl.setMainURL(url);
+ }
- public static URL getMainWatchURL(Context context) {
- ConfigurationWatchList cwl = getConfigurationWatchList(context);
- if (cwl == null) {
- return null;
- } else {
- return cwl.getMainURL();
- }
+ public static URL getMainWatchURL(Context context) {
+ ConfigurationWatchList cwl = getConfigurationWatchList(context);
+ if (cwl == null) {
+ return null;
+ } else {
+ return cwl.getMainURL();
}
+ }
- public static void addToWatchList(Context context, URL url) {
- ConfigurationWatchList cwl = getConfigurationWatchList(context);
- if (cwl == null) {
- addWarn(context, "Null ConfigurationWatchList. Cannot add " + url);
- } else {
- addInfo(context, "Adding [" + url + "] to configuration watch list.");
- cwl.addToWatchList(url);
- }
+ public static void addToWatchList(Context context, URL url) {
+ ConfigurationWatchList cwl = getConfigurationWatchList(context);
+ if (cwl == null) {
+ addWarn(context, "Null ConfigurationWatchList. Cannot add " + url);
+ } else {
+ addInfo(context, "Adding [" + url + "] to configuration watch list.");
+ cwl.addToWatchList(url);
}
+ }
-// public static boolean wasConfigurationWatchListReset(Context context) {
-// Object o = context.getObject(CoreConstants.CONFIGURATION_WATCH_LIST_RESET);
-// if (o == null)
-// return false;
-// else {
-// return ((Boolean) o).booleanValue();
-// }
-// }
+ public static boolean wasConfigurationWatchListReset(Context context) {
+ Object o = context.getObject(CoreConstants.CONFIGURATION_WATCH_LIST_RESET);
+ if (o == null)
+ return false;
+ else {
+ return ((Boolean) o).booleanValue();
+ }
+ }
-// public static void setConfigurationWatchListResetFlag(Context context, boolean val) {
-// context.putObject(CoreConstants.CONFIGURATION_WATCH_LIST_RESET, new Boolean(val));
-// }
+ public static void setConfigurationWatchListResetFlag(Context context, boolean val) {
+ context.putObject(CoreConstants.CONFIGURATION_WATCH_LIST_RESET, new Boolean(val));
+ }
- public static ConfigurationWatchList getConfigurationWatchList(Context context) {
- return (ConfigurationWatchList) context.getObject(CoreConstants.CONFIGURATION_WATCH_LIST);
- }
+ public static ConfigurationWatchList getConfigurationWatchList(Context context) {
+ return (ConfigurationWatchList) context.getObject(CoreConstants.CONFIGURATION_WATCH_LIST);
+ }
- static void addStatus(Context context, Status s) {
- if (context == null) {
- System.out.println("Null context in " + ConfigurationWatchList.class.getName());
- return;
- }
- StatusManager sm = context.getStatusManager();
- if (sm == null)
- return;
- sm.add(s);
+ static void addStatus(Context context, Status s) {
+ if (context == null) {
+ System.out.println("Null context in " + ConfigurationWatchList.class.getName());
+ return;
}
+ StatusManager sm = context.getStatusManager();
+ if (sm == null) return;
+ sm.add(s);
+ }
- static void addInfo(Context context, String msg) {
- addStatus(context, new InfoStatus(msg, origin));
- }
+ static void addInfo(Context context, String msg) {
+ addStatus(context, new InfoStatus(msg, origin));
+ }
- static void addWarn(Context context, String msg) {
- addStatus(context, new WarnStatus(msg, origin));
- }
+ static void addWarn(Context context, String msg) {
+ addStatus(context, new WarnStatus(msg, origin));
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/util/PropertySetter.java b/logback-core/src/main/java/ch/qos/logback/core/joran/util/PropertySetter.java
index 9ff3ec5..8651e0c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/util/PropertySetter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/util/PropertySetter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,14 +14,16 @@
// Contributors: Georg Lundesgaard
package ch.qos.logback.core.joran.util;
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.MethodDescriptor;
+import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import ch.qos.logback.core.joran.spi.DefaultClass;
import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
-import ch.qos.logback.core.joran.util.beans.BeanDescription;
-import ch.qos.logback.core.joran.util.beans.BeanDescriptionCache;
-import ch.qos.logback.core.joran.util.beans.BeanUtil;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.util.AggregationType;
import ch.qos.logback.core.util.PropertySetterException;
@@ -31,368 +33,462 @@ import ch.qos.logback.core.util.PropertySetterException;
* {@link #setProperty setProperty(name,value)} in order to invoke setters on
* the Object specified in the constructor. This class relies on the JavaBeans
* {@link Introspector} to analyze the given Object Class using reflection.
- *
+ *
* <p>
* Usage:
- *
+ *
* <pre>
* PropertySetter ps = new PropertySetter(anObject);
* ps.set("name", "Joe");
* ps.set("age", "32");
* ps.set("isMale", "true");
* </pre>
- *
+ *
* will cause the invocations anObject.setName("Joe"), anObject.setAge(32), and
* setMale(true) if such methods exist with those signatures. Otherwise an
* {@link IntrospectionException} are thrown.
- *
+ *
* @author Anders Kristensen
* @author Ceki Gulcu
*/
public class PropertySetter extends ContextAwareBase {
- protected final Object obj;
- protected final Class<?> objClass;
- protected final BeanDescription beanDescription;
-
- /**
- * Create a new PropertySetter for the specified Object. This is done in
- * preparation for invoking {@link #setProperty} one or more times.
- *
- * @param obj
- * the object for which to set properties
- */
- public PropertySetter(BeanDescriptionCache beanDescriptionCache, Object obj) {
- this.obj = obj;
- this.objClass = obj.getClass();
- this.beanDescription = beanDescriptionCache.getBeanDescription(objClass);
- }
-
- /**
- * Set a property on this PropertySetter's Object. If successful, this method
- * will invoke a setter method on the underlying Object. The setter is the one
- * for the specified property name and the value is determined partly from the
- * setter argument type and partly from the value specified in the call to
- * this method.
- *
- * <p>
- * If the setter expects a String no conversion is necessary. If it expects an
- * int, then an attempt is made to convert 'value' to an int using new
- * Integer(value). If the setter expects a boolean, the conversion is by new
- * Boolean(value).
- *
- * @param name
- * name of the property
- * @param value
- * String value of the property
- */
- public void setProperty(String name, String value) {
- if (value == null) {
- return;
- }
- Method setter = findSetterMethod(name);
- if (setter == null) {
- addWarn("No setter for property [" + name + "] in " + objClass.getName() + ".");
- } else {
- try {
- setProperty(setter, name, value);
- } catch (PropertySetterException ex) {
- addWarn("Failed to set property [" + name + "] to value \"" + value + "\". ", ex);
- }
- }
- }
-
- /**
- * Set the named property given a {@link PropertyDescriptor}.
- *
- * @param prop
- * A PropertyDescriptor describing the characteristics of the
- * property to set.
- * @param name
- * The named of the property to set.
- * @param value
- * The value of the property.
- */
- private void setProperty(Method setter, String name, String value) throws PropertySetterException {
- Class<?>[] paramTypes = setter.getParameterTypes();
-
- Object arg;
-
- try {
- arg = StringToObjectConverter.convertArg(this, value, paramTypes[0]);
- } catch (Throwable t) {
- throw new PropertySetterException("Conversion to type [" + paramTypes[0] + "] failed. ", t);
- }
-
- if (arg == null) {
- throw new PropertySetterException("Conversion to type [" + paramTypes[0] + "] failed.");
- }
- try {
- setter.invoke(obj, arg);
- } catch (Exception ex) {
- throw new PropertySetterException(ex);
- }
- }
-
- public AggregationType computeAggregationType(String name) {
- String cName = capitalizeFirstLetter(name);
-
- Method addMethod = findAdderMethod(cName);
-
- if (addMethod != null) {
- AggregationType type = computeRawAggregationType(addMethod);
- switch (type) {
- case NOT_FOUND:
- return AggregationType.NOT_FOUND;
- case AS_BASIC_PROPERTY:
- return AggregationType.AS_BASIC_PROPERTY_COLLECTION;
-
- case AS_COMPLEX_PROPERTY:
- return AggregationType.AS_COMPLEX_PROPERTY_COLLECTION;
- case AS_BASIC_PROPERTY_COLLECTION:
- case AS_COMPLEX_PROPERTY_COLLECTION:
- addError("Unexpected AggregationType " + type);
- }
- }
-
- Method setter = findSetterMethod(name);
- if (setter != null) {
- return computeRawAggregationType(setter);
- } else {
- // we have failed
- return AggregationType.NOT_FOUND;
- }
- }
-
- private Method findAdderMethod(String name) {
- String propertyName = BeanUtil.toLowerCamelCase(name);
- return beanDescription.getAdder(propertyName);
- }
-
- private Method findSetterMethod(String name) {
- String propertyName = BeanUtil.toLowerCamelCase(name);
- return beanDescription.getSetter(propertyName);
- }
-
- private Class<?> getParameterClassForMethod(Method method) {
- if (method == null) {
- return null;
- }
- Class<?>[] classArray = method.getParameterTypes();
- if (classArray.length != 1) {
- return null;
- } else {
- return classArray[0];
- }
- }
-
- private AggregationType computeRawAggregationType(Method method) {
- Class<?> parameterClass = getParameterClassForMethod(method);
- if (parameterClass == null) {
- return AggregationType.NOT_FOUND;
- }
- if (StringToObjectConverter.canBeBuiltFromSimpleString(parameterClass)) {
- return AggregationType.AS_BASIC_PROPERTY;
- } else {
- return AggregationType.AS_COMPLEX_PROPERTY;
- }
- }
-
- /**
- * Can the given clazz instantiable with certainty?
- *
- * @param clazz
- * The class to test for instantiability
- * @return true if clazz can be instantiated, and false otherwise.
- */
- private boolean isUnequivocallyInstantiable(Class<?> clazz) {
- if (clazz.isInterface()) {
- return false;
- }
- // checking for constructors would be more elegant, but in
- // classes without any declared constructors, Class.getConstructor()
- // returns null.
- Object o;
- try {
- o = clazz.newInstance();
- if (o != null) {
- return true;
- } else {
- return false;
- }
- } catch (InstantiationException e) {
- return false;
- } catch (IllegalAccessException e) {
- return false;
- }
- }
-
- public Class<?> getObjClass() {
- return objClass;
- }
-
- public void addComplexProperty(String name, Object complexProperty) {
- Method adderMethod = findAdderMethod(name);
- // first let us use the addXXX method
- if (adderMethod != null) {
- Class<?>[] paramTypes = adderMethod.getParameterTypes();
- if (!isSanityCheckSuccessful(name, adderMethod, paramTypes, complexProperty)) {
- return;
- }
- invokeMethodWithSingleParameterOnThisObject(adderMethod, complexProperty);
- } else {
- addError("Could not find method [" + "add" + name + "] in class [" + objClass.getName() + "].");
- }
- }
-
- void invokeMethodWithSingleParameterOnThisObject(Method method, Object parameter) {
- Class<?> ccc = parameter.getClass();
- try {
- method.invoke(this.obj, parameter);
- } catch (Exception e) {
- addError("Could not invoke method " + method.getName() + " in class " + obj.getClass().getName() + " with parameter of type " + ccc.getName(), e);
- }
- }
-
- public void addBasicProperty(String name, String strValue) {
-
- if (strValue == null) {
- return;
- }
-
- name = capitalizeFirstLetter(name);
- Method adderMethod = findAdderMethod(name);
-
- if (adderMethod == null) {
- addError("No adder for property [" + name + "].");
- return;
- }
-
- Class<?>[] paramTypes = adderMethod.getParameterTypes();
- isSanityCheckSuccessful(name, adderMethod, paramTypes, strValue);
-
- Object arg;
- try {
- arg = StringToObjectConverter.convertArg(this, strValue, paramTypes[0]);
- } catch (Throwable t) {
- addError("Conversion to type [" + paramTypes[0] + "] failed. ", t);
- return;
- }
- if (arg != null) {
- invokeMethodWithSingleParameterOnThisObject(adderMethod, strValue);
- }
- }
-
- public void setComplexProperty(String name, Object complexProperty) {
- Method setter = findSetterMethod(name);
-
- if (setter == null) {
- addWarn("Not setter method for property [" + name + "] in " + obj.getClass().getName());
-
- return;
- }
-
- Class<?>[] paramTypes = setter.getParameterTypes();
-
- if (!isSanityCheckSuccessful(name, setter, paramTypes, complexProperty)) {
- return;
- }
- try {
- invokeMethodWithSingleParameterOnThisObject(setter, complexProperty);
-
- } catch (Exception e) {
- addError("Could not set component " + obj + " for parent component " + obj, e);
- }
- }
-
- private boolean isSanityCheckSuccessful(String name, Method method, Class<?>[] params, Object complexProperty) {
- Class<?> ccc = complexProperty.getClass();
- if (params.length != 1) {
- addError("Wrong number of parameters in setter method for property [" + name + "] in " + obj.getClass().getName());
-
- return false;
- }
-
- if (!params[0].isAssignableFrom(complexProperty.getClass())) {
- addError("A \"" + ccc.getName() + "\" object is not assignable to a \"" + params[0].getName() + "\" variable.");
- addError("The class \"" + params[0].getName() + "\" was loaded by ");
- addError("[" + params[0].getClassLoader() + "] whereas object of type ");
- addError("\"" + ccc.getName() + "\" was loaded by [" + ccc.getClassLoader() + "].");
- return false;
- }
+ protected Object obj;
+ protected Class<?> objClass;
+ protected PropertyDescriptor[] propertyDescriptors;
+ protected MethodDescriptor[] methodDescriptors;
+
+ /**
+ * Create a new PropertySetter for the specified Object. This is done in
+ * preparation for invoking {@link #setProperty} one or more times.
+ *
+ * @param obj
+ * the object for which to set properties
+ */
+ public PropertySetter(Object obj) {
+ this.obj = obj;
+ this.objClass = obj.getClass();
+ }
+
+ /**
+ * Uses JavaBeans {@link Introspector} to computer setters of object to be
+ * configured.
+ */
+ protected void introspect() {
+ try {
+ BeanInfo bi = Introspector.getBeanInfo(obj.getClass());
+ propertyDescriptors = bi.getPropertyDescriptors();
+ methodDescriptors = bi.getMethodDescriptors();
+ } catch (IntrospectionException ex) {
+ addError("Failed to introspect " + obj + ": " + ex.getMessage());
+ propertyDescriptors = new PropertyDescriptor[0];
+ methodDescriptors = new MethodDescriptor[0];
+ }
+ }
+
+ /**
+ * Set a property on this PropertySetter's Object. If successful, this method
+ * will invoke a setter method on the underlying Object. The setter is the one
+ * for the specified property name and the value is determined partly from the
+ * setter argument type and partly from the value specified in the call to
+ * this method.
+ *
+ * <p>
+ * If the setter expects a String no conversion is necessary. If it expects an
+ * int, then an attempt is made to convert 'value' to an int using new
+ * Integer(value). If the setter expects a boolean, the conversion is by new
+ * Boolean(value).
+ *
+ * @param name
+ * name of the property
+ * @param value
+ * String value of the property
+ */
+ public void setProperty(String name, String value) {
+ if (value == null) {
+ return;
+ }
+
+ name = Introspector.decapitalize(name);
+
+ PropertyDescriptor prop = getPropertyDescriptor(name);
+
+ if (prop == null) {
+ addWarn("No such property [" + name + "] in " + objClass.getName() + ".");
+ } else {
+ try {
+ setProperty(prop, name, value);
+ } catch (PropertySetterException ex) {
+ addWarn("Failed to set property [" + name + "] to value \"" + value
+ + "\". ", ex);
+ }
+ }
+ }
+
+ /**
+ * Set the named property given a {@link PropertyDescriptor}.
+ *
+ * @param prop
+ * A PropertyDescriptor describing the characteristics of the
+ * property to set.
+ * @param name
+ * The named of the property to set.
+ * @param value
+ * The value of the property.
+ */
+ public void setProperty(PropertyDescriptor prop, String name, String value)
+ throws PropertySetterException {
+ Method setter = prop.getWriteMethod();
+
+ if (setter == null) {
+ throw new PropertySetterException("No setter for property [" + name
+ + "].");
+ }
+
+ Class<?>[] paramTypes = setter.getParameterTypes();
+
+ if (paramTypes.length != 1) {
+ throw new PropertySetterException("#params for setter != 1");
+ }
+ Object arg;
+
+ try {
+ arg = StringToObjectConverter.convertArg(this, value, paramTypes[0]);
+ } catch (Throwable t) {
+ throw new PropertySetterException("Conversion to type [" + paramTypes[0]
+ + "] failed. ", t);
+ }
+
+ if (arg == null) {
+ throw new PropertySetterException("Conversion to type [" + paramTypes[0]
+ + "] failed.");
+ }
+ try {
+ setter.invoke(obj, arg);
+ } catch (Exception ex) {
+ throw new PropertySetterException(ex);
+ }
+ }
+
+ public AggregationType computeAggregationType(String name) {
+ String cName = capitalizeFirstLetter(name);
+
+ Method addMethod = findAdderMethod(cName);
+
+ // if the
+ if (addMethod != null) {
+ AggregationType type = computeRawAggregationType(addMethod);
+ switch (type) {
+ case NOT_FOUND:
+ return AggregationType.NOT_FOUND;
+ case AS_BASIC_PROPERTY:
+ return AggregationType.AS_BASIC_PROPERTY_COLLECTION;
+ case AS_COMPLEX_PROPERTY:
+ return AggregationType.AS_COMPLEX_PROPERTY_COLLECTION;
+ }
+ }
+
+ Method setterMethod = findSetterMethod(name);
+ if (setterMethod != null) {
+ return computeRawAggregationType(setterMethod);
+ } else {
+ // we have failed
+ return AggregationType.NOT_FOUND;
+ }
+ }
+
+ private Method findAdderMethod(String name) {
+ name = capitalizeFirstLetter(name);
+ return getMethod("add" + name);
+ }
+
+ private Method findSetterMethod(String name) {
+ String dName = Introspector.decapitalize(name);
+ PropertyDescriptor propertyDescriptor = getPropertyDescriptor(dName);
+ if (propertyDescriptor != null) {
+ return propertyDescriptor.getWriteMethod();
+ } else {
+ return null;
+ }
+ }
+
+ private Class<?> getParameterClassForMethod(Method method) {
+ if (method == null) {
+ return null;
+ }
+ Class<?>[] classArray = method.getParameterTypes();
+ if (classArray.length != 1) {
+ return null;
+ } else {
+ return classArray[0];
+ }
+ }
+
+ private AggregationType computeRawAggregationType(Method method) {
+ Class<?> parameterClass = getParameterClassForMethod(method);
+ if (parameterClass == null) {
+ return AggregationType.NOT_FOUND;
+ }
+ if (StringToObjectConverter.canBeBuiltFromSimpleString(parameterClass)) {
+ return AggregationType.AS_BASIC_PROPERTY;
+ } else {
+ return AggregationType.AS_COMPLEX_PROPERTY;
+ }
+ }
+
+ /**
+ * Can the given clazz instantiable with certainty?
+ *
+ * @param clazz
+ * The class to test for instantiability
+ * @return true if clazz can be instantiated, and false otherwise.
+ */
+ private boolean isUnequivocallyInstantiable(Class<?> clazz) {
+ if (clazz.isInterface()) {
+ return false;
+ }
+ // checking for constructors would be more elegant, but in
+ // classes without any declared constructors, Class.getConstructor()
+ // returns null.
+ Object o;
+ try {
+ o = clazz.newInstance();
+ if (o != null) {
return true;
+ } else {
+ return false;
+ }
+ } catch (InstantiationException e) {
+ return false;
+ } catch (IllegalAccessException e) {
+ return false;
+ }
+ }
+
+ public Class<?> getObjClass() {
+ return objClass;
+ }
+
+ public void addComplexProperty(String name, Object complexProperty) {
+ Method adderMethod = findAdderMethod(name);
+ // first let us use the addXXX method
+ if (adderMethod != null) {
+ Class<?>[] paramTypes = adderMethod.getParameterTypes();
+ if (!isSanityCheckSuccessful(name, adderMethod, paramTypes,
+ complexProperty)) {
+ return;
+ }
+ invokeMethodWithSingleParameterOnThisObject(adderMethod, complexProperty);
+ } else {
+ addError("Could not find method [" + "add" + name + "] in class ["
+ + objClass.getName() + "].");
+ }
+ }
+
+ void invokeMethodWithSingleParameterOnThisObject(Method method,
+ Object parameter) {
+ Class<?> ccc = parameter.getClass();
+ try {
+ method.invoke(this.obj, parameter);
+ } catch (Exception e) {
+ addError("Could not invoke method " + method.getName() + " in class "
+ + obj.getClass().getName() + " with parameter of type "
+ + ccc.getName(), e);
+ }
+ }
+
+ public void addBasicProperty(String name, String strValue) {
+
+ if (strValue == null) {
+ return;
}
- private String capitalizeFirstLetter(String name) {
- return name.substring(0, 1).toUpperCase() + name.substring(1);
+ name = capitalizeFirstLetter(name);
+ Method adderMethod = findAdderMethod(name);
+
+ if (adderMethod == null) {
+ addError("No adder for property [" + name + "].");
+ return;
+ }
+
+ Class<?>[] paramTypes = adderMethod.getParameterTypes();
+ isSanityCheckSuccessful(name, adderMethod, paramTypes, strValue);
+
+ Object arg;
+ try {
+ arg = StringToObjectConverter.convertArg(this, strValue, paramTypes[0]);
+ } catch (Throwable t) {
+ addError("Conversion to type [" + paramTypes[0] + "] failed. ", t);
+ return;
+ }
+ if (arg != null) {
+ invokeMethodWithSingleParameterOnThisObject(adderMethod, strValue);
+ }
+ }
+
+ public void setComplexProperty(String name, Object complexProperty) {
+ String dName = Introspector.decapitalize(name);
+ PropertyDescriptor propertyDescriptor = getPropertyDescriptor(dName);
+
+ if (propertyDescriptor == null) {
+ addWarn("Could not find PropertyDescriptor for [" + name + "] in "
+ + objClass.getName());
+
+ return;
}
- public Object getObj() {
- return obj;
+ Method setter = propertyDescriptor.getWriteMethod();
+
+ if (setter == null) {
+ addWarn("Not setter method for property [" + name + "] in "
+ + obj.getClass().getName());
+
+ return;
+ }
+
+ Class<?>[] paramTypes = setter.getParameterTypes();
+
+ if (!isSanityCheckSuccessful(name, setter, paramTypes, complexProperty)) {
+ return;
}
+ try {
+ invokeMethodWithSingleParameterOnThisObject(setter, complexProperty);
- Method getRelevantMethod(String name, AggregationType aggregationType) {
- Method relevantMethod;
- if (aggregationType == AggregationType.AS_COMPLEX_PROPERTY_COLLECTION) {
- relevantMethod = findAdderMethod(name);
- } else if (aggregationType == AggregationType.AS_COMPLEX_PROPERTY) {
- relevantMethod = findSetterMethod(name);
- } else {
- throw new IllegalStateException(aggregationType + " not allowed here");
- }
- return relevantMethod;
+ } catch (Exception e) {
+ addError("Could not set component " + obj + " for parent component "
+ + obj, e);
}
+ }
- <T extends Annotation> T getAnnotation(String name, Class<T> annonationClass, Method relevantMethod) {
+ private boolean isSanityCheckSuccessful(String name, Method method,
+ Class<?>[] params, Object complexProperty) {
+ Class<?> ccc = complexProperty.getClass();
+ if (params.length != 1) {
+ addError("Wrong number of parameters in setter method for property ["
+ + name + "] in " + obj.getClass().getName());
- if (relevantMethod != null) {
- return relevantMethod.getAnnotation(annonationClass);
- } else {
- return null;
- }
+ return false;
}
- Class<?> getDefaultClassNameByAnnonation(String name, Method relevantMethod) {
- DefaultClass defaultClassAnnon = getAnnotation(name, DefaultClass.class, relevantMethod);
- if (defaultClassAnnon != null) {
- return defaultClassAnnon.value();
- }
- return null;
+ if (!params[0].isAssignableFrom(complexProperty.getClass())) {
+ addError("A \"" + ccc.getName() + "\" object is not assignable to a \""
+ + params[0].getName() + "\" variable.");
+ addError("The class \"" + params[0].getName() + "\" was loaded by ");
+ addError("[" + params[0].getClassLoader() + "] whereas object of type ");
+ addError("\"" + ccc.getName() + "\" was loaded by ["
+ + ccc.getClassLoader() + "].");
+ return false;
}
- Class<?> getByConcreteType(String name, Method relevantMethod) {
+ return true;
+ }
- Class<?> paramType = getParameterClassForMethod(relevantMethod);
- if (paramType == null) {
- return null;
- }
+ private String capitalizeFirstLetter(String name) {
+ return name.substring(0, 1).toUpperCase() + name.substring(1);
+ }
- boolean isUnequivocallyInstantiable = isUnequivocallyInstantiable(paramType);
- if (isUnequivocallyInstantiable) {
- return paramType;
- } else {
- return null;
- }
+ protected Method getMethod(String methodName) {
+ if (methodDescriptors == null) {
+ introspect();
+ }
+ for (int i = 0; i < methodDescriptors.length; i++) {
+ if (methodName.equals(methodDescriptors[i].getName())) {
+ return methodDescriptors[i].getMethod();
+ }
}
- public Class<?> getClassNameViaImplicitRules(String name, AggregationType aggregationType, DefaultNestedComponentRegistry registry) {
+ return null;
+ }
+
+ protected PropertyDescriptor getPropertyDescriptor(String name) {
+ if (propertyDescriptors == null) {
+ introspect();
+ }
- Class<?> registryResult = registry.findDefaultComponentType(obj.getClass(), name);
- if (registryResult != null) {
- return registryResult;
- }
- // find the relevant method for the given property name and aggregationType
- Method relevantMethod = getRelevantMethod(name, aggregationType);
- if (relevantMethod == null) {
- return null;
- }
- Class<?> byAnnotation = getDefaultClassNameByAnnonation(name, relevantMethod);
- if (byAnnotation != null) {
- return byAnnotation;
- }
- return getByConcreteType(name, relevantMethod);
+ for (int i = 0; i < propertyDescriptors.length; i++) {
+ // System.out.println("Comparing " + name + " against "
+ // + propertyDescriptors[i].getName());
+ if (name.equals(propertyDescriptors[i].getName())) {
+ // System.out.println("matched");
+ return propertyDescriptors[i];
+ }
+ }
+
+ return null;
+ }
+
+ public Object getObj() {
+ return obj;
+ }
+
+ Method getRelevantMethod(String name, AggregationType aggregationType) {
+ String cName = capitalizeFirstLetter(name);
+ Method relevantMethod;
+ if (aggregationType == AggregationType.AS_COMPLEX_PROPERTY_COLLECTION) {
+ relevantMethod = findAdderMethod(cName);
+ } else if (aggregationType == AggregationType.AS_COMPLEX_PROPERTY) {
+ relevantMethod = findSetterMethod(cName);
+ } else {
+ throw new IllegalStateException(aggregationType + " not allowed here");
+ }
+ return relevantMethod;
+ }
+
+ <T extends Annotation> T getAnnotation(String name, Class<T> annonationClass,
+ Method relevantMethod) {
+
+ if (relevantMethod != null) {
+ return relevantMethod.getAnnotation(annonationClass);
+ } else {
+ return null;
+ }
+ }
+
+ Class<?> getDefaultClassNameByAnnonation(String name, Method relevantMethod) {
+ DefaultClass defaultClassAnnon = getAnnotation(name, DefaultClass.class,
+ relevantMethod);
+ if (defaultClassAnnon != null) {
+ return defaultClassAnnon.value();
+ }
+ return null;
+ }
+
+ Class<?> getByConcreteType(String name, Method relevantMethod) {
+
+ Class<?> paramType = getParameterClassForMethod(relevantMethod);
+ if (paramType == null) {
+ return null;
+ }
+
+ boolean isUnequivocallyInstantiable = isUnequivocallyInstantiable(paramType);
+ if (isUnequivocallyInstantiable) {
+ return paramType;
+ } else {
+ return null;
+ }
+
+ }
+
+ public Class<?> getClassNameViaImplicitRules(String name,
+ AggregationType aggregationType, DefaultNestedComponentRegistry registry) {
+
+ Class<?> registryResult = registry.findDefaultComponentType(obj.getClass(),
+ name);
+ if (registryResult != null) {
+ return registryResult;
+ }
+ // find the relevant method for the given property name and aggregationType
+ Method relevantMethod = getRelevantMethod(name, aggregationType);
+ if (relevantMethod == null) {
+ return null;
+ }
+ Class<?> byAnnotation = getDefaultClassNameByAnnonation(name, relevantMethod);
+ if (byAnnotation != null) {
+ return byAnnotation;
}
+ return getByConcreteType(name, relevantMethod);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/util/StringToObjectConverter.java b/logback-core/src/main/java/ch/qos/logback/core/joran/util/StringToObjectConverter.java
index 9cc63bf..082780a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/util/StringToObjectConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/util/StringToObjectConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,109 +28,110 @@ import ch.qos.logback.core.spi.ContextAware;
*/
public class StringToObjectConverter {
- private static final Class<?>[] STING_CLASS_PARAMETER = new Class[] { String.class };
+ private static final Class<?>[] STING_CLASS_PARAMETER = new Class[] { String.class };
- static public boolean canBeBuiltFromSimpleString(Class<?> parameterClass) {
- Package p = parameterClass.getPackage();
- if (parameterClass.isPrimitive()) {
- return true;
- } else if (p != null && "java.lang".equals(p.getName())) {
- return true;
- } else if (followsTheValueOfConvention(parameterClass)) {
- return true;
- } else if (parameterClass.isEnum()) {
- return true;
- } else if (isOfTypeCharset(parameterClass)) {
- return true;
- }
- return false;
+ static public boolean canBeBuiltFromSimpleString(Class<?> parameterClass) {
+ Package p = parameterClass.getPackage();
+ if (parameterClass.isPrimitive()) {
+ return true;
+ } else if (p != null && "java.lang".equals(p.getName())) {
+ return true;
+ } else if (followsTheValueOfConvention(parameterClass)) {
+ return true;
+ } else if (parameterClass.isEnum()) {
+ return true;
+ } else if (isOfTypeCharset(parameterClass)) {
+ return true;
}
+ return false;
+ }
- /**
- * Convert <code>val</code> a String parameter to an object of a given type.
- */
- @SuppressWarnings("unchecked")
- public static Object convertArg(ContextAware ca, String val, Class<?> type) {
- if (val == null) {
- return null;
- }
- String v = val.trim();
- if (String.class.isAssignableFrom(type)) {
- return v;
- } else if (Integer.TYPE.isAssignableFrom(type)) {
- return new Integer(v);
- } else if (Long.TYPE.isAssignableFrom(type)) {
- return new Long(v);
- } else if (Float.TYPE.isAssignableFrom(type)) {
- return new Float(v);
- } else if (Double.TYPE.isAssignableFrom(type)) {
- return new Double(v);
- } else if (Boolean.TYPE.isAssignableFrom(type)) {
- if ("true".equalsIgnoreCase(v)) {
- return Boolean.TRUE;
- } else if ("false".equalsIgnoreCase(v)) {
- return Boolean.FALSE;
- }
- } else if (type.isEnum()) {
- return convertToEnum(ca, v, (Class<? extends Enum<?>>) type);
- } else if (StringToObjectConverter.followsTheValueOfConvention(type)) {
- return convertByValueOfMethod(ca, type, v);
- } else if (isOfTypeCharset(type)) {
- return convertToCharset(ca, val);
- }
-
- return null;
+ /**
+ * Convert <code>val</code> a String parameter to an object of a given type.
+ */
+ @SuppressWarnings("unchecked")
+ public static Object convertArg(ContextAware ca, String val, Class<?> type) {
+ if (val == null) {
+ return null;
}
-
- static private boolean isOfTypeCharset(Class<?> type) {
- return Charset.class.isAssignableFrom(type);
+ String v = val.trim();
+ if (String.class.isAssignableFrom(type)) {
+ return v;
+ } else if (Integer.TYPE.isAssignableFrom(type)) {
+ return new Integer(v);
+ } else if (Long.TYPE.isAssignableFrom(type)) {
+ return new Long(v);
+ } else if (Float.TYPE.isAssignableFrom(type)) {
+ return new Float(v);
+ } else if (Double.TYPE.isAssignableFrom(type)) {
+ return new Double(v);
+ } else if (Boolean.TYPE.isAssignableFrom(type)) {
+ if ("true".equalsIgnoreCase(v)) {
+ return Boolean.TRUE;
+ } else if ("false".equalsIgnoreCase(v)) {
+ return Boolean.FALSE;
+ }
+ } else if (type.isEnum()) {
+ return convertToEnum(ca, v, (Class<? extends Enum>) type);
+ } else if (StringToObjectConverter.followsTheValueOfConvention(type)) {
+ return convertByValueOfMethod(ca, type, v);
+ } else if (isOfTypeCharset(type)) {
+ return convertToCharset(ca, val);
}
- static private Charset convertToCharset(ContextAware ca, String val) {
- try {
- return Charset.forName(val);
- } catch (UnsupportedCharsetException e) {
- ca.addError("Failed to get charset [" + val + "]", e);
- return null;
- }
- }
+ return null;
+ }
- // returned value may be null and in most cases it is null.
- public static Method getValueOfMethod(Class<?> type) {
- try {
- return type.getMethod(CoreConstants.VALUE_OF, STING_CLASS_PARAMETER);
- } catch (NoSuchMethodException e) {
- return null;
- } catch (SecurityException e) {
- return null;
- }
- }
+ static private boolean isOfTypeCharset(Class<?> type) {
+ return Charset.class.isAssignableFrom(type);
+ }
- static private boolean followsTheValueOfConvention(Class<?> parameterClass) {
- Method valueOfMethod = getValueOfMethod(parameterClass);
- if (valueOfMethod == null)
- return false;
-
- int mod = valueOfMethod.getModifiers();
- return Modifier.isStatic(mod);
+ static private Charset convertToCharset(ContextAware ca, String val) {
+ try {
+ return Charset.forName(val);
+ } catch (UnsupportedCharsetException e) {
+ ca.addError("Failed to get charset [" + val + "]", e);
+ return null;
}
+ }
- private static Object convertByValueOfMethod(ContextAware ca, Class<?> type, String val) {
- try {
- Method valueOfMethod = type.getMethod(CoreConstants.VALUE_OF, STING_CLASS_PARAMETER);
- return valueOfMethod.invoke(null, val);
- } catch (Exception e) {
- ca.addError("Failed to invoke " + CoreConstants.VALUE_OF + "{} method in class [" + type.getName() + "] with value [" + val + "]");
- return null;
- }
+ static private boolean followsTheValueOfConvention(Class<?> parameterClass) {
+ try {
+ Method valueOfMethod = parameterClass.getMethod(CoreConstants.VALUE_OF,
+ STING_CLASS_PARAMETER);
+ int mod = valueOfMethod.getModifiers();
+ if (Modifier.isStatic(mod)) {
+ return true;
+ }
+ } catch (SecurityException e) {
+ // nop
+ } catch (NoSuchMethodException e) {
+ // nop
}
+ return false;
+ }
- @SuppressWarnings({ "unchecked", "rawtypes" })
- private static Object convertToEnum(ContextAware ca, String val, Class<? extends Enum> enumType) {
- return Enum.valueOf(enumType, val);
+ private static Object convertByValueOfMethod(ContextAware ca, Class<?> type,
+ String val) {
+ try {
+ Method valueOfMethod = type.getMethod(CoreConstants.VALUE_OF,
+ STING_CLASS_PARAMETER);
+ return valueOfMethod.invoke(null, val);
+ } catch (Exception e) {
+ ca.addError("Failed to invoke " + CoreConstants.VALUE_OF
+ + "{} method in class [" + type.getName() + "] with value [" + val
+ + "]");
+ return null;
}
+ }
- boolean isBuildableFromSimpleString() {
- return false;
- }
+ @SuppressWarnings("unchecked")
+ private static Object convertToEnum(ContextAware ca, String val,
+ Class<? extends Enum> enumType) {
+ return Enum.valueOf(enumType, val);
+ }
+
+ boolean isBuildableFromSimpleString() {
+ return false;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/util/beans/BeanDescription.java b/logback-core/src/main/java/ch/qos/logback/core/joran/util/beans/BeanDescription.java
deleted file mode 100644
index 57965b2..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/util/beans/BeanDescription.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package ch.qos.logback.core.joran.util.beans;
-
-import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * Lightweight pendant to the java.beans.BeanInfo class. An instance of this
- * class encapsulates the properties of a certain class. The properties are the
- * public setters and getters. In addition the 'add-er'-methods are included,
- * which are the public methods which start with the prefix 'add'.
- *
- * @author urechm
- *
- */
-public class BeanDescription {
-
- private final Class<?> clazz;
-
- private final Map<String, Method> propertyNameToGetter;
-
- private final Map<String, Method> propertyNameToSetter;
-
- private final Map<String, Method> propertyNameToAdder;
-
- /**
- * Scope protected since only the {@link BeanDescriptionFactory} must create
- * BeanDescriptions in order to guarantee consistency between the given
- * parameters.
- *
- * @param clazz of the bean.
- * @param propertyNameToGetter map of property names to the associated getter.
- * @param propertyNameToSetter map of property names to the associated setter.
- * @param propertyNameToAdder map of property names to the associated adder.
- */
- protected BeanDescription(Class<?> clazz,Map<String, Method> propertyNameToGetter,Map<String, Method> propertyNameToSetter,Map<String, Method> propertyNameToAdder) {
- this.clazz = clazz;
- this.propertyNameToGetter = Collections.unmodifiableMap(propertyNameToGetter);
- this.propertyNameToSetter = Collections.unmodifiableMap(propertyNameToSetter);
- this.propertyNameToAdder = Collections.unmodifiableMap(propertyNameToAdder);
- }
-
- public Class<?> getClazz() {
- return clazz;
- }
-
- public Map<String, Method> getPropertyNameToGetter() {
- return propertyNameToGetter;
- }
-
- public Map<String, Method> getPropertyNameToSetter() {
- return propertyNameToSetter;
- }
-
- public Method getGetter(String propertyName) {
- return propertyNameToGetter.get(propertyName);
- }
-
- public Method getSetter(String propertyName) {
- return propertyNameToSetter.get(propertyName);
- }
-
- public Map<String, Method> getPropertyNameToAdder() {
- return propertyNameToAdder;
- }
-
- public Method getAdder(String propertyName) {
- return propertyNameToAdder.get(propertyName);
- }
-
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/util/beans/BeanDescriptionCache.java b/logback-core/src/main/java/ch/qos/logback/core/joran/util/beans/BeanDescriptionCache.java
deleted file mode 100644
index 1b8350e..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/util/beans/BeanDescriptionCache.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package ch.qos.logback.core.joran.util.beans;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import ch.qos.logback.core.Context;
-import ch.qos.logback.core.spi.ContextAwareBase;
-
-/**
- *
- * Cache for {@link BeanDescription} instances. All the cache users which use
- * the same instance of BeanDescriptionCache can profit from each others cached
- * bean descriptions.
- *
- * <p>The cache is not thread-safe and should not be shared across configurator instances.
- *
- * @author urechm
- *
- */
-public class BeanDescriptionCache extends ContextAwareBase {
-
- private Map<Class<?>, BeanDescription> classToBeanDescription = new HashMap<Class<?>, BeanDescription>();
- private BeanDescriptionFactory beanDescriptionFactory;
-
- public BeanDescriptionCache(Context context) {
- setContext(context);
- }
-
- private BeanDescriptionFactory getBeanDescriptionFactory() {
- if (beanDescriptionFactory == null) {
- beanDescriptionFactory = new BeanDescriptionFactory(getContext());
- }
- return beanDescriptionFactory;
- }
-
- /**
- * Returned bean descriptions are hold in a cache. If the cache does not
- * contain a description for a given class, a new bean description is
- * created and put in the cache, before it is returned.
- *
- * @param clazz
- * to get a bean description for.
- * @return a bean description for the given class.
- */
- public BeanDescription getBeanDescription(Class<?> clazz) {
- if (!classToBeanDescription.containsKey(clazz)) {
- BeanDescription beanDescription = getBeanDescriptionFactory().create(clazz);
- classToBeanDescription.put(clazz, beanDescription);
- }
- return classToBeanDescription.get(clazz);
- }
-
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/util/beans/BeanDescriptionFactory.java b/logback-core/src/main/java/ch/qos/logback/core/joran/util/beans/BeanDescriptionFactory.java
deleted file mode 100644
index 96bb205..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/util/beans/BeanDescriptionFactory.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package ch.qos.logback.core.joran.util.beans;
-
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-
-import ch.qos.logback.core.Context;
-import ch.qos.logback.core.spi.ContextAwareBase;
-
-/**
- * Encapsulates creation of {@link BeanDescription} instances.
- * This factory is kind of a lightweight Introspector as described in the Java Beans API specification.
- * The given class is only analyzed for its public getters, setters and adders methods.
- * Implementations of the BeanInfo interface are not taken into account for analysis.
- * Therefore this class is only partially compatible with the Java Beans API specification.
- *
- *
- * @author urechm
- */
-public class BeanDescriptionFactory extends ContextAwareBase {
-
- BeanDescriptionFactory(Context context) {
- setContext(context);
- }
-
- /**
- *
- * @param clazz to create a {@link BeanDescription} for.
- * @return a {@link BeanDescription} for the given class.
- */
- public BeanDescription create(Class<?> clazz) {
- Map<String, Method> propertyNameToGetter = new HashMap<String, Method>();
- Map<String, Method> propertyNameToSetter = new HashMap<String, Method>();
- Map<String, Method> propertyNameToAdder = new HashMap<String, Method>();
- Method[] methods = clazz.getMethods();
- for (Method method : methods) {
- if(method.isBridge()) {
- // we can safely ignore bridge methods
- continue;
- }
- if (BeanUtil.isGetter(method)) {
- String propertyName = BeanUtil.getPropertyName(method);
- Method oldGetter = propertyNameToGetter.put(propertyName, method);
- if (oldGetter != null) {
- if (oldGetter.getName().startsWith(BeanUtil.PREFIX_GETTER_IS)) {
- propertyNameToGetter.put(propertyName, oldGetter);
- }
- String message = String.format("Class '%s' contains multiple getters for the same property '%s'.", clazz.getCanonicalName(), propertyName);
- addWarn(message);
- }
- } else if (BeanUtil.isSetter(method)) {
- String propertyName = BeanUtil.getPropertyName(method);
- Method oldSetter = propertyNameToSetter.put(propertyName, method);
- if (oldSetter != null) {
- String message = String.format("Class '%s' contains multiple setters for the same property '%s'.", clazz.getCanonicalName(), propertyName);
- addWarn(message);
- }
- } else if (BeanUtil.isAdder(method)) {
- String propertyName = BeanUtil.getPropertyName(method);
- Method oldAdder = propertyNameToAdder.put(propertyName, method);
- if (oldAdder != null) {
- String message = String.format("Class '%s' contains multiple adders for the same property '%s'.", clazz.getCanonicalName(), propertyName);
- addWarn(message);
- }
- }
- }
- return new BeanDescription(clazz, propertyNameToGetter, propertyNameToSetter, propertyNameToAdder);
- }
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/util/beans/BeanUtil.java b/logback-core/src/main/java/ch/qos/logback/core/joran/util/beans/BeanUtil.java
deleted file mode 100644
index aa17515..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/util/beans/BeanUtil.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package ch.qos.logback.core.joran.util.beans;
-
-import java.lang.reflect.Method;
-
-/**
- * Encapsulates utility methods associated with standard java beans.
- * @author urechm
- */
-public class BeanUtil {
-
- //public static final BeanUtil SINGLETON = new BeanUtil();
-
- public static final String PREFIX_GETTER_IS = "is";
- public static final String PREFIX_GETTER_GET = "get";
- public static final String PREFIX_SETTER = "set";
- public static final String PREFIX_ADDER = "add";
-
- /**
- *
- * @param method to check if it is an 'adder' method.
- * @return true if the given method is an 'adder' method.
- */
- static public boolean isAdder(Method method) {
- int parameterCount = getParameterCount(method);
- if (parameterCount != 1) {
- return false;
- }
- Class<?> returnType = method.getReturnType();
- if (returnType != void.class) {
- return false;
- }
- String methodName = method.getName();
- return methodName.startsWith(PREFIX_ADDER);
- }
-
- /**
- *
- * @param method to check if it is a standard java beans getter.
- * @return true if the given method is a standard java beans getter.
- */
- static public boolean isGetter(Method method) {
- int parameterCount = getParameterCount(method);
- if (parameterCount > 0) {
- return false;
- }
- Class<?> returnType = method.getReturnType();
- if (returnType == void.class) {
- return false;
- }
- String methodName = method.getName();
- if (!methodName.startsWith(PREFIX_GETTER_GET) && !methodName.startsWith(PREFIX_GETTER_IS)) {
- return false;
- }
- if (methodName.startsWith(PREFIX_GETTER_IS)) {
- if (!returnType.equals(boolean.class) && !returnType.equals(Boolean.class)) {
- return false;
- }
- }
- return true;
- }
-
- static private int getParameterCount(Method method) {
- return method.getParameterTypes().length;
- }
-
- /**
- *
- * @param method to check if it is a standard java beans setter.
- * @return true if the given method is a standard java beans setter.
- */
- static public boolean isSetter(Method method) {
- int parameterCount = getParameterCount(method);
- if (parameterCount != 1) {
- return false;
- }
- Class<?> returnType = method.getReturnType();
- if (returnType != void.class) {
- return false;
- }
- String methodName = method.getName();
- if (!methodName.startsWith(PREFIX_SETTER)) {
- return false;
- }
- return true;
- }
-
- /**
- * @param method to get the associated property name for.
- * @return The property name of the associated property if the given method matches a standard java beans getter or setter.
- */
- static public String getPropertyName(Method method) {
- String methodName = method.getName();
- String rawPropertyName = getSubstringIfPrefixMatches(methodName, PREFIX_GETTER_GET);
- if (rawPropertyName == null) {
- rawPropertyName = getSubstringIfPrefixMatches(methodName, PREFIX_SETTER);
- }
- if (rawPropertyName == null) {
- rawPropertyName = getSubstringIfPrefixMatches(methodName, PREFIX_GETTER_IS);
- }
- if (rawPropertyName == null) {
- rawPropertyName = getSubstringIfPrefixMatches(methodName, PREFIX_ADDER);
- }
- return toLowerCamelCase(rawPropertyName);
- }
-
- /**
- * Converts the given String into lower camel case form.
- * @param string to decapitalize.
- * @return null if the given String is null.
- * Emtpy string if the given string is empty.
- * The given string if the first two consecutive letters are in upper case.
- * The given string with the first letter in lower case otherwise, which might be the given string.
- */
- static public String toLowerCamelCase(String string) {
- if (string == null) {
- return null;
- }
- if (string.isEmpty()) {
- return string;
- }
- if (string.length() > 1 && Character.isUpperCase(string.charAt(1)) && Character.isUpperCase(string.charAt(0))) {
- return string;
- }
- char chars[] = string.toCharArray();
- chars[0] = Character.toLowerCase(chars[0]);
- return new String(chars);
- }
-
- static private String getSubstringIfPrefixMatches(String wholeString, String prefix) {
- if (wholeString.startsWith(prefix)) {
- return wholeString.substring(prefix.length());
- }
- return null;
- }
-
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/layout/EchoLayout.java b/logback-core/src/main/java/ch/qos/logback/core/layout/EchoLayout.java
index 07e159c..8e9a5c0 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/layout/EchoLayout.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/layout/EchoLayout.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,8 +23,8 @@ import ch.qos.logback.core.LayoutBase;
*/
public class EchoLayout<E> extends LayoutBase<E> {
- public String doLayout(E event) {
- return event + CoreConstants.LINE_SEPARATOR;
- }
+ public String doLayout(E event) {
+ return event+CoreConstants.LINE_SEPARATOR;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/AbstractSSLSocketAppender.java b/logback-core/src/main/java/ch/qos/logback/core/net/AbstractSSLSocketAppender.java
index 9a7a6e6..e652c10 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/AbstractSSLSocketAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/AbstractSSLSocketAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,61 +27,64 @@ import ch.qos.logback.core.net.ssl.SSLParametersConfiguration;
*
* @author Carl Harris
*/
-public abstract class AbstractSSLSocketAppender<E> extends AbstractSocketAppender<E> implements SSLComponent {
+public abstract class AbstractSSLSocketAppender<E> extends AbstractSocketAppender<E>
+ implements SSLComponent {
- private SSLConfiguration ssl;
- private SocketFactory socketFactory;
+ private SSLConfiguration ssl;
+ private SocketFactory socketFactory;
- /**
- * Constructs a new appender.
- */
- protected AbstractSSLSocketAppender() {
- }
+ /**
+ * Constructs a new appender.
+ */
+ protected AbstractSSLSocketAppender() {
+ }
- /**
- * Gets an {@link SocketFactory} that produces SSL sockets using an
- * {@link SSLContext} that is derived from the appender's configuration.
- * @return socket factory
- */
- @Override
- protected SocketFactory getSocketFactory() {
- return socketFactory;
- }
+ /**
+ * Gets an {@link SocketFactory} that produces SSL sockets using an
+ * {@link SSLContext} that is derived from the appender's configuration.
+ * @return socket factory
+ */
+ @Override
+ protected SocketFactory getSocketFactory() {
+ return socketFactory;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public void start() {
- try {
- SSLContext sslContext = getSsl().createContext(this);
- SSLParametersConfiguration parameters = getSsl().getParameters();
- parameters.setContext(getContext());
- socketFactory = new ConfigurableSSLSocketFactory(parameters, sslContext.getSocketFactory());
- super.start();
- } catch (Exception ex) {
- addError(ex.getMessage(), ex);
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void start() {
+ try {
+ SSLContext sslContext = getSsl().createContext(this);
+ SSLParametersConfiguration parameters = getSsl().getParameters();
+ parameters.setContext(getContext());
+ socketFactory = new ConfigurableSSLSocketFactory(parameters,
+ sslContext.getSocketFactory());
+ super.start();
}
-
- /**
- * Gets the SSL configuration.
- * @return SSL configuration; if no configuration has been set, a
- * default configuration is returned
- */
- public SSLConfiguration getSsl() {
- if (ssl == null) {
- ssl = new SSLConfiguration();
- }
- return ssl;
+ catch (Exception ex) {
+ addError(ex.getMessage(), ex);
}
+ }
- /**
- * Sets the SSL configuration.
- * @param ssl the SSL configuration to set
- */
- public void setSsl(SSLConfiguration ssl) {
- this.ssl = ssl;
+ /**
+ * Gets the SSL configuration.
+ * @return SSL configuration; if no configuration has been set, a
+ * default configuration is returned
+ */
+ public SSLConfiguration getSsl() {
+ if (ssl == null) {
+ ssl = new SSLConfiguration();
}
+ return ssl;
+ }
+
+ /**
+ * Sets the SSL configuration.
+ * @param ssl the SSL configuration to set
+ */
+ public void setSsl(SSLConfiguration ssl) {
+ this.ssl = ssl;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/AbstractSocketAppender.java b/logback-core/src/main/java/ch/qos/logback/core/net/AbstractSocketAppender.java
index dfdb7a5..7b6c2e3 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/AbstractSocketAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/AbstractSocketAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,18 +15,25 @@
package ch.qos.logback.core.net;
import java.io.IOException;
+import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
-import java.util.concurrent.BlockingDeque;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
+
import javax.net.SocketFactory;
import ch.qos.logback.core.AppenderBase;
+import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.spi.PreSerializationTransformer;
import ch.qos.logback.core.util.CloseUtil;
import ch.qos.logback.core.util.Duration;
@@ -38,366 +45,407 @@ import ch.qos.logback.core.util.Duration;
* @author Ceki Gülcü
* @author Sébastien Pennec
* @author Carl Harris
- * @author Sebastian Gröbler
*/
-public abstract class AbstractSocketAppender<E> extends AppenderBase<E> implements SocketConnector.ExceptionHandler {
-
- /**
- * The default port number of remote logging server (4560).
- */
- public static final int DEFAULT_PORT = 4560;
-
- /**
- * The default reconnection delay (30000 milliseconds or 30 seconds).
- */
- public static final int DEFAULT_RECONNECTION_DELAY = 30000;
-
- /**
- * Default size of the deque used to hold logging events that are destined
- * for the remote peer.
- */
- public static final int DEFAULT_QUEUE_SIZE = 128;
-
- /**
- * Default timeout when waiting for the remote server to accept our
- * connection.
- */
- private static final int DEFAULT_ACCEPT_CONNECTION_DELAY = 5000;
-
- /**
- * Default timeout for how long to wait when inserting an event into
- * the BlockingQueue.
- */
- private static final int DEFAULT_EVENT_DELAY_TIMEOUT = 100;
-
- private final ObjectWriterFactory objectWriterFactory;
- private final QueueFactory queueFactory;
-
- private String remoteHost;
- private int port = DEFAULT_PORT;
- private InetAddress address;
- private Duration reconnectionDelay = new Duration(DEFAULT_RECONNECTION_DELAY);
- private int queueSize = DEFAULT_QUEUE_SIZE;
- private int acceptConnectionTimeout = DEFAULT_ACCEPT_CONNECTION_DELAY;
- private Duration eventDelayLimit = new Duration(DEFAULT_EVENT_DELAY_TIMEOUT);
-
- private BlockingDeque<E> deque;
- private String peerId;
- private SocketConnector connector;
- private Future<?> task;
-
- private volatile Socket socket;
-
- /**
- * Constructs a new appender.
- */
- protected AbstractSocketAppender() {
- this(new QueueFactory(), new ObjectWriterFactory());
- }
-
- /**
- * Constructs a new appender using the given {@link QueueFactory} and {@link ObjectWriterFactory}.
- */
- AbstractSocketAppender(QueueFactory queueFactory, ObjectWriterFactory objectWriterFactory) {
- this.objectWriterFactory = objectWriterFactory;
- this.queueFactory = queueFactory;
+public abstract class AbstractSocketAppender<E> extends AppenderBase<E>
+ implements Runnable, SocketConnector.ExceptionHandler {
+
+ /**
+ * The default port number of remote logging server (4560).
+ */
+ public static final int DEFAULT_PORT = 4560;
+
+ /**
+ * The default reconnection delay (30000 milliseconds or 30 seconds).
+ */
+ public static final int DEFAULT_RECONNECTION_DELAY = 30000;
+
+ /**
+ * Default size of the queue used to hold logging events that are destined
+ * for the remote peer.
+ */
+ public static final int DEFAULT_QUEUE_SIZE = 128;
+
+ /**
+ * Default timeout when waiting for the remote server to accept our
+ * connection.
+ */
+ private static final int DEFAULT_ACCEPT_CONNECTION_DELAY = 5000;
+
+ /**
+ * Default timeout for how long to wait when inserting an event into
+ * the BlockingQueue.
+ */
+ private static final int DEFAULT_EVENT_DELAY_TIMEOUT = 100;
+
+ private String remoteHost;
+ private int port = DEFAULT_PORT;
+ private InetAddress address;
+ private Duration reconnectionDelay = new Duration(DEFAULT_RECONNECTION_DELAY);
+ private int queueSize = DEFAULT_QUEUE_SIZE;
+ private int acceptConnectionTimeout = DEFAULT_ACCEPT_CONNECTION_DELAY;
+ private Duration eventDelayLimit = new Duration(DEFAULT_EVENT_DELAY_TIMEOUT);
+
+ private BlockingQueue<E> queue;
+ private String peerId;
+ private Future<?> task;
+ private Future<Socket> connectorTask;
+
+ private volatile Socket socket;
+
+ /**
+ * Constructs a new appender.
+ */
+ protected AbstractSocketAppender() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void start() {
+ if (isStarted()) return;
+ int errorCount = 0;
+ if (port <= 0) {
+ errorCount++;
+ addError("No port was configured for appender"
+ + name
+ + " For more information, please visit http://logback.qos.ch/codes.html#socket_no_port");
}
- /**
- * {@inheritDoc}
- */
- public void start() {
- if (isStarted())
- return;
- int errorCount = 0;
- if (port <= 0) {
- errorCount++;
- addError("No port was configured for appender" + name + " For more information, please visit http://logback.qos.ch/codes.html#socket_no_port");
- }
-
- if (remoteHost == null) {
- errorCount++;
- addError("No remote host was configured for appender" + name
- + " For more information, please visit http://logback.qos.ch/codes.html#socket_no_host");
- }
-
- if (queueSize == 0) {
- addWarn("Queue size of zero is deprecated, use a size of one to indicate synchronous processing");
- }
-
- if (queueSize < 0) {
- errorCount++;
- addError("Queue size must be greater than zero");
- }
-
- if (errorCount == 0) {
- try {
- address = InetAddress.getByName(remoteHost);
- } catch (UnknownHostException ex) {
- addError("unknown host: " + remoteHost);
- errorCount++;
- }
- }
-
- if (errorCount == 0) {
- deque = queueFactory.newLinkedBlockingDeque(queueSize);
- peerId = "remote peer " + remoteHost + ":" + port + ": ";
- connector = createConnector(address, port, 0, reconnectionDelay.getMilliseconds());
- task = getContext().getExecutorService().submit(new Runnable() {
- @Override
- public void run() {
- connectSocketAndDispatchEvents();
- }
- });
- super.start();
- }
+ if (remoteHost == null) {
+ errorCount++;
+ addError("No remote host was configured for appender"
+ + name
+ + " For more information, please visit http://logback.qos.ch/codes.html#socket_no_host");
}
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void stop() {
- if (!isStarted())
- return;
- CloseUtil.closeQuietly(socket);
- task.cancel(true);
- super.stop();
+
+ if (queueSize < 0) {
+ errorCount++;
+ addError("Queue size must be non-negative");
}
- /**
- * {@inheritDoc}
- */
- @Override
- protected void append(E event) {
- if (event == null || !isStarted())
- return;
-
- try {
- final boolean inserted = deque.offer(event, eventDelayLimit.getMilliseconds(), TimeUnit.MILLISECONDS);
- if (!inserted) {
- addInfo("Dropping event due to timeout limit of [" + eventDelayLimit + "] being exceeded");
- }
- } catch (InterruptedException e) {
- addError("Interrupted while appending event to SocketAppender", e);
- }
+ if (errorCount == 0) {
+ try {
+ address = InetAddress.getByName(remoteHost);
+ } catch (UnknownHostException ex) {
+ addError("unknown host: " + remoteHost);
+ errorCount++;
+ }
}
- private void connectSocketAndDispatchEvents() {
- try {
- while (socketConnectionCouldBeEstablished()) {
- try {
- ObjectWriter objectWriter = createObjectWriterForSocket();
- addInfo(peerId + "connection established");
- dispatchEvents(objectWriter);
- } catch (IOException ex) {
- addInfo(peerId + "connection failed: " + ex);
- } finally {
- CloseUtil.closeQuietly(socket);
- socket = null;
- addInfo(peerId + "connection closed");
- }
- }
- } catch (InterruptedException ex) {
- assert true; // ok... we'll exit now
- }
- addInfo("shutting down");
+ if (errorCount == 0) {
+ queue = newBlockingQueue(queueSize);
+ peerId = "remote peer " + remoteHost + ":" + port + ": ";
+ task = getContext().getExecutorService().submit(this);
+ super.start();
}
-
- private boolean socketConnectionCouldBeEstablished() throws InterruptedException {
- return (socket = connector.call()) != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void stop() {
+ if (!isStarted()) return;
+ CloseUtil.closeQuietly(socket);
+ task.cancel(true);
+ if(connectorTask != null)
+ connectorTask.cancel(true);
+ super.stop();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void append(E event) {
+ if (event == null || !isStarted()) return;
+
+ try {
+ final boolean inserted = queue.offer(event, eventDelayLimit.getMilliseconds(), TimeUnit.MILLISECONDS);
+ if (!inserted) {
+ addInfo("Dropping event due to timeout limit of [" + eventDelayLimit +
+ "] milliseconds being exceeded");
+ }
+ } catch (InterruptedException e) {
+ addError("Interrupted while appending event to SocketAppender", e);
}
-
- private ObjectWriter createObjectWriterForSocket() throws IOException {
- socket.setSoTimeout(acceptConnectionTimeout);
- ObjectWriter objectWriter = objectWriterFactory.newAutoFlushingObjectWriter(socket.getOutputStream());
- socket.setSoTimeout(0);
- return objectWriter;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void run() {
+ signalEntryInRunMethod();
+ try {
+ while (!Thread.currentThread().isInterrupted()) {
+ SocketConnector connector = createConnector(address, port, 0,
+ reconnectionDelay.getMilliseconds());
+
+ connectorTask = activateConnector(connector);
+ if(connectorTask == null)
+ break;
+
+ socket = waitForConnectorToReturnASocket();
+ if(socket == null)
+ break;
+ dispatchEvents();
+ }
+ } catch (InterruptedException ex) {
+ assert true; // ok... we'll exit now
}
+ addInfo("shutting down");
+ }
- private SocketConnector createConnector(InetAddress address, int port, int initialDelay, long retryDelay) {
- SocketConnector connector = newConnector(address, port, initialDelay, retryDelay);
- connector.setExceptionHandler(this);
- connector.setSocketFactory(getSocketFactory());
- return connector;
+ protected void signalEntryInRunMethod() {
+ // do nothing by default
}
- private void dispatchEvents(ObjectWriter objectWriter) throws InterruptedException, IOException {
- while (true) {
- E event = deque.takeFirst();
- postProcessEvent(event);
- Serializable serializableEvent = getPST().transform(event);
- try {
- objectWriter.write(serializableEvent);
- } catch (IOException e) {
- tryReAddingEventToFrontOfQueue(event);
- throw e;
- }
- }
+ private SocketConnector createConnector(InetAddress address, int port,
+ int initialDelay, long retryDelay) {
+ SocketConnector connector = newConnector(address, port, initialDelay,
+ retryDelay);
+ connector.setExceptionHandler(this);
+ connector.setSocketFactory(getSocketFactory());
+ return connector;
+ }
+
+ private Future<Socket> activateConnector(SocketConnector connector) {
+ try {
+ return getContext().getExecutorService().submit(connector);
+ } catch (RejectedExecutionException ex) {
+ return null;
}
-
- private void tryReAddingEventToFrontOfQueue(E event) {
- final boolean wasInserted = deque.offerFirst(event);
- if (!wasInserted) {
- addInfo("Dropping event due to socket connection error and maxed out deque capacity");
- }
+ }
+
+ private Socket waitForConnectorToReturnASocket() throws InterruptedException {
+ try {
+ Socket s = connectorTask.get();
+ connectorTask = null;
+ return s;
+ } catch (ExecutionException e) {
+ return null;
}
-
- /**
- * {@inheritDoc}
- */
- public void connectionFailed(SocketConnector connector, Exception ex) {
- if (ex instanceof InterruptedException) {
- addInfo("connector interrupted");
- } else if (ex instanceof ConnectException) {
- addInfo(peerId + "connection refused");
- } else {
- addInfo(peerId + ex);
+ }
+
+ private void dispatchEvents() throws InterruptedException {
+ try {
+ socket.setSoTimeout(acceptConnectionTimeout);
+ ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
+ socket.setSoTimeout(0);
+ addInfo(peerId + "connection established");
+ int counter = 0;
+ while (true) {
+ E event = queue.take();
+ postProcessEvent(event);
+ Serializable serEvent = getPST().transform(event);
+ oos.writeObject(serEvent);
+ oos.flush();
+ if (++counter >= CoreConstants.OOS_RESET_FREQUENCY) {
+ // Failing to reset the object output stream every now and
+ // then creates a serious memory leak.
+ oos.reset();
+ counter = 0;
}
+ }
+ } catch (IOException ex) {
+ addInfo(peerId + "connection failed: " + ex);
+ } finally {
+ CloseUtil.closeQuietly(socket);
+ socket = null;
+ addInfo(peerId + "connection closed");
}
-
- /**
- * Creates a new {@link SocketConnector}.
- * <p>
- * The default implementation creates an instance of {@link DefaultSocketConnector}.
- * A subclass may override to provide a different {@link SocketConnector}
- * implementation.
- *
- * @param address target remote address
- * @param port target remote port
- * @param initialDelay delay before the first connection attempt
- * @param retryDelay delay before a reconnection attempt
- * @return socket connector
- */
- protected SocketConnector newConnector(InetAddress address, int port, long initialDelay, long retryDelay) {
- return new DefaultSocketConnector(address, port, initialDelay, retryDelay);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void connectionFailed(SocketConnector connector, Exception ex) {
+ if (ex instanceof InterruptedException) {
+ addInfo("connector interrupted");
+ } else if (ex instanceof ConnectException) {
+ addInfo(peerId + "connection refused");
+ } else {
+ addInfo(peerId + ex);
}
-
- /**
- * Gets the default {@link SocketFactory} for the platform.
- * <p>
- * Subclasses may override to provide a custom socket factory.
- */
- protected SocketFactory getSocketFactory() {
- return SocketFactory.getDefault();
- }
-
- /**
- * Post-processes an event before it is serialized for delivery to the
- * remote receiver.
- * @param event the event to post-process
- */
- protected abstract void postProcessEvent(E event);
-
- /**
- * Get the pre-serialization transformer that will be used to transform
- * each event into a Serializable object before delivery to the remote
- * receiver.
- * @return transformer object
- */
- protected abstract PreSerializationTransformer<E> getPST();
-
- /**
- * The <b>RemoteHost</b> property takes the name of of the host where a corresponding server is running.
- */
- public void setRemoteHost(String host) {
- remoteHost = host;
- }
-
- /**
- * Returns value of the <b>RemoteHost</b> property.
- */
- public String getRemoteHost() {
- return remoteHost;
- }
-
- /**
- * The <b>Port</b> property takes a positive integer representing the port
- * where the server is waiting for connections.
- */
- public void setPort(int port) {
- this.port = port;
- }
-
- /**
- * Returns value of the <b>Port</b> property.
- */
- public int getPort() {
- return port;
- }
-
- /**
- * The <b>reconnectionDelay</b> property takes a positive {@link Duration} value
- * representing the time to wait between each failed connection attempt
- * to the server. The default value of this option is to 30 seconds.
- *
- * <p>
- * Setting this option to zero turns off reconnection capability.
- */
- public void setReconnectionDelay(Duration delay) {
- this.reconnectionDelay = delay;
- }
-
- /**
- * Returns value of the <b>reconnectionDelay</b> property.
- */
- public Duration getReconnectionDelay() {
- return reconnectionDelay;
- }
-
- /**
- * The <b>queueSize</b> property takes a non-negative integer representing
- * the number of logging events to retain for delivery to the remote receiver.
- * When the deque size is zero, event delivery to the remote receiver is
- * synchronous. When the deque size is greater than zero, the
- * {@link #append(Object)} method returns immediately after enqueing the
- * event, assuming that there is space available in the deque. Using a
- * non-zero deque length can improve performance by eliminating delays
- * caused by transient network delays.
- *
- * @param queueSize the deque size to set.
- */
- public void setQueueSize(int queueSize) {
- this.queueSize = queueSize;
- }
-
- /**
- * Returns the value of the <b>queueSize</b> property.
- */
- public int getQueueSize() {
- return queueSize;
- }
-
- /**
- * The <b>eventDelayLimit</b> takes a non-negative integer representing the
- * number of milliseconds to allow the appender to block if the underlying
- * BlockingQueue is full. Once this limit is reached, the event is dropped.
- *
- * @param eventDelayLimit the event delay limit
- */
- public void setEventDelayLimit(Duration eventDelayLimit) {
- this.eventDelayLimit = eventDelayLimit;
- }
-
- /**
- * Returns the value of the <b>eventDelayLimit</b> property.
- */
- public Duration getEventDelayLimit() {
- return eventDelayLimit;
- }
-
- /**
- * Sets the timeout that controls how long we'll wait for the remote
- * peer to accept our connection attempt.
- * <p>
- * This property is configurable primarily to support instrumentation
- * for unit testing.
- *
- * @param acceptConnectionTimeout timeout value in milliseconds
- */
- void setAcceptConnectionTimeout(int acceptConnectionTimeout) {
- this.acceptConnectionTimeout = acceptConnectionTimeout;
+ }
+
+
+
+ /**
+ * Creates a new {@link SocketConnector}.
+ * <p>
+ * The default implementation creates an instance of {@link DefaultSocketConnector}.
+ * A subclass may override to provide a different {@link SocketConnector}
+ * implementation.
+ *
+ * @param address target remote address
+ * @param port target remote port
+ * @param initialDelay delay before the first connection attempt
+ * @param retryDelay delay before a reconnection attempt
+ * @return socket connector
+ */
+ protected SocketConnector newConnector(InetAddress address,
+ int port, long initialDelay, long retryDelay) {
+ return new DefaultSocketConnector(address, port, initialDelay, retryDelay);
+ }
+
+ /**
+ * Gets the default {@link SocketFactory} for the platform.
+ * <p>
+ * Subclasses may override to provide a custom socket factory.
+ */
+ protected SocketFactory getSocketFactory() {
+ return SocketFactory.getDefault();
+ }
+
+ /**
+ * Creates a blocking queue that will be used to hold logging events until
+ * they can be delivered to the remote receiver.
+ * <p>
+ * The default implementation creates a (bounded) {@link ArrayBlockingQueue}
+ * for positive queue sizes. Otherwise it creates a {@link SynchronousQueue}.
+ * <p>
+ * This method is exposed primarily to support instrumentation for unit
+ * testing.
+ *
+ * @param queueSize size of the queue
+ * @return
+ */
+ BlockingQueue<E> newBlockingQueue(int queueSize) {
+ return queueSize <= 0 ?
+ new SynchronousQueue<E>() : new ArrayBlockingQueue<E>(queueSize);
+ }
+
+ /**
+ * Post-processes an event before it is serialized for delivery to the
+ * remote receiver.
+ * @param event the event to post-process
+ */
+ protected abstract void postProcessEvent(E event);
+
+ /**
+ * Get the pre-serialization transformer that will be used to transform
+ * each event into a Serializable object before delivery to the remote
+ * receiver.
+ * @return transformer object
+ */
+ protected abstract PreSerializationTransformer<E> getPST();
+
+ /*
+ * This method is used by logback modules only in the now deprecated
+ * convenience constructors for SocketAppender
+ */
+ @Deprecated
+ protected static InetAddress getAddressByName(String host) {
+ try {
+ return InetAddress.getByName(host);
+ } catch (Exception e) {
+ // addError("Could not find address of [" + host + "].", e);
+ return null;
}
+ }
+
+ /**
+ * The <b>RemoteHost</b> property takes the name of of the host where a corresponding server is running.
+ */
+ public void setRemoteHost(String host) {
+ remoteHost = host;
+ }
+
+ /**
+ * Returns value of the <b>RemoteHost</b> property.
+ */
+ public String getRemoteHost() {
+ return remoteHost;
+ }
+
+ /**
+ * The <b>Port</b> property takes a positive integer representing the port
+ * where the server is waiting for connections.
+ */
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ /**
+ * Returns value of the <b>Port</b> property.
+ */
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * The <b>reconnectionDelay</b> property takes a positive {@link Duration} value
+ * representing the time to wait between each failed connection attempt
+ * to the server. The default value of this option is to 30 seconds.
+ *
+ * <p>
+ * Setting this option to zero turns off reconnection capability.
+ */
+ public void setReconnectionDelay(Duration delay) {
+ this.reconnectionDelay = delay;
+ }
+
+ /**
+ * Returns value of the <b>reconnectionDelay</b> property.
+ */
+ public Duration getReconnectionDelay() {
+ return reconnectionDelay;
+ }
+
+ /**
+ * The <b>queueSize</b> property takes a non-negative integer representing
+ * the number of logging events to retain for delivery to the remote receiver.
+ * When the queue size is zero, event delivery to the remote receiver is
+ * synchronous. When the queue size is greater than zero, the
+ * {@link #append(Object)} method returns immediately after enqueing the
+ * event, assuming that there is space available in the queue. Using a
+ * non-zero queue length can improve performance by eliminating delays
+ * caused by transient network delays.
+ *
+ * @param queueSize the queue size to set.
+ */
+ public void setQueueSize(int queueSize) {
+ this.queueSize = queueSize;
+ }
+
+ /**
+ * Returns the value of the <b>queueSize</b> property.
+ */
+ public int getQueueSize() {
+ return queueSize;
+ }
+
+ /**
+ * The <b>eventDelayLimit</b> takes a non-negative integer representing the
+ * number of milliseconds to allow the appender to block if the underlying
+ * BlockingQueue is full. Once this limit is reached, the event is dropped.
+ *
+ * @param eventDelayLimit the event delay limit
+ */
+ public void setEventDelayLimit(Duration eventDelayLimit) {
+ this.eventDelayLimit = eventDelayLimit;
+ }
+
+ /**
+ * Returns the value of the <b>eventDelayLimit</b> property.
+ */
+ public Duration getEventDelayLimit() {
+ return eventDelayLimit;
+ }
+
+ /**
+ * Sets the timeout that controls how long we'll wait for the remote
+ * peer to accept our connection attempt.
+ * <p>
+ * This property is configurable primarily to support instrumentation
+ * for unit testing.
+ *
+ * @param acceptConnectionTimeout timeout value in milliseconds
+ */
+ void setAcceptConnectionTimeout(int acceptConnectionTimeout) {
+ this.acceptConnectionTimeout = acceptConnectionTimeout;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/AutoFlushingObjectWriter.java b/logback-core/src/main/java/ch/qos/logback/core/net/AutoFlushingObjectWriter.java
deleted file mode 100644
index df13e7b..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/net/AutoFlushingObjectWriter.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.net;
-
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-
-/**
- * Automatically flushes the underlying {@link java.io.ObjectOutputStream} immediately after calling
- * it's {@link java.io.ObjectOutputStream#writeObject(Object)} method.
- *
- * @author Sebastian Gröbler
- */
-public class AutoFlushingObjectWriter implements ObjectWriter {
-
- private final ObjectOutputStream objectOutputStream;
- private final int resetFrequency;
- private int writeCounter = 0;
-
- /**
- * Creates a new instance for the given {@link java.io.ObjectOutputStream}.
- *
- * @param objectOutputStream the stream to write to
- * @param resetFrequency the frequency with which the given stream will be
- * automatically reset to prevent a memory leak
- */
- public AutoFlushingObjectWriter(ObjectOutputStream objectOutputStream, int resetFrequency) {
- this.objectOutputStream = objectOutputStream;
- this.resetFrequency = resetFrequency;
- }
-
- @Override
- public void write(Object object) throws IOException {
- objectOutputStream.writeObject(object);
- objectOutputStream.flush();
- preventMemoryLeak();
- }
-
- /**
- * Failing to reset the object output stream every now and then creates a serious memory leak which
- * is why the underlying stream will be reset according to the {@code resetFrequency}.
- */
- private void preventMemoryLeak() throws IOException {
- if (++writeCounter >= resetFrequency) {
- objectOutputStream.reset();
- writeCounter = 0;
- }
- }
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/DefaultSocketConnector.java b/logback-core/src/main/java/ch/qos/logback/core/net/DefaultSocketConnector.java
index 9ecf7d8..38b26e7 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/DefaultSocketConnector.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/DefaultSocketConnector.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,94 +30,96 @@ import ch.qos.logback.core.util.FixedDelay;
*/
public class DefaultSocketConnector implements SocketConnector {
- private final InetAddress address;
- private final int port;
- private final DelayStrategy delayStrategy;
-
- private ExceptionHandler exceptionHandler;
- private SocketFactory socketFactory;
-
- /**
- * Constructs a new connector.
- *
- * @param address address of remote listener
- * @param port port of remote listener
- * @param initialDelay delay before initial connection attempt
- * @param retryDelay delay after failed connection attempt
- */
- public DefaultSocketConnector(InetAddress address, int port, long initialDelay, long retryDelay) {
- this(address, port, new FixedDelay(initialDelay, retryDelay));
+ private final InetAddress address;
+ private final int port;
+ private final DelayStrategy delayStrategy;
+
+ private ExceptionHandler exceptionHandler;
+ private SocketFactory socketFactory;
+
+ /**
+ * Constructs a new connector.
+ *
+ * @param address address of remote listener
+ * @param port port of remote listener
+ * @param initialDelay delay before initial connection attempt
+ * @param retryDelay delay after failed connection attempt
+ */
+ public DefaultSocketConnector(InetAddress address, int port,
+ long initialDelay, long retryDelay) {
+ this(address, port, new FixedDelay(initialDelay, retryDelay));
+ }
+
+ /**
+ * Constructs a new connector.
+ *
+ * @param address address of remote listener
+ * @param port port of remote listener
+ * @param delayStrategy strategy for choosing the delay to impose before
+ * each connection attempt
+ */
+ public DefaultSocketConnector(InetAddress address, int port,
+ DelayStrategy delayStrategy) {
+ this.address = address;
+ this.port = port;
+ this.delayStrategy = delayStrategy;
+ }
+
+ /**
+ * Loops until the desired connection is established and returns the resulting connector.
+ */
+ public Socket call() throws InterruptedException {
+ useDefaultsForMissingFields();
+ Socket socket = createSocket();
+ while (socket == null && !Thread.currentThread().isInterrupted()) {
+ Thread.sleep(delayStrategy.nextDelay());
+ socket = createSocket();
}
-
- /**
- * Constructs a new connector.
- *
- * @param address address of remote listener
- * @param port port of remote listener
- * @param delayStrategy strategy for choosing the delay to impose before
- * each connection attempt
- */
- public DefaultSocketConnector(InetAddress address, int port, DelayStrategy delayStrategy) {
- this.address = address;
- this.port = port;
- this.delayStrategy = delayStrategy;
- }
-
- /**
- * Loops until the desired connection is established and returns the resulting connector.
- */
- public Socket call() throws InterruptedException {
- useDefaultsForMissingFields();
- Socket socket = createSocket();
- while (socket == null && !Thread.currentThread().isInterrupted()) {
- Thread.sleep(delayStrategy.nextDelay());
- socket = createSocket();
- }
- return socket;
- }
-
- private Socket createSocket() {
- Socket newSocket = null;
- try {
- newSocket = socketFactory.createSocket(address, port);
- } catch (IOException ioex) {
- exceptionHandler.connectionFailed(this, ioex);
- }
- return newSocket;
+ return socket;
+ }
+
+ private Socket createSocket() {
+ Socket newSocket = null;
+ try {
+ newSocket = socketFactory.createSocket(address, port);
+ } catch (IOException ioex) {
+ exceptionHandler.connectionFailed(this, ioex);
}
+ return newSocket;
+ }
- private void useDefaultsForMissingFields() {
- if (exceptionHandler == null) {
- exceptionHandler = new ConsoleExceptionHandler();
- }
- if (socketFactory == null) {
- socketFactory = SocketFactory.getDefault();
- }
+ private void useDefaultsForMissingFields() {
+ if (exceptionHandler == null) {
+ exceptionHandler = new ConsoleExceptionHandler();
}
-
- /**
- * {@inheritDoc}
- */
- public void setExceptionHandler(ExceptionHandler exceptionHandler) {
- this.exceptionHandler = exceptionHandler;
+ if (socketFactory == null) {
+ socketFactory = SocketFactory.getDefault();
}
-
- /**
- * {@inheritDoc}
- */
- public void setSocketFactory(SocketFactory socketFactory) {
- this.socketFactory = socketFactory;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setExceptionHandler(ExceptionHandler exceptionHandler) {
+ this.exceptionHandler = exceptionHandler;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setSocketFactory(SocketFactory socketFactory) {
+ this.socketFactory = socketFactory;
+ }
+
+ /**
+ * A default {@link ExceptionHandler} that writes to {@code System.out}
+ */
+ private static class ConsoleExceptionHandler implements ExceptionHandler {
+
+ public void connectionFailed(SocketConnector connector, Exception ex) {
+ System.out.println(ex);
}
- /**
- * A default {@link ExceptionHandler} that writes to {@code System.out}
- */
- private static class ConsoleExceptionHandler implements ExceptionHandler {
-
- public void connectionFailed(SocketConnector connector, Exception ex) {
- System.out.println(ex);
- }
-
- }
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/JMSAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/net/JMSAppenderBase.java
index 828d40d..965c6eb 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/JMSAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/JMSAppenderBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -35,137 +35,143 @@ import ch.qos.logback.core.AppenderBase;
*/
public abstract class JMSAppenderBase<E> extends AppenderBase<E> {
- protected String securityPrincipalName;
- protected String securityCredentials;
- protected String initialContextFactoryName;
- protected String urlPkgPrefixes;
- protected String providerURL;
- protected String userName;
- protected String password;
-
- protected Object lookup(Context ctx, String name) throws NamingException {
- try {
- return ctx.lookup(name);
- } catch (NameNotFoundException e) {
- addError("Could not find name [" + name + "].");
- throw e;
- }
- }
-
- public Context buildJNDIContext() throws NamingException {
- Context jndi = null;
-
- // addInfo("Getting initial context.");
- if (initialContextFactoryName != null) {
- Properties env = buildEnvProperties();
- jndi = new InitialContext(env);
- } else {
- jndi = new InitialContext();
- }
- return jndi;
- }
-
- public Properties buildEnvProperties() {
- Properties env = new Properties();
- env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactoryName);
- if (providerURL != null) {
- env.put(Context.PROVIDER_URL, providerURL);
- } else {
- addWarn("You have set InitialContextFactoryName option but not the " + "ProviderURL. This is likely to cause problems.");
- }
- if (urlPkgPrefixes != null) {
- env.put(Context.URL_PKG_PREFIXES, urlPkgPrefixes);
- }
-
- if (securityPrincipalName != null) {
- env.put(Context.SECURITY_PRINCIPAL, securityPrincipalName);
- if (securityCredentials != null) {
- env.put(Context.SECURITY_CREDENTIALS, securityCredentials);
- } else {
- addWarn("You have set SecurityPrincipalName option but not the " + "SecurityCredentials. This is likely to cause problems.");
- }
- }
- return env;
- }
-
- /**
- * Returns the value of the <b>InitialContextFactoryName</b> option. See
- * {@link #setInitialContextFactoryName} for more details on the meaning of
- * this option.
- */
- public String getInitialContextFactoryName() {
- return initialContextFactoryName;
- }
-
- /**
- * Setting the <b>InitialContextFactoryName</b> method will cause this
- * <code>JMSAppender</code> instance to use the {@link
- * InitialContext#InitialContext(Hashtable)} method instead of the no-argument
- * constructor. If you set this option, you should also at least set the
- * <b>ProviderURL</b> option.
- *
- * <p>
- * See also {@link #setProviderURL(String)}.
- */
- public void setInitialContextFactoryName(String initialContextFactoryName) {
- this.initialContextFactoryName = initialContextFactoryName;
- }
-
- public String getProviderURL() {
- return providerURL;
- }
-
- public void setProviderURL(String providerURL) {
- this.providerURL = providerURL;
- }
-
- public String getURLPkgPrefixes() {
- return urlPkgPrefixes;
- }
-
- public void setURLPkgPrefixes(String urlPkgPrefixes) {
- this.urlPkgPrefixes = urlPkgPrefixes;
- }
-
- public String getSecurityCredentials() {
- return securityCredentials;
- }
-
- public void setSecurityCredentials(String securityCredentials) {
- this.securityCredentials = securityCredentials;
- }
-
- public String getSecurityPrincipalName() {
- return securityPrincipalName;
- }
-
- public void setSecurityPrincipalName(String securityPrincipalName) {
- this.securityPrincipalName = securityPrincipalName;
- }
-
- public String getUserName() {
- return userName;
- }
-
- /**
- * The user name to use when {@link
- * javax.jms.TopicConnectionFactory#createTopicConnection(String, String)}
- * creating a topic session}. If you set this option, you should also set the
- * <b>Password</b> option. See {@link #setPassword(String)}.
- */
- public void setUserName(String userName) {
- this.userName = userName;
- }
-
- public String getPassword() {
- return password;
- }
-
- /**
- * The password to use when creating a topic session.
- */
- public void setPassword(String password) {
- this.password = password;
- }
-
+ protected String securityPrincipalName;
+ protected String securityCredentials;
+ protected String initialContextFactoryName;
+ protected String urlPkgPrefixes;
+ protected String providerURL;
+ protected String userName;
+ protected String password;
+
+
+ protected Object lookup(Context ctx, String name) throws NamingException {
+ try {
+ return ctx.lookup(name);
+ } catch (NameNotFoundException e) {
+ addError("Could not find name [" + name + "].");
+ throw e;
+ }
+ }
+
+ public Context buildJNDIContext() throws NamingException {
+ Context jndi = null;
+
+ // addInfo("Getting initial context.");
+ if (initialContextFactoryName != null) {
+ Properties env = buildEnvProperties();
+ jndi = new InitialContext(env);
+ } else {
+ jndi = new InitialContext();
+ }
+ return jndi;
+ }
+
+ public Properties buildEnvProperties() {
+ Properties env = new Properties();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactoryName);
+ if (providerURL != null) {
+ env.put(Context.PROVIDER_URL, providerURL);
+ } else {
+ addWarn("You have set InitialContextFactoryName option but not the "
+ + "ProviderURL. This is likely to cause problems.");
+ }
+ if (urlPkgPrefixes != null) {
+ env.put(Context.URL_PKG_PREFIXES, urlPkgPrefixes);
+ }
+
+ if (securityPrincipalName != null) {
+ env.put(Context.SECURITY_PRINCIPAL, securityPrincipalName);
+ if (securityCredentials != null) {
+ env.put(Context.SECURITY_CREDENTIALS, securityCredentials);
+ } else {
+ addWarn("You have set SecurityPrincipalName option but not the "
+ + "SecurityCredentials. This is likely to cause problems.");
+ }
+ }
+ return env;
+ }
+
+
+
+ /**
+ * Returns the value of the <b>InitialContextFactoryName</b> option. See
+ * {@link #setInitialContextFactoryName} for more details on the meaning of
+ * this option.
+ */
+ public String getInitialContextFactoryName() {
+ return initialContextFactoryName;
+ }
+
+ /**
+ * Setting the <b>InitialContextFactoryName</b> method will cause this
+ * <code>JMSAppender</code> instance to use the {@link
+ * InitialContext#InitialContext(Hashtable)} method instead of the no-argument
+ * constructor. If you set this option, you should also at least set the
+ * <b>ProviderURL</b> option.
+ *
+ * <p>
+ * See also {@link #setProviderURL(String)}.
+ */
+ public void setInitialContextFactoryName(String initialContextFactoryName) {
+ this.initialContextFactoryName = initialContextFactoryName;
+ }
+
+ public String getProviderURL() {
+ return providerURL;
+ }
+
+ public void setProviderURL(String providerURL) {
+ this.providerURL = providerURL;
+ }
+
+ public String getURLPkgPrefixes() {
+ return urlPkgPrefixes;
+ }
+
+ public void setURLPkgPrefixes(String urlPkgPrefixes) {
+ this.urlPkgPrefixes = urlPkgPrefixes;
+ }
+
+ public String getSecurityCredentials() {
+ return securityCredentials;
+ }
+
+ public void setSecurityCredentials(String securityCredentials) {
+ this.securityCredentials = securityCredentials;
+ }
+
+ public String getSecurityPrincipalName() {
+ return securityPrincipalName;
+ }
+
+ public void setSecurityPrincipalName(String securityPrincipalName) {
+ this.securityPrincipalName = securityPrincipalName;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ /**
+ * The user name to use when {@link
+ * javax.jms.TopicConnectionFactory#createTopicConnection(String, String)}
+ * creating a topic session}. If you set this option, you should also set the
+ * <b>Password</b> option. See {@link #setPassword(String)}.
+ */
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ /**
+ * The password to use when creating a topic session.
+ */
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/LoginAuthenticator.java b/logback-core/src/main/java/ch/qos/logback/core/net/LoginAuthenticator.java
index 3ee2503..4b5a587 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/LoginAuthenticator.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/LoginAuthenticator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,16 +21,16 @@ import javax.mail.PasswordAuthentication;
*/
public class LoginAuthenticator extends Authenticator {
- String username;
- String password;
-
- LoginAuthenticator(String username, String password) {
- this.username = username;
- this.password = password;
- }
-
- public PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication(username, password);
- }
+ String username;
+ String password;
+
+ LoginAuthenticator(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ public PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(username, password);
+}
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ObjectWriter.java b/logback-core/src/main/java/ch/qos/logback/core/net/ObjectWriter.java
deleted file mode 100644
index 17ac9f5..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ObjectWriter.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.net;
-
-import java.io.IOException;
-
-/**
- * Writes objects to an output.
- *
- * @author Sebastian Gröbler
- */
-public interface ObjectWriter {
-
- /**
- * Writes an object to an output.
- *
- * @param object the {@link Object} to write
- * @throws IOException in case input/output fails, details are defined by the implementation
- */
- void write(Object object) throws IOException;
-
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ObjectWriterFactory.java b/logback-core/src/main/java/ch/qos/logback/core/net/ObjectWriterFactory.java
deleted file mode 100644
index f9759d8..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ObjectWriterFactory.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.net;
-
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-
-import ch.qos.logback.core.CoreConstants;
-
-/**
- * Factory for {@link ch.qos.logback.core.net.ObjectWriter} instances.
- *
- * @author Sebastian Gröbler
- */
-public class ObjectWriterFactory {
-
- /**
- * Creates a new {@link ch.qos.logback.core.net.AutoFlushingObjectWriter} instance.
- *
- * @param outputStream the underlying {@link java.io.OutputStream} to write to
- * @return a new {@link ch.qos.logback.core.net.AutoFlushingObjectWriter} instance
- * @throws IOException if an I/O error occurs while writing stream header
- */
- public AutoFlushingObjectWriter newAutoFlushingObjectWriter(OutputStream outputStream) throws IOException {
- return new AutoFlushingObjectWriter(new ObjectOutputStream(outputStream), CoreConstants.OOS_RESET_FREQUENCY);
- }
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/QueueFactory.java b/logback-core/src/main/java/ch/qos/logback/core/net/QueueFactory.java
deleted file mode 100644
index 9d6ef55..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/net/QueueFactory.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.net;
-
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.LinkedBlockingDeque;
-
-/**
- * Factory for {@link java.util.Queue} instances.
- *
- * @author Sebastian Gröbler
- */
-public class QueueFactory {
-
- /**
- * Creates a new {@link LinkedBlockingDeque} with the given {@code capacity}.
- * In case the given capacity is smaller than one it will automatically be
- * converted to one.
- *
- * @param capacity the capacity to use for the queue
- * @param <E> the type of elements held in the queue
- * @return a new instance of {@link ArrayBlockingQueue}
- */
- public <E> LinkedBlockingDeque<E> newLinkedBlockingDeque(int capacity) {
- final int actualCapacity = capacity < 1 ? 1 : capacity;
- return new LinkedBlockingDeque<E>(actualCapacity);
- }
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
index 9a913ba..45c256b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,6 +20,7 @@ import java.util.List;
import java.util.Properties;
import javax.mail.Message;
+import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
@@ -60,614 +61,640 @@ import ch.qos.logback.core.util.OptionHelper;
*/
public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
- static InternetAddress[] EMPTY_IA_ARRAY = new InternetAddress[0];
- // ~ 14 days
- static final long MAX_DELAY_BETWEEN_STATUS_MESSAGES = 1228800 * CoreConstants.MILLIS_IN_ONE_SECOND;
+ static InternetAddress[] EMPTY_IA_ARRAY = new InternetAddress[0];
+ // ~ 14 days
+ static final int MAX_DELAY_BETWEEN_STATUS_MESSAGES = 1228800 * CoreConstants.MILLIS_IN_ONE_SECOND;
- long lastTrackerStatusPrint = 0;
- long delayBetweenStatusMessages = 300 * CoreConstants.MILLIS_IN_ONE_SECOND;
+ long lastTrackerStatusPrint = 0;
+ int delayBetweenStatusMessages = 300 * CoreConstants.MILLIS_IN_ONE_SECOND;
- protected Layout<E> subjectLayout;
- protected Layout<E> layout;
+ protected Layout<E> subjectLayout;
+ protected Layout<E> layout;
- private List<PatternLayoutBase<E>> toPatternLayoutList = new ArrayList<PatternLayoutBase<E>>();
- private String from;
- private String subjectStr = null;
- private String smtpHost;
- private int smtpPort = 25;
- private boolean starttls = false;
- private boolean ssl = false;
- private boolean sessionViaJNDI = false;
- private String jndiLocation = CoreConstants.JNDI_COMP_PREFIX + "/mail/Session";
+ private List<PatternLayoutBase<E>> toPatternLayoutList = new ArrayList<PatternLayoutBase<E>>();
+ private String from;
+ private String subjectStr = null;
+ private String smtpHost;
+ private int smtpPort = 25;
+ private boolean starttls = false;
+ private boolean ssl = false;
+ private boolean sessionViaJNDI = false;
+ private String jndiLocation = CoreConstants.JNDI_COMP_PREFIX + "/mail/Session";
- String username;
- String password;
- String localhost;
- boolean asynchronousSending = true;
+ String username;
+ String password;
+ String localhost;
- private String charsetEncoding = "UTF-8";
+ boolean asynchronousSending = true;
- protected Session session;
+ private String charsetEncoding = "UTF-8";
- protected EventEvaluator<E> eventEvaluator;
+ protected MimeMessage mimeMsg;
- protected Discriminator<E> discriminator = new DefaultDiscriminator<E>();
- protected CyclicBufferTracker<E> cbTracker;
+ protected EventEvaluator<E> eventEvaluator;
- private int errorCount = 0;
+ protected Discriminator<E> discriminator = new DefaultDiscriminator<E>();
+ protected CyclicBufferTracker<E> cbTracker;
- /**
- * return a layout for the subject string as appropriate for the module. If the
- * subjectStr parameter is null, then a default value for subjectStr should be
- * used.
- *
- * @param subjectStr
- * @return a layout as appropriate for the module
- */
- abstract protected Layout<E> makeSubjectLayout(String subjectStr);
+ private int errorCount = 0;
- /**
- * Start the appender
- */
- public void start() {
+ /**
+ * return a layout for the subject string as appropriate for the module. If the
+ * subjectStr parameter is null, then a default value for subjectStr should be
+ * used.
+ *
+ * @param subjectStr
+ * @return a layout as appropriate for the module
+ */
+ abstract protected Layout<E> makeSubjectLayout(String subjectStr);
- if (cbTracker == null) {
- cbTracker = new CyclicBufferTracker<E>();
- }
-
- if (sessionViaJNDI)
- session = lookupSessionInJNDI();
- else
- session = buildSessionFromProperties();
-
- if (session == null) {
- addError("Failed to obtain javax.mail.Session. Cannot start.");
- return;
- }
-
- subjectLayout = makeSubjectLayout(subjectStr);
-
- started = true;
- }
+ /**
+ * Start the appender
+ */
+ public void start() {
- private Session lookupSessionInJNDI() {
- addInfo("Looking up javax.mail.Session at JNDI location [" + jndiLocation + "]");
- try {
- Context initialContext = new InitialContext();
- Object obj = initialContext.lookup(jndiLocation);
- return (Session) obj;
- } catch (Exception e) {
- addError("Failed to obtain javax.mail.Session from JNDI location [" + jndiLocation + "]");
- return null;
- }
+ if (cbTracker == null) {
+ cbTracker = new CyclicBufferTracker<E>();
}
- private Session buildSessionFromProperties() {
- Properties props = new Properties(OptionHelper.getSystemProperties());
- if (smtpHost != null) {
- props.put("mail.smtp.host", smtpHost);
- }
- props.put("mail.smtp.port", Integer.toString(smtpPort));
-
- if (localhost != null) {
- props.put("mail.smtp.localhost", localhost);
- }
-
- LoginAuthenticator loginAuthenticator = null;
+ Session session = null;
+ if (sessionViaJNDI)
+ session = lookupSessionInJNDI();
+ else
+ session = buildSessionFromProperties();
- if (username != null) {
- loginAuthenticator = new LoginAuthenticator(username, password);
- props.put("mail.smtp.auth", "true");
- }
-
- if (isSTARTTLS() && isSSL()) {
- addError("Both SSL and StartTLS cannot be enabled simultaneously");
- } else {
- if (isSTARTTLS()) {
- // see also http://jira.qos.ch/browse/LBCORE-225
- props.put("mail.smtp.starttls.enable", "true");
- }
- if (isSSL()) {
- String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
- props.put("mail.smtp.socketFactory.port", Integer.toString(smtpPort));
- props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
- props.put("mail.smtp.socketFactory.fallback", "true");
- }
- }
-
- // props.put("mail.debug", "true");
-
- return Session.getInstance(props, loginAuthenticator);
+ if (session == null) {
+ addError("Failed to obtain javax.mail.Session. Cannot start.");
+ return;
}
+ mimeMsg = new MimeMessage(session);
- /**
- * Perform SMTPAppender specific appending actions, delegating some of them to
- * a subclass and checking if the event triggers an e-mail to be sent.
- */
- protected void append(E eventObject) {
+ try {
+ if (from != null) {
+ mimeMsg.setFrom(getAddress(from));
+ } else {
+ mimeMsg.setFrom();
+ }
- if (!checkEntryConditions()) {
- return;
- }
-
- String key = discriminator.getDiscriminatingValue(eventObject);
- long now = System.currentTimeMillis();
- final CyclicBuffer<E> cb = cbTracker.getOrCreate(key, now);
- subAppend(cb, eventObject);
-
- try {
- if (eventEvaluator.evaluate(eventObject)) {
- // clone the CyclicBuffer before sending out asynchronously
- CyclicBuffer<E> cbClone = new CyclicBuffer<E>(cb);
- // see http://jira.qos.ch/browse/LBCLASSIC-221
- cb.clear();
-
- if (asynchronousSending) {
- // perform actual sending asynchronously
- SenderRunnable senderRunnable = new SenderRunnable(cbClone, eventObject);
- context.getExecutorService().execute(senderRunnable);
- } else {
- // synchronous sending
- sendBuffer(cbClone, eventObject);
- }
- }
- } catch (EvaluationException ex) {
- errorCount++;
- if (errorCount < CoreConstants.MAX_ERROR_COUNT) {
- addError("SMTPAppender's EventEvaluator threw an Exception-", ex);
- }
- }
+ subjectLayout = makeSubjectLayout(subjectStr);
- // immediately remove the buffer if asked by the user
- if (eventMarksEndOfLife(eventObject)) {
- cbTracker.endOfLife(key);
- }
-
- cbTracker.removeStaleComponents(now);
+ started = true;
- if (lastTrackerStatusPrint + delayBetweenStatusMessages < now) {
- addInfo("SMTPAppender [" + name + "] is tracking [" + cbTracker.getComponentCount() + "] buffers");
- lastTrackerStatusPrint = now;
- // quadruple 'delay' assuming less than max delay
- if (delayBetweenStatusMessages < MAX_DELAY_BETWEEN_STATUS_MESSAGES) {
- delayBetweenStatusMessages *= 4;
- }
- }
+ } catch (MessagingException e) {
+ addError("Could not activate SMTPAppender options.", e);
}
+ }
- abstract protected boolean eventMarksEndOfLife(E eventObject);
-
- abstract protected void subAppend(CyclicBuffer<E> cb, E eventObject);
-
- /**
- * This method determines if there is a sense in attempting to append.
- * <p/>
- * <p/>
- * It checks whether there is a set output target and also if there is a set
- * layout. If these checks fail, then the boolean value <code>false</code> is
- * returned.
- */
- public boolean checkEntryConditions() {
- if (!this.started) {
- addError("Attempting to append to a non-started appender: " + this.getName());
- return false;
- }
-
- if (this.eventEvaluator == null) {
- addError("No EventEvaluator is set for appender [" + name + "].");
- return false;
- }
-
- if (this.layout == null) {
- addError("No layout set for appender named [" + name + "]. For more information, please visit http://logback.qos.ch/codes.html#smtp_no_layout");
- return false;
- }
- return true;
+ private Session lookupSessionInJNDI() {
+ addInfo("Looking up javax.mail.Session at JNDI location [" + jndiLocation + "]");
+ try {
+ Context initialContext = new InitialContext();
+ Object obj = initialContext.lookup(jndiLocation);
+ return (Session) obj;
+ } catch (Exception e) {
+ addError("Failed to obtain javax.mail.Session from JNDI location [" + jndiLocation+"]");
+ return null;
}
+ }
- synchronized public void stop() {
- this.started = false;
+ private Session buildSessionFromProperties() {
+ Properties props = new Properties(OptionHelper.getSystemProperties());
+ if (smtpHost != null) {
+ props.put("mail.smtp.host", smtpHost);
}
+ props.put("mail.smtp.port", Integer.toString(smtpPort));
- InternetAddress getAddress(String addressStr) {
- try {
- return new InternetAddress(addressStr);
- } catch (AddressException e) {
- addError("Could not parse address [" + addressStr + "].", e);
- return null;
- }
+ if (localhost != null) {
+ props.put("mail.smtp.localhost", localhost);
}
- private List<InternetAddress> parseAddress(E event) {
- int len = toPatternLayoutList.size();
-
- List<InternetAddress> iaList = new ArrayList<InternetAddress>();
-
- for (int i = 0; i < len; i++) {
- try {
- PatternLayoutBase<E> emailPL = toPatternLayoutList.get(i);
- String emailAdrr = emailPL.doLayout(event);
- if (emailAdrr == null || emailAdrr.length() == 0) {
- continue;
- }
- InternetAddress[] tmp = InternetAddress.parse(emailAdrr, true);
- iaList.addAll(Arrays.asList(tmp));
- } catch (AddressException e) {
- addError("Could not parse email address for [" + toPatternLayoutList.get(i) + "] for event [" + event + "]", e);
- return iaList;
- }
- }
+ LoginAuthenticator loginAuthenticator = null;
- return iaList;
+ if (username != null) {
+ loginAuthenticator = new LoginAuthenticator(username, password);
+ props.put("mail.smtp.auth", "true");
}
- /**
- * Returns value of the <b>toList</b> option.
- */
- public List<PatternLayoutBase<E>> getToList() {
- return toPatternLayoutList;
+ if (isSTARTTLS() && isSSL()) {
+ addError("Both SSL and StartTLS cannot be enabled simultaneously");
+ } else {
+ if (isSTARTTLS()) {
+ // see also http://jira.qos.ch/browse/LBCORE-225
+ props.put("mail.smtp.starttls.enable", "true");
+ }
+ if (isSSL()) {
+ String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
+ props.put("mail.smtp.socketFactory.port", Integer.toString(smtpPort));
+ props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
+ props.put("mail.smtp.socketFactory.fallback", "true");
+ }
}
- /**
- * Send the contents of the cyclic buffer as an e-mail message.
- */
- protected void sendBuffer(CyclicBuffer<E> cb, E lastEventObject) {
-
- // Note: this code already owns the monitor for this
- // appender. This frees us from needing to synchronize on 'cb'.
- try {
- MimeBodyPart part = new MimeBodyPart();
-
- StringBuffer sbuf = new StringBuffer();
-
- String header = layout.getFileHeader();
- if (header != null) {
- sbuf.append(header);
- }
- String presentationHeader = layout.getPresentationHeader();
- if (presentationHeader != null) {
- sbuf.append(presentationHeader);
- }
- fillBuffer(cb, sbuf);
- String presentationFooter = layout.getPresentationFooter();
- if (presentationFooter != null) {
- sbuf.append(presentationFooter);
- }
- String footer = layout.getFileFooter();
- if (footer != null) {
- sbuf.append(footer);
- }
-
- String subjectStr = "Undefined subject";
- if (subjectLayout != null) {
- subjectStr = subjectLayout.doLayout(lastEventObject);
-
- // The subject must not contain new-line characters, which cause
- // an SMTP error (LOGBACK-865). Truncate the string at the first
- // new-line character.
- int newLinePos = (subjectStr != null) ? subjectStr.indexOf('\n') : -1;
- if (newLinePos > -1) {
- subjectStr = subjectStr.substring(0, newLinePos);
- }
- }
-
- MimeMessage mimeMsg = new MimeMessage(session);
-
- if (from != null) {
- mimeMsg.setFrom(getAddress(from));
- } else {
- mimeMsg.setFrom();
- }
-
- mimeMsg.setSubject(subjectStr, charsetEncoding);
-
- List<InternetAddress> destinationAddresses = parseAddress(lastEventObject);
- if (destinationAddresses.isEmpty()) {
- addInfo("Empty destination address. Aborting email transmission");
- return;
- }
-
- InternetAddress[] toAddressArray = destinationAddresses.toArray(EMPTY_IA_ARRAY);
- mimeMsg.setRecipients(Message.RecipientType.TO, toAddressArray);
-
- String contentType = layout.getContentType();
-
- if (ContentTypeUtil.isTextual(contentType)) {
- part.setText(sbuf.toString(), charsetEncoding, ContentTypeUtil.getSubType(contentType));
- } else {
- part.setContent(sbuf.toString(), layout.getContentType());
- }
-
- Multipart mp = new MimeMultipart();
- mp.addBodyPart(part);
- mimeMsg.setContent(mp);
-
- mimeMsg.setSentDate(new Date());
- addInfo("About to send out SMTP message \"" + subjectStr + "\" to " + Arrays.toString(toAddressArray));
- Transport.send(mimeMsg);
- } catch (Exception e) {
- addError("Error occurred while sending e-mail notification.", e);
- }
- }
+ // props.put("mail.debug", "true");
- abstract protected void fillBuffer(CyclicBuffer<E> cb, StringBuffer sbuf);
+ return Session.getInstance(props, loginAuthenticator);
+ }
- /**
- * Returns value of the <b>From</b> option.
- */
- public String getFrom() {
- return from;
- }
+ /**
+ * Perform SMTPAppender specific appending actions, delegating some of them to
+ * a subclass and checking if the event triggers an e-mail to be sent.
+ */
+ protected void append(E eventObject) {
- /**
- * Returns value of the <b>Subject</b> option.
- */
- public String getSubject() {
- return subjectStr;
+ if (!checkEntryConditions()) {
+ return;
}
- /**
- * The <b>From</b> option takes a string value which should be a e-mail
- * address of the sender.
- */
- public void setFrom(String from) {
- this.from = from;
- }
+ String key = discriminator.getDiscriminatingValue(eventObject);
+ long now = System.currentTimeMillis();
+ final CyclicBuffer<E> cb = cbTracker.getOrCreate(key, now);
+ subAppend(cb, eventObject);
- /**
- * The <b>Subject</b> option takes a string value which should be a the
- * subject of the e-mail message.
- */
- public void setSubject(String subject) {
- this.subjectStr = subject;
- }
-
- /**
- * Alias for smtpHost
- *
- * @param smtpHost
- */
- public void setSMTPHost(String smtpHost) {
- setSmtpHost(smtpHost);
- }
-
- /**
- * The <b>smtpHost</b> option takes a string value which should be a the host
- * name of the SMTP server that will send the e-mail message.
- */
- public void setSmtpHost(String smtpHost) {
- this.smtpHost = smtpHost;
- }
-
- /**
- * Alias for getSmtpHost().
- */
- public String getSMTPHost() {
- return getSmtpHost();
- }
-
- /**
- * Returns value of the <b>SMTPHost</b> option.
- */
- public String getSmtpHost() {
- return smtpHost;
- }
-
- /**
- * Alias for {@link #setSmtpPort}.
- *
- * @param port
- */
- public void setSMTPPort(int port) {
- setSmtpPort(port);
- }
+ try {
+ if (eventEvaluator.evaluate(eventObject)) {
+ // clone the CyclicBuffer before sending out asynchronously
+ CyclicBuffer<E> cbClone = new CyclicBuffer<E>(cb);
+ // see http://jira.qos.ch/browse/LBCLASSIC-221
+ cb.clear();
- /**
- * The port where the SMTP server is running. Default value is 25.
- *
- * @param port
- */
- public void setSmtpPort(int port) {
- this.smtpPort = port;
- }
-
- /**
- * Alias for {@link #getSmtpPort}
- *
- * @return
- */
- public int getSMTPPort() {
- return getSmtpPort();
- }
-
- /**
- * See {@link #setSmtpPort}
- *
- * @return
- */
- public int getSmtpPort() {
- return smtpPort;
- }
-
- public String getLocalhost() {
- return localhost;
- }
-
- /**
- * Set the "mail.smtp.localhost" property to the value passed as parameter to
- * this method.
- * <p/>
- * <p>Useful in case the hostname for the client host is not fully qualified
- * and as a consequence the SMTP server rejects the clients HELO/EHLO command.
- * </p>
- *
- * @param localhost
- */
- public void setLocalhost(String localhost) {
- this.localhost = localhost;
- }
-
- public CyclicBufferTracker<E> getCyclicBufferTracker() {
- return cbTracker;
- }
-
- public void setCyclicBufferTracker(CyclicBufferTracker<E> cbTracker) {
- this.cbTracker = cbTracker;
- }
-
- public Discriminator<E> getDiscriminator() {
- return discriminator;
- }
-
- public void setDiscriminator(Discriminator<E> discriminator) {
- this.discriminator = discriminator;
- }
-
- public boolean isAsynchronousSending() {
- return asynchronousSending;
- }
-
- /**
- * By default, SMTAppender transmits emails asynchronously. For synchronous email transmission set
- * asynchronousSending to 'false'.
- *
- * @param asynchronousSending determines whether sending is done asynchronously or not
- * @since 1.0.4
- */
- public void setAsynchronousSending(boolean asynchronousSending) {
- this.asynchronousSending = asynchronousSending;
- }
-
- public void addTo(String to) {
- if (to == null || to.length() == 0) {
- throw new IllegalArgumentException("Null or empty <to> property");
- }
- PatternLayoutBase plb = makeNewToPatternLayout(to.trim());
- plb.setContext(context);
- plb.start();
- this.toPatternLayoutList.add(plb);
- }
-
- abstract protected PatternLayoutBase<E> makeNewToPatternLayout(String toPattern);
-
- public List<String> getToAsListOfString() {
- List<String> toList = new ArrayList<String>();
- for (PatternLayoutBase plb : toPatternLayoutList) {
- toList.add(plb.getPattern());
+ if (asynchronousSending) {
+ // perform actual sending asynchronously
+ SenderRunnable senderRunnable = new SenderRunnable(cbClone, eventObject);
+ context.getExecutorService().execute(senderRunnable);
+ } else {
+ // synchronous sending
+ sendBuffer(cbClone, eventObject);
}
- return toList;
- }
-
- public boolean isSTARTTLS() {
- return starttls;
+ }
+ } catch (EvaluationException ex) {
+ errorCount++;
+ if (errorCount < CoreConstants.MAX_ERROR_COUNT) {
+ addError("SMTPAppender's EventEvaluator threw an Exception-", ex);
+ }
}
- public void setSTARTTLS(boolean startTLS) {
- this.starttls = startTLS;
+ // immediately remove the buffer if asked by the user
+ if (eventMarksEndOfLife(eventObject)) {
+ cbTracker.endOfLife(key);
}
- public boolean isSSL() {
- return ssl;
- }
+ cbTracker.removeStaleComponents(now);
- public void setSSL(boolean ssl) {
- this.ssl = ssl;
+ if (lastTrackerStatusPrint + delayBetweenStatusMessages < now) {
+ addInfo("SMTPAppender [" + name + "] is tracking [" + cbTracker.getComponentCount() + "] buffers");
+ lastTrackerStatusPrint = now;
+ // quadruple 'delay' assuming less than max delay
+ if (delayBetweenStatusMessages < MAX_DELAY_BETWEEN_STATUS_MESSAGES) {
+ delayBetweenStatusMessages *= 4;
+ }
}
+ }
- /**
- * The <b>EventEvaluator</b> option takes a string value representing the name
- * of the class implementing the {@link EventEvaluator} interface. A
- * corresponding object will be instantiated and assigned as the event
- * evaluator for the SMTPAppender.
- */
- public void setEvaluator(EventEvaluator<E> eventEvaluator) {
- this.eventEvaluator = eventEvaluator;
- }
+ abstract protected boolean eventMarksEndOfLife(E eventObject);
- public String getUsername() {
- return username;
- }
+ abstract protected void subAppend(CyclicBuffer<E> cb, E eventObject);
- public void setUsername(String username) {
- this.username = username;
+ /**
+ * This method determines if there is a sense in attempting to append.
+ * <p/>
+ * <p/>
+ * It checks whether there is a set output target and also if there is a set
+ * layout. If these checks fail, then the boolean value <code>false</code> is
+ * returned.
+ */
+ public boolean checkEntryConditions() {
+ if (!this.started) {
+ addError("Attempting to append to a non-started appender: "
+ + this.getName());
+ return false;
}
- public String getPassword() {
- return password;
+ if (this.mimeMsg == null) {
+ addError("Message object not configured.");
+ return false;
}
- public void setPassword(String password) {
- this.password = password;
+ if (this.eventEvaluator == null) {
+ addError("No EventEvaluator is set for appender [" + name + "].");
+ return false;
}
- /**
- * @return the charset encoding value
- * @see #setCharsetEncoding(String)
- */
- public String getCharsetEncoding() {
- return charsetEncoding;
+ if (this.layout == null) {
+ addError("No layout set for appender named ["
+ + name
+ + "]. For more information, please visit http://logback.qos.ch/codes.html#smtp_no_layout");
+ return false;
}
+ return true;
+ }
- public String getJndiLocation() {
- return jndiLocation;
- }
+ synchronized public void stop() {
+ this.started = false;
+ }
- /**
- * Set the location where a {@link javax.mail.Session} resource is located in JNDI. Default value is
- * "java:comp/env/mail/Session".
- *
- * @param jndiLocation
- * @since 1.0.6
- */
- public void setJndiLocation(String jndiLocation) {
- this.jndiLocation = jndiLocation;
+ InternetAddress getAddress(String addressStr) {
+ try {
+ return new InternetAddress(addressStr);
+ } catch (AddressException e) {
+ addError("Could not parse address [" + addressStr + "].", e);
+ return null;
}
+ }
- public boolean isSessionViaJNDI() {
- return sessionViaJNDI;
- }
+ private List<InternetAddress> parseAddress(E event) {
+ int len = toPatternLayoutList.size();
- /**
- * If set to true, a {@link javax.mail.Session} resource will be retrieved from JNDI. Default is false.
- *
- * @param sessionViaJNDI whether to obtain a javax.mail.Session by JNDI
- * @since 1.0.6
- */
- public void setSessionViaJNDI(boolean sessionViaJNDI) {
- this.sessionViaJNDI = sessionViaJNDI;
- }
+ List<InternetAddress> iaList = new ArrayList<InternetAddress>();
- /**
- * Set the character set encoding of the outgoing email messages. The default
- * encoding is "UTF-8" which usually works well for most purposes.
- *
- * @param charsetEncoding
- */
- public void setCharsetEncoding(String charsetEncoding) {
- this.charsetEncoding = charsetEncoding;
- }
-
- public Layout<E> getLayout() {
- return layout;
- }
-
- public void setLayout(Layout<E> layout) {
- this.layout = layout;
- }
-
- class SenderRunnable implements Runnable {
-
- final CyclicBuffer<E> cyclicBuffer;
- final E e;
-
- SenderRunnable(CyclicBuffer<E> cyclicBuffer, E e) {
- this.cyclicBuffer = cyclicBuffer;
- this.e = e;
+ for (int i = 0; i < len; i++) {
+ try {
+ PatternLayoutBase<E> emailPL = toPatternLayoutList.get(i);
+ String emailAdrr = emailPL.doLayout(event);
+ if (emailAdrr == null || emailAdrr.length() == 0) {
+ continue;
}
-
- public void run() {
- sendBuffer(cyclicBuffer, e);
+ InternetAddress[] tmp = InternetAddress.parse(emailAdrr, true);
+ iaList.addAll(Arrays.asList(tmp));
+ } catch (AddressException e) {
+ addError("Could not parse email address for [" + toPatternLayoutList.get(i) + "] for event [" + event + "]", e);
+ return iaList;
+ }
+ }
+
+ return iaList;
+ }
+
+ /**
+ * Returns value of the <b>toList</b> option.
+ */
+ public List<PatternLayoutBase<E>> getToList() {
+ return toPatternLayoutList;
+ }
+
+ /**
+ * Send the contents of the cyclic buffer as an e-mail message.
+ */
+ protected void sendBuffer(CyclicBuffer<E> cb, E lastEventObject) {
+
+ // Note: this code already owns the monitor for this
+ // appender. This frees us from needing to synchronize on 'cb'.
+ try {
+ MimeBodyPart part = new MimeBodyPart();
+
+ StringBuffer sbuf = new StringBuffer();
+
+ String header = layout.getFileHeader();
+ if (header != null) {
+ sbuf.append(header);
+ }
+ String presentationHeader = layout.getPresentationHeader();
+ if (presentationHeader != null) {
+ sbuf.append(presentationHeader);
+ }
+ fillBuffer(cb, sbuf);
+ String presentationFooter = layout.getPresentationFooter();
+ if (presentationFooter != null) {
+ sbuf.append(presentationFooter);
+ }
+ String footer = layout.getFileFooter();
+ if (footer != null) {
+ sbuf.append(footer);
+ }
+
+ String subjectStr = "Undefined subject";
+ if (subjectLayout != null) {
+ subjectStr = subjectLayout.doLayout(lastEventObject);
+
+ // The subject must not contain new-line characters, which cause
+ // an SMTP error (LOGBACK-865). Truncate the string at the first
+ // new-line character.
+ int newLinePos = (subjectStr != null) ? subjectStr.indexOf('\n') : -1;
+ if (newLinePos > -1) {
+ subjectStr = subjectStr.substring(0, newLinePos);
}
- }
+ }
+ mimeMsg.setSubject(subjectStr, charsetEncoding);
+
+ List<InternetAddress> destinationAddresses = parseAddress(lastEventObject);
+ if (destinationAddresses.isEmpty()) {
+ addInfo("Empty destination address. Aborting email transmission");
+ return;
+ }
+
+ InternetAddress[] toAddressArray = destinationAddresses.toArray(EMPTY_IA_ARRAY);
+ mimeMsg.setRecipients(Message.RecipientType.TO, toAddressArray);
+
+ String contentType = layout.getContentType();
+
+ if (ContentTypeUtil.isTextual(contentType)) {
+ part.setText(sbuf.toString(), charsetEncoding, ContentTypeUtil
+ .getSubType(contentType));
+ } else {
+ part.setContent(sbuf.toString(), layout.getContentType());
+ }
+
+ Multipart mp = new MimeMultipart();
+ mp.addBodyPart(part);
+ mimeMsg.setContent(mp);
+
+ mimeMsg.setSentDate(new Date());
+ addInfo("About to send out SMTP message \"" + subjectStr + "\" to " + Arrays.toString(toAddressArray));
+ Transport.send(mimeMsg);
+ } catch (Exception e) {
+ addError("Error occurred while sending e-mail notification.", e);
+ }
+ }
+
+ abstract protected void fillBuffer(CyclicBuffer<E> cb, StringBuffer sbuf);
+
+ /**
+ * Returns value of the <b>From</b> option.
+ */
+ public String getFrom() {
+ return from;
+ }
+
+ /**
+ * Returns value of the <b>Subject</b> option.
+ */
+ public String getSubject() {
+ return subjectStr;
+ }
+
+ /**
+ * The <b>From</b> option takes a string value which should be a e-mail
+ * address of the sender.
+ */
+ public void setFrom(String from) {
+ this.from = from;
+ }
+
+ /**
+ * The <b>Subject</b> option takes a string value which should be a the
+ * subject of the e-mail message.
+ */
+ public void setSubject(String subject) {
+ this.subjectStr = subject;
+ }
+
+ /**
+ * Alias for smtpHost
+ *
+ * @param smtpHost
+ */
+ public void setSMTPHost(String smtpHost) {
+ setSmtpHost(smtpHost);
+ }
+
+ /**
+ * The <b>smtpHost</b> option takes a string value which should be a the host
+ * name of the SMTP server that will send the e-mail message.
+ */
+ public void setSmtpHost(String smtpHost) {
+ this.smtpHost = smtpHost;
+ }
+
+ /**
+ * Alias for getSmtpHost().
+ */
+ public String getSMTPHost() {
+ return getSmtpHost();
+ }
+
+ /**
+ * Returns value of the <b>SMTPHost</b> option.
+ */
+ public String getSmtpHost() {
+ return smtpHost;
+ }
+
+ /**
+ * Alias for {@link #setSmtpPort}.
+ *
+ * @param port
+ */
+ public void setSMTPPort(int port) {
+ setSmtpPort(port);
+ }
+
+ /**
+ * The port where the SMTP server is running. Default value is 25.
+ *
+ * @param port
+ */
+ public void setSmtpPort(int port) {
+ this.smtpPort = port;
+ }
+
+ /**
+ * Alias for {@link #getSmtpPort}
+ *
+ * @return
+ */
+ public int getSMTPPort() {
+ return getSmtpPort();
+ }
+
+ /**
+ * See {@link #setSmtpPort}
+ *
+ * @return
+ */
+ public int getSmtpPort() {
+ return smtpPort;
+ }
+
+ public String getLocalhost() {
+ return localhost;
+ }
+
+ /**
+ * Set the "mail.smtp.localhost" property to the value passed as parameter to
+ * this method.
+ * <p/>
+ * <p>Useful in case the hostname for the client host is not fully qualified
+ * and as a consequence the SMTP server rejects the clients HELO/EHLO command.
+ * </p>
+ *
+ * @param localhost
+ */
+ public void setLocalhost(String localhost) {
+ this.localhost = localhost;
+ }
+
+ public CyclicBufferTracker<E> getCyclicBufferTracker() {
+ return cbTracker;
+ }
+
+ public void setCyclicBufferTracker(CyclicBufferTracker<E> cbTracker) {
+ this.cbTracker = cbTracker;
+ }
+
+ public Discriminator<E> getDiscriminator() {
+ return discriminator;
+ }
+
+ public void setDiscriminator(Discriminator<E> discriminator) {
+ this.discriminator = discriminator;
+ }
+
+ public boolean isAsynchronousSending() {
+ return asynchronousSending;
+ }
+
+ /**
+ * By default, SMTAppender transmits emails asynchronously. For synchronous email transmission set
+ * asynchronousSending to 'false'.
+ *
+ * @param asynchronousSending determines whether sending is done asynchronously or not
+ * @since 1.0.4
+ */
+ public void setAsynchronousSending(boolean asynchronousSending) {
+ this.asynchronousSending = asynchronousSending;
+ }
+
+ public void addTo(String to) {
+ if (to == null || to.length() == 0) {
+ throw new IllegalArgumentException("Null or empty <to> property");
+ }
+ PatternLayoutBase plb = makeNewToPatternLayout(to.trim());
+ plb.setContext(context);
+ plb.start();
+ this.toPatternLayoutList.add(plb);
+ }
+
+ abstract protected PatternLayoutBase<E> makeNewToPatternLayout(String toPattern);
+
+ public List<String> getToAsListOfString() {
+ List<String> toList = new ArrayList<String>();
+ for (PatternLayoutBase plb : toPatternLayoutList) {
+ toList.add(plb.getPattern());
+ }
+ return toList;
+ }
+
+ // for testing purpose only
+ public Message getMessage() {
+ return mimeMsg;
+ }
+
+ // for testing purpose only
+
+ public void setMessage(MimeMessage msg) {
+ this.mimeMsg = msg;
+ }
+
+ public boolean isSTARTTLS() {
+ return starttls;
+ }
+
+ public void setSTARTTLS(boolean startTLS) {
+ this.starttls = startTLS;
+ }
+
+ public boolean isSSL() {
+ return ssl;
+ }
+
+ public void setSSL(boolean ssl) {
+ this.ssl = ssl;
+ }
+
+ /**
+ * The <b>EventEvaluator</b> option takes a string value representing the name
+ * of the class implementing the {@link EventEvaluator} interface. A
+ * corresponding object will be instantiated and assigned as the event
+ * evaluator for the SMTPAppender.
+ */
+ public void setEvaluator(EventEvaluator<E> eventEvaluator) {
+ this.eventEvaluator = eventEvaluator;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ /**
+ * @return the charset encoding value
+ * @see #setCharsetEncoding(String)
+ */
+ public String getCharsetEncoding() {
+ return charsetEncoding;
+ }
+
+
+ public String getJndiLocation() {
+ return jndiLocation;
+ }
+
+ /**
+ * Set the location where a {@link javax.mail.Session} resource is located in JNDI. Default value is
+ * "java:comp/env/mail/Session".
+ *
+ * @param jndiLocation
+ * @since 1.0.6
+ */
+ public void setJndiLocation(String jndiLocation) {
+ this.jndiLocation = jndiLocation;
+ }
+
+ public boolean isSessionViaJNDI() {
+ return sessionViaJNDI;
+ }
+
+ /**
+ * If set to true, a {@link javax.mail.Session} resource will be retrieved from JNDI. Default is false.
+ *
+ * @param sessionViaJNDI whether to obtain a javax.mail.Session by JNDI
+ * @since 1.0.6
+ */
+ public void setSessionViaJNDI(boolean sessionViaJNDI) {
+ this.sessionViaJNDI = sessionViaJNDI;
+ }
+
+ /**
+ * Set the character set encoding of the outgoing email messages. The default
+ * encoding is "UTF-8" which usually works well for most purposes.
+ *
+ * @param charsetEncoding
+ */
+ public void setCharsetEncoding(String charsetEncoding) {
+ this.charsetEncoding = charsetEncoding;
+ }
+
+ public Layout<E> getLayout() {
+ return layout;
+ }
+
+ public void setLayout(Layout<E> layout) {
+ this.layout = layout;
+ }
+
+ class SenderRunnable implements Runnable {
+
+ final CyclicBuffer<E> cyclicBuffer;
+ final E e;
+
+ SenderRunnable(CyclicBuffer<E> cyclicBuffer, E e) {
+ this.cyclicBuffer = cyclicBuffer;
+ this.e = e;
+ }
+
+ public void run() {
+ sendBuffer(cyclicBuffer, e);
+ }
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/SocketConnector.java b/logback-core/src/main/java/ch/qos/logback/core/net/SocketConnector.java
index 9542210..5ddd52b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/SocketConnector.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/SocketConnector.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,38 +28,38 @@ import javax.net.SocketFactory;
*/
public interface SocketConnector extends Callable<Socket> {
- /**
- * An exception handler that is notified of all exceptions that occur
- * during the (re)connection process.
- */
- public interface ExceptionHandler {
- void connectionFailed(SocketConnector connector, Exception ex);
- }
-
- /**
- * Blocks the calling thread until a connection is successfully
- * established.
- * @return the connected socket
- * @throws InterruptedException
- */
- Socket call() throws InterruptedException;
-
- /**
- * Sets the connector's exception handler.
- * <p>
- * The handler must be set before the {@link #call()} method is invoked.
- * @param exceptionHandler the handler to set
- */
- void setExceptionHandler(ExceptionHandler exceptionHandler);
-
- /**
- * Sets the connector's socket factory.
- * <p>
- * If no factory is configured that connector will use the platform's
- * default factory.
- *
- * @param socketFactory the factory to set
- */
- void setSocketFactory(SocketFactory socketFactory);
+ /**
+ * An exception handler that is notified of all exceptions that occur
+ * during the (re)connection process.
+ */
+ public interface ExceptionHandler {
+ void connectionFailed(SocketConnector connector, Exception ex);
+ }
+
+ /**
+ * Blocks the calling thread until a connection is successfully
+ * established.
+ * @return the connected socket
+ * @throws InterruptedException
+ */
+ Socket call() throws InterruptedException;
+ /**
+ * Sets the connector's exception handler.
+ * <p>
+ * The handler must be set before the {@link #call()} method is invoked.
+ * @param exceptionHandler the handler to set
+ */
+ void setExceptionHandler(ExceptionHandler exceptionHandler);
+
+ /**
+ * Sets the connector's socket factory.
+ * <p>
+ * If no factory is configured that connector will use the platform's
+ * default factory.
+ *
+ * @param socketFactory the factory to set
+ */
+ void setSocketFactory(SocketFactory socketFactory);
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/SyslogAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/net/SyslogAppenderBase.java
index df16d9c..7f25479 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/SyslogAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/SyslogAppenderBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,7 +17,6 @@ import java.io.IOException;
import java.io.OutputStream;
import java.net.SocketException;
import java.net.UnknownHostException;
-import java.nio.charset.Charset;
import ch.qos.logback.core.AppenderBase;
import ch.qos.logback.core.CoreConstants;
@@ -32,277 +31,258 @@ import ch.qos.logback.core.Layout;
*/
public abstract class SyslogAppenderBase<E> extends AppenderBase<E> {
- final static String SYSLOG_LAYOUT_URL = CoreConstants.CODES_URL + "#syslog_layout";
- final static int MAX_MESSAGE_SIZE_LIMIT = 65000;
-
- Layout<E> layout;
- String facilityStr;
- String syslogHost;
- protected String suffixPattern;
- SyslogOutputStream sos;
- int port = SyslogConstants.SYSLOG_PORT;
- int maxMessageSize;
- Charset charset;
-
- public void start() {
- int errorCount = 0;
- if (facilityStr == null) {
- addError("The Facility option is mandatory");
- errorCount++;
- }
-
- if (charset == null) {
- // Using defaultCharset() preserves the previous behavior when String.getBytes() was
- // called without arguments
- charset = Charset.defaultCharset();
- }
-
- try {
- sos = createOutputStream();
-
- final int systemDatagramSize = sos.getSendBufferSize();
- if (maxMessageSize == 0) {
- maxMessageSize = Math.min(systemDatagramSize, MAX_MESSAGE_SIZE_LIMIT);
- addInfo("Defaulting maxMessageSize to [" + maxMessageSize + "]");
- } else if (maxMessageSize > systemDatagramSize) {
- addWarn("maxMessageSize of [" + maxMessageSize + "] is larger than the system defined datagram size of [" + systemDatagramSize + "].");
- addWarn("This may result in dropped logs.");
- }
- } catch (UnknownHostException e) {
- addError("Could not create SyslogWriter", e);
- errorCount++;
- } catch (SocketException e) {
- addWarn("Failed to bind to a random datagram socket. Will try to reconnect later.", e);
- }
-
- if (layout == null) {
- layout = buildLayout();
- }
-
- if (errorCount == 0) {
- super.start();
- }
- }
-
- abstract public SyslogOutputStream createOutputStream() throws UnknownHostException, SocketException;
-
- abstract public Layout<E> buildLayout();
-
- abstract public int getSeverityForEvent(Object eventObject);
-
- @Override
- protected void append(E eventObject) {
- if (!isStarted()) {
- return;
- }
-
- try {
- String msg = layout.doLayout(eventObject);
- if (msg == null) {
- return;
- }
- if (msg.length() > maxMessageSize) {
- msg = msg.substring(0, maxMessageSize);
- }
- sos.write(msg.getBytes(charset));
- sos.flush();
- postProcess(eventObject, sos);
- } catch (IOException ioe) {
- addError("Failed to send diagram to " + syslogHost, ioe);
- }
- }
-
- protected void postProcess(Object event, OutputStream sw) {
-
+ final static String SYSLOG_LAYOUT_URL = CoreConstants.CODES_URL
+ + "#syslog_layout";
+ final static int MAX_MESSAGE_SIZE_LIMIT = 65000;
+
+ Layout<E> layout;
+ String facilityStr;
+ String syslogHost;
+ protected String suffixPattern;
+ SyslogOutputStream sos;
+ int port = SyslogConstants.SYSLOG_PORT;
+ int maxMessageSize;
+
+ public void start() {
+ int errorCount = 0;
+ if (facilityStr == null) {
+ addError("The Facility option is mandatory");
+ errorCount++;
}
- /**
- * Returns the integer value corresponding to the named syslog facility.
- *
- * @throws IllegalArgumentException
- * if the facility string is not recognized
- */
- static public int facilityStringToint(String facilityStr) {
- if ("KERN".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_KERN;
- } else if ("USER".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_USER;
- } else if ("MAIL".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_MAIL;
- } else if ("DAEMON".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_DAEMON;
- } else if ("AUTH".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_AUTH;
- } else if ("SYSLOG".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_SYSLOG;
- } else if ("LPR".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_LPR;
- } else if ("NEWS".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_NEWS;
- } else if ("UUCP".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_UUCP;
- } else if ("CRON".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_CRON;
- } else if ("AUTHPRIV".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_AUTHPRIV;
- } else if ("FTP".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_FTP;
- } else if ("NTP".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_NTP;
- } else if ("AUDIT".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_AUDIT;
- } else if ("ALERT".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_ALERT;
- } else if ("CLOCK".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_CLOCK;
- } else if ("LOCAL0".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_LOCAL0;
- } else if ("LOCAL1".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_LOCAL1;
- } else if ("LOCAL2".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_LOCAL2;
- } else if ("LOCAL3".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_LOCAL3;
- } else if ("LOCAL4".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_LOCAL4;
- } else if ("LOCAL5".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_LOCAL5;
- } else if ("LOCAL6".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_LOCAL6;
- } else if ("LOCAL7".equalsIgnoreCase(facilityStr)) {
- return SyslogConstants.LOG_LOCAL7;
- } else {
- throw new IllegalArgumentException(facilityStr + " is not a valid syslog facility string");
- }
+ try {
+ sos = createOutputStream();
+
+ final int systemDatagramSize = sos.getSendBufferSize();
+ if (maxMessageSize == 0) {
+ maxMessageSize = Math.min(systemDatagramSize, MAX_MESSAGE_SIZE_LIMIT);
+ addInfo("Defaulting maxMessageSize to [" + maxMessageSize + "]");
+ } else if (maxMessageSize > systemDatagramSize) {
+ addWarn("maxMessageSize of [" + maxMessageSize + "] is larger than the system defined datagram size of [" + systemDatagramSize + "].");
+ addWarn("This may result in dropped logs.");
+ }
+ } catch (UnknownHostException e) {
+ addError("Could not create SyslogWriter", e);
+ errorCount++;
+ } catch (SocketException e) {
+ addWarn(
+ "Failed to bind to a random datagram socket. Will try to reconnect later.",
+ e);
}
- /**
- * Returns the value of the <b>SyslogHost</b> option.
- */
- public String getSyslogHost() {
- return syslogHost;
+ if (layout == null) {
+ layout = buildLayout();
}
- /**
- * The <b>SyslogHost</b> option is the name of the the syslog host where log
- * output should go.
- *
- * <b>WARNING</b> If the SyslogHost is not set, then this appender will fail.
- */
- public void setSyslogHost(String syslogHost) {
- this.syslogHost = syslogHost;
+ if (errorCount == 0) {
+ super.start();
}
+ }
- /**
- * Returns the string value of the <b>Facility</b> option.
- *
- * See {@link #setFacility} for the set of allowed values.
- */
- public String getFacility() {
- return facilityStr;
- }
-
- /**
- * The <b>Facility</b> option must be set one of the strings KERN, USER, MAIL,
- * DAEMON, AUTH, SYSLOG, LPR, NEWS, UUCP, CRON, AUTHPRIV, FTP, NTP, AUDIT,
- * ALERT, CLOCK, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6,
- * LOCAL7. Case is not important.
- *
- * <p>
- * See {@link SyslogConstants} and RFC 3164 for more information about the
- * <b>Facility</b> option.
- */
- public void setFacility(String facilityStr) {
- if (facilityStr != null) {
- facilityStr = facilityStr.trim();
- }
- this.facilityStr = facilityStr;
- }
-
- /**
- *
- * @return
- */
- public int getPort() {
- return port;
- }
-
- /**
- * The port number on the syslog server to connect to. Normally, you would not
- * want to change the default value, that is 514.
- */
- public void setPort(int port) {
- this.port = port;
- }
-
- /**
- *
- * @return
- */
- public int getMaxMessageSize() {
- return maxMessageSize;
- }
+ abstract public SyslogOutputStream createOutputStream() throws UnknownHostException, SocketException;
- /**
- * Maximum size for the syslog message (in characters); messages
- * longer than this are truncated. The default value is 65400 (which
- * is near the maximum for syslog-over-UDP). Note that the value is
- * characters; the number of bytes may vary if non-ASCII characters
- * are present.
- */
- public void setMaxMessageSize(int maxMessageSize) {
- this.maxMessageSize = maxMessageSize;
- }
+ abstract public Layout<E> buildLayout();
- public Layout<E> getLayout() {
- return layout;
- }
+ abstract public int getSeverityForEvent(Object eventObject);
- public void setLayout(Layout<E> layout) {
- addWarn("The layout of a SyslogAppender cannot be set directly. See also " + SYSLOG_LAYOUT_URL);
+ @Override
+ protected void append(E eventObject) {
+ if (!isStarted()) {
+ return;
}
- @Override
- public void stop() {
- if (sos != null) {
- sos.close();
- }
- super.stop();
+ try {
+ String msg = layout.doLayout(eventObject);
+ if(msg == null) {
+ return;
+ }
+ if (msg.length() > maxMessageSize) {
+ msg = msg.substring(0, maxMessageSize);
+ }
+ sos.write(msg.getBytes());
+ sos.flush();
+ postProcess(eventObject, sos);
+ } catch (IOException ioe) {
+ addError("Failed to send diagram to " + syslogHost, ioe);
}
-
- /**
- * See {@link #setSuffixPattern(String).
- *
- * @return
- */
- public String getSuffixPattern() {
- return suffixPattern;
+ }
+
+ protected void postProcess(Object event, OutputStream sw) {
+
+ }
+
+ /**
+ * Returns the integer value corresponding to the named syslog facility.
+ *
+ * @throws IllegalArgumentException
+ * if the facility string is not recognized
+ */
+ static public int facilityStringToint(String facilityStr) {
+ if ("KERN".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_KERN;
+ } else if ("USER".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_USER;
+ } else if ("MAIL".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_MAIL;
+ } else if ("DAEMON".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_DAEMON;
+ } else if ("AUTH".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_AUTH;
+ } else if ("SYSLOG".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_SYSLOG;
+ } else if ("LPR".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_LPR;
+ } else if ("NEWS".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_NEWS;
+ } else if ("UUCP".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_UUCP;
+ } else if ("CRON".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_CRON;
+ } else if ("AUTHPRIV".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_AUTHPRIV;
+ } else if ("FTP".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_FTP;
+ } else if ("NTP".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_NTP;
+ } else if ("AUDIT".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_AUDIT;
+ } else if ("ALERT".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_ALERT;
+ } else if ("CLOCK".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_CLOCK;
+ } else if ("LOCAL0".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_LOCAL0;
+ } else if ("LOCAL1".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_LOCAL1;
+ } else if ("LOCAL2".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_LOCAL2;
+ } else if ("LOCAL3".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_LOCAL3;
+ } else if ("LOCAL4".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_LOCAL4;
+ } else if ("LOCAL5".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_LOCAL5;
+ } else if ("LOCAL6".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_LOCAL6;
+ } else if ("LOCAL7".equalsIgnoreCase(facilityStr)) {
+ return SyslogConstants.LOG_LOCAL7;
+ } else {
+ throw new IllegalArgumentException(facilityStr
+ + " is not a valid syslog facility string");
}
-
- /**
- * The <b>suffixPattern</b> option specifies the format of the
- * non-standardized part of the message sent to the syslog server.
- *
- * @param suffixPattern
- */
- public void setSuffixPattern(String suffixPattern) {
- this.suffixPattern = suffixPattern;
+ }
+
+ /**
+ * Returns the value of the <b>SyslogHost</b> option.
+ */
+ public String getSyslogHost() {
+ return syslogHost;
+ }
+
+ /**
+ * The <b>SyslogHost</b> option is the name of the the syslog host where log
+ * output should go.
+ *
+ * <b>WARNING</b> If the SyslogHost is not set, then this appender will fail.
+ */
+ public void setSyslogHost(String syslogHost) {
+ this.syslogHost = syslogHost;
+ }
+
+ /**
+ * Returns the string value of the <b>Facility</b> option.
+ *
+ * See {@link #setFacility} for the set of allowed values.
+ */
+ public String getFacility() {
+ return facilityStr;
+ }
+
+ /**
+ * The <b>Facility</b> option must be set one of the strings KERN, USER, MAIL,
+ * DAEMON, AUTH, SYSLOG, LPR, NEWS, UUCP, CRON, AUTHPRIV, FTP, NTP, AUDIT,
+ * ALERT, CLOCK, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6,
+ * LOCAL7. Case is not important.
+ *
+ * <p>
+ * See {@link SyslogConstants} and RFC 3164 for more information about the
+ * <b>Facility</b> option.
+ */
+ public void setFacility(String facilityStr) {
+ if (facilityStr != null) {
+ facilityStr = facilityStr.trim();
}
-
- /**
- * Returns the Charset used to encode String messages into byte sequences when writing to
- * syslog.
- */
- public Charset getCharset() {
- return charset;
+ this.facilityStr = facilityStr;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * The port number on the syslog server to connect to. Normally, you would not
+ * want to change the default value, that is 514.
+ */
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public int getMaxMessageSize() {
+ return maxMessageSize;
+ }
+
+ /**
+ * Maximum size for the syslog message (in characters); messages
+ * longer than this are truncated. The default value is 65400 (which
+ * is near the maximum for syslog-over-UDP). Note that the value is
+ * characters; the number of bytes may vary if non-ASCII characters
+ * are present.
+ */
+ public void setMaxMessageSize(int maxMessageSize) {
+ this.maxMessageSize = maxMessageSize;
+ }
+
+ public Layout<E> getLayout() {
+ return layout;
+ }
+
+ public void setLayout(Layout<E> layout) {
+ addWarn("The layout of a SyslogAppender cannot be set directly. See also "
+ + SYSLOG_LAYOUT_URL);
+ }
+
+ @Override
+ public void stop() {
+ if (sos != null) {
+ sos.close();
}
+ super.stop();
+ }
- /**
- * The Charset to use when encoding messages into byte sequences.
- *
- * @param charset
- */
- public void setCharset(Charset charset) {
- this.charset = charset;
- }
+/**
+ * See {@link #setSuffixPattern(String).
+ *
+ * @return
+ */
+ public String getSuffixPattern() {
+ return suffixPattern;
+ }
+
+ /**
+ * The <b>suffixPattern</b> option specifies the format of the
+ * non-standardized part of the message sent to the syslog server.
+ *
+ * @param suffixPattern
+ */
+ public void setSuffixPattern(String suffixPattern) {
+ this.suffixPattern = suffixPattern;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/SyslogConstants.java b/logback-core/src/main/java/ch/qos/logback/core/net/SyslogConstants.java
index 077bf14..a9e7b09 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/SyslogConstants.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/SyslogConstants.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,76 +19,78 @@ package ch.qos.logback.core.net;
* @author Ceki Gülcü
**/
public class SyslogConstants {
+
+ static public final int SYSLOG_PORT = 514;
+
+
+ // Following constants extracted from RFC 3164, we multiply them by 8
+ // in order to precompute the facility part of PRI.
+ // See RFC 3164, Section 4.1.1 for exact details.
- static public final int SYSLOG_PORT = 514;
-
- // Following constants extracted from RFC 3164, we multiply them by 8
- // in order to precompute the facility part of PRI.
- // See RFC 3164, Section 4.1.1 for exact details.
-
- /** Emergency: system is unusable */
- public static final int EMERGENCY_SEVERITY = 0;
- /** Alert: action must be taken immediately */
- public static final int ALERT_SEVERITY = 1;
- /** Critical: critical conditions */
- public static final int CRITICAL_SEVERITY = 2;
- /** Error: error conditions */
- public static final int ERROR_SEVERITY = 3;
- /** Warning: warning conditions */
- public static final int WARNING_SEVERITY = 4;
- /** Notice: normal but significant condition */
- public static final int NOTICE_SEVERITY = 5;
- /** Informational: informational messages */
- public static final int INFO_SEVERITY = 6;
- /** Debug: debug-level messages */
- public static final int DEBUG_SEVERITY = 7;
-
- /** kernel messages, numerical code 0. */
- public static final int LOG_KERN = 0;
- /** user-level messages, numerical code 1. */
- public static final int LOG_USER = 1 << 3;
- /** mail system, numerical code 2. */
- public static final int LOG_MAIL = 2 << 3;
- /** system daemons, numerical code 3. */
- public static final int LOG_DAEMON = 3 << 3;
- /** security/authorization messages, numerical code 4. */
- public static final int LOG_AUTH = 4 << 3;
- /** messages generated internally by syslogd, numerical code 5. */
- public static final int LOG_SYSLOG = 5 << 3;
- /** line printer subsystem, numerical code 6. */
- public static final int LOG_LPR = 6 << 3;
- /** network news subsystem, numerical code 7. */
- public static final int LOG_NEWS = 7 << 3;
- /** UUCP subsystem, numerical code 8 */
- public static final int LOG_UUCP = 8 << 3;
- /** clock daemon, numerical code 9. */
- public static final int LOG_CRON = 9 << 3;
- /** security/authorization messages, numerical code 10. */
- public static final int LOG_AUTHPRIV = 10 << 3;
- /** ftp daemon, numerical code 11. */
- public static final int LOG_FTP = 11 << 3;
- /** NTP subsystem, numerical code 12. */
- public static final int LOG_NTP = 12 << 3;
- /** log audit, numerical code 13. */
- public static final int LOG_AUDIT = 13 << 3;
- /** log alert, numerical code 14. */
- public static final int LOG_ALERT = 14 << 3;
- /** clock daemon, numerical code 15. */
- public static final int LOG_CLOCK = 15 << 3;
- /** reserved for local use, numerical code 16. */
- public static final int LOG_LOCAL0 = 16 << 3;
- /** reserved for local use, numerical code 17. */
- public static final int LOG_LOCAL1 = 17 << 3;
- /** reserved for local use, numerical code 18. */
- public static final int LOG_LOCAL2 = 18 << 3;
- /** reserved for local use, numerical code 19. */
- public static final int LOG_LOCAL3 = 19 << 3;
- /** reserved for local use, numerical code 20. */
- public static final int LOG_LOCAL4 = 20 << 3;
- /** reserved for local use, numerical code 21. */
- public static final int LOG_LOCAL5 = 21 << 3;
- /** reserved for local use, numerical code 22. */
- public static final int LOG_LOCAL6 = 22 << 3;
- /** reserved for local use, numerical code 23.*/
- public static final int LOG_LOCAL7 = 23 << 3;
+ /** Emergency: system is unusable */
+ public static final int EMERGENCY_SEVERITY = 0;
+ /** Alert: action must be taken immediately */
+ public static final int ALERT_SEVERITY = 1;
+ /** Critical: critical conditions */
+ public static final int CRITICAL_SEVERITY = 2;
+ /** Error: error conditions */
+ public static final int ERROR_SEVERITY = 3;
+ /** Warning: warning conditions */
+ public static final int WARNING_SEVERITY = 4;
+ /** Notice: normal but significant condition */
+ public static final int NOTICE_SEVERITY = 5;
+ /** Informational: informational messages */
+ public static final int INFO_SEVERITY = 6;
+ /** Debug: debug-level messages */
+ public static final int DEBUG_SEVERITY = 7;
+
+
+ /** kernel messages, numerical code 0. */
+ public static final int LOG_KERN = 0;
+ /** user-level messages, numerical code 1. */
+ public static final int LOG_USER = 1 << 3;
+ /** mail system, numerical code 2. */
+ public static final int LOG_MAIL = 2 << 3;
+ /** system daemons, numerical code 3. */
+ public static final int LOG_DAEMON = 3 << 3;
+ /** security/authorization messages, numerical code 4. */
+ public static final int LOG_AUTH = 4 << 3;
+ /** messages generated internally by syslogd, numerical code 5. */
+ public static final int LOG_SYSLOG = 5 << 3;
+ /** line printer subsystem, numerical code 6. */
+ public static final int LOG_LPR = 6 << 3;
+ /** network news subsystem, numerical code 7. */
+ public static final int LOG_NEWS = 7 << 3;
+ /** UUCP subsystem, numerical code 8 */
+ public static final int LOG_UUCP = 8 << 3;
+ /** clock daemon, numerical code 9. */
+ public static final int LOG_CRON = 9 << 3;
+ /** security/authorization messages, numerical code 10. */
+ public static final int LOG_AUTHPRIV = 10 << 3;
+ /** ftp daemon, numerical code 11. */
+ public static final int LOG_FTP = 11 << 3;
+ /** NTP subsystem, numerical code 12. */
+ public static final int LOG_NTP = 12 << 3;
+ /** log audit, numerical code 13. */
+ public static final int LOG_AUDIT = 13 << 3;
+ /** log alert, numerical code 14. */
+ public static final int LOG_ALERT = 14 << 3;
+ /** clock daemon, numerical code 15. */
+ public static final int LOG_CLOCK = 15 << 3;
+ /** reserved for local use, numerical code 16. */
+ public static final int LOG_LOCAL0 = 16 << 3;
+ /** reserved for local use, numerical code 17. */
+ public static final int LOG_LOCAL1 = 17 << 3;
+ /** reserved for local use, numerical code 18. */
+ public static final int LOG_LOCAL2 = 18 << 3;
+ /** reserved for local use, numerical code 19. */
+ public static final int LOG_LOCAL3 = 19 << 3;
+ /** reserved for local use, numerical code 20. */
+ public static final int LOG_LOCAL4 = 20 << 3;
+ /** reserved for local use, numerical code 21. */
+ public static final int LOG_LOCAL5 = 21 << 3;
+ /** reserved for local use, numerical code 22. */
+ public static final int LOG_LOCAL6 = 22 << 3;
+ /** reserved for local use, numerical code 23.*/
+ public static final int LOG_LOCAL7 = 23 << 3;
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/SyslogOutputStream.java b/logback-core/src/main/java/ch/qos/logback/core/net/SyslogOutputStream.java
index cb72700..dbb12fe 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/SyslogOutputStream.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/SyslogOutputStream.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,64 +28,66 @@ import java.net.UnknownHostException;
*/
public class SyslogOutputStream extends OutputStream {
- /**
- * The maximum length after which we discard the existing string buffer and
- * start anew.
- */
- private static final int MAX_LEN = 1024;
+ /**
+ * The maximum length after which we discard the existing string buffer and
+ * start anew.
+ */
+ private static final int MAX_LEN = 1024;
- private InetAddress address;
- private DatagramSocket ds;
- private ByteArrayOutputStream baos = new ByteArrayOutputStream();
- final private int port;
+ private InetAddress address;
+ private DatagramSocket ds;
+ private ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final private int port;
- public SyslogOutputStream(String syslogHost, int port) throws UnknownHostException, SocketException {
- this.address = InetAddress.getByName(syslogHost);
- this.port = port;
- this.ds = new DatagramSocket();
- }
-
- public void write(byte[] byteArray, int offset, int len) throws IOException {
- baos.write(byteArray, offset, len);
- }
+ public SyslogOutputStream(String syslogHost, int port) throws UnknownHostException,
+ SocketException {
+ this.address = InetAddress.getByName(syslogHost);
+ this.port = port;
+ this.ds = new DatagramSocket();
+ }
- public void flush() throws IOException {
- byte[] bytes = baos.toByteArray();
- DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, port);
+ public void write(byte[] byteArray, int offset, int len) throws IOException {
+ baos.write(byteArray, offset, len);
+ }
- // clean up for next round
- if (baos.size() > MAX_LEN) {
- baos = new ByteArrayOutputStream();
- } else {
- baos.reset();
- }
-
- // after a failure, it can happen that bytes.length is zero
- // in that case, there is no point in sending out an empty message/
- if (bytes.length == 0) {
- return;
- }
- if (this.ds != null) {
- ds.send(packet);
- }
+ public void flush() throws IOException {
+ byte[] bytes = baos.toByteArray();
+ DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address,
+ port);
+ // clean up for next round
+ if (baos.size() > MAX_LEN) {
+ baos = new ByteArrayOutputStream();
+ } else {
+ baos.reset();
}
-
- public void close() {
- address = null;
- ds = null;
+
+ // after a failure, it can happen that bytes.length is zero
+ // in that case, there is no point in sending out an empty message/
+ if(bytes.length == 0) {
+ return;
}
-
- public int getPort() {
- return port;
+ if (this.ds != null) {
+ ds.send(packet);
}
+
+ }
- @Override
- public void write(int b) throws IOException {
- baos.write(b);
- }
+ public void close() {
+ address = null;
+ ds = null;
+ }
- int getSendBufferSize() throws SocketException {
- return ds.getSendBufferSize();
- }
+ public int getPort() {
+ return port;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ baos.write(b);
+ }
+
+ int getSendBufferSize() throws SocketException {
+ return ds.getSendBufferSize();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/server/AbstractServerSocketAppender.java b/logback-core/src/main/java/ch/qos/logback/core/net/server/AbstractServerSocketAppender.java
index 49a4959..768b2b2 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/server/AbstractServerSocketAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/server/AbstractServerSocketAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -35,181 +35,184 @@ import ch.qos.logback.core.spi.PreSerializationTransformer;
*/
public abstract class AbstractServerSocketAppender<E> extends AppenderBase<E> {
- /**
- * Default {@link ServerSocket} backlog
- */
- public static final int DEFAULT_BACKLOG = 50;
-
- /**
- * Default queue size used for each client
- */
- public static final int DEFAULT_CLIENT_QUEUE_SIZE = 100;
-
- private int port = AbstractSocketAppender.DEFAULT_PORT;
- private int backlog = DEFAULT_BACKLOG;
- private int clientQueueSize = DEFAULT_CLIENT_QUEUE_SIZE;
-
- private String address;
-
- private ServerRunner<RemoteReceiverClient> runner;
-
- @Override
- public void start() {
- if (isStarted())
- return;
- try {
- ServerSocket socket = getServerSocketFactory().createServerSocket(getPort(), getBacklog(), getInetAddress());
- ServerListener<RemoteReceiverClient> listener = createServerListener(socket);
-
- runner = createServerRunner(listener, getContext().getExecutorService());
- runner.setContext(getContext());
- getContext().getExecutorService().execute(runner);
- super.start();
- } catch (Exception ex) {
- addError("server startup error: " + ex, ex);
- }
+ /**
+ * Default {@link ServerSocket} backlog
+ */
+ public static final int DEFAULT_BACKLOG = 50;
+
+ /**
+ * Default queue size used for each client
+ */
+ public static final int DEFAULT_CLIENT_QUEUE_SIZE = 100;
+
+ private int port = AbstractSocketAppender.DEFAULT_PORT;
+ private int backlog = DEFAULT_BACKLOG;
+ private int clientQueueSize = DEFAULT_CLIENT_QUEUE_SIZE;
+
+ private String address;
+
+ private ServerRunner<RemoteReceiverClient> runner;
+
+ @Override
+ public void start() {
+ if (isStarted()) return;
+ try {
+ ServerSocket socket = getServerSocketFactory().createServerSocket(
+ getPort(), getBacklog(), getInetAddress());
+ ServerListener<RemoteReceiverClient> listener = createServerListener(socket);
+
+ runner = createServerRunner(listener, getContext().getExecutorService());
+ runner.setContext(getContext());
+ getContext().getExecutorService().execute(runner);
+ super.start();
+ } catch (Exception ex) {
+ addError("server startup error: " + ex, ex);
}
-
- protected ServerListener<RemoteReceiverClient> createServerListener(ServerSocket socket) {
- return new RemoteReceiverServerListener(socket);
- }
-
- protected ServerRunner<RemoteReceiverClient> createServerRunner(ServerListener<RemoteReceiverClient> listener, Executor executor) {
- return new RemoteReceiverServerRunner(listener, executor, getClientQueueSize());
- }
-
- @Override
- public void stop() {
- if (!isStarted())
- return;
- try {
- runner.stop();
- super.stop();
- } catch (IOException ex) {
- addError("server shutdown error: " + ex, ex);
- }
- }
-
- @Override
- protected void append(E event) {
- if (event == null)
- return;
- postProcessEvent(event);
- final Serializable serEvent = getPST().transform(event);
- runner.accept(new ClientVisitor<RemoteReceiverClient>() {
- public void visit(RemoteReceiverClient client) {
- client.offer(serEvent);
- }
- });
+ }
+
+ protected ServerListener<RemoteReceiverClient> createServerListener(
+ ServerSocket socket) {
+ return new RemoteReceiverServerListener(socket);
+ }
+
+ protected ServerRunner<RemoteReceiverClient> createServerRunner(
+ ServerListener<RemoteReceiverClient> listener,
+ Executor executor) {
+ return new RemoteReceiverServerRunner(listener, executor,
+ getClientQueueSize());
+ }
+
+ @Override
+ public void stop() {
+ if (!isStarted()) return;
+ try {
+ runner.stop();
+ super.stop();
}
-
- /**
- * Post process an event received via {@link #append(E)}.
- * @param event
- */
- protected abstract void postProcessEvent(E event);
-
- /**
- * Gets a transformer that will be used to convert a received event
- * to a {@link Serializable} form.
- * @return
- */
- protected abstract PreSerializationTransformer<E> getPST();
-
- /**
- * Gets the factory used to create {@link ServerSocket} objects.
- * <p>
- * The default implementation delegates to
- * {@link ServerSocketFactory#getDefault()}. Subclasses may override to
- * private a different socket factory implementation.
- *
- * @return socket factory.
- */
- protected ServerSocketFactory getServerSocketFactory() throws Exception {
- return ServerSocketFactory.getDefault();
- }
-
- /**
- * Gets the local address for the listener.
- * @return an {@link InetAddress} representation of the local address.
- * @throws UnknownHostException
- */
- protected InetAddress getInetAddress() throws UnknownHostException {
- if (getAddress() == null)
- return null;
- return InetAddress.getByName(getAddress());
- }
-
- /**
- * Gets the local port for the listener.
- * @return local port
- */
- public int getPort() {
- return port;
- }
-
- /**
- * Sets the local port for the listener.
- * @param port the local port to set
- */
- public void setPort(int port) {
- this.port = port;
- }
-
- /**
- * Gets the listener queue depth.
- * <p>
- * This represents the number of connected clients whose connections
- * have not yet been accepted.
- * @return queue depth
- * @see java.net.ServerSocket
- */
- public int getBacklog() {
- return backlog;
- }
-
- /**
- * Sets the listener queue depth.
- * <p>
- * This represents the number of connected clients whose connections
- * have not yet been accepted.
- * @param backlog the queue depth to set
- * @see java.net.ServerSocket
- */
- public void setBacklog(int backlog) {
- this.backlog = backlog;
- }
-
- /**
- * Gets the local address for the listener.
- * @return a string representation of the local address
- */
- public String getAddress() {
- return address;
- }
-
- /**
- * Sets the local address for the listener.
- * @param address a host name or a string representation of an IP address
- */
- public void setAddress(String address) {
- this.address = address;
- }
-
- /**
- * Gets the event queue size used for each client connection.
- * @return queue size
- */
- public int getClientQueueSize() {
- return clientQueueSize;
- }
-
- /**
- * Sets the event queue size used for each client connection.
- * @param clientQueueSize the queue size to set
- */
- public void setClientQueueSize(int clientQueueSize) {
- this.clientQueueSize = clientQueueSize;
+ catch (IOException ex) {
+ addError("server shutdown error: " + ex, ex);
}
+ }
+
+ @Override
+ protected void append(E event) {
+ if (event == null) return;
+ postProcessEvent(event);
+ final Serializable serEvent = getPST().transform(event);
+ runner.accept(new ClientVisitor<RemoteReceiverClient>() {
+ public void visit(RemoteReceiverClient client) {
+ client.offer(serEvent);
+ }
+ });
+ }
+
+ /**
+ * Post process an event received via {@link #append(E)}.
+ * @param event
+ */
+ protected abstract void postProcessEvent(E event);
+
+ /**
+ * Gets a transformer that will be used to convert a received event
+ * to a {@link Serializable} form.
+ * @return
+ */
+ protected abstract PreSerializationTransformer<E> getPST();
+
+ /**
+ * Gets the factory used to create {@link ServerSocket} objects.
+ * <p>
+ * The default implementation delegates to
+ * {@link ServerSocketFactory#getDefault()}. Subclasses may override to
+ * private a different socket factory implementation.
+ *
+ * @return socket factory.
+ */
+ protected ServerSocketFactory getServerSocketFactory() throws Exception {
+ return ServerSocketFactory.getDefault();
+ }
+
+ /**
+ * Gets the local address for the listener.
+ * @return an {@link InetAddress} representation of the local address.
+ * @throws UnknownHostException
+ */
+ protected InetAddress getInetAddress() throws UnknownHostException {
+ if (getAddress() == null) return null;
+ return InetAddress.getByName(getAddress());
+ }
+
+ /**
+ * Gets the local port for the listener.
+ * @return local port
+ */
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * Sets the local port for the listener.
+ * @param port the local port to set
+ */
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ /**
+ * Gets the listener queue depth.
+ * <p>
+ * This represents the number of connected clients whose connections
+ * have not yet been accepted.
+ * @return queue depth
+ * @see java.net.ServerSocket
+ */
+ public int getBacklog() {
+ return backlog;
+ }
+
+ /**
+ * Sets the listener queue depth.
+ * <p>
+ * This represents the number of connected clients whose connections
+ * have not yet been accepted.
+ * @param backlog the queue depth to set
+ * @see java.net.ServerSocket
+ */
+ public void setBacklog(int backlog) {
+ this.backlog = backlog;
+ }
+
+ /**
+ * Gets the local address for the listener.
+ * @return a string representation of the local address
+ */
+ public String getAddress() {
+ return address;
+ }
+
+ /**
+ * Sets the local address for the listener.
+ * @param address a host name or a string representation of an IP address
+ */
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ /**
+ * Gets the event queue size used for each client connection.
+ * @return queue size
+ */
+ public int getClientQueueSize() {
+ return clientQueueSize;
+ }
+
+ /**
+ * Sets the event queue size used for each client connection.
+ * @param clientQueueSize the queue size to set
+ */
+ public void setClientQueueSize(int clientQueueSize) {
+ this.clientQueueSize = clientQueueSize;
+ }
}
+
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/server/Client.java b/logback-core/src/main/java/ch/qos/logback/core/net/server/Client.java
index 56287c1..2a856c1 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/server/Client.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/server/Client.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -37,21 +37,21 @@ import java.io.IOException;
*/
public interface Client extends Runnable, Closeable {
- /**
- * Closes any resources that are held by the client.
- * <p>
- * Note that (as described in Doug Lea's discussion about interrupting I/O
- * operations in "Concurrent Programming in Java" (Addison-Wesley
- * Professional, 2nd edition, 1999) this method is used to interrupt
- * any blocked I/O operation in the client when the server is shutting
- * down. The client implementation must anticipate this potential,
- * and gracefully exit when the blocked I/O operation throws the
- * relevant {@link IOException} subclass.
- * <p>
- * Note also, that unlike {@link Closeable#close()} this method is not
- * permitted to propagate any {@link IOException} that occurs when closing
- * the underlying resource(s).
- */
- void close();
-
+ /**
+ * Closes any resources that are held by the client.
+ * <p>
+ * Note that (as described in Doug Lea's discussion about interrupting I/O
+ * operations in "Concurrent Programming in Java" (Addison-Wesley
+ * Professional, 2nd edition, 1999) this method is used to interrupt
+ * any blocked I/O operation in the client when the server is shutting
+ * down. The client implementation must anticipate this potential,
+ * and gracefully exit when the blocked I/O operation throws the
+ * relevant {@link IOException} subclass.
+ * <p>
+ * Note also, that unlike {@link Closeable#close()} this method is not
+ * permitted to propagate any {@link IOException} that occurs when closing
+ * the underlying resource(s).
+ */
+ void close();
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/server/ClientVisitor.java b/logback-core/src/main/java/ch/qos/logback/core/net/server/ClientVisitor.java
index 4b9b4f6..efd7d1e 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/server/ClientVisitor.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/server/ClientVisitor.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,6 +20,6 @@ package ch.qos.logback.core.net.server;
*/
public interface ClientVisitor<T extends Client> {
- void visit(T client);
-
+ void visit(T client);
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/server/ConcurrentServerRunner.java b/logback-core/src/main/java/ch/qos/logback/core/net/server/ConcurrentServerRunner.java
index 06c8fc2..e7341e7 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/server/ConcurrentServerRunner.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/server/ConcurrentServerRunner.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -44,178 +44,188 @@ import ch.qos.logback.core.spi.ContextAwareBase;
*
* @author Carl Harris
*/
-public abstract class ConcurrentServerRunner<T extends Client> extends ContextAwareBase implements Runnable, ServerRunner<T> {
-
- private final Lock clientsLock = new ReentrantLock();
-
- private final Collection<T> clients = new ArrayList<T>();
-
- private final ServerListener<T> listener;
- private final Executor executor;
-
- private boolean running;
-
- /**
- * Constructs a new server runner.
- * @param listener the listener from which the server will accept new
- * clients
- * @param executor a executor that will facilitate execution of the
- * listening and client-handling tasks; while any {@link Executor}
- * is allowed here, outside of unit testing the only reasonable choice
- * is a bounded thread pool of some kind.
- */
- public ConcurrentServerRunner(ServerListener<T> listener, Executor executor) {
- this.listener = listener;
- this.executor = executor;
+public abstract class ConcurrentServerRunner<T extends Client>
+ extends ContextAwareBase
+ implements Runnable, ServerRunner<T> {
+
+ private final Lock clientsLock = new ReentrantLock();
+
+ private final Collection<T> clients = new ArrayList<T>();
+
+ private final ServerListener<T> listener;
+ private final Executor executor;
+
+ private boolean running;
+
+ /**
+ * Constructs a new server runner.
+ * @param listener the listener from which the server will accept new
+ * clients
+ * @param executor a executor that will facilitate execution of the
+ * listening and client-handling tasks; while any {@link Executor}
+ * is allowed here, outside of unit testing the only reasonable choice
+ * is a bounded thread pool of some kind.
+ */
+ public ConcurrentServerRunner(ServerListener<T> listener, Executor executor) {
+ this.listener = listener;
+ this.executor = executor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isRunning() {
+ return running;
+ }
+
+ protected void setRunning(boolean running) {
+ this.running = running;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void stop() throws IOException {
+ listener.close();
+ accept(new ClientVisitor<T>() {
+ public void visit(T client) {
+ client.close();
+ }
+ });
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void accept(ClientVisitor<T> visitor) {
+ Collection<T> clients = copyClients();
+ for (T client : clients) {
+ try {
+ visitor.visit(client);
+ }
+ catch (RuntimeException ex) {
+ addError(client + ": " + ex);
+ }
}
-
- /**
- * {@inheritDoc}
- */
- public boolean isRunning() {
- return running;
+ }
+
+ /**
+ * Creates a copy of the collection of all clients that are presently
+ * being tracked by the server.
+ * @return collection of client objects
+ */
+ private Collection<T> copyClients() {
+ clientsLock.lock();
+ try {
+ Collection<T> copy = new ArrayList<T>(clients);
+ return copy;
}
-
- protected void setRunning(boolean running) {
- this.running = running;
+ finally {
+ clientsLock.unlock();
}
-
- /**
- * {@inheritDoc}
- */
- public void stop() throws IOException {
- listener.close();
- accept(new ClientVisitor<T>() {
- public void visit(T client) {
- client.close();
- }
- });
- }
-
- /**
- * {@inheritDoc}
- */
- public void accept(ClientVisitor<T> visitor) {
- Collection<T> clients = copyClients();
- for (T client : clients) {
- try {
- visitor.visit(client);
- } catch (RuntimeException ex) {
- addError(client + ": " + ex);
- }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void run() {
+ setRunning(true);
+ try {
+ addInfo("listening on " + listener);
+ while (!Thread.currentThread().isInterrupted()) {
+ T client = listener.acceptClient();
+ if (!configureClient(client)) {
+ addError(client + ": connection dropped");
+ client.close();
+ continue;
}
- }
-
- /**
- * Creates a copy of the collection of all clients that are presently
- * being tracked by the server.
- * @return collection of client objects
- */
- private Collection<T> copyClients() {
- clientsLock.lock();
try {
- Collection<T> copy = new ArrayList<T>(clients);
- return copy;
- } finally {
- clientsLock.unlock();
+ executor.execute(new ClientWrapper(client));
}
- }
-
- /**
- * {@inheritDoc}
- */
- public void run() {
- setRunning(true);
- try {
- addInfo("listening on " + listener);
- while (!Thread.currentThread().isInterrupted()) {
- T client = listener.acceptClient();
- if (!configureClient(client)) {
- addError(client + ": connection dropped");
- client.close();
- continue;
- }
- try {
- executor.execute(new ClientWrapper(client));
- } catch (RejectedExecutionException ex) {
- addError(client + ": connection dropped");
- client.close();
- }
- }
- } catch (InterruptedException ex) {
- assert true; // ok... we'll shut down
- } catch (Exception ex) {
- addError("listener: " + ex);
+ catch (RejectedExecutionException ex) {
+ addError(client + ": connection dropped");
+ client.close();
}
-
- setRunning(false);
- addInfo("shutting down");
- listener.close();
+ }
}
-
- /**
- * Configures a connected client.
- * <p>
- * A subclass implements this method to perform any necessary configuration
- * of the client object before its {@link Client#run()} method is invoked.
- *
- * @param client the subject client
- * @return {@code true} if configuration was successful; if the return
- * value is {@code false} the client connection will be dropped
- */
- protected abstract boolean configureClient(T client);
-
- /**
- * Adds a client to the collection of those being tracked by the server.
- * @param client the client to add
- */
- private void addClient(T client) {
- clientsLock.lock();
- try {
- clients.add(client);
- } finally {
- clientsLock.unlock();
- }
+ catch (InterruptedException ex) {
+ assert true; // ok... we'll shut down
}
-
- /**
- * Removes a client from the collection of those being tracked by the server.
- * @param client the client to remote
- */
- private void removeClient(T client) {
- clientsLock.lock();
- try {
- clients.remove(client);
- } finally {
- clientsLock.unlock();
- }
+ catch (Exception ex) {
+ addError("listener: " + ex);
}
- /**
- * A wrapper for a {@link Client} responsible for ensuring that client
- * tracking is performed properly.
- */
- private class ClientWrapper implements Client {
-
- private final T delegate;
-
- public ClientWrapper(T client) {
- this.delegate = client;
- }
-
- public void run() {
- addClient(delegate);
- try {
- delegate.run();
- } finally {
- removeClient(delegate);
- }
- }
-
- public void close() {
- delegate.close();
- }
+ setRunning(false);
+ addInfo("shutting down");
+ listener.close();
+ }
+
+ /**
+ * Configures a connected client.
+ * <p>
+ * A subclass implements this method to perform any necessary configuration
+ * of the client object before its {@link Client#run()} method is invoked.
+ *
+ * @param client the subject client
+ * @return {@code true} if configuration was successful; if the return
+ * value is {@code false} the client connection will be dropped
+ */
+ protected abstract boolean configureClient(T client);
+
+ /**
+ * Adds a client to the collection of those being tracked by the server.
+ * @param client the client to add
+ */
+ private void addClient(T client) {
+ clientsLock.lock();
+ try {
+ clients.add(client);
+ }
+ finally {
+ clientsLock.unlock();
+ }
+ }
+
+ /**
+ * Removes a client from the collection of those being tracked by the server.
+ * @param client the client to remote
+ */
+ private void removeClient(T client) {
+ clientsLock.lock();
+ try {
+ clients.remove(client);
+ }
+ finally {
+ clientsLock.unlock();
+ }
+ }
+
+ /**
+ * A wrapper for a {@link Client} responsible for ensuring that client
+ * tracking is performed properly.
+ */
+ private class ClientWrapper implements Client {
+
+ private final T delegate;
+
+ public ClientWrapper(T client) {
+ this.delegate = client;
+ }
+ public void run() {
+ addClient(delegate);
+ try {
+ delegate.run();
+ }
+ finally {
+ removeClient(delegate);
+ }
}
+ public void close() {
+ delegate.close();
+ }
+
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverClient.java b/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverClient.java
index 10b17bc..5a38468 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverClient.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverClient.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,7 @@ import java.util.concurrent.BlockingQueue;
import ch.qos.logback.core.spi.ContextAware;
+
/**
* A client of a {@link ServerRunner} that receives events from a local
* appender and logs them according to local policy.
@@ -26,20 +27,20 @@ import ch.qos.logback.core.spi.ContextAware;
*/
interface RemoteReceiverClient extends Client, ContextAware {
- /**
- * Sets the client's event queue.
- * <p>
- * This method must be invoked before the {@link #run()} method is invoked.
- * @param queue the queue to set
- */
- void setQueue(BlockingQueue<Serializable> queue);
-
- /**
- * Offers an event to the client.
- * @param event the subject event
- * @return {@code true} if the client's queue accepted the event,
- * {@code false} if the client's queue is full
- */
- boolean offer(Serializable event);
-
+ /**
+ * Sets the client's event queue.
+ * <p>
+ * This method must be invoked before the {@link #run()} method is invoked.
+ * @param queue the queue to set
+ */
+ void setQueue(BlockingQueue<Serializable> queue);
+
+ /**
+ * Offers an event to the client.
+ * @param event the subject event
+ * @return {@code true} if the client's queue accepted the event,
+ * {@code false} if the client's queue is full
+ */
+ boolean offer(Serializable event);
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverServerListener.java b/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverServerListener.java
index 9afe695..d2a158f 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverServerListener.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverServerListener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,23 +23,25 @@ import java.net.Socket;
*
* @author Carl Harris
*/
-class RemoteReceiverServerListener extends ServerSocketListener<RemoteReceiverClient> {
+class RemoteReceiverServerListener
+ extends ServerSocketListener<RemoteReceiverClient> {
- /**
- * Constructs a new listener.
- * @param serverSocket server socket from which new client connections
- * will be accepted
- */
- public RemoteReceiverServerListener(ServerSocket serverSocket) {
- super(serverSocket);
- }
+ /**
+ * Constructs a new listener.
+ * @param serverSocket server socket from which new client connections
+ * will be accepted
+ */
+ public RemoteReceiverServerListener(ServerSocket serverSocket) {
+ super(serverSocket);
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- protected RemoteReceiverClient createClient(String id, Socket socket) throws IOException {
- return new RemoteReceiverStreamClient(id, socket);
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected RemoteReceiverClient createClient(String id, Socket socket)
+ throws IOException {
+ return new RemoteReceiverStreamClient(id, socket);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverServerRunner.java b/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverServerRunner.java
index ab0bc5f..f99edf3 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverServerRunner.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverServerRunner.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,32 +23,35 @@ import java.util.concurrent.Executor;
*
* @author Carl Harris
*/
-class RemoteReceiverServerRunner extends ConcurrentServerRunner<RemoteReceiverClient> {
+class RemoteReceiverServerRunner
+ extends ConcurrentServerRunner<RemoteReceiverClient> {
- private final int clientQueueSize;
+ private final int clientQueueSize;
+
+ /**
+ * Constructs a new server runner.
+ * @param listener the listener from which the server will accept new
+ * clients
+ * @param executor that will be used to execute asynchronous tasks
+ * on behalf of the runner.
+ * @param queueSize size of the event queue that will be maintained for
+ * each client
+ */
+ public RemoteReceiverServerRunner(
+ ServerListener<RemoteReceiverClient> listener, Executor executor,
+ int clientQueueSize) {
+ super(listener, executor);
+ this.clientQueueSize = clientQueueSize;
+ }
- /**
- * Constructs a new server runner.
- * @param listener the listener from which the server will accept new
- * clients
- * @param executor that will be used to execute asynchronous tasks
- * on behalf of the runner.
- * @param queueSize size of the event queue that will be maintained for
- * each client
- */
- public RemoteReceiverServerRunner(ServerListener<RemoteReceiverClient> listener, Executor executor, int clientQueueSize) {
- super(listener, executor);
- this.clientQueueSize = clientQueueSize;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected boolean configureClient(RemoteReceiverClient client) {
- client.setContext(getContext());
- client.setQueue(new ArrayBlockingQueue<Serializable>(clientQueueSize));
- return true;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean configureClient(RemoteReceiverClient client) {
+ client.setContext(getContext());
+ client.setQueue(new ArrayBlockingQueue<Serializable>(clientQueueSize));
+ return true;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverStreamClient.java b/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverStreamClient.java
index fb146e3..29a432e 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverStreamClient.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/server/RemoteReceiverStreamClient.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,110 +31,115 @@ import ch.qos.logback.core.util.CloseUtil;
*
* @author Carl Harris
*/
-class RemoteReceiverStreamClient extends ContextAwareBase implements RemoteReceiverClient {
+class RemoteReceiverStreamClient
+ extends ContextAwareBase implements RemoteReceiverClient {
- private final String clientId;
- private final Socket socket;
- private final OutputStream outputStream;
+ private final String clientId;
+ private final Socket socket;
+ private final OutputStream outputStream;
+
+ private BlockingQueue<Serializable> queue;
+
+ /**
+ * Constructs a new client.
+ * @param id identifier string for the client
+ * @param socket socket to which logging events will be written
+ */
+ public RemoteReceiverStreamClient(String id, Socket socket) {
+ this.clientId = "client " + id + ": ";
+ this.socket = socket;
+ this.outputStream = null;
+ }
- private BlockingQueue<Serializable> queue;
+ /**
+ * Constructs a new client.
+ * <p>
+ * This constructor exists primarily to support unit tests where it
+ * is inconvenient to have to create a socket for the test.
+ *
+ * @param id identifier string for the client
+ * @param outputStream output stream to which logging Events will be written
+ */
+ RemoteReceiverStreamClient(String id, OutputStream outputStream) {
+ this.clientId = "client " + id + ": ";
+ this.socket = null;
+ this.outputStream = outputStream;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setQueue(BlockingQueue<Serializable> queue) {
+ this.queue = queue;
+ }
- /**
- * Constructs a new client.
- * @param id identifier string for the client
- * @param socket socket to which logging events will be written
- */
- public RemoteReceiverStreamClient(String id, Socket socket) {
- this.clientId = "client " + id + ": ";
- this.socket = socket;
- this.outputStream = null;
+ /**
+ * {@inheritDoc}
+ */
+ public boolean offer(Serializable event) {
+ if (queue == null) {
+ throw new IllegalStateException("client has no event queue");
}
+ return queue.offer(event);
+ }
- /**
- * Constructs a new client.
- * <p>
- * This constructor exists primarily to support unit tests where it
- * is inconvenient to have to create a socket for the test.
- *
- * @param id identifier string for the client
- * @param outputStream output stream to which logging Events will be written
- */
- RemoteReceiverStreamClient(String id, OutputStream outputStream) {
- this.clientId = "client " + id + ": ";
- this.socket = null;
- this.outputStream = outputStream;
- }
+ /**
+ * {@inheritDoc}
+ */
+ public void close() {
+ if (socket == null) return;
+ CloseUtil.closeQuietly(socket);
+ }
- /**
- * {@inheritDoc}
- */
- public void setQueue(BlockingQueue<Serializable> queue) {
- this.queue = queue;
- }
+ /**
+ * {@inheritDoc}
+ */
+ public void run() {
+ addInfo(clientId + "connected");
- /**
- * {@inheritDoc}
- */
- public boolean offer(Serializable event) {
- if (queue == null) {
- throw new IllegalStateException("client has no event queue");
+ ObjectOutputStream oos = null;
+ try {
+ int counter = 0;
+ oos = createObjectOutputStream();
+ while (!Thread.currentThread().isInterrupted()) {
+ try {
+ Serializable event = queue.take();
+ oos.writeObject(event);
+ oos.flush();
+ if (++counter >= CoreConstants.OOS_RESET_FREQUENCY) {
+ // failing to reset the stream periodically will result in a
+ // serious memory leak (as noted in AbstractSocketAppender)
+ counter = 0;
+ oos.reset();
+ }
}
- return queue.offer(event);
+ catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ }
+ }
}
-
- /**
- * {@inheritDoc}
- */
- public void close() {
- if (socket == null)
- return;
- CloseUtil.closeQuietly(socket);
+ catch (SocketException ex) {
+ addInfo(clientId + ex);
}
-
- /**
- * {@inheritDoc}
- */
- public void run() {
- addInfo(clientId + "connected");
-
- ObjectOutputStream oos = null;
- try {
- int counter = 0;
- oos = createObjectOutputStream();
- while (!Thread.currentThread().isInterrupted()) {
- try {
- Serializable event = queue.take();
- oos.writeObject(event);
- oos.flush();
- if (++counter >= CoreConstants.OOS_RESET_FREQUENCY) {
- // failing to reset the stream periodically will result in a
- // serious memory leak (as noted in AbstractSocketAppender)
- counter = 0;
- oos.reset();
- }
- } catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- }
- }
- } catch (SocketException ex) {
- addInfo(clientId + ex);
- } catch (IOException ex) {
- addError(clientId + ex);
- } catch (RuntimeException ex) {
- addError(clientId + ex);
- } finally {
- if (oos != null) {
- CloseUtil.closeQuietly(oos);
- }
- close();
- addInfo(clientId + "connection closed");
- }
+ catch (IOException ex) {
+ addError(clientId + ex);
}
+ catch (RuntimeException ex) {
+ addError(clientId + ex);
+ }
+ finally {
+ if (oos != null) {
+ CloseUtil.closeQuietly(oos);
+ }
+ close();
+ addInfo(clientId + "connection closed");
+ }
+ }
- private ObjectOutputStream createObjectOutputStream() throws IOException {
- if (socket == null) {
- return new ObjectOutputStream(outputStream);
- }
- return new ObjectOutputStream(socket.getOutputStream());
+ private ObjectOutputStream createObjectOutputStream() throws IOException {
+ if (socket == null) {
+ return new ObjectOutputStream(outputStream);
}
+ return new ObjectOutputStream(socket.getOutputStream());
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/server/SSLServerSocketAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/net/server/SSLServerSocketAppenderBase.java
index 443e7b3..4b58bb3 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/server/SSLServerSocketAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/server/SSLServerSocketAppenderBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,50 +28,53 @@ import ch.qos.logback.core.net.ssl.SSLParametersConfiguration;
*
* @author Carl Harris
*/
-public abstract class SSLServerSocketAppenderBase<E> extends AbstractServerSocketAppender<E> implements SSLComponent {
+public abstract class SSLServerSocketAppenderBase<E>
+ extends AbstractServerSocketAppender<E> implements SSLComponent {
- private SSLConfiguration ssl;
- private ServerSocketFactory socketFactory;
+ private SSLConfiguration ssl;
+ private ServerSocketFactory socketFactory;
+
+ @Override
+ protected ServerSocketFactory getServerSocketFactory() {
+ return socketFactory;
+ }
- @Override
- protected ServerSocketFactory getServerSocketFactory() {
- return socketFactory;
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void start() {
+ try {
+ SSLContext sslContext = getSsl().createContext(this);
+ SSLParametersConfiguration parameters = getSsl().getParameters();
+ parameters.setContext(getContext());
+ socketFactory = new ConfigurableSSLServerSocketFactory(parameters,
+ sslContext.getServerSocketFactory());
+ super.start();
}
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void start() {
- try {
- SSLContext sslContext = getSsl().createContext(this);
- SSLParametersConfiguration parameters = getSsl().getParameters();
- parameters.setContext(getContext());
- socketFactory = new ConfigurableSSLServerSocketFactory(parameters, sslContext.getServerSocketFactory());
- super.start();
- } catch (Exception ex) {
- addError(ex.getMessage(), ex);
- }
- }
-
- /**
- * Gets the SSL configuration.
- * @return SSL configuration; if no configuration has been set, a
- * default configuration is returned
- */
- public SSLConfiguration getSsl() {
- if (ssl == null) {
- ssl = new SSLConfiguration();
- }
- return ssl;
+ catch (Exception ex) {
+ addError(ex.getMessage(), ex);
}
+ }
- /**
- * Sets the SSL configuration.
- * @param ssl the SSL configuration to set
- */
- public void setSsl(SSLConfiguration ssl) {
- this.ssl = ssl;
+ /**
+ * Gets the SSL configuration.
+ * @return SSL configuration; if no configuration has been set, a
+ * default configuration is returned
+ */
+ public SSLConfiguration getSsl() {
+ if (ssl == null) {
+ ssl = new SSLConfiguration();
}
+ return ssl;
+ }
+ /**
+ * Sets the SSL configuration.
+ * @param ssl the SSL configuration to set
+ */
+ public void setSsl(SSLConfiguration ssl) {
+ this.ssl = ssl;
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/server/ServerListener.java b/logback-core/src/main/java/ch/qos/logback/core/net/server/ServerListener.java
index 7831bd3..ec26f36 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/server/ServerListener.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/server/ServerListener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -34,34 +34,34 @@ import java.io.IOException;
*/
public interface ServerListener<T extends Client> extends Closeable {
- /**
- * Accepts the next client that appears on this listener.
- * <p>
- * An implementation of this method is expected to block the calling thread
- * and not return until either a client appears or an exception occurs.
- *
- * @return client object
- * @throws IOException
- * @throws InterruptedException
- */
- T acceptClient() throws IOException, InterruptedException;
-
- /**
- * Closes any underlying {@link Closeable} resources associated with this
- * listener.
- * <p>
- * Note that (as described in Doug Lea's discussion about interrupting I/O
- * operations in "Concurrent Programming in Java" (Addison-Wesley
- * Professional, 2nd edition, 1999) this method is used to interrupt
- * any blocked I/O operation in the client when the server is shutting
- * down. The client implementation must anticipate this potential,
- * and gracefully exit when the blocked I/O operation throws the
- * relevant {@link IOException} subclass.
- * <p>
- * Note also, that unlike {@link Closeable#close()} this method is not
- * permitted to propagate any {@link IOException} that occurs when closing
- * the underlying resource(s).
- */
- void close();
-
+ /**
+ * Accepts the next client that appears on this listener.
+ * <p>
+ * An implementation of this method is expected to block the calling thread
+ * and not return until either a client appears or an exception occurs.
+ *
+ * @return client object
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ T acceptClient() throws IOException, InterruptedException;
+
+ /**
+ * Closes any underlying {@link Closeable} resources associated with this
+ * listener.
+ * <p>
+ * Note that (as described in Doug Lea's discussion about interrupting I/O
+ * operations in "Concurrent Programming in Java" (Addison-Wesley
+ * Professional, 2nd edition, 1999) this method is used to interrupt
+ * any blocked I/O operation in the client when the server is shutting
+ * down. The client implementation must anticipate this potential,
+ * and gracefully exit when the blocked I/O operation throws the
+ * relevant {@link IOException} subclass.
+ * <p>
+ * Note also, that unlike {@link Closeable#close()} this method is not
+ * permitted to propagate any {@link IOException} that occurs when closing
+ * the underlying resource(s).
+ */
+ void close();
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/server/ServerRunner.java b/logback-core/src/main/java/ch/qos/logback/core/net/server/ServerRunner.java
index 6dc2188..fc24bc7 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/server/ServerRunner.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/server/ServerRunner.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,26 +28,26 @@ import ch.qos.logback.core.spi.ContextAware;
*/
public interface ServerRunner<T extends Client> extends ContextAware, Runnable {
- /**
- * Gets a flag indicating whether the server is currently running.
- * @return flag state
- */
- boolean isRunning();
-
- /**
- * Stops execution of the runner.
- * <p>
- * This method must cause all I/O and thread resources associated with
- * the runner to be released. If the receiver has not been started, this
- * method must have no effect.
- * @throws IOException
- */
- void stop() throws IOException;
-
- /**
- * Presents each connected client to the given visitor.
- * @param visitor the subject visitor
- */
- void accept(ClientVisitor<T> visitor);
+ /**
+ * Gets a flag indicating whether the server is currently running.
+ * @return flag state
+ */
+ boolean isRunning();
+
+ /**
+ * Stops execution of the runner.
+ * <p>
+ * This method must cause all I/O and thread resources associated with
+ * the runner to be released. If the receiver has not been started, this
+ * method must have no effect.
+ * @throws IOException
+ */
+ void stop() throws IOException;
+ /**
+ * Presents each connected client to the given visitor.
+ * @param visitor the subject visitor
+ */
+ void accept(ClientVisitor<T> visitor);
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/server/ServerSocketListener.java b/logback-core/src/main/java/ch/qos/logback/core/net/server/ServerSocketListener.java
index eb6f4a7..5abd77e 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/server/ServerSocketListener.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/server/ServerSocketListener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,62 +25,65 @@ import ch.qos.logback.core.util.CloseUtil;
*
* @author Carl Harris
*/
-public abstract class ServerSocketListener<T extends Client> implements ServerListener<T> {
+public abstract class ServerSocketListener<T extends Client>
+ implements ServerListener<T> {
- private final ServerSocket serverSocket;
+ private final ServerSocket serverSocket;
- /**
- * Constructs a new listener.
- * @param serverSocket server socket delegate
- */
- public ServerSocketListener(ServerSocket serverSocket) {
- this.serverSocket = serverSocket;
- }
+ /**
+ * Constructs a new listener.
+ * @param serverSocket server socket delegate
+ */
+ public ServerSocketListener(ServerSocket serverSocket) {
+ this.serverSocket = serverSocket;
+ }
- /**
- * {@inheritDoc}
- */
- public T acceptClient() throws IOException {
- Socket socket = serverSocket.accept();
- return createClient(socketAddressToString(socket.getRemoteSocketAddress()), socket);
- }
+ /**
+ * {@inheritDoc}
+ */
+ public T acceptClient() throws IOException {
+ Socket socket = serverSocket.accept();
+ return createClient(
+ socketAddressToString(socket.getRemoteSocketAddress()), socket);
+ }
- /**
- * Creates the client object for a new socket connection
- * @param id identifier string for the client
- * @param socket client's socket connection
- * @return client object
- * @throws IOException
- */
- protected abstract T createClient(String id, Socket socket) throws IOException;
+ /**
+ * Creates the client object for a new socket connection
+ * @param id identifier string for the client
+ * @param socket client's socket connection
+ * @return client object
+ * @throws IOException
+ */
+ protected abstract T createClient(String id, Socket socket)
+ throws IOException;
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() {
+ CloseUtil.closeQuietly(serverSocket);
+ }
- /**
- * {@inheritDoc}
- */
- public void close() {
- CloseUtil.closeQuietly(serverSocket);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- return socketAddressToString(serverSocket.getLocalSocketAddress());
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return socketAddressToString(serverSocket.getLocalSocketAddress());
+ }
- /**
- * Converts a socket address to a reasonable display string.
- * @param address the subject socket address
- * @return display string
- */
- private String socketAddressToString(SocketAddress address) {
- String addr = address.toString();
- int i = addr.indexOf("/");
- if (i >= 0) {
- addr = addr.substring(i + 1);
- }
- return addr;
+ /**
+ * Converts a socket address to a reasonable display string.
+ * @param address the subject socket address
+ * @return display string
+ */
+ private String socketAddressToString(SocketAddress address) {
+ String addr = address.toString();
+ int i = addr.indexOf("/");
+ if (i >= 0) {
+ addr = addr.substring(i + 1);
}
+ return addr;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/ConfigurableSSLServerSocketFactory.java b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/ConfigurableSSLServerSocketFactory.java
index c4d58f2..1ef326c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/ConfigurableSSLServerSocketFactory.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/ConfigurableSSLServerSocketFactory.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -35,49 +35,55 @@ import javax.net.ssl.SSLServerSocketFactory;
*/
public class ConfigurableSSLServerSocketFactory extends ServerSocketFactory {
- private final SSLParametersConfiguration parameters;
- private final SSLServerSocketFactory delegate;
+ private final SSLParametersConfiguration parameters;
+ private final SSLServerSocketFactory delegate;
- /**
- * Creates a new factory.
- * @param parameters parameters that will be configured on each
- * socket created by the factory
- * @param delegate socket factory that will be called upon to create
- * server sockets before configuration
- */
- public ConfigurableSSLServerSocketFactory(SSLParametersConfiguration parameters, SSLServerSocketFactory delegate) {
- this.parameters = parameters;
- this.delegate = delegate;
- }
+ /**
+ * Creates a new factory.
+ * @param parameters parameters that will be configured on each
+ * socket created by the factory
+ * @param delegate socket factory that will be called upon to create
+ * server sockets before configuration
+ */
+ public ConfigurableSSLServerSocketFactory(
+ SSLParametersConfiguration parameters, SSLServerSocketFactory delegate) {
+ this.parameters = parameters;
+ this.delegate = delegate;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public ServerSocket createServerSocket(int port, int backlog, InetAddress ifAddress) throws IOException {
- SSLServerSocket socket = (SSLServerSocket) delegate.createServerSocket(port, backlog, ifAddress);
- parameters.configure(new SSLConfigurableServerSocket(socket));
- return socket;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ServerSocket createServerSocket(int port, int backlog, InetAddress ifAddress)
+ throws IOException {
+ SSLServerSocket socket = (SSLServerSocket) delegate.createServerSocket(
+ port, backlog, ifAddress);
+ parameters.configure(new SSLConfigurableServerSocket(socket));
+ return socket;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public ServerSocket createServerSocket(int port, int backlog) throws IOException {
- SSLServerSocket socket = (SSLServerSocket) delegate.createServerSocket(port, backlog);
- parameters.configure(new SSLConfigurableServerSocket(socket));
- return socket;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ServerSocket createServerSocket(int port, int backlog)
+ throws IOException {
+ SSLServerSocket socket = (SSLServerSocket) delegate.createServerSocket(
+ port, backlog);
+ parameters.configure(new SSLConfigurableServerSocket(socket));
+ return socket;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public ServerSocket createServerSocket(int port) throws IOException {
- SSLServerSocket socket = (SSLServerSocket) delegate.createServerSocket(port);
- parameters.configure(new SSLConfigurableServerSocket(socket));
- return socket;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ServerSocket createServerSocket(int port) throws IOException {
+ SSLServerSocket socket = (SSLServerSocket) delegate.createServerSocket(
+ port);
+ parameters.configure(new SSLConfigurableServerSocket(socket));
+ return socket;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/ConfigurableSSLSocketFactory.java b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/ConfigurableSSLSocketFactory.java
index d70b4db..f04abe6 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/ConfigurableSSLSocketFactory.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/ConfigurableSSLSocketFactory.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -36,59 +36,65 @@ import javax.net.ssl.SSLSocketFactory;
*/
public class ConfigurableSSLSocketFactory extends SocketFactory {
- private final SSLParametersConfiguration parameters;
- private final SSLSocketFactory delegate;
+ private final SSLParametersConfiguration parameters;
+ private final SSLSocketFactory delegate;
- /**
- * Creates a new factory.
- * @param parameters parameters that will be configured on each
- * socket created by the factory
- * @param delegate socket factory that will be called upon to create
- * sockets before configuration
- */
- public ConfigurableSSLSocketFactory(SSLParametersConfiguration parameters, SSLSocketFactory delegate) {
- this.parameters = parameters;
- this.delegate = delegate;
- }
+ /**
+ * Creates a new factory.
+ * @param parameters parameters that will be configured on each
+ * socket created by the factory
+ * @param delegate socket factory that will be called upon to create
+ * sockets before configuration
+ */
+ public ConfigurableSSLSocketFactory(SSLParametersConfiguration parameters,
+ SSLSocketFactory delegate) {
+ this.parameters = parameters;
+ this.delegate = delegate;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
- SSLSocket socket = (SSLSocket) delegate.createSocket(address, port, localAddress, localPort);
- parameters.configure(new SSLConfigurableSocket(socket));
- return socket;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Socket createSocket(InetAddress address, int port,
+ InetAddress localAddress, int localPort) throws IOException {
+ SSLSocket socket = (SSLSocket) delegate.createSocket(address, port,
+ localAddress, localPort);
+ parameters.configure(new SSLConfigurableSocket(socket));
+ return socket;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public Socket createSocket(InetAddress host, int port) throws IOException {
- SSLSocket socket = (SSLSocket) delegate.createSocket(host, port);
- parameters.configure(new SSLConfigurableSocket(socket));
- return socket;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Socket createSocket(InetAddress host, int port) throws IOException {
+ SSLSocket socket = (SSLSocket) delegate.createSocket(host, port);
+ parameters.configure(new SSLConfigurableSocket(socket));
+ return socket;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
- SSLSocket socket = (SSLSocket) delegate.createSocket(host, port, localHost, localPort);
- parameters.configure(new SSLConfigurableSocket(socket));
- return socket;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
- SSLSocket socket = (SSLSocket) delegate.createSocket(host, port);
- parameters.configure(new SSLConfigurableSocket(socket));
- return socket;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Socket createSocket(String host, int port, InetAddress localHost,
+ int localPort) throws IOException, UnknownHostException {
+ SSLSocket socket = (SSLSocket) delegate.createSocket(host, port,
+ localHost, localPort);
+ parameters.configure(new SSLConfigurableSocket(socket));
+ return socket;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Socket createSocket(String host, int port) throws IOException,
+ UnknownHostException {
+ SSLSocket socket = (SSLSocket) delegate.createSocket(host, port);
+ parameters.configure(new SSLConfigurableSocket(socket));
+ return socket;
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/KeyManagerFactoryFactoryBean.java b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/KeyManagerFactoryFactoryBean.java
index d900f86..cce54b3 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/KeyManagerFactoryFactoryBean.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/KeyManagerFactoryFactoryBean.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,61 +28,64 @@ import javax.net.ssl.KeyManagerFactory;
*/
public class KeyManagerFactoryFactoryBean {
- private String algorithm;
- private String provider;
+ private String algorithm;
+ private String provider;
- /**
- * Creates a {@link KeyManagerFactory} using the receiver's configuration.
- * @return factory object
- * @throws NoSuchProviderException if the provider specified by
- * {@link #setProvider(String)} is not known to the platform
- * @throws NoSuchAlgorithmException if the algorithm specified by
- * {@link #setAlgorithm(String)} is not known to the specified provider
- * (or to the default platform provider if no provider is specified)
- */
- public KeyManagerFactory createKeyManagerFactory() throws NoSuchProviderException, NoSuchAlgorithmException {
-
- return getProvider() != null ? KeyManagerFactory.getInstance(getAlgorithm(), getProvider()) : KeyManagerFactory.getInstance(getAlgorithm());
- }
-
- /**
- * Gets the algorithm name for the key manager factory.
- * @return algorithm name (e.g. {@code SunX509}); the default algorithm
- * (obtained from {@link KeyManagerFactory#getDefaultAlgorithm()})
- * is returned if no algorithm has been configured
- */
- public String getAlgorithm() {
- if (algorithm == null) {
- return KeyManagerFactory.getDefaultAlgorithm();
- }
- return algorithm;
+ /**
+ * Creates a {@link KeyManagerFactory} using the receiver's configuration.
+ * @return factory object
+ * @throws NoSuchProviderException if the provider specified by
+ * {@link #setProvider(String)} is not known to the platform
+ * @throws NoSuchAlgorithmException if the algorithm specified by
+ * {@link #setAlgorithm(String)} is not known to the specified provider
+ * (or to the default platform provider if no provider is specified)
+ */
+ public KeyManagerFactory createKeyManagerFactory()
+ throws NoSuchProviderException, NoSuchAlgorithmException {
+
+ return getProvider() != null ?
+ KeyManagerFactory.getInstance(getAlgorithm(), getProvider())
+ : KeyManagerFactory.getInstance(getAlgorithm());
+ }
+
+ /**
+ * Gets the algorithm name for the key manager factory.
+ * @return algorithm name (e.g. {@code SunX509}); the default algorithm
+ * (obtained from {@link KeyManagerFactory#getDefaultAlgorithm()})
+ * is returned if no algorithm has been configured
+ */
+ public String getAlgorithm() {
+ if (algorithm == null) {
+ return KeyManagerFactory.getDefaultAlgorithm();
}
+ return algorithm;
+ }
- /**
- * Sets the algorithm name for the key manager factory.
- * @param algorithm an algorithm name, which must be recognized by the
- * provider specified by {@link #setProvider(String)} or by the
- * platform's default provider if no provider is specified.
- */
- public void setAlgorithm(String algorithm) {
- this.algorithm = algorithm;
- }
+ /**
+ * Sets the algorithm name for the key manager factory.
+ * @param algorithm an algorithm name, which must be recognized by the
+ * provider specified by {@link #setProvider(String)} or by the
+ * platform's default provider if no provider is specified.
+ */
+ public void setAlgorithm(String algorithm) {
+ this.algorithm = algorithm;
+ }
- /**
- * Gets the JSSE provider name for the key manager factory.
- * @return provider name
- */
- public String getProvider() {
- return provider;
- }
+ /**
+ * Gets the JSSE provider name for the key manager factory.
+ * @return provider name
+ */
+ public String getProvider() {
+ return provider;
+ }
- /**
- * Sets the JSSE provider name for the key manager factory.
- * @param provider name of the JSSE provider to utilize in creating the
- * key manager factory
- */
- public void setProvider(String provider) {
- this.provider = provider;
- }
+ /**
+ * Sets the JSSE provider name for the key manager factory.
+ * @param provider name of the JSSE provider to utilize in creating the
+ * key manager factory
+ */
+ public void setProvider(String provider) {
+ this.provider = provider;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/KeyStoreFactoryBean.java b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/KeyStoreFactoryBean.java
index b50a5fb..8472fdc 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/KeyStoreFactoryBean.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/KeyStoreFactoryBean.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,6 +24,7 @@ import java.security.NoSuchProviderException;
import ch.qos.logback.core.util.LocationUtil;
+
/**
* A factory bean for a JCA {@link KeyStore}.
* <p>
@@ -34,140 +35,152 @@ import ch.qos.logback.core.util.LocationUtil;
*/
public class KeyStoreFactoryBean {
- private String location;
- private String provider;
- private String type;
- private String password;
-
- /**
- * Creates a new {@link KeyStore} using the receiver's configuration.
- * @return key store
- * @throws NoSuchProviderException if the provider specified by
- * {@link #setProvider(String)} is not known to the platform
- * @throws NoSuchAlgorithmException if the key store type specified by
- * {@link #setType(String)} is not known to the specified provider
- * (or the platform's default provider if the provider isn't specified)
- * @throws KeyStoreException if some other error occurs in loading
- * the key store from the resource specified by
- * {@link #setLocation(String)}
- */
- public KeyStore createKeyStore() throws NoSuchProviderException, NoSuchAlgorithmException, KeyStoreException {
-
- if (getLocation() == null) {
- throw new IllegalArgumentException("location is required");
- }
-
- InputStream inputStream = null;
- try {
- URL url = LocationUtil.urlForResource(getLocation());
- inputStream = url.openStream();
- KeyStore keyStore = newKeyStore();
- keyStore.load(inputStream, getPassword().toCharArray());
- return keyStore;
- } catch (NoSuchProviderException ex) {
- throw new NoSuchProviderException("no such keystore provider: " + getProvider());
- } catch (NoSuchAlgorithmException ex) {
- throw new NoSuchAlgorithmException("no such keystore type: " + getType());
- } catch (FileNotFoundException ex) {
- throw new KeyStoreException(getLocation() + ": file not found");
- } catch (Exception ex) {
- throw new KeyStoreException(getLocation() + ": " + ex.getMessage(), ex);
- } finally {
- try {
- if (inputStream != null) {
- inputStream.close();
- }
- } catch (IOException ex) {
- ex.printStackTrace(System.err);
- }
- }
- }
-
- /**
- * Invokes the appropriate JCE factory method to obtain a new
- * {@link KeyStore} object.
- */
- private KeyStore newKeyStore() throws NoSuchAlgorithmException, NoSuchProviderException, KeyStoreException {
-
- return getProvider() != null ? KeyStore.getInstance(getType(), getProvider()) : KeyStore.getInstance(getType());
- }
-
- /**
- * Gets the location of the key store resource.
- * @return a String containing a URL for the resource
- */
- public String getLocation() {
- return location;
+ private String location;
+ private String provider;
+ private String type;
+ private String password;
+
+ /**
+ * Creates a new {@link KeyStore} using the receiver's configuration.
+ * @return key store
+ * @throws NoSuchProviderException if the provider specified by
+ * {@link #setProvider(String)} is not known to the platform
+ * @throws NoSuchAlgorithmException if the key store type specified by
+ * {@link #setType(String)} is not known to the specified provider
+ * (or the platform's default provider if the provider isn't specified)
+ * @throws KeyStoreException if some other error occurs in loading
+ * the key store from the resource specified by
+ * {@link #setLocation(String)}
+ */
+ public KeyStore createKeyStore() throws NoSuchProviderException,
+ NoSuchAlgorithmException, KeyStoreException {
+
+ if (getLocation() == null) {
+ throw new IllegalArgumentException("location is required");
}
-
- /**
- * Sets the location of the key store resource.
- * @param location a String containing a URL for the resource; if the
- * URL string isn't prefixed by a scheme, the path is assumed to be
- * relative to the root of the classpath.
- */
- public void setLocation(String location) {
- this.location = location;
+
+ InputStream inputStream = null;
+ try {
+ URL url = LocationUtil.urlForResource(getLocation());
+ inputStream = url.openStream();
+ KeyStore keyStore = newKeyStore();
+ keyStore.load(inputStream, getPassword().toCharArray());
+ return keyStore;
}
-
- /**
- * Gets the type of key store to load.
- * @return a key store type name (e.g. {@code JKS}); the
- * {@link SSL#DEFAULT_KEYSTORE_TYPE} is returned if no type has been configured
- */
- public String getType() {
- if (type == null) {
- return SSL.DEFAULT_KEYSTORE_TYPE;
- }
- return type;
+ catch (NoSuchProviderException ex) {
+ throw new NoSuchProviderException("no such keystore provider: "
+ + getProvider());
}
-
- /**
- * Sets the type of key store to load.
- * @param type a key store type name (e.g. {@code JKS}, {@code PKCS12});
- * the type specified must be supported by the provider specified by
- * {@link #setProvider(String)} or by the platform's default provider
- * if no provider is specified
- */
- public void setType(String type) {
- this.type = type;
+ catch (NoSuchAlgorithmException ex) {
+ throw new NoSuchAlgorithmException("no such keystore type: "
+ + getType());
}
-
- /**
- * Gets the JCA key store provider name.
- * @return provider name or {@code null} if no provider has been configured
- */
- public String getProvider() {
- return provider;
+ catch (FileNotFoundException ex) {
+ throw new KeyStoreException(getLocation() + ": file not found");
}
-
- /**
- * Sets the JCA key store provider name.
- * @param provider name of the JCA provider to utilize in creating the
- * key store
- */
- public void setProvider(String provider) {
- this.provider = provider;
+ catch (Exception ex) {
+ throw new KeyStoreException(getLocation() + ": " + ex.getMessage(), ex);
}
-
- /**
- * Gets the password to use to access the key store.
- * @return password string; the {@link SSL#DEFAULT_KEYSTORE_PASSWORD} is returned
- * if no password has been configured
- */
- public String getPassword() {
- if (password == null) {
- return SSL.DEFAULT_KEYSTORE_PASSWORD;
+ finally {
+ try {
+ if (inputStream != null) {
+ inputStream.close();
}
- return password;
+ }
+ catch (IOException ex) {
+ ex.printStackTrace(System.err);
+ }
}
-
- /**
- * Sets the password to use to access the keystore.
- * @param password the password to set
- */
- public void setPassword(String password) {
- this.password = password;
+ }
+
+ /**
+ * Invokes the appropriate JCE factory method to obtain a new
+ * {@link KeyStore} object.
+ */
+ private KeyStore newKeyStore() throws NoSuchAlgorithmException,
+ NoSuchProviderException, KeyStoreException {
+
+ return getProvider() != null ?
+ KeyStore.getInstance(getType(), getProvider())
+ : KeyStore.getInstance(getType());
+ }
+
+ /**
+ * Gets the location of the key store resource.
+ * @return a String containing a URL for the resource
+ */
+ public String getLocation() {
+ return location;
+ }
+
+ /**
+ * Sets the location of the key store resource.
+ * @param location a String containing a URL for the resource; if the
+ * URL string isn't prefixed by a scheme, the path is assumed to be
+ * relative to the root of the classpath.
+ */
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+ /**
+ * Gets the type of key store to load.
+ * @return a key store type name (e.g. {@code JKS}); the
+ * {@link SSL#DEFAULT_KEYSTORE_TYPE} is returned if no type has been configured
+ */
+ public String getType() {
+ if (type == null) {
+ return SSL.DEFAULT_KEYSTORE_TYPE;
+ }
+ return type;
+ }
+
+ /**
+ * Sets the type of key store to load.
+ * @param type a key store type name (e.g. {@code JKS}, {@code PKCS12});
+ * the type specified must be supported by the provider specified by
+ * {@link #setProvider(String)} or by the platform's default provider
+ * if no provider is specified
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ /**
+ * Gets the JCA key store provider name.
+ * @return provider name or {@code null} if no provider has been configured
+ */
+ public String getProvider() {
+ return provider;
+ }
+
+ /**
+ * Sets the JCA key store provider name.
+ * @param provider name of the JCA provider to utilize in creating the
+ * key store
+ */
+ public void setProvider(String provider) {
+ this.provider = provider;
+ }
+
+ /**
+ * Gets the password to use to access the key store.
+ * @return password string; the {@link SSL#DEFAULT_KEYSTORE_PASSWORD} is returned
+ * if no password has been configured
+ */
+ public String getPassword() {
+ if (password == null) {
+ return SSL.DEFAULT_KEYSTORE_PASSWORD;
}
+ return password;
+ }
+
+ /**
+ * Sets the password to use to access the keystore.
+ * @param password the password to set
+ */
+ public void setPassword(String password) {
+ this.password = password;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSL.java b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSL.java
index db30d86..f76fcc2 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSL.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSL.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.net.ssl;
+
/**
* Various constants used by the SSL implementation.
*
@@ -20,16 +21,16 @@ package ch.qos.logback.core.net.ssl;
*/
public interface SSL {
- /** Default secure transport protocol */
- String DEFAULT_PROTOCOL = "SSL";
-
- /** Default key store type */
- String DEFAULT_KEYSTORE_TYPE = "JKS";
-
- /** Default key store passphrase */
- String DEFAULT_KEYSTORE_PASSWORD = "changeit";
-
- /** Default secure random generator algorithm */
- String DEFAULT_SECURE_RANDOM_ALGORITHM = "SHA1PRNG";
+ /** Default secure transport protocol */
+ String DEFAULT_PROTOCOL = "SSL";
+
+ /** Default key store type */
+ String DEFAULT_KEYSTORE_TYPE = "JKS";
+
+ /** Default key store passphrase */
+ String DEFAULT_KEYSTORE_PASSWORD = "changeit";
+ /** Default secure random generator algorithm */
+ String DEFAULT_SECURE_RANDOM_ALGORITHM = "SHA1PRNG";
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLComponent.java b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLComponent.java
index 57e07dc..ab84608 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLComponent.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLComponent.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,8 +20,8 @@ package ch.qos.logback.core.net.ssl;
*/
public interface SSLComponent {
- SSLConfiguration getSsl();
-
- void setSsl(SSLConfiguration ssl);
-
+ SSLConfiguration getSsl();
+
+ void setSsl(SSLConfiguration ssl);
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfigurable.java b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfigurable.java
index 709aa5c..f43e8d2 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfigurable.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfigurable.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,62 +24,62 @@ package ch.qos.logback.core.net.ssl;
*/
public interface SSLConfigurable {
- /**
- * Gets the set of protocols that the SSL component enables by default.
- *
- * @return protocols (generally a subset of the set returned by
- * {@link #getSupportedProtocols()}); the return value may be
- * an empty array but must never be {@code null}.
- */
- String[] getDefaultProtocols();
+ /**
+ * Gets the set of protocols that the SSL component enables by default.
+ *
+ * @return protocols (generally a subset of the set returned by
+ * {@link #getSupportedProtocols()}); the return value may be
+ * an empty array but must never be {@code null}.
+ */
+ String[] getDefaultProtocols();
- /**
- * Gets the set of protocols that the SSL component supports.
- * @return protocols supported protocols; the return value may be
- * an empty array but must never be {@code null}.
- */
- String[] getSupportedProtocols();
+ /**
+ * Gets the set of protocols that the SSL component supports.
+ * @return protocols supported protocols; the return value may be
+ * an empty array but must never be {@code null}.
+ */
+ String[] getSupportedProtocols();
- /**
- * Sets the enabled protocols on the SSL component.
- * @param cipherSuites the protocols to enable
- */
- void setEnabledProtocols(String[] protocols);
-
- /**
- * Gets the set of cipher suites that the SSL component enables by default.
- *
- * @return cipher suites (generally a subset of the set returned by
- * {@link #getSupportedCipherSuites()}); the return value may be
- * an empty array but must never be {@code null}
- */
- String[] getDefaultCipherSuites();
-
- /**
- * Gets the set of cipher suites that the SSL component supports.
- * @return supported cipher suites; the return value may be
- * an empty array but must never be {@code null}
- */
- String[] getSupportedCipherSuites();
-
- /**
- * Sets the enabled cipher suites on the SSL component.
- * @param cipherSuites the cipher suites to enable
- */
- void setEnabledCipherSuites(String[] cipherSuites);
-
- /**
- * Sets a flag indicating whether the SSL component should require
- * client authentication.
- * @param state the flag state to set
- */
- void setNeedClientAuth(boolean state);
-
- /**
- * Sets a flag indicating whether the SSL component should request
- * client authentication.
- * @param state the flag state to set
- */
- void setWantClientAuth(boolean state);
+ /**
+ * Sets the enabled protocols on the SSL component.
+ * @param cipherSuites the protocols to enable
+ */
+ void setEnabledProtocols(String[] protocols);
+ /**
+ * Gets the set of cipher suites that the SSL component enables by default.
+ *
+ * @return cipher suites (generally a subset of the set returned by
+ * {@link #getSupportedCipherSuites()}); the return value may be
+ * an empty array but must never be {@code null}
+ */
+ String[] getDefaultCipherSuites();
+
+ /**
+ * Gets the set of cipher suites that the SSL component supports.
+ * @return supported cipher suites; the return value may be
+ * an empty array but must never be {@code null}
+ */
+ String[] getSupportedCipherSuites();
+
+ /**
+ * Sets the enabled cipher suites on the SSL component.
+ * @param cipherSuites the cipher suites to enable
+ */
+ void setEnabledCipherSuites(String[] cipherSuites);
+
+ /**
+ * Sets a flag indicating whether the SSL component should require
+ * client authentication.
+ * @param state the flag state to set
+ */
+ void setNeedClientAuth(boolean state);
+
+ /**
+ * Sets a flag indicating whether the SSL component should request
+ * client authentication.
+ * @param state the flag state to set
+ */
+ void setWantClientAuth(boolean state);
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfigurableServerSocket.java b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfigurableServerSocket.java
index d395541..2971b4c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfigurableServerSocket.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfigurableServerSocket.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,42 +22,42 @@ import javax.net.ssl.SSLServerSocket;
*/
public class SSLConfigurableServerSocket implements SSLConfigurable {
- private final SSLServerSocket delegate;
+ private final SSLServerSocket delegate;
- public SSLConfigurableServerSocket(SSLServerSocket delegate) {
- this.delegate = delegate;
- }
+ public SSLConfigurableServerSocket(SSLServerSocket delegate) {
+ this.delegate = delegate;
+ }
- public String[] getDefaultProtocols() {
- return delegate.getEnabledProtocols();
- }
+ public String[] getDefaultProtocols() {
+ return delegate.getEnabledProtocols();
+ }
- public String[] getSupportedProtocols() {
- return delegate.getSupportedProtocols();
- }
+ public String[] getSupportedProtocols() {
+ return delegate.getSupportedProtocols();
+ }
- public void setEnabledProtocols(String[] protocols) {
- delegate.setEnabledProtocols(protocols);
- }
+ public void setEnabledProtocols(String[] protocols) {
+ delegate.setEnabledProtocols(protocols);
+ }
- public String[] getDefaultCipherSuites() {
- return delegate.getEnabledCipherSuites();
- }
+ public String[] getDefaultCipherSuites() {
+ return delegate.getEnabledCipherSuites();
+ }
- public String[] getSupportedCipherSuites() {
- return delegate.getSupportedCipherSuites();
- }
+ public String[] getSupportedCipherSuites() {
+ return delegate.getSupportedCipherSuites();
+ }
- public void setEnabledCipherSuites(String[] suites) {
- delegate.setEnabledCipherSuites(suites);
- }
+ public void setEnabledCipherSuites(String[] suites) {
+ delegate.setEnabledCipherSuites(suites);
+ }
- public void setNeedClientAuth(boolean state) {
- delegate.setNeedClientAuth(state);
- }
-
- public void setWantClientAuth(boolean state) {
- delegate.setWantClientAuth(state);
- }
+ public void setNeedClientAuth(boolean state) {
+ delegate.setNeedClientAuth(state);
+ }
+ public void setWantClientAuth(boolean state) {
+ delegate.setWantClientAuth(state);
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfigurableSocket.java b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfigurableSocket.java
index fe7f28f..e2bcdec 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfigurableSocket.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfigurableSocket.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,42 +22,42 @@ import javax.net.ssl.SSLSocket;
*/
public class SSLConfigurableSocket implements SSLConfigurable {
- private final SSLSocket delegate;
+ private final SSLSocket delegate;
- public SSLConfigurableSocket(SSLSocket delegate) {
- this.delegate = delegate;
- }
+ public SSLConfigurableSocket(SSLSocket delegate) {
+ this.delegate = delegate;
+ }
- public String[] getDefaultProtocols() {
- return delegate.getEnabledProtocols();
- }
+ public String[] getDefaultProtocols() {
+ return delegate.getEnabledProtocols();
+ }
- public String[] getSupportedProtocols() {
- return delegate.getSupportedProtocols();
- }
+ public String[] getSupportedProtocols() {
+ return delegate.getSupportedProtocols();
+ }
- public void setEnabledProtocols(String[] protocols) {
- delegate.setEnabledProtocols(protocols);
- }
+ public void setEnabledProtocols(String[] protocols) {
+ delegate.setEnabledProtocols(protocols);
+ }
- public String[] getDefaultCipherSuites() {
- return delegate.getEnabledCipherSuites();
- }
+ public String[] getDefaultCipherSuites() {
+ return delegate.getEnabledCipherSuites();
+ }
- public String[] getSupportedCipherSuites() {
- return delegate.getSupportedCipherSuites();
- }
+ public String[] getSupportedCipherSuites() {
+ return delegate.getSupportedCipherSuites();
+ }
- public void setEnabledCipherSuites(String[] suites) {
- delegate.setEnabledCipherSuites(suites);
- }
+ public void setEnabledCipherSuites(String[] suites) {
+ delegate.setEnabledCipherSuites(suites);
+ }
- public void setNeedClientAuth(boolean state) {
- delegate.setNeedClientAuth(state);
- }
-
- public void setWantClientAuth(boolean state) {
- delegate.setWantClientAuth(state);
- }
+ public void setNeedClientAuth(boolean state) {
+ delegate.setNeedClientAuth(state);
+ }
+ public void setWantClientAuth(boolean state) {
+ delegate.setWantClientAuth(state);
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfiguration.java b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfiguration.java
index c26ac4a..6cbbc6c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfiguration.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLConfiguration.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,26 +23,26 @@ import javax.net.ssl.SSLContext;
*/
public class SSLConfiguration extends SSLContextFactoryBean {
- private SSLParametersConfiguration parameters;
+ private SSLParametersConfiguration parameters;
- /**
- * Gets the SSL parameters configuration.
- * @return parameters configuration; if no parameters object was
- * configured, a default parameters object is returned
- */
- public SSLParametersConfiguration getParameters() {
- if (parameters == null) {
- parameters = new SSLParametersConfiguration();
- }
- return parameters;
+ /**
+ * Gets the SSL parameters configuration.
+ * @return parameters configuration; if no parameters object was
+ * configured, a default parameters object is returned
+ */
+ public SSLParametersConfiguration getParameters() {
+ if (parameters == null) {
+ parameters = new SSLParametersConfiguration();
}
+ return parameters;
+ }
- /**
- * Sets the SSL parameters configuration.
- * @param parameters the parameters configuration to set
- */
- public void setParameters(SSLParametersConfiguration parameters) {
- this.parameters = parameters;
- }
+ /**
+ * Sets the SSL parameters configuration.
+ * @param parameters the parameters configuration to set
+ */
+ public void setParameters(SSLParametersConfiguration parameters) {
+ this.parameters = parameters;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLContextFactoryBean.java b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLContextFactoryBean.java
index 6c67930..a57880c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLContextFactoryBean.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLContextFactoryBean.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -39,286 +39,303 @@ import ch.qos.logback.core.spi.ContextAware;
* @author Carl Harris
*/
public class SSLContextFactoryBean {
-
- private static final String JSSE_KEY_STORE_PROPERTY = "javax.net.ssl.keyStore";
- private static final String JSSE_TRUST_STORE_PROPERTY = "javax.net.ssl.trustStore";
-
- private KeyStoreFactoryBean keyStore;
- private KeyStoreFactoryBean trustStore;
- private SecureRandomFactoryBean secureRandom;
- private KeyManagerFactoryFactoryBean keyManagerFactory;
- private TrustManagerFactoryFactoryBean trustManagerFactory;
- private String protocol;
- private String provider;
-
- /**
- * Creates a new {@link SSLContext} using the receiver's configuration.
- * @param context context for status messages
- * @return {@link SSLContext} object
- * @throws NoSuchProviderException if a provider specified for one of the
- * JCA or JSSE components utilized in creating the context is not
- * known to the platform
- * @throws NoSuchAlgorithmException if a JCA or JSSE algorithm, protocol,
- * or type name specified for one of the context's components is not
- * known to a given provider (or platform default provider for the
- * component)
- * @throws KeyManagementException if an error occurs in creating a
- * {@link KeyManager} for the context
- * @throws UnrecoverableKeyException if a private key needed by a
- * {@link KeyManager} cannot be obtained from a key store
- * @throws KeyStoreException if an error occurs in reading the
- * contents of a key store
- * @throws CertificateException if an error occurs in reading the
- * contents of a certificate
- */
- public SSLContext createContext(ContextAware context) throws NoSuchProviderException, NoSuchAlgorithmException, KeyManagementException,
- UnrecoverableKeyException, KeyStoreException, CertificateException {
-
- SSLContext sslContext = getProvider() != null ? SSLContext.getInstance(getProtocol(), getProvider()) : SSLContext.getInstance(getProtocol());
-
- context.addInfo("SSL protocol '" + sslContext.getProtocol() + "' provider '" + sslContext.getProvider() + "'");
-
- KeyManager[] keyManagers = createKeyManagers(context);
- TrustManager[] trustManagers = createTrustManagers(context);
- SecureRandom secureRandom = createSecureRandom(context);
- sslContext.init(keyManagers, trustManagers, secureRandom);
- return sslContext;
- }
-
- /**
- * Creates key managers using the receiver's key store configuration.
- * @param context context for status messages
- * @return an array of key managers or {@code null} if no key store
- * configuration was provided
- * @throws NoSuchProviderException if a provider specified for one
- * of the key manager components is not known to the platform
- * @throws NoSuchAlgorithmException if an algorithm specified for
- * one of the key manager components is not known to the relevant
- * provider
- * @throws KeyStoreException if an error occurs in reading a key store
- */
- private KeyManager[] createKeyManagers(ContextAware context) throws NoSuchProviderException, NoSuchAlgorithmException, UnrecoverableKeyException,
- KeyStoreException {
-
- if (getKeyStore() == null)
- return null;
-
- KeyStore keyStore = getKeyStore().createKeyStore();
- context.addInfo("key store of type '" + keyStore.getType() + "' provider '" + keyStore.getProvider() + "': " + getKeyStore().getLocation());
-
- KeyManagerFactory kmf = getKeyManagerFactory().createKeyManagerFactory();
- context.addInfo("key manager algorithm '" + kmf.getAlgorithm() + "' provider '" + kmf.getProvider() + "'");
-
- char[] passphrase = getKeyStore().getPassword().toCharArray();
- kmf.init(keyStore, passphrase);
- return kmf.getKeyManagers();
- }
-
- /**
- * Creates trust managers using the receiver's trust store configuration.
- * @param context context for status messages
- * @return an array of trust managers or {@code null} if no trust store
- * configuration was provided
- * @throws NoSuchProviderException if a provider specified for one
- * of the trust manager components is not known to the platform
- * @throws NoSuchAlgorithmException if an algorithm specified for
- * one of the trust manager components is not known to the relevant
- * provider
- * @throws KeyStoreException if an error occurs in reading a key
- * store containing trust anchors
- */
- private TrustManager[] createTrustManagers(ContextAware context) throws NoSuchProviderException, NoSuchAlgorithmException, KeyStoreException {
-
- if (getTrustStore() == null)
- return null;
-
- KeyStore trustStore = getTrustStore().createKeyStore();
- context.addInfo("trust store of type '" + trustStore.getType() + "' provider '" + trustStore.getProvider() + "': " + getTrustStore().getLocation());
-
- TrustManagerFactory tmf = getTrustManagerFactory().createTrustManagerFactory();
- context.addInfo("trust manager algorithm '" + tmf.getAlgorithm() + "' provider '" + tmf.getProvider() + "'");
-
- tmf.init(trustStore);
- return tmf.getTrustManagers();
- }
-
- private SecureRandom createSecureRandom(ContextAware context) throws NoSuchProviderException, NoSuchAlgorithmException {
-
- SecureRandom secureRandom = getSecureRandom().createSecureRandom();
- context.addInfo("secure random algorithm '" + secureRandom.getAlgorithm() + "' provider '" + secureRandom.getProvider() + "'");
-
- return secureRandom;
- }
-
- /**
- * Gets the key store configuration.
- * @return key store factory bean or {@code null} if no key store
- * configuration was provided
- */
- public KeyStoreFactoryBean getKeyStore() {
- if (keyStore == null) {
- keyStore = keyStoreFromSystemProperties(JSSE_KEY_STORE_PROPERTY);
- }
- return keyStore;
+
+ private static final String JSSE_KEY_STORE_PROPERTY = "javax.net.ssl.keyStore";
+ private static final String JSSE_TRUST_STORE_PROPERTY = "javax.net.ssl.trustStore";
+
+ private KeyStoreFactoryBean keyStore;
+ private KeyStoreFactoryBean trustStore;
+ private SecureRandomFactoryBean secureRandom;
+ private KeyManagerFactoryFactoryBean keyManagerFactory;
+ private TrustManagerFactoryFactoryBean trustManagerFactory;
+ private String protocol;
+ private String provider;
+
+ /**
+ * Creates a new {@link SSLContext} using the receiver's configuration.
+ * @param context context for status messages
+ * @return {@link SSLContext} object
+ * @throws NoSuchProviderException if a provider specified for one of the
+ * JCA or JSSE components utilized in creating the context is not
+ * known to the platform
+ * @throws NoSuchAlgorithmException if a JCA or JSSE algorithm, protocol,
+ * or type name specified for one of the context's components is not
+ * known to a given provider (or platform default provider for the
+ * component)
+ * @throws KeyManagementException if an error occurs in creating a
+ * {@link KeyManager} for the context
+ * @throws UnrecoverableKeyException if a private key needed by a
+ * {@link KeyManager} cannot be obtained from a key store
+ * @throws KeyStoreException if an error occurs in reading the
+ * contents of a key store
+ * @throws CertificateException if an error occurs in reading the
+ * contents of a certificate
+ */
+ public SSLContext createContext(ContextAware context) throws NoSuchProviderException,
+ NoSuchAlgorithmException, KeyManagementException,
+ UnrecoverableKeyException, KeyStoreException, CertificateException {
+
+ SSLContext sslContext = getProvider() != null ?
+ SSLContext.getInstance(getProtocol(), getProvider())
+ : SSLContext.getInstance(getProtocol());
+
+ context.addInfo("SSL protocol '" + sslContext.getProtocol()
+ + "' provider '" + sslContext.getProvider() + "'");
+
+ KeyManager[] keyManagers = createKeyManagers(context);
+ TrustManager[] trustManagers = createTrustManagers(context);
+ SecureRandom secureRandom = createSecureRandom(context);
+ sslContext.init(keyManagers, trustManagers, secureRandom);
+ return sslContext;
+ }
+
+ /**
+ * Creates key managers using the receiver's key store configuration.
+ * @param context context for status messages
+ * @return an array of key managers or {@code null} if no key store
+ * configuration was provided
+ * @throws NoSuchProviderException if a provider specified for one
+ * of the key manager components is not known to the platform
+ * @throws NoSuchAlgorithmException if an algorithm specified for
+ * one of the key manager components is not known to the relevant
+ * provider
+ * @throws KeyStoreException if an error occurs in reading a key store
+ */
+ private KeyManager[] createKeyManagers(ContextAware context)
+ throws NoSuchProviderException, NoSuchAlgorithmException,
+ UnrecoverableKeyException, KeyStoreException {
+
+ if (getKeyStore() == null) return null;
+
+ KeyStore keyStore = getKeyStore().createKeyStore();
+ context.addInfo(
+ "key store of type '" + keyStore.getType()
+ + "' provider '" + keyStore.getProvider()
+ + "': " + getKeyStore().getLocation());
+
+ KeyManagerFactory kmf = getKeyManagerFactory().createKeyManagerFactory();
+ context.addInfo("key manager algorithm '" + kmf.getAlgorithm()
+ + "' provider '" + kmf.getProvider() + "'");
+
+ char[] passphrase = getKeyStore().getPassword().toCharArray();
+ kmf.init(keyStore, passphrase);
+ return kmf.getKeyManagers();
+ }
+
+ /**
+ * Creates trust managers using the receiver's trust store configuration.
+ * @param context context for status messages
+ * @return an array of trust managers or {@code null} if no trust store
+ * configuration was provided
+ * @throws NoSuchProviderException if a provider specified for one
+ * of the trust manager components is not known to the platform
+ * @throws NoSuchAlgorithmException if an algorithm specified for
+ * one of the trust manager components is not known to the relevant
+ * provider
+ * @throws KeyStoreException if an error occurs in reading a key
+ * store containing trust anchors
+ */
+ private TrustManager[] createTrustManagers(ContextAware context)
+ throws NoSuchProviderException, NoSuchAlgorithmException,
+ KeyStoreException {
+
+ if (getTrustStore() == null) return null;
+
+ KeyStore trustStore = getTrustStore().createKeyStore();
+ context.addInfo(
+ "trust store of type '" + trustStore.getType()
+ + "' provider '" + trustStore.getProvider()
+ + "': " + getTrustStore().getLocation());
+
+ TrustManagerFactory tmf = getTrustManagerFactory()
+ .createTrustManagerFactory();
+ context.addInfo("trust manager algorithm '" + tmf.getAlgorithm()
+ + "' provider '" + tmf.getProvider() + "'");
+
+ tmf.init(trustStore);
+ return tmf.getTrustManagers();
+ }
+
+ private SecureRandom createSecureRandom(ContextAware context)
+ throws NoSuchProviderException, NoSuchAlgorithmException {
+
+ SecureRandom secureRandom = getSecureRandom().createSecureRandom();
+ context.addInfo("secure random algorithm '" + secureRandom.getAlgorithm()
+ + "' provider '" + secureRandom.getProvider() + "'");
+
+ return secureRandom;
+ }
+
+ /**
+ * Gets the key store configuration.
+ * @return key store factory bean or {@code null} if no key store
+ * configuration was provided
+ */
+ public KeyStoreFactoryBean getKeyStore() {
+ if (keyStore == null) {
+ keyStore = keyStoreFromSystemProperties(JSSE_KEY_STORE_PROPERTY);
}
-
- /**
- * Sets the key store configuration.
- * @param keyStore the key store factory bean to set
- */
- public void setKeyStore(KeyStoreFactoryBean keyStore) {
- this.keyStore = keyStore;
- }
-
- /**
- * Gets the trust store configuration.
- * @return trust store factory bean or {@code null} if no trust store
- * configuration was provided
- */
- public KeyStoreFactoryBean getTrustStore() {
- if (trustStore == null) {
- trustStore = keyStoreFromSystemProperties(JSSE_TRUST_STORE_PROPERTY);
- }
- return trustStore;
- }
-
- /**
- * Sets the trust store configuration.
- * @param trustStore the trust store factory bean to set
- */
- public void setTrustStore(KeyStoreFactoryBean trustStore) {
- this.trustStore = trustStore;
- }
-
- /**
- * Constructs a key store factory bean using JSSE system properties.
- * @param property base property name (e.g. {@code javax.net.ssl.keyStore})
- * @return key store or {@code null} if no value is defined for the
- * base system property name
- */
- private KeyStoreFactoryBean keyStoreFromSystemProperties(String property) {
- if (System.getProperty(property) == null)
- return null;
- KeyStoreFactoryBean keyStore = new KeyStoreFactoryBean();
- keyStore.setLocation(locationFromSystemProperty(property));
- keyStore.setProvider(System.getProperty(property + "Provider"));
- keyStore.setPassword(System.getProperty(property + "Password"));
- keyStore.setType(System.getProperty(property + "Type"));
- return keyStore;
- }
-
- /**
- * Constructs a resource location from a JSSE system property.
- * @param name property name (e.g. {@code javax.net.ssl.keyStore})
- * @return URL for the location specified in the property or {@code null}
- * if no value is defined for the property
- */
- private String locationFromSystemProperty(String name) {
- String location = System.getProperty(name);
- if (location != null && !location.startsWith("file:")) {
- location = "file:" + location;
- }
- return location;
- }
-
- /**
- * Gets the secure random generator configuration.
- * @return secure random factory bean; if no secure random generator
- * configuration has been set, a default factory bean is returned
- */
- public SecureRandomFactoryBean getSecureRandom() {
- if (secureRandom == null) {
- return new SecureRandomFactoryBean();
- }
- return secureRandom;
- }
-
- /**
- * Sets the secure random generator configuration.
- * @param secureRandom the secure random factory bean to set
- */
- public void setSecureRandom(SecureRandomFactoryBean secureRandom) {
- this.secureRandom = secureRandom;
- }
-
- /**
- * Gets the key manager factory configuration.
- * @return factory bean; if no key manager factory
- * configuration has been set, a default factory bean is returned
- */
- public KeyManagerFactoryFactoryBean getKeyManagerFactory() {
- if (keyManagerFactory == null) {
- return new KeyManagerFactoryFactoryBean();
- }
- return keyManagerFactory;
- }
-
- /**
- * Sets the key manager factory configuration.
- * @param keyManagerFactory the key manager factory factory bean to set
- */
- public void setKeyManagerFactory(KeyManagerFactoryFactoryBean keyManagerFactory) {
- this.keyManagerFactory = keyManagerFactory;
- }
-
- /**
- * Gets the trust manager factory configuration.
- * @return factory bean; if no trust manager factory
- * configuration has been set, a default factory bean is returned
- */
- public TrustManagerFactoryFactoryBean getTrustManagerFactory() {
- if (trustManagerFactory == null) {
- return new TrustManagerFactoryFactoryBean();
- }
- return trustManagerFactory;
+ return keyStore;
+ }
+
+ /**
+ * Sets the key store configuration.
+ * @param keyStore the key store factory bean to set
+ */
+ public void setKeyStore(KeyStoreFactoryBean keyStore) {
+ this.keyStore = keyStore;
+ }
+
+ /**
+ * Gets the trust store configuration.
+ * @return trust store factory bean or {@code null} if no trust store
+ * configuration was provided
+ */
+ public KeyStoreFactoryBean getTrustStore() {
+ if (trustStore == null) {
+ trustStore = keyStoreFromSystemProperties(JSSE_TRUST_STORE_PROPERTY);
}
-
- /**
- * Sets the trust manager factory configuration.
- * @param trustManagerFactory the factory bean to set
- */
- public void setTrustManagerFactory(TrustManagerFactoryFactoryBean trustManagerFactory) {
- this.trustManagerFactory = trustManagerFactory;
+ return trustStore;
+ }
+
+ /**
+ * Sets the trust store configuration.
+ * @param trustStore the trust store factory bean to set
+ */
+ public void setTrustStore(KeyStoreFactoryBean trustStore) {
+ this.trustStore = trustStore;
+ }
+
+ /**
+ * Constructs a key store factory bean using JSSE system properties.
+ * @param property base property name (e.g. {@code javax.net.ssl.keyStore})
+ * @return key store or {@code null} if no value is defined for the
+ * base system property name
+ */
+ private KeyStoreFactoryBean keyStoreFromSystemProperties(String property) {
+ if (System.getProperty(property) == null) return null;
+ KeyStoreFactoryBean keyStore = new KeyStoreFactoryBean();
+ keyStore.setLocation(locationFromSystemProperty(property));
+ keyStore.setProvider(System.getProperty(property + "Provider"));
+ keyStore.setPassword(System.getProperty(property + "Password"));
+ keyStore.setType(System.getProperty(property + "Type"));
+ return keyStore;
+ }
+
+ /**
+ * Constructs a resource location from a JSSE system property.
+ * @param name property name (e.g. {@code javax.net.ssl.keyStore})
+ * @return URL for the location specified in the property or {@code null}
+ * if no value is defined for the property
+ */
+ private String locationFromSystemProperty(String name) {
+ String location = System.getProperty(name);
+ if (location != null && !location.startsWith("file:")) {
+ location = "file:" + location;
}
-
- /**
- * Gets the secure transport protocol name.
- * @return protocol name (e.g. {@code SSL}, {@code TLS}); the
- * {@link SSL#DEFAULT_PROTOCOL} is returned if no protocol has been
- * configured
- */
- public String getProtocol() {
- if (protocol == null) {
- return SSL.DEFAULT_PROTOCOL;
- }
- return protocol;
+ return location;
+ }
+
+ /**
+ * Gets the secure random generator configuration.
+ * @return secure random factory bean; if no secure random generator
+ * configuration has been set, a default factory bean is returned
+ */
+ public SecureRandomFactoryBean getSecureRandom() {
+ if (secureRandom == null) {
+ return new SecureRandomFactoryBean();
}
-
- /**
- * Sets the secure transport protocol name.
- * @param protocol a protocol name, which must be recognized by the provider
- * specified by {@link #setProvider(String)} or by the platform's
- * default provider if no platform was specified.
- */
- public void setProtocol(String protocol) {
- this.protocol = protocol;
+ return secureRandom;
+ }
+
+ /**
+ * Sets the secure random generator configuration.
+ * @param secureRandom the secure random factory bean to set
+ */
+ public void setSecureRandom(SecureRandomFactoryBean secureRandom) {
+ this.secureRandom = secureRandom;
+ }
+
+ /**
+ * Gets the key manager factory configuration.
+ * @return factory bean; if no key manager factory
+ * configuration has been set, a default factory bean is returned
+ */
+ public KeyManagerFactoryFactoryBean getKeyManagerFactory() {
+ if (keyManagerFactory == null) {
+ return new KeyManagerFactoryFactoryBean();
}
-
- /**
- * Gets the JSSE provider name for the SSL context.
- * @return JSSE provider name
- */
- public String getProvider() {
- return provider;
+ return keyManagerFactory;
+ }
+
+ /**
+ * Sets the key manager factory configuration.
+ * @param keyManagerFactory the key manager factory factory bean to set
+ */
+ public void setKeyManagerFactory(
+ KeyManagerFactoryFactoryBean keyManagerFactory) {
+ this.keyManagerFactory = keyManagerFactory;
+ }
+
+ /**
+ * Gets the trust manager factory configuration.
+ * @return factory bean; if no trust manager factory
+ * configuration has been set, a default factory bean is returned
+ */
+ public TrustManagerFactoryFactoryBean getTrustManagerFactory() {
+ if (trustManagerFactory == null) {
+ return new TrustManagerFactoryFactoryBean();
}
-
- /**
- * Sets the JSSE provider name for the SSL context.
- * @param provider name of the JSSE provider to use in creating the
- * SSL context
- */
- public void setProvider(String provider) {
- this.provider = provider;
+ return trustManagerFactory;
+ }
+
+ /**
+ * Sets the trust manager factory configuration.
+ * @param trustManagerFactory the factory bean to set
+ */
+ public void setTrustManagerFactory(
+ TrustManagerFactoryFactoryBean trustManagerFactory) {
+ this.trustManagerFactory = trustManagerFactory;
+ }
+
+ /**
+ * Gets the secure transport protocol name.
+ * @return protocol name (e.g. {@code SSL}, {@code TLS}); the
+ * {@link SSL#DEFAULT_PROTOCOL} is returned if no protocol has been
+ * configured
+ */
+ public String getProtocol() {
+ if (protocol == null) {
+ return SSL.DEFAULT_PROTOCOL;
}
+ return protocol;
+ }
+
+ /**
+ * Sets the secure transport protocol name.
+ * @param protocol a protocol name, which must be recognized by the provider
+ * specified by {@link #setProvider(String)} or by the platform's
+ * default provider if no platform was specified.
+ */
+ public void setProtocol(String protocol) {
+ this.protocol = protocol;
+ }
+
+ /**
+ * Gets the JSSE provider name for the SSL context.
+ * @return JSSE provider name
+ */
+ public String getProvider() {
+ return provider;
+ }
+
+ /**
+ * Sets the JSSE provider name for the SSL context.
+ * @param provider name of the JSSE provider to use in creating the
+ * SSL context
+ */
+ public void setProvider(String provider) {
+ this.provider = provider;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLNestedComponentRegistryRules.java b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLNestedComponentRegistryRules.java
index e446990..6f02509 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLNestedComponentRegistryRules.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLNestedComponentRegistryRules.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,14 +23,21 @@ import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
*/
public class SSLNestedComponentRegistryRules {
- static public void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
- registry.add(SSLComponent.class, "ssl", SSLConfiguration.class);
- registry.add(SSLConfiguration.class, "parameters", SSLParametersConfiguration.class);
- registry.add(SSLConfiguration.class, "keyStore", KeyStoreFactoryBean.class);
- registry.add(SSLConfiguration.class, "trustStore", KeyStoreFactoryBean.class);
- registry.add(SSLConfiguration.class, "keyManagerFactory", KeyManagerFactoryFactoryBean.class);
- registry.add(SSLConfiguration.class, "trustManagerFactory", TrustManagerFactoryFactoryBean.class);
- registry.add(SSLConfiguration.class, "secureRandom", SecureRandomFactoryBean.class);
- }
+ static public void addDefaultNestedComponentRegistryRules(
+ DefaultNestedComponentRegistry registry) {
+ registry.add(SSLComponent.class, "ssl", SSLConfiguration.class);
+ registry.add(SSLConfiguration.class, "parameters",
+ SSLParametersConfiguration.class);
+ registry.add(SSLConfiguration.class, "keyStore",
+ KeyStoreFactoryBean.class);
+ registry.add(SSLConfiguration.class, "trustStore",
+ KeyStoreFactoryBean.class);
+ registry.add(SSLConfiguration.class, "keyManagerFactory",
+ KeyManagerFactoryFactoryBean.class);
+ registry.add(SSLConfiguration.class, "trustManagerFactory",
+ TrustManagerFactoryFactoryBean.class);
+ registry.add(SSLConfiguration.class, "secureRandom",
+ SecureRandomFactoryBean.class);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLParametersConfiguration.java b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLParametersConfiguration.java
index 81f6bce..efdd73a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLParametersConfiguration.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLParametersConfiguration.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,6 +25,7 @@ import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.util.OptionHelper;
import ch.qos.logback.core.util.StringCollectionUtil;
+
/**
* A configuration of SSL parameters for an {@link SSLEngine}.
*
@@ -32,211 +33,224 @@ import ch.qos.logback.core.util.StringCollectionUtil;
*/
public class SSLParametersConfiguration extends ContextAwareBase {
- private String includedProtocols;
- private String excludedProtocols;
- private String includedCipherSuites;
- private String excludedCipherSuites;
- private Boolean needClientAuth;
- private Boolean wantClientAuth;
- private String[] enabledProtocols;
- private String[] enabledCipherSuites;
-
- /**
- * Configures SSL parameters on an {@link SSLConfigurable}.
- * @param socket the subject configurable
- */
- public void configure(SSLConfigurable socket) {
- socket.setEnabledProtocols(enabledProtocols(socket.getSupportedProtocols(), socket.getDefaultProtocols()));
- socket.setEnabledCipherSuites(enabledCipherSuites(socket.getSupportedCipherSuites(), socket.getDefaultCipherSuites()));
- if (isNeedClientAuth() != null) {
- socket.setNeedClientAuth(isNeedClientAuth());
- }
- if (isWantClientAuth() != null) {
- socket.setWantClientAuth(isWantClientAuth());
- }
+ private String includedProtocols;
+ private String excludedProtocols;
+ private String includedCipherSuites;
+ private String excludedCipherSuites;
+ private Boolean needClientAuth;
+ private Boolean wantClientAuth;
+ private String[] enabledProtocols;
+ private String[] enabledCipherSuites;
+
+ /**
+ * Configures SSL parameters on an {@link SSLConfigurable}.
+ * @param socket the subject configurable
+ */
+ public void configure(SSLConfigurable socket) {
+ socket.setEnabledProtocols(enabledProtocols(
+ socket.getSupportedProtocols(), socket.getDefaultProtocols()));
+ socket.setEnabledCipherSuites(enabledCipherSuites(
+ socket.getSupportedCipherSuites(), socket.getDefaultCipherSuites()));
+ if (isNeedClientAuth() != null) {
+ socket.setNeedClientAuth(isNeedClientAuth());
}
-
- /**
- * Gets the set of enabled protocols based on the configuration.
- * @param supportedProtocols protocols supported by the SSL engine
- * @param defaultProtocols default protocols enabled by the SSL engine
- * @return enabled protocols
- */
- private String[] enabledProtocols(String[] supportedProtocols, String[] defaultProtocols) {
- if (enabledProtocols == null) {
- // we're assuming that the same engine is used for all configurables
- // so once we determine the enabled set, we won't do it again
- if (OptionHelper.isEmpty(getIncludedProtocols()) && OptionHelper.isEmpty(getExcludedProtocols())) {
- enabledProtocols = Arrays.copyOf(defaultProtocols, defaultProtocols.length);
- } else {
- enabledProtocols = includedStrings(supportedProtocols, getIncludedProtocols(), getExcludedProtocols());
- }
- for (String protocol : enabledProtocols) {
- addInfo("enabled protocol: " + protocol);
- }
- }
- return enabledProtocols;
+ if (isWantClientAuth() != null) {
+ socket.setWantClientAuth(isWantClientAuth());
}
-
- /**
- * Gets the set of enabled cipher suites based on the configuration.
- * @param supportedCipherSuites cipher suites supported by the SSL engine
- * @param defaultCipherSuites default cipher suites enabled by the SSL engine
- * @return enabled cipher suites
- */
- private String[] enabledCipherSuites(String[] supportedCipherSuites, String[] defaultCipherSuites) {
- if (enabledCipherSuites == null) {
- // we're assuming that the same engine is used for all configurables
- // so once we determine the enabled set, we won't do it again
- if (OptionHelper.isEmpty(getIncludedCipherSuites()) && OptionHelper.isEmpty(getExcludedCipherSuites())) {
- enabledCipherSuites = Arrays.copyOf(defaultCipherSuites, defaultCipherSuites.length);
- } else {
- enabledCipherSuites = includedStrings(supportedCipherSuites, getIncludedCipherSuites(), getExcludedCipherSuites());
- }
- for (String cipherSuite : enabledCipherSuites) {
- addInfo("enabled cipher suite: " + cipherSuite);
- }
- }
- return enabledCipherSuites;
+ }
+
+ /**
+ * Gets the set of enabled protocols based on the configuration.
+ * @param supportedProtocols protocols supported by the SSL engine
+ * @param defaultProtocols default protocols enabled by the SSL engine
+ * @return enabled protocols
+ */
+ private String[] enabledProtocols(String[] supportedProtocols,
+ String[] defaultProtocols) {
+ if (enabledProtocols == null) {
+ // we're assuming that the same engine is used for all configurables
+ // so once we determine the enabled set, we won't do it again
+ if (OptionHelper.isEmpty(getIncludedProtocols())
+ && OptionHelper.isEmpty(getExcludedProtocols())) {
+ enabledProtocols = Arrays.copyOf(defaultProtocols,
+ defaultProtocols.length);
+ }
+ else {
+ enabledProtocols = includedStrings(supportedProtocols,
+ getIncludedProtocols(), getExcludedProtocols());
+ }
+ for (String protocol : enabledProtocols) {
+ addInfo("enabled protocol: " + protocol);
+ }
}
-
- /**
- * Applies include and exclude patterns to an array of default string values
- * to produce an array of strings included by the patterns.
- * @param defaults default list of string values
- * @param included comma-separated patterns that identity values to include
- * @param excluded comma-separated patterns that identity string to exclude
- * @return an array of strings containing those strings from {@code defaults}
- * that match at least one pattern in {@code included} that are not
- * matched by any pattern in {@code excluded}
- */
- private String[] includedStrings(String[] defaults, String included, String excluded) {
- List<String> values = new ArrayList<String>(defaults.length);
- values.addAll(Arrays.asList(defaults));
- if (included != null) {
- StringCollectionUtil.retainMatching(values, stringToArray(included));
- }
- if (excluded != null) {
- StringCollectionUtil.removeMatching(values, stringToArray(excluded));
- }
- return values.toArray(new String[values.size()]);
+ return enabledProtocols;
+ }
+
+ /**
+ * Gets the set of enabled cipher suites based on the configuration.
+ * @param supportedCipherSuites cipher suites supported by the SSL engine
+ * @param defaultCipherSuites default cipher suites enabled by the SSL engine
+ * @return enabled cipher suites
+ */
+ private String[] enabledCipherSuites(String[] supportedCipherSuites,
+ String[] defaultCipherSuites) {
+ if (enabledCipherSuites == null) {
+ // we're assuming that the same engine is used for all configurables
+ // so once we determine the enabled set, we won't do it again
+ if (OptionHelper.isEmpty(getIncludedCipherSuites())
+ && OptionHelper.isEmpty(getExcludedCipherSuites())) {
+ enabledCipherSuites = Arrays.copyOf(defaultCipherSuites,
+ defaultCipherSuites.length);
+ }
+ else {
+ enabledCipherSuites = includedStrings(supportedCipherSuites,
+ getIncludedCipherSuites(), getExcludedCipherSuites());
+ }
+ for (String cipherSuite : enabledCipherSuites) {
+ addInfo("enabled cipher suite: " + cipherSuite);
+ }
}
-
- /**
- * Splits a string containing comma-separated values into an array.
- * @param s the subject string
- * @return array of values contained in {@code s}
- */
- private String[] stringToArray(String s) {
- return s.split("\\s*,\\s*");
+ return enabledCipherSuites;
+ }
+
+ /**
+ * Applies include and exclude patterns to an array of default string values
+ * to produce an array of strings included by the patterns.
+ * @param defaults default list of string values
+ * @param included comma-separated patterns that identity values to include
+ * @param excluded comma-separated patterns that identity string to exclude
+ * @return an array of strings containing those strings from {@code defaults}
+ * that match at least one pattern in {@code included} that are not
+ * matched by any pattern in {@code excluded}
+ */
+ private String[] includedStrings(String[] defaults, String included,
+ String excluded) {
+ List<String> values = new ArrayList<String>(defaults.length);
+ values.addAll(Arrays.asList(defaults));
+ if (included != null) {
+ StringCollectionUtil.retainMatching(values, stringToArray(included));
}
-
- /**
- * Gets the JSSE secure transport protocols to include.
- * @return a string containing comma-separated JSSE secure transport
- * protocol names (e.g. {@code TLSv1})
- */
- public String getIncludedProtocols() {
- return includedProtocols;
+ if (excluded != null) {
+ StringCollectionUtil.removeMatching(values, stringToArray(excluded));
}
+ return values.toArray(new String[values.size()]);
+ }
+
+ /**
+ * Splits a string containing comma-separated values into an array.
+ * @param s the subject string
+ * @return array of values contained in {@code s}
+ */
+ private String[] stringToArray(String s) {
+ return s.split("\\s*,\\s*");
+ }
+
+ /**
+ * Gets the JSSE secure transport protocols to include.
+ * @return a string containing comma-separated JSSE secure transport
+ * protocol names (e.g. {@code TLSv1})
+ */
+ public String getIncludedProtocols() {
+ return includedProtocols;
+ }
- /**
- * Sets the JSSE secure transport protocols to include.
- * @param protocols a string containing comma-separated JSSE secure
- * transport protocol names
- * @see Java Cryptography Architecture Standard Algorithm Name Documentation
- */
- public void setIncludedProtocols(String protocols) {
- this.includedProtocols = protocols;
- }
+ /**
+ * Sets the JSSE secure transport protocols to include.
+ * @param protocols a string containing comma-separated JSSE secure
+ * transport protocol names
+ * @see Java Cryptography Architecture Standard Algorithm Name Documentation
+ */
+ public void setIncludedProtocols(String protocols) {
+ this.includedProtocols = protocols;
+ }
- /**
- * Gets the JSSE secure transport protocols to exclude.
- * @return a string containing comma-separated JSSE secure transport
- * protocol names (e.g. {@code TLSv1})
- */
- public String getExcludedProtocols() {
- return excludedProtocols;
- }
+ /**
+ * Gets the JSSE secure transport protocols to exclude.
+ * @return a string containing comma-separated JSSE secure transport
+ * protocol names (e.g. {@code TLSv1})
+ */
+ public String getExcludedProtocols() {
+ return excludedProtocols;
+ }
- /**
- * Sets the JSSE secure transport protocols to exclude.
- * @param protocols a string containing comma-separated JSSE secure
- * transport protocol names
- * @see Java Cryptography Architecture Standard Algorithm Name Documentation
- */
- public void setExcludedProtocols(String protocols) {
- this.excludedProtocols = protocols;
- }
+ /**
+ * Sets the JSSE secure transport protocols to exclude.
+ * @param protocols a string containing comma-separated JSSE secure
+ * transport protocol names
+ * @see Java Cryptography Architecture Standard Algorithm Name Documentation
+ */
+ public void setExcludedProtocols(String protocols) {
+ this.excludedProtocols = protocols;
+ }
- /**
- * Gets the JSSE cipher suite names to include.
- * @return a string containing comma-separated JSSE cipher suite names
- * (e.g. {@code TLS_DHE_RSA_WITH_AES_256_CBC_SHA})
- */
- public String getIncludedCipherSuites() {
- return includedCipherSuites;
- }
+ /**
+ * Gets the JSSE cipher suite names to include.
+ * @return a string containing comma-separated JSSE cipher suite names
+ * (e.g. {@code TLS_DHE_RSA_WITH_AES_256_CBC_SHA})
+ */
+ public String getIncludedCipherSuites() {
+ return includedCipherSuites;
+ }
- /**
- * Sets the JSSE cipher suite names to include.
- * @param cipherSuites a string containing comma-separated JSSE cipher
- * suite names
- * @see Java Cryptography Architecture Standard Algorithm Name Documentation
- */
- public void setIncludedCipherSuites(String cipherSuites) {
- this.includedCipherSuites = cipherSuites;
- }
+ /**
+ * Sets the JSSE cipher suite names to include.
+ * @param cipherSuites a string containing comma-separated JSSE cipher
+ * suite names
+ * @see Java Cryptography Architecture Standard Algorithm Name Documentation
+ */
+ public void setIncludedCipherSuites(String cipherSuites) {
+ this.includedCipherSuites = cipherSuites;
+ }
- /**
- * Gets the JSSE cipher suite names to exclude.
- * @return a string containing comma-separated JSSE cipher suite names
- * (e.g. {@code TLS_DHE_RSA_WITH_AES_256_CBC_SHA})
- */
- public String getExcludedCipherSuites() {
- return excludedCipherSuites;
- }
+ /**
+ * Gets the JSSE cipher suite names to exclude.
+ * @return a string containing comma-separated JSSE cipher suite names
+ * (e.g. {@code TLS_DHE_RSA_WITH_AES_256_CBC_SHA})
+ */
+ public String getExcludedCipherSuites() {
+ return excludedCipherSuites;
+ }
- /**
- * Sets the JSSE cipher suite names to exclude.
- * @param cipherSuites a string containing comma-separated JSSE cipher
- * suite names
- * @see Java Cryptography Architecture Standard Algorithm Name Documentation
- */
- public void setExcludedCipherSuites(String cipherSuites) {
- this.excludedCipherSuites = cipherSuites;
- }
+ /**
+ * Sets the JSSE cipher suite names to exclude.
+ * @param cipherSuites a string containing comma-separated JSSE cipher
+ * suite names
+ * @see Java Cryptography Architecture Standard Algorithm Name Documentation
+ */
+ public void setExcludedCipherSuites(String cipherSuites) {
+ this.excludedCipherSuites = cipherSuites;
+ }
- /**
- * Gets a flag indicating whether client authentication is required.
- * @return flag state
- */
- public Boolean isNeedClientAuth() {
- return needClientAuth;
- }
+ /**
+ * Gets a flag indicating whether client authentication is required.
+ * @return flag state
+ */
+ public Boolean isNeedClientAuth() {
+ return needClientAuth;
+ }
- /**
- * Sets a flag indicating whether client authentication is required.
- * @param needClientAuth the flag state to set
- */
- public void setNeedClientAuth(Boolean needClientAuth) {
- this.needClientAuth = needClientAuth;
- }
+ /**
+ * Sets a flag indicating whether client authentication is required.
+ * @param needClientAuth the flag state to set
+ */
+ public void setNeedClientAuth(Boolean needClientAuth) {
+ this.needClientAuth = needClientAuth;
+ }
- /**
- * Gets a flag indicating whether client authentication is desired.
- * @return flag state
- */
- public Boolean isWantClientAuth() {
- return wantClientAuth;
- }
+ /**
+ * Gets a flag indicating whether client authentication is desired.
+ * @return flag state
+ */
+ public Boolean isWantClientAuth() {
+ return wantClientAuth;
+ }
- /**
- * Sets a flag indicating whether client authentication is desired.
- * @param wantClientAuth the flag state to set
- */
- public void setWantClientAuth(Boolean wantClientAuth) {
- this.wantClientAuth = wantClientAuth;
- }
+ /**
+ * Sets a flag indicating whether client authentication is desired.
+ * @param wantClientAuth the flag state to set
+ */
+ public void setWantClientAuth(Boolean wantClientAuth) {
+ this.wantClientAuth = wantClientAuth;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SecureRandomFactoryBean.java b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SecureRandomFactoryBean.java
index cedfc4c..9f56532 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SecureRandomFactoryBean.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SecureRandomFactoryBean.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,68 +27,75 @@ import java.security.SecureRandom;
*/
public class SecureRandomFactoryBean {
- private String algorithm;
- private String provider;
+ private String algorithm;
+ private String provider;
- /**
- * Creates a new {@link SecureRandom} generator using the receiver's
- * configuration.
- * @return secure random generator instance
- * @throws NoSuchProviderException if the provider name specified by
- * {@link #setProvider(String)} is not known to the platform
- * @throws NoSuchAlgorithmException if the algorithm name specified by
- * {@link #setAlgorithm(String)} is not recognized by the specified
- * provider (or the platform's default provider if the provider isn't
- * specified)
- */
- public SecureRandom createSecureRandom() throws NoSuchProviderException, NoSuchAlgorithmException {
- try {
- return getProvider() != null ? SecureRandom.getInstance(getAlgorithm(), getProvider()) : SecureRandom.getInstance(getAlgorithm());
- } catch (NoSuchProviderException ex) {
- throw new NoSuchProviderException("no such secure random provider: " + getProvider());
- } catch (NoSuchAlgorithmException ex) {
- throw new NoSuchAlgorithmException("no such secure random algorithm: " + getAlgorithm());
- }
+ /**
+ * Creates a new {@link SecureRandom} generator using the receiver's
+ * configuration.
+ * @return secure random generator instance
+ * @throws NoSuchProviderException if the provider name specified by
+ * {@link #setProvider(String)} is not known to the platform
+ * @throws NoSuchAlgorithmException if the algorithm name specified by
+ * {@link #setAlgorithm(String)} is not recognized by the specified
+ * provider (or the platform's default provider if the provider isn't
+ * specified)
+ */
+ public SecureRandom createSecureRandom() throws NoSuchProviderException,
+ NoSuchAlgorithmException {
+ try {
+ return getProvider() != null ?
+ SecureRandom.getInstance(getAlgorithm(), getProvider())
+ : SecureRandom.getInstance(getAlgorithm());
}
-
- /**
- * Gets the secure random generator algorithm name.
- * @return an algorithm name (e.g. {@code SHA1PRNG}); the
- * {@link SSL#DEFAULT_SECURE_RANDOM_ALGORITHM} is returned if no algorithm has been
- * specified
- */
- public String getAlgorithm() {
- if (algorithm == null) {
- return SSL.DEFAULT_SECURE_RANDOM_ALGORITHM;
- }
- return algorithm;
+ catch (NoSuchProviderException ex) {
+ throw new NoSuchProviderException("no such secure random provider: "
+ + getProvider());
}
-
- /**
- * Sets the secure random generator algorithm name.
- * @param algorithm an algorithm name, which must be recognized by the
- * provider specified via {@link #setProvider(String)} or by the
- * platform's default provider if no provider is specified.
- */
- public void setAlgorithm(String algorithm) {
- this.algorithm = algorithm;
+ catch (NoSuchAlgorithmException ex) {
+ throw new NoSuchAlgorithmException("no such secure random algorithm: "
+ + getAlgorithm());
}
-
- /**
- * Gets the JCA provider name for the secure random generator.
- * @return provider name
- */
- public String getProvider() {
- return provider;
+ }
+
+ /**
+ * Gets the secure random generator algorithm name.
+ * @return an algorithm name (e.g. {@code SHA1PRNG}); the
+ * {@link SSL#DEFAULT_SECURE_RANDOM_ALGORITHM} is returned if no algorithm has been
+ * specified
+ */
+ public String getAlgorithm() {
+ if (algorithm == null) {
+ return SSL.DEFAULT_SECURE_RANDOM_ALGORITHM;
}
+ return algorithm;
+ }
- /**
- * Sets the JCA provider name for the secure random generator.
- * @param provider name of the JCA provider to utilize in creating the
- * secure random generator
- */
- public void setProvider(String provider) {
- this.provider = provider;
- }
+ /**
+ * Sets the secure random generator algorithm name.
+ * @param algorithm an algorithm name, which must be recognized by the
+ * provider specified via {@link #setProvider(String)} or by the
+ * platform's default provider if no provider is specified.
+ */
+ public void setAlgorithm(String algorithm) {
+ this.algorithm = algorithm;
+ }
+
+ /**
+ * Gets the JCA provider name for the secure random generator.
+ * @return provider name
+ */
+ public String getProvider() {
+ return provider;
+ }
+
+ /**
+ * Sets the JCA provider name for the secure random generator.
+ * @param provider name of the JCA provider to utilize in creating the
+ * secure random generator
+ */
+ public void setProvider(String provider) {
+ this.provider = provider;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/TrustManagerFactoryFactoryBean.java b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/TrustManagerFactoryFactoryBean.java
index 0f1c112..6043a71 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/TrustManagerFactoryFactoryBean.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/TrustManagerFactoryFactoryBean.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,61 +28,64 @@ import javax.net.ssl.TrustManagerFactory;
*/
public class TrustManagerFactoryFactoryBean {
- private String algorithm;
- private String provider;
+ private String algorithm;
+ private String provider;
- /**
- * Creates a {@link TrustManagerFactory} using the receiver's configuration.
- * @return factory object
- * @throws NoSuchProviderException if the provider specified by
- * {@link #setProvider(String)} is not known to the platform
- * @throws NoSuchAlgorithmException if the algorithm specified by
- * {@link #setAlgorithm(String)} is not known to the specified provider
- * (or to the default platform provider if no provider is specified)
- */
- public TrustManagerFactory createTrustManagerFactory() throws NoSuchProviderException, NoSuchAlgorithmException {
-
- return getProvider() != null ? TrustManagerFactory.getInstance(getAlgorithm(), getProvider()) : TrustManagerFactory.getInstance(getAlgorithm());
- }
-
- /**
- * Gets the algorithm name for the trust manager factory.
- * @return algorithm name (e.g. {@code PKIX}); the default algorithm
- * (obtained from {@link TrustManagerFactory#getDefaultAlgorithm()})
- * is returned if no algorithm has been configured
- */
- public String getAlgorithm() {
- if (algorithm == null) {
- return TrustManagerFactory.getDefaultAlgorithm();
- }
- return algorithm;
+ /**
+ * Creates a {@link TrustManagerFactory} using the receiver's configuration.
+ * @return factory object
+ * @throws NoSuchProviderException if the provider specified by
+ * {@link #setProvider(String)} is not known to the platform
+ * @throws NoSuchAlgorithmException if the algorithm specified by
+ * {@link #setAlgorithm(String)} is not known to the specified provider
+ * (or to the default platform provider if no provider is specified)
+ */
+ public TrustManagerFactory createTrustManagerFactory()
+ throws NoSuchProviderException, NoSuchAlgorithmException {
+
+ return getProvider() != null ?
+ TrustManagerFactory.getInstance(getAlgorithm(), getProvider())
+ : TrustManagerFactory.getInstance(getAlgorithm());
+ }
+
+ /**
+ * Gets the algorithm name for the trust manager factory.
+ * @return algorithm name (e.g. {@code PKIX}); the default algorithm
+ * (obtained from {@link TrustManagerFactory#getDefaultAlgorithm()})
+ * is returned if no algorithm has been configured
+ */
+ public String getAlgorithm() {
+ if (algorithm == null) {
+ return TrustManagerFactory.getDefaultAlgorithm();
}
+ return algorithm;
+ }
- /**
- * Sets the algorithm name for the trust manager factory.
- * @param algorithm an algorithm name, which must be recognized by the
- * provider specified by {@link #setProvider(String)} or by the
- * platform's default provider if no provider is specified.
- */
- public void setAlgorithm(String algorithm) {
- this.algorithm = algorithm;
- }
+ /**
+ * Sets the algorithm name for the trust manager factory.
+ * @param algorithm an algorithm name, which must be recognized by the
+ * provider specified by {@link #setProvider(String)} or by the
+ * platform's default provider if no provider is specified.
+ */
+ public void setAlgorithm(String algorithm) {
+ this.algorithm = algorithm;
+ }
- /**
- * Gets the JSSE provider name for the trust manager factory.
- * @return provider name
- */
- public String getProvider() {
- return provider;
- }
+ /**
+ * Gets the JSSE provider name for the trust manager factory.
+ * @return provider name
+ */
+ public String getProvider() {
+ return provider;
+ }
- /**
- * Sets the JSSE provider name for the trust manager factory.
- * @param provider name of the JSSE provider to utilize in creating the
- * trust manager factory
- */
- public void setProvider(String provider) {
- this.provider = provider;
- }
+ /**
+ * Sets the JSSE provider name for the trust manager factory.
+ * @param provider name of the JSSE provider to utilize in creating the
+ * trust manager factory
+ */
+ public void setProvider(String provider) {
+ this.provider = provider;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/CompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/CompositeConverter.java
index d0d331e..2e8158f 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/CompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/CompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,39 +15,39 @@ package ch.qos.logback.core.pattern;
abstract public class CompositeConverter<E> extends DynamicConverter<E> {
- Converter<E> childConverter;
+ Converter<E> childConverter;
- public String convert(E event) {
- StringBuilder buf = new StringBuilder();
+ public String convert(E event) {
+ StringBuilder buf = new StringBuilder();
- for (Converter<E> c = childConverter; c != null; c = c.next) {
- c.write(buf, event);
- }
- String intermediary = buf.toString();
- return transform(event, intermediary);
+ for (Converter<E> c = childConverter; c != null; c = c.next) {
+ c.write(buf, event);
}
+ String intermediary = buf.toString();
+ return transform(event, intermediary);
+ }
- abstract protected String transform(E event, String in);
+ abstract protected String transform(E event, String in);
- public Converter<E> getChildConverter() {
- return childConverter;
- }
+ public Converter<E> getChildConverter() {
+ return childConverter;
+ }
- public void setChildConverter(Converter<E> child) {
- childConverter = child;
- }
+ public void setChildConverter(Converter<E> child) {
+ childConverter = child;
+ }
- public String toString() {
- StringBuilder buf = new StringBuilder();
- buf.append("CompositeConverter<");
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ buf.append("CompositeConverter<");
- if (formattingInfo != null)
- buf.append(formattingInfo);
+ if (formattingInfo != null)
+ buf.append(formattingInfo);
- if (childConverter != null) {
- buf.append(", children: ").append(childConverter);
- }
- buf.append(">");
- return buf.toString();
+ if (childConverter != null) {
+ buf.append(", children: ").append(childConverter);
}
+ buf.append(">");
+ return buf.toString();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/Converter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/Converter.java
index 6dbefcd..f8e4e9e 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/Converter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/Converter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,36 +20,36 @@ package ch.qos.logback.core.pattern;
* @author ceki
*/
abstract public class Converter<E> {
+
+ Converter<E> next;
- Converter<E> next;
+ /**
+ * The convert method is responsible for extracting data from the event and
+ * storing it for later use by the write method.
+ *
+ * @param event
+ */
+ public abstract String convert(E event);
- /**
- * The convert method is responsible for extracting data from the event and
- * storing it for later use by the write method.
- *
- * @param event
- */
- public abstract String convert(E event);
-
- /**
- * In its simplest incarnation, a convert simply appends the data extracted from
- * the event to the buffer passed as parameter.
- *
- * @param buf The input buffer where data is appended
- * @param event The event from where data is extracted
- */
- public void write(StringBuilder buf, E event) {
- buf.append(convert(event));
- }
-
- public final void setNext(Converter<E> next) {
- if (this.next != null) {
- throw new IllegalStateException("Next converter has been already set");
- }
- this.next = next;
+ /**
+ * In its simplest incarnation, a convert simply appends the data extracted from
+ * the event to the buffer passed as parameter.
+ *
+ * @param buf The input buffer where data is appended
+ * @param event The event from where data is extracted
+ */
+ public void write(StringBuilder buf, E event) {
+ buf.append(convert(event));
+ }
+
+ public final void setNext(Converter<E> next) {
+ if (this.next != null) {
+ throw new IllegalStateException("Next converter has been already set");
}
+ this.next = next;
+ }
- public final Converter<E> getNext() {
- return next;
- }
+ public final Converter<E> getNext() {
+ return next;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/ConverterUtil.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/ConverterUtil.java
index d13e3eb..1c4682d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/ConverterUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/ConverterUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,48 +18,49 @@ import ch.qos.logback.core.spi.ContextAware;
public class ConverterUtil {
- /**
- * Start converters in the chain of converters.
- *
- * @param head
- */
- public static <E> void startConverters(Converter<E> head) {
- Converter<E> c = head;
- while (c != null) {
- // CompositeConverter is a subclass of DynamicConverter
- if (c instanceof CompositeConverter) {
- CompositeConverter<E> cc = (CompositeConverter<E>) c;
- Converter<E> childConverter = cc.childConverter;
- startConverters(childConverter);
- cc.start();
- } else if (c instanceof DynamicConverter) {
- DynamicConverter<E> dc = (DynamicConverter<E>) c;
- dc.start();
- }
- c = c.getNext();
- }
+ /**
+ * Start converters in the chain of converters.
+ *
+ * @param head
+ */
+ public static <E> void startConverters(Converter<E> head) {
+ Converter<E> c = head;
+ while (c != null) {
+ // CompositeConverter is a subclass of DynamicConverter
+ if (c instanceof CompositeConverter) {
+ CompositeConverter<E> cc = (CompositeConverter<E>) c;
+ Converter<E> childConverter = cc.childConverter;
+ startConverters(childConverter);
+ cc.start();
+ } else if (c instanceof DynamicConverter) {
+ DynamicConverter<E> dc = (DynamicConverter<E>) c;
+ dc.start();
+ }
+ c = c.getNext();
}
+ }
- public static <E> Converter<E> findTail(Converter<E> head) {
- Converter<E> p = head;
- while (p != null) {
- Converter<E> next = p.getNext();
- if (next == null) {
- break;
- } else {
- p = next;
- }
- }
- return p;
+
+ public static <E> Converter<E> findTail(Converter<E> head) {
+ Converter<E> p = head;
+ while (p != null) {
+ Converter<E> next = p.getNext();
+ if (next == null) {
+ break;
+ } else {
+ p = next;
+ }
}
+ return p;
+ }
- public static <E> void setContextForConverters(Context context, Converter<E> head) {
- Converter<E> c = head;
- while (c != null) {
- if (c instanceof ContextAware) {
- ((ContextAware) c).setContext(context);
- }
- c = c.getNext();
- }
+ public static <E> void setContextForConverters(Context context, Converter<E> head) {
+ Converter<E> c = head;
+ while (c != null) {
+ if (c instanceof ContextAware) {
+ ((ContextAware) c).setContext(context);
+ }
+ c = c.getNext();
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/DynamicConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/DynamicConverter.java
index 4351b95..2967a60 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/DynamicConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/DynamicConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,91 +21,92 @@ import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.spi.LifeCycle;
import ch.qos.logback.core.status.Status;
-abstract public class DynamicConverter<E> extends FormattingConverter<E> implements LifeCycle, ContextAware {
-
- ContextAwareBase cab = new ContextAwareBase(this);
-
- // Contains a list of option Strings.
- private List<String> optionList;
-
- /**
- * Is this component active?
- */
- protected boolean started = false;
-
- /**
- * Components that depend on options passed during configuration can override
- * this method in order to make appropriate use of those options. For simpler
- * components, the trivial implementation found in this abstract class will be
- * sufficient.
- */
- public void start() {
- started = true;
- }
-
- public void stop() {
- started = false;
- }
-
- public boolean isStarted() {
- return started;
- }
-
- public void setOptionList(List<String> optionList) {
- this.optionList = optionList;
- }
-
- /**
- * Return the first option passed to this component. The returned value may be
- * null if there are no options.
- *
- * @return First option, may be null.
- */
- public String getFirstOption() {
- if (optionList == null || optionList.size() == 0) {
- return null;
- } else {
- return optionList.get(0);
- }
+abstract public class DynamicConverter<E> extends FormattingConverter<E>
+ implements LifeCycle, ContextAware {
+
+ ContextAwareBase cab = new ContextAwareBase(this);
+
+ // Contains a list of option Strings.
+ private List<String> optionList;
+
+ /**
+ * Is this component active?
+ */
+ protected boolean started = false;
+
+ /**
+ * Components that depend on options passed during configuration can override
+ * this method in order to make appropriate use of those options. For simpler
+ * components, the trivial implementation found in this abstract class will be
+ * sufficient.
+ */
+ public void start() {
+ started = true;
+ }
+
+ public void stop() {
+ started = false;
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public void setOptionList(List<String> optionList) {
+ this.optionList = optionList;
+ }
+
+ /**
+ * Return the first option passed to this component. The returned value may be
+ * null if there are no options.
+ *
+ * @return First option, may be null.
+ */
+ public String getFirstOption() {
+ if (optionList == null || optionList.size() == 0) {
+ return null;
+ } else {
+ return optionList.get(0);
}
+ }
- protected List<String> getOptionList() {
- return optionList;
- }
+ protected List<String> getOptionList() {
+ return optionList;
+ }
- public void setContext(Context context) {
- cab.setContext(context);
- }
+ public void setContext(Context context) {
+ cab.setContext(context);
+ }
- public Context getContext() {
- return cab.getContext();
- }
+ public Context getContext() {
+ return cab.getContext();
+ }
- public void addStatus(Status status) {
- cab.addStatus(status);
- }
+ public void addStatus(Status status) {
+ cab.addStatus(status);
+ }
- public void addInfo(String msg) {
- cab.addInfo(msg);
- }
+ public void addInfo(String msg) {
+ cab.addInfo(msg);
+ }
- public void addInfo(String msg, Throwable ex) {
- cab.addInfo(msg, ex);
- }
+ public void addInfo(String msg, Throwable ex) {
+ cab.addInfo(msg, ex);
+ }
- public void addWarn(String msg) {
- cab.addWarn(msg);
- }
+ public void addWarn(String msg) {
+ cab.addWarn(msg);
+ }
- public void addWarn(String msg, Throwable ex) {
- cab.addWarn(msg, ex);
- }
+ public void addWarn(String msg, Throwable ex) {
+ cab.addWarn(msg, ex);
+ }
- public void addError(String msg) {
- cab.addError(msg);
- }
+ public void addError(String msg) {
+ cab.addError(msg);
+ }
- public void addError(String msg, Throwable ex) {
- cab.addError(msg, ex);
- }
+ public void addError(String msg, Throwable ex) {
+ cab.addError(msg, ex);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/FormatInfo.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/FormatInfo.java
index 8f2a394..d59817d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/FormatInfo.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/FormatInfo.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,133 +20,136 @@ package ch.qos.logback.core.pattern;
* @author Ceki Gülcü
*/
public class FormatInfo {
- private int min = Integer.MIN_VALUE;
- private int max = Integer.MAX_VALUE;
- private boolean leftPad = true;
- private boolean leftTruncate = true;
-
- public FormatInfo() {
+ private int min = Integer.MIN_VALUE;
+ private int max = Integer.MAX_VALUE;
+ private boolean leftPad = true;
+ private boolean leftTruncate = true;
+
+ public FormatInfo() {
+ }
+
+ public FormatInfo(int min, int max) {
+ this.min = min;
+ this.max = max;
+ }
+
+ public FormatInfo(int min, int max, boolean leftPad, boolean leftTruncate) {
+ this.min = min;
+ this.max = max;
+ this.leftPad = leftPad;
+ this.leftTruncate = leftTruncate;
+ }
+
+ /**
+ * This method is used to parse a string such as "5", ".7", "5.7" or "-5.7" into
+ * a FormatInfo.
+ *
+ * @param str A String to convert into a FormatInfo object
+ * @return A newly created and appropriately initialized FormatInfo object.
+ * @throws IllegalArgumentException
+ */
+ public static FormatInfo valueOf(String str) throws IllegalArgumentException {
+ if (str == null) {
+ throw new NullPointerException("Argument cannot be null");
}
- public FormatInfo(int min, int max) {
- this.min = min;
- this.max = max;
+ FormatInfo fi = new FormatInfo();
+
+ int indexOfDot = str.indexOf('.');
+ String minPart = null;
+ String maxPart = null;
+ if (indexOfDot != -1) {
+ minPart = str.substring(0, indexOfDot);
+ if (indexOfDot + 1 == str.length()) {
+ throw new IllegalArgumentException("Formatting string [" + str
+ + "] should not end with '.'");
+ } else {
+ maxPart = str.substring(indexOfDot + 1);
+ }
+ } else {
+ minPart = str;
}
- public FormatInfo(int min, int max, boolean leftPad, boolean leftTruncate) {
- this.min = min;
- this.max = max;
- this.leftPad = leftPad;
- this.leftTruncate = leftTruncate;
+ if (minPart != null && minPart.length() > 0) {
+ int min = Integer.parseInt(minPart);
+ if (min >= 0) {
+ fi.min = min;
+ } else {
+ fi.min = -min;
+ fi.leftPad = false;
+ }
}
- /**
- * This method is used to parse a string such as "5", ".7", "5.7" or "-5.7" into
- * a FormatInfo.
- *
- * @param str A String to convert into a FormatInfo object
- * @return A newly created and appropriately initialized FormatInfo object.
- * @throws IllegalArgumentException
- */
- public static FormatInfo valueOf(String str) throws IllegalArgumentException {
- if (str == null) {
- throw new NullPointerException("Argument cannot be null");
- }
-
- FormatInfo fi = new FormatInfo();
-
- int indexOfDot = str.indexOf('.');
- String minPart = null;
- String maxPart = null;
- if (indexOfDot != -1) {
- minPart = str.substring(0, indexOfDot);
- if (indexOfDot + 1 == str.length()) {
- throw new IllegalArgumentException("Formatting string [" + str + "] should not end with '.'");
- } else {
- maxPart = str.substring(indexOfDot + 1);
- }
- } else {
- minPart = str;
- }
-
- if (minPart != null && minPart.length() > 0) {
- int min = Integer.parseInt(minPart);
- if (min >= 0) {
- fi.min = min;
- } else {
- fi.min = -min;
- fi.leftPad = false;
- }
- }
-
- if (maxPart != null && maxPart.length() > 0) {
- int max = Integer.parseInt(maxPart);
- if (max >= 0) {
- fi.max = max;
- } else {
- fi.max = -max;
- fi.leftTruncate = false;
- }
- }
-
- return fi;
-
+ if (maxPart != null && maxPart.length() > 0) {
+ int max = Integer.parseInt(maxPart);
+ if (max >= 0) {
+ fi.max = max;
+ } else {
+ fi.max = -max;
+ fi.leftTruncate = false;
+ }
}
- public boolean isLeftPad() {
- return leftPad;
- }
+ return fi;
- public void setLeftPad(boolean leftAlign) {
- this.leftPad = leftAlign;
- }
+ }
- public int getMax() {
- return max;
- }
+ public boolean isLeftPad() {
+ return leftPad;
+ }
- public void setMax(int max) {
- this.max = max;
- }
+ public void setLeftPad(boolean leftAlign) {
+ this.leftPad = leftAlign;
+ }
- public int getMin() {
- return min;
- }
+ public int getMax() {
+ return max;
+ }
- public void setMin(int min) {
- this.min = min;
- }
+ public void setMax(int max) {
+ this.max = max;
+ }
- public boolean isLeftTruncate() {
- return leftTruncate;
- }
+ public int getMin() {
+ return min;
+ }
- public void setLeftTruncate(boolean leftTruncate) {
- this.leftTruncate = leftTruncate;
- }
+ public void setMin(int min) {
+ this.min = min;
+ }
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof FormatInfo)) {
- return false;
- }
- FormatInfo r = (FormatInfo) o;
+ public boolean isLeftTruncate() {
+ return leftTruncate;
+ }
- return (min == r.min) && (max == r.max) && (leftPad == r.leftPad) && (leftTruncate == r.leftTruncate);
- }
+ public void setLeftTruncate(boolean leftTruncate) {
+ this.leftTruncate = leftTruncate;
+ }
- @Override
- public int hashCode() {
- int result = min;
- result = 31 * result + max;
- result = 31 * result + (leftPad ? 1 : 0);
- result = 31 * result + (leftTruncate ? 1 : 0);
- return result;
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
}
-
- public String toString() {
- return "FormatInfo(" + min + ", " + max + ", " + leftPad + ", " + leftTruncate + ")";
+ if (!(o instanceof FormatInfo)) {
+ return false;
}
+ FormatInfo r = (FormatInfo) o;
+
+ return (min == r.min) && (max == r.max) && (leftPad == r.leftPad)
+ && (leftTruncate == r.leftTruncate);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = min;
+ result = 31 * result + max;
+ result = 31 * result + (leftPad ? 1 : 0);
+ result = 31 * result + (leftTruncate ? 1 : 0);
+ return result;
+ }
+
+ public String toString() {
+ return "FormatInfo(" + min + ", " + max + ", " + leftPad + ", "
+ + leftTruncate + ")";
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/FormattingConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/FormattingConverter.java
index 1c3e494..4e55204 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/FormattingConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/FormattingConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,56 +15,58 @@ package ch.qos.logback.core.pattern;
abstract public class FormattingConverter<E> extends Converter<E> {
- static final int INITIAL_BUF_SIZE = 256;
- static final int MAX_CAPACITY = 1024;
+ static final int INITIAL_BUF_SIZE = 256;
+ static final int MAX_CAPACITY = 1024;
- FormatInfo formattingInfo;
+
+ FormatInfo formattingInfo;
- final public FormatInfo getFormattingInfo() {
- return formattingInfo;
- }
+ final public FormatInfo getFormattingInfo() {
+ return formattingInfo;
+ }
- final public void setFormattingInfo(FormatInfo formattingInfo) {
- if (this.formattingInfo != null) {
- throw new IllegalStateException("FormattingInfo has been already set");
- }
- this.formattingInfo = formattingInfo;
+ final public void setFormattingInfo(FormatInfo formattingInfo) {
+ if (this.formattingInfo != null) {
+ throw new IllegalStateException("FormattingInfo has been already set");
}
+ this.formattingInfo = formattingInfo;
+ }
- @Override
- final public void write(StringBuilder buf, E event) {
- String s = convert(event);
-
- if (formattingInfo == null) {
- buf.append(s);
- return;
- }
+ @Override
+ final public void write(StringBuilder buf, E event) {
+ String s = convert(event);
+
+ if(formattingInfo == null) {
+ buf.append(s);
+ return;
+ }
+
+ int min = formattingInfo.getMin();
+ int max = formattingInfo.getMax();
- int min = formattingInfo.getMin();
- int max = formattingInfo.getMax();
- if (s == null) {
- if (0 < min)
- SpacePadder.spacePad(buf, min);
- return;
- }
+ if (s == null) {
+ if (0 < min)
+ SpacePadder.spacePad(buf, min);
+ return;
+ }
- int len = s.length();
+ int len = s.length();
- if (len > max) {
- if (formattingInfo.isLeftTruncate()) {
- buf.append(s.substring(len - max));
- } else {
- buf.append(s.substring(0, max));
- }
- } else if (len < min) {
- if (formattingInfo.isLeftPad()) {
- SpacePadder.leftPad(buf, s, min);
- } else {
- SpacePadder.rightPad(buf, s, min);
- }
- } else {
- buf.append(s);
- }
+ if (len > max) {
+ if(formattingInfo.isLeftTruncate()) {
+ buf.append(s.substring(len - max));
+ } else {
+ buf.append(s.substring(0, max));
+ }
+ } else if (len < min) {
+ if (formattingInfo.isLeftPad()) {
+ SpacePadder.leftPad(buf, s, min);
+ } else {
+ SpacePadder.rightPad(buf, s, min);
+ }
+ } else {
+ buf.append(s);
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/IdentityCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/IdentityCompositeConverter.java
index 1e83069..d5f109d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/IdentityCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/IdentityCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,8 +15,8 @@ package ch.qos.logback.core.pattern;
public class IdentityCompositeConverter<E> extends CompositeConverter<E> {
- @Override
- protected String transform(E event, String in) {
- return in;
- }
+ @Override
+ protected String transform(E event, String in) {
+ return in;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/LiteralConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/LiteralConverter.java
index 219d17d..153cd06 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/LiteralConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/LiteralConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,14 +15,15 @@ package ch.qos.logback.core.pattern;
public final class LiteralConverter<E> extends Converter<E> {
- String literal;
+ String literal;
- public LiteralConverter(String literal) {
- this.literal = literal;
- }
-
- public String convert(E o) {
- return literal;
- }
+ public LiteralConverter(String literal) {
+ this.literal = literal;
+ }
+ public String convert(E o) {
+ return literal;
+ }
+
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutBase.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutBase.java
index 50e3fa5..89b9475 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,131 +25,137 @@ import ch.qos.logback.core.status.StatusManager;
import java.util.HashMap;
import java.util.Map;
-abstract public class PatternLayoutBase<E> extends LayoutBase<E> {
-
- Converter<E> head;
- String pattern;
- protected PostCompileProcessor<E> postCompileProcessor;
-
- Map<String, String> instanceConverterMap = new HashMap<String, String>();
- protected boolean outputPatternAsHeader = false;
-
- /**
- * Concrete implementations of this class are responsible for elaborating the
- * mapping between pattern words and converters.
- *
- * @return A map associating pattern words to the names of converter classes
- */
- abstract public Map<String, String> getDefaultConverterMap();
-
- /**
- * Returns a map where the default converter map is merged with the map
- * contained in the context.
- */
- public Map<String, String> getEffectiveConverterMap() {
- Map<String, String> effectiveMap = new HashMap<String, String>();
-
- // add the least specific map fist
- Map<String, String> defaultMap = getDefaultConverterMap();
- if (defaultMap != null) {
- effectiveMap.putAll(defaultMap);
- }
-
- // contextMap is more specific than the default map
- Context context = getContext();
- if (context != null) {
- @SuppressWarnings("unchecked")
- Map<String, String> contextMap = (Map<String, String>) context.getObject(CoreConstants.PATTERN_RULE_REGISTRY);
- if (contextMap != null) {
- effectiveMap.putAll(contextMap);
- }
- }
- // set the most specific map last
- effectiveMap.putAll(instanceConverterMap);
- return effectiveMap;
- }
-
- public void start() {
- if (pattern == null || pattern.length() == 0) {
- addError("Empty or null pattern.");
- return;
- }
- try {
- Parser<E> p = new Parser<E>(pattern);
- if (getContext() != null) {
- p.setContext(getContext());
- }
- Node t = p.parse();
- this.head = p.compile(t, getEffectiveConverterMap());
- if (postCompileProcessor != null) {
- postCompileProcessor.process(context, head);
- }
- ConverterUtil.setContextForConverters(getContext(), head);
- ConverterUtil.startConverters(this.head);
- super.start();
- } catch (ScanException sce) {
- StatusManager sm = getContext().getStatusManager();
- sm.add(new ErrorStatus("Failed to parse pattern \"" + getPattern() + "\".", this, sce));
- }
- }
-
- public void setPostCompileProcessor(PostCompileProcessor<E> postCompileProcessor) {
- this.postCompileProcessor = postCompileProcessor;
- }
-
- /**
- *
- * @param head
- * @deprecated Use {@link ConverterUtil#setContextForConverters} instead. This method will
- * be removed in future releases.
- */
- protected void setContextForConverters(Converter<E> head) {
- ConverterUtil.setContextForConverters(getContext(), head);
- }
-
- protected String writeLoopOnConverters(E event) {
- StringBuilder buf = new StringBuilder(128);
- Converter<E> c = head;
- while (c != null) {
- c.write(buf, event);
- c = c.getNext();
- }
- return buf.toString();
- }
-
- public String getPattern() {
- return pattern;
- }
-
- public void setPattern(String pattern) {
- this.pattern = pattern;
- }
- public String toString() {
- return this.getClass().getName() + "(\"" + getPattern() + "\")";
- }
+abstract public class PatternLayoutBase<E> extends LayoutBase<E> {
- public Map<String, String> getInstanceConverterMap() {
- return instanceConverterMap;
+ Converter<E> head;
+ String pattern;
+ protected PostCompileProcessor<E> postCompileProcessor;
+
+
+ Map<String, String> instanceConverterMap = new HashMap<String, String>();
+ protected boolean outputPatternAsHeader = false;
+
+ /**
+ * Concrete implementations of this class are responsible for elaborating the
+ * mapping between pattern words and converters.
+ *
+ * @return A map associating pattern words to the names of converter classes
+ */
+ abstract public Map<String, String> getDefaultConverterMap();
+
+ /**
+ * Returns a map where the default converter map is merged with the map
+ * contained in the context.
+ */
+ public Map<String, String> getEffectiveConverterMap() {
+ Map<String, String> effectiveMap = new HashMap<String, String>();
+
+ // add the least specific map fist
+ Map<String, String> defaultMap = getDefaultConverterMap();
+ if (defaultMap != null) {
+ effectiveMap.putAll(defaultMap);
}
- protected String getPresentationHeaderPrefix() {
- return CoreConstants.EMPTY_STRING;
+ // contextMap is more specific than the default map
+ Context context = getContext();
+ if (context != null) {
+ @SuppressWarnings("unchecked")
+ Map<String, String> contextMap = (Map<String, String>) context
+ .getObject(CoreConstants.PATTERN_RULE_REGISTRY);
+ if (contextMap != null) {
+ effectiveMap.putAll(contextMap);
+ }
}
-
- public boolean isOutputPatternAsHeader() {
- return outputPatternAsHeader;
+ // set the most specific map last
+ effectiveMap.putAll(instanceConverterMap);
+ return effectiveMap;
+ }
+
+ public void start() {
+ if(pattern == null || pattern.length() == 0) {
+ addError("Empty or null pattern.");
+ return;
}
-
- public void setOutputPatternAsHeader(boolean outputPatternAsHeader) {
- this.outputPatternAsHeader = outputPatternAsHeader;
+ try {
+ Parser<E> p = new Parser<E>(pattern);
+ if (getContext() != null) {
+ p.setContext(getContext());
+ }
+ Node t = p.parse();
+ this.head = p.compile(t, getEffectiveConverterMap());
+ if (postCompileProcessor != null) {
+ postCompileProcessor.process(head);
+ }
+ ConverterUtil.setContextForConverters(getContext(), head);
+ ConverterUtil.startConverters(this.head);
+ super.start();
+ } catch (ScanException sce) {
+ StatusManager sm = getContext().getStatusManager();
+ sm.add(new ErrorStatus("Failed to parse pattern \"" + getPattern()
+ + "\".", this, sce));
}
-
- @Override
- public String getPresentationHeader() {
- if (outputPatternAsHeader)
- return getPresentationHeaderPrefix() + pattern;
- else
- return super.getPresentationHeader();
+ }
+
+ public void setPostCompileProcessor(
+ PostCompileProcessor<E> postCompileProcessor) {
+ this.postCompileProcessor = postCompileProcessor;
+ }
+
+ /**
+ *
+ * @param head
+ * @deprecated Use {@link ConverterUtil#setContextForConverters} instead. This method will
+ * be removed in future releases.
+ */
+ protected void setContextForConverters(Converter<E> head) {
+ ConverterUtil.setContextForConverters(getContext(), head);
+ }
+
+ protected String writeLoopOnConverters(E event) {
+ StringBuilder buf = new StringBuilder(128);
+ Converter<E> c = head;
+ while (c != null) {
+ c.write(buf, event);
+ c = c.getNext();
}
+ return buf.toString();
+ }
+
+ public String getPattern() {
+ return pattern;
+ }
+
+ public void setPattern(String pattern) {
+ this.pattern = pattern;
+ }
+
+ public String toString() {
+ return this.getClass().getName() + "(\"" + getPattern() + "\")";
+ }
+
+ public Map<String, String> getInstanceConverterMap() {
+ return instanceConverterMap;
+ }
+
+
+ protected String getPresentationHeaderPrefix() {
+ return CoreConstants.EMPTY_STRING;
+ }
+
+ public boolean isOutputPatternAsHeader() {
+ return outputPatternAsHeader;
+ }
+
+ public void setOutputPatternAsHeader(boolean outputPatternAsHeader) {
+ this.outputPatternAsHeader = outputPatternAsHeader;
+ }
+
+ @Override
+ public String getPresentationHeader() {
+ if(outputPatternAsHeader)
+ return getPresentationHeaderPrefix()+pattern;
+ else
+ return super.getPresentationHeader();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutEncoderBase.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutEncoderBase.java
index 14158de..c510c7f 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutEncoderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutEncoderBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,48 +18,51 @@ import ch.qos.logback.core.encoder.LayoutWrappingEncoder;
public class PatternLayoutEncoderBase<E> extends LayoutWrappingEncoder<E> {
- String pattern;
+ String pattern;
- // due to popular demand outputPatternAsHeader is set to false by default
- protected boolean outputPatternAsHeader = false;
+ // due to popular demand outputPatternAsHeader is set to false by default
+ protected boolean outputPatternAsHeader = false;
- public String getPattern() {
- return pattern;
- }
+ public String getPattern() {
+ return pattern;
+ }
- public void setPattern(String pattern) {
- this.pattern = pattern;
- }
+ public void setPattern(String pattern) {
+ this.pattern = pattern;
+ }
- public boolean isOutputPatternAsHeader() {
- return outputPatternAsHeader;
- }
+ public boolean isOutputPatternAsHeader() {
+ return outputPatternAsHeader;
+ }
- /**
- * Print the pattern string as a header in log files
- *
- * @param outputPatternAsHeader
- * @since 1.0.3
- */
- public void setOutputPatternAsHeader(boolean outputPatternAsHeader) {
- this.outputPatternAsHeader = outputPatternAsHeader;
- }
- public boolean isOutputPatternAsPresentationHeader() {
- return outputPatternAsHeader;
- }
+ /**
+ * Print the pattern string as a header in log files
+ *
+ * @param outputPatternAsHeader
+ * @since 1.0.3
+ */
+ public void setOutputPatternAsHeader(boolean outputPatternAsHeader) {
+ this.outputPatternAsHeader = outputPatternAsHeader;
+ }
- /**
- * @deprecated replaced by {@link #setOutputPatternAsHeader(boolean)}
- */
- public void setOutputPatternAsPresentationHeader(boolean outputPatternAsHeader) {
- addWarn("[outputPatternAsPresentationHeader] property is deprecated. Please use [outputPatternAsHeader] option instead.");
- this.outputPatternAsHeader = outputPatternAsHeader;
- }
- @Override
- public void setLayout(Layout<E> layout) {
- throw new UnsupportedOperationException("one cannot set the layout of " + this.getClass().getName());
- }
+ public boolean isOutputPatternAsPresentationHeader() {
+ return outputPatternAsHeader;
+ }
+
+ /**
+ * @deprecated replaced by {@link #setOutputPatternAsHeader(boolean)}
+ */
+ public void setOutputPatternAsPresentationHeader(boolean outputPatternAsHeader) {
+ addWarn("[outputPatternAsPresentationHeader] property is deprecated. Please use [outputPatternAsHeader] option instead.");
+ this.outputPatternAsHeader = outputPatternAsHeader;
+ }
+
+ @Override
+ public void setLayout(Layout<E> layout) {
+ throw new UnsupportedOperationException("one cannot set the layout of "
+ + this.getClass().getName());
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/PostCompileProcessor.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/PostCompileProcessor.java
index 414b560..4ff169a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/PostCompileProcessor.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/PostCompileProcessor.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,7 +13,6 @@
*/
package ch.qos.logback.core.pattern;
-import ch.qos.logback.core.Context;
/**
* Implements this to perform post compile processing for a PatternLayout.
@@ -25,11 +24,11 @@ import ch.qos.logback.core.Context;
*/
public interface PostCompileProcessor<E> {
- /**
- * Post compile processing of the converter chain.
- *
- * @param head
- * The first converter in the chain
- */
- void process(Context context, Converter<E> head);
+ /**
+ * Post compile processing of the converter chain.
+ *
+ * @param head
+ * The first converter in the chain
+ */
+ void process(Converter<E> head);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/ReplacingCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/ReplacingCompositeConverter.java
index 4ab281a..cda692e 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/ReplacingCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/ReplacingCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,33 +18,33 @@ import java.util.regex.Pattern;
public class ReplacingCompositeConverter<E> extends CompositeConverter<E> {
- Pattern pattern;
- String regex;
- String replacement;
+ Pattern pattern;
+ String regex;
+ String replacement;
- public void start() {
- final List<String> optionList = getOptionList();
- if (optionList == null) {
- addError("at least two options are expected whereas you have declared none");
- return;
- }
+ public void start() {
+ final List<String> optionList = getOptionList();
+ if (optionList == null) {
+ addError("at least two options are expected whereas you have declared none");
+ return;
+ }
- int numOpts = optionList.size();
+ int numOpts = optionList.size();
- if (numOpts < 2) {
- addError("at least two options are expected whereas you have declared only " + numOpts + "as [" + optionList + "]");
- return;
- }
- regex = optionList.get(0);
- pattern = Pattern.compile(regex);
- replacement = optionList.get(1);
- super.start();
+ if (numOpts < 2) {
+ addError("at least two options are expected whereas you have declared only " + numOpts + "as [" + optionList + "]");
+ return;
}
+ regex = optionList.get(0);
+ pattern = Pattern.compile(regex);
+ replacement = optionList.get(1);
+ super.start();
+ }
- @Override
- protected String transform(E event, String in) {
- if (!started)
- return in;
- return pattern.matcher(in).replaceAll(replacement);
- }
+ @Override
+ protected String transform(E event, String in) {
+ if (!started)
+ return in;
+ return pattern.matcher(in).replaceAll(replacement);
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/SpacePadder.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/SpacePadder.java
index 8c07936..7fec9f5 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/SpacePadder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/SpacePadder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,50 +15,50 @@ package ch.qos.logback.core.pattern;
public class SpacePadder {
- final static String[] SPACES = { " ", " ", " ", " ", // 1,2,4,8
- // spaces
- " ", // 16 spaces
- " " }; // 32 spaces
+ final static String[] SPACES = { " ", " ", " ", " ", // 1,2,4,8
+ // spaces
+ " ", // 16 spaces
+ " " }; // 32 spaces
- final static public void leftPad(StringBuilder buf, String s, int desiredLength) {
- int actualLen = 0;
- if (s != null) {
- actualLen = s.length();
- }
- if (actualLen < desiredLength) {
- spacePad(buf, desiredLength - actualLen);
- }
- if (s != null) {
- buf.append(s);
- }
+ final static public void leftPad(StringBuilder buf, String s, int desiredLength) {
+ int actualLen = 0;
+ if (s != null) {
+ actualLen = s.length();
}
-
- final static public void rightPad(StringBuilder buf, String s, int desiredLength) {
- int actualLen = 0;
- if (s != null) {
- actualLen = s.length();
- }
- if (s != null) {
- buf.append(s);
- }
- if (actualLen < desiredLength) {
- spacePad(buf, desiredLength - actualLen);
- }
+ if (actualLen < desiredLength) {
+ spacePad(buf, desiredLength - actualLen);
+ }
+ if (s != null) {
+ buf.append(s);
}
+ }
- /**
- * Fast space padding method.
- */
- final static public void spacePad(StringBuilder sbuf, int length) {
- while (length >= 32) {
- sbuf.append(SPACES[5]);
- length -= 32;
- }
+ final static public void rightPad(StringBuilder buf, String s, int desiredLength) {
+ int actualLen = 0;
+ if (s != null) {
+ actualLen = s.length();
+ }
+ if (s != null) {
+ buf.append(s);
+ }
+ if (actualLen < desiredLength) {
+ spacePad(buf, desiredLength - actualLen);
+ }
+ }
+
+ /**
+ * Fast space padding method.
+ */
+ final static public void spacePad(StringBuilder sbuf, int length) {
+ while (length >= 32) {
+ sbuf.append(SPACES[5]);
+ length -= 32;
+ }
- for (int i = 4; i >= 0; i--) {
- if ((length & (1 << i)) != 0) {
- sbuf.append(SPACES[i]);
- }
- }
+ for (int i = 4; i >= 0; i--) {
+ if ((length & (1 << i)) != 0) {
+ sbuf.append(SPACES[i]);
+ }
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/ANSIConstants.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/ANSIConstants.java
index 3c70429..0488fdf 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/ANSIConstants.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/ANSIConstants.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,18 +15,19 @@ package ch.qos.logback.core.pattern.color;
public class ANSIConstants {
- public final static String ESC_START = "\033[";
- public final static String ESC_END = "m";
- public final static String BOLD = "1;";
+ public final static String ESC_START = "\033[";
+ public final static String ESC_END = "m";
+ public final static String BOLD = "1;";
+
+ public final static String BLACK_FG = "30";
+ public final static String RED_FG = "31";
+ public final static String GREEN_FG = "32";
+ public final static String YELLOW_FG = "33";
+ public final static String BLUE_FG = "34";
+ public final static String MAGENTA_FG = "35";
+ public final static String CYAN_FG = "36";
+ public final static String WHITE_FG = "37";
+ public final static String DEFAULT_FG = "39";
- public final static String BLACK_FG = "30";
- public final static String RED_FG = "31";
- public final static String GREEN_FG = "32";
- public final static String YELLOW_FG = "33";
- public final static String BLUE_FG = "34";
- public final static String MAGENTA_FG = "35";
- public final static String CYAN_FG = "36";
- public final static String WHITE_FG = "37";
- public final static String DEFAULT_FG = "39";
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BlackCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BlackCompositeConverter.java
index 6d89b04..37b2164 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BlackCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BlackCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,8 +21,8 @@ package ch.qos.logback.core.pattern.color;
*/
public class BlackCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return ANSIConstants.BLACK_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return ANSIConstants.BLACK_FG;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BlueCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BlueCompositeConverter.java
index 0d0a6ce..f3fa002 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BlueCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BlueCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,8 +21,8 @@ package ch.qos.logback.core.pattern.color;
*/
public class BlueCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return ANSIConstants.BLUE_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return ANSIConstants.BLUE_FG;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldBlueCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldBlueCompositeConverter.java
index b8dbd85..4089531 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldBlueCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldBlueCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,8 +25,8 @@ import static ch.qos.logback.core.pattern.color.ANSIConstants.BOLD;
*/
public class BoldBlueCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return BOLD + BLUE_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return BOLD + BLUE_FG;
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldCyanCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldCyanCompositeConverter.java
index fd14341..93ece1b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldCyanCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldCyanCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,8 +25,8 @@ import static ch.qos.logback.core.pattern.color.ANSIConstants.CYAN_FG;
*/
public class BoldCyanCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return BOLD + CYAN_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return BOLD + CYAN_FG;
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldGreenCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldGreenCompositeConverter.java
index a8e44b6..8e9934a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldGreenCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldGreenCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,8 +25,8 @@ import static ch.qos.logback.core.pattern.color.ANSIConstants.GREEN_FG;
*/
public class BoldGreenCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return BOLD + GREEN_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return BOLD + GREEN_FG;
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldMagentaCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldMagentaCompositeConverter.java
index 84a44bd..69b5af1 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldMagentaCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldMagentaCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,8 +25,8 @@ import static ch.qos.logback.core.pattern.color.ANSIConstants.MAGENTA_FG;
*/
public class BoldMagentaCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return BOLD + MAGENTA_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return BOLD + MAGENTA_FG;
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldRedCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldRedCompositeConverter.java
index 02f9464..2b63f1b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldRedCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldRedCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,10 +21,10 @@ import static ch.qos.logback.core.pattern.color.ANSIConstants.*;
* @author Ceki Gülcü
* @since 1.0.5
*/
-public class BoldRedCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
+public class BoldRedCompositeConverter <E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return BOLD + RED_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return BOLD+RED_FG;
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldWhiteCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldWhiteCompositeConverter.java
index 12f8a78..86991ea 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldWhiteCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldWhiteCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,8 +25,8 @@ import static ch.qos.logback.core.pattern.color.ANSIConstants.WHITE_FG;
*/
public class BoldWhiteCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return BOLD + WHITE_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return BOLD + WHITE_FG;
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldYellowCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldYellowCompositeConverter.java
index fcde84b..5aa5ea6 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldYellowCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/BoldYellowCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,8 +25,8 @@ import static ch.qos.logback.core.pattern.color.ANSIConstants.YELLOW_FG;
*/
public class BoldYellowCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return BOLD + YELLOW_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return BOLD + YELLOW_FG;
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/CyanCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/CyanCompositeConverter.java
index 1c11f5d..0bee1bb 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/CyanCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/CyanCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,8 +21,8 @@ package ch.qos.logback.core.pattern.color;
*/
public class CyanCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return ANSIConstants.CYAN_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return ANSIConstants.CYAN_FG;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/ForegroundCompositeConverterBase.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/ForegroundCompositeConverterBase.java
index f8ff933..c8f3209 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/ForegroundCompositeConverterBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/ForegroundCompositeConverterBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,22 +24,22 @@ import static ch.qos.logback.core.pattern.color.ANSIConstants.*;
*/
abstract public class ForegroundCompositeConverterBase<E> extends CompositeConverter<E> {
- final private static String SET_DEFAULT_COLOR = ESC_START + "0;" + DEFAULT_FG + ESC_END;
+ final private static String SET_DEFAULT_COLOR = ESC_START+"0;"+DEFAULT_FG+ESC_END;
- @Override
- protected String transform(E event, String in) {
- StringBuilder sb = new StringBuilder();
- sb.append(ESC_START);
- sb.append(getForegroundColorCode(event));
- sb.append(ESC_END);
- sb.append(in);
- sb.append(SET_DEFAULT_COLOR);
- return sb.toString();
- }
+ @Override
+ protected String transform(E event, String in) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(ESC_START);
+ sb.append(getForegroundColorCode(event));
+ sb.append(ESC_END);
+ sb.append(in);
+ sb.append(SET_DEFAULT_COLOR);
+ return sb.toString();
+ }
- /**
- * Derived classes return the foreground color specific to the derived class instance.
- * @return the foreground color for this instance
- */
- abstract protected String getForegroundColorCode(E event);
+ /**
+ * Derived classes return the foreground color specific to the derived class instance.
+ * @return the foreground color for this instance
+ */
+ abstract protected String getForegroundColorCode(E event);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/GrayCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/GrayCompositeConverter.java
index bcd320e..3c0740e 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/GrayCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/GrayCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,8 +25,8 @@ import static ch.qos.logback.core.pattern.color.ANSIConstants.*;
*/
public class GrayCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return BOLD + BLACK_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return BOLD + BLACK_FG;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/GreenCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/GreenCompositeConverter.java
index 2fd82a4..f16efa8 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/GreenCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/GreenCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,8 +21,8 @@ package ch.qos.logback.core.pattern.color;
*/
public class GreenCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return ANSIConstants.GREEN_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return ANSIConstants.GREEN_FG;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/MagentaCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/MagentaCompositeConverter.java
index 25f8b94..3d3c9e4 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/MagentaCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/MagentaCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,8 +21,8 @@ package ch.qos.logback.core.pattern.color;
*/
public class MagentaCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return ANSIConstants.MAGENTA_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return ANSIConstants.MAGENTA_FG;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/RedCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/RedCompositeConverter.java
index 6919cd1..3e6bacc 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/RedCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/RedCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,8 +21,8 @@ package ch.qos.logback.core.pattern.color;
*/
public class RedCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return ANSIConstants.RED_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return ANSIConstants.RED_FG;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/WhiteCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/WhiteCompositeConverter.java
index 77634ee..ef1f9c3 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/WhiteCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/WhiteCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,8 +21,8 @@ package ch.qos.logback.core.pattern.color;
*/
public class WhiteCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return ANSIConstants.WHITE_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return ANSIConstants.WHITE_FG;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/YellowCompositeConverter.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/YellowCompositeConverter.java
index bbd18cf..061209c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/color/YellowCompositeConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/color/YellowCompositeConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,8 +21,8 @@ package ch.qos.logback.core.pattern.color;
*/
public class YellowCompositeConverter<E> extends ForegroundCompositeConverterBase<E> {
- @Override
- protected String getForegroundColorCode(E event) {
- return ANSIConstants.YELLOW_FG;
- }
+ @Override
+ protected String getForegroundColorCode(E event) {
+ return ANSIConstants.YELLOW_FG;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Compiler.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Compiler.java
index 6331f0e..76b884c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Compiler.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Compiler.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,125 +25,135 @@ import ch.qos.logback.core.util.OptionHelper;
class Compiler<E> extends ContextAwareBase {
- Converter<E> head;
- Converter<E> tail;
- final Node top;
- final Map converterMap;
+ Converter<E> head;
+ Converter<E> tail;
+ final Node top;
+ final Map converterMap;
- Compiler(final Node top, final Map converterMap) {
- this.top = top;
- this.converterMap = converterMap;
- }
+ Compiler(final Node top, final Map converterMap) {
+ this.top = top;
+ this.converterMap = converterMap;
+ }
- Converter<E> compile() {
- head = tail = null;
- for (Node n = top; n != null; n = n.next) {
- switch (n.type) {
- case Node.LITERAL:
- addToList(new LiteralConverter<E>((String) n.getValue()));
- break;
- case Node.COMPOSITE_KEYWORD:
- CompositeNode cn = (CompositeNode) n;
- CompositeConverter<E> compositeConverter = createCompositeConverter(cn);
- if (compositeConverter == null) {
- addError("Failed to create converter for [%" + cn.getValue() + "] keyword");
- addToList(new LiteralConverter<E>("%PARSER_ERROR[" + cn.getValue() + "]"));
- break;
- }
- compositeConverter.setFormattingInfo(cn.getFormatInfo());
- compositeConverter.setOptionList(cn.getOptions());
- Compiler<E> childCompiler = new Compiler<E>(cn.getChildNode(), converterMap);
- childCompiler.setContext(context);
- Converter<E> childConverter = childCompiler.compile();
- compositeConverter.setChildConverter(childConverter);
- addToList(compositeConverter);
- break;
- case Node.SIMPLE_KEYWORD:
- SimpleKeywordNode kn = (SimpleKeywordNode) n;
- DynamicConverter<E> dynaConverter = createConverter(kn);
- if (dynaConverter != null) {
- dynaConverter.setFormattingInfo(kn.getFormatInfo());
- dynaConverter.setOptionList(kn.getOptions());
- addToList(dynaConverter);
- } else {
- // if the appropriate dynaconverter cannot be found, then replace
- // it with a dummy LiteralConverter indicating an error.
- Converter<E> errConveter = new LiteralConverter<E>("%PARSER_ERROR[" + kn.getValue() + "]");
- addStatus(new ErrorStatus("[" + kn.getValue() + "] is not a valid conversion word", this));
- addToList(errConveter);
- }
+ Converter<E> compile() {
+ head = tail = null;
+ for (Node n = top; n != null; n = n.next) {
+ switch (n.type) {
+ case Node.LITERAL:
+ addToList(new LiteralConverter<E>((String) n.getValue()));
+ break;
+ case Node.COMPOSITE_KEYWORD:
+ CompositeNode cn = (CompositeNode) n;
+ CompositeConverter<E> compositeConverter = createCompositeConverter(cn);
+ if(compositeConverter == null) {
+ addError("Failed to create converter for [%"+cn.getValue()+"] keyword");
+ addToList(new LiteralConverter<E>("%PARSER_ERROR["+cn.getValue()+"]"));
+ break;
+ }
+ compositeConverter.setFormattingInfo(cn.getFormatInfo());
+ compositeConverter.setOptionList(cn.getOptions());
+ Compiler<E> childCompiler = new Compiler<E>(cn.getChildNode(),
+ converterMap);
+ childCompiler.setContext(context);
+ Converter<E> childConverter = childCompiler.compile();
+ compositeConverter.setChildConverter(childConverter);
+ addToList(compositeConverter);
+ break;
+ case Node.SIMPLE_KEYWORD:
+ SimpleKeywordNode kn = (SimpleKeywordNode) n;
+ DynamicConverter<E> dynaConverter = createConverter(kn);
+ if (dynaConverter != null) {
+ dynaConverter.setFormattingInfo(kn.getFormatInfo());
+ dynaConverter.setOptionList(kn.getOptions());
+ addToList(dynaConverter);
+ } else {
+ // if the appropriate dynaconverter cannot be found, then replace
+ // it with a dummy LiteralConverter indicating an error.
+ Converter<E> errConveter = new LiteralConverter<E>("%PARSER_ERROR["
+ + kn.getValue() + "]");
+ addStatus(new ErrorStatus("[" + kn.getValue()
+ + "] is not a valid conversion word", this));
+ addToList(errConveter);
+ }
- }
- }
- return head;
+ }
}
+ return head;
+ }
- private void addToList(Converter<E> c) {
- if (head == null) {
- head = tail = c;
- } else {
- tail.setNext(c);
- tail = c;
- }
+ private void addToList(Converter<E> c) {
+ if (head == null) {
+ head = tail = c;
+ } else {
+ tail.setNext(c);
+ tail = c;
}
+ }
- /**
- * Attempt to create a converter using the information found in
- * 'converterMap'.
- *
- * @param kn
- * @return
- */
- @SuppressWarnings("unchecked")
- DynamicConverter<E> createConverter(SimpleKeywordNode kn) {
- String keyword = (String) kn.getValue();
- String converterClassStr = (String) converterMap.get(keyword);
+ /**
+ * Attempt to create a converter using the information found in
+ * 'converterMap'.
+ *
+ * @param kn
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ DynamicConverter<E> createConverter(SimpleKeywordNode kn) {
+ String keyword = (String) kn.getValue();
+ String converterClassStr = (String) converterMap.get(keyword);
- if (converterClassStr != null) {
- try {
- return (DynamicConverter) OptionHelper.instantiateByClassName(converterClassStr, DynamicConverter.class, context);
- } catch (Exception e) {
- addError("Failed to instantiate converter class [" + converterClassStr + "] for keyword [" + keyword + "]", e);
- return null;
- }
- } else {
- addError("There is no conversion class registered for conversion word [" + keyword + "]");
- return null;
- }
+ if (converterClassStr != null) {
+ try {
+ return (DynamicConverter) OptionHelper.instantiateByClassName(
+ converterClassStr, DynamicConverter.class, context);
+ } catch (Exception e) {
+ addError("Failed to instantiate converter class [" + converterClassStr
+ + "] for keyword ["+keyword+"]", e);
+ return null;
+ }
+ } else {
+ addError("There is no conversion class registered for conversion word ["
+ + keyword + "]");
+ return null;
}
+ }
- /**
- * Attempt to create a converter using the information found in
- * 'compositeConverterMap'.
- *
- * @param cn
- * @return
- */
- @SuppressWarnings("unchecked")
- CompositeConverter<E> createCompositeConverter(CompositeNode cn) {
- String keyword = (String) cn.getValue();
- String converterClassStr = (String) converterMap.get(keyword);
+ /**
+ * Attempt to create a converter using the information found in
+ * 'compositeConverterMap'.
+ *
+ * @param cn
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ CompositeConverter<E> createCompositeConverter(CompositeNode cn) {
+ String keyword = (String) cn.getValue();
+ String converterClassStr = (String) converterMap.get(keyword);
- if (converterClassStr != null) {
- try {
- return (CompositeConverter) OptionHelper.instantiateByClassName(converterClassStr, CompositeConverter.class, context);
- } catch (Exception e) {
- addError("Failed to instantiate converter class [" + converterClassStr + "] as a composite converter for keyword [" + keyword + "]", e);
- return null;
- }
- } else {
- addError("There is no conversion class registered for composite conversion word [" + keyword + "]");
- return null;
- }
+ if (converterClassStr != null) {
+ try {
+ return (CompositeConverter) OptionHelper.instantiateByClassName(
+ converterClassStr, CompositeConverter.class, context);
+ } catch (Exception e) {
+ addError("Failed to instantiate converter class [" + converterClassStr
+ + "] as a composite converter for keyword ["+keyword+"]", e);
+ return null;
+ }
+ } else {
+ addError("There is no conversion class registered for composite conversion word ["
+ + keyword + "]");
+ return null;
}
+ }
+
- // public void setStatusManager(StatusManager statusManager) {
- // this.statusManager = statusManager;
- // }
- //
- // void addStatus(Status status) {
- // if(statusManager != null) {
- // statusManager.add(status);
- // }
- // }
+ // public void setStatusManager(StatusManager statusManager) {
+ // this.statusManager = statusManager;
+ // }
+ //
+ // void addStatus(Status status) {
+ // if(statusManager != null) {
+ // statusManager.add(status);
+ // }
+ // }
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/CompositeNode.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/CompositeNode.java
index b17bb86..cce49f5 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/CompositeNode.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/CompositeNode.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,46 +14,47 @@
package ch.qos.logback.core.pattern.parser;
public class CompositeNode extends SimpleKeywordNode {
- Node childNode;
+ Node childNode;
- CompositeNode(String keyword) {
- super(Node.COMPOSITE_KEYWORD, keyword);
+ CompositeNode(String keyword) {
+ super(Node.COMPOSITE_KEYWORD, keyword);
- }
-
- public Node getChildNode() {
- return childNode;
- }
-
- public void setChildNode(Node childNode) {
- this.childNode = childNode;
- }
-
- public boolean equals(Object o) {
- if (!super.equals(o)) {
- return false;
- }
- if (!(o instanceof CompositeNode)) {
- return false;
- }
- CompositeNode r = (CompositeNode) o;
+ }
- return (childNode != null) ? childNode.equals(r.childNode) : (r.childNode == null);
- }
+ public Node getChildNode() {
+ return childNode;
+ }
- @Override
- public int hashCode() {
- return super.hashCode();
- }
+ public void setChildNode(Node childNode) {
+ this.childNode = childNode;
+ }
- public String toString() {
- StringBuilder buf = new StringBuilder();
- if (childNode != null) {
- buf.append("CompositeNode(" + childNode + ")");
- } else {
- buf.append("CompositeNode(no child)");
- }
- buf.append(printNext());
- return buf.toString();
+ public boolean equals(Object o) {
+ if(!super.equals(o)) {
+ return false;
}
+ if (!(o instanceof CompositeNode)) {
+ return false;
+ }
+ CompositeNode r = (CompositeNode) o;
+
+ return (childNode != null) ? childNode.equals(r.childNode)
+ : (r.childNode == null);
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ if(childNode != null) {
+ buf.append("CompositeNode("+childNode+")");
+ } else {
+ buf.append("CompositeNode(no child)");
+ }
+ buf.append(printNext());
+ return buf.toString();
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/FormattingNode.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/FormattingNode.java
index 4c3170d..748d804 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/FormattingNode.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/FormattingNode.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,41 +17,42 @@ import ch.qos.logback.core.pattern.FormatInfo;
public class FormattingNode extends Node {
- FormatInfo formatInfo;
+ FormatInfo formatInfo;
- FormattingNode(int type) {
- super(type);
- }
-
- FormattingNode(int type, Object value) {
- super(type, value);
- }
+ FormattingNode(int type) {
+ super(type);
+ }
- public FormatInfo getFormatInfo() {
- return formatInfo;
- }
-
- public void setFormatInfo(FormatInfo formatInfo) {
- this.formatInfo = formatInfo;
- }
+ FormattingNode(int type, Object value) {
+ super(type, value);
+ }
- public boolean equals(Object o) {
- if (!super.equals(o)) {
- return false;
- }
+ public FormatInfo getFormatInfo() {
+ return formatInfo;
+ }
- if (!(o instanceof FormattingNode)) {
- return false;
- }
- FormattingNode r = (FormattingNode) o;
+ public void setFormatInfo(FormatInfo formatInfo) {
+ this.formatInfo = formatInfo;
+ }
- return (formatInfo != null ? formatInfo.equals(r.formatInfo) : r.formatInfo == null);
+ public boolean equals(Object o) {
+ if (!super.equals(o)) {
+ return false;
}
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + (formatInfo != null ? formatInfo.hashCode() : 0);
- return result;
+ if(!(o instanceof FormattingNode)) {
+ return false;
}
+ FormattingNode r = (FormattingNode) o;
+
+ return (formatInfo != null ? formatInfo.equals(r.formatInfo)
+ : r.formatInfo == null);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (formatInfo != null ? formatInfo.hashCode() : 0);
+ return result;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Node.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Node.java
index a2bdb19..590334f 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Node.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Node.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,84 +14,86 @@
package ch.qos.logback.core.pattern.parser;
public class Node {
- static final int LITERAL = 0;
- static final int SIMPLE_KEYWORD = 1;
- static final int COMPOSITE_KEYWORD = 2;
+ static final int LITERAL = 0;
+ static final int SIMPLE_KEYWORD = 1;
+ static final int COMPOSITE_KEYWORD = 2;
- final int type;
- final Object value;
- Node next;
+ final int type;
+ final Object value;
+ Node next;
- Node(int type) {
- this(type, null);
- }
+ Node(int type) {
+ this(type, null);
+ }
- Node(int type, Object value) {
- this.type = type;
- this.value = value;
- }
+ Node(int type, Object value) {
+ this.type = type;
+ this.value = value;
+ }
- /**
- * @return Returns the type.
- */
- public int getType() {
- return type;
- }
+ /**
+ * @return Returns the type.
+ */
+ public int getType() {
+ return type;
+ }
- /**
- * @return Returns the value.
- */
- public Object getValue() {
- return value;
- }
+ /**
+ * @return Returns the value.
+ */
+ public Object getValue() {
+ return value;
+ }
- public Node getNext() {
- return next;
- }
+ public Node getNext() {
+ return next;
+ }
- public void setNext(Node next) {
- this.next = next;
- }
+ public void setNext(Node next) {
+ this.next = next;
+ }
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof Node)) {
- return false;
- }
- Node r = (Node) o;
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof Node)) {
+ return false;
+ }
+ Node r = (Node) o;
- return (type == r.type) && (value != null ? value.equals(r.value) : r.value == null) && (next != null ? next.equals(r.next) : r.next == null);
- }
+ return (type == r.type)
+ && (value != null ? value.equals(r.value) : r.value == null)
+ && (next != null ? next.equals(r.next) : r.next == null);
+ }
- @Override
- public int hashCode() {
- int result = type;
- result = 31 * result + (value != null ? value.hashCode() : 0);
- return result;
- }
+ @Override
+ public int hashCode() {
+ int result = type;
+ result = 31 * result + (value != null ? value.hashCode() : 0);
+ return result;
+ }
- String printNext() {
- if (next != null) {
- return " -> " + next;
- } else {
- return "";
- }
- }
+ String printNext() {
+ if (next != null) {
+ return " -> " + next;
+ } else {
+ return "";
+ }
+ }
- public String toString() {
- StringBuilder buf = new StringBuilder();
- switch (type) {
- case LITERAL:
- buf.append("LITERAL(" + value + ")");
- break;
- default:
- buf.append(super.toString());
- }
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ switch (type) {
+ case LITERAL:
+ buf.append("LITERAL(" + value + ")");
+ break;
+ default:
+ buf.append(super.toString());
+ }
- buf.append(printNext());
-
- return buf.toString();
- }
+ buf.append(printNext());
+
+ return buf.toString();
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/OptionTokenizer.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/OptionTokenizer.java
index dfbef2b..a0fec77 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/OptionTokenizer.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/OptionTokenizer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,124 +21,128 @@ import ch.qos.logback.core.pattern.util.IEscapeUtil;
import static ch.qos.logback.core.CoreConstants.CURLY_RIGHT;
+
import static ch.qos.logback.core.CoreConstants.ESCAPE_CHAR;
import static ch.qos.logback.core.CoreConstants.COMMA_CHAR;
import static ch.qos.logback.core.CoreConstants.SINGLE_QUOTE_CHAR;
import static ch.qos.logback.core.CoreConstants.DOUBLE_QUOTE_CHAR;
+
import ch.qos.logback.core.pattern.parser.TokenStream.TokenizerState;
import ch.qos.logback.core.spi.ScanException;
public class OptionTokenizer {
- private final static int EXPECTING_STATE = 0;
- private final static int RAW_COLLECTING_STATE = 1;
- private final static int QUOTED_COLLECTING_STATE = 2;
-
- final IEscapeUtil escapeUtil;
- final TokenStream tokenStream;
- final String pattern;
- final int patternLength;
-
- char quoteChar;
- int state = EXPECTING_STATE;
-
- OptionTokenizer(TokenStream tokenStream) {
- this(tokenStream, new AsIsEscapeUtil());
+ private final static int EXPECTING_STATE = 0;
+ private final static int RAW_COLLECTING_STATE = 1;
+ private final static int QUOTED_COLLECTING_STATE = 2;
+
+
+ final IEscapeUtil escapeUtil;
+ final TokenStream tokenStream;
+ final String pattern;
+ final int patternLength;
+
+ char quoteChar;
+ int state = EXPECTING_STATE;
+
+ OptionTokenizer(TokenStream tokenStream) {
+ this(tokenStream, new AsIsEscapeUtil());
+ }
+
+ OptionTokenizer(TokenStream tokenStream, IEscapeUtil escapeUtil) {
+ this.tokenStream = tokenStream;
+ this.pattern = tokenStream.pattern;
+ this.patternLength = tokenStream.patternLength;
+ this.escapeUtil = escapeUtil;
+ }
+
+ void tokenize(char firstChar, List<Token> tokenList) throws ScanException {
+ StringBuffer buf = new StringBuffer();
+ List<String> optionList = new ArrayList<String>();
+ char c = firstChar;
+
+ while (tokenStream.pointer < patternLength) {
+ switch (state) {
+ case EXPECTING_STATE:
+ switch (c) {
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ case COMMA_CHAR:
+ break;
+ case SINGLE_QUOTE_CHAR:
+ case DOUBLE_QUOTE_CHAR:
+ state = QUOTED_COLLECTING_STATE;
+ quoteChar = c;
+ break;
+ case CURLY_RIGHT:
+ emitOptionToken(tokenList, optionList);
+ return;
+ default:
+ buf.append(c);
+ state = RAW_COLLECTING_STATE;
+ }
+ break;
+ case RAW_COLLECTING_STATE:
+ switch (c) {
+ case COMMA_CHAR:
+ optionList.add(buf.toString().trim());
+ buf.setLength(0);
+ state = EXPECTING_STATE;
+ break;
+ case CURLY_RIGHT:
+ optionList.add(buf.toString().trim());
+ emitOptionToken(tokenList, optionList);
+ return;
+ default:
+ buf.append(c);
+ }
+ break;
+ case QUOTED_COLLECTING_STATE:
+ if (c == quoteChar) {
+ optionList.add(buf.toString());
+ buf.setLength(0);
+ state = EXPECTING_STATE;
+ } else if (c == ESCAPE_CHAR) {
+ escape(String.valueOf(quoteChar), buf);
+ } else {
+ buf.append(c);
+ }
+
+ break;
+ }
+
+ c = pattern.charAt(tokenStream.pointer);
+ tokenStream.pointer++;
}
- OptionTokenizer(TokenStream tokenStream, IEscapeUtil escapeUtil) {
- this.tokenStream = tokenStream;
- this.pattern = tokenStream.pattern;
- this.patternLength = tokenStream.patternLength;
- this.escapeUtil = escapeUtil;
- }
- void tokenize(char firstChar, List<Token> tokenList) throws ScanException {
- StringBuffer buf = new StringBuffer();
- List<String> optionList = new ArrayList<String>();
- char c = firstChar;
-
- while (tokenStream.pointer < patternLength) {
- switch (state) {
- case EXPECTING_STATE:
- switch (c) {
- case ' ':
- case '\t':
- case '\r':
- case '\n':
- case COMMA_CHAR:
- break;
- case SINGLE_QUOTE_CHAR:
- case DOUBLE_QUOTE_CHAR:
- state = QUOTED_COLLECTING_STATE;
- quoteChar = c;
- break;
- case CURLY_RIGHT:
- emitOptionToken(tokenList, optionList);
- return;
- default:
- buf.append(c);
- state = RAW_COLLECTING_STATE;
- }
- break;
- case RAW_COLLECTING_STATE:
- switch (c) {
- case COMMA_CHAR:
- optionList.add(buf.toString().trim());
- buf.setLength(0);
- state = EXPECTING_STATE;
- break;
- case CURLY_RIGHT:
- optionList.add(buf.toString().trim());
- emitOptionToken(tokenList, optionList);
- return;
- default:
- buf.append(c);
- }
- break;
- case QUOTED_COLLECTING_STATE:
- if (c == quoteChar) {
- optionList.add(buf.toString());
- buf.setLength(0);
- state = EXPECTING_STATE;
- } else if (c == ESCAPE_CHAR) {
- escape(String.valueOf(quoteChar), buf);
- } else {
- buf.append(c);
- }
-
- break;
- }
-
- c = pattern.charAt(tokenStream.pointer);
- tokenStream.pointer++;
- }
-
- // EOS
- if (c == CURLY_RIGHT) {
- if (state == EXPECTING_STATE) {
- emitOptionToken(tokenList, optionList);
- } else if (state == RAW_COLLECTING_STATE) {
- optionList.add(buf.toString().trim());
- emitOptionToken(tokenList, optionList);
- } else {
- throw new ScanException("Unexpected end of pattern string in OptionTokenizer");
- }
- } else {
- throw new ScanException("Unexpected end of pattern string in OptionTokenizer");
- }
+ // EOS
+ if (c == CURLY_RIGHT) {
+ if(state == EXPECTING_STATE) {
+ emitOptionToken(tokenList, optionList);
+ } else if(state == RAW_COLLECTING_STATE){
+ optionList.add(buf.toString().trim());
+ emitOptionToken(tokenList, optionList);
+ } else {
+ throw new ScanException("Unexpected end of pattern string in OptionTokenizer");
+ }
+ } else {
+ throw new ScanException("Unexpected end of pattern string in OptionTokenizer");
}
+ }
- void emitOptionToken(List<Token> tokenList, List<String> optionList) {
- tokenList.add(new Token(Token.OPTION, optionList));
- tokenStream.state = TokenizerState.LITERAL_STATE;
- }
+ void emitOptionToken( List<Token> tokenList, List<String> optionList) {
+ tokenList.add(new Token(Token.OPTION, optionList));
+ tokenStream.state = TokenizerState.LITERAL_STATE;
+ }
- void escape(String escapeChars, StringBuffer buf) {
- if ((tokenStream.pointer < patternLength)) {
- char next = pattern.charAt(tokenStream.pointer++);
- escapeUtil.escape(escapeChars, buf, next, tokenStream.pointer);
- }
+ void escape(String escapeChars, StringBuffer buf) {
+ if ((tokenStream.pointer < patternLength)) {
+ char next = pattern.charAt(tokenStream.pointer++);
+ escapeUtil.escape(escapeChars, buf, next, tokenStream.pointer);
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Parser.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Parser.java
index 2bcba17..aad4f47 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Parser.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Parser.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -41,194 +41,199 @@ import ch.qos.logback.core.spi.ScanException;
// OPTION = {...} | ~
// COMPOSITE = E ')' OPTION
-public class Parser<E> extends ContextAwareBase {
-
- public final static String MISSING_RIGHT_PARENTHESIS = CoreConstants.CODES_URL + "#missingRightParenthesis";
- public final static Map<String, String> DEFAULT_COMPOSITE_CONVERTER_MAP = new HashMap<String, String>();
- public final static String REPLACE_CONVERTER_WORD = "replace";
- static {
- DEFAULT_COMPOSITE_CONVERTER_MAP.put(Token.BARE_COMPOSITE_KEYWORD_TOKEN.getValue().toString(), IdentityCompositeConverter.class.getName());
- DEFAULT_COMPOSITE_CONVERTER_MAP.put(REPLACE_CONVERTER_WORD, ReplacingCompositeConverter.class.getName());
- }
-
- final List tokenList;
- int pointer = 0;
-
- Parser(TokenStream ts) throws ScanException {
- this.tokenList = ts.tokenize();
- }
-
- public Parser(String pattern) throws ScanException {
- this(pattern, new RegularEscapeUtil());
- }
-
- public Parser(String pattern, IEscapeUtil escapeUtil) throws ScanException {
- try {
- TokenStream ts = new TokenStream(pattern, escapeUtil);
- this.tokenList = ts.tokenize();
- } catch (IllegalArgumentException npe) {
- throw new ScanException("Failed to initialize Parser", npe);
- }
- }
-
- /**
- * When the parsing step is done, the Node list can be transformed into a
- * converter chain.
- *
- * @param top
- * @param converterMap
- * @return
- * @throws ScanException
- */
- public Converter<E> compile(final Node top, Map converterMap) {
- Compiler<E> compiler = new Compiler<E>(top, converterMap);
- compiler.setContext(context);
- // compiler.setStatusManager(statusManager);
- return compiler.compile();
- }
-
- public Node parse() throws ScanException {
- return E();
- }
-
- // E = TEopt
- Node E() throws ScanException {
- Node t = T();
- if (t == null) {
- return null;
- }
- Node eOpt = Eopt();
- if (eOpt != null) {
- t.setNext(eOpt);
- }
- return t;
- }
-
- // Eopt = E|~
- Node Eopt() throws ScanException {
- // System.out.println("in Eopt()");
- Token next = getCurentToken();
- // System.out.println("Current token is " + next);
- if (next == null) {
- return null;
- } else {
- return E();
- }
- }
-
- // T = LITERAL | '%' C | '%' FORMAT_MODIFIER C
- Node T() throws ScanException {
- Token t = getCurentToken();
- expectNotNull(t, "a LITERAL or '%'");
-
- switch (t.getType()) {
- case Token.LITERAL:
- advanceTokenPointer();
- return new Node(Node.LITERAL, t.getValue());
- case Token.PERCENT:
- advanceTokenPointer();
- // System.out.println("% token found");
- FormatInfo fi;
- Token u = getCurentToken();
- FormattingNode c;
- expectNotNull(u, "a FORMAT_MODIFIER, SIMPLE_KEYWORD or COMPOUND_KEYWORD");
- if (u.getType() == Token.FORMAT_MODIFIER) {
- fi = FormatInfo.valueOf((String) u.getValue());
- advanceTokenPointer();
- c = C();
- c.setFormatInfo(fi);
- } else {
- c = C();
- }
- return c;
-
- default:
- return null;
-
- }
- }
-
- FormattingNode C() throws ScanException {
- Token t = getCurentToken();
- // System.out.println("in C()");
- // System.out.println("Current token is " + t);
- expectNotNull(t, "a LEFT_PARENTHESIS or KEYWORD");
- int type = t.getType();
- switch (type) {
- case Token.SIMPLE_KEYWORD:
- return SINGLE();
- case Token.COMPOSITE_KEYWORD:
- advanceTokenPointer();
- return COMPOSITE(t.getValue().toString());
- default:
- throw new IllegalStateException("Unexpected token " + t);
- }
- }
-
- FormattingNode SINGLE() throws ScanException {
- // System.out.println("in SINGLE()");
- Token t = getNextToken();
- // System.out.println("==" + t);
- SimpleKeywordNode keywordNode = new SimpleKeywordNode(t.getValue());
-
- Token ot = getCurentToken();
- if (ot != null && ot.getType() == Token.OPTION) {
- List<String> optionList = (List<String>) ot.getValue();
- keywordNode.setOptions(optionList);
- advanceTokenPointer();
- }
- return keywordNode;
- }
-
- FormattingNode COMPOSITE(String keyword) throws ScanException {
- CompositeNode compositeNode = new CompositeNode(keyword);
-
- Node childNode = E();
- compositeNode.setChildNode(childNode);
-
- Token t = getNextToken();
-
- if (t == null || t.getType() != Token.RIGHT_PARENTHESIS) {
- String msg = "Expecting RIGHT_PARENTHESIS token but got " + t;
- addError(msg);
- addError("See also " + MISSING_RIGHT_PARENTHESIS);
- throw new ScanException(msg);
- }
- Token ot = getCurentToken();
- if (ot != null && ot.getType() == Token.OPTION) {
- List<String> optionList = (List<String>) ot.getValue();
- compositeNode.setOptions(optionList);
- advanceTokenPointer();
- }
- return compositeNode;
- }
- Token getNextToken() {
- if (pointer < tokenList.size()) {
- return (Token) tokenList.get(pointer++);
- }
- return null;
- }
-
- Token getCurentToken() {
- if (pointer < tokenList.size()) {
- return (Token) tokenList.get(pointer);
- }
- return null;
- }
-
- void advanceTokenPointer() {
- pointer++;
- }
-
- void expectNotNull(Token t, String expected) {
- if (t == null) {
- throw new IllegalStateException("All tokens consumed but was expecting " + expected);
- }
- }
+public class Parser<E> extends ContextAwareBase {
- // public void setStatusManager(StatusManager statusManager) {
- // this.statusManager = statusManager;
- // }
+ public final static String MISSING_RIGHT_PARENTHESIS = CoreConstants.CODES_URL+"#missingRightParenthesis";
+ public final static Map<String, String> DEFAULT_COMPOSITE_CONVERTER_MAP = new HashMap<String, String>();
+ public final static String REPLACE_CONVERTER_WORD = "replace";
+ static {
+ DEFAULT_COMPOSITE_CONVERTER_MAP.put(Token.BARE_COMPOSITE_KEYWORD_TOKEN.getValue().toString(),
+ IdentityCompositeConverter.class.getName());
+ DEFAULT_COMPOSITE_CONVERTER_MAP.put(REPLACE_CONVERTER_WORD,
+ ReplacingCompositeConverter.class.getName());
+ }
+
+ final List tokenList;
+ int pointer = 0;
+
+ Parser(TokenStream ts) throws ScanException {
+ this.tokenList = ts.tokenize();
+ }
+
+ public Parser(String pattern) throws ScanException {
+ this(pattern, new RegularEscapeUtil());
+ }
+
+ public Parser(String pattern, IEscapeUtil escapeUtil) throws ScanException {
+ try {
+ TokenStream ts = new TokenStream(pattern, escapeUtil);
+ this.tokenList = ts.tokenize();
+ } catch (IllegalArgumentException npe) {
+ throw new ScanException("Failed to initialize Parser", npe);
+ }
+ }
+
+ /**
+ * When the parsing step is done, the Node list can be transformed into a
+ * converter chain.
+ *
+ * @param top
+ * @param converterMap
+ * @return
+ * @throws ScanException
+ */
+ public Converter<E> compile(final Node top, Map converterMap) {
+ Compiler<E> compiler = new Compiler<E>(top, converterMap);
+ compiler.setContext(context);
+ //compiler.setStatusManager(statusManager);
+ return compiler.compile();
+ }
+
+ public Node parse() throws ScanException {
+ return E();
+ }
+
+ // E = TEopt
+ Node E() throws ScanException {
+ Node t = T();
+ if (t == null) {
+ return null;
+ }
+ Node eOpt = Eopt();
+ if (eOpt != null) {
+ t.setNext(eOpt);
+ }
+ return t;
+ }
+
+ // Eopt = E|~
+ Node Eopt() throws ScanException {
+ // System.out.println("in Eopt()");
+ Token next = getCurentToken();
+ // System.out.println("Current token is " + next);
+ if (next == null) {
+ return null;
+ } else {
+ return E();
+ }
+ }
+
+ // T = LITERAL | '%' C | '%' FORMAT_MODIFIER C
+ Node T() throws ScanException {
+ Token t = getCurentToken();
+ expectNotNull(t, "a LITERAL or '%'");
+
+ switch (t.getType()) {
+ case Token.LITERAL:
+ advanceTokenPointer();
+ return new Node(Node.LITERAL, t.getValue());
+ case Token.PERCENT:
+ advanceTokenPointer();
+ // System.out.println("% token found");
+ FormatInfo fi;
+ Token u = getCurentToken();
+ FormattingNode c;
+ expectNotNull(u, "a FORMAT_MODIFIER, SIMPLE_KEYWORD or COMPOUND_KEYWORD");
+ if (u.getType() == Token.FORMAT_MODIFIER) {
+ fi = FormatInfo.valueOf((String) u.getValue());
+ advanceTokenPointer();
+ c = C();
+ c.setFormatInfo(fi);
+ } else {
+ c = C();
+ }
+ return c;
+
+ default:
+ return null;
+
+ }
+
+ }
+
+ FormattingNode C() throws ScanException {
+ Token t = getCurentToken();
+ // System.out.println("in C()");
+ // System.out.println("Current token is " + t);
+ expectNotNull(t, "a LEFT_PARENTHESIS or KEYWORD");
+ int type = t.getType();
+ switch (type) {
+ case Token.SIMPLE_KEYWORD:
+ return SINGLE();
+ case Token.COMPOSITE_KEYWORD:
+ advanceTokenPointer();
+ return COMPOSITE(t.getValue().toString());
+ default:
+ throw new IllegalStateException("Unexpected token " + t);
+ }
+ }
+
+ FormattingNode SINGLE() throws ScanException {
+ // System.out.println("in SINGLE()");
+ Token t = getNextToken();
+ // System.out.println("==" + t);
+ SimpleKeywordNode keywordNode = new SimpleKeywordNode(t.getValue());
+
+ Token ot = getCurentToken();
+ if (ot != null && ot.getType() == Token.OPTION) {
+ List<String> optionList = (List<String>) ot.getValue();
+ keywordNode.setOptions(optionList);
+ advanceTokenPointer();
+ }
+ return keywordNode;
+ }
+
+ FormattingNode COMPOSITE(String keyword) throws ScanException {
+ CompositeNode compositeNode = new CompositeNode(keyword);
+
+ Node childNode = E();
+ compositeNode.setChildNode(childNode);
+
+ Token t = getNextToken();
+
+ if (t == null || t.getType() != Token.RIGHT_PARENTHESIS) {
+ String msg = "Expecting RIGHT_PARENTHESIS token but got " + t;
+ addError(msg);
+ addError("See also "+MISSING_RIGHT_PARENTHESIS);
+ throw new ScanException(msg);
+ }
+ Token ot = getCurentToken();
+ if (ot != null && ot.getType() == Token.OPTION) {
+ List<String> optionList = (List<String>) ot.getValue();
+ compositeNode.setOptions(optionList);
+ advanceTokenPointer();
+ }
+ return compositeNode;
+ }
+
+ Token getNextToken() {
+ if (pointer < tokenList.size()) {
+ return (Token) tokenList.get(pointer++);
+ }
+ return null;
+ }
+
+ Token getCurentToken() {
+ if (pointer < tokenList.size()) {
+ return (Token) tokenList.get(pointer);
+ }
+ return null;
+ }
+
+ void advanceTokenPointer() {
+ pointer++;
+ }
+
+ void expectNotNull(Token t, String expected) {
+ if (t == null) {
+ throw new IllegalStateException("All tokens consumed but was expecting "
+ + expected);
+ }
+ }
+
+// public void setStatusManager(StatusManager statusManager) {
+// this.statusManager = statusManager;
+// }
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/SimpleKeywordNode.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/SimpleKeywordNode.java
index afc3083..33050e8 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/SimpleKeywordNode.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/SimpleKeywordNode.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,50 +17,52 @@ import java.util.List;
public class SimpleKeywordNode extends FormattingNode {
- List<String> optionList;
+ List<String> optionList;
- SimpleKeywordNode(Object value) {
- super(Node.SIMPLE_KEYWORD, value);
- }
-
- protected SimpleKeywordNode(int type, Object value) {
- super(type, value);
- }
-
- public List<String> getOptions() {
- return optionList;
- }
+ SimpleKeywordNode(Object value) {
+ super(Node.SIMPLE_KEYWORD, value);
+ }
- public void setOptions(List<String> optionList) {
- this.optionList = optionList;
- }
+ protected SimpleKeywordNode(int type, Object value) {
+ super(type, value);
+ }
- public boolean equals(Object o) {
- if (!super.equals(o)) {
- return false;
- }
+ public List<String> getOptions() {
+ return optionList;
+ }
- if (!(o instanceof SimpleKeywordNode)) {
- return false;
- }
- SimpleKeywordNode r = (SimpleKeywordNode) o;
+ public void setOptions(List<String> optionList) {
+ this.optionList = optionList;
+ }
- return (optionList != null ? optionList.equals(r.optionList) : r.optionList == null);
+ public boolean equals(Object o) {
+ if (!super.equals(o)) {
+ return false;
}
- @Override
- public int hashCode() {
- return super.hashCode();
+ if (!(o instanceof SimpleKeywordNode)) {
+ return false;
}
+ SimpleKeywordNode r = (SimpleKeywordNode) o;
+
+ return (optionList != null ? optionList.equals(r.optionList)
+ : r.optionList == null);
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
- public String toString() {
- StringBuilder buf = new StringBuilder();
- if (optionList == null) {
- buf.append("KeyWord(" + value + "," + formatInfo + ")");
- } else {
- buf.append("KeyWord(" + value + ", " + formatInfo + "," + optionList + ")");
- }
- buf.append(printNext());
- return buf.toString();
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ if (optionList == null) {
+ buf.append("KeyWord(" + value + "," + formatInfo + ")");
+ } else {
+ buf.append("KeyWord(" + value + ", " + formatInfo + "," + optionList
+ + ")");
}
+ buf.append(printNext());
+ return buf.toString();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Token.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Token.java
index 7861ef3..86c3da6 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Token.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/Token.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,103 +15,103 @@ package ch.qos.logback.core.pattern.parser;
class Token {
- static final int PERCENT = 37;
- // static final int LEFT_PARENTHESIS = 40;
- static final int RIGHT_PARENTHESIS = 41;
- static final int MINUS = 45;
- static final int DOT = 46;
- static final int CURLY_LEFT = 123;
- static final int CURLY_RIGHT = 125;
- static final int LITERAL = 1000;
- static final int FORMAT_MODIFIER = 1002;
- static final int SIMPLE_KEYWORD = 1004;
- static final int COMPOSITE_KEYWORD = 1005;
- static final int OPTION = 1006;
-
- static final int EOF = Integer.MAX_VALUE;
-
- static Token EOF_TOKEN = new Token(EOF, "EOF");
- static Token RIGHT_PARENTHESIS_TOKEN = new Token(RIGHT_PARENTHESIS);
- static Token BARE_COMPOSITE_KEYWORD_TOKEN = new Token(COMPOSITE_KEYWORD, "BARE");
- static Token PERCENT_TOKEN = new Token(PERCENT);
-
- private final int type;
- private final Object value;
-
- public Token(int type) {
- this(type, null);
+ static final int PERCENT = 37;
+ //static final int LEFT_PARENTHESIS = 40;
+ static final int RIGHT_PARENTHESIS = 41;
+ static final int MINUS = 45;
+ static final int DOT = 46;
+ static final int CURLY_LEFT = 123;
+ static final int CURLY_RIGHT = 125;
+
+ static final int LITERAL = 1000;
+ static final int FORMAT_MODIFIER = 1002;
+ static final int SIMPLE_KEYWORD = 1004;
+ static final int COMPOSITE_KEYWORD = 1005;
+ static final int OPTION = 1006;
+
+ static final int EOF = Integer.MAX_VALUE;
+
+ static Token EOF_TOKEN = new Token(EOF, "EOF");
+ static Token RIGHT_PARENTHESIS_TOKEN = new Token(RIGHT_PARENTHESIS);
+ static Token BARE_COMPOSITE_KEYWORD_TOKEN = new Token(COMPOSITE_KEYWORD, "BARE");
+ static Token PERCENT_TOKEN = new Token(PERCENT);
+
+ private final int type;
+ private final Object value;
+
+
+ public Token(int type) {
+ this(type, null);
+ }
+
+ public Token(int type, Object value) {
+ this.type = type;
+ this.value = value;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+
+ public String toString() {
+ String typeStr = null;
+ switch (type) {
+
+ case PERCENT:
+ typeStr = "%";
+ break;
+ case FORMAT_MODIFIER:
+ typeStr = "FormatModifier";
+ break;
+ case LITERAL:
+ typeStr = "LITERAL";
+ break;
+ case OPTION:
+ typeStr = "OPTION";
+ break;
+ case SIMPLE_KEYWORD:
+ typeStr = "SIMPLE_KEYWORD";
+ break;
+ case COMPOSITE_KEYWORD:
+ typeStr = "COMPOSITE_KEYWORD";
+ break;
+ case RIGHT_PARENTHESIS:
+ typeStr = "RIGHT_PARENTHESIS";
+ break;
+ default:
+ typeStr = "UNKNOWN";
}
+ if (value == null) {
+ return "Token(" + typeStr + ")";
- public Token(int type, Object value) {
- this.type = type;
- this.value = value;
+ } else {
+ return "Token(" + typeStr + ", \"" + value + "\")";
}
+ }
- public int getType() {
- return type;
- }
+ public int hashCode() {
+ int result;
+ result = type;
+ result = 29 * result + (value != null ? value.hashCode() : 0);
+ return result;
+ }
- public Object getValue() {
- return value;
- }
- public String toString() {
- String typeStr = null;
- switch (type) {
-
- case PERCENT:
- typeStr = "%";
- break;
- case FORMAT_MODIFIER:
- typeStr = "FormatModifier";
- break;
- case LITERAL:
- typeStr = "LITERAL";
- break;
- case OPTION:
- typeStr = "OPTION";
- break;
- case SIMPLE_KEYWORD:
- typeStr = "SIMPLE_KEYWORD";
- break;
- case COMPOSITE_KEYWORD:
- typeStr = "COMPOSITE_KEYWORD";
- break;
- case RIGHT_PARENTHESIS:
- typeStr = "RIGHT_PARENTHESIS";
- break;
- default:
- typeStr = "UNKNOWN";
- }
- if (value == null) {
- return "Token(" + typeStr + ")";
-
- } else {
- return "Token(" + typeStr + ", \"" + value + "\")";
- }
- }
-
- public int hashCode() {
- int result;
- result = type;
- result = 29 * result + (value != null ? value.hashCode() : 0);
- return result;
- }
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Token)) return false;
- public boolean equals(Object o) {
- if (this == o)
- return true;
- if (!(o instanceof Token))
- return false;
+ final Token token = (Token) o;
- final Token token = (Token) o;
+ if (type != token.type) return false;
+ if (value != null ? !value.equals(token.value) : token.value != null) return false;
- if (type != token.type)
- return false;
- if (value != null ? !value.equals(token.value) : token.value != null)
- return false;
-
- return true;
- }
+ return true;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/TokenStream.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/TokenStream.java
index 4c46c34..8a26d35 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/TokenStream.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/parser/TokenStream.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -46,190 +46,192 @@ import ch.qos.logback.core.spi.ScanException;
*/
class TokenStream {
- enum TokenizerState {
- LITERAL_STATE, FORMAT_MODIFIER_STATE, KEYWORD_STATE, OPTION_STATE, RIGHT_PARENTHESIS_STATE
- }
+ enum TokenizerState { LITERAL_STATE, FORMAT_MODIFIER_STATE, KEYWORD_STATE, OPTION_STATE, RIGHT_PARENTHESIS_STATE}
- final String pattern;
- final int patternLength;
- final IEscapeUtil escapeUtil;
+ final String pattern;
+ final int patternLength;
+ final IEscapeUtil escapeUtil;
- final IEscapeUtil optionEscapeUtil = new RestrictedEscapeUtil();
+ final IEscapeUtil optionEscapeUtil = new RestrictedEscapeUtil();
- TokenizerState state = TokenizerState.LITERAL_STATE;
- int pointer = 0;
+ TokenizerState state = TokenizerState.LITERAL_STATE;
+ int pointer = 0;
- // this variant should be used for testing purposes only
- TokenStream(String pattern) {
- this(pattern, new RegularEscapeUtil());
- }
+ // this variant should be used for testing purposes only
+ TokenStream(String pattern) {
+ this(pattern, new RegularEscapeUtil());
+ }
- TokenStream(String pattern, IEscapeUtil escapeUtil) {
- if (pattern == null || pattern.length() == 0) {
- throw new IllegalArgumentException("null or empty pattern string not allowed");
- }
- this.pattern = pattern;
- patternLength = pattern.length();
- this.escapeUtil = escapeUtil;
+ TokenStream(String pattern, IEscapeUtil escapeUtil) {
+ if (pattern == null || pattern.length() == 0) {
+ throw new IllegalArgumentException(
+ "null or empty pattern string not allowed");
}
+ this.pattern = pattern;
+ patternLength = pattern.length();
+ this.escapeUtil = escapeUtil;
+ }
- List tokenize() throws ScanException {
- List<Token> tokenList = new ArrayList<Token>();
- StringBuffer buf = new StringBuffer();
-
- while (pointer < patternLength) {
- char c = pattern.charAt(pointer);
- pointer++;
-
- switch (state) {
- case LITERAL_STATE:
- handleLiteralState(c, tokenList, buf);
- break;
- case FORMAT_MODIFIER_STATE:
- handleFormatModifierState(c, tokenList, buf);
- break;
- case OPTION_STATE:
- processOption(c, tokenList, buf);
- break;
- case KEYWORD_STATE:
- handleKeywordState(c, tokenList, buf);
- break;
- case RIGHT_PARENTHESIS_STATE:
- handleRightParenthesisState(c, tokenList, buf);
- break;
-
- default:
- }
- }
+ List tokenize() throws ScanException {
+ List<Token> tokenList = new ArrayList<Token>();
+ StringBuffer buf = new StringBuffer();
- // EOS
- switch (state) {
- case LITERAL_STATE:
- addValuedToken(Token.LITERAL, buf, tokenList);
- break;
- case KEYWORD_STATE:
- tokenList.add(new Token(Token.SIMPLE_KEYWORD, buf.toString()));
- break;
- case RIGHT_PARENTHESIS_STATE:
- tokenList.add(Token.RIGHT_PARENTHESIS_TOKEN);
- break;
+ while (pointer < patternLength) {
+ char c = pattern.charAt(pointer);
+ pointer++;
+ switch (state) {
+ case LITERAL_STATE:
+ handleLiteralState(c, tokenList, buf);
+ break;
case FORMAT_MODIFIER_STATE:
+ handleFormatModifierState(c, tokenList, buf);
+ break;
case OPTION_STATE:
- throw new ScanException("Unexpected end of pattern string");
- }
+ processOption(c, tokenList, buf);
+ break;
+ case KEYWORD_STATE:
+ handleKeywordState(c, tokenList, buf);
+ break;
+ case RIGHT_PARENTHESIS_STATE:
+ handleRightParenthesisState(c, tokenList, buf);
+ break;
- return tokenList;
+ default:
+ }
}
- private void handleRightParenthesisState(char c, List<Token> tokenList, StringBuffer buf) {
+ // EOS
+ switch (state) {
+ case LITERAL_STATE:
+ addValuedToken(Token.LITERAL, buf, tokenList);
+ break;
+ case KEYWORD_STATE:
+ tokenList.add(new Token(Token.SIMPLE_KEYWORD, buf.toString()));
+ break;
+ case RIGHT_PARENTHESIS_STATE:
tokenList.add(Token.RIGHT_PARENTHESIS_TOKEN);
- switch (c) {
- case CoreConstants.RIGHT_PARENTHESIS_CHAR:
- break;
- case CURLY_LEFT:
- state = TokenizerState.OPTION_STATE;
- break;
- case ESCAPE_CHAR:
- escape("%{}", buf);
- state = TokenizerState.LITERAL_STATE;
- break;
- default:
- buf.append(c);
- state = TokenizerState.LITERAL_STATE;
- }
- }
+ break;
- private void processOption(char c, List<Token> tokenList, StringBuffer buf) throws ScanException {
- OptionTokenizer ot = new OptionTokenizer(this);
- ot.tokenize(c, tokenList);
+ case FORMAT_MODIFIER_STATE:
+ case OPTION_STATE:
+ throw new ScanException("Unexpected end of pattern string");
}
- private void handleFormatModifierState(char c, List<Token> tokenList, StringBuffer buf) {
- if (c == CoreConstants.LEFT_PARENTHESIS_CHAR) {
- addValuedToken(Token.FORMAT_MODIFIER, buf, tokenList);
- tokenList.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
- state = TokenizerState.LITERAL_STATE;
- } else if (Character.isJavaIdentifierStart(c)) {
- addValuedToken(Token.FORMAT_MODIFIER, buf, tokenList);
- state = TokenizerState.KEYWORD_STATE;
- buf.append(c);
- } else {
- buf.append(c);
- }
+ return tokenList;
+ }
+
+ private void handleRightParenthesisState(char c, List<Token> tokenList, StringBuffer buf) {
+ tokenList.add(Token.RIGHT_PARENTHESIS_TOKEN);
+ switch (c) {
+ case CoreConstants.RIGHT_PARENTHESIS_CHAR:
+ break;
+ case CURLY_LEFT:
+ state = TokenizerState.OPTION_STATE;
+ break;
+ case ESCAPE_CHAR:
+ escape("%{}", buf);
+ state = TokenizerState.LITERAL_STATE;
+ break;
+ default:
+ buf.append(c);
+ state = TokenizerState.LITERAL_STATE;
}
-
- private void handleLiteralState(char c, List<Token> tokenList, StringBuffer buf) {
- switch (c) {
- case ESCAPE_CHAR:
- escape("%()", buf);
- break;
-
- case CoreConstants.PERCENT_CHAR:
- addValuedToken(Token.LITERAL, buf, tokenList);
- tokenList.add(Token.PERCENT_TOKEN);
- state = TokenizerState.FORMAT_MODIFIER_STATE;
- break;
-
- case CoreConstants.RIGHT_PARENTHESIS_CHAR:
- addValuedToken(Token.LITERAL, buf, tokenList);
- state = TokenizerState.RIGHT_PARENTHESIS_STATE;
- break;
-
- default:
- buf.append(c);
- }
+ }
+
+ private void processOption(char c, List<Token> tokenList, StringBuffer buf) throws ScanException {
+ OptionTokenizer ot = new OptionTokenizer(this);
+ ot.tokenize(c, tokenList);
+ }
+
+ private void handleFormatModifierState(char c, List<Token> tokenList, StringBuffer buf) {
+ if (c == CoreConstants.LEFT_PARENTHESIS_CHAR) {
+ addValuedToken(Token.FORMAT_MODIFIER, buf, tokenList);
+ tokenList.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
+ state = TokenizerState.LITERAL_STATE;
+ } else if (Character.isJavaIdentifierStart(c)) {
+ addValuedToken(Token.FORMAT_MODIFIER, buf, tokenList);
+ state = TokenizerState.KEYWORD_STATE;
+ buf.append(c);
+ } else {
+ buf.append(c);
}
-
- private void handleKeywordState(char c, List<Token> tokenList, StringBuffer buf) {
-
- if (Character.isJavaIdentifierPart(c)) {
- buf.append(c);
- } else if (c == CURLY_LEFT) {
- addValuedToken(Token.SIMPLE_KEYWORD, buf, tokenList);
- state = TokenizerState.OPTION_STATE;
- } else if (c == CoreConstants.LEFT_PARENTHESIS_CHAR) {
- addValuedToken(Token.COMPOSITE_KEYWORD, buf, tokenList);
- state = TokenizerState.LITERAL_STATE;
- } else if (c == CoreConstants.PERCENT_CHAR) {
- addValuedToken(Token.SIMPLE_KEYWORD, buf, tokenList);
- tokenList.add(Token.PERCENT_TOKEN);
- state = TokenizerState.FORMAT_MODIFIER_STATE;
- } else if (c == CoreConstants.RIGHT_PARENTHESIS_CHAR) {
- addValuedToken(Token.SIMPLE_KEYWORD, buf, tokenList);
- state = TokenizerState.RIGHT_PARENTHESIS_STATE;
- } else {
- addValuedToken(Token.SIMPLE_KEYWORD, buf, tokenList);
- if (c == ESCAPE_CHAR) {
- if ((pointer < patternLength)) {
- char next = pattern.charAt(pointer++);
- escapeUtil.escape("%()", buf, next, pointer);
- }
- } else {
- buf.append(c);
- }
- state = TokenizerState.LITERAL_STATE;
- }
+ }
+
+ private void handleLiteralState(char c, List<Token> tokenList, StringBuffer buf) {
+ switch (c) {
+ case ESCAPE_CHAR:
+ escape("%()", buf);
+ break;
+
+ case CoreConstants.PERCENT_CHAR:
+ addValuedToken(Token.LITERAL, buf, tokenList);
+ tokenList.add(Token.PERCENT_TOKEN);
+ state = TokenizerState.FORMAT_MODIFIER_STATE;
+ break;
+
+ case CoreConstants.RIGHT_PARENTHESIS_CHAR:
+ addValuedToken(Token.LITERAL, buf, tokenList);
+ state = TokenizerState.RIGHT_PARENTHESIS_STATE;
+ break;
+
+ default:
+ buf.append(c);
}
-
- void escape(String escapeChars, StringBuffer buf) {
+ }
+
+ private void handleKeywordState(char c, List<Token> tokenList, StringBuffer buf) {
+
+ if (Character.isJavaIdentifierPart(c)) {
+ buf.append(c);
+ } else if (c == CURLY_LEFT) {
+ addValuedToken(Token.SIMPLE_KEYWORD, buf, tokenList);
+ state = TokenizerState.OPTION_STATE;
+ } else if (c == CoreConstants.LEFT_PARENTHESIS_CHAR) {
+ addValuedToken(Token.COMPOSITE_KEYWORD, buf, tokenList);
+ state = TokenizerState.LITERAL_STATE;
+ } else if (c == CoreConstants.PERCENT_CHAR) {
+ addValuedToken(Token.SIMPLE_KEYWORD, buf, tokenList);
+ tokenList.add(Token.PERCENT_TOKEN);
+ state = TokenizerState.FORMAT_MODIFIER_STATE;
+ } else if (c == CoreConstants.RIGHT_PARENTHESIS_CHAR) {
+ addValuedToken(Token.SIMPLE_KEYWORD, buf, tokenList);
+ state = TokenizerState.RIGHT_PARENTHESIS_STATE;
+ } else {
+ addValuedToken(Token.SIMPLE_KEYWORD, buf, tokenList);
+ if (c == ESCAPE_CHAR) {
if ((pointer < patternLength)) {
- char next = pattern.charAt(pointer++);
- escapeUtil.escape(escapeChars, buf, next, pointer);
+ char next = pattern.charAt(pointer++);
+ escapeUtil.escape("%()", buf, next, pointer);
}
+ } else {
+ buf.append(c);
+ }
+ state = TokenizerState.LITERAL_STATE;
}
+ }
- void optionEscape(String escapeChars, StringBuffer buf) {
- if ((pointer < patternLength)) {
- char next = pattern.charAt(pointer++);
- optionEscapeUtil.escape(escapeChars, buf, next, pointer);
- }
+ void escape(String escapeChars, StringBuffer buf) {
+ if ((pointer < patternLength)) {
+ char next = pattern.charAt(pointer++);
+ escapeUtil.escape(escapeChars, buf, next, pointer);
}
+ }
- private void addValuedToken(int type, StringBuffer buf, List<Token> tokenList) {
- if (buf.length() > 0) {
- tokenList.add(new Token(type, buf.toString()));
- buf.setLength(0);
- }
+ void optionEscape(String escapeChars, StringBuffer buf) {
+ if ((pointer < patternLength)) {
+ char next = pattern.charAt(pointer++);
+ optionEscapeUtil.escape(escapeChars, buf, next, pointer);
+ }
+ }
+
+
+
+
+ private void addValuedToken(int type, StringBuffer buf, List<Token> tokenList) {
+ if (buf.length() > 0) {
+ tokenList.add(new Token(type, buf.toString()));
+ buf.setLength(0);
}
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/util/AlmostAsIsEscapeUtil.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/util/AlmostAsIsEscapeUtil.java
index fafda99..1daea37 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/util/AlmostAsIsEscapeUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/util/AlmostAsIsEscapeUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,22 +23,23 @@ import ch.qos.logback.core.rolling.helper.FileNamePattern;
*/
public class AlmostAsIsEscapeUtil extends RestrictedEscapeUtil {
- /**
- * Do not perform any character escaping, except for '%', and ')'.
- *
- * <p>
- * Here is the rationale. First, filename patterns do not include escape
- * combinations such as \r or \n. Moreover, characters which have special
- * meaning in logback parsers, such as '{', or '}' cannot be part of file
- * names (so me thinks). The left parenthesis character has special meaning
- * only if it is preceded by %. Thus, the only characters that needs escaping
- * are '%' and ')'.
- *
- * <p>
- * Note that this method assumes that it is called after the escape character
- * has been consumed.
- */
- public void escape(String escapeChars, StringBuffer buf, char next, int pointer) {
- super.escape("" + CoreConstants.PERCENT_CHAR + CoreConstants.RIGHT_PARENTHESIS_CHAR, buf, next, pointer);
- }
+ /**
+ * Do not perform any character escaping, except for '%', and ')'.
+ *
+ * <p>
+ * Here is the rationale. First, filename patterns do not include escape
+ * combinations such as \r or \n. Moreover, characters which have special
+ * meaning in logback parsers, such as '{', or '}' cannot be part of file
+ * names (so me thinks). The left parenthesis character has special meaning
+ * only if it is preceded by %. Thus, the only characters that needs escaping
+ * are '%' and ')'.
+ *
+ * <p>
+ * Note that this method assumes that it is called after the escape character
+ * has been consumed.
+ */
+ public void escape(String escapeChars, StringBuffer buf, char next,
+ int pointer) {
+ super.escape(""+CoreConstants.PERCENT_CHAR+CoreConstants.RIGHT_PARENTHESIS_CHAR, buf, next, pointer);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/util/AsIsEscapeUtil.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/util/AsIsEscapeUtil.java
index 452c7d9..e02a350 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/util/AsIsEscapeUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/util/AsIsEscapeUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,17 +18,18 @@ package ch.qos.logback.core.pattern.util;
*/
public class AsIsEscapeUtil implements IEscapeUtil {
- /**
- * Do not perform any character escaping.
- * <p/>
- * Note that this method assumes that it is called after the escape character
- * has been consumed.
- */
- public void escape(String escapeChars, StringBuffer buf, char next, int pointer) {
- // restitute the escape char (because it was consumed
- // before this method was called).
- buf.append("\\");
- // restitute the next character
- buf.append(next);
- }
+ /**
+ * Do not perform any character escaping.
+ * <p/>
+ * Note that this method assumes that it is called after the escape character
+ * has been consumed.
+ */
+ public void escape(String escapeChars, StringBuffer buf, char next,
+ int pointer) {
+ // restitute the escape char (because it was consumed
+ // before this method was called).
+ buf.append("\\");
+ // restitute the next character
+ buf.append(next);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/util/IEscapeUtil.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/util/IEscapeUtil.java
index 55536bc..c597b9c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/util/IEscapeUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/util/IEscapeUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,5 +15,5 @@ package ch.qos.logback.core.pattern.util;
public interface IEscapeUtil {
- void escape(String additionalEscapeChars, StringBuffer buf, char next, int pointer);
+ void escape(String additionalEscapeChars, StringBuffer buf, char next, int pointer);
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/util/RegularEscapeUtil.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/util/RegularEscapeUtil.java
index 8a09731..481bdf0 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/util/RegularEscapeUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/util/RegularEscapeUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,71 +20,73 @@ package ch.qos.logback.core.pattern.util;
*/
public class RegularEscapeUtil implements IEscapeUtil {
- public void escape(String escapeChars, StringBuffer buf, char next, int pointer) {
- if (escapeChars.indexOf(next) >= 0) {
- buf.append(next);
- } else
- switch (next) {
- case '_':
- // the \_ sequence is swallowed
- break;
- case '\\':
- buf.append(next);
- break;
- case 't':
- buf.append('\t');
- break;
- case 'r':
- buf.append('\r');
- break;
- case 'n':
- buf.append('\n');
- break;
- default:
- String commaSeperatedEscapeChars = formatEscapeCharsForListing(escapeChars);
- throw new IllegalArgumentException("Illegal char '" + next + " at column " + pointer + ". Only \\\\, \\_" + commaSeperatedEscapeChars
- + ", \\t, \\n, \\r combinations are allowed as escape characters.");
- }
- }
+ public void escape(String escapeChars, StringBuffer buf, char next,
+ int pointer) {
+ if (escapeChars.indexOf(next) >= 0) {
+ buf.append(next);
+ } else
+ switch (next) {
+ case '_':
+ // the \_ sequence is swallowed
+ break;
+ case '\\':
+ buf.append(next);
+ break;
+ case 't':
+ buf.append('\t');
+ break;
+ case 'r':
+ buf.append('\r');
+ break;
+ case 'n':
+ buf.append('\n');
+ break;
+ default:
+ String commaSeperatedEscapeChars = formatEscapeCharsForListing(escapeChars);
+ throw new IllegalArgumentException("Illegal char '" + next + " at column "
+ + pointer + ". Only \\\\, \\_" + commaSeperatedEscapeChars
+ + ", \\t, \\n, \\r combinations are allowed as escape characters.");
+ }
+ }
- String formatEscapeCharsForListing(String escapeChars) {
- StringBuilder commaSeperatedEscapeChars = new StringBuilder();
- for (int i = 0; i < escapeChars.length(); i++) {
- commaSeperatedEscapeChars.append(", \\").append(escapeChars.charAt(i));
- }
- return commaSeperatedEscapeChars.toString();
+ String formatEscapeCharsForListing(String escapeChars) {
+ StringBuilder commaSeperatedEscapeChars = new StringBuilder();
+ for (int i = 0; i < escapeChars.length(); i++) {
+ commaSeperatedEscapeChars.append(", \\").append(escapeChars.charAt(i));
}
+ return commaSeperatedEscapeChars.toString();
+ }
- public static String basicEscape(String s) {
- char c;
- int len = s.length();
- StringBuilder sbuf = new StringBuilder(len);
+ public static String basicEscape(String s) {
+ char c;
+ int len = s.length();
+ StringBuilder sbuf = new StringBuilder(len);
- int i = 0;
- while (i < len) {
- c = s.charAt(i++);
- if (c == '\\') {
- c = s.charAt(i++);
- if (c == 'n') {
- c = '\n';
- } else if (c == 'r') {
- c = '\r';
- } else if (c == 't') {
- c = '\t';
- } else if (c == 'f') {
- c = '\f';
- } else if (c == '\b') {
- c = '\b';
- } else if (c == '\"') {
- c = '\"';
- } else if (c == '\'') {
- c = '\'';
- } else if (c == '\\') {
- c = '\\';
- }
- }
- sbuf.append(c);
+ int i = 0;
+ while (i < len) {
+ c = s.charAt(i++);
+ if (c == '\\') {
+ c = s.charAt(i++);
+ if (c == 'n') {
+ c = '\n';
+ } else if (c == 'r') {
+ c = '\r';
+ } else if (c == 't') {
+ c = '\t';
+ } else if (c == 'f') {
+ c = '\f';
+ } else if (c == '\b') {
+ c = '\b';
+ } else if (c == '\"') {
+ c = '\"';
+ } else if (c == '\'') {
+ c = '\'';
+ } else if (c == '\\') {
+ c = '\\';
}
- return sbuf.toString();
+ }
+ sbuf.append(c);
}
+ return sbuf.toString();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/util/RestrictedEscapeUtil.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/util/RestrictedEscapeUtil.java
index dd73bf1..0a6599c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/util/RestrictedEscapeUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/util/RestrictedEscapeUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,16 +20,18 @@ package ch.qos.logback.core.pattern.util;
*/
public class RestrictedEscapeUtil implements IEscapeUtil {
- public void escape(String escapeChars, StringBuffer buf, char next, int pointer) {
- if (escapeChars.indexOf(next) >= 0) {
- buf.append(next);
- } else {
- // restitute the escape char (because it was consumed
- // before this method was called).
- buf.append("\\");
- // restitute the next character
- buf.append(next);
- }
+ public void escape(String escapeChars, StringBuffer buf, char next,
+ int pointer) {
+ if (escapeChars.indexOf(next) >= 0) {
+ buf.append(next);
+ } else {
+ // restitute the escape char (because it was consumed
+ // before this method was called).
+ buf.append("\\");
+ // restitute the next character
+ buf.append(next);
}
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/property/FileExistsPropertyDefiner.java b/logback-core/src/main/java/ch/qos/logback/core/property/FileExistsPropertyDefiner.java
index b304cd9..b265ddd 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/property/FileExistsPropertyDefiner.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/property/FileExistsPropertyDefiner.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,38 +25,38 @@ import java.io.File;
*
* @see #getPropertyValue()
*
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class FileExistsPropertyDefiner extends PropertyDefinerBase {
- String path;
-
- public String getPath() {
- return path;
- }
-
- /**
- * The path for the file to search for.
- *
- * @param path
- */
- public void setPath(String path) {
- this.path = path;
+ String path;
+
+ public String getPath() {
+ return path;
+ }
+
+ /**
+ * The path for the file to search for.
+ *
+ * @param path
+ */
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ /**
+ * Returns "true" if the file specified by {@link #setPath(String) path} property exists.
+ * Returns "false" otherwise.
+ *
+ * @return "true"|"false" depending on the existence of file
+ */
+ public String getPropertyValue() {
+ if (OptionHelper.isEmpty(path)) {
+ addError("The \"path\" property must be set.");
+ return null;
}
- /**
- * Returns "true" if the file specified by {@link #setPath(String) path} property exists.
- * Returns "false" otherwise.
- *
- * @return "true"|"false" depending on the existence of file
- */
- public String getPropertyValue() {
- if (OptionHelper.isEmpty(path)) {
- addError("The \"path\" property must be set.");
- return null;
- }
-
- File file = new File(path);
- return booleanAsStr(file.exists());
- }
+ File file = new File(path);
+ return booleanAsStr(file.exists());
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/property/ResourceExistsPropertyDefiner.java b/logback-core/src/main/java/ch/qos/logback/core/property/ResourceExistsPropertyDefiner.java
index b2b28fc..d5f7672 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/property/ResourceExistsPropertyDefiner.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/property/ResourceExistsPropertyDefiner.java
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
package ch.qos.logback.core.property;
import ch.qos.logback.core.PropertyDefinerBase;
@@ -32,35 +19,35 @@ import java.net.URL;
*/
public class ResourceExistsPropertyDefiner extends PropertyDefinerBase {
- String resourceStr;
-
- public String getResource() {
- return resourceStr;
- }
-
- /**
- * The resource to search for on the class path.
- *
- * @param resource
- */
- public void setResource(String resource) {
- this.resourceStr = resource;
+ String resourceStr;
+
+ public String getResource() {
+ return resourceStr;
+ }
+
+ /**
+ * The resource to search for on the class path.
+ *
+ * @param resource
+ */
+ public void setResource(String resource) {
+ this.resourceStr = resource;
+ }
+
+ /**
+ * Returns the string "true" if the {@link #setResource(String) resource} specified by the
+ * user is available on the class path, "false" otherwise.
+ *
+ * @return "true"|"false" depending on the availability of resource on the classpath
+ */
+ public String getPropertyValue() {
+ if (OptionHelper.isEmpty(resourceStr)) {
+ addError("The \"resource\" property must be set.");
+ return null;
}
- /**
- * Returns the string "true" if the {@link #setResource(String) resource} specified by the
- * user is available on the class path, "false" otherwise.
- *
- * @return "true"|"false" depending on the availability of resource on the classpath
- */
- public String getPropertyValue() {
- if (OptionHelper.isEmpty(resourceStr)) {
- addError("The \"resource\" property must be set.");
- return null;
- }
-
- URL resourceURL = Loader.getResourceBySelfClassLoader(resourceStr);
- return booleanAsStr(resourceURL != null);
- }
+ URL resourceURL = Loader.getResourceBySelfClassLoader(resourceStr);
+ return booleanAsStr(resourceURL != null);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/read/CyclicBufferAppender.java b/logback-core/src/main/java/ch/qos/logback/core/read/CyclicBufferAppender.java
index 7ddc50f..7dd1d75 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/read/CyclicBufferAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/read/CyclicBufferAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,56 +25,56 @@ import ch.qos.logback.core.helpers.CyclicBuffer;
*/
public class CyclicBufferAppender<E> extends AppenderBase<E> {
- CyclicBuffer<E> cb;
- int maxSize = 512;
+ CyclicBuffer<E> cb;
+ int maxSize = 512;
- public void start() {
- cb = new CyclicBuffer<E>(maxSize);
- super.start();
- }
+ public void start() {
+ cb = new CyclicBuffer<E>(maxSize);
+ super.start();
+ }
- public void stop() {
- cb = null;
- super.stop();
- }
+ public void stop() {
+ cb = null;
+ super.stop();
+ }
- @Override
- protected void append(E eventObject) {
- if (!isStarted()) {
- return;
- }
- cb.add(eventObject);
+ @Override
+ protected void append(E eventObject) {
+ if (!isStarted()) {
+ return;
}
+ cb.add(eventObject);
+ }
- public int getLength() {
- if (isStarted()) {
- return cb.length();
- } else {
- return 0;
- }
+ public int getLength() {
+ if (isStarted()) {
+ return cb.length();
+ } else {
+ return 0;
}
+ }
- public E get(int i) {
- if (isStarted()) {
- return cb.get(i);
- } else {
- return null;
- }
+ public E get(int i) {
+ if (isStarted()) {
+ return cb.get(i);
+ } else {
+ return null;
}
+ }
- public void reset() {
- cb.clear();
- }
+ public void reset() {
+ cb.clear();
+ }
- /**
- * Set the size of the cyclic buffer.
- */
- public int getMaxSize() {
- return maxSize;
- }
+ /**
+ * Set the size of the cyclic buffer.
+ */
+ public int getMaxSize() {
+ return maxSize;
+ }
- public void setMaxSize(int maxSize) {
- this.maxSize = maxSize;
- }
+ public void setMaxSize(int maxSize) {
+ this.maxSize = maxSize;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/read/ListAppender.java b/logback-core/src/main/java/ch/qos/logback/core/read/ListAppender.java
index bbf8f36..f934443 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/read/ListAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/read/ListAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,9 +20,9 @@ import ch.qos.logback.core.AppenderBase;
public class ListAppender<E> extends AppenderBase<E> {
- public List<E> list = new ArrayList<E>();
-
- protected void append(E e) {
- list.add(e);
- }
+ public List<E> list = new ArrayList<E>();
+
+ protected void append(E e) {
+ list.add(e);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/recovery/RecoveryCoordinator.java b/logback-core/src/main/java/ch/qos/logback/core/recovery/RecoveryCoordinator.java
index a8f965e..21341ac 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/recovery/RecoveryCoordinator.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/recovery/RecoveryCoordinator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,52 +15,41 @@ package ch.qos.logback.core.recovery;
public class RecoveryCoordinator {
- public final static long BACKOFF_COEFFICIENT_MIN = 20;
- public final static long BACKOFF_MULTIPLIER = 4;
- static long BACKOFF_COEFFICIENT_MAX = 327680; // BACKOFF_COEFFICIENT_MIN * 4^7
-
- private long backOffCoefficient = BACKOFF_COEFFICIENT_MIN;
-
- private static long UNSET = -1;
- // tests can set the time directly independently of system clock
- private long currentTime = UNSET;
- private long next;
-
- public RecoveryCoordinator() {
- next = getCurrentTime() + getBackoffCoefficient();
+ public final static long BACKOFF_COEFFICIENT_MIN = 20;
+ static long BACKOFF_COEFFICIENT_MAX = 327680; // BACKOFF_COEFFICIENT_MIN * 4^7
+
+ private long backOffCoefficient = BACKOFF_COEFFICIENT_MIN;
+
+ private static long UNSET = -1;
+ private long currentTime = UNSET;
+ long next = System.currentTimeMillis()+getBackoffCoefficient();
+
+ public boolean isTooSoon() {
+ long now = getCurrentTime();
+ if(now > next) {
+ next = now + getBackoffCoefficient();
+ return false;
+ } else {
+ return true;
}
-
- public RecoveryCoordinator(long currentTime) {
- this.currentTime = currentTime;
- next = getCurrentTime() + getBackoffCoefficient();
- }
-
- public boolean isTooSoon() {
- long now = getCurrentTime();
- if (now > next) {
- next = now + getBackoffCoefficient();
- return false;
- } else {
- return true;
- }
+ }
+
+ void setCurrentTime(long forcedTime) {
+ currentTime = forcedTime;
+ }
+
+ private long getCurrentTime() {
+ if(currentTime != UNSET) {
+ return currentTime;
}
-
- void setCurrentTime(long forcedTime) {
- currentTime = forcedTime;
- }
-
- private long getCurrentTime() {
- if (currentTime != UNSET) {
- return currentTime;
- }
- return System.currentTimeMillis();
- }
-
- private long getBackoffCoefficient() {
- long currentCoeff = backOffCoefficient;
- if (backOffCoefficient < BACKOFF_COEFFICIENT_MAX) {
- backOffCoefficient *= BACKOFF_MULTIPLIER;
- }
- return currentCoeff;
+ return System.currentTimeMillis();
+ }
+
+ private long getBackoffCoefficient() {
+ long currentCoeff = backOffCoefficient;
+ if(backOffCoefficient < BACKOFF_COEFFICIENT_MAX) {
+ backOffCoefficient*=4;
}
+ return currentCoeff;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientFileOutputStream.java b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientFileOutputStream.java
index 2c0d22b..bd958fb 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientFileOutputStream.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientFileOutputStream.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,42 +18,45 @@ import java.nio.channels.FileChannel;
public class ResilientFileOutputStream extends ResilientOutputStreamBase {
- private File file;
- private FileOutputStream fos;
+ private File file;
+ private FileOutputStream fos;
- public ResilientFileOutputStream(File file, boolean append) throws FileNotFoundException {
- this.file = file;
- fos = new FileOutputStream(file, append);
- this.os = new BufferedOutputStream(fos);
- this.presumedClean = true;
- }
-
- public FileChannel getChannel() {
- if (os == null) {
- return null;
- }
- return fos.getChannel();
- }
-
- public File getFile() {
- return file;
- }
-
- @Override
- String getDescription() {
- return "file [" + file + "]";
- }
- @Override
- OutputStream openNewOutputStream() throws IOException {
- // see LOGBACK-765
- fos = new FileOutputStream(file, true);
- return new BufferedOutputStream(fos);
- }
+ public ResilientFileOutputStream(File file, boolean append)
+ throws FileNotFoundException {
+ this.file = file;
+ fos = new FileOutputStream(file, append);
+ this.os = new BufferedOutputStream(fos);
+ this.presumedClean = true;
+ }
- @Override
- public String toString() {
- return "c.q.l.c.recovery.ResilientFileOutputStream@" + System.identityHashCode(this);
+ public FileChannel getChannel() {
+ if (os == null) {
+ return null;
}
+ return fos.getChannel();
+ }
+
+ public File getFile() {
+ return file;
+ }
+
+ @Override
+ String getDescription() {
+ return "file ["+file+"]";
+ }
+
+ @Override
+ OutputStream openNewOutputStream() throws IOException {
+ // see LOGBACK-765
+ fos = new FileOutputStream(file, true);
+ return new BufferedOutputStream(fos);
+ }
+
+ @Override
+ public String toString() {
+ return "c.q.l.c.recovery.ResilientFileOutputStream@"
+ + System.identityHashCode(this);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientOutputStreamBase.java b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientOutputStreamBase.java
index d3f18da..5d922a1 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientOutputStreamBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientOutputStreamBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,140 +24,145 @@ import ch.qos.logback.core.status.StatusManager;
abstract public class ResilientOutputStreamBase extends OutputStream {
- final static int STATUS_COUNT_LIMIT = 2 * 4;
+ final static int STATUS_COUNT_LIMIT = 2 * 4;
- private int noContextWarning = 0;
- private int statusCount = 0;
+ private int noContextWarning = 0;
+ private int statusCount = 0;
- private Context context;
- private RecoveryCoordinator recoveryCoordinator;
+ private Context context;
+ private RecoveryCoordinator recoveryCoordinator;
- protected OutputStream os;
- protected boolean presumedClean = true;
+ protected OutputStream os;
+ protected boolean presumedClean = true;
- private boolean isPresumedInError() {
- // existence of recoveryCoordinator indicates failed state
- return (recoveryCoordinator != null && !presumedClean);
- }
+ private boolean isPresumedInError() {
+ // existence of recoveryCoordinator indicates failed state
+ return (recoveryCoordinator != null && !presumedClean);
+ }
- public void write(byte b[], int off, int len) {
- if (isPresumedInError()) {
- if (!recoveryCoordinator.isTooSoon()) {
- attemptRecovery();
- }
- return; // return regardless of the success of the recovery attempt
- }
-
- try {
- os.write(b, off, len);
- postSuccessfulWrite();
- } catch (IOException e) {
- postIOFailure(e);
- }
+ public void write(byte b[], int off, int len) {
+ if (isPresumedInError()) {
+ if (!recoveryCoordinator.isTooSoon()) {
+ attemptRecovery();
+ }
+ return; // return regardless of the success of the recovery attempt
}
- @Override
- public void write(int b) {
- if (isPresumedInError()) {
- if (!recoveryCoordinator.isTooSoon()) {
- attemptRecovery();
- }
- return; // return regardless of the success of the recovery attempt
- }
- try {
- os.write(b);
- postSuccessfulWrite();
- } catch (IOException e) {
- postIOFailure(e);
- }
+ try {
+ os.write(b, off, len);
+ postSuccessfulWrite();
+ } catch (IOException e) {
+ postIOFailure(e);
}
-
- @Override
- public void flush() {
- if (os != null) {
- try {
- os.flush();
- postSuccessfulWrite();
- } catch (IOException e) {
- postIOFailure(e);
- }
- }
+ }
+
+ @Override
+ public void write(int b) {
+ if (isPresumedInError()) {
+ if (!recoveryCoordinator.isTooSoon()) {
+ attemptRecovery();
+ }
+ return; // return regardless of the success of the recovery attempt
+ }
+ try {
+ os.write(b);
+ postSuccessfulWrite();
+ } catch (IOException e) {
+ postIOFailure(e);
}
+ }
+
+ @Override
+ public void flush() {
+ if (os != null) {
+ try {
+ os.flush();
+ postSuccessfulWrite();
+ } catch (IOException e) {
+ postIOFailure(e);
+ }
+ }
+ }
- abstract String getDescription();
+ abstract String getDescription();
- abstract OutputStream openNewOutputStream() throws IOException;
+ abstract OutputStream openNewOutputStream() throws IOException;
- private void postSuccessfulWrite() {
- if (recoveryCoordinator != null) {
- recoveryCoordinator = null;
- statusCount = 0;
- addStatus(new InfoStatus("Recovered from IO failure on " + getDescription(), this));
- }
+ private void postSuccessfulWrite() {
+ if (recoveryCoordinator != null) {
+ recoveryCoordinator = null;
+ statusCount = 0;
+ addStatus(new InfoStatus("Recovered from IO failure on "
+ + getDescription(), this));
}
-
- public void postIOFailure(IOException e) {
- addStatusIfCountNotOverLimit(new ErrorStatus("IO failure while writing to " + getDescription(), this, e));
- presumedClean = false;
- if (recoveryCoordinator == null) {
- recoveryCoordinator = new RecoveryCoordinator();
- }
+ }
+
+ void postIOFailure(IOException e) {
+ addStatusIfCountNotOverLimit(new ErrorStatus("IO failure while writing to "
+ + getDescription(), this, e));
+ presumedClean = false;
+ if (recoveryCoordinator == null) {
+ recoveryCoordinator = new RecoveryCoordinator();
}
+ }
- @Override
- public void close() throws IOException {
- if (os != null) {
- os.close();
- }
+ @Override
+ public void close() throws IOException {
+ if (os != null) {
+ os.close();
}
+ }
- void attemptRecovery() {
- try {
- close();
- } catch (IOException e) {
- }
-
- addStatusIfCountNotOverLimit(new InfoStatus("Attempting to recover from IO failure on " + getDescription(), this));
-
- // subsequent writes must always be in append mode
- try {
- os = openNewOutputStream();
- presumedClean = true;
- } catch (IOException e) {
- addStatusIfCountNotOverLimit(new ErrorStatus("Failed to open " + getDescription(), this, e));
- }
+ void attemptRecovery() {
+ try {
+ close();
+ } catch (IOException e) {
}
- void addStatusIfCountNotOverLimit(Status s) {
- ++statusCount;
- if (statusCount < STATUS_COUNT_LIMIT) {
- addStatus(s);
- }
+ addStatusIfCountNotOverLimit(new InfoStatus(
+ "Attempting to recover from IO failure on " + getDescription(), this));
- if (statusCount == STATUS_COUNT_LIMIT) {
- addStatus(s);
- addStatus(new InfoStatus("Will supress future messages regarding " + getDescription(), this));
- }
+ // subsequent writes must always be in append mode
+ try {
+ os = openNewOutputStream();
+ presumedClean = true;
+ } catch (IOException e) {
+ addStatusIfCountNotOverLimit(new ErrorStatus("Failed to open "
+ + getDescription(), this, e));
}
+ }
- public void addStatus(Status status) {
- if (context == null) {
- if (noContextWarning++ == 0) {
- System.out.println("LOGBACK: No context given for " + this);
- }
- return;
- }
- StatusManager sm = context.getStatusManager();
- if (sm != null) {
- sm.add(status);
- }
+ void addStatusIfCountNotOverLimit(Status s) {
+ ++statusCount;
+ if (statusCount < STATUS_COUNT_LIMIT) {
+ addStatus(s);
}
- public Context getContext() {
- return context;
+ if (statusCount == STATUS_COUNT_LIMIT) {
+ addStatus(s);
+ addStatus(new InfoStatus("Will supress future messages regarding "
+ + getDescription(), this));
}
-
- public void setContext(Context context) {
- this.context = context;
+ }
+
+ public void addStatus(Status status) {
+ if (context == null) {
+ if (noContextWarning++ == 0) {
+ System.out.println("LOGBACK: No context given for " + this);
+ }
+ return;
+ }
+ StatusManager sm = context.getStatusManager();
+ if (sm != null) {
+ sm.add(status);
}
+ }
+
+ public Context getContext() {
+ return context;
+ }
+
+ public void setContext(Context context) {
+ this.context = context;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientSyslogOutputStream.java b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientSyslogOutputStream.java
index 21c4f88..ab20b71 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientSyslogOutputStream.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientSyslogOutputStream.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,29 +22,32 @@ import ch.qos.logback.core.net.SyslogOutputStream;
public class ResilientSyslogOutputStream extends ResilientOutputStreamBase {
- String syslogHost;
- int port;
-
- public ResilientSyslogOutputStream(String syslogHost, int port) throws UnknownHostException, SocketException {
- this.syslogHost = syslogHost;
- this.port = port;
- super.os = new SyslogOutputStream(syslogHost, port);
- this.presumedClean = true;
- }
-
- @Override
- String getDescription() {
- return "syslog [" + syslogHost + ":" + port + "]";
- }
-
- @Override
- OutputStream openNewOutputStream() throws IOException {
- return new SyslogOutputStream(syslogHost, port);
- }
-
- @Override
- public String toString() {
- return "c.q.l.c.recovery.ResilientSyslogOutputStream@" + System.identityHashCode(this);
- }
+
+ String syslogHost;
+ int port;
+
+ public ResilientSyslogOutputStream(String syslogHost, int port)
+ throws UnknownHostException, SocketException {
+ this.syslogHost = syslogHost;
+ this.port = port;
+ super.os = new SyslogOutputStream(syslogHost, port);
+ this.presumedClean = true;
+ }
+
+ @Override
+ String getDescription() {
+ return "syslog ["+syslogHost+":"+port+"]";
+ }
+
+ @Override
+ OutputStream openNewOutputStream() throws IOException {
+ return new SyslogOutputStream(syslogHost, port);
+ }
+
+ @Override
+ public String toString() {
+ return "c.q.l.c.recovery.ResilientSyslogOutputStream@"
+ + System.identityHashCode(this);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/DefaultTimeBasedFileNamingAndTriggeringPolicy.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/DefaultTimeBasedFileNamingAndTriggeringPolicy.java
index 61113bc..5114e1d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/DefaultTimeBasedFileNamingAndTriggeringPolicy.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/DefaultTimeBasedFileNamingAndTriggeringPolicy.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,7 +16,6 @@ package ch.qos.logback.core.rolling;
import java.io.File;
import java.util.Date;
-import ch.qos.logback.core.joran.spi.NoAutoStart;
import ch.qos.logback.core.rolling.helper.TimeBasedArchiveRemover;
/**
@@ -25,40 +24,34 @@ import ch.qos.logback.core.rolling.helper.TimeBasedArchiveRemover;
*
* @param <E>
*/
- at NoAutoStart
-public class DefaultTimeBasedFileNamingAndTriggeringPolicy<E> extends TimeBasedFileNamingAndTriggeringPolicyBase<E> {
+public class DefaultTimeBasedFileNamingAndTriggeringPolicy<E> extends
+ TimeBasedFileNamingAndTriggeringPolicyBase<E> {
- @Override
- public void start() {
- super.start();
- if (!super.isErrorFree())
- return;
- if(tbrp.fileNamePattern.hasIntegerTokenCOnverter()) {
- addError("Filename pattern ["+tbrp.fileNamePattern+"] contains an integer token converter, i.e. %i, INCOMPATIBLE with this configuration. Remove it.");
- return;
- }
-
- archiveRemover = new TimeBasedArchiveRemover(tbrp.fileNamePattern, rc);
- archiveRemover.setContext(context);
- started = true;
- }
+ @Override
+ public void start() {
+ super.start();
+ archiveRemover = new TimeBasedArchiveRemover(tbrp.fileNamePattern, rc);
+ archiveRemover.setContext(context);
+ started = true;
+ }
- public boolean isTriggeringEvent(File activeFile, final E event) {
- long time = getCurrentTime();
- if (time >= nextCheck) {
- Date dateOfElapsedPeriod = dateInCurrentPeriod;
- addInfo("Elapsed period: " + dateOfElapsedPeriod);
- elapsedPeriodsFileName = tbrp.fileNamePatternWithoutCompSuffix.convert(dateOfElapsedPeriod);
- setDateInCurrentPeriod(time);
- computeNextCheck();
- return true;
- } else {
- return false;
- }
+ public boolean isTriggeringEvent(File activeFile, final E event) {
+ long time = getCurrentTime();
+ if (time >= nextCheck) {
+ Date dateOfElapsedPeriod = dateInCurrentPeriod;
+ addInfo("Elapsed period: "+dateOfElapsedPeriod);
+ elapsedPeriodsFileName = tbrp.fileNamePatternWCS
+ .convert(dateOfElapsedPeriod);
+ setDateInCurrentPeriod(time);
+ computeNextCheck();
+ return true;
+ } else {
+ return false;
}
+ }
- @Override
- public String toString() {
- return "c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy";
- }
+ @Override
+ public String toString() {
+ return "c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy";
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java
index 2dce9f0..a395f1b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,8 +13,6 @@
*/
package ch.qos.logback.core.rolling;
-import static ch.qos.logback.core.CoreConstants.CODES_URL;
-
import java.io.File;
import java.util.Date;
@@ -31,153 +29,157 @@ import ch.qos.logback.core.rolling.helper.*;
* @author Ceki Gülcü
*/
public class FixedWindowRollingPolicy extends RollingPolicyBase {
- static final String FNP_NOT_SET = "The \"FileNamePattern\" property must be set before using FixedWindowRollingPolicy. ";
- static final String PRUDENT_MODE_UNSUPPORTED = "See also "+CODES_URL+"#tbr_fnp_prudent_unsupported";
- static final String SEE_PARENT_FN_NOT_SET = "Please refer to "+CODES_URL+"#fwrp_parentFileName_not_set";
- int maxIndex;
- int minIndex;
- RenameUtil util = new RenameUtil();
- Compressor compressor;
-
- public static final String ZIP_ENTRY_DATE_PATTERN = "yyyy-MM-dd_HHmm";
-
- /**
- * It's almost always a bad idea to have a large window size, say over 20.
- */
- private static int MAX_WINDOW_SIZE = 20;
-
- public FixedWindowRollingPolicy() {
- minIndex = 1;
- maxIndex = 7;
+ static final String FNP_NOT_SET = "The \"FileNamePattern\" property must be set before using FixedWindowRollingPolicy. ";
+ static final String PRUDENT_MODE_UNSUPPORTED = "See also http://logback.qos.ch/codes.html#tbr_fnp_prudent_unsupported";
+ static final String SEE_PARENT_FN_NOT_SET = "Please refer to http://logback.qos.ch/codes.html#fwrp_parentFileName_not_set";
+ int maxIndex;
+ int minIndex;
+ RenameUtil util = new RenameUtil();
+ Compressor compressor;
+
+ public static final String ZIP_ENTRY_DATE_PATTERN = "yyyy-MM-dd_HHmm";
+
+ /**
+ * It's almost always a bad idea to have a large window size, say over 20.
+ */
+ private static int MAX_WINDOW_SIZE = 20;
+
+ public FixedWindowRollingPolicy() {
+ minIndex = 1;
+ maxIndex = 7;
+ }
+
+ public void start() {
+ util.setContext(this.context);
+
+ if (fileNamePatternStr != null) {
+ fileNamePattern = new FileNamePattern(fileNamePatternStr, this.context);
+ determineCompressionMode();
+ } else {
+ addError(FNP_NOT_SET);
+ addError(CoreConstants.SEE_FNP_NOT_SET);
+ throw new IllegalStateException(FNP_NOT_SET + CoreConstants.SEE_FNP_NOT_SET);
}
- public void start() {
- util.setContext(this.context);
-
- if (fileNamePatternStr != null) {
- fileNamePattern = new FileNamePattern(fileNamePatternStr, this.context);
- determineCompressionMode();
- } else {
- addError(FNP_NOT_SET);
- addError(CoreConstants.SEE_FNP_NOT_SET);
- throw new IllegalStateException(FNP_NOT_SET + CoreConstants.SEE_FNP_NOT_SET);
- }
-
- if (isParentPrudent()) {
- addError("Prudent mode is not supported with FixedWindowRollingPolicy.");
- addError(PRUDENT_MODE_UNSUPPORTED);
- throw new IllegalStateException("Prudent mode is not supported.");
- }
-
- if (getParentsRawFileProperty() == null) {
- addError("The File name property must be set before using this rolling policy.");
- addError(SEE_PARENT_FN_NOT_SET);
- throw new IllegalStateException("The \"File\" option must be set.");
- }
-
- if (maxIndex < minIndex) {
- addWarn("MaxIndex (" + maxIndex + ") cannot be smaller than MinIndex (" + minIndex + ").");
- addWarn("Setting maxIndex to equal minIndex.");
- maxIndex = minIndex;
- }
-
- final int maxWindowSize = getMaxWindowSize();
- if ((maxIndex - minIndex) > maxWindowSize) {
- addWarn("Large window sizes are not allowed.");
- maxIndex = minIndex + maxWindowSize;
- addWarn("MaxIndex reduced to " + maxIndex);
- }
-
- IntegerTokenConverter itc = fileNamePattern.getIntegerTokenConverter();
-
- if (itc == null) {
- throw new IllegalStateException("FileNamePattern [" + fileNamePattern.getPattern() + "] does not contain a valid IntegerToken");
- }
-
- if (compressionMode == CompressionMode.ZIP) {
- String zipEntryFileNamePatternStr = transformFileNamePatternFromInt2Date(fileNamePatternStr);
- zipEntryFileNamePattern = new FileNamePattern(zipEntryFileNamePatternStr, context);
- }
- compressor = new Compressor(compressionMode);
- compressor.setContext(this.context);
- super.start();
- }
-
- /**
- * Subclasses can override this method to increase the max window size, if required. This is to
- * address LOGBACK-266.
- * @return
- */
- protected int getMaxWindowSize() {
- return MAX_WINDOW_SIZE;
+ if(isParentPrudent()) {
+ addError("Prudent mode is not supported with FixedWindowRollingPolicy.");
+ addError(PRUDENT_MODE_UNSUPPORTED);
+ throw new IllegalStateException("Prudent mode is not supported.");
}
-
- private String transformFileNamePatternFromInt2Date(String fileNamePatternStr) {
- String slashified = FileFilterUtil.slashify(fileNamePatternStr);
- String stemOfFileNamePattern = FileFilterUtil.afterLastSlash(slashified);
- return stemOfFileNamePattern.replace("%i", "%d{" + ZIP_ENTRY_DATE_PATTERN + "}");
+
+ if (getParentsRawFileProperty() == null) {
+ addError("The File name property must be set before using this rolling policy.");
+ addError(SEE_PARENT_FN_NOT_SET);
+ throw new IllegalStateException("The \"File\" option must be set.");
}
- public void rollover() throws RolloverFailure {
-
- // Inside this method it is guaranteed that the hereto active log file is
- // closed.
- // If maxIndex <= 0, then there is no file renaming to be done.
- if (maxIndex >= 0) {
- // Delete the oldest file, to keep Windows happy.
- File file = new File(fileNamePattern.convertInt(maxIndex));
-
- if (file.exists()) {
- file.delete();
- }
-
- // Map {(maxIndex - 1), ..., minIndex} to {maxIndex, ..., minIndex+1}
- for (int i = maxIndex - 1; i >= minIndex; i--) {
- String toRenameStr = fileNamePattern.convertInt(i);
- File toRename = new File(toRenameStr);
- // no point in trying to rename an inexistent file
- if (toRename.exists()) {
- util.rename(toRenameStr, fileNamePattern.convertInt(i + 1));
- } else {
- addInfo("Skipping roll-over for inexistent file " + toRenameStr);
- }
- }
-
- // move active file name to min
- switch (compressionMode) {
- case NONE:
- util.rename(getActiveFileName(), fileNamePattern.convertInt(minIndex));
- break;
- case GZ:
- compressor.compress(getActiveFileName(), fileNamePattern.convertInt(minIndex), null);
- break;
- case ZIP:
- compressor.compress(getActiveFileName(), fileNamePattern.convertInt(minIndex), zipEntryFileNamePattern.convert(new Date()));
- break;
- }
- }
+ if (maxIndex < minIndex) {
+ addWarn("MaxIndex (" + maxIndex + ") cannot be smaller than MinIndex ("
+ + minIndex + ").");
+ addWarn("Setting maxIndex to equal minIndex.");
+ maxIndex = minIndex;
}
- /**
- * Return the value of the parent's RawFile property.
- */
- public String getActiveFileName() {
- return getParentsRawFileProperty();
+ final int maxWindowSize = getMaxWindowSize();
+ if ((maxIndex - minIndex) > maxWindowSize) {
+ addWarn("Large window sizes are not allowed.");
+ maxIndex = minIndex + maxWindowSize;
+ addWarn("MaxIndex reduced to " + maxIndex);
}
- public int getMaxIndex() {
- return maxIndex;
- }
+ IntegerTokenConverter itc = fileNamePattern.getIntegerTokenConverter();
- public int getMinIndex() {
- return minIndex;
+ if (itc == null) {
+ throw new IllegalStateException("FileNamePattern ["
+ + fileNamePattern.getPattern()
+ + "] does not contain a valid IntegerToken");
}
- public void setMaxIndex(int maxIndex) {
- this.maxIndex = maxIndex;
+ if(compressionMode == CompressionMode.ZIP) {
+ String zipEntryFileNamePatternStr = transformFileNamePatternFromInt2Date(fileNamePatternStr);
+ zipEntryFileNamePattern = new FileNamePattern(zipEntryFileNamePatternStr, context);
}
-
- public void setMinIndex(int minIndex) {
- this.minIndex = minIndex;
+ compressor = new Compressor(compressionMode);
+ compressor.setContext(this.context);
+ super.start();
+ }
+
+ /**
+ * Subclasses can override this method to increase the max window size, if required. This is to
+ * address LOGBACK-266.
+ * @return
+ */
+ protected int getMaxWindowSize() {
+ return MAX_WINDOW_SIZE;
+ }
+
+ private String transformFileNamePatternFromInt2Date(String fileNamePatternStr) {
+ String slashified = FileFilterUtil.slashify(fileNamePatternStr);
+ String stemOfFileNamePattern = FileFilterUtil.afterLastSlash(slashified);
+ return stemOfFileNamePattern.replace("%i", "%d{"+ZIP_ENTRY_DATE_PATTERN+"}");
+ }
+
+ public void rollover() throws RolloverFailure {
+
+ // Inside this method it is guaranteed that the hereto active log file is
+ // closed.
+ // If maxIndex <= 0, then there is no file renaming to be done.
+ if (maxIndex >= 0) {
+ // Delete the oldest file, to keep Windows happy.
+ File file = new File(fileNamePattern.convertInt(maxIndex));
+
+ if (file.exists()) {
+ file.delete();
+ }
+
+ // Map {(maxIndex - 1), ..., minIndex} to {maxIndex, ..., minIndex+1}
+ for (int i = maxIndex - 1; i >= minIndex; i--) {
+ String toRenameStr = fileNamePattern.convertInt(i);
+ File toRename = new File(toRenameStr);
+ // no point in trying to rename an inexistent file
+ if (toRename.exists()) {
+ util.rename(toRenameStr, fileNamePattern.convertInt(i + 1));
+ } else {
+ addInfo("Skipping roll-over for inexistent file " + toRenameStr);
+ }
+ }
+
+ // move active file name to min
+ switch (compressionMode) {
+ case NONE:
+ util.rename(getActiveFileName(), fileNamePattern
+ .convertInt(minIndex));
+ break;
+ case GZ:
+ compressor.compress(getActiveFileName(), fileNamePattern.convertInt(minIndex), null);
+ break;
+ case ZIP:
+ compressor.compress(getActiveFileName(), fileNamePattern.convertInt(minIndex), zipEntryFileNamePattern.convert(new Date()));
+ break;
+ }
}
+ }
+
+ /**
+ * Return the value of the parent's RawFile property.
+ */
+ public String getActiveFileName() {
+ return getParentsRawFileProperty();
+ }
+
+ public int getMaxIndex() {
+ return maxIndex;
+ }
+
+ public int getMinIndex() {
+ return minIndex;
+ }
+
+ public void setMaxIndex(int maxIndex) {
+ this.maxIndex = maxIndex;
+ }
+
+ public void setMinIndex(int minIndex) {
+ this.minIndex = minIndex;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java
index 1d6dc43..0b1e76c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,19 +13,14 @@
*/
package ch.qos.logback.core.rolling;
-import static ch.qos.logback.core.CoreConstants.CODES_URL;
-import static ch.qos.logback.core.CoreConstants.MORE_INFO_PREFIX;
+import ch.qos.logback.core.FileAppender;
+import ch.qos.logback.core.rolling.helper.CompressionMode;
+import ch.qos.logback.core.rolling.helper.FileNamePattern;
import java.io.File;
import java.io.IOException;
-import java.util.Map;
-import java.util.Map.Entry;
-import ch.qos.logback.core.CoreConstants;
-import ch.qos.logback.core.FileAppender;
-import ch.qos.logback.core.rolling.helper.CompressionMode;
-import ch.qos.logback.core.rolling.helper.FileNamePattern;
-import ch.qos.logback.core.util.ContextUtil;
+import static ch.qos.logback.core.CoreConstants.CODES_URL;
/**
* <code>RollingFileAppender</code> extends {@link FileAppender} to backup the
@@ -39,230 +34,182 @@ import ch.qos.logback.core.util.ContextUtil;
* @author Ceki Gülcü
*/
public class RollingFileAppender<E> extends FileAppender<E> {
- File currentlyActiveFile;
- TriggeringPolicy<E> triggeringPolicy;
- RollingPolicy rollingPolicy;
-
- static private String RFA_NO_TP_URL = CODES_URL + "#rfa_no_tp";
- static private String RFA_NO_RP_URL = CODES_URL + "#rfa_no_rp";
- static private String COLLISION_URL = CODES_URL + "#rfa_collision";
- static private String RFA_LATE_FILE_URL = CODES_URL + "#rfa_file_after";
-
- public void start() {
- if (triggeringPolicy == null) {
- addWarn("No TriggeringPolicy was set for the RollingFileAppender named " + getName());
- addWarn(MORE_INFO_PREFIX + RFA_NO_TP_URL);
- return;
- }
- if (!triggeringPolicy.isStarted()) {
- addWarn("TriggeringPolicy has not started. RollingFileAppender will not start");
- return;
- }
-
- if (checkForCollisionsInPreviousRollingFileAppenders()) {
- addError("Collisions detected with FileAppender/RollingAppender instances defined earlier. Aborting.");
- addError(MORE_INFO_PREFIX + COLLISION_WITH_EARLIER_APPENDER_URL);
- return;
- }
-
- // we don't want to void existing log files
- if (!append) {
- addWarn("Append mode is mandatory for RollingFileAppender. Defaulting to append=true.");
- append = true;
- }
-
- if (rollingPolicy == null) {
- addError("No RollingPolicy was set for the RollingFileAppender named " + getName());
- addError(MORE_INFO_PREFIX + RFA_NO_RP_URL);
- return;
- }
-
- // sanity check for http://jira.qos.ch/browse/LOGBACK-796
- if (checkForFileAndPatternCollisions()) {
- addError("File property collides with fileNamePattern. Aborting.");
- addError(MORE_INFO_PREFIX + COLLISION_URL);
- return;
- }
-
- if (isPrudent()) {
- if (rawFileProperty() != null) {
- addWarn("Setting \"File\" property to null on account of prudent mode");
- setFile(null);
- }
- if (rollingPolicy.getCompressionMode() != CompressionMode.NONE) {
- addError("Compression is not supported in prudent mode. Aborting");
- return;
- }
- }
-
- currentlyActiveFile = new File(getFile());
- addInfo("Active log file name: " + getFile());
- super.start();
+ File currentlyActiveFile;
+ TriggeringPolicy<E> triggeringPolicy;
+ RollingPolicy rollingPolicy;
+
+ static private String RFA_NO_TP_URL = CODES_URL + "#rfa_no_tp";
+ static private String RFA_NO_RP_URL = CODES_URL + "#rfa_no_rp";
+ static private String COLLISION_URL = CODES_URL + "#rfa_collision";
+
+ public void start() {
+ if (triggeringPolicy == null) {
+ addWarn("No TriggeringPolicy was set for the RollingFileAppender named "
+ + getName());
+ addWarn("For more information, please visit " + RFA_NO_TP_URL);
+ return;
}
- private boolean checkForFileAndPatternCollisions() {
- if (triggeringPolicy instanceof RollingPolicyBase) {
- final RollingPolicyBase base = (RollingPolicyBase) triggeringPolicy;
- final FileNamePattern fileNamePattern = base.fileNamePattern;
- // no use checking if either fileName or fileNamePattern are null
- if (fileNamePattern != null && fileName != null) {
- String regex = fileNamePattern.toRegex();
- return fileName.matches(regex);
- }
- }
- return false;
+ // we don't want to void existing log files
+ if (!append) {
+ addWarn("Append mode is mandatory for RollingFileAppender");
+ append = true;
}
- private boolean checkForCollisionsInPreviousRollingFileAppenders() {
- boolean collisionResult = false;
- if (triggeringPolicy instanceof RollingPolicyBase) {
- final RollingPolicyBase base = (RollingPolicyBase) triggeringPolicy;
- final FileNamePattern fileNamePattern = base.fileNamePattern;
- boolean collisionsDetected = innerCheckForFileNamePatternCollisionInPreviousRFA(fileNamePattern);
- if (collisionsDetected)
- collisionResult = true;
- }
- return collisionResult;
+ if (rollingPolicy == null) {
+ addError("No RollingPolicy was set for the RollingFileAppender named "
+ + getName());
+ addError("For more information, please visit " + RFA_NO_RP_URL);
+ return;
}
- private boolean innerCheckForFileNamePatternCollisionInPreviousRFA(FileNamePattern fileNamePattern) {
- boolean collisionsDetected = false;
- @SuppressWarnings("unchecked")
- Map<String, FileNamePattern> map = (Map<String, FileNamePattern>) context.getObject(CoreConstants.RFA_FILENAME_PATTERN_COLLISION_MAP);
- if (map == null) {
- return collisionsDetected;
- }
- for (Entry<String, FileNamePattern> entry : map.entrySet()) {
- if (fileNamePattern.equals(entry.getValue())) {
- addErrorForCollision("FileNamePattern", entry.getValue().toString(), entry.getKey());
- collisionsDetected = true;
- }
- }
- if (name != null) {
- map.put(getName(), fileNamePattern);
- }
- return collisionsDetected;
+ // sanity check for http://jira.qos.ch/browse/LOGBACK-796
+ if (fileAndPatternCollide()) {
+ addError("File property collides with fileNamePattern. Aborting.");
+ addError("For more information, please visit " + COLLISION_URL);
+ return;
}
- @Override
- public void stop() {
- super.stop();
-
- if (rollingPolicy != null)
- rollingPolicy.stop();
- if (triggeringPolicy != null)
- triggeringPolicy.stop();
-
- Map<String, FileNamePattern> map = ContextUtil.getFilenamePatternCollisionMap(context);
- if (map != null && getName() != null)
- map.remove(getName());
-
+ if (isPrudent()) {
+ if (rawFileProperty() != null) {
+ addWarn("Setting \"File\" property to null on account of prudent mode");
+ setFile(null);
+ }
+ if (rollingPolicy.getCompressionMode() != CompressionMode.NONE) {
+ addError("Compression is not supported in prudent mode. Aborting");
+ return;
+ }
}
- @Override
- public void setFile(String file) {
- // http://jira.qos.ch/browse/LBCORE-94
- // allow setting the file name to null if mandated by prudent mode
- if (file != null && ((triggeringPolicy != null) || (rollingPolicy != null))) {
- addError("File property must be set before any triggeringPolicy or rollingPolicy properties");
- addError(MORE_INFO_PREFIX + RFA_LATE_FILE_URL);
- }
- super.setFile(file);
+ currentlyActiveFile = new File(getFile());
+ addInfo("Active log file name: " + getFile());
+ super.start();
+ }
+
+ private boolean fileAndPatternCollide() {
+ if (triggeringPolicy instanceof RollingPolicyBase) {
+ final RollingPolicyBase base = (RollingPolicyBase) triggeringPolicy;
+ final FileNamePattern fileNamePattern = base.fileNamePattern;
+ // no use checking if either fileName or fileNamePattern are null
+ if (fileNamePattern != null && fileName != null) {
+ String regex = fileNamePattern.toRegex();
+ return fileName.matches(regex);
+ }
}
-
- @Override
- public String getFile() {
- return rollingPolicy.getActiveFileName();
+ return false;
+ }
+
+ @Override
+ public void stop() {
+ if (rollingPolicy != null) rollingPolicy.stop();
+ if (triggeringPolicy != null) triggeringPolicy.stop();
+ super.stop();
+ }
+
+ @Override
+ public void setFile(String file) {
+ // http://jira.qos.ch/browse/LBCORE-94
+ // allow setting the file name to null if mandated by prudent mode
+ if (file != null && ((triggeringPolicy != null) || (rollingPolicy != null))) {
+ addError("File property must be set before any triggeringPolicy or rollingPolicy properties");
+ addError("Visit " + CODES_URL + "#rfa_file_after for more information");
}
-
- /**
- * Implemented by delegating most of the rollover work to a rolling policy.
- */
- public void rollover() {
- lock.lock();
- try {
- // Note: This method needs to be synchronized because it needs exclusive
- // access while it closes and then re-opens the target file.
- //
- // make sure to close the hereto active log file! Renaming under windows
- // does not work for open files.
- this.closeOutputStream();
- attemptRollover();
- attemptOpenFile();
- } finally {
- lock.unlock();
- }
+ super.setFile(file);
+ }
+
+ @Override
+ public String getFile() {
+ return rollingPolicy.getActiveFileName();
+ }
+
+ /**
+ * Implemented by delegating most of the rollover work to a rolling policy.
+ */
+ public void rollover() {
+ lock.lock();
+ try {
+ // Note: This method needs to be synchronized because it needs exclusive
+ // access while it closes and then re-opens the target file.
+ //
+ // make sure to close the hereto active log file! Renaming under windows
+ // does not work for open files.
+ this.closeOutputStream();
+ attemptRollover();
+ attemptOpenFile();
+ } finally {
+ lock.unlock();
}
+ }
private void attemptOpenFile() {
- try {
- // update the currentlyActiveFile LOGBACK-64
- currentlyActiveFile = new File(rollingPolicy.getActiveFileName());
-
- // This will also close the file. This is OK since multiple close operations are safe.
- this.openFile(rollingPolicy.getActiveFileName());
- } catch (IOException e) {
- addError("setFile(" + fileName + ", false) call failed.", e);
- }
+ try {
+ // update the currentlyActiveFile LOGBACK-64
+ currentlyActiveFile = new File(rollingPolicy.getActiveFileName());
+
+ // This will also close the file. This is OK since multiple close operations are safe.
+ this.openFile(rollingPolicy.getActiveFileName());
+ } catch (IOException e) {
+ addError("setFile(" + fileName + ", false) call failed.", e);
+ }
}
private void attemptRollover() {
- try {
- rollingPolicy.rollover();
- } catch (RolloverFailure rf) {
- addWarn("RolloverFailure occurred. Deferring roll-over.");
- // we failed to roll-over, let us not truncate and risk data loss
- this.append = true;
- }
+ try {
+ rollingPolicy.rollover();
+ } catch (RolloverFailure rf) {
+ addWarn("RolloverFailure occurred. Deferring roll-over.");
+ // we failed to roll-over, let us not truncate and risk data loss
+ this.append = true;
+ }
}
/**
- * This method differentiates RollingFileAppender from its super class.
- */
- @Override
- protected void subAppend(E event) {
- // The roll-over check must precede actual writing. This is the
- // only correct behavior for time driven triggers.
-
- // We need to synchronize on triggeringPolicy so that only one rollover
- // occurs at a time
- synchronized (triggeringPolicy) {
- if (triggeringPolicy.isTriggeringEvent(currentlyActiveFile, event)) {
- rollover();
- }
- }
-
- super.subAppend(event);
- }
-
- public RollingPolicy getRollingPolicy() {
- return rollingPolicy;
+ * This method differentiates RollingFileAppender from its super class.
+ */
+ @Override
+ protected void subAppend(E event) {
+ // The roll-over check must precede actual writing. This is the
+ // only correct behavior for time driven triggers.
+
+ // We need to synchronize on triggeringPolicy so that only one rollover
+ // occurs at a time
+ synchronized (triggeringPolicy) {
+ if (triggeringPolicy.isTriggeringEvent(currentlyActiveFile, event)) {
+ rollover();
+ }
}
- public TriggeringPolicy<E> getTriggeringPolicy() {
- return triggeringPolicy;
+ super.subAppend(event);
+ }
+
+ public RollingPolicy getRollingPolicy() {
+ return rollingPolicy;
+ }
+
+ public TriggeringPolicy<E> getTriggeringPolicy() {
+ return triggeringPolicy;
+ }
+
+ /**
+ * Sets the rolling policy. In case the 'policy' argument also implements
+ * {@link TriggeringPolicy}, then the triggering policy for this appender is
+ * automatically set to be the policy argument.
+ *
+ * @param policy
+ */
+ @SuppressWarnings("unchecked")
+ public void setRollingPolicy(RollingPolicy policy) {
+ rollingPolicy = policy;
+ if (rollingPolicy instanceof TriggeringPolicy) {
+ triggeringPolicy = (TriggeringPolicy<E>) policy;
}
- /**
- * Sets the rolling policy. In case the 'policy' argument also implements
- * {@link TriggeringPolicy}, then the triggering policy for this appender is
- * automatically set to be the policy argument.
- *
- * @param policy
- */
- @SuppressWarnings("unchecked")
- public void setRollingPolicy(RollingPolicy policy) {
- rollingPolicy = policy;
- if (rollingPolicy instanceof TriggeringPolicy) {
- triggeringPolicy = (TriggeringPolicy<E>) policy;
- }
-
- }
+ }
- public void setTriggeringPolicy(TriggeringPolicy<E> policy) {
- triggeringPolicy = policy;
- if (policy instanceof RollingPolicy) {
- rollingPolicy = (RollingPolicy) policy;
- }
+ public void setTriggeringPolicy(TriggeringPolicy<E> policy) {
+ triggeringPolicy = policy;
+ if (policy instanceof RollingPolicy) {
+ rollingPolicy = (RollingPolicy) policy;
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicy.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicy.java
index 21d66be..49dce02 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicy.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicy.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,41 +27,41 @@ import ch.qos.logback.core.spi.LifeCycle;
*/
public interface RollingPolicy extends LifeCycle {
- /**
- * Rolls over log files according to implementation policy.
- *
- * <p>This method is invoked by {@link RollingFileAppender}, usually at the
- * behest of its {@link TriggeringPolicy}.
- *
- * @throws RolloverFailure
- * Thrown if the rollover operation fails for any reason.
- */
- void rollover() throws RolloverFailure;
+ /**
+ * Rolls over log files according to implementation policy.
+ *
+ * <p>This method is invoked by {@link RollingFileAppender}, usually at the
+ * behest of its {@link TriggeringPolicy}.
+ *
+ * @throws RolloverFailure
+ * Thrown if the rollover operation fails for any reason.
+ */
+ void rollover() throws RolloverFailure;
- /**
- * Get the name of the active log file.
- *
- * <p>With implementations such as {@link TimeBasedRollingPolicy}, this
- * method returns a new file name, where the actual output will be sent.
- *
- * <p>On other implementations, this method might return the FileAppender's
- * file property.
- */
- String getActiveFileName();
+ /**
+ * Get the name of the active log file.
+ *
+ * <p>With implementations such as {@link TimeBasedRollingPolicy}, this
+ * method returns a new file name, where the actual output will be sent.
+ *
+ * <p>On other implementations, this method might return the FileAppender's
+ * file property.
+ */
+ String getActiveFileName();
- /**
- * The compression mode for this policy.
- *
- * @return
- */
- CompressionMode getCompressionMode();
+ /**
+ * The compression mode for this policy.
+ *
+ * @return
+ */
+ CompressionMode getCompressionMode();
+
+ /**
+ * This method allows RollingPolicy implementations to be aware of their
+ * containing appender.
+ *
+ * @param appender
+ */
- /**
- * This method allows RollingPolicy implementations to be aware of their
- * containing appender.
- *
- * @param appender
- */
-
- void setParent(FileAppender<?> appender);
+ void setParent(FileAppender appender);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicyBase.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicyBase.java
index e2f9ac2..0f2ddd6 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicyBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicyBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,72 +24,73 @@ import ch.qos.logback.core.spi.ContextAwareBase;
*
* @author Ceki Gülcü
*/
-public abstract class RollingPolicyBase extends ContextAwareBase implements RollingPolicy {
- protected CompressionMode compressionMode = CompressionMode.NONE;
+public abstract class RollingPolicyBase extends ContextAwareBase implements
+ RollingPolicy {
+ protected CompressionMode compressionMode = CompressionMode.NONE;
- FileNamePattern fileNamePattern;
- // fileNamePatternStr is always slashified, see setter
- protected String fileNamePatternStr;
+ FileNamePattern fileNamePattern;
+ // fileNamePatternStr is always slashified, see setter
+ protected String fileNamePatternStr;
- private FileAppender<?> parent;
+ private FileAppender parent;
- // use to name files within zip file, i.e. the zipEntry
- FileNamePattern zipEntryFileNamePattern;
- private boolean started;
+ // use to name files within zip file, i.e. the zipEntry
+ FileNamePattern zipEntryFileNamePattern;
+ private boolean started;
- /**
- * Given the FileNamePattern string, this method determines the compression
- * mode depending on last letters of the fileNamePatternStr. Patterns ending
- * with .gz imply GZIP compression, endings with '.zip' imply ZIP compression.
- * Otherwise and by default, there is no compression.
- *
- */
- protected void determineCompressionMode() {
- if (fileNamePatternStr.endsWith(".gz")) {
- addInfo("Will use gz compression");
- compressionMode = CompressionMode.GZ;
- } else if (fileNamePatternStr.endsWith(".zip")) {
- addInfo("Will use zip compression");
- compressionMode = CompressionMode.ZIP;
- } else {
- addInfo("No compression will be used");
- compressionMode = CompressionMode.NONE;
- }
+ /**
+ * Given the FileNamePattern string, this method determines the compression
+ * mode depending on last letters of the fileNamePatternStr. Patterns ending
+ * with .gz imply GZIP compression, endings with '.zip' imply ZIP compression.
+ * Otherwise and by default, there is no compression.
+ *
+ */
+ protected void determineCompressionMode() {
+ if (fileNamePatternStr.endsWith(".gz")) {
+ addInfo("Will use gz compression");
+ compressionMode = CompressionMode.GZ;
+ } else if (fileNamePatternStr.endsWith(".zip")) {
+ addInfo("Will use zip compression");
+ compressionMode = CompressionMode.ZIP;
+ } else {
+ addInfo("No compression will be used");
+ compressionMode = CompressionMode.NONE;
}
+ }
- public void setFileNamePattern(String fnp) {
- fileNamePatternStr = fnp;
- }
+ public void setFileNamePattern(String fnp) {
+ fileNamePatternStr = fnp;
+ }
- public String getFileNamePattern() {
- return fileNamePatternStr;
- }
+ public String getFileNamePattern() {
+ return fileNamePatternStr;
+ }
- public CompressionMode getCompressionMode() {
- return compressionMode;
- }
+ public CompressionMode getCompressionMode() {
+ return compressionMode;
+ }
- public boolean isStarted() {
- return started;
- }
+ public boolean isStarted() {
+ return started;
+ }
- public void start() {
- started = true;
- }
+ public void start() {
+ started = true;
+ }
- public void stop() {
- started = false;
- }
+ public void stop() {
+ started = false;
+ }
- public void setParent(FileAppender<?> appender) {
- this.parent = appender;
- }
+ public void setParent(FileAppender appender) {
+ this.parent = appender;
+ }
- public boolean isParentPrudent() {
- return parent.isPrudent();
- }
+ public boolean isParentPrudent() {
+ return parent.isPrudent();
+ }
- public String getParentsRawFileProperty() {
- return parent.rawFileProperty();
- }
+ public String getParentsRawFileProperty() {
+ return parent.rawFileProperty();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/RolloverFailure.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/RolloverFailure.java
index 659a55a..a88c548 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/RolloverFailure.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/RolloverFailure.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.rolling;
+
import ch.qos.logback.core.LogbackException;
/**
@@ -22,13 +23,13 @@ import ch.qos.logback.core.LogbackException;
*/
public class RolloverFailure extends LogbackException {
- private static final long serialVersionUID = -4407533730831239458L;
+ private static final long serialVersionUID = -4407533730831239458L;
- public RolloverFailure(String msg) {
- super(msg);
- }
+ public RolloverFailure(String msg) {
+ super(msg);
+ }
- public RolloverFailure(String message, Throwable cause) {
- super(message, cause);
- }
+ public RolloverFailure(String message, Throwable cause) {
+ super(message, cause);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP.java
index 933273a..76bf92d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,171 +13,126 @@
*/
package ch.qos.logback.core.rolling;
-import static ch.qos.logback.core.CoreConstants.MANUAL_URL_PREFIX;
-
import java.io.File;
import java.util.Date;
-import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.joran.spi.NoAutoStart;
import ch.qos.logback.core.rolling.helper.ArchiveRemover;
import ch.qos.logback.core.rolling.helper.CompressionMode;
import ch.qos.logback.core.rolling.helper.FileFilterUtil;
import ch.qos.logback.core.rolling.helper.SizeAndTimeBasedArchiveRemover;
import ch.qos.logback.core.util.FileSize;
-import ch.qos.logback.core.util.DefaultInvocationGate;
-import ch.qos.logback.core.util.InvocationGate;
@NoAutoStart
-public class SizeAndTimeBasedFNATP<E> extends TimeBasedFileNamingAndTriggeringPolicyBase<E> {
+public class SizeAndTimeBasedFNATP<E> extends
+ TimeBasedFileNamingAndTriggeringPolicyBase<E> {
- enum Usage {EMBEDDED, DIRECT};
+ int currentPeriodsCounter = 0;
+ FileSize maxFileSize;
+ String maxFileSizeAsString;
-
- int currentPeriodsCounter = 0;
- FileSize maxFileSize;
- // String maxFileSizeAsString;
+ @Override
+ public void start() {
+ // we depend on certain fields having been initialized
+ // in super.start()
+ super.start();
- long nextSizeCheck = 0;
- static String MISSING_INT_TOKEN = "Missing integer token, that is %i, in FileNamePattern [";
- static String MISSING_DATE_TOKEN = "Missing date token, that is %d, in FileNamePattern [";
+ archiveRemover = createArchiveRemover();
+ archiveRemover.setContext(context);
- private final Usage usage;
-
- public SizeAndTimeBasedFNATP() {
- this(Usage.DIRECT);
- }
-
- public SizeAndTimeBasedFNATP(Usage usage) {
- this.usage = usage;
- }
-
- @Override
- public void start() {
- // we depend on certain fields having been initialized in super class
- super.start();
-
- if(usage == Usage.DIRECT) {
- addWarn(CoreConstants.SIZE_AND_TIME_BASED_FNATP_IS_DEPRECATED);
- addWarn("For more information see "+MANUAL_URL_PREFIX+"appenders.html#SizeAndTimeBasedRollingPolicy");
- }
-
- if (!super.isErrorFree())
- return;
-
-
- if (maxFileSize == null) {
- addError("maxFileSize property is mandatory.");
- withErrors();
- }
-
- if (!validateDateAndIntegerTokens()) {
- withErrors();
- return;
- }
-
- archiveRemover = createArchiveRemover();
- archiveRemover.setContext(context);
-
- // we need to get the correct value of currentPeriodsCounter.
- // usually the value is 0, unless the appender or the application
- // is stopped and restarted within the same period
- String regex = tbrp.fileNamePattern.toRegexForFixedDate(dateInCurrentPeriod);
- String stemRegex = FileFilterUtil.afterLastSlash(regex);
-
- computeCurrentPeriodsHighestCounterValue(stemRegex);
-
- if (isErrorFree()) {
- started = true;
- }
- }
+ // we need to get the correct value of currentPeriodsCounter.
+ // usually the value is 0, unless the appender or the application
+ // is stopped and restarted within the same period
+ String regex = tbrp.fileNamePattern.toRegexForFixedDate(dateInCurrentPeriod);
+ String stemRegex = FileFilterUtil.afterLastSlash(regex);
- private boolean validateDateAndIntegerTokens() {
- boolean inError = false;
- if (tbrp.fileNamePattern.getIntegerTokenConverter() == null) {
- inError = true;
- addError(MISSING_INT_TOKEN + tbrp.fileNamePatternStr + "]");
- addError(CoreConstants.SEE_MISSING_INTEGER_TOKEN);
- }
- if (tbrp.fileNamePattern.getPrimaryDateTokenConverter() == null) {
- inError = true;
- addError(MISSING_DATE_TOKEN + tbrp.fileNamePatternStr + "]");
- }
-
- return !inError;
- }
- protected ArchiveRemover createArchiveRemover() {
- return new SizeAndTimeBasedArchiveRemover(tbrp.fileNamePattern, rc);
- }
+ computeCurrentPeriodsHighestCounterValue(stemRegex);
+
+ started = true;
+ }
- void computeCurrentPeriodsHighestCounterValue(final String stemRegex) {
- File file = new File(getCurrentPeriodsFileNameWithoutCompressionSuffix());
- File parentDir = file.getParentFile();
+ protected ArchiveRemover createArchiveRemover() {
+ return new SizeAndTimeBasedArchiveRemover(tbrp.fileNamePattern, rc);
+ }
- File[] matchingFileArray = FileFilterUtil.filesInFolderMatchingStemRegex(parentDir, stemRegex);
+ void computeCurrentPeriodsHighestCounterValue(final String stemRegex) {
+ File file = new File(getCurrentPeriodsFileNameWithoutCompressionSuffix());
+ File parentDir = file.getParentFile();
- if (matchingFileArray == null || matchingFileArray.length == 0) {
- currentPeriodsCounter = 0;
- return;
- }
- currentPeriodsCounter = FileFilterUtil.findHighestCounter(matchingFileArray, stemRegex);
+ File[] matchingFileArray = FileFilterUtil
+ .filesInFolderMatchingStemRegex(parentDir, stemRegex);
- // if parent raw file property is not null, then the next
- // counter is max found counter+1
- if (tbrp.getParentsRawFileProperty() != null || (tbrp.compressionMode != CompressionMode.NONE)) {
- // TODO test me
- currentPeriodsCounter++;
- }
+ if (matchingFileArray == null || matchingFileArray.length == 0) {
+ currentPeriodsCounter = 0;
+ return;
}
+ currentPeriodsCounter = FileFilterUtil.findHighestCounter(matchingFileArray, stemRegex);
- InvocationGate invocationGate = new DefaultInvocationGate();
-
- @Override
- public boolean isTriggeringEvent(File activeFile, final E event) {
-
- long time = getCurrentTime();
-
- // first check for roll-over based on time
- if (time >= nextCheck) {
- Date dateInElapsedPeriod = dateInCurrentPeriod;
- elapsedPeriodsFileName = tbrp.fileNamePatternWithoutCompSuffix.convertMultipleArguments(dateInElapsedPeriod, currentPeriodsCounter);
- currentPeriodsCounter = 0;
- setDateInCurrentPeriod(time);
- computeNextCheck();
- return true;
- }
-
- // next check for roll-over based on size
- if (invocationGate.isTooSoon(time)) {
- return false;
- }
-
- if (activeFile == null) {
- addWarn("activeFile == null");
- return false;
- }
- if (maxFileSize == null) {
- addWarn("maxFileSize = null");
- return false;
- }
- if (activeFile.length() >= maxFileSize.getSize()) {
-
- elapsedPeriodsFileName = tbrp.fileNamePatternWithoutCompSuffix.convertMultipleArguments(dateInCurrentPeriod, currentPeriodsCounter);
- currentPeriodsCounter++;
- return true;
- }
-
- return false;
+ // if parent raw file property is not null, then the next
+ // counter is max found counter+1
+ if (tbrp.getParentsRawFileProperty() != null || (tbrp.compressionMode != CompressionMode.NONE)) {
+ // TODO test me
+ currentPeriodsCounter++;
+ }
+ }
+
+ // IMPORTANT: This field can be updated by multiple threads. It follows that
+ // its values may *not* be incremented sequentially. However, we don't care
+ // about the actual value of the field except that from time to time the
+ // expression (invocationCounter++ & invocationMask) == invocationMask) should be true.
+ private int invocationCounter;
+ private int invocationMask = 0x1;
+
+ public boolean isTriggeringEvent(File activeFile, final E event) {
+
+ long time = getCurrentTime();
+ if (time >= nextCheck) {
+ Date dateInElapsedPeriod = dateInCurrentPeriod;
+ elapsedPeriodsFileName = tbrp.fileNamePatternWCS
+ .convertMultipleArguments(dateInElapsedPeriod, currentPeriodsCounter);
+ currentPeriodsCounter = 0;
+ setDateInCurrentPeriod(time);
+ computeNextCheck();
+ return true;
}
- @Override
- public String getCurrentPeriodsFileNameWithoutCompressionSuffix() {
- return tbrp.fileNamePatternWithoutCompSuffix.convertMultipleArguments(dateInCurrentPeriod, currentPeriodsCounter);
+ // for performance reasons, check for changes every 16,invocationMask invocations
+ if (((++invocationCounter) & invocationMask) != invocationMask) {
+ return false;
+ }
+ if (invocationMask < 0x0F) {
+ invocationMask = (invocationMask << 1) + 1;
}
- public void setMaxFileSize(FileSize aMaxFileSize) {
- this.maxFileSize = aMaxFileSize;
+ if (activeFile.length() >= maxFileSize.getSize()) {
+ elapsedPeriodsFileName = tbrp.fileNamePatternWCS
+ .convertMultipleArguments(dateInCurrentPeriod, currentPeriodsCounter);
+ currentPeriodsCounter++;
+ return true;
}
+ return false;
+ }
+
+ private String getFileNameIncludingCompressionSuffix(Date date, int counter) {
+ return tbrp.fileNamePattern.convertMultipleArguments(
+ dateInCurrentPeriod, counter);
+ }
+
+
+ @Override
+ public String getCurrentPeriodsFileNameWithoutCompressionSuffix() {
+ return tbrp.fileNamePatternWCS.convertMultipleArguments(
+ dateInCurrentPeriod, currentPeriodsCounter);
+ }
+
+ public String getMaxFileSize() {
+ return maxFileSizeAsString;
+ }
+
+ public void setMaxFileSize(String maxFileSize) {
+ this.maxFileSizeAsString = maxFileSize;
+ this.maxFileSize = FileSize.valueOf(maxFileSize);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedRollingPolicy.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedRollingPolicy.java
deleted file mode 100644
index 9c04089..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedRollingPolicy.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package ch.qos.logback.core.rolling;
-
-import ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP.Usage;
-import ch.qos.logback.core.util.FileSize;
-
-
-
-public class SizeAndTimeBasedRollingPolicy<E> extends TimeBasedRollingPolicy<E> {
-
- FileSize maxFileSize;
-
- @Override
- public void start() {
- SizeAndTimeBasedFNATP<E> sizeAndTimeBasedFNATP = new SizeAndTimeBasedFNATP<E>(Usage.EMBEDDED);
- if(maxFileSize == null) {
- addError("maxFileSize property is mandatory.");
- return;
- } else {
- addInfo("Archive files will be limited to ["+maxFileSize+"] each.");
- }
-
- sizeAndTimeBasedFNATP.setMaxFileSize(maxFileSize);
- timeBasedFileNamingAndTriggeringPolicy = sizeAndTimeBasedFNATP;
-
- if(!isUnboundedTotalSizeCap() && totalSizeCap.getSize() < maxFileSize.getSize()) {
- addError("totalSizeCap of ["+totalSizeCap+"] is smaller than maxFileSize ["+maxFileSize+"] which is non-sensical");
- return;
- }
-
- // most work is done by the parent
- super.start();
- }
-
-
- public void setMaxFileSize(FileSize aMaxFileSize) {
- this.maxFileSize = aMaxFileSize;
- }
-
- @Override
- public String toString() {
- return "c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@"+this.hashCode();
- }
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java
index f3f081c..f27b55d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,7 +16,6 @@ package ch.qos.logback.core.rolling;
import java.io.File;
import ch.qos.logback.core.util.FileSize;
-import ch.qos.logback.core.util.DefaultInvocationGate;
import ch.qos.logback.core.util.InvocationGate;
/**
@@ -32,29 +31,70 @@ import ch.qos.logback.core.util.InvocationGate;
*/
public class SizeBasedTriggeringPolicy<E> extends TriggeringPolicyBase<E> {
- public static final String SEE_SIZE_FORMAT = "http://logback.qos.ch/codes.html#sbtp_size_format";
- /**
- * The default maximum file size.
- */
- public static final long DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024; // 10 MB
+ public static final String SEE_SIZE_FORMAT = "http://logback.qos.ch/codes.html#sbtp_size_format";
+ /**
+ * The default maximum file size.
+ */
+ public static final long DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024; // 10 MB
- FileSize maxFileSize = new FileSize(DEFAULT_MAX_FILE_SIZE);
+ String maxFileSizeAsString = Long.toString(DEFAULT_MAX_FILE_SIZE);
+ FileSize maxFileSize;
- public SizeBasedTriggeringPolicy() {
- }
+ public SizeBasedTriggeringPolicy() {
+ }
- InvocationGate invocationGate = new DefaultInvocationGate();
+ public SizeBasedTriggeringPolicy(final String maxFileSize) {
+ setMaxFileSize(maxFileSize);
+ }
- public boolean isTriggeringEvent(final File activeFile, final E event) {
- long now = System.currentTimeMillis();
- if (invocationGate.isTooSoon(now))
- return false;
+ private InvocationGate invocationGate = new InvocationGate();
- return (activeFile.length() >= maxFileSize.getSize());
- }
+ public boolean isTriggeringEvent(final File activeFile, final E event) {
+ if(invocationGate.skipFurtherWork())
+ return false;
- public void setMaxFileSize(FileSize aMaxFileSize) {
- this.maxFileSize = aMaxFileSize;
- }
+ long now = System.currentTimeMillis();
+ invocationGate.updateMaskIfNecessary(now);
+
+ return (activeFile.length() >= maxFileSize.getSize());
+ }
+
+ public String getMaxFileSize() {
+ return maxFileSizeAsString;
+ }
+ public void setMaxFileSize(String maxFileSize) {
+ this.maxFileSizeAsString = maxFileSize;
+ this.maxFileSize = FileSize.valueOf(maxFileSize);
+ }
+
+ long toFileSize(String value) {
+ if (value == null)
+ return DEFAULT_MAX_FILE_SIZE;
+
+ String s = value.trim().toUpperCase();
+ long multiplier = 1;
+ int index;
+
+ if ((index = s.indexOf("KB")) != -1) {
+ multiplier = 1024;
+ s = s.substring(0, index);
+ } else if ((index = s.indexOf("MB")) != -1) {
+ multiplier = 1024 * 1024;
+ s = s.substring(0, index);
+ } else if ((index = s.indexOf("GB")) != -1) {
+ multiplier = 1024 * 1024 * 1024;
+ s = s.substring(0, index);
+ }
+ if (s != null) {
+ try {
+ return Long.valueOf(s).longValue() * multiplier;
+ } catch (NumberFormatException e) {
+ addError("[" + s + "] is not in proper int format. Please refer to "
+ + SEE_SIZE_FORMAT);
+ addError("[" + value + "] not in expected format.", e);
+ }
+ }
+ return DEFAULT_MAX_FILE_SIZE;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicy.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicy.java
index 2da43ba..7a77628 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicy.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicy.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,60 +24,61 @@ import ch.qos.logback.core.spi.ContextAware;
*
* @param <E>
*/
-public interface TimeBasedFileNamingAndTriggeringPolicy<E> extends TriggeringPolicy<E>, ContextAware {
+public interface TimeBasedFileNamingAndTriggeringPolicy<E> extends
+ TriggeringPolicy<E>, ContextAware {
- /**
- * Set the host/parent {@link TimeBasedRollingPolicy}.
- *
- * @param tbrp
- * parent TimeBasedRollingPolicy
- */
- void setTimeBasedRollingPolicy(TimeBasedRollingPolicy<E> tbrp);
+ /**
+ * Set the host/parent {@link TimeBasedRollingPolicy}.
+ *
+ * @param tbrp
+ * parent TimeBasedRollingPolicy
+ */
+ void setTimeBasedRollingPolicy(TimeBasedRollingPolicy<E> tbrp);
- /**
- * Return the file name for the elapsed periods file name.
- *
- * @return
- */
- String getElapsedPeriodsFileName();
+ /**
+ * Return the file name for the elapsed periods file name.
+ *
+ * @return
+ */
+ String getElapsedPeriodsFileName();
- /**
- * Return the current periods file name without the compression suffix. This
- * value is equivalent to the active file name.
- *
- * @return current period's file name (without compression suffix)
- */
- String getCurrentPeriodsFileNameWithoutCompressionSuffix();
+ /**
+ * Return the current periods file name without the compression suffix. This
+ * value is equivalent to the active file name.
+ *
+ * @return current period's file name (without compression suffix)
+ */
+ String getCurrentPeriodsFileNameWithoutCompressionSuffix();
- /**
- * Return the archive remover appropriate for this instance.
- */
- ArchiveRemover getArchiveRemover();
+ /**
+ * Return the archive remover appropriate for this instance.
+ */
+ ArchiveRemover getArchiveRemover();
+
+ /**
+ * Return the current time which is usually the value returned by
+ * System.currentMillis(). However, for <b>testing</b> purposed this value
+ * may be different than the real time.
+ *
+ * @return current time value
+ */
+ long getCurrentTime();
- /**
- * Return the current time which is usually the value returned by
- * System.currentMillis(). However, for <b>testing</b> purposed this value
- * may be different than the real time.
- *
- * @return current time value
- */
- long getCurrentTime();
+ /**
+ * Set the current time. Only unit tests should invoke this method.
+ *
+ * @param now
+ */
+ void setCurrentTime(long now);
- /**
- * Set the current time. Only unit tests should invoke this method.
- *
- * @param now
- */
- void setCurrentTime(long now);
-
- /**
- * Set some date in the current period. Only unit tests should invoke this
- * method.
- *
- * WARNING: method removed. A unit test should not set the
- * date in current period. It is the job of the FNATP to compute that.
- *
- * @param date
- */
- // void setDateInCurrentPeriod(Date date);
+ /**
+ * Set some date in the current period. Only unit tests should invoke this
+ * method.
+ *
+ * WARNING: method removed. A unit test should not set the
+ * date in current period. It is the job of the FNATP to compute that.
+ *
+ * @param date
+ */
+ //void setDateInCurrentPeriod(Date date);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicyBase.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicyBase.java
index 045461a..8fec847 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicyBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicyBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,125 +13,106 @@
*/
package ch.qos.logback.core.rolling;
-import static ch.qos.logback.core.CoreConstants.CODES_URL;
-
import java.io.File;
import java.util.Date;
-import java.util.Locale;
-import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.rolling.helper.ArchiveRemover;
import ch.qos.logback.core.rolling.helper.DateTokenConverter;
import ch.qos.logback.core.rolling.helper.RollingCalendar;
import ch.qos.logback.core.spi.ContextAwareBase;
-abstract public class TimeBasedFileNamingAndTriggeringPolicyBase<E> extends ContextAwareBase implements TimeBasedFileNamingAndTriggeringPolicy<E> {
-
- static private String COLLIDING_DATE_FORMAT_URL = CODES_URL + "#rfa_collision_in_dateFormat";
-
- protected TimeBasedRollingPolicy<E> tbrp;
-
- protected ArchiveRemover archiveRemover = null;
- protected String elapsedPeriodsFileName;
- protected RollingCalendar rc;
-
- protected long artificialCurrentTime = -1;
- protected Date dateInCurrentPeriod = null;
-
- protected long nextCheck;
- protected boolean started = false;
- protected boolean errorFree = true;
-
- public boolean isStarted() {
- return started;
- }
-
- public void start() {
- DateTokenConverter<Object> dtc = tbrp.fileNamePattern.getPrimaryDateTokenConverter();
- if (dtc == null) {
- throw new IllegalStateException("FileNamePattern [" + tbrp.fileNamePattern.getPattern() + "] does not contain a valid DateToken");
- }
-
- if (dtc.getTimeZone() != null) {
- rc = new RollingCalendar(dtc.getDatePattern(), dtc.getTimeZone(), Locale.getDefault());
- } else {
- rc = new RollingCalendar(dtc.getDatePattern());
- }
- addInfo("The date pattern is '" + dtc.getDatePattern() + "' from file name pattern '" + tbrp.fileNamePattern.getPattern() + "'.");
- rc.printPeriodicity(this);
-
- if (!rc.isCollisionFree()) {
- addError("The date format in FileNamePattern will result in collisions in the names of archived log files.");
- addError(CoreConstants.MORE_INFO_PREFIX + COLLIDING_DATE_FORMAT_URL);
- withErrors();
- return;
- }
-
- setDateInCurrentPeriod(new Date(getCurrentTime()));
- if (tbrp.getParentsRawFileProperty() != null) {
- File currentFile = new File(tbrp.getParentsRawFileProperty());
- if (currentFile.exists() && currentFile.canRead()) {
- setDateInCurrentPeriod(new Date(currentFile.lastModified()));
- }
- }
- addInfo("Setting initial period to " + dateInCurrentPeriod);
- computeNextCheck();
- }
+abstract public class TimeBasedFileNamingAndTriggeringPolicyBase<E> extends
+ ContextAwareBase implements TimeBasedFileNamingAndTriggeringPolicy<E> {
- public void stop() {
- started = false;
- }
+ protected TimeBasedRollingPolicy<E> tbrp;
- protected void computeNextCheck() {
- nextCheck = rc.getNextTriggeringDate(dateInCurrentPeriod).getTime();
- }
+ protected ArchiveRemover archiveRemover = null;
+ protected String elapsedPeriodsFileName;
+ protected RollingCalendar rc;
- protected void setDateInCurrentPeriod(long now) {
- dateInCurrentPeriod.setTime(now);
- }
+ protected long artificialCurrentTime = -1;
+ protected Date dateInCurrentPeriod = null;
- // allow Test classes to act on the dateInCurrentPeriod field to simulate old
- // log files needing rollover
- public void setDateInCurrentPeriod(Date _dateInCurrentPeriod) {
- this.dateInCurrentPeriod = _dateInCurrentPeriod;
- }
+ protected long nextCheck;
+ protected boolean started = false;
- public String getElapsedPeriodsFileName() {
- return elapsedPeriodsFileName;
- }
+ public boolean isStarted() {
+ return started;
+ }
- public String getCurrentPeriodsFileNameWithoutCompressionSuffix() {
- return tbrp.fileNamePatternWithoutCompSuffix.convert(dateInCurrentPeriod);
+ public void start() {
+ DateTokenConverter dtc = tbrp.fileNamePattern.getPrimaryDateTokenConverter();
+ if (dtc == null) {
+ throw new IllegalStateException("FileNamePattern ["
+ + tbrp.fileNamePattern.getPattern()
+ + "] does not contain a valid DateToken");
}
- public void setCurrentTime(long timeInMillis) {
- artificialCurrentTime = timeInMillis;
+ rc = new RollingCalendar();
+ rc.init(dtc.getDatePattern());
+ addInfo("The date pattern is '" + dtc.getDatePattern()
+ + "' from file name pattern '" + tbrp.fileNamePattern.getPattern()
+ + "'.");
+ rc.printPeriodicity(this);
+
+ setDateInCurrentPeriod(new Date(getCurrentTime()));
+ if (tbrp.getParentsRawFileProperty() != null) {
+ File currentFile = new File(tbrp.getParentsRawFileProperty());
+ if (currentFile.exists() && currentFile.canRead()) {
+ setDateInCurrentPeriod(new Date(currentFile.lastModified()));
+ }
}
- public long getCurrentTime() {
- // if time is forced return the time set by user
- if (artificialCurrentTime >= 0) {
- return artificialCurrentTime;
- } else {
- return System.currentTimeMillis();
- }
+ addInfo("Setting initial period to " + dateInCurrentPeriod);
+ computeNextCheck();
+ }
+
+ public void stop() {
+ started = false;
+ }
+
+ protected void computeNextCheck() {
+ nextCheck = rc.getNextTriggeringMillis(dateInCurrentPeriod);
+ }
+
+ protected void setDateInCurrentPeriod(long now) {
+ dateInCurrentPeriod.setTime(now);
+ }
+
+ // allow Test classes to act on the dateInCurrentPeriod field to simulate old
+ // log files needing rollover
+ public void setDateInCurrentPeriod(Date _dateInCurrentPeriod) {
+ this.dateInCurrentPeriod = _dateInCurrentPeriod;
+ }
+
+ public String getElapsedPeriodsFileName() {
+ return elapsedPeriodsFileName;
+ }
+
+ public String getCurrentPeriodsFileNameWithoutCompressionSuffix() {
+ return tbrp.fileNamePatternWCS.convert(dateInCurrentPeriod);
+ }
+
+ public void setCurrentTime(long timeInMillis) {
+ artificialCurrentTime = timeInMillis;
+ }
+
+ public long getCurrentTime() {
+ // if time is forced return the time set by user
+ if (artificialCurrentTime >= 0) {
+ return artificialCurrentTime;
+ } else {
+ return System.currentTimeMillis();
}
+ }
- public void setTimeBasedRollingPolicy(TimeBasedRollingPolicy<E> _tbrp) {
- this.tbrp = _tbrp;
+ public void setTimeBasedRollingPolicy(TimeBasedRollingPolicy<E> _tbrp) {
+ this.tbrp = _tbrp;
- }
-
- public ArchiveRemover getArchiveRemover() {
- return archiveRemover;
- }
+ }
- protected void withErrors() {
- errorFree = false;
- }
-
- protected boolean isErrorFree() {
- return errorFree;
- }
+ public ArchiveRemover getArchiveRemover() {
+ return archiveRemover;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java
index ee3952f..9f7ac41 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,23 +13,15 @@
*/
package ch.qos.logback.core.rolling;
-import static ch.qos.logback.core.CoreConstants.UNBOUND_HISTORY;
-import static ch.qos.logback.core.CoreConstants.UNBOUNDED_TOTAL_SIZE_CAP;
-
import java.io.File;
import java.util.Date;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import ch.qos.logback.core.CoreConstants;
-import ch.qos.logback.core.rolling.helper.ArchiveRemover;
-import ch.qos.logback.core.rolling.helper.CompressionMode;
-import ch.qos.logback.core.rolling.helper.Compressor;
-import ch.qos.logback.core.rolling.helper.FileFilterUtil;
-import ch.qos.logback.core.rolling.helper.FileNamePattern;
-import ch.qos.logback.core.rolling.helper.RenameUtil;
-import ch.qos.logback.core.util.FileSize;
+import ch.qos.logback.core.rolling.helper.*;
/**
* <code>TimeBasedRollingPolicy</code> is both easy to configure and quite
@@ -41,226 +33,222 @@ import ch.qos.logback.core.util.FileSize;
*
* @author Ceki Gülcü
*/
-public class TimeBasedRollingPolicy<E> extends RollingPolicyBase implements TriggeringPolicy<E> {
- static final String FNP_NOT_SET = "The FileNamePattern option must be set before using TimeBasedRollingPolicy. ";
- // WCS: without compression suffix
- FileNamePattern fileNamePatternWithoutCompSuffix;
-
- private Compressor compressor;
- private RenameUtil renameUtil = new RenameUtil();
- Future<?> compressionFuture;
- Future<?> cleanUpFuture;
-
- private int maxHistory = UNBOUND_HISTORY;
- protected FileSize totalSizeCap = new FileSize(UNBOUNDED_TOTAL_SIZE_CAP);
-
- private ArchiveRemover archiveRemover;
-
- TimeBasedFileNamingAndTriggeringPolicy<E> timeBasedFileNamingAndTriggeringPolicy;
-
- boolean cleanHistoryOnStart = false;
-
- public void start() {
- // set the LR for our utility object
- renameUtil.setContext(this.context);
-
- // find out period from the filename pattern
- if (fileNamePatternStr != null) {
- fileNamePattern = new FileNamePattern(fileNamePatternStr, this.context);
- determineCompressionMode();
- } else {
- addWarn(FNP_NOT_SET);
- addWarn(CoreConstants.SEE_FNP_NOT_SET);
- throw new IllegalStateException(FNP_NOT_SET + CoreConstants.SEE_FNP_NOT_SET);
- }
-
- compressor = new Compressor(compressionMode);
- compressor.setContext(context);
-
- // wcs : without compression suffix
- fileNamePatternWithoutCompSuffix = new FileNamePattern(Compressor.computeFileNameStrWithoutCompSuffix(fileNamePatternStr, compressionMode), this.context);
-
- addInfo("Will use the pattern " + fileNamePatternWithoutCompSuffix + " for the active file");
-
- if (compressionMode == CompressionMode.ZIP) {
- String zipEntryFileNamePatternStr = transformFileNamePattern2ZipEntry(fileNamePatternStr);
- zipEntryFileNamePattern = new FileNamePattern(zipEntryFileNamePatternStr, context);
- }
-
- if (timeBasedFileNamingAndTriggeringPolicy == null) {
- timeBasedFileNamingAndTriggeringPolicy = new DefaultTimeBasedFileNamingAndTriggeringPolicy<E>();
- }
- timeBasedFileNamingAndTriggeringPolicy.setContext(context);
- timeBasedFileNamingAndTriggeringPolicy.setTimeBasedRollingPolicy(this);
- timeBasedFileNamingAndTriggeringPolicy.start();
-
- if (!timeBasedFileNamingAndTriggeringPolicy.isStarted()) {
- addWarn("Subcomponent did not start. TimeBasedRollingPolicy will not start.");
- return;
- }
-
- // the maxHistory property is given to TimeBasedRollingPolicy instead of to
- // the TimeBasedFileNamingAndTriggeringPolicy. This makes it more convenient
- // for the user at the cost of inconsistency here.
- if (maxHistory != UNBOUND_HISTORY) {
- archiveRemover = timeBasedFileNamingAndTriggeringPolicy.getArchiveRemover();
- archiveRemover.setMaxHistory(maxHistory);
- archiveRemover.setTotalSizeCap(totalSizeCap.getSize());
- if (cleanHistoryOnStart) {
- addInfo("Cleaning on start up");
- Date now = new Date(timeBasedFileNamingAndTriggeringPolicy.getCurrentTime());
- cleanUpFuture = archiveRemover.cleanAsynchronously(now);
- }
- } else if (!isUnboundedTotalSizeCap()) {
- addWarn("'maxHistory' is not set, ignoring 'totalSizeCap' option with value ["+totalSizeCap+"]");
- }
-
- super.start();
- }
-
- protected boolean isUnboundedTotalSizeCap() {
- return totalSizeCap.getSize() == UNBOUNDED_TOTAL_SIZE_CAP;
- }
-
- @Override
- public void stop() {
- if (!isStarted())
- return;
- waitForAsynchronousJobToStop(compressionFuture, "compression");
- waitForAsynchronousJobToStop(cleanUpFuture, "clean-up");
- super.stop();
- }
-
- private void waitForAsynchronousJobToStop(Future<?> aFuture, String jobDescription) {
- if (aFuture != null) {
- try {
- aFuture.get(CoreConstants.SECONDS_TO_WAIT_FOR_COMPRESSION_JOBS, TimeUnit.SECONDS);
- } catch (TimeoutException e) {
- addError("Timeout while waiting for " + jobDescription + " job to finish", e);
- } catch (Exception e) {
- addError("Unexpected exception while waiting for " + jobDescription + " job to finish", e);
- }
- }
- }
-
- private String transformFileNamePattern2ZipEntry(String fileNamePatternStr) {
- String slashified = FileFilterUtil.slashify(fileNamePatternStr);
- return FileFilterUtil.afterLastSlash(slashified);
- }
-
- public void setTimeBasedFileNamingAndTriggeringPolicy(TimeBasedFileNamingAndTriggeringPolicy<E> timeBasedTriggering) {
- this.timeBasedFileNamingAndTriggeringPolicy = timeBasedTriggering;
- }
-
- public TimeBasedFileNamingAndTriggeringPolicy<E> getTimeBasedFileNamingAndTriggeringPolicy() {
- return timeBasedFileNamingAndTriggeringPolicy;
- }
-
- public void rollover() throws RolloverFailure {
-
- // when rollover is called the elapsed period's file has
- // been already closed. This is a working assumption of this method.
-
- String elapsedPeriodsFileName = timeBasedFileNamingAndTriggeringPolicy.getElapsedPeriodsFileName();
+public class TimeBasedRollingPolicy<E> extends RollingPolicyBase implements
+ TriggeringPolicy<E> {
+ static final String FNP_NOT_SET = "The FileNamePattern option must be set before using TimeBasedRollingPolicy. ";
+ static final int INFINITE_HISTORY = 0;
+
+ // WCS: without compression suffix
+ FileNamePattern fileNamePatternWCS;
+
+ private Compressor compressor;
+ private RenameUtil renameUtil = new RenameUtil();
+ Future<?> future;
+
+ private int maxHistory = INFINITE_HISTORY;
+ private ArchiveRemover archiveRemover;
- String elapsedPeriodStem = FileFilterUtil.afterLastSlash(elapsedPeriodsFileName);
+ TimeBasedFileNamingAndTriggeringPolicy<E> timeBasedFileNamingAndTriggeringPolicy;
- if (compressionMode == CompressionMode.NONE) {
- if (getParentsRawFileProperty() != null) {
- renameUtil.rename(getParentsRawFileProperty(), elapsedPeriodsFileName);
- } // else { nothing to do if CompressionMode == NONE and parentsRawFileProperty == null }
- } else {
- if (getParentsRawFileProperty() == null) {
- compressionFuture = compressor.asyncCompress(elapsedPeriodsFileName, elapsedPeriodsFileName, elapsedPeriodStem);
- } else {
- compressionFuture = renameRawAndAsyncCompress(elapsedPeriodsFileName, elapsedPeriodStem);
- }
- }
+ boolean cleanHistoryOnStart = false;
- if (archiveRemover != null) {
- Date now = new Date(timeBasedFileNamingAndTriggeringPolicy.getCurrentTime());
- cleanUpFuture = archiveRemover.cleanAsynchronously(now);
- }
+ public void start() {
+ // set the LR for our utility object
+ renameUtil.setContext(this.context);
+
+ // find out period from the filename pattern
+ if (fileNamePatternStr != null) {
+ fileNamePattern = new FileNamePattern(fileNamePatternStr, this.context);
+ determineCompressionMode();
+ } else {
+ addWarn(FNP_NOT_SET);
+ addWarn(CoreConstants.SEE_FNP_NOT_SET);
+ throw new IllegalStateException(FNP_NOT_SET
+ + CoreConstants.SEE_FNP_NOT_SET);
}
- Future<?> renameRawAndAsyncCompress(String nameOfCompressedFile, String innerEntryName) throws RolloverFailure {
- String parentsRawFile = getParentsRawFileProperty();
- String tmpTarget = nameOfCompressedFile + System.nanoTime() + ".tmp";
- renameUtil.rename(parentsRawFile, tmpTarget);
- return compressor.asyncCompress(tmpTarget, nameOfCompressedFile, innerEntryName);
- }
-
- /**
- *
- * The active log file is determined by the value of the parent's filename
- * option. However, in case the file name is left blank, then, the active log
- * file equals the file name for the current period as computed by the
- * <b>FileNamePattern</b> option.
- *
- * <p>The RollingPolicy must know whether it is responsible for changing the
- * name of the active file or not. If the active file name is set by the user
- * via the configuration file, then the RollingPolicy must let it like it is.
- * If the user does not specify an active file name, then the RollingPolicy
- * generates one.
- *
- * <p> To be sure that the file name used by the parent class has been
- * generated by the RollingPolicy and not specified by the user, we keep track
- * of the last generated name object and compare its reference to the parent
- * file name. If they match, then the RollingPolicy knows it's responsible for
- * the change of the file name.
- *
- */
- public String getActiveFileName() {
- String parentsRawFileProperty = getParentsRawFileProperty();
- if (parentsRawFileProperty != null) {
- return parentsRawFileProperty;
- } else {
- return timeBasedFileNamingAndTriggeringPolicy.getCurrentPeriodsFileNameWithoutCompressionSuffix();
- }
- }
-
- public boolean isTriggeringEvent(File activeFile, final E event) {
- return timeBasedFileNamingAndTriggeringPolicy.isTriggeringEvent(activeFile, event);
- }
-
- /**
- * Get the number of archive files to keep.
- *
- * @return number of archive files to keep
- */
- public int getMaxHistory() {
- return maxHistory;
- }
-
- /**
- * Set the maximum number of archive files to keep.
- *
- * @param maxHistory
- * number of archive files to keep
- */
- public void setMaxHistory(int maxHistory) {
- this.maxHistory = maxHistory;
- }
-
- public boolean isCleanHistoryOnStart() {
- return cleanHistoryOnStart;
- }
-
- /**
- * Should archive removal be attempted on application start up? Default is false.
- * @since 1.0.1
- * @param cleanHistoryOnStart
- */
- public void setCleanHistoryOnStart(boolean cleanHistoryOnStart) {
- this.cleanHistoryOnStart = cleanHistoryOnStart;
- }
-
- @Override
- public String toString() {
- return "c.q.l.core.rolling.TimeBasedRollingPolicy@"+this.hashCode();
- }
-
- public void setTotalSizeCap(FileSize totalSizeCap) {
- this.totalSizeCap = totalSizeCap;
- }
+ compressor = new Compressor(compressionMode);
+ compressor.setContext(context);
+
+ // wcs : without compression suffix
+ fileNamePatternWCS = new FileNamePattern(Compressor.computeFileNameStr_WCS(
+ fileNamePatternStr, compressionMode), this.context);
+
+ addInfo("Will use the pattern " + fileNamePatternWCS
+ + " for the active file");
+
+ if(compressionMode == CompressionMode.ZIP) {
+ String zipEntryFileNamePatternStr = transformFileNamePattern2ZipEntry(fileNamePatternStr);
+ zipEntryFileNamePattern = new FileNamePattern(zipEntryFileNamePatternStr, context);
+ }
+
+ if (timeBasedFileNamingAndTriggeringPolicy == null) {
+ timeBasedFileNamingAndTriggeringPolicy = new DefaultTimeBasedFileNamingAndTriggeringPolicy<E>();
+ }
+ timeBasedFileNamingAndTriggeringPolicy.setContext(context);
+ timeBasedFileNamingAndTriggeringPolicy.setTimeBasedRollingPolicy(this);
+ timeBasedFileNamingAndTriggeringPolicy.start();
+
+ // the maxHistory property is given to TimeBasedRollingPolicy instead of to
+ // the TimeBasedFileNamingAndTriggeringPolicy. This makes it more convenient
+ // for the user at the cost of inconsistency here.
+ if (maxHistory != INFINITE_HISTORY) {
+ archiveRemover = timeBasedFileNamingAndTriggeringPolicy.getArchiveRemover();
+ archiveRemover.setMaxHistory(maxHistory);
+ if(cleanHistoryOnStart) {
+ addInfo("Cleaning on start up");
+ archiveRemover.clean(new Date(timeBasedFileNamingAndTriggeringPolicy.getCurrentTime()));
+ }
+ }
+
+ super.start();
+ }
+
+ @Override
+ public void stop() {
+ if(!isStarted())
+ return;
+ waitForAsynchronousJobToStop();
+ super.stop();
+ }
+
+
+ private void waitForAsynchronousJobToStop() {
+ if(future != null) {
+ try {
+ future.get(CoreConstants.SECONDS_TO_WAIT_FOR_COMPRESSION_JOBS, TimeUnit.SECONDS);
+ } catch (TimeoutException e) {
+ addError("Timeout while waiting for compression job to finish", e);
+ } catch (Exception e) {
+ addError("Unexpected exception while waiting for compression job to finish", e);
+ }
+ }
+ }
+ private String transformFileNamePattern2ZipEntry(String fileNamePatternStr) {
+ String slashified = FileFilterUtil.slashify(fileNamePatternStr);
+ return FileFilterUtil.afterLastSlash(slashified);
+ }
+
+ public void setTimeBasedFileNamingAndTriggeringPolicy(
+ TimeBasedFileNamingAndTriggeringPolicy<E> timeBasedTriggering) {
+ this.timeBasedFileNamingAndTriggeringPolicy = timeBasedTriggering;
+ }
+
+ public TimeBasedFileNamingAndTriggeringPolicy<E> getTimeBasedFileNamingAndTriggeringPolicy() {
+ return timeBasedFileNamingAndTriggeringPolicy;
+ }
+
+ public void rollover() throws RolloverFailure {
+
+ // when rollover is called the elapsed period's file has
+ // been already closed. This is a working assumption of this method.
+
+ String elapsedPeriodsFileName = timeBasedFileNamingAndTriggeringPolicy
+ .getElapsedPeriodsFileName();
+
+ String elapsedPeriodStem = FileFilterUtil.afterLastSlash(elapsedPeriodsFileName);
+
+ if (compressionMode == CompressionMode.NONE) {
+ if (getParentsRawFileProperty() != null) {
+ renameUtil.rename(getParentsRawFileProperty(), elapsedPeriodsFileName);
+ } // else { nothing to do if CompressionMode == NONE and parentsRawFileProperty == null }
+ } else {
+ if (getParentsRawFileProperty() == null) {
+ future = asyncCompress(elapsedPeriodsFileName, elapsedPeriodsFileName, elapsedPeriodStem);
+ } else {
+ future = renamedRawAndAsyncCompress(elapsedPeriodsFileName, elapsedPeriodStem);
+ }
+ }
+
+ if (archiveRemover != null) {
+ archiveRemover.clean(new Date(timeBasedFileNamingAndTriggeringPolicy.getCurrentTime()));
+ }
+ }
+
+ Future asyncCompress(String nameOfFile2Compress, String nameOfCompressedFile, String innerEntryName)
+ throws RolloverFailure {
+ AsynchronousCompressor ac = new AsynchronousCompressor(compressor);
+ return ac.compressAsynchronously(nameOfFile2Compress, nameOfCompressedFile, innerEntryName);
+ }
+
+ Future renamedRawAndAsyncCompress(String nameOfCompressedFile, String innerEntryName)
+ throws RolloverFailure {
+ String parentsRawFile = getParentsRawFileProperty();
+ String tmpTarget = parentsRawFile + System.nanoTime() + ".tmp";
+ renameUtil.rename(parentsRawFile, tmpTarget);
+ return asyncCompress(tmpTarget, nameOfCompressedFile, innerEntryName);
+ }
+
+ /**
+ *
+ * The active log file is determined by the value of the parent's filename
+ * option. However, in case the file name is left blank, then, the active log
+ * file equals the file name for the current period as computed by the
+ * <b>FileNamePattern</b> option.
+ *
+ * <p>The RollingPolicy must know whether it is responsible for changing the
+ * name of the active file or not. If the active file name is set by the user
+ * via the configuration file, then the RollingPolicy must let it like it is.
+ * If the user does not specify an active file name, then the RollingPolicy
+ * generates one.
+ *
+ * <p> To be sure that the file name used by the parent class has been
+ * generated by the RollingPolicy and not specified by the user, we keep track
+ * of the last generated name object and compare its reference to the parent
+ * file name. If they match, then the RollingPolicy knows it's responsible for
+ * the change of the file name.
+ *
+ */
+ public String getActiveFileName() {
+ String parentsRawFileProperty = getParentsRawFileProperty();
+ if (parentsRawFileProperty != null) {
+ return parentsRawFileProperty;
+ } else {
+ return timeBasedFileNamingAndTriggeringPolicy
+ .getCurrentPeriodsFileNameWithoutCompressionSuffix();
+ }
+ }
+
+ public boolean isTriggeringEvent(File activeFile, final E event) {
+ return timeBasedFileNamingAndTriggeringPolicy.isTriggeringEvent(activeFile, event);
+ }
+
+ /**
+ * Get the number of archive files to keep.
+ *
+ * @return number of archive files to keep
+ */
+ public int getMaxHistory() {
+ return maxHistory;
+ }
+
+ /**
+ * Set the maximum number of archive files to keep.
+ *
+ * @param maxHistory
+ * number of archive files to keep
+ */
+ public void setMaxHistory(int maxHistory) {
+ this.maxHistory = maxHistory;
+ }
+
+
+ public boolean isCleanHistoryOnStart() {
+ return cleanHistoryOnStart;
+ }
+
+ /**
+ * Should archive removal be attempted on application start up? Default is false.
+ * @since 1.0.1
+ * @param cleanHistoryOnStart
+ */
+ public void setCleanHistoryOnStart(boolean cleanHistoryOnStart) {
+ this.cleanHistoryOnStart = cleanHistoryOnStart;
+ }
+
+
+ @Override
+ public String toString() {
+ return "c.q.l.core.rolling.TimeBasedRollingPolicy";
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/TriggeringPolicy.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/TriggeringPolicy.java
index 16d5f9f..8bdfce2 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/TriggeringPolicy.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/TriggeringPolicy.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,6 +17,7 @@ import java.io.File;
import ch.qos.logback.core.spi.LifeCycle;
+
/**
* A <code>TriggeringPolicy</code> controls the conditions under which roll-over
* occurs. Such conditions include time of day, file size, an
@@ -26,13 +27,13 @@ import ch.qos.logback.core.spi.LifeCycle;
* */
public interface TriggeringPolicy<E> extends LifeCycle {
-
- /**
- * Should roll-over be triggered at this time?
- *
- * @param activeFile A reference to the currently active log file.
- * @param event A reference to the currently event.
- * @return true if a roll-over should occur.
- */
- boolean isTriggeringEvent(final File activeFile, final E event);
+
+ /**
+ * Should roll-over be triggered at this time?
+ *
+ * @param activeFile A reference to the currently active log file.
+ * @param event A reference to the currently event.
+ * @return true if a roll-over should occur.
+ */
+ boolean isTriggeringEvent(final File activeFile, final E event);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/TriggeringPolicyBase.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/TriggeringPolicyBase.java
index 884db7f..8d5a9be 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/TriggeringPolicyBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/TriggeringPolicyBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,6 +15,7 @@ package ch.qos.logback.core.rolling;
import ch.qos.logback.core.spi.ContextAwareBase;
+
/**
* SizeBasedTriggeringPolicy looks at size of the file being
* currently written to.
@@ -23,19 +24,21 @@ import ch.qos.logback.core.spi.ContextAwareBase;
*
*/
abstract public class TriggeringPolicyBase<E> extends ContextAwareBase implements TriggeringPolicy<E> {
+
+ private boolean start;
+
+ public void start() {
+ start = true;
+ }
- private boolean start;
+ public void stop() {
+ start = false;
+ }
- public void start() {
- start = true;
- }
+ public boolean isStarted() {
+ return start;
+ }
- public void stop() {
- start = false;
- }
- public boolean isStarted() {
- return start;
- }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/ArchiveRemover.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/ArchiveRemover.java
index c5fcbab..23b0f93 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/ArchiveRemover.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/ArchiveRemover.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,7 +14,6 @@
package ch.qos.logback.core.rolling.helper;
import java.util.Date;
-import java.util.concurrent.Future;
import ch.qos.logback.core.spi.ContextAware;
@@ -24,8 +23,6 @@ import ch.qos.logback.core.spi.ContextAware;
* @author Ceki Gülcü
*/
public interface ArchiveRemover extends ContextAware {
- void clean(Date now);
- void setMaxHistory(int maxHistory);
- void setTotalSizeCap(long totalSizeCap);
- Future<?> cleanAsynchronously(Date now);
-}
\ No newline at end of file
+ void clean(Date now);
+ void setMaxHistory(int maxHistory);
+}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/AsynchronousCompressor.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/AsynchronousCompressor.java
new file mode 100644
index 0000000..3f42b60
--- /dev/null
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/AsynchronousCompressor.java
@@ -0,0 +1,36 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.core.rolling.helper;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+public class AsynchronousCompressor {
+ Compressor compressor;
+
+ public AsynchronousCompressor(Compressor compressor) {
+ this.compressor = compressor;
+ }
+
+ public Future<?> compressAsynchronously(String nameOfFile2Compress,
+ String nameOfCompressedFile, String innerEntryName) {
+ ExecutorService executor = Executors.newScheduledThreadPool(1);
+ Future<?> future = executor.submit(new CompressionRunnable(compressor,
+ nameOfFile2Compress, nameOfCompressedFile, innerEntryName));
+ executor.shutdown();
+ return future;
+ }
+
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/CompressionMode.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/CompressionMode.java
index 0ba303b..703bd38 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/CompressionMode.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/CompressionMode.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,5 +14,5 @@
package ch.qos.logback.core.rolling.helper;
public enum CompressionMode {
- NONE, GZ, ZIP;
+ NONE, GZ, ZIP;
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/CompressionRunnable.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/CompressionRunnable.java
new file mode 100644
index 0000000..77d4287
--- /dev/null
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/CompressionRunnable.java
@@ -0,0 +1,35 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.core.rolling.helper;
+
+
+public class CompressionRunnable implements Runnable {
+
+ final Compressor compressor;
+ final String nameOfFile2Compress;
+ final String nameOfCompressedFile;
+ final String innerEntryName;
+
+ public CompressionRunnable(Compressor compressor, String nameOfFile2Compress,
+ String nameOfCompressedFile, String innerEntryName) {
+ this.compressor = compressor;
+ this.nameOfFile2Compress = nameOfFile2Compress;
+ this.nameOfCompressedFile = nameOfCompressedFile;
+ this.innerEntryName = innerEntryName;
+ }
+
+ public void run() {
+ compressor.compress(nameOfFile2Compress, nameOfCompressedFile, innerEntryName);
+ }
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/Compressor.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/Compressor.java
index 044732c..4380195 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/Compressor.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/Compressor.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,8 +18,6 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -38,250 +36,242 @@ import ch.qos.logback.core.util.FileUtil;
*/
public class Compressor extends ContextAwareBase {
- final CompressionMode compressionMode;
-
- static final int BUFFER_SIZE = 8192;
-
- public Compressor(CompressionMode compressionMode) {
- this.compressionMode = compressionMode;
+ final CompressionMode compressionMode;
+
+ static final int BUFFER_SIZE = 8192;
+
+ public Compressor(CompressionMode compressionMode) {
+ this.compressionMode = compressionMode;
+ }
+
+ /**
+ * @param nameOfFile2Compress
+ * @param nameOfCompressedFile
+ * @param innerEntryName The name of the file within the zip file. Use for ZIP compression.
+ */
+ public void compress(String nameOfFile2Compress, String nameOfCompressedFile, String innerEntryName) {
+ switch (compressionMode) {
+ case GZ:
+ gzCompress(nameOfFile2Compress, nameOfCompressedFile);
+ break;
+ case ZIP:
+ zipCompress(nameOfFile2Compress, nameOfCompressedFile, innerEntryName);
+ break;
+ case NONE:
+ throw new UnsupportedOperationException(
+ "compress method called in NONE compression mode");
}
+ }
- /**
- * @param nameOfFile2Compress
- * @param nameOfCompressedFile
- * @param innerEntryName
- * The name of the file within the zip file. Use for ZIP compression.
- */
- public void compress(String nameOfFile2Compress, String nameOfCompressedFile, String innerEntryName) {
- switch (compressionMode) {
- case GZ:
- gzCompress(nameOfFile2Compress, nameOfCompressedFile);
- break;
- case ZIP:
- zipCompress(nameOfFile2Compress, nameOfCompressedFile, innerEntryName);
- break;
- case NONE:
- throw new UnsupportedOperationException("compress method called in NONE compression mode");
- }
- }
+ private void zipCompress(String nameOfFile2zip, String nameOfZippedFile, String innerEntryName) {
+ File file2zip = new File(nameOfFile2zip);
- private void zipCompress(String nameOfFile2zip, String nameOfZippedFile, String innerEntryName) {
- File file2zip = new File(nameOfFile2zip);
+ if (!file2zip.exists()) {
+ addStatus(new WarnStatus("The file to compress named [" + nameOfFile2zip
+ + "] does not exist.", this));
- if (!file2zip.exists()) {
- addStatus(new WarnStatus("The file to compress named [" + nameOfFile2zip + "] does not exist.", this));
+ return;
+ }
- return;
- }
+ if (innerEntryName == null) {
+ addStatus(new WarnStatus("The innerEntryName parameter cannot be null", this));
+ return;
+ }
- if (innerEntryName == null) {
- addStatus(new WarnStatus("The innerEntryName parameter cannot be null", this));
- return;
- }
+ if (!nameOfZippedFile.endsWith(".zip")) {
+ nameOfZippedFile = nameOfZippedFile + ".zip";
+ }
- if (!nameOfZippedFile.endsWith(".zip")) {
- nameOfZippedFile = nameOfZippedFile + ".zip";
- }
+ File zippedFile = new File(nameOfZippedFile);
- File zippedFile = new File(nameOfZippedFile);
+ if (zippedFile.exists()) {
+ addStatus(new WarnStatus("The target compressed file named ["
+ + nameOfZippedFile + "] exist already.", this));
- if (zippedFile.exists()) {
- addStatus(new WarnStatus("The target compressed file named [" + nameOfZippedFile + "] exist already.", this));
+ return;
+ }
- return;
+ addInfo("ZIP compressing [" + file2zip + "] as ["+zippedFile+"]");
+ createMissingTargetDirsIfNecessary(zippedFile);
+
+ BufferedInputStream bis = null;
+ ZipOutputStream zos = null;
+ try {
+ bis = new BufferedInputStream(new FileInputStream(nameOfFile2zip));
+ zos = new ZipOutputStream(new FileOutputStream(nameOfZippedFile));
+
+ ZipEntry zipEntry = computeZipEntry(innerEntryName);
+ zos.putNextEntry(zipEntry);
+
+ byte[] inbuf = new byte[BUFFER_SIZE];
+ int n;
+
+ while ((n = bis.read(inbuf)) != -1) {
+ zos.write(inbuf, 0, n);
+ }
+
+ bis.close();
+ bis = null;
+ zos.close();
+ zos = null;
+
+ if (!file2zip.delete()) {
+ addStatus(new WarnStatus("Could not delete [" + nameOfFile2zip + "].",
+ this));
+ }
+ } catch (Exception e) {
+ addStatus(new ErrorStatus("Error occurred while compressing ["
+ + nameOfFile2zip + "] into [" + nameOfZippedFile + "].", this, e));
+ } finally {
+ if (bis != null) {
+ try {
+ bis.close();
+ } catch (IOException e) {
+ // ignore
}
-
- addInfo("ZIP compressing [" + file2zip + "] as [" + zippedFile + "]");
- createMissingTargetDirsIfNecessary(zippedFile);
-
- BufferedInputStream bis = null;
- ZipOutputStream zos = null;
+ }
+ if (zos != null) {
try {
- bis = new BufferedInputStream(new FileInputStream(nameOfFile2zip));
- zos = new ZipOutputStream(new FileOutputStream(nameOfZippedFile));
-
- ZipEntry zipEntry = computeZipEntry(innerEntryName);
- zos.putNextEntry(zipEntry);
-
- byte[] inbuf = new byte[BUFFER_SIZE];
- int n;
-
- while ((n = bis.read(inbuf)) != -1) {
- zos.write(inbuf, 0, n);
- }
-
- bis.close();
- bis = null;
- zos.close();
- zos = null;
-
- if (!file2zip.delete()) {
- addStatus(new WarnStatus("Could not delete [" + nameOfFile2zip + "].", this));
- }
- } catch (Exception e) {
- addStatus(new ErrorStatus("Error occurred while compressing [" + nameOfFile2zip + "] into [" + nameOfZippedFile + "].", this, e));
- } finally {
- if (bis != null) {
- try {
- bis.close();
- } catch (IOException e) {
- // ignore
- }
- }
- if (zos != null) {
- try {
- zos.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ zos.close();
+ } catch (IOException e) {
+ // ignore
}
-
+ }
}
- // http://jira.qos.ch/browse/LBCORE-98
- // The name of the compressed file as nested within the zip archive
- //
- // Case 1: RawFile = null, Patern = foo-%d.zip
- // nestedFilename = foo-${current-date}
- //
- // Case 2: RawFile = hello.txt, Pattern = = foo-%d.zip
- // nestedFilename = foo-${current-date}
- //
- // in both cases, the strategy consisting of removing the compression
- // suffix of zip file works reasonably well. The alternative strategy
- // whereby the nested file name was based on the value of the raw file name
- // (applicable to case 2 only) has the disadvantage of the nested files
- // all having the same name, which could make it harder for the user
- // to unzip the file without collisions
- ZipEntry computeZipEntry(File zippedFile) {
- return computeZipEntry(zippedFile.getName());
- }
- ZipEntry computeZipEntry(String filename) {
- String nameOfFileNestedWithinArchive = computeFileNameStrWithoutCompSuffix(filename, compressionMode);
- return new ZipEntry(nameOfFileNestedWithinArchive);
+ }
+
+ // http://jira.qos.ch/browse/LBCORE-98
+ // The name of the compressed file as nested within the zip archive
+ //
+ // Case 1: RawFile = null, Patern = foo-%d.zip
+ // nestedFilename = foo-${current-date}
+ //
+ // Case 2: RawFile = hello.txt, Pattern = = foo-%d.zip
+ // nestedFilename = foo-${current-date}
+ //
+ // in both cases, the strategy consisting of removing the compression
+ // suffix of zip file works reasonably well. The alternative strategy
+ // whereby the nested file name was based on the value of the raw file name
+ // (applicable to case 2 only) has the disadvantage of the nested files
+ // all having the same name, which could make it harder for the user
+ // to unzip the file without collisions
+ ZipEntry computeZipEntry(File zippedFile) {
+ return computeZipEntry(zippedFile.getName());
+ }
+
+ ZipEntry computeZipEntry(String filename) {
+ String nameOfFileNestedWithinArchive = computeFileNameStr_WCS(filename, compressionMode);
+ return new ZipEntry(nameOfFileNestedWithinArchive);
+ }
+
+
+ private void gzCompress(String nameOfFile2gz, String nameOfgzedFile) {
+ File file2gz = new File(nameOfFile2gz);
+
+ if (!file2gz.exists()) {
+ addStatus(new WarnStatus("The file to compress named [" + nameOfFile2gz
+ + "] does not exist.", this));
+
+ return;
}
- private void gzCompress(String nameOfFile2gz, String nameOfgzedFile) {
- File file2gz = new File(nameOfFile2gz);
-
- if (!file2gz.exists()) {
- addStatus(new WarnStatus("The file to compress named [" + nameOfFile2gz + "] does not exist.", this));
-
- return;
- }
- if (!nameOfgzedFile.endsWith(".gz")) {
- nameOfgzedFile = nameOfgzedFile + ".gz";
- }
-
- File gzedFile = new File(nameOfgzedFile);
-
- if (gzedFile.exists()) {
- addWarn("The target compressed file named [" + nameOfgzedFile + "] exist already. Aborting file compression.");
- return;
- }
+ if (!nameOfgzedFile.endsWith(".gz")) {
+ nameOfgzedFile = nameOfgzedFile + ".gz";
+ }
- addInfo("GZ compressing [" + file2gz + "] as [" + gzedFile + "]");
- createMissingTargetDirsIfNecessary(gzedFile);
+ File gzedFile = new File(nameOfgzedFile);
- BufferedInputStream bis = null;
- GZIPOutputStream gzos = null;
- try {
- bis = new BufferedInputStream(new FileInputStream(nameOfFile2gz));
- gzos = new GZIPOutputStream(new FileOutputStream(nameOfgzedFile));
- byte[] inbuf = new byte[BUFFER_SIZE];
- int n;
-
- while ((n = bis.read(inbuf)) != -1) {
- gzos.write(inbuf, 0, n);
- }
-
- bis.close();
- bis = null;
- gzos.close();
- gzos = null;
-
- if (!file2gz.delete()) {
- addStatus(new WarnStatus("Could not delete [" + nameOfFile2gz + "].", this));
- }
- } catch (Exception e) {
- addStatus(new ErrorStatus("Error occurred while compressing [" + nameOfFile2gz + "] into [" + nameOfgzedFile + "].", this, e));
- } finally {
- if (bis != null) {
- try {
- bis.close();
- } catch (IOException e) {
- // ignore
- }
- }
- if (gzos != null) {
- try {
- gzos.close();
- } catch (IOException e) {
- // ignore
- }
- }
- }
+ if (gzedFile.exists()) {
+ addWarn("The target compressed file named ["
+ + nameOfgzedFile + "] exist already. Aborting file compression.");
+ return;
}
- static public String computeFileNameStrWithoutCompSuffix(String fileNamePatternStr, CompressionMode compressionMode) {
- int len = fileNamePatternStr.length();
- switch (compressionMode) {
- case GZ:
- if (fileNamePatternStr.endsWith(".gz"))
- return fileNamePatternStr.substring(0, len - 3);
- else
- return fileNamePatternStr;
- case ZIP:
- if (fileNamePatternStr.endsWith(".zip"))
- return fileNamePatternStr.substring(0, len - 4);
- else
- return fileNamePatternStr;
- case NONE:
- return fileNamePatternStr;
+ addInfo("GZ compressing [" + file2gz + "] as ["+gzedFile+"]");
+ createMissingTargetDirsIfNecessary(gzedFile);
+
+ BufferedInputStream bis = null;
+ GZIPOutputStream gzos = null;
+ try {
+ bis = new BufferedInputStream(new FileInputStream(nameOfFile2gz));
+ gzos = new GZIPOutputStream(new FileOutputStream(nameOfgzedFile));
+ byte[] inbuf = new byte[BUFFER_SIZE];
+ int n;
+
+ while ((n = bis.read(inbuf)) != -1) {
+ gzos.write(inbuf, 0, n);
+ }
+
+ bis.close();
+ bis = null;
+ gzos.close();
+ gzos = null;
+
+ if (!file2gz.delete()) {
+ addStatus(new WarnStatus("Could not delete [" + nameOfFile2gz + "].",
+ this));
+ }
+ } catch (Exception e) {
+ addStatus(new ErrorStatus("Error occurred while compressing ["
+ + nameOfFile2gz + "] into [" + nameOfgzedFile + "].", this, e));
+ } finally {
+ if (bis != null) {
+ try {
+ bis.close();
+ } catch (IOException e) {
+ // ignore
}
- throw new IllegalStateException("Execution should not reach this point");
- }
-
- void createMissingTargetDirsIfNecessary(File file) {
- boolean result = FileUtil.createMissingParentDirectories(file);
- if (!result) {
- addError("Failed to create parent directories for [" + file.getAbsolutePath() + "]");
+ }
+ if (gzos != null) {
+ try {
+ gzos.close();
+ } catch (IOException e) {
+ // ignore
}
+ }
}
-
- @Override
- public String toString() {
- return this.getClass().getName();
+ }
+
+ static public String computeFileNameStr_WCS(String fileNamePatternStr,
+ CompressionMode compressionMode) {
+ int len = fileNamePatternStr.length();
+ switch (compressionMode) {
+ case GZ:
+ if (fileNamePatternStr.endsWith(".gz"))
+ return fileNamePatternStr.substring(0, len - 3);
+ else
+ return fileNamePatternStr;
+ case ZIP:
+ if (fileNamePatternStr.endsWith(".zip"))
+ return fileNamePatternStr.substring(0, len - 4);
+ else
+ return fileNamePatternStr;
+ case NONE:
+ return fileNamePatternStr;
}
-
-
- public Future<?> asyncCompress(String nameOfFile2Compress, String nameOfCompressedFile, String innerEntryName) throws RolloverFailure {
- CompressionRunnable runnable = new CompressionRunnable(nameOfFile2Compress, nameOfCompressedFile, innerEntryName);
- ExecutorService executorService = context.getScheduledExecutorService();
- Future<?> future = executorService.submit(runnable);
- return future;
+ throw new IllegalStateException("Execution should not reach this point");
+ }
+
+
+ void createMissingTargetDirsIfNecessary(File file) {
+ if (FileUtil.isParentDirectoryCreationRequired(file)) {
+ boolean result = FileUtil.createMissingParentDirectories(file);
+ if (!result) {
+ addError("Failed to create parent directories for ["
+ + file.getAbsolutePath() + "]");
+ } else {
+ addInfo("Created missing parent directories for ["
+ + file.getAbsolutePath() + "]");
+ }
}
+ }
+ @Override
+ public String toString() {
+ return this.getClass().getName();
+ }
- class CompressionRunnable implements Runnable {
- final String nameOfFile2Compress;
- final String nameOfCompressedFile;
- final String innerEntryName;
-
- public CompressionRunnable(String nameOfFile2Compress, String nameOfCompressedFile, String innerEntryName) {
- this.nameOfFile2Compress = nameOfFile2Compress;
- this.nameOfCompressedFile = nameOfCompressedFile;
- this.innerEntryName = innerEntryName;
- }
-
- public void run() {
-
- Compressor.this.compress(nameOfFile2Compress, nameOfCompressedFile, innerEntryName);
- }
- }
-
-
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DateTokenConverter.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DateTokenConverter.java
index da51088..6949c27 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DateTokenConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DateTokenConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,7 +15,6 @@ package ch.qos.logback.core.rolling.helper;
import java.util.Date;
import java.util.List;
-import java.util.TimeZone;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.pattern.DynamicConverter;
@@ -25,83 +24,69 @@ import ch.qos.logback.core.util.DatePatternToRegexUtil;
/**
* Returns a date formatted by SimpleDateFormatter.
*
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class DateTokenConverter<E> extends DynamicConverter<E> implements MonoTypedConverter {
- /**
- * The conversion word/character with which this converter is registered.
- */
- public final static String CONVERTER_KEY = "d";
- public final static String AUXILIARY_TOKEN = "AUX";
- public static final String DEFAULT_DATE_PATTERN = CoreConstants.DAILY_DATE_PATTERN;
+ /**
+ * The conversion word/character with which this converter is registered.
+ */
+ public final static String CONVERTER_KEY = "d";
+ public final static String AUXILIARY_TOKEN = "AUX";
+ public static final String DEFAULT_DATE_PATTERN = CoreConstants.DAILY_DATE_PATTERN;
- private String datePattern;
- private TimeZone timeZone;
- private CachingDateFormatter cdf;
- // is this token converter primary or auxiliary? Only the primary converter
- // determines the rolling period
- private boolean primary = true;
-
- public void start() {
- this.datePattern = getFirstOption();
- if (this.datePattern == null) {
- this.datePattern = DEFAULT_DATE_PATTERN;
- }
-
- final List<String> optionList = getOptionList();
- if (optionList != null) {
- for (int optionIndex = 1; optionIndex < optionList.size(); optionIndex++) {
- String option = optionList.get(optionIndex);
- if (AUXILIARY_TOKEN.equalsIgnoreCase(option)) {
- primary = false;
- } else {
- timeZone = TimeZone.getTimeZone(option);
- }
- }
- }
-
- cdf = new CachingDateFormatter(datePattern);
- if (timeZone != null) {
- cdf.setTimeZone(timeZone);
- }
+ private String datePattern;
+ private CachingDateFormatter cdf;
+ // is this token converter primary or auxiliary? Only the primary converter
+ // determines the rolling period
+ private boolean primary = true;
+ public void start() {
+ this.datePattern = getFirstOption();
+ if (this.datePattern == null) {
+ this.datePattern = DEFAULT_DATE_PATTERN;
}
- public String convert(Date date) {
- return cdf.format(date.getTime());
+ final List<String> optionList = getOptionList();
+ if(optionList != null && optionList.size()> 1) {
+ String secondOption = optionList.get(1);
+ if(AUXILIARY_TOKEN.equalsIgnoreCase(secondOption)) {
+ primary = false;
+ }
}
+ cdf = new CachingDateFormatter(datePattern);
+ }
- public String convert(Object o) {
- if (o == null) {
- throw new IllegalArgumentException("Null argument forbidden");
- }
- if (o instanceof Date) {
- return convert((Date) o);
- }
- throw new IllegalArgumentException("Cannot convert " + o + " of type" + o.getClass().getName());
- }
+ public String convert(Date date) {
+ return cdf.format(date.getTime());
+ }
- /**
- * Return the date pattern.
- */
- public String getDatePattern() {
- return datePattern;
+ public String convert(Object o) {
+ if (o == null) {
+ throw new IllegalArgumentException("Null argument forbidden");
}
+ if (o instanceof Date) {
+ return convert((Date) o);
+ }
+ throw new IllegalArgumentException("Cannot convert "+o+" of type"+o.getClass().getName());
+ }
- public TimeZone getTimeZone() {
- return timeZone;
- }
+ /**
+ * Return the date pattern.
+ */
+ public String getDatePattern() {
+ return datePattern;
+ }
- public boolean isApplicable(Object o) {
- return (o instanceof Date);
- }
+ public boolean isApplicable(Object o) {
+ return (o instanceof Date);
+ }
- public String toRegex() {
- DatePatternToRegexUtil datePatternToRegexUtil = new DatePatternToRegexUtil(datePattern);
- return datePatternToRegexUtil.toRegex();
- }
+ public String toRegex() {
+ DatePatternToRegexUtil datePatternToRegexUtil = new DatePatternToRegexUtil(datePattern);
+ return datePatternToRegexUtil.toRegex();
+ }
- public boolean isPrimary() {
- return primary;
- }
+ public boolean isPrimary() {
+ return primary;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DefaultArchiveRemover.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DefaultArchiveRemover.java
new file mode 100644
index 0000000..7b10dd7
--- /dev/null
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DefaultArchiveRemover.java
@@ -0,0 +1,138 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.core.rolling.helper;
+
+import java.io.File;
+import java.util.Date;
+
+import ch.qos.logback.core.CoreConstants;
+import ch.qos.logback.core.pattern.Converter;
+import ch.qos.logback.core.pattern.LiteralConverter;
+import ch.qos.logback.core.spi.ContextAwareBase;
+
+abstract public class DefaultArchiveRemover extends ContextAwareBase implements
+ ArchiveRemover {
+
+ static protected final long UNINITIALIZED = -1;
+ // aim for 64 days, except in case of hourly rollover
+ static protected final long INACTIVITY_TOLERANCE_IN_MILLIS = 64L * (long) CoreConstants.MILLIS_IN_ONE_DAY;
+ static final int MAX_VALUE_FOR_INACTIVITY_PERIODS = 14 * 24; // 14 days in case of hourly rollover
+
+ final FileNamePattern fileNamePattern;
+ final RollingCalendar rc;
+ int periodOffsetForDeletionTarget;
+ final boolean parentClean;
+ long lastHeartBeat = UNINITIALIZED;
+
+ public DefaultArchiveRemover(FileNamePattern fileNamePattern,
+ RollingCalendar rc) {
+ this.fileNamePattern = fileNamePattern;
+ this.rc = rc;
+ this.parentClean = computeParentCleaningFlag(fileNamePattern);
+ }
+
+
+ int computeElapsedPeriodsSinceLastClean(long nowInMillis) {
+ long periodsElapsed = 0;
+ if (lastHeartBeat == UNINITIALIZED) {
+ addInfo("first clean up after appender initialization");
+ periodsElapsed = rc.periodsElapsed(nowInMillis, nowInMillis + INACTIVITY_TOLERANCE_IN_MILLIS);
+ if (periodsElapsed > MAX_VALUE_FOR_INACTIVITY_PERIODS)
+ periodsElapsed = MAX_VALUE_FOR_INACTIVITY_PERIODS;
+ } else {
+ periodsElapsed = rc.periodsElapsed(lastHeartBeat, nowInMillis);
+ if (periodsElapsed < 1) {
+ addWarn("Unexpected periodsElapsed value " + periodsElapsed);
+ periodsElapsed = 1;
+ }
+ }
+ return (int) periodsElapsed;
+ }
+
+ public void clean(Date now) {
+ long nowInMillis = now.getTime();
+ int periodsElapsed = computeElapsedPeriodsSinceLastClean(nowInMillis);
+ lastHeartBeat = nowInMillis;
+ if (periodsElapsed > 1) {
+ addInfo("periodsElapsed = " + periodsElapsed);
+ }
+ for (int i = 0; i < periodsElapsed; i++) {
+ cleanByPeriodOffset(now, periodOffsetForDeletionTarget - i);
+ }
+ }
+
+ abstract void cleanByPeriodOffset(Date now, int periodOffset);
+
+ boolean computeParentCleaningFlag(FileNamePattern fileNamePattern) {
+ DateTokenConverter dtc = fileNamePattern.getPrimaryDateTokenConverter();
+ // if the date pattern has a /, then we need parent cleaning
+ if (dtc.getDatePattern().indexOf('/') != -1) {
+ return true;
+ }
+ // if the literal string subsequent to the dtc contains a /, we also
+ // need parent cleaning
+
+ Converter<Object> p = fileNamePattern.headTokenConverter;
+
+ // find the date converter
+ while (p != null) {
+ if (p instanceof DateTokenConverter) {
+ break;
+ }
+ p = p.getNext();
+ }
+
+ while (p != null) {
+ if (p instanceof LiteralConverter) {
+ String s = p.convert(null);
+ if (s.indexOf('/') != -1) {
+ return true;
+ }
+ }
+ p = p.getNext();
+ }
+
+ // no /, so we don't need parent cleaning
+ return false;
+ }
+
+ void removeFolderIfEmpty(File dir) {
+ removeFolderIfEmpty(dir, 0);
+ }
+
+ /**
+ * Will remove the directory passed as parameter if empty. After that, if the
+ * parent is also becomes empty, remove the parent dir as well but at most 3
+ * times.
+ *
+ * @param dir
+ * @param depth
+ */
+ private void removeFolderIfEmpty(File dir, int depth) {
+ // we should never go more than 3 levels higher
+ if (depth >= 3) {
+ return;
+ }
+ if (dir.isDirectory() && FileFilterUtil.isEmptyDirectory(dir)) {
+ addInfo("deleting folder [" + dir + "]");
+ dir.delete();
+ removeFolderIfEmpty(dir.getParentFile(), depth + 1);
+ }
+ }
+
+ public void setMaxHistory(int maxHistory) {
+ this.periodOffsetForDeletionTarget = -maxHistory - 1;
+ }
+
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileFilterUtil.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileFilterUtil.java
index 4ff32e3..32119a5 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileFilterUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileFilterUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,105 +22,108 @@ import java.util.regex.Pattern;
public class FileFilterUtil {
- public static void sortFileArrayByName(File[] fileArray) {
- Arrays.sort(fileArray, new Comparator<File>() {
- public int compare(File o1, File o2) {
- String o1Name = o1.getName();
- String o2Name = o2.getName();
- return (o1Name.compareTo(o2Name));
- }
- });
- }
+ public static void sortFileArrayByName(File[] fileArray) {
+ Arrays.sort(fileArray, new Comparator<File>() {
+ public int compare(File o1, File o2) {
+ String o1Name = o1.getName();
+ String o2Name = o2.getName();
+ return (o1Name.compareTo(o2Name));
+ }
+ });
+ }
- public static void reverseSortFileArrayByName(File[] fileArray) {
- Arrays.sort(fileArray, new Comparator<File>() {
- public int compare(File o1, File o2) {
- String o1Name = o1.getName();
- String o2Name = o2.getName();
- return (o2Name.compareTo(o1Name));
- }
- });
- }
+ public static void reverseSortFileArrayByName(File[] fileArray) {
+ Arrays.sort(fileArray, new Comparator<File>() {
+ public int compare(File o1, File o2) {
+ String o1Name = o1.getName();
+ String o2Name = o2.getName();
+ return (o2Name.compareTo(o1Name));
+ }
+ });
+ }
- public static String afterLastSlash(String sregex) {
- int i = sregex.lastIndexOf('/');
- if (i == -1) {
- return sregex;
- } else {
- return sregex.substring(i + 1);
- }
+ public static String afterLastSlash(String sregex) {
+ int i = sregex.lastIndexOf('/');
+ if (i == -1) {
+ return sregex;
+ } else {
+ return sregex.substring(i + 1);
}
+ }
- static public boolean isEmptyDirectory(File dir) {
- if (!dir.isDirectory()) {
- throw new IllegalArgumentException("[" + dir + "] must be a directory");
- }
- String[] filesInDir = dir.list();
- if (filesInDir == null || filesInDir.length == 0) {
- return true;
- } else {
- return false;
- }
+ static public boolean isEmptyDirectory(File dir) {
+ if (!dir.isDirectory()) {
+ throw new IllegalArgumentException("[" + dir + "] must be a directory");
+ }
+ String[] filesInDir = dir.list();
+ if (filesInDir == null || filesInDir.length == 0) {
+ return true;
+ } else {
+ return false;
}
+ }
- /**
- * Return the set of files matching the stemRegex as found in 'directory'. A
- * stemRegex does not contain any slash characters or any folder separators.
- *
- * @param file
- * @param stemRegex
- * @return
- */
- public static File[] filesInFolderMatchingStemRegex(File file, final String stemRegex) {
+ /**
+ * Return the set of files matching the stemRegex as found in 'directory'. A
+ * stemRegex does not contain any slash characters or any folder separators.
+ *
+ * @param file
+ * @param stemRegex
+ * @return
+ */
+ public static File[] filesInFolderMatchingStemRegex(File file,
+ final String stemRegex) {
- if (file == null) {
- return new File[0];
- }
- if (!file.exists() || !file.isDirectory()) {
- return new File[0];
- }
- return file.listFiles(new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.matches(stemRegex);
- }
- });
+ if (file == null) {
+ return new File[0];
}
+ if (!file.exists() || !file.isDirectory()) {
+ return new File[0];
+ }
+ return file.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.matches(stemRegex);
+ }
+ });
+ }
- static public int findHighestCounter(File[] matchingFileArray, final String stemRegex) {
- int max = Integer.MIN_VALUE;
- for (File aFile : matchingFileArray) {
- int aCounter = FileFilterUtil.extractCounter(aFile, stemRegex);
- if (max < aCounter)
- max = aCounter;
- }
- return max;
+ static public int findHighestCounter(File[] matchingFileArray, final String stemRegex) {
+ int max = Integer.MIN_VALUE;
+ for (File aFile : matchingFileArray) {
+ int aCounter = FileFilterUtil.extractCounter(aFile, stemRegex);
+ if (max < aCounter)
+ max = aCounter;
}
+ return max;
+ }
- static public int extractCounter(File file, final String stemRegex) {
- Pattern p = Pattern.compile(stemRegex);
- String lastFileName = file.getName();
+ static public int extractCounter(File file, final String stemRegex) {
+ Pattern p = Pattern.compile(stemRegex);
+ String lastFileName = file.getName();
- Matcher m = p.matcher(lastFileName);
- if (!m.matches()) {
- throw new IllegalStateException("The regex [" + stemRegex + "] should match [" + lastFileName + "]");
- }
- String counterAsStr = m.group(1);
- return new Integer(counterAsStr).intValue();
+ Matcher m = p.matcher(lastFileName);
+ if (!m.matches()) {
+ throw new IllegalStateException("The regex [" + stemRegex
+ + "] should match [" + lastFileName + "]");
}
+ String counterAsStr = m.group(1);
+ return new Integer(counterAsStr).intValue();
+ }
- public static String slashify(String in) {
- return in.replace('\\', '/');
- }
+ public static String slashify(String in) {
+ return in.replace('\\', '/');
+ }
- public static void removeEmptyParentDirectories(File file, int recursivityCount) {
- // we should never go more than 3 levels higher
- if (recursivityCount >= 3) {
- return;
- }
- File parent = file.getParentFile();
- if (parent.isDirectory() && FileFilterUtil.isEmptyDirectory(parent)) {
- parent.delete();
- removeEmptyParentDirectories(parent, recursivityCount + 1);
- }
+ public static void removeEmptyParentDirectories(File file,
+ int recursivityCount) {
+ // we should never go more than 3 levels higher
+ if (recursivityCount >= 3) {
+ return;
+ }
+ File parent = file.getParentFile();
+ if (parent.isDirectory() && FileFilterUtil.isEmptyDirectory(parent)) {
+ parent.delete();
+ removeEmptyParentDirectories(parent, recursivityCount + 1);
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java
index d3af779..06b40db 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,201 +30,170 @@ import ch.qos.logback.core.spi.ContextAwareBase;
/**
* After parsing file name patterns, given a number or a date, instances of this
* class can be used to compute a file name according to the file name pattern
- * and the current date or integer.
+ * and the given integer or date.
*
* @author Ceki Gülcü
*
*/
public class FileNamePattern extends ContextAwareBase {
- static final Map<String, String> CONVERTER_MAP = new HashMap<String, String>();
- static {
- CONVERTER_MAP.put(IntegerTokenConverter.CONVERTER_KEY, IntegerTokenConverter.class.getName());
- CONVERTER_MAP.put(DateTokenConverter.CONVERTER_KEY, DateTokenConverter.class.getName());
- }
-
- String pattern;
- Converter<Object> headTokenConverter;
-
- public FileNamePattern(String patternArg, Context contextArg) {
- // the pattern is slashified
- setPattern(FileFilterUtil.slashify(patternArg));
- setContext(contextArg);
- parse();
- ConverterUtil.startConverters(this.headTokenConverter);
- }
-
-
- void parse() {
- try {
- // http://jira.qos.ch/browse/LOGBACK-197
- // we escape ')' for parsing purposes. Note that the original pattern is preserved
- // because it is shown to the user in status messages. We don't want the escaped version
- // to leak out.
- String patternForParsing = escapeRightParantesis(pattern);
- Parser<Object> p = new Parser<Object>(patternForParsing, new AlmostAsIsEscapeUtil());
- p.setContext(context);
- Node t = p.parse();
- this.headTokenConverter = p.compile(t, CONVERTER_MAP);
-
- } catch (ScanException sce) {
- addError("Failed to parse pattern \"" + pattern + "\".", sce);
- }
- }
-
- String escapeRightParantesis(String in) {
- return pattern.replace(")", "\\)");
- }
-
- public String toString() {
- return pattern;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((pattern == null) ? 0 : pattern.hashCode());
- return result;
- }
-
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- FileNamePattern other = (FileNamePattern) obj;
- if (pattern == null) {
- if (other.pattern != null)
- return false;
- } else if (!pattern.equals(other.pattern))
- return false;
- return true;
- }
-
-
- public DateTokenConverter<Object> getPrimaryDateTokenConverter() {
- Converter<Object> p = headTokenConverter;
-
- while (p != null) {
- if (p instanceof DateTokenConverter) {
- DateTokenConverter<Object> dtc = (DateTokenConverter<Object>) p;
- // only primary converters should be returned as
- if (dtc.isPrimary())
- return dtc;
- }
-
- p = p.getNext();
+ static final Map<String, String> CONVERTER_MAP = new HashMap<String, String>();
+ static {
+ CONVERTER_MAP.put(IntegerTokenConverter.CONVERTER_KEY,
+ IntegerTokenConverter.class.getName());
+ CONVERTER_MAP.put(DateTokenConverter.CONVERTER_KEY,
+ DateTokenConverter.class.getName());
+ }
+
+ String pattern;
+ Converter<Object> headTokenConverter;
+
+ public FileNamePattern(String patternArg, Context contextArg) {
+ // the pattern is slashified
+ setPattern(FileFilterUtil.slashify(patternArg));
+ setContext(contextArg);
+ parse();
+ ConverterUtil.startConverters(this.headTokenConverter);
+ }
+
+ void parse() {
+ try {
+ // http://jira.qos.ch/browse/LBCORE-130
+ // we escape ')' for parsing purposes. Note that the original pattern is preserved
+ // because it is shown to the user in status messages. We don't want the escaped version
+ // to leak out.
+ String patternForParsing = escapeRightParantesis(pattern);
+ Parser<Object> p = new Parser<Object>(patternForParsing, new AlmostAsIsEscapeUtil());
+ p.setContext(context);
+ Node t = p.parse();
+ this.headTokenConverter = p.compile(t, CONVERTER_MAP);
+
+ } catch (ScanException sce) {
+ addError("Failed to parse pattern \"" + pattern + "\".", sce);
+ }
+ }
+
+ String escapeRightParantesis(String in) {
+ return pattern.replace(")", "\\)");
+ }
+
+ public String toString() {
+ return pattern;
+ }
+
+ public DateTokenConverter getPrimaryDateTokenConverter() {
+ Converter p = headTokenConverter;
+
+ while (p != null) {
+ if (p instanceof DateTokenConverter) {
+ DateTokenConverter dtc = (DateTokenConverter) p;
+ // only primary converters should be returned as
+ if(dtc.isPrimary())
+ return dtc;
+ }
+
+ p = p.getNext();
+ }
+
+ return null;
+ }
+
+ public IntegerTokenConverter getIntegerTokenConverter() {
+ Converter p = headTokenConverter;
+
+ while (p != null) {
+ if (p instanceof IntegerTokenConverter) {
+ return (IntegerTokenConverter) p;
+ }
+
+ p = p.getNext();
+ }
+ return null;
+ }
+
+ public String convertMultipleArguments(Object... objectList) {
+ StringBuilder buf = new StringBuilder();
+ Converter<Object> c = headTokenConverter;
+ while (c != null) {
+ if (c instanceof MonoTypedConverter) {
+ MonoTypedConverter monoTyped = (MonoTypedConverter) c;
+ for (Object o : objectList) {
+ if (monoTyped.isApplicable(o)) {
+ buf.append(c.convert(o));
+ }
}
-
- return null;
- }
-
- public IntegerTokenConverter getIntegerTokenConverter() {
- Converter<Object> p = headTokenConverter;
-
- while (p != null) {
- if (p instanceof IntegerTokenConverter) {
- return (IntegerTokenConverter) p;
- }
-
- p = p.getNext();
- }
- return null;
- }
-
- public boolean hasIntegerTokenCOnverter() {
- IntegerTokenConverter itc = getIntegerTokenConverter();
- return itc != null;
- }
-
- public String convertMultipleArguments(Object... objectList) {
- StringBuilder buf = new StringBuilder();
- Converter<Object> c = headTokenConverter;
- while (c != null) {
- if (c instanceof MonoTypedConverter) {
- MonoTypedConverter monoTyped = (MonoTypedConverter) c;
- for (Object o : objectList) {
- if (monoTyped.isApplicable(o)) {
- buf.append(c.convert(o));
- }
- }
- } else {
- buf.append(c.convert(objectList));
- }
- c = c.getNext();
- }
- return buf.toString();
- }
-
- public String convert(Object o) {
- StringBuilder buf = new StringBuilder();
- Converter<Object> p = headTokenConverter;
- while (p != null) {
- buf.append(p.convert(o));
- p = p.getNext();
- }
- return buf.toString();
- }
-
- public String convertInt(int i) {
- return convert(i);
- }
-
- public void setPattern(String pattern) {
- if (pattern != null) {
- // Trailing spaces in the pattern are assumed to be undesired.
- this.pattern = pattern.trim();
- }
- }
-
- public String getPattern() {
- return pattern;
- }
-
- /**
- * Given date, convert this instance to a regular expression.
- *
- * Used to compute sub-regex when the pattern has both %d and %i, and the
- * date is known.
- */
- public String toRegexForFixedDate(Date date) {
- StringBuilder buf = new StringBuilder();
- Converter<Object> p = headTokenConverter;
- while (p != null) {
- if (p instanceof LiteralConverter) {
- buf.append(p.convert(null));
- } else if (p instanceof IntegerTokenConverter) {
- buf.append("(\\d{1,3})");
- } else if (p instanceof DateTokenConverter) {
- buf.append(p.convert(date));
- }
- p = p.getNext();
- }
- return buf.toString();
- }
-
- /**
- * Given date, convert this instance to a regular expression
- */
- public String toRegex() {
- StringBuilder buf = new StringBuilder();
- Converter<Object> p = headTokenConverter;
- while (p != null) {
- if (p instanceof LiteralConverter) {
- buf.append(p.convert(null));
- } else if (p instanceof IntegerTokenConverter) {
- buf.append("\\d{1,2}");
- } else if (p instanceof DateTokenConverter) {
- DateTokenConverter<Object> dtc = (DateTokenConverter<Object>) p;
- buf.append(dtc.toRegex());
- }
- p = p.getNext();
- }
- return buf.toString();
- }
+ } else {
+ buf.append(c.convert(objectList));
+ }
+ c = c.getNext();
+ }
+ return buf.toString();
+ }
+
+ public String convert(Object o) {
+ StringBuilder buf = new StringBuilder();
+ Converter<Object> p = headTokenConverter;
+ while (p != null) {
+ buf.append(p.convert(o));
+ p = p.getNext();
+ }
+ return buf.toString();
+ }
+
+ public String convertInt(int i) {
+ return convert(i);
+ }
+
+ public void setPattern(String pattern) {
+ if (pattern != null) {
+ // Trailing spaces in the pattern are assumed to be undesired.
+ this.pattern = pattern.trim();
+ }
+ }
+
+ public String getPattern() {
+ return pattern;
+ }
+
+ /**
+ * Given date, convert this instance to a regular expression.
+ *
+ * Used to compute sub-regex when the pattern has both %d and %i, and the
+ * date is known.
+ */
+ public String toRegexForFixedDate(Date date) {
+ StringBuilder buf = new StringBuilder();
+ Converter<Object> p = headTokenConverter;
+ while (p != null) {
+ if (p instanceof LiteralConverter) {
+ buf.append(p.convert(null));
+ } else if (p instanceof IntegerTokenConverter) {
+ buf.append("(\\d{1,3})");
+ } else if (p instanceof DateTokenConverter) {
+ buf.append(p.convert(date));
+ }
+ p = p.getNext();
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Given date, convert this instance to a regular expression
+ */
+ public String toRegex() {
+ StringBuilder buf = new StringBuilder();
+ Converter<Object> p = headTokenConverter;
+ while (p != null) {
+ if (p instanceof LiteralConverter) {
+ buf.append(p.convert(null));
+ } else if (p instanceof IntegerTokenConverter) {
+ buf.append("\\d{1,2}");
+ } else if (p instanceof DateTokenConverter) {
+ DateTokenConverter<Object> dtc = (DateTokenConverter<Object>) p;
+ buf.append(dtc.toRegex());
+ }
+ p = p.getNext();
+ }
+ return buf.toString();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileStoreUtil.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileStoreUtil.java
index f426e26..5a2a68d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileStoreUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileStoreUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,49 +26,50 @@ import java.lang.reflect.Method;
*/
public class FileStoreUtil {
- static final String PATH_CLASS_STR = "java.nio.file.Path";
- static final String FILES_CLASS_STR = "java.nio.file.Files";
+ static final String PATH_CLASS_STR = "java.nio.file.Path";
+ static final String FILES_CLASS_STR = "java.nio.file.Files";
- /**
- * This method assumes that both files a and b exists.
- *
- * @param a
- * @param b
- * @return
- * @throws Exception
- */
- static public boolean areOnSameFileStore(File a, File b) throws RolloverFailure {
- if (!a.exists()) {
- throw new IllegalArgumentException("File [" + a + "] does not exist.");
- }
- if (!b.exists()) {
- throw new IllegalArgumentException("File [" + b + "] does not exist.");
- }
+ /**
+ * This method assumes that both files a and b exists.
+ *
+ * @param a
+ * @param b
+ * @return
+ * @throws Exception
+ */
+ static public boolean areOnSameFileStore(File a, File b) throws RolloverFailure {
+ if (!a.exists()) {
+ throw new IllegalArgumentException("File [" + a + "] does not exist.");
+ }
+ if (!b.exists()) {
+ throw new IllegalArgumentException("File [" + b + "] does not exist.");
+ }
+
+// Implements the following by reflection
+// Path pathA = a.toPath();
+// Path pathB = b.toPath();
+//
+// FileStore fileStoreA = Files.getFileStore(pathA);
+// FileStore fileStoreB = Files.getFileStore(pathB);
+//
+// return fileStoreA.equals(fileStoreB);
- // Implements the following by reflection
- // Path pathA = a.toPath();
- // Path pathB = b.toPath();
- //
- // FileStore fileStoreA = Files.getFileStore(pathA);
- // FileStore fileStoreB = Files.getFileStore(pathB);
- //
- // return fileStoreA.equals(fileStoreB);
+ try {
+ Class<?> pathClass = Class.forName(PATH_CLASS_STR);
+ Class<?> filesClass = Class.forName(FILES_CLASS_STR);
- try {
- Class<?> pathClass = Class.forName(PATH_CLASS_STR);
- Class<?> filesClass = Class.forName(FILES_CLASS_STR);
+ Method toPath = File.class.getMethod("toPath");
+ Method getFileStoreMethod = filesClass.getMethod("getFileStore", pathClass);
- Method toPath = File.class.getMethod("toPath");
- Method getFileStoreMethod = filesClass.getMethod("getFileStore", pathClass);
- Object pathA = toPath.invoke(a);
- Object pathB = toPath.invoke(b);
+ Object pathA = toPath.invoke(a);
+ Object pathB = toPath.invoke(b);
- Object fileStoreA = getFileStoreMethod.invoke(null, pathA);
- Object fileStoreB = getFileStoreMethod.invoke(null, pathB);
- return fileStoreA.equals(fileStoreB);
- } catch (Exception e) {
- throw new RolloverFailure("Failed to check file store equality for [" + a + "] and [" + b + "]", e);
- }
+ Object fileStoreA = getFileStoreMethod.invoke(null, pathA);
+ Object fileStoreB = getFileStoreMethod.invoke(null, pathB);
+ return fileStoreA.equals(fileStoreB);
+ } catch (Exception e) {
+ throw new RolloverFailure("Failed to check file store equality for [" + a + "] and [" + b + "]", e);
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/IntegerTokenConverter.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/IntegerTokenConverter.java
index f04043b..1cf1736 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/IntegerTokenConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/IntegerTokenConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,26 +21,26 @@ import ch.qos.logback.core.pattern.DynamicConverter;
*
* @author Ceki Gulcu
*/
-public class IntegerTokenConverter extends DynamicConverter<Object> implements MonoTypedConverter {
+public class IntegerTokenConverter extends DynamicConverter implements MonoTypedConverter {
- public final static String CONVERTER_KEY = "i";
+ public final static String CONVERTER_KEY = "i";
+
+ public String convert(int i) {
+ return Integer.toString(i);
+ }
- public String convert(int i) {
- return Integer.toString(i);
+ public String convert(Object o) {
+ if(o == null) {
+ throw new IllegalArgumentException("Null argument forbidden");
}
+ if(o instanceof Integer) {
+ Integer i = (Integer) o;
+ return convert(i.intValue());
+ }
+ throw new IllegalArgumentException("Cannot convert "+o+" of type"+o.getClass().getName());
+ }
- public String convert(Object o) {
- if (o == null) {
- throw new IllegalArgumentException("Null argument forbidden");
- }
- if (o instanceof Integer) {
- Integer i = (Integer) o;
- return convert(i.intValue());
- }
- throw new IllegalArgumentException("Cannot convert " + o + " of type" + o.getClass().getName());
- }
-
- public boolean isApplicable(Object o) {
- return (o instanceof Integer);
- }
+ public boolean isApplicable(Object o) {
+ return (o instanceof Integer);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/MonoTypedConverter.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/MonoTypedConverter.java
index 3fcf235..f7e752d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/MonoTypedConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/MonoTypedConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,9 +16,9 @@ package ch.qos.logback.core.rolling.helper;
/**
* Converters which can deal only with one type should implement this interface.
*
- * @author Ceki Gülcü
+ * @author Ceki G&ulcu;lcü
*
*/
public interface MonoTypedConverter {
- boolean isApplicable(Object o);
+ boolean isApplicable(Object o);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/PeriodicityType.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/PeriodicityType.java
index de8371f..ac8c40e 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/PeriodicityType.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/PeriodicityType.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,11 +15,14 @@ package ch.qos.logback.core.rolling.helper;
public enum PeriodicityType {
- ERRONEOUS, TOP_OF_MILLISECOND, TOP_OF_SECOND, TOP_OF_MINUTE, TOP_OF_HOUR, HALF_DAY, TOP_OF_DAY, TOP_OF_WEEK, TOP_OF_MONTH;
+ ERRONEOUS, TOP_OF_MILLISECOND, TOP_OF_SECOND, TOP_OF_MINUTE, TOP_OF_HOUR, HALF_DAY, TOP_OF_DAY, TOP_OF_WEEK, TOP_OF_MONTH;
- // The followed list consists of valid periodicy types in increasing period
- // lengths
- static PeriodicityType[] VALID_ORDERED_LIST = new PeriodicityType[] { TOP_OF_MILLISECOND, PeriodicityType.TOP_OF_SECOND, PeriodicityType.TOP_OF_MINUTE,
- PeriodicityType.TOP_OF_HOUR, PeriodicityType.TOP_OF_DAY, PeriodicityType.TOP_OF_WEEK, PeriodicityType.TOP_OF_MONTH };
+ // The followed list consists of valid periodicy types in increasing period
+ // lengths
+ static PeriodicityType[] VALID_ORDERED_LIST = new PeriodicityType[] {
+ TOP_OF_MILLISECOND, PeriodicityType.TOP_OF_SECOND,
+ PeriodicityType.TOP_OF_MINUTE, PeriodicityType.TOP_OF_HOUR,
+ PeriodicityType.TOP_OF_DAY, PeriodicityType.TOP_OF_WEEK,
+ PeriodicityType.TOP_OF_MONTH };
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/RenameUtil.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/RenameUtil.java
index 77ee6df..f38a625 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/RenameUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/RenameUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,7 +13,13 @@
*/
package ch.qos.logback.core.rolling.helper;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.rolling.RollingFileAppender;
@@ -22,6 +28,7 @@ import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.util.EnvUtil;
import ch.qos.logback.core.util.FileUtil;
+
/**
* Utility class to help solving problems encountered while renaming files.
*
@@ -29,105 +36,100 @@ import ch.qos.logback.core.util.FileUtil;
*/
public class RenameUtil extends ContextAwareBase {
- static String RENAMING_ERROR_URL = CoreConstants.CODES_URL + "#renamingError";
-
- /**
- * A relatively robust file renaming method which in case of failure due to
- * src and target being on different volumes, falls back onto
- * renaming by copying.
- *
- * @param src
- * @param target
- * @throws RolloverFailure
- */
- public void rename(String src, String target) throws RolloverFailure {
- if (src.equals(target)) {
- addWarn("Source and target files are the same [" + src + "]. Skipping.");
- return;
- }
- File srcFile = new File(src);
-
- if (srcFile.exists()) {
- File targetFile = new File(target);
- createMissingTargetDirsIfNecessary(targetFile);
-
- addInfo("Renaming file [" + srcFile + "] to [" + targetFile + "]");
-
- boolean result = srcFile.renameTo(targetFile);
-
- if (!result) {
- addWarn("Failed to rename file [" + srcFile + "] as [" + targetFile + "].");
- Boolean areOnDifferentVolumes = areOnDifferentVolumes(srcFile, targetFile);
- if (Boolean.TRUE.equals(areOnDifferentVolumes)) {
- addWarn("Detected different file systems for source [" + src + "] and target [" + target + "]. Attempting rename by copying.");
- renameByCopying(src, target);
- return;
- } else {
- addWarn("Please consider leaving the [file] option of " + RollingFileAppender.class.getSimpleName() + " empty.");
- addWarn("See also " + RENAMING_ERROR_URL);
- }
- }
- } else {
- throw new RolloverFailure("File [" + src + "] does not exist.");
- }
+ static String RENAMING_ERROR_URL = CoreConstants.CODES_URL + "#renamingError";
+
+ /**
+ * A relatively robust file renaming method which in case of failure due to
+ * src and target being on different volumes, falls back onto
+ * renaming by copying.
+ *
+ * @param src
+ * @param target
+ * @throws RolloverFailure
+ */
+ public void rename(String src, String target) throws RolloverFailure {
+ if (src.equals(target)) {
+ addWarn("Source and target files are the same [" + src + "]. Skipping.");
+ return;
}
+ File srcFile = new File(src);
-
-
- /**
- * Attempts to determine whether both files are on different volumes. Returns true if we could determine that
- * the files are on different volumes. Returns false otherwise or if an error occurred while doing the check.
- *
- * @param srcFile
- * @param targetFile
- * @return true if on different volumes, false otherwise or if an error occurred
- */
- Boolean areOnDifferentVolumes(File srcFile, File targetFile) throws RolloverFailure {
- if (!EnvUtil.isJDK7OrHigher())
- return false;
-
- // target file is not certain to exist but its parent has to exist given the call hierarchy of this method
- File parentOfTarget = targetFile.getAbsoluteFile().getParentFile();
-
- if(parentOfTarget == null) {
- addWarn("Parent of target file ["+targetFile+"] is null");
- return null;
- }
- if(!parentOfTarget.exists()) {
- addWarn("Parent of target file ["+targetFile+"] does not exist");
- return null;
- }
-
- try {
- boolean onSameFileStore = FileStoreUtil.areOnSameFileStore(srcFile, parentOfTarget);
- return !onSameFileStore;
- } catch (RolloverFailure rf) {
- addWarn("Error while checking file store equality", rf);
- return null;
+ if (srcFile.exists()) {
+ File targetFile = new File(target);
+ createMissingTargetDirsIfNecessary(targetFile);
+
+ addInfo("Renaming file [" + srcFile + "] to [" + targetFile + "]");
+
+ boolean result = srcFile.renameTo(targetFile);
+
+ if (!result) {
+ addWarn("Failed to rename file [" + srcFile + "] as [" + targetFile + "].");
+ if (areOnDifferentVolumes(srcFile, targetFile)) {
+ addWarn("Detected different file systems for source [" + src + "] and target [" + target + "]. Attempting rename by copying.");
+ renameByCopying(src, target);
+ return;
+ } else {
+ addWarn("Please consider leaving the [file] option of " + RollingFileAppender.class.getSimpleName() + " empty.");
+ addWarn("See also " + RENAMING_ERROR_URL);
}
+ }
+ } else {
+ throw new RolloverFailure("File [" + src + "] does not exist.");
+ }
+ }
+
+
+ /**
+ * Attempts tp determine whether both files are on different volumes. Returns true if we could determine that
+ * the files are on different volumes. Returns false otherwise or if an error occurred while doing the check.
+ *
+ * @param srcFile
+ * @param targetFile
+ * @return true if on different volumes, false otherwise or if an error occurred
+ */
+ boolean areOnDifferentVolumes(File srcFile, File targetFile) throws RolloverFailure {
+ if (!EnvUtil.isJDK7OrHigher())
+ return false;
+
+ File parentOfTarget = targetFile.getParentFile();
+
+ try {
+ boolean onSameFileStore = FileStoreUtil.areOnSameFileStore(srcFile, parentOfTarget);
+ return !onSameFileStore;
+ } catch (RolloverFailure rf) {
+ addWarn("Error while checking file store equality", rf);
+ return false;
}
+ }
- public void renameByCopying(String src, String target) throws RolloverFailure {
- FileUtil fileUtil = new FileUtil(getContext());
- fileUtil.copy(src, target);
- File srcFile = new File(src);
- if (!srcFile.delete()) {
- addWarn("Could not delete " + src);
- }
- }
+ public void renameByCopying(String src, String target)
+ throws RolloverFailure {
- void createMissingTargetDirsIfNecessary(File toFile) throws RolloverFailure {
- boolean result = FileUtil.createMissingParentDirectories(toFile);
- if (!result) {
- throw new RolloverFailure("Failed to create parent directories for [" + toFile.getAbsolutePath() + "]");
- }
+ FileUtil fileUtil = new FileUtil(getContext());
+ fileUtil.copy(src, target);
+
+ File srcFile = new File(src);
+ if (!srcFile.delete()) {
+ addWarn("Could not delete " + src);
}
- @Override
- public String toString() {
- return "c.q.l.co.rolling.helper.RenameUtil";
+ }
+
+ void createMissingTargetDirsIfNecessary(File toFile) throws RolloverFailure {
+ if (FileUtil.isParentDirectoryCreationRequired(toFile)) {
+ boolean result = FileUtil.createMissingParentDirectories(toFile);
+ if (!result) {
+ throw new RolloverFailure("Failed to create parent directories for ["
+ + toFile.getAbsolutePath() + "]");
+ }
}
+ }
+
+ @Override
+ public String toString() {
+ return "c.q.l.co.rolling.helper.RenameUtil";
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/RollingCalendar.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/RollingCalendar.java
index ddcd4ce..87a02f5 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/RollingCalendar.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/RollingCalendar.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,9 +13,6 @@
*/
package ch.qos.logback.core.rolling.helper;
-import static ch.qos.logback.core.CoreConstants.MILLIS_IN_ONE_HOUR;
-import static ch.qos.logback.core.CoreConstants.MILLIS_IN_ONE_DAY;
-
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
@@ -36,261 +33,211 @@ import ch.qos.logback.core.spi.ContextAwareBase;
*/
public class RollingCalendar extends GregorianCalendar {
- private static final long serialVersionUID = -5937537740925066161L;
-
- // The gmtTimeZone is used only in computeCheckPeriod() method.
- static final TimeZone GMT_TIMEZONE = TimeZone.getTimeZone("GMT");
+ private static final long serialVersionUID = -5937537740925066161L;
- PeriodicityType periodicityType = PeriodicityType.ERRONEOUS;
- String datePattern;
-
- public RollingCalendar(String datePattern) {
- super();
- this.datePattern = datePattern;
- this.periodicityType = computePeriodicityType();
- }
+ // The gmtTimeZone is used only in computeCheckPeriod() method.
+ static final TimeZone GMT_TIMEZONE = TimeZone.getTimeZone("GMT");
- public RollingCalendar(String datePattern, TimeZone tz, Locale locale) {
- super(tz, locale);
- this.datePattern = datePattern;
- this.periodicityType = computePeriodicityType();
- }
-
- public PeriodicityType getPeriodicityType() {
- return periodicityType;
- }
-
- // This method computes the roll over period by looping over the
- // periods, starting with the shortest, and stopping when the r0 is
- // different from from r1, where r0 is the epoch formatted according
- // the datePattern (supplied by the user) and r1 is the
- // epoch+nextMillis(i) formatted according to datePattern. All date
- // formatting is done in GMT and not local format because the test
- // logic is based on comparisons relative to 1970-01-01 00:00:00
- // GMT (the epoch).
- public PeriodicityType computePeriodicityType() {
-
- GregorianCalendar calendar = new GregorianCalendar(GMT_TIMEZONE, Locale.getDefault());
-
-
- // set sate to 1970-01-01 00:00:00 GMT
- Date epoch = new Date(0);
-
- if (datePattern != null) {
- for (PeriodicityType i : PeriodicityType.VALID_ORDERED_LIST) {
- SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePattern);
- simpleDateFormat.setTimeZone(GMT_TIMEZONE); // all date formatting done in GMT
-
- String r0 = simpleDateFormat.format(epoch);
-
- Date next = innerGetEndOfThisPeriod(calendar, i, epoch);
- String r1 = simpleDateFormat.format(next);
-
- // System.out.println("Type = "+i+", r0 = "+r0+", r1 = "+r1);
- if ((r0 != null) && (r1 != null) && !r0.equals(r1)) {
- return i;
- }
- }
- }
- // we failed
- return PeriodicityType.ERRONEOUS;
- }
-
- public boolean isCollisionFree() {
- switch (periodicityType) {
- case TOP_OF_HOUR:
- // isolated hh or KK
- return !collision(12 * MILLIS_IN_ONE_HOUR);
-
- case TOP_OF_DAY:
- // EE or uu
- if (collision(7 * MILLIS_IN_ONE_DAY))
- return false;
- // isolated dd
- if (collision(31 * MILLIS_IN_ONE_DAY))
- return false;
- // DD
- if (collision(365 * MILLIS_IN_ONE_DAY))
- return false;
- return true;
- case TOP_OF_WEEK:
- // WW
- if (collision(34 * MILLIS_IN_ONE_DAY))
- return false;
- // isolated ww
- if (collision(366 * MILLIS_IN_ONE_DAY))
- return false;
- return true;
- default:
- return true;
- }
- }
+ PeriodicityType periodicityType = PeriodicityType.ERRONEOUS;
- private boolean collision(long delta) {
- SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePattern);
- simpleDateFormat.setTimeZone(GMT_TIMEZONE); // all date formatting done in GMT
- Date epoch0 = new Date(0);
- String r0 = simpleDateFormat.format(epoch0);
- Date epoch12 = new Date(delta);
- String r12 = simpleDateFormat.format(epoch12);
+ public RollingCalendar() {
+ super();
+ }
- return r0.equals(r12);
- }
+ public RollingCalendar(TimeZone tz, Locale locale) {
+ super(tz, locale);
+ }
- public void printPeriodicity(ContextAwareBase cab) {
- switch (periodicityType) {
- case TOP_OF_MILLISECOND:
- cab.addInfo("Roll-over every millisecond.");
- break;
+ public void init(String datePattern) {
+ periodicityType = computePeriodicityType(datePattern);
+ }
- case TOP_OF_SECOND:
- cab.addInfo("Roll-over every second.");
- break;
+ private void setPeriodicityType(PeriodicityType periodicityType) {
+ this.periodicityType = periodicityType;
+ }
- case TOP_OF_MINUTE:
- cab.addInfo("Roll-over every minute.");
- break;
+ public PeriodicityType getPeriodicityType() {
+ return periodicityType;
+ }
- case TOP_OF_HOUR:
- cab.addInfo("Roll-over at the top of every hour.");
- break;
+ public long getNextTriggeringMillis(Date now) {
+ return getNextTriggeringDate(now).getTime();
+ }
- case HALF_DAY:
- cab.addInfo("Roll-over at midday and midnight.");
- break;
+ // This method computes the roll over period by looping over the
+ // periods, starting with the shortest, and stopping when the r0 is
+ // different from from r1, where r0 is the epoch formatted according
+ // the datePattern (supplied by the user) and r1 is the
+ // epoch+nextMillis(i) formatted according to datePattern. All date
+ // formatting is done in GMT and not local format because the test
+ // logic is based on comparisons relative to 1970-01-01 00:00:00
+ // GMT (the epoch).
+ public PeriodicityType computePeriodicityType(String datePattern) {
+ RollingCalendar rollingCalendar = new RollingCalendar(GMT_TIMEZONE, Locale
+ .getDefault());
- case TOP_OF_DAY:
- cab.addInfo("Roll-over at midnight.");
- break;
+ // set sate to 1970-01-01 00:00:00 GMT
+ Date epoch = new Date(0);
- case TOP_OF_WEEK:
- cab.addInfo("Rollover at the start of week.");
- break;
+ if (datePattern != null) {
+ for (PeriodicityType i : PeriodicityType.VALID_ORDERED_LIST) {
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePattern);
+ simpleDateFormat.setTimeZone(GMT_TIMEZONE); // all date formatting done
+ // in GMT
- case TOP_OF_MONTH:
- cab.addInfo("Rollover at start of every month.");
- break;
+ String r0 = simpleDateFormat.format(epoch);
+ rollingCalendar.setPeriodicityType(i);
- default:
- cab.addInfo("Unknown periodicity.");
- }
- }
+ Date next = new Date(rollingCalendar.getNextTriggeringMillis(epoch));
+ String r1 = simpleDateFormat.format(next);
- public long periodBarriersCrossed(long start, long end) {
- if (start > end)
- throw new IllegalArgumentException("Start cannot come before end");
-
- Date startFloored = getsStartOfCurrentPeriod(start);
- Date endFloored = getsStartOfCurrentPeriod(end);
-
- long diff = endFloored.getTime() - startFloored.getTime();
-
- switch (periodicityType) {
-
- case TOP_OF_MILLISECOND:
- return diff;
- case TOP_OF_SECOND:
- return diff / CoreConstants.MILLIS_IN_ONE_SECOND;
- case TOP_OF_MINUTE:
- return diff / CoreConstants.MILLIS_IN_ONE_MINUTE;
- case TOP_OF_HOUR:
- return (int) diff / CoreConstants.MILLIS_IN_ONE_HOUR;
- case TOP_OF_DAY:
- return diff / CoreConstants.MILLIS_IN_ONE_DAY;
- case TOP_OF_WEEK:
- return diff / CoreConstants.MILLIS_IN_ONE_WEEK;
- case TOP_OF_MONTH:
- return diffInMonths(start, end);
- default:
- throw new IllegalStateException("Unknown periodicity type.");
+ // System.out.println("Type = "+i+", r0 = "+r0+", r1 = "+r1);
+ if ((r0 != null) && (r1 != null) && !r0.equals(r1)) {
+ return i;
}
+ }
}
-
- public static int diffInMonths(long startTime, long endTime) {
- if (startTime > endTime)
- throw new IllegalArgumentException("startTime cannot be larger than endTime");
- Calendar startCal = Calendar.getInstance();
- startCal.setTimeInMillis(startTime);
- Calendar endCal = Calendar.getInstance();
- endCal.setTimeInMillis(endTime);
- int yearDiff = endCal.get(Calendar.YEAR) - startCal.get(Calendar.YEAR);
- int monthDiff = endCal.get(Calendar.MONTH) - startCal.get(Calendar.MONTH);
- return yearDiff * 12 + monthDiff;
+ // we failed
+ return PeriodicityType.ERRONEOUS;
+ }
+
+ public void printPeriodicity(ContextAwareBase cab) {
+ switch (periodicityType) {
+ case TOP_OF_MILLISECOND:
+ cab.addInfo("Roll-over every millisecond.");
+ break;
+
+ case TOP_OF_SECOND:
+ cab.addInfo("Roll-over every second.");
+ break;
+
+ case TOP_OF_MINUTE:
+ cab.addInfo("Roll-over every minute.");
+ break;
+
+ case TOP_OF_HOUR:
+ cab.addInfo("Roll-over at the top of every hour.");
+ break;
+
+ case HALF_DAY:
+ cab.addInfo("Roll-over at midday and midnight.");
+ break;
+
+ case TOP_OF_DAY:
+ cab.addInfo("Roll-over at midnight.");
+ break;
+
+ case TOP_OF_WEEK:
+ cab.addInfo("Rollover at the start of week.");
+ break;
+
+ case TOP_OF_MONTH:
+ cab.addInfo("Rollover at start of every month.");
+ break;
+
+ default:
+ cab.addInfo("Unknown periodicity.");
}
-
- static private Date innerGetEndOfThisPeriod(Calendar cal, PeriodicityType periodicityType, Date now) {
- return innerGetEndOfNextNthPeriod(cal, periodicityType, now, 1);
+ }
+
+ public long periodsElapsed(long start, long end) {
+ if (start > end)
+ throw new IllegalArgumentException("Start cannot come before end");
+
+ long diff = end - start;
+ switch (periodicityType) {
+
+ case TOP_OF_MILLISECOND:
+ return diff;
+ case TOP_OF_SECOND:
+ return diff / CoreConstants.MILLIS_IN_ONE_SECOND;
+ case TOP_OF_MINUTE:
+ return diff / CoreConstants.MILLIS_IN_ONE_MINUTE;
+ case TOP_OF_HOUR:
+ return (int) diff / CoreConstants.MILLIS_IN_ONE_HOUR;
+ case TOP_OF_DAY:
+ return diff / CoreConstants.MILLIS_IN_ONE_DAY;
+ case TOP_OF_WEEK:
+ return diff / CoreConstants.MILLIS_IN_ONE_WEEK;
+ case TOP_OF_MONTH:
+ return diffInMonths(start, end);
+ default:
+ throw new IllegalStateException("Unknown periodicity type.");
}
-
- static private Date innerGetEndOfNextNthPeriod(Calendar cal, PeriodicityType periodicityType, Date now, int numPeriods) {
- cal.setTime(now);
- switch (periodicityType) {
- case TOP_OF_MILLISECOND:
- cal.add(Calendar.MILLISECOND, numPeriods);
- break;
-
- case TOP_OF_SECOND:
- cal.set(Calendar.MILLISECOND, 0);
- cal.add(Calendar.SECOND, numPeriods);
- break;
-
- case TOP_OF_MINUTE:
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MILLISECOND, 0);
- cal.add(Calendar.MINUTE, numPeriods);
- break;
-
- case TOP_OF_HOUR:
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MILLISECOND, 0);
- cal.add(Calendar.HOUR_OF_DAY, numPeriods);
- break;
-
- case TOP_OF_DAY:
- cal.set(Calendar.HOUR_OF_DAY, 0);
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MILLISECOND, 0);
- cal.add(Calendar.DATE, numPeriods);
- break;
-
- case TOP_OF_WEEK:
- cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
- cal.set(Calendar.HOUR_OF_DAY, 0);
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MILLISECOND, 0);
- cal.add(Calendar.WEEK_OF_YEAR, numPeriods);
- break;
-
- case TOP_OF_MONTH:
- cal.set(Calendar.DATE, 1);
- cal.set(Calendar.HOUR_OF_DAY, 0);
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MILLISECOND, 0);
- cal.add(Calendar.MONTH, numPeriods);
- break;
-
- default:
- throw new IllegalStateException("Unknown periodicity type.");
- }
-
- return cal.getTime();
+ }
+
+ public static int diffInMonths(long startTime, long endTime) {
+ if (startTime > endTime)
+ throw new IllegalArgumentException("startTime cannot be larger than endTime");
+ Calendar startCal = Calendar.getInstance();
+ startCal.setTimeInMillis(startTime);
+ Calendar endCal = Calendar.getInstance();
+ endCal.setTimeInMillis(endTime);
+ int yearDiff = endCal.get(Calendar.YEAR) - startCal.get(Calendar.YEAR);
+ int monthDiff = endCal.get(Calendar.MONTH) - startCal.get(Calendar.MONTH);
+ return yearDiff * 12 + monthDiff;
+ }
+
+ public Date getRelativeDate(Date now, int periods) {
+ this.setTime(now);
+
+ switch (periodicityType) {
+ case TOP_OF_MILLISECOND:
+ this.add(Calendar.MILLISECOND, periods);
+ break;
+
+ case TOP_OF_SECOND:
+ this.set(Calendar.MILLISECOND, 0);
+ this.add(Calendar.SECOND, periods);
+ break;
+
+ case TOP_OF_MINUTE:
+ this.set(Calendar.SECOND, 0);
+ this.set(Calendar.MILLISECOND, 0);
+ this.add(Calendar.MINUTE, periods);
+ break;
+
+ case TOP_OF_HOUR:
+ this.set(Calendar.MINUTE, 0);
+ this.set(Calendar.SECOND, 0);
+ this.set(Calendar.MILLISECOND, 0);
+ this.add(Calendar.HOUR_OF_DAY, periods);
+ break;
+
+ case TOP_OF_DAY:
+ this.set(Calendar.HOUR_OF_DAY, 0);
+ this.set(Calendar.MINUTE, 0);
+ this.set(Calendar.SECOND, 0);
+ this.set(Calendar.MILLISECOND, 0);
+ this.add(Calendar.DATE, periods);
+ break;
+
+ case TOP_OF_WEEK:
+ this.set(Calendar.DAY_OF_WEEK, getFirstDayOfWeek());
+ this.set(Calendar.HOUR_OF_DAY, 0);
+ this.set(Calendar.MINUTE, 0);
+ this.set(Calendar.SECOND, 0);
+ this.set(Calendar.MILLISECOND, 0);
+ this.add(Calendar.WEEK_OF_YEAR, periods);
+ break;
+
+ case TOP_OF_MONTH:
+ this.set(Calendar.DATE, 1);
+ this.set(Calendar.HOUR_OF_DAY, 0);
+ this.set(Calendar.MINUTE, 0);
+ this.set(Calendar.SECOND, 0);
+ this.set(Calendar.MILLISECOND, 0);
+ this.add(Calendar.MONTH, periods);
+ break;
+
+ default:
+ throw new IllegalStateException("Unknown periodicity type.");
}
- public Date getEndOfNextNthPeriod(Date now, int periods) {
- return innerGetEndOfNextNthPeriod(this, this.periodicityType, now, periods);
- }
+ return getTime();
+ }
- public Date getNextTriggeringDate(Date now) {
- return getEndOfNextNthPeriod(now, 1);
- }
-
- public Date getsStartOfCurrentPeriod(long now) {
- Calendar aCal = Calendar.getInstance(getTimeZone());
- aCal.setTimeInMillis(now);
- return getEndOfNextNthPeriod(aCal.getTime(), 0);
- }
+ public Date getNextTriggeringDate(Date now) {
+ return getRelativeDate(now, 1);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/SizeAndTimeBasedArchiveRemover.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/SizeAndTimeBasedArchiveRemover.java
index 8ba91cb..f275aa5 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/SizeAndTimeBasedArchiveRemover.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/SizeAndTimeBasedArchiveRemover.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,23 +16,36 @@ package ch.qos.logback.core.rolling.helper;
import java.io.File;
import java.util.Date;
-public class SizeAndTimeBasedArchiveRemover extends TimeBasedArchiveRemover {
+public class SizeAndTimeBasedArchiveRemover extends DefaultArchiveRemover {
- public SizeAndTimeBasedArchiveRemover(FileNamePattern fileNamePattern, RollingCalendar rc) {
- super(fileNamePattern, rc);
- }
+ public SizeAndTimeBasedArchiveRemover(FileNamePattern fileNamePattern,
+ RollingCalendar rc) {
+ super(fileNamePattern, rc);
+ }
+
+ public void cleanByPeriodOffset(Date now, int periodOffset) {
+ Date dateOfPeriodToClean = rc.getRelativeDate(now, periodOffset);
+
+ String regex = fileNamePattern.toRegexForFixedDate(dateOfPeriodToClean);
+ String stemRegex = FileFilterUtil.afterLastSlash(regex);
+ File archive0 = new File(fileNamePattern.convertMultipleArguments(
+ dateOfPeriodToClean, 0));
+ // in case the file has no directory part, i.e. if it's written into the
+ // user's current directory.
+ archive0 = archive0.getAbsoluteFile();
- protected File[] getFilesInPeriod(Date dateOfPeriodToClean) {
- File archive0 = new File(fileNamePattern.convertMultipleArguments(dateOfPeriodToClean, 0));
- File parentDir = getParentDir(archive0);
- String stemRegex = createStemRegex(dateOfPeriodToClean);
- File[] matchingFileArray = FileFilterUtil.filesInFolderMatchingStemRegex(parentDir, stemRegex);
- return matchingFileArray;
+ File parentDir = archive0.getAbsoluteFile().getParentFile();
+ File[] matchingFileArray = FileFilterUtil.filesInFolderMatchingStemRegex(
+ parentDir, stemRegex);
+
+ for (File f : matchingFileArray) {
+ f.delete();
}
- private String createStemRegex(final Date dateOfPeriodToClean) {
- String regex = fileNamePattern.toRegexForFixedDate(dateOfPeriodToClean);
- return FileFilterUtil.afterLastSlash(regex);
+ if (parentClean) {
+ removeFolderIfEmpty(parentDir);
}
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/TimeBasedArchiveRemover.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/TimeBasedArchiveRemover.java
index 4d31425..c46d1d6 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/TimeBasedArchiveRemover.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/TimeBasedArchiveRemover.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,235 +13,30 @@
*/
package ch.qos.logback.core.rolling.helper;
-import static ch.qos.logback.core.CoreConstants.UNBOUNDED_TOTAL_SIZE_CAP;
-
import java.io.File;
-import java.util.Arrays;
-import java.util.Comparator;
import java.util.Date;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-
-import ch.qos.logback.core.CoreConstants;
-import ch.qos.logback.core.pattern.Converter;
-import ch.qos.logback.core.pattern.LiteralConverter;
-import ch.qos.logback.core.spi.ContextAwareBase;
-import ch.qos.logback.core.util.FileSize;
-
-public class TimeBasedArchiveRemover extends ContextAwareBase implements ArchiveRemover {
-
- static protected final long UNINITIALIZED = -1;
- // aim for 64 days, except in case of hourly rollover
- static protected final long INACTIVITY_TOLERANCE_IN_MILLIS = 32L * (long) CoreConstants.MILLIS_IN_ONE_DAY;
- static final int MAX_VALUE_FOR_INACTIVITY_PERIODS = 14 * 24; // 14 days in case of hourly rollover
-
- final FileNamePattern fileNamePattern;
- final RollingCalendar rc;
- private int maxHistory = CoreConstants.UNBOUND_HISTORY;
- private long totalSizeCap = CoreConstants.UNBOUNDED_TOTAL_SIZE_CAP;
- final boolean parentClean;
- long lastHeartBeat = UNINITIALIZED;
-
- public TimeBasedArchiveRemover(FileNamePattern fileNamePattern, RollingCalendar rc) {
- this.fileNamePattern = fileNamePattern;
- this.rc = rc;
- this.parentClean = computeParentCleaningFlag(fileNamePattern);
- }
-
- public void clean(Date now) {
- long nowInMillis = now.getTime();
- // for a live appender periodsElapsed is usually one
- int periodsElapsed = computeElapsedPeriodsSinceLastClean(nowInMillis);
- lastHeartBeat = nowInMillis;
- if (periodsElapsed > 1) {
- addInfo("Multiple periods, i.e. " + periodsElapsed + " periods, seem to have elapsed. This is expected at application start.");
- }
- for (int i = 0; i < periodsElapsed; i++) {
- int offset = getPeriodOffsetForDeletionTarget() - i;
- Date dateOfPeriodToClean = rc.getEndOfNextNthPeriod(now, offset);
- cleanPeriod(dateOfPeriodToClean);
- }
- }
-
- protected File[] getFilesInPeriod(Date dateOfPeriodToClean) {
- String filenameToDelete = fileNamePattern.convert(dateOfPeriodToClean);
- File file2Delete = new File(filenameToDelete);
-
- if (fileExistsAndIsFile(file2Delete)) {
- return new File[] { file2Delete };
- } else {
- return new File[0];
- }
- }
-
- private boolean fileExistsAndIsFile(File file2Delete) {
- return file2Delete.exists() && file2Delete.isFile();
- }
-
- public void cleanPeriod(Date dateOfPeriodToClean) {
- File[] matchingFileArray = getFilesInPeriod(dateOfPeriodToClean);
-
- for (File f : matchingFileArray) {
- addInfo("deleting " + f);
- f.delete();
- }
-
- if (parentClean && matchingFileArray.length > 0) {
- File parentDir = getParentDir(matchingFileArray[0]);
- removeFolderIfEmpty(parentDir);
- }
- }
-
- void capTotalSize(Date now) {
- int totalSize = 0;
- int totalRemoved = 0;
- for (int offset = 0; offset < maxHistory; offset++) {
- Date date = rc.getEndOfNextNthPeriod(now, -offset);
- File[] matchingFileArray = getFilesInPeriod(date);
- descendingSortByLastModified(matchingFileArray);
- for (File f : matchingFileArray) {
- long size = f.length();
- if (totalSize + size > totalSizeCap) {
- addInfo("Deleting [" + f + "]" + " of size " + new FileSize(size));
- totalRemoved += size;
- f.delete();
- }
- totalSize += size;
- }
- }
- addInfo("Removed " + new FileSize(totalRemoved) + " of files");
- }
-
- private void descendingSortByLastModified(File[] matchingFileArray) {
- Arrays.sort(matchingFileArray, new Comparator<File>() {
- @Override
- public int compare(final File f1, final File f2) {
- long l1 = f1.lastModified();
- long l2 = f2.lastModified();
- if (l1 == l2)
- return 0;
- // descending sort, i.e. newest files first
- if (l2 < l1)
- return -1;
- else
- return 1;
- }
- });
- }
-
- File getParentDir(File file) {
- File absolute = file.getAbsoluteFile();
- File parentDir = absolute.getParentFile();
- return parentDir;
- }
-
- int computeElapsedPeriodsSinceLastClean(long nowInMillis) {
- long periodsElapsed = 0;
- if (lastHeartBeat == UNINITIALIZED) {
- addInfo("first clean up after appender initialization");
- periodsElapsed = rc.periodBarriersCrossed(nowInMillis, nowInMillis + INACTIVITY_TOLERANCE_IN_MILLIS);
- periodsElapsed = Math.min(periodsElapsed, MAX_VALUE_FOR_INACTIVITY_PERIODS);
- } else {
- periodsElapsed = rc.periodBarriersCrossed(lastHeartBeat, nowInMillis);
- // periodsElapsed of zero is possible for Size and time based policies
- }
- return (int) periodsElapsed;
- }
-
- boolean computeParentCleaningFlag(FileNamePattern fileNamePattern) {
- DateTokenConverter<Object> dtc = fileNamePattern.getPrimaryDateTokenConverter();
- // if the date pattern has a /, then we need parent cleaning
- if (dtc.getDatePattern().indexOf('/') != -1) {
- return true;
- }
- // if the literal string subsequent to the dtc contains a /, we also
- // need parent cleaning
-
- Converter<Object> p = fileNamePattern.headTokenConverter;
-
- // find the date converter
- while (p != null) {
- if (p instanceof DateTokenConverter) {
- break;
- }
- p = p.getNext();
- }
-
- while (p != null) {
- if (p instanceof LiteralConverter) {
- String s = p.convert(null);
- if (s.indexOf('/') != -1) {
- return true;
- }
- }
- p = p.getNext();
- }
-
- // no /, so we don't need parent cleaning
- return false;
- }
-
- void removeFolderIfEmpty(File dir) {
- removeFolderIfEmpty(dir, 0);
- }
-
- /**
- * Will remove the directory passed as parameter if empty. After that, if the
- * parent is also becomes empty, remove the parent dir as well but at most 3
- * times.
- *
- * @param dir
- * @param depth
- */
- private void removeFolderIfEmpty(File dir, int depth) {
- // we should never go more than 3 levels higher
- if (depth >= 3) {
- return;
- }
- if (dir.isDirectory() && FileFilterUtil.isEmptyDirectory(dir)) {
- addInfo("deleting folder [" + dir + "]");
- dir.delete();
- removeFolderIfEmpty(dir.getParentFile(), depth + 1);
- }
- }
-
- public void setMaxHistory(int maxHistory) {
- this.maxHistory = maxHistory;
- }
-
- protected int getPeriodOffsetForDeletionTarget() {
- return -maxHistory - 1;
- }
-
- public void setTotalSizeCap(long totalSizeCap) {
- this.totalSizeCap = totalSizeCap;
- }
-
- public String toString() {
- return "c.q.l.core.rolling.helper.TimeBasedArchiveRemover";
- }
-
- public Future<?> cleanAsynchronously(Date now) {
- ArhiveRemoverRunnable runnable = new ArhiveRemoverRunnable(now);
- ExecutorService executorService = context.getScheduledExecutorService();
- Future<?> future = executorService.submit(runnable);
- return future;
- }
-
- public class ArhiveRemoverRunnable implements Runnable {
- Date now;
-
- ArhiveRemoverRunnable(Date now) {
- this.now = now;
- }
-
- @Override
- public void run() {
- clean(now);
- if (totalSizeCap != UNBOUNDED_TOTAL_SIZE_CAP && totalSizeCap > 0) {
- capTotalSize(now);
- }
- }
- }
+public class TimeBasedArchiveRemover extends DefaultArchiveRemover {
+
+ public TimeBasedArchiveRemover(FileNamePattern fileNamePattern,
+ RollingCalendar rc) {
+ super(fileNamePattern, rc);
+ }
+
+ protected void cleanByPeriodOffset(Date now, int periodOffset) {
+ Date date2delete = rc.getRelativeDate(now, periodOffset);
+ String filename = fileNamePattern.convert(date2delete);
+ File file2Delete = new File(filename);
+ if (file2Delete.exists() && file2Delete.isFile()) {
+ file2Delete.delete();
+ addInfo("deleting " + file2Delete);
+ if (parentClean) {
+ removeFolderIfEmpty(file2Delete.getParentFile());
+ }
+ }
+ }
+
+ public String toString() {
+ return "c.q.l.core.rolling.helper.TimeBasedArchiveRemover";
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/TokenConverter.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/TokenConverter.java
index ffa515e..4af5483 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/TokenConverter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/TokenConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.rolling.helper;
+
/**
* <code>TokenConverter</code> offers some basic functionality used by more
* specific token converters.
@@ -24,31 +25,32 @@ package ch.qos.logback.core.rolling.helper;
* @since 1.3
*/
public class TokenConverter {
-
- static final int IDENTITY = 0;
- static final int INTEGER = 1;
- static final int DATE = 1;
- int type;
- TokenConverter next;
-
- protected TokenConverter(int t) {
- type = t;
- }
-
- public TokenConverter getNext() {
- return next;
- }
-
- public void setNext(TokenConverter next) {
- this.next = next;
- }
-
- public int getType() {
- return type;
- }
-
- public void setType(int i) {
- type = i;
- }
+
+
+ static final int IDENTITY = 0;
+ static final int INTEGER = 1;
+ static final int DATE = 1;
+ int type;
+ TokenConverter next;
+
+ protected TokenConverter(int t) {
+ type = t;
+ }
+
+ public TokenConverter getNext() {
+ return next;
+ }
+
+ public void setNext(TokenConverter next) {
+ this.next = next;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int i) {
+ type = i;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/sift/AbstractAppenderFactoryUsingJoran.java b/logback-core/src/main/java/ch/qos/logback/core/sift/AbstractAppenderFactoryUsingJoran.java
index 297549d..07ae389 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/sift/AbstractAppenderFactoryUsingJoran.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/sift/AbstractAppenderFactoryUsingJoran.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,32 +28,32 @@ import ch.qos.logback.core.joran.spi.JoranException;
*/
public abstract class AbstractAppenderFactoryUsingJoran<E> implements AppenderFactory<E> {
- final List<SaxEvent> eventList;
- protected String key;
- protected Map<String, String> parentPropertyMap;
-
- protected AbstractAppenderFactoryUsingJoran(List<SaxEvent> eventList, String key, Map<String, String> parentPropertyMap) {
- this.eventList = removeSiftElement(eventList);
- this.key = key;
- this.parentPropertyMap = parentPropertyMap;
-
- }
-
- List<SaxEvent> removeSiftElement(List<SaxEvent> eventList) {
- return eventList.subList(1, eventList.size() - 1);
- }
-
- public abstract SiftingJoranConfiguratorBase<E> getSiftingJoranConfigurator(String k);
-
- public Appender<E> buildAppender(Context context, String discriminatingValue) throws JoranException {
- SiftingJoranConfiguratorBase<E> sjc = getSiftingJoranConfigurator(discriminatingValue);
- sjc.setContext(context);
- sjc.doConfigure(eventList);
- return sjc.getAppender();
- }
-
- public List<SaxEvent> getEventList() {
- return eventList;
- }
+ final List<SaxEvent> eventList;
+ protected String key;
+ protected Map<String, String> parentPropertyMap;
+
+ protected AbstractAppenderFactoryUsingJoran(List<SaxEvent> eventList, String key, Map<String, String> parentPropertyMap) {
+ this.eventList = removeSiftElement(eventList);
+ this.key = key;
+ this.parentPropertyMap = parentPropertyMap;
+
+ }
+
+ List<SaxEvent> removeSiftElement(List<SaxEvent> eventList) {
+ return eventList.subList(1, eventList.size() - 1);
+ }
+
+ public abstract SiftingJoranConfiguratorBase<E> getSiftingJoranConfigurator(String k);
+
+ public Appender<E> buildAppender(Context context, String discriminatingValue) throws JoranException {
+ SiftingJoranConfiguratorBase<E> sjc = getSiftingJoranConfigurator(discriminatingValue);
+ sjc.setContext(context);
+ sjc.doConfigure(eventList);
+ return sjc.getAppender();
+ }
+
+ public List<SaxEvent> getEventList() {
+ return eventList;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/sift/AbstractDiscriminator.java b/logback-core/src/main/java/ch/qos/logback/core/sift/AbstractDiscriminator.java
index 3e54b1b..1c74cd6 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/sift/AbstractDiscriminator.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/sift/AbstractDiscriminator.java
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
package ch.qos.logback.core.sift;
import ch.qos.logback.core.spi.ContextAwareBase;
@@ -23,17 +10,17 @@ import ch.qos.logback.core.spi.ContextAwareBase;
*/
public abstract class AbstractDiscriminator<E> extends ContextAwareBase implements Discriminator<E> {
- protected boolean started;
+ protected boolean started;
- public void start() {
- started = true;
- }
+ public void start() {
+ started = true;
+ }
- public void stop() {
- started = false;
- }
+ public void stop() {
+ started = false;
+ }
- public boolean isStarted() {
- return started;
- }
+ public boolean isStarted() {
+ return started;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactory.java b/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactory.java
index 8ab8afe..f5d0b2b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactory.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactory.java
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
package ch.qos.logback.core.sift;
import ch.qos.logback.core.Appender;
@@ -25,5 +12,5 @@ import ch.qos.logback.core.joran.spi.JoranException;
* To change this template use File | Settings | File Templates.
*/
public interface AppenderFactory<E> {
- Appender<E> buildAppender(Context context, String discriminatingValue) throws JoranException;
+ Appender<E> buildAppender(Context context, String discriminatingValue) throws JoranException;
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTracker.java b/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTracker.java
index 068ad05..f45c0d0 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTracker.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTracker.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,53 +31,54 @@ import ch.qos.logback.core.spi.ContextAwareImpl;
*/
public class AppenderTracker<E> extends AbstractComponentTracker<Appender<E>> {
- int nopaWarningCount = 0;
+ int nopaWarningCount = 0;
- final Context context;
- final AppenderFactory<E> appenderFactory;
- final ContextAwareImpl contextAware;
+ final Context context;
+ final AppenderFactory<E> appenderFactory;
+ final ContextAwareImpl contextAware;
- public AppenderTracker(Context context, AppenderFactory<E> appenderFactory) {
- super();
- this.context = context;
- this.appenderFactory = appenderFactory;
- this.contextAware = new ContextAwareImpl(context, this);
- }
+ public AppenderTracker(Context context, AppenderFactory<E> appenderFactory) {
+ super();
+ this.context = context;
+ this.appenderFactory = appenderFactory;
+ this.contextAware = new ContextAwareImpl(context, this);
+ }
- @Override
- protected void processPriorToRemoval(Appender<E> component) {
- component.stop();
- }
- @Override
- protected Appender<E> buildComponent(String key) {
- Appender<E> appender = null;
- try {
- appender = appenderFactory.buildAppender(context, key);
- } catch (JoranException je) {
- contextAware.addError("Error while building appender with discriminating value [" + key + "]");
- }
- if (appender == null) {
- appender = buildNOPAppender(key);
- }
+ @Override
+ protected void processPriorToRemoval(Appender<E> component) {
+ component.stop();
+ }
- return appender;
+ @Override
+ protected Appender<E> buildComponent(String key) {
+ Appender<E> appender = null;
+ try {
+ appender = appenderFactory.buildAppender(context, key);
+ } catch (JoranException je) {
+ contextAware.addError("Error while building appender with discriminating value [" + key + "]");
}
-
- private NOPAppender<E> buildNOPAppender(String key) {
- if (nopaWarningCount < CoreConstants.MAX_ERROR_COUNT) {
- nopaWarningCount++;
- contextAware.addError("Building NOPAppender for discriminating value [" + key + "]");
- }
- NOPAppender<E> nopa = new NOPAppender<E>();
- nopa.setContext(context);
- nopa.start();
- return nopa;
+ if (appender == null) {
+ appender = buildNOPAppender(key);
}
- @Override
- protected boolean isComponentStale(Appender<E> appender) {
- return !appender.isStarted();
+ return appender;
+ }
+
+ private NOPAppender<E> buildNOPAppender(String key) {
+ if (nopaWarningCount < CoreConstants.MAX_ERROR_COUNT) {
+ nopaWarningCount++;
+ contextAware.addError("Building NOPAppender for discriminating value [" + key + "]");
}
+ NOPAppender<E> nopa = new NOPAppender<E>();
+ nopa.setContext(context);
+ nopa.start();
+ return nopa;
+ }
+
+ @Override
+ protected boolean isComponentStale(Appender<E> appender) {
+ return !appender.isStarted();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/sift/DefaultDiscriminator.java b/logback-core/src/main/java/ch/qos/logback/core/sift/DefaultDiscriminator.java
index e49600c..83dcc24 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/sift/DefaultDiscriminator.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/sift/DefaultDiscriminator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,19 +13,20 @@
*/
package ch.qos.logback.core.sift;
+
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class DefaultDiscriminator<E> extends AbstractDiscriminator<E> {
- static public final String DEFAULT = "default";
+ static public final String DEFAULT = "default";
- public String getDiscriminatingValue(E e) {
- return DEFAULT;
- }
+ public String getDiscriminatingValue(E e) {
+ return DEFAULT;
+ }
- public String getKey() {
- return DEFAULT;
- }
+ public String getKey() {
+ return DEFAULT;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/sift/Discriminator.java b/logback-core/src/main/java/ch/qos/logback/core/sift/Discriminator.java
index d2ec977..d800596 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/sift/Discriminator.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/sift/Discriminator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,20 +27,20 @@ import ch.qos.logback.core.spi.LifeCycle;
* @param <E>
*/
public interface Discriminator<E> extends LifeCycle {
+
+ /**
+ * Given event 'e' return a discriminating value.
+ *
+ * @param e
+ * @return
+ */
+ String getDiscriminatingValue(E e);
- /**
- * Given event 'e' return a discriminating value.
- *
- * @param e
- * @return
- */
- String getDiscriminatingValue(E e);
-
- /**
- * The key or variable name under which the discriminating value should be
- * exported into the host environment.
- *
- * @return
- */
- String getKey();
+ /**
+ * The key or variable name under which the discriminating value should be
+ * exported into the host environment.
+ *
+ * @return
+ */
+ String getKey();
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
index 4d71906..7bc7514 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,117 +27,119 @@ import ch.qos.logback.core.util.Duration;
*
* @author Ceki Gulcu
*/
-public abstract class SiftingAppenderBase<E> extends AppenderBase<E> {
-
- protected AppenderTracker<E> appenderTracker;
- AppenderFactory<E> appenderFactory;
- Duration timeout = new Duration(AppenderTracker.DEFAULT_TIMEOUT);
- int maxAppenderCount = AppenderTracker.DEFAULT_MAX_COMPONENTS;
-
- Discriminator<E> discriminator;
-
- public Duration getTimeout() {
- return timeout;
+public abstract class SiftingAppenderBase<E> extends
+ AppenderBase<E> {
+
+ protected AppenderTracker<E> appenderTracker;
+ AppenderFactory<E> appenderFactory;
+ Duration timeout = new Duration(AppenderTracker.DEFAULT_TIMEOUT);
+ int maxAppenderCount = AppenderTracker.DEFAULT_MAX_COMPONENTS;
+
+ Discriminator<E> discriminator;
+
+ public Duration getTimeout() {
+ return timeout;
+ }
+
+ public void setTimeout(Duration timeout) {
+ this.timeout = timeout;
+ }
+
+ public int getMaxAppenderCount() {
+ return maxAppenderCount;
+ }
+
+ public void setMaxAppenderCount(int maxAppenderCount) {
+ this.maxAppenderCount = maxAppenderCount;
+ }
+
+ /**
+ * This setter is intended to be invoked by SiftAction. Customers have no reason to invoke
+ * this method directly.
+ */
+ public void setAppenderFactory(AppenderFactory<E> appenderFactory) {
+ this.appenderFactory = appenderFactory;
+ }
+
+ @Override
+ public void start() {
+ int errors = 0;
+ if (discriminator == null) {
+ addError("Missing discriminator. Aborting");
+ errors++;
}
-
- public void setTimeout(Duration timeout) {
- this.timeout = timeout;
+ if (!discriminator.isStarted()) {
+ addError("Discriminator has not started successfully. Aborting");
+ errors++;
}
-
- public int getMaxAppenderCount() {
- return maxAppenderCount;
+ if (appenderFactory == null) {
+ addError("AppenderFactory has not been set. Aborting");
+ errors++;
+ } else {
+ appenderTracker = new AppenderTracker<E>(context, appenderFactory);
+ appenderTracker.setMaxComponents(maxAppenderCount);
+ appenderTracker.setTimeout(timeout.getMilliseconds());
}
-
- public void setMaxAppenderCount(int maxAppenderCount) {
- this.maxAppenderCount = maxAppenderCount;
+ if (errors == 0) {
+ super.start();
}
+ }
- /**
- * This setter is intended to be invoked by SiftAction. Customers have no reason to invoke
- * this method directly.
- */
- public void setAppenderFactory(AppenderFactory<E> appenderFactory) {
- this.appenderFactory = appenderFactory;
+ @Override
+ public void stop() {
+ for (Appender<E> appender : appenderTracker.allComponents()) {
+ appender.stop();
}
+ }
- @Override
- public void start() {
- int errors = 0;
- if (discriminator == null) {
- addError("Missing discriminator. Aborting");
- errors++;
- }
- if (!discriminator.isStarted()) {
- addError("Discriminator has not started successfully. Aborting");
- errors++;
- }
- if (appenderFactory == null) {
- addError("AppenderFactory has not been set. Aborting");
- errors++;
- } else {
- appenderTracker = new AppenderTracker<E>(context, appenderFactory);
- appenderTracker.setMaxComponents(maxAppenderCount);
- appenderTracker.setTimeout(timeout.getMilliseconds());
- }
- if (errors == 0) {
- super.start();
- }
- }
+ abstract protected long getTimestamp(E event);
- @Override
- public void stop() {
- for (Appender<E> appender : appenderTracker.allComponents()) {
- appender.stop();
- }
+ @Override
+ protected void append(E event) {
+ if (!isStarted()) {
+ return;
}
+ String discriminatingValue = discriminator.getDiscriminatingValue(event);
+ long timestamp = getTimestamp(event);
- abstract protected long getTimestamp(E event);
-
- @Override
- protected void append(E event) {
- if (!isStarted()) {
- return;
- }
- String discriminatingValue = discriminator.getDiscriminatingValue(event);
- long timestamp = getTimestamp(event);
-
- Appender<E> appender = appenderTracker.getOrCreate(discriminatingValue, timestamp);
- // marks the appender for removal as specified by the user
- if (eventMarksEndOfLife(event)) {
- appenderTracker.endOfLife(discriminatingValue);
- }
- appenderTracker.removeStaleComponents(timestamp);
- appender.doAppend(event);
+ Appender<E> appender = appenderTracker.getOrCreate(discriminatingValue, timestamp);
+ // marks the appender for removal as specified by the user
+ if (eventMarksEndOfLife(event)) {
+ appenderTracker.endOfLife(discriminatingValue);
}
-
- protected abstract boolean eventMarksEndOfLife(E event);
-
- public Discriminator<E> getDiscriminator() {
- return discriminator;
- }
-
- public void setDiscriminator(Discriminator<E> discriminator) {
- this.discriminator = discriminator;
- }
-
- // sometimes one needs to close a nested appender immediately
- // for example when executing a command which has its own nested appender
- // and the command also cleans up after itself. However, an open file appender
- // will prevent the folder from being deleted
- // see http://www.qos.ch/pipermail/logback-user/2010-March/001487.html
-
- /**
- * @since 0.9.19
- */
- public AppenderTracker<E> getAppenderTracker() {
- return appenderTracker;
- }
-
- public String getDiscriminatorKey() {
- if (discriminator != null) {
- return discriminator.getKey();
- } else {
- return null;
- }
+ appenderTracker.removeStaleComponents(timestamp);
+ appender.doAppend(event);
+ }
+
+ protected abstract boolean eventMarksEndOfLife(E event);
+
+ public Discriminator<E> getDiscriminator() {
+ return discriminator;
+ }
+
+ public void setDiscriminator(Discriminator<E> discriminator) {
+ this.discriminator = discriminator;
+ }
+
+
+ // sometimes one needs to close a nested appender immediately
+ // for example when executing a command which has its own nested appender
+ // and the command also cleans up after itself. However, an open file appender
+ // will prevent the folder from being deleted
+ // see http://www.qos.ch/pipermail/logback-user/2010-March/001487.html
+
+ /**
+ * @since 0.9.19
+ */
+ public AppenderTracker<E> getAppenderTracker() {
+ return appenderTracker;
+ }
+
+ public String getDiscriminatorKey() {
+ if (discriminator != null) {
+ return discriminator.getKey();
+ } else {
+ return null;
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfiguratorBase.java b/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfiguratorBase.java
index dc2b847..fb07701 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfiguratorBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfiguratorBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,64 +26,67 @@ import ch.qos.logback.core.joran.spi.Interpreter;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.joran.spi.RuleStore;
-public abstract class SiftingJoranConfiguratorBase<E> extends GenericConfigurator {
+public abstract class SiftingJoranConfiguratorBase<E> extends
+ GenericConfigurator {
- protected final String key;
- protected final String value;
- // properties inherited from the main joran run
- protected final Map<String, String> parentPropertyMap;
+ protected final String key;
+ protected final String value;
+ // properties inherited from the main joran run
+ protected final Map<String, String> parentPropertyMap;
- protected SiftingJoranConfiguratorBase(String key, String value, Map<String, String> parentPropertyMap) {
- this.key = key;
- this.value = value;
- this.parentPropertyMap = parentPropertyMap;
- }
-
- final static String ONE_AND_ONLY_ONE_URL = CoreConstants.CODES_URL + "#1andOnly1";
+ protected SiftingJoranConfiguratorBase(String key, String value, Map<String, String> parentPropertyMap) {
+ this.key = key;
+ this.value = value;
+ this.parentPropertyMap = parentPropertyMap;
+ }
- @Override
- protected void addImplicitRules(Interpreter interpreter) {
- NestedComplexPropertyIA nestedComplexIA = new NestedComplexPropertyIA(getBeanDescriptionCache());
- nestedComplexIA.setContext(context);
- interpreter.addImplicitAction(nestedComplexIA);
+ final static String ONE_AND_ONLY_ONE_URL = CoreConstants.CODES_URL
+ + "#1andOnly1";
- NestedBasicPropertyIA nestedSimpleIA = new NestedBasicPropertyIA(getBeanDescriptionCache());
- nestedSimpleIA.setContext(context);
- interpreter.addImplicitAction(nestedSimpleIA);
- }
+ @Override
+ protected void addImplicitRules(Interpreter interpreter) {
+ NestedComplexPropertyIA nestedComplexIA = new NestedComplexPropertyIA();
+ nestedComplexIA.setContext(context);
+ interpreter.addImplicitAction(nestedComplexIA);
- @Override
- protected void addInstanceRules(RuleStore rs) {
- rs.addRule(new ElementSelector("configuration/property"), new PropertyAction());
- rs.addRule(new ElementSelector("configuration/timestamp"), new TimestampAction());
- rs.addRule(new ElementSelector("configuration/define"), new DefinePropertyAction());
- }
+ NestedBasicPropertyIA nestedSimpleIA = new NestedBasicPropertyIA();
+ nestedSimpleIA.setContext(context);
+ interpreter.addImplicitAction(nestedSimpleIA);
+ }
- abstract public Appender<E> getAppender();
+ @Override
+ protected void addInstanceRules(RuleStore rs) {
+ rs.addRule(new ElementSelector("configuration/property"), new PropertyAction());
+ rs.addRule(new ElementSelector("configuration/timestamp"), new TimestampAction());
+ rs.addRule(new ElementSelector("configuration/define"), new DefinePropertyAction());
+ }
- int errorEmmissionCount = 0;
+ abstract public Appender<E> getAppender();
- protected void oneAndOnlyOneCheck(Map<?, ?> appenderMap) {
- String errMsg = null;
- if (appenderMap.size() == 0) {
- errorEmmissionCount++;
- errMsg = "No nested appenders found within the <sift> element in SiftingAppender.";
- } else if (appenderMap.size() > 1) {
- errorEmmissionCount++;
- errMsg = "Only and only one appender can be nested the <sift> element in SiftingAppender. See also " + ONE_AND_ONLY_ONE_URL;
- }
+ int errorEmmissionCount = 0;
- if (errMsg != null && errorEmmissionCount < CoreConstants.MAX_ERROR_COUNT) {
- addError(errMsg);
- }
+ protected void oneAndOnlyOneCheck(Map<?, ?> appenderMap) {
+ String errMsg = null;
+ if (appenderMap.size() == 0) {
+ errorEmmissionCount++;
+ errMsg = "No nested appenders found within the <sift> element in SiftingAppender.";
+ } else if (appenderMap.size() > 1) {
+ errorEmmissionCount++;
+ errMsg = "Only and only one appender can be nested the <sift> element in SiftingAppender. See also "
+ + ONE_AND_ONLY_ONE_URL;
}
- public void doConfigure(final List<SaxEvent> eventList) throws JoranException {
- super.doConfigure(eventList);
+ if (errMsg != null && errorEmmissionCount < CoreConstants.MAX_ERROR_COUNT) {
+ addError(errMsg);
}
+ }
- @Override
- public String toString() {
- return this.getClass().getName() + "{" + key + "=" + value + '}';
- }
+ public void doConfigure(final List<SaxEvent> eventList) throws JoranException {
+ super.doConfigure(eventList);
+ }
+
+ @Override
+ public String toString() {
+ return this.getClass().getName() + "{" + key + "=" + value + '}';
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/AbstractComponentTracker.java b/logback-core/src/main/java/ch/qos/logback/core/spi/AbstractComponentTracker.java
index 81c11b6..33b0158 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/AbstractComponentTracker.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/AbstractComponentTracker.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.spi;
+
import ch.qos.logback.core.CoreConstants;
import java.util.*;
@@ -29,284 +30,281 @@ import java.util.*;
* @author David Roussel
*/
abstract public class AbstractComponentTracker<C> implements ComponentTracker<C> {
- private static final boolean ACCESS_ORDERED = true;
-
- // Components in lingering state last 10 seconds
- final public static long LINGERING_TIMEOUT = 10 * CoreConstants.MILLIS_IN_ONE_SECOND;
-
- /**
- * The minimum amount of time that has to elapse between successive removal iterations.
- */
- final public static long WAIT_BETWEEN_SUCCESSIVE_REMOVAL_ITERATIONS = CoreConstants.MILLIS_IN_ONE_SECOND;
-
- protected int maxComponents = DEFAULT_MAX_COMPONENTS;
- protected long timeout = DEFAULT_TIMEOUT;
-
- // an access ordered map. Least recently accessed element will be removed after a 'timeout'
- LinkedHashMap<String, Entry<C>> liveMap = new LinkedHashMap<String, Entry<C>>(32, .75f, ACCESS_ORDERED);
-
- // an access ordered map. Least recently accessed element will be removed after LINGERING_TIMEOUT
- LinkedHashMap<String, Entry<C>> lingerersMap = new LinkedHashMap<String, Entry<C>>(16, .75f, ACCESS_ORDERED);
- long lastCheck = 0;
-
- /**
- * Stop or clean the component.
- *
- * @param component
- */
- abstract protected void processPriorToRemoval(C component);
-
- /**
- * Build a component based on the key.
- *
- * @param key
- * @return
- */
- abstract protected C buildComponent(String key);
-
- /**
- * Components can declare themselves stale. Such components may be
- * removed before they time out.
- *
- * @param c
- * @return
- */
- protected abstract boolean isComponentStale(C c);
-
- public int getComponentCount() {
- return liveMap.size() + lingerersMap.size();
- }
-
- /**
- * Get an entry from the liveMap, if not found search the lingerersMap.
- *
- * @param key
- * @return
- */
- private Entry<C> getFromEitherMap(String key) {
- Entry<C> entry = liveMap.get(key);
- if (entry != null)
- return entry;
- else {
- return lingerersMap.get(key);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>Note that this method is synchronized.</p>
- *
- * @param key {@inheritDoc}
- * @return {@inheritDoc}
- *
- */
- public synchronized C find(String key) {
- Entry<C> entry = getFromEitherMap(key);
- if (entry == null)
- return null;
- else
- return entry.component;
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>Note that this method is atomic, i.e. synchronized.</p>
- *
- * @param key {@inheritDoc}
- * @param timestamp {@inheritDoc}
- * @return {@inheritDoc}
- */
- public synchronized C getOrCreate(String key, long timestamp) {
- Entry<C> entry = getFromEitherMap(key);
- if (entry == null) {
- C c = buildComponent(key);
- entry = new Entry<C>(key, c, timestamp);
- // new entries go into the main map
- liveMap.put(key, entry);
- } else {
- entry.setTimestamp(timestamp);
- }
- return entry.component;
- }
-
- /**
- * Mark component identified by 'key' as having reached its end-of-life.
- *
- * @param key
- */
- public void endOfLife(String key) {
- Entry<C> entry = liveMap.remove(key);
- if (entry == null)
- return;
- lingerersMap.put(key, entry);
- }
-
- /**
- * Clear (and detach) components which are stale. Components which have not
- * been accessed for more than a user-specified duration are deemed stale.
- *
- * @param now
- */
- public synchronized void removeStaleComponents(long now) {
- if (isTooSoonForRemovalIteration(now))
- return;
- removeExcedentComponents();
- removeStaleComponentsFromMainMap(now);
- removeStaleComponentsFromLingerersMap(now);
- }
-
- private void removeExcedentComponents() {
- genericStaleComponentRemover(liveMap, 0, byExcedent);
- }
-
- private void removeStaleComponentsFromMainMap(long now) {
- genericStaleComponentRemover(liveMap, now, byTimeout);
+ private static final boolean ACCESS_ORDERED = true;
+
+ // Components in lingering state last 10 seconds
+ final public static long LINGERING_TIMEOUT = 10 * CoreConstants.MILLIS_IN_ONE_SECOND;
+
+ /**
+ * The minimum amount of time that has to elapse between successive removal iterations.
+ */
+ final public static long WAIT_BETWEEN_SUCCESSIVE_REMOVAL_ITERATIONS = CoreConstants.MILLIS_IN_ONE_SECOND;
+
+ protected int maxComponents = DEFAULT_MAX_COMPONENTS;
+ protected long timeout = DEFAULT_TIMEOUT;
+
+ // an access ordered map. Least recently accessed element will be removed after a 'timeout'
+ LinkedHashMap<String, Entry<C>> liveMap = new LinkedHashMap<String, Entry<C>>(32, .75f, ACCESS_ORDERED);
+
+ // an access ordered map. Least recently accessed element will be removed after LINGERING_TIMEOUT
+ LinkedHashMap<String, Entry<C>> lingerersMap = new LinkedHashMap<String, Entry<C>>(16, .75f, ACCESS_ORDERED);
+ long lastCheck = 0;
+
+ /**
+ * Stop or clean the component.
+ *
+ * @param component
+ */
+ abstract protected void processPriorToRemoval(C component);
+
+ /**
+ * Build a component based on the key.
+ *
+ * @param key
+ * @return
+ */
+ abstract protected C buildComponent(String key);
+
+ /**
+ * Components can declare themselves stale. Such components may be
+ * removed before they time out.
+ *
+ * @param c
+ * @return
+ */
+ protected abstract boolean isComponentStale(C c);
+
+
+ public int getComponentCount() {
+ return liveMap.size() + lingerersMap.size();
+ }
+
+ /**
+ * Get an entry from the liveMap, if not found search the lingerersMap.
+ *
+ * @param key
+ * @return
+ */
+ private Entry<C> getFromEitherMap(String key) {
+ Entry<C> entry = liveMap.get(key);
+ if (entry != null)
+ return entry;
+ else {
+ return lingerersMap.get(key);
}
-
- private void removeStaleComponentsFromLingerersMap(long now) {
- genericStaleComponentRemover(lingerersMap, now, byLingering);
- }
-
- private void genericStaleComponentRemover(LinkedHashMap<String, Entry<C>> map, long now, RemovalPredicator<C> removalPredicator) {
- Iterator<Map.Entry<String, Entry<C>>> iter = map.entrySet().iterator();
- while (iter.hasNext()) {
- Map.Entry<String, Entry<C>> mapEntry = iter.next();
- Entry<C> entry = mapEntry.getValue();
- if (removalPredicator.isSlatedForRemoval(entry, now)) {
- iter.remove();
- C c = entry.component;
- processPriorToRemoval(c);
- } else {
- break;
- }
- }
- }
-
- private RemovalPredicator<C> byExcedent = new RemovalPredicator<C>() {
- public boolean isSlatedForRemoval(Entry<C> entry, long timestamp) {
- return (liveMap.size() > maxComponents);
- }
- };
-
- private RemovalPredicator<C> byTimeout = new RemovalPredicator<C>() {
- public boolean isSlatedForRemoval(Entry<C> entry, long timestamp) {
- return isEntryStale(entry, timestamp);
- }
- };
- private RemovalPredicator<C> byLingering = new RemovalPredicator<C>() {
- public boolean isSlatedForRemoval(Entry<C> entry, long timestamp) {
- return isEntryDoneLingering(entry, timestamp);
- }
- };
-
- private boolean isTooSoonForRemovalIteration(long now) {
- if (lastCheck + WAIT_BETWEEN_SUCCESSIVE_REMOVAL_ITERATIONS > now) {
- return true;
- }
- lastCheck = now;
- return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Note that this method is synchronized.</p>
+ *
+ * @param key {@inheritDoc}
+ * @return {@inheritDoc}
+ *
+ */
+ public synchronized C find(String key) {
+ Entry<C> entry = getFromEitherMap(key);
+ if (entry == null) return null;
+ else return entry.component;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Note that this method is atomic, i.e. synchronized.</p>
+ *
+ * @param key {@inheritDoc}
+ * @param timestamp {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ public synchronized C getOrCreate(String key, long timestamp) {
+ Entry<C> entry = getFromEitherMap(key);
+ if (entry == null) {
+ C c = buildComponent(key);
+ entry = new Entry(key, c, timestamp);
+ // new entries go into the main map
+ liveMap.put(key, entry);
+ } else {
+ entry.setTimestamp(timestamp);
}
-
- private boolean isEntryStale(Entry<C> entry, long now) {
- // stopped or improperly started appenders are considered stale
- // see also http://jira.qos.ch/browse/LBCLASSIC-316
+ return entry.component;
+ }
+
+ /**
+ * Mark component identified by 'key' as having reached its end-of-life.
+ *
+ * @param key
+ */
+ public void endOfLife(String key) {
+ Entry entry = liveMap.remove(key);
+ if (entry == null)
+ return;
+ lingerersMap.put(key, entry);
+ }
+
+ /**
+ * Clear (and detach) components which are stale. Components which have not
+ * been accessed for more than a user-specified duration are deemed stale.
+ *
+ * @param now
+ */
+ public synchronized void removeStaleComponents(long now) {
+ if (isTooSoonForRemovalIteration(now)) return;
+ removeExcedentComponents();
+ removeStaleComponentsFromMainMap(now);
+ removeStaleComponentsFromLingerersMap(now);
+ }
+
+ private void removeExcedentComponents() {
+ genericStaleComponentRemover(liveMap, 0, byExcedent);
+ }
+
+ private void removeStaleComponentsFromMainMap(long now) {
+ genericStaleComponentRemover(liveMap, now, byTimeout);
+ }
+
+ private void removeStaleComponentsFromLingerersMap(long now) {
+ genericStaleComponentRemover(lingerersMap, now, byLingering);
+ }
+
+ private void genericStaleComponentRemover(LinkedHashMap<String, Entry<C>> map, long now,
+ RemovalPredicator<C> removalPredicator) {
+ Iterator<Map.Entry<String, Entry<C>>> iter = map.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry<String, Entry<C>> mapEntry = iter.next();
+ Entry<C> entry = mapEntry.getValue();
+ if (removalPredicator.isSlatedForRemoval(entry, now)) {
+ iter.remove();
C c = entry.component;
- if (isComponentStale(c))
- return true;
-
- return ((entry.timestamp + timeout) < now);
+ processPriorToRemoval(c);
+ } else {
+ break;
+ }
}
+ }
- private boolean isEntryDoneLingering(Entry<C> entry, long now) {
- return ((entry.timestamp + LINGERING_TIMEOUT) < now);
+ private RemovalPredicator<C> byExcedent = new RemovalPredicator<C>() {
+ public boolean isSlatedForRemoval(Entry<C> entry, long timestamp) {
+ return (liveMap.size() > maxComponents);
}
+ };
- public Set<String> allKeys() {
- HashSet<String> allKeys = new HashSet<String>(liveMap.keySet());
- allKeys.addAll(lingerersMap.keySet());
- return allKeys;
+ private RemovalPredicator<C> byTimeout = new RemovalPredicator<C>() {
+ public boolean isSlatedForRemoval(Entry<C> entry, long timestamp) {
+ return isEntryStale(entry, timestamp);
}
-
- public Collection<C> allComponents() {
- List<C> allComponents = new ArrayList<C>();
- for (Entry<C> e : liveMap.values())
- allComponents.add(e.component);
- for (Entry<C> e : lingerersMap.values())
- allComponents.add(e.component);
-
- return allComponents;
+ };
+ private RemovalPredicator<C> byLingering = new RemovalPredicator<C>() {
+ public boolean isSlatedForRemoval(Entry<C> entry, long timestamp) {
+ return isEntryDoneLingering(entry, timestamp);
}
+ };
- public long getTimeout() {
- return timeout;
+ private boolean isTooSoonForRemovalIteration(long now) {
+ if (lastCheck + WAIT_BETWEEN_SUCCESSIVE_REMOVAL_ITERATIONS > now) {
+ return true;
}
-
- public void setTimeout(long timeout) {
- this.timeout = timeout;
+ lastCheck = now;
+ return false;
+ }
+
+ private boolean isEntryStale(Entry<C> entry, long now) {
+ // stopped or improperly started appenders are considered stale
+ // see also http://jira.qos.ch/browse/LBCLASSIC-316
+ C c = entry.component;
+ if (isComponentStale(c))
+ return true;
+
+ return ((entry.timestamp + timeout) < now);
+ }
+
+ private boolean isEntryDoneLingering(Entry entry, long now) {
+ return ((entry.timestamp + LINGERING_TIMEOUT) < now);
+ }
+
+ public Set<String> allKeys() {
+ HashSet<String> allKeys = new HashSet<String>(liveMap.keySet());
+ allKeys.addAll(lingerersMap.keySet());
+ return allKeys;
+ }
+
+ public Collection<C> allComponents() {
+ List<C> allComponents = new ArrayList<C>();
+ for (Entry<C> e : liveMap.values())
+ allComponents.add(e.component);
+ for (Entry<C> e : lingerersMap.values())
+ allComponents.add(e.component);
+
+ return allComponents;
+ }
+
+ public long getTimeout() {
+ return timeout;
+ }
+
+ public void setTimeout(long timeout) {
+ this.timeout = timeout;
+ }
+
+ public int getMaxComponents() {
+ return maxComponents;
+ }
+
+ public void setMaxComponents(int maxComponents) {
+ this.maxComponents = maxComponents;
+ }
+
+ // ================================================================
+ private interface RemovalPredicator<C> {
+ boolean isSlatedForRemoval(Entry<C> entry, long timestamp);
+ }
+ // ================================================================
+ private static class Entry<C> {
+ String key;
+ C component;
+ long timestamp;
+
+ Entry(String k, C c, long timestamp) {
+ this.key = k;
+ this.component = c;
+ this.timestamp = timestamp;
}
- public int getMaxComponents() {
- return maxComponents;
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
}
- public void setMaxComponents(int maxComponents) {
- this.maxComponents = maxComponents;
+ @Override
+ public int hashCode() {
+ return key.hashCode();
}
- // ================================================================
- private interface RemovalPredicator<C> {
- boolean isSlatedForRemoval(Entry<C> entry, long timestamp);
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final Entry other = (Entry) obj;
+ if (key == null) {
+ if (other.key != null)
+ return false;
+ } else if (!key.equals(other.key))
+ return false;
+ if (component == null) {
+ if (other.component != null)
+ return false;
+ } else if (!component.equals(other.component))
+ return false;
+ return true;
}
- // ================================================================
- private static class Entry<C> {
- String key;
- C component;
- long timestamp;
-
- Entry(String k, C c, long timestamp) {
- this.key = k;
- this.component = c;
- this.timestamp = timestamp;
- }
-
- public void setTimestamp(long timestamp) {
- this.timestamp = timestamp;
- }
-
- @Override
- public int hashCode() {
- return key.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- @SuppressWarnings("unchecked")
- final Entry<C> other = (Entry<C>) obj;
- if (key == null) {
- if (other.key != null)
- return false;
- } else if (!key.equals(other.key))
- return false;
- if (component == null) {
- if (other.component != null)
- return false;
- } else if (!component.equals(other.component))
- return false;
- return true;
- }
-
- @Override
- public String toString() {
- return "(" + key + ", " + component + ")";
- }
+ @Override
+ public String toString() {
+ return "(" + key + ", " + component + ")";
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/AppenderAttachable.java b/logback-core/src/main/java/ch/qos/logback/core/spi/AppenderAttachable.java
index b6de119..e18271c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/AppenderAttachable.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/AppenderAttachable.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,40 +23,40 @@ import ch.qos.logback.core.Appender;
* @author Ceki Gülcü
*/
public interface AppenderAttachable<E> {
- /**
- * Add an appender.
- */
- void addAppender(Appender<E> newAppender);
-
- /**
- * Get an iterator for appenders contained in the parent object.
- */
- Iterator<Appender<E>> iteratorForAppenders();
-
- /**
- * Get an appender by name.
- */
- Appender<E> getAppender(String name);
-
- /**
- * Returns <code>true</code> if the specified appender is in list of
- * attached attached, <code>false</code> otherwise.
- */
- boolean isAttached(Appender<E> appender);
-
- /**
- * Detach and processPriorToRemoval all previously added appenders.
- */
- void detachAndStopAllAppenders();
-
- /**
- * Detach the appender passed as parameter from the list of appenders.
- */
- boolean detachAppender(Appender<E> appender);
-
- /**
- * Detach the appender with the name passed as parameter from the list of
- * appenders.
- */
- boolean detachAppender(String name);
+ /**
+ * Add an appender.
+ */
+ void addAppender(Appender<E> newAppender);
+
+ /**
+ * Get an iterator for appenders contained in the parent object.
+ */
+ Iterator<Appender<E>> iteratorForAppenders();
+
+ /**
+ * Get an appender by name.
+ */
+ Appender<E> getAppender(String name);
+
+ /**
+ * Returns <code>true</code> if the specified appender is in list of
+ * attached attached, <code>false</code> otherwise.
+ */
+ boolean isAttached(Appender<E> appender);
+
+ /**
+ * Detach and processPriorToRemoval all previously added appenders.
+ */
+ void detachAndStopAllAppenders();
+
+ /**
+ * Detach the appender passed as parameter from the list of appenders.
+ */
+ boolean detachAppender(Appender<E> appender);
+
+ /**
+ * Detach the appender with the name passed as parameter from the list of
+ * appenders.
+ */
+ boolean detachAppender(String name);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/AppenderAttachableImpl.java b/logback-core/src/main/java/ch/qos/logback/core/spi/AppenderAttachableImpl.java
index 672bfa2..4d3578c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/AppenderAttachableImpl.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/AppenderAttachableImpl.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,116 +26,116 @@ import ch.qos.logback.core.Appender;
*/
public class AppenderAttachableImpl<E> implements AppenderAttachable<E> {
- final private CopyOnWriteArrayList<Appender<E>> appenderList = new CopyOnWriteArrayList<Appender<E>>();
+ final private CopyOnWriteArrayList<Appender<E>> appenderList = new CopyOnWriteArrayList<Appender<E>>();
- /**
- * Attach an appender. If the appender is already in the list in won't be
- * added again.
- */
- public void addAppender(Appender<E> newAppender) {
- if (newAppender == null) {
- throw new IllegalArgumentException("Null argument disallowed");
- }
- appenderList.addIfAbsent(newAppender);
+ /**
+ * Attach an appender. If the appender is already in the list in won't be
+ * added again.
+ */
+ public void addAppender(Appender<E> newAppender) {
+ if (newAppender == null) {
+ throw new IllegalArgumentException("Null argument disallowed");
}
+ appenderList.addIfAbsent(newAppender);
+ }
- /**
- * Call the <code>doAppend</code> method on all attached appenders.
- */
- public int appendLoopOnAppenders(E e) {
- int size = 0;
- for (Appender<E> appender : appenderList) {
- appender.doAppend(e);
- size++;
- }
- return size;
- }
+ /**
+ * Call the <code>doAppend</code> method on all attached appenders.
+ */
+ public int appendLoopOnAppenders(E e) {
+ int size = 0;
+ for (Appender<E> appender : appenderList) {
+ appender.doAppend(e);
+ size++;
+ }
+ return size;
+ }
- /**
- * Get all attached appenders as an Enumeration. If there are no attached
- * appenders <code>null</code> is returned.
- *
- * @return Iterator An iterator of attached appenders.
- */
- public Iterator<Appender<E>> iteratorForAppenders() {
- return appenderList.iterator();
- }
+ /**
+ * Get all attached appenders as an Enumeration. If there are no attached
+ * appenders <code>null</code> is returned.
+ *
+ * @return Iterator An iterator of attached appenders.
+ */
+ public Iterator<Appender<E>> iteratorForAppenders() {
+ return appenderList.iterator();
+ }
- /**
- * Look for an attached appender named as <code>name</code>.
- * <p/>
- * <p> Return the appender with that name if in the list. Return null
- * otherwise.
- */
- public Appender<E> getAppender(String name) {
- if (name == null) {
- return null;
- }
- for (Appender<E> appender : appenderList) {
- if (name.equals(appender.getName())) {
- return appender;
- }
- }
- return null;
+ /**
+ * Look for an attached appender named as <code>name</code>.
+ * <p/>
+ * <p> Return the appender with that name if in the list. Return null
+ * otherwise.
+ */
+ public Appender<E> getAppender(String name) {
+ if (name == null) {
+ return null;
}
+ Appender<E> found = null;
+ for (Appender<E> appender : appenderList) {
+ if (name.equals(appender.getName())) {
+ return appender;
+ }
+ }
+ return null;
+ }
- /**
- * Returns <code>true</code> if the specified appender is in the list of
- * attached appenders, <code>false</code> otherwise.
- *
- * @since 1.2
- */
- public boolean isAttached(Appender<E> appender) {
- if (appender == null) {
- return false;
- }
- for (Appender<E> a : appenderList) {
- if (a == appender)
- return true;
- }
- return false;
+ /**
+ * Returns <code>true</code> if the specified appender is in the list of
+ * attached appenders, <code>false</code> otherwise.
+ *
+ * @since 1.2
+ */
+ public boolean isAttached(Appender<E> appender) {
+ if (appender == null) {
+ return false;
+ }
+ for (Appender<E> a : appenderList) {
+ if (a == appender) return true;
}
+ return false;
+ }
- /**
- * Remove and processPriorToRemoval all previously attached appenders.
- */
- public void detachAndStopAllAppenders() {
- for (Appender<E> a : appenderList) {
- a.stop();
- }
- appenderList.clear();
+ /**
+ * Remove and processPriorToRemoval all previously attached appenders.
+ */
+ public void detachAndStopAllAppenders() {
+ for (Appender<E> a : appenderList) {
+ a.stop();
}
+ appenderList.clear();
+ }
- static final long START = System.currentTimeMillis();
+ static final long START = System.currentTimeMillis();
- /**
- * Remove the appender passed as parameter form the list of attached
- * appenders.
- */
- public boolean detachAppender(Appender<E> appender) {
- if (appender == null) {
- return false;
- }
- boolean result;
- result = appenderList.remove(appender);
- return result;
+ /**
+ * Remove the appender passed as parameter form the list of attached
+ * appenders.
+ */
+ public boolean detachAppender(Appender<E> appender) {
+ if (appender == null) {
+ return false;
}
+ boolean result;
+ result = appenderList.remove(appender);
+ return result;
+ }
- /**
- * Remove the appender with the name passed as parameter form the list of
- * appenders.
- */
- public boolean detachAppender(String name) {
- if (name == null) {
- return false;
- }
- boolean removed = false;
- for (Appender<E> a : appenderList) {
- if (name.equals((a).getName())) {
- removed = appenderList.remove(a);
- break;
- }
- }
- return removed;
+ /**
+ * Remove the appender with the name passed as parameter form the list of
+ * appenders.
+ */
+ public boolean detachAppender(String name) {
+ if (name == null) {
+ return false;
}
+ boolean removed = false;
+ for (Appender<E> a : appenderList) {
+ if (name.equals((a).getName())) {
+ removed = appenderList.remove(a);
+ break;
+ }
+ }
+ return removed;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/ComponentTracker.java b/logback-core/src/main/java/ch/qos/logback/core/spi/ComponentTracker.java
index 8f5f701..a6ba061 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/ComponentTracker.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/ComponentTracker.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.spi;
+
import ch.qos.logback.core.CoreConstants;
import java.util.Collection;
@@ -33,73 +34,77 @@ import java.util.Set;
*/
public interface ComponentTracker<C> {
- /**
- * The default timeout duration is 30 minutes
- */
- public final int DEFAULT_TIMEOUT = (int) (30 * 60 * CoreConstants.MILLIS_IN_ONE_SECOND); // 30 minutes
-
- /**
- * By default an unlimited number of elements can be tracked.
- */
- int DEFAULT_MAX_COMPONENTS = Integer.MAX_VALUE;
-
- /**
- * Returns the number of components tracked.
- * @return number of components
- */
- int getComponentCount();
-
- /**
- * Find the component identified by 'key', without updating the timestamp. Returns null if no
- * corresponding component could be found.
- *
- * @param key
- * @return corresponding component, may be null
- */
- C find(String key);
-
- /**
- * Get the component identified by 'key', updating its timestamp in the
- * process. If the corresponding component could not be found, it is created.
- *
- * @param key
- * @param timestamp
- * @return
- */
- C getOrCreate(String key, long timestamp);
-
- /**
- * Remove components which are deemed stale. Components which have not
- * been accessed for more than a user-specified duration are deemed stale.
- *
- * <p>If the number of components exceeds, {@link #getComponentCount()},
- * components in excess will be removed.</p>
- *
- * <p>Depending on the component type, components will be cleared or stopped
- * (as appropriate) right before removal.</p>
- *
- * @param now current time in milliseconds
- */
- void removeStaleComponents(long now);
-
- /**
- * Mark component identified by 'key' as having reached its end-of-life. End-of-lifed
- * components will linger for a few more seconds before being removed.
- *
- * @param key
- */
- void endOfLife(String key);
-
- /**
- * Returns the collection of all components tracked by this instance.
- * @return collection of components
- */
- Collection<C> allComponents();
-
- /**
- * Set of all keys in this tracker in no particular order.
- *
- * @return
- */
- Set<String> allKeys();
+ /**
+ * The default timeout duration is 30 minutes
+ */
+ public final int DEFAULT_TIMEOUT = 30 * 60 * CoreConstants.MILLIS_IN_ONE_SECOND; // 30 minutes
+
+ /**
+ * By default an unlimited number of elements can be tracked.
+ */
+ int DEFAULT_MAX_COMPONENTS = Integer.MAX_VALUE;
+
+ /**
+ * Returns the number of components tracked.
+ * @return number of components
+ */
+ int getComponentCount();
+
+
+ /**
+ * Find the component identified by 'key', without updating the timestamp. Returns null if no
+ * corresponding component could be found.
+ *
+ * @param key
+ * @return corresponding component, may be null
+ */
+ C find(String key);
+
+ /**
+ * Get the component identified by 'key', updating its timestamp in the
+ * process. If the corresponding component could not be found, it is created.
+ *
+ * @param key
+ * @param timestamp
+ * @return
+ */
+ C getOrCreate(String key, long timestamp);
+
+
+ /**
+ * Remove components which are deemed stale. Components which have not
+ * been accessed for more than a user-specified duration are deemed stale.
+ *
+ * <p>If the number of components exceeds, {@link #getComponentCount()},
+ * components in excess will be removed.</p>
+ *
+ * <p>Depending on the component type, components will be cleared or stopped
+ * (as appropriate) right before removal.</p>
+ *
+ * @param now current time in milliseconds
+ */
+ void removeStaleComponents(long now);
+
+
+ /**
+ * Mark component identified by 'key' as having reached its end-of-life. End-of-lifed
+ * components will linger for a few more seconds before being removed.
+ *
+ * @param key
+ */
+ void endOfLife(String key);
+
+ /**
+ * Returns the collection of all components tracked by this instance.
+ * @return collection of components
+ */
+ Collection<C> allComponents();
+
+
+ /**
+ * Set of all keys in this tracker in no particular order.
+ *
+ * @return
+ */
+ Set<String> allKeys();
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/ContextAware.java b/logback-core/src/main/java/ch/qos/logback/core/spi/ContextAware.java
index 881ae40..3096ac8 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/ContextAware.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/ContextAware.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,27 +16,28 @@ package ch.qos.logback.core.spi;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.status.Status;
+
/**
* An object which has a context and add methods for updating internal status messages.
*/
public interface ContextAware {
- void setContext(Context context);
+ void setContext(Context context);
- Context getContext();
+ Context getContext();
- void addStatus(Status status);
+ void addStatus(Status status);
- void addInfo(String msg);
+ void addInfo(String msg);
- void addInfo(String msg, Throwable ex);
+ void addInfo(String msg, Throwable ex);
- void addWarn(String msg);
+ void addWarn(String msg);
- void addWarn(String msg, Throwable ex);
+ void addWarn(String msg, Throwable ex);
- void addError(String msg);
+ void addError(String msg);
- void addError(String msg, Throwable ex);
+ void addError(String msg, Throwable ex);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/ContextAwareBase.java b/logback-core/src/main/java/ch/qos/logback/core/spi/ContextAwareBase.java
index b8a7f67..8b8e4d2 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/ContextAwareBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/ContextAwareBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,81 +27,80 @@ import ch.qos.logback.core.status.WarnStatus;
* @author Ceki Gülcü
*/
public class ContextAwareBase implements ContextAware {
- private int noContextWarning = 0;
- protected Context context;
- final Object declaredOrigin;
+ private int noContextWarning = 0;
+ protected Context context;
+ final Object declaredOrigin;
- public ContextAwareBase() {
- declaredOrigin = this;
- }
+ public ContextAwareBase() {
+ declaredOrigin = this;
+ }
+ public ContextAwareBase(ContextAware declaredOrigin) {
+ this.declaredOrigin = declaredOrigin;
+ }
- public ContextAwareBase(ContextAware declaredOrigin) {
- this.declaredOrigin = declaredOrigin;
+ public void setContext(Context context) {
+ if (this.context == null) {
+ this.context = context;
+ } else if (this.context != context) {
+ throw new IllegalStateException("Context has been already set");
}
+ }
- public void setContext(Context context) {
- if (this.context == null) {
- this.context = context;
- } else if (this.context != context) {
- throw new IllegalStateException("Context has been already set");
- }
- }
+ public Context getContext() {
+ return this.context;
+ }
- public Context getContext() {
- return this.context;
+ public StatusManager getStatusManager() {
+ if (context == null) {
+ return null;
}
+ return context.getStatusManager();
+ }
- public StatusManager getStatusManager() {
- if (context == null) {
- return null;
- }
- return context.getStatusManager();
- }
+ /**
+ * The declared origin of status messages. By default 'this'. Derived classes may override this
+ * method to declare other origin.
+ *
+ * @return the declared origin, by default 'this'
+ */
+ protected Object getDeclaredOrigin() {
+ return declaredOrigin;
+ }
- /**
- * The declared origin of status messages. By default 'this'. Derived classes may override this
- * method to declare other origin.
- *
- * @return the declared origin, by default 'this'
- */
- protected Object getDeclaredOrigin() {
- return declaredOrigin;
+ public void addStatus(Status status) {
+ if (context == null) {
+ if (noContextWarning++ == 0) {
+ System.out.println("LOGBACK: No context given for " + this);
+ }
+ return;
}
-
- public void addStatus(Status status) {
- if (context == null) {
- if (noContextWarning++ == 0) {
- System.out.println("LOGBACK: No context given for " + this);
- }
- return;
- }
- StatusManager sm = context.getStatusManager();
- if (sm != null) {
- sm.add(status);
- }
+ StatusManager sm = context.getStatusManager();
+ if (sm != null) {
+ sm.add(status);
}
+ }
- public void addInfo(String msg) {
- addStatus(new InfoStatus(msg, getDeclaredOrigin()));
- }
+ public void addInfo(String msg) {
+ addStatus(new InfoStatus(msg, getDeclaredOrigin()));
+ }
- public void addInfo(String msg, Throwable ex) {
- addStatus(new InfoStatus(msg, getDeclaredOrigin(), ex));
- }
+ public void addInfo(String msg, Throwable ex) {
+ addStatus(new InfoStatus(msg, getDeclaredOrigin(), ex));
+ }
- public void addWarn(String msg) {
- addStatus(new WarnStatus(msg, getDeclaredOrigin()));
- }
+ public void addWarn(String msg) {
+ addStatus(new WarnStatus(msg, getDeclaredOrigin()));
+ }
- public void addWarn(String msg, Throwable ex) {
- addStatus(new WarnStatus(msg, getDeclaredOrigin(), ex));
- }
+ public void addWarn(String msg, Throwable ex) {
+ addStatus(new WarnStatus(msg, getDeclaredOrigin(), ex));
+ }
- public void addError(String msg) {
- addStatus(new ErrorStatus(msg, getDeclaredOrigin()));
- }
+ public void addError(String msg) {
+ addStatus(new ErrorStatus(msg, getDeclaredOrigin()));
+ }
- public void addError(String msg, Throwable ex) {
- addStatus(new ErrorStatus(msg, getDeclaredOrigin(), ex));
- }
+ public void addError(String msg, Throwable ex) {
+ addStatus(new ErrorStatus(msg, getDeclaredOrigin(), ex));
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/ContextAwareImpl.java b/logback-core/src/main/java/ch/qos/logback/core/spi/ContextAwareImpl.java
index df8465b..a859acd 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/ContextAwareImpl.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/ContextAwareImpl.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,6 +20,7 @@ import ch.qos.logback.core.status.Status;
import ch.qos.logback.core.status.StatusManager;
import ch.qos.logback.core.status.WarnStatus;
+
/**
* A helper class that implements ContextAware methods. Use this class to
* implement the ContextAware interface by composition.
@@ -28,74 +29,74 @@ import ch.qos.logback.core.status.WarnStatus;
*/
public class ContextAwareImpl implements ContextAware {
- private int noContextWarning = 0;
- protected Context context;
- final Object origin;
-
- public ContextAwareImpl(Context context, Object origin) {
- this.context = context;
- this.origin = origin;
-
+ private int noContextWarning = 0;
+ protected Context context;
+ final Object origin;
+
+ public ContextAwareImpl(Context context, Object origin) {
+ this.context = context;
+ this.origin = origin;
+
+ }
+
+ protected Object getOrigin() {
+ return origin;
+ }
+
+ public void setContext(Context context) {
+ if (this.context == null) {
+ this.context = context;
+ } else if (this.context != context) {
+ throw new IllegalStateException("Context has been already set");
}
+ }
- protected Object getOrigin() {
- return origin;
- }
+ public Context getContext() {
+ return this.context;
+ }
- public void setContext(Context context) {
- if (this.context == null) {
- this.context = context;
- } else if (this.context != context) {
- throw new IllegalStateException("Context has been already set");
- }
+ public StatusManager getStatusManager() {
+ if (context == null) {
+ return null;
}
-
- public Context getContext() {
- return this.context;
- }
-
- public StatusManager getStatusManager() {
- if (context == null) {
- return null;
- }
- return context.getStatusManager();
+ return context.getStatusManager();
+ }
+
+ public void addStatus(Status status) {
+ if (context == null) {
+ if (noContextWarning++ == 0) {
+ System.out.println("LOGBACK: No context given for " + this);
+ }
+ return;
}
-
- public void addStatus(Status status) {
- if (context == null) {
- if (noContextWarning++ == 0) {
- System.out.println("LOGBACK: No context given for " + this);
- }
- return;
- }
- StatusManager sm = context.getStatusManager();
- if (sm != null) {
- sm.add(status);
- }
+ StatusManager sm = context.getStatusManager();
+ if (sm != null) {
+ sm.add(status);
}
+ }
- public void addInfo(String msg) {
- addStatus(new InfoStatus(msg, getOrigin()));
- }
+ public void addInfo(String msg) {
+ addStatus(new InfoStatus(msg, getOrigin()));
+ }
- public void addInfo(String msg, Throwable ex) {
- addStatus(new InfoStatus(msg, getOrigin(), ex));
- }
+ public void addInfo(String msg, Throwable ex) {
+ addStatus(new InfoStatus(msg, getOrigin(), ex));
+ }
- public void addWarn(String msg) {
- addStatus(new WarnStatus(msg, getOrigin()));
- }
+ public void addWarn(String msg) {
+ addStatus(new WarnStatus(msg, getOrigin()));
+ }
- public void addWarn(String msg, Throwable ex) {
- addStatus(new WarnStatus(msg, getOrigin(), ex));
- }
+ public void addWarn(String msg, Throwable ex) {
+ addStatus(new WarnStatus(msg, getOrigin(), ex));
+ }
- public void addError(String msg) {
- addStatus(new ErrorStatus(msg, getOrigin()));
- }
+ public void addError(String msg) {
+ addStatus(new ErrorStatus(msg, getOrigin()));
+ }
- public void addError(String msg, Throwable ex) {
- addStatus(new ErrorStatus(msg, getOrigin(), ex));
- }
+ public void addError(String msg, Throwable ex) {
+ addStatus(new ErrorStatus(msg, getOrigin(), ex));
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/CyclicBufferTracker.java b/logback-core/src/main/java/ch/qos/logback/core/spi/CyclicBufferTracker.java
index 6efb75e..2c5cab4 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/CyclicBufferTracker.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/CyclicBufferTracker.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,51 +20,52 @@ import java.util.*;
/**
* CyclicBufferTracker tracks {@link CyclicBuffer} instances.
*
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class CyclicBufferTracker<E> extends AbstractComponentTracker<CyclicBuffer<E>> {
- static final int DEFAULT_NUMBER_OF_BUFFERS = 64;
+ static final int DEFAULT_NUMBER_OF_BUFFERS = 64;
- static final int DEFAULT_BUFFER_SIZE = 256;
- int bufferSize = DEFAULT_BUFFER_SIZE;
+ static final int DEFAULT_BUFFER_SIZE = 256;
+ int bufferSize = DEFAULT_BUFFER_SIZE;
- public CyclicBufferTracker() {
- super();
- setMaxComponents(DEFAULT_NUMBER_OF_BUFFERS);
- }
- public int getBufferSize() {
- return bufferSize;
- }
+ public CyclicBufferTracker() {
+ super();
+ setMaxComponents(DEFAULT_NUMBER_OF_BUFFERS);
+ }
- public void setBufferSize(int bufferSize) {
- this.bufferSize = bufferSize;
- }
+ public int getBufferSize() {
+ return bufferSize;
+ }
- @Override
- protected void processPriorToRemoval(CyclicBuffer<E> component) {
- component.clear();
- }
+ public void setBufferSize(int bufferSize) {
+ this.bufferSize = bufferSize;
+ }
- @Override
- protected CyclicBuffer<E> buildComponent(String key) {
- return new CyclicBuffer<E>(bufferSize);
- }
+ @Override
+ protected void processPriorToRemoval(CyclicBuffer<E> component) {
+ component.clear();
+ }
- @Override
- protected boolean isComponentStale(CyclicBuffer<E> eCyclicBuffer) {
- return false;
- }
+ @Override
+ protected CyclicBuffer<E> buildComponent(String key) {
+ return new CyclicBuffer<E>(bufferSize);
+ }
- // for testing purposes
- List<String> liveKeysAsOrderedList() {
- return new ArrayList<String>(liveMap.keySet());
- }
+ @Override
+ protected boolean isComponentStale(CyclicBuffer<E> eCyclicBuffer) {
+ return false;
+ }
- List<String> lingererKeysAsOrderedList() {
- return new ArrayList<String>(lingerersMap.keySet());
+ // for testing purposes
+ List<String> liveKeysAsOrderedList() {
+ return new ArrayList<String>(liveMap.keySet());
+ }
- }
+ List<String> lingererKeysAsOrderedList() {
+ return new ArrayList<String>(lingerersMap.keySet());
+
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/DeferredProcessingAware.java b/logback-core/src/main/java/ch/qos/logback/core/spi/DeferredProcessingAware.java
index 403c1a4..76969b2 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/DeferredProcessingAware.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/DeferredProcessingAware.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,5 +15,5 @@ package ch.qos.logback.core.spi;
public interface DeferredProcessingAware {
- void prepareForDeferredProcessing();
+ void prepareForDeferredProcessing();
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachable.java b/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachable.java
index c79f61a..2701ab9 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachable.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachable.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,25 +23,25 @@ import ch.qos.logback.core.filter.Filter;
* @author Ceki Gülcü
*/
public interface FilterAttachable<E> {
- /**
- * Add a filter.
- */
- void addFilter(Filter<E> newFilter);
+ /**
+ * Add a filter.
+ */
+ void addFilter(Filter<E> newFilter);
- void clearAllFilters();
+ void clearAllFilters();
- /**
- * Get a copy of all the filters contained within this FilterAttachable
- * object.
- *
- * @return all attached filters as a list
- */
- List<Filter<E>> getCopyOfAttachedFiltersList();
+ /**
+ * Get a copy of all the filters contained within this FilterAttachable
+ * object.
+ *
+ * @return all attached filters as a list
+ */
+ List<Filter<E>> getCopyOfAttachedFiltersList();
- /**
- * Loop through the filters in the chain. As soon as a filter decides on
- * ACCEPT or DENY, then that value is returned. If all of the filters return
- * NEUTRAL, then NEUTRAL is returned.
- */
- FilterReply getFilterChainDecision(E event);
+ /**
+ * Loop through the filters in the chain. As soon as a filter decides on
+ * ACCEPT or DENY, then that value is returned. If all of the filters return
+ * NEUTRAL, then NEUTRAL is returned.
+ */
+ FilterReply getFilterChainDecision(E event);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachableImpl.java b/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachableImpl.java
index 0257e36..d90813c 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachableImpl.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachableImpl.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,38 +26,38 @@ import ch.qos.logback.core.filter.Filter;
*/
final public class FilterAttachableImpl<E> implements FilterAttachable<E> {
- CopyOnWriteArrayList<Filter<E>> filterList = new CopyOnWriteArrayList<Filter<E>>();
-
- /**
- * Add a filter to end of the filter list.
- */
- public void addFilter(Filter<E> newFilter) {
- filterList.add(newFilter);
- }
-
- /**
- * Clear the filter chain
- */
- public void clearAllFilters() {
- filterList.clear();
+ CopyOnWriteArrayList<Filter<E>> filterList = new CopyOnWriteArrayList<Filter<E>>();
+
+ /**
+ * Add a filter to end of the filter list.
+ */
+ public void addFilter(Filter<E> newFilter) {
+ filterList.add(newFilter);
+ }
+
+ /**
+ * Clear the filter chain
+ */
+ public void clearAllFilters() {
+ filterList.clear();
+ }
+
+ /**
+ * Loop through the filters in the list. As soon as a filter decides on
+ * ACCEPT or DENY, then that value is returned. If all of the filters return
+ * NEUTRAL, then NEUTRAL is returned.
+ */
+ public FilterReply getFilterChainDecision(E event) {
+ for (Filter<E> f : filterList) {
+ final FilterReply r = f.decide(event);
+ if (r == FilterReply.DENY || r == FilterReply.ACCEPT) {
+ return r;
+ }
}
+ return FilterReply.NEUTRAL;
+ }
- /**
- * Loop through the filters in the list. As soon as a filter decides on
- * ACCEPT or DENY, then that value is returned. If all of the filters return
- * NEUTRAL, then NEUTRAL is returned.
- */
- public FilterReply getFilterChainDecision(E event) {
- for (Filter<E> f : filterList) {
- final FilterReply r = f.decide(event);
- if (r == FilterReply.DENY || r == FilterReply.ACCEPT) {
- return r;
- }
- }
- return FilterReply.NEUTRAL;
- }
-
- public List<Filter<E>> getCopyOfAttachedFiltersList() {
- return new ArrayList<Filter<E>>(filterList);
- }
+ public List<Filter<E>> getCopyOfAttachedFiltersList() {
+ return new ArrayList<Filter<E>>(filterList);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/FilterReply.java b/logback-core/src/main/java/ch/qos/logback/core/spi/FilterReply.java
index 2691e0f..128fb2f 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/FilterReply.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/FilterReply.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.spi;
+
/**
*
* This enum represents the possible replies that a filtering component
@@ -27,5 +28,7 @@ package ch.qos.logback.core.spi;
* @author Sébastien Pennec
*/
public enum FilterReply {
- DENY, NEUTRAL, ACCEPT;
+ DENY,
+ NEUTRAL,
+ ACCEPT;
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/LifeCycle.java b/logback-core/src/main/java/ch/qos/logback/core/spi/LifeCycle.java
index 2792cd1..a6761f6 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/LifeCycle.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/LifeCycle.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,10 +15,8 @@ package ch.qos.logback.core.spi;
public interface LifeCycle {
- void start();
-
- void stop();
-
- boolean isStarted();
+ void start();
+ void stop();
+ boolean isStarted();
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/LogbackLock.java b/logback-core/src/main/java/ch/qos/logback/core/spi/LogbackLock.java
index a8b486f..03137f4 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/LogbackLock.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/LogbackLock.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,8 +17,9 @@ package ch.qos.logback.core.spi;
* This class just makes it easier to identify locks associated with logback
* when analysing thread dumps.
*
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class LogbackLock extends Object {
-
+
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/PreSerializationTransformer.java b/logback-core/src/main/java/ch/qos/logback/core/spi/PreSerializationTransformer.java
index 151ded5..203f5c8 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/PreSerializationTransformer.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/PreSerializationTransformer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,5 +24,5 @@ import java.io.Serializable;
* @param <E>
*/
public interface PreSerializationTransformer<E> {
- Serializable transform(E event);
+ Serializable transform(E event);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/PropertyContainer.java b/logback-core/src/main/java/ch/qos/logback/core/spi/PropertyContainer.java
index 0f7804c..448ef93 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/PropertyContainer.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/PropertyContainer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,7 +17,7 @@ import java.util.Map;
public interface PropertyContainer {
- String getProperty(String key);
-
- Map<String, String> getCopyOfPropertyMap();
+ String getProperty(String key);
+
+ Map<String, String> getCopyOfPropertyMap();
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/PropertyDefiner.java b/logback-core/src/main/java/ch/qos/logback/core/spi/PropertyDefiner.java
index 6072665..7027690 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/PropertyDefiner.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/PropertyDefiner.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,10 +15,10 @@ package ch.qos.logback.core.spi;
public interface PropertyDefiner extends ContextAware {
- /**
- * Get the property value, defined by this property definer
- *
- * @return defined property value
- */
- String getPropertyValue();
+ /**
+ * Get the property value, defined by this property definer
+ *
+ * @return defined property value
+ */
+ String getPropertyValue();
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/ScanException.java b/logback-core/src/main/java/ch/qos/logback/core/spi/ScanException.java
index 441fa92..8eef629 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/spi/ScanException.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/ScanException.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,20 +15,21 @@ package ch.qos.logback.core.spi;
public class ScanException extends Exception {
- private static final long serialVersionUID = -3132040414328475658L;
+ private static final long serialVersionUID = -3132040414328475658L;
- Throwable cause;
+ Throwable cause;
- public ScanException(String msg) {
- super(msg);
- }
+ public ScanException(String msg) {
+ super(msg);
+ }
- public ScanException(String msg, Throwable rootCause) {
- super(msg);
- this.cause = rootCause;
- }
+ public ScanException(String msg, Throwable rootCause) {
+ super(msg);
+ this.cause = rootCause;
+ }
- public Throwable getCause() {
- return cause;
- }
+ public Throwable getCause() {
+ return cause;
+ }
}
+
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/ErrorStatus.java b/logback-core/src/main/java/ch/qos/logback/core/status/ErrorStatus.java
index f48c50a..8f5f470 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/ErrorStatus.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/ErrorStatus.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,14 +13,16 @@
*/
package ch.qos.logback.core.status;
-public class ErrorStatus extends StatusBase {
- public ErrorStatus(String msg, Object origin) {
- super(Status.ERROR, msg, origin);
- }
- public ErrorStatus(String msg, Object origin, Throwable t) {
- super(Status.ERROR, msg, origin, t);
- }
+public class ErrorStatus extends StatusBase {
+
+ public ErrorStatus(String msg, Object origin) {
+ super(Status.ERROR, msg, origin);
+ }
+
+ public ErrorStatus(String msg, Object origin, Throwable t) {
+ super(Status.ERROR, msg, origin, t);
+ }
-}
+ }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/InfoStatus.java b/logback-core/src/main/java/ch/qos/logback/core/status/InfoStatus.java
index e4b1d88..08fb01d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/InfoStatus.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/InfoStatus.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,13 +13,15 @@
*/
package ch.qos.logback.core.status;
+
+
public class InfoStatus extends StatusBase {
- public InfoStatus(String msg, Object origin) {
- super(Status.INFO, msg, origin);
- }
+ public InfoStatus(String msg, Object origin) {
+ super(Status.INFO, msg, origin);
+ }
- public InfoStatus(String msg, Object origin, Throwable t) {
- super(Status.INFO, msg, origin, t);
- }
+ public InfoStatus(String msg, Object origin, Throwable t) {
+ super(Status.INFO, msg, origin, t);
+ }
-}
+ }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/NopStatusListener.java b/logback-core/src/main/java/ch/qos/logback/core/status/NopStatusListener.java
index d0f0869..9a630ed 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/NopStatusListener.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/NopStatusListener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,12 +16,12 @@ package ch.qos.logback.core.status;
/**
* A no-operation (nop) StatusListener
*
- * @author Ceki Gülcü
+ * @author Ceki Gücü
* @since 1.0.8
*/
public class NopStatusListener implements StatusListener {
- public void addStatusEvent(Status status) {
- // nothing to do
- }
+ public void addStatusEvent(Status status) {
+ // nothing to do
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/OnConsoleStatusListener.java b/logback-core/src/main/java/ch/qos/logback/core/status/OnConsoleStatusListener.java
index af6e74d..ca36171 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/OnConsoleStatusListener.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/OnConsoleStatusListener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,8 @@
*/
package ch.qos.logback.core.status;
+import ch.qos.logback.core.Context;
+
import java.io.PrintStream;
/**
@@ -22,9 +24,24 @@ import java.io.PrintStream;
*/
public class OnConsoleStatusListener extends OnPrintStreamStatusListenerBase {
- @Override
- protected PrintStream getPrintStream() {
- return System.out;
- }
+ @Override
+ protected PrintStream getPrintStream() {
+ return System.out;
+ }
+
+ /**
+ * This utility method adds a new OnConsoleStatusListener to the context
+ * passed as parameter.
+ *
+ * @param context
+ * @since 1.0.1
+ */
+ static public void addNewInstanceToContext(Context context) {
+ OnConsoleStatusListener onConsoleStatusListener = new OnConsoleStatusListener();
+ onConsoleStatusListener.setContext(context);
+ onConsoleStatusListener.start();
+ context.getStatusManager().add(onConsoleStatusListener);
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/OnErrorConsoleStatusListener.java b/logback-core/src/main/java/ch/qos/logback/core/status/OnErrorConsoleStatusListener.java
index f91b9c5..7558bf9 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/OnErrorConsoleStatusListener.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/OnErrorConsoleStatusListener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,13 +18,13 @@ import java.io.PrintStream;
/**
* Print all new incoming status messages on the error console (System.err).
*
- * @author Ceki Gülcü
+ * @author Ceki Gücü
* @since 1.0.8
*/
public class OnErrorConsoleStatusListener extends OnPrintStreamStatusListenerBase {
- @Override
- protected PrintStream getPrintStream() {
- return System.err;
- }
+ @Override
+ protected PrintStream getPrintStream() {
+ return System.err;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/OnPrintStreamStatusListenerBase.java b/logback-core/src/main/java/ch/qos/logback/core/status/OnPrintStreamStatusListenerBase.java
index 7a113e7..397d2ad 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/OnPrintStreamStatusListenerBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/OnPrintStreamStatusListenerBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,80 +22,72 @@ import java.util.List;
/**
* Print all new incoming status messages on the on the designated PrintStream.
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
abstract class OnPrintStreamStatusListenerBase extends ContextAwareBase implements StatusListener, LifeCycle {
- boolean isStarted = false;
-
- static final long DEFAULT_RETROSPECTIVE = 300;
- long retrospectiveThresold = DEFAULT_RETROSPECTIVE;
-
- /**
- * The PrintStream used by derived classes
- * @return
- */
- abstract protected PrintStream getPrintStream();
-
- private void print(Status status) {
- StringBuilder sb = new StringBuilder();
- StatusPrinter.buildStr(sb, "", status);
- getPrintStream().print(sb);
- }
-
- public void addStatusEvent(Status status) {
- if (!isStarted)
- return;
+ boolean isStarted = false;
+
+ static final long DEFAULT_RETROSPECTIVE = 300;
+ long retrospective = DEFAULT_RETROSPECTIVE;
+
+
+ /**
+ * The PrintStream used by derived classes
+ * @return
+ */
+ abstract protected PrintStream getPrintStream();
+
+ private void print(Status status) {
+ StringBuilder sb = new StringBuilder();
+ StatusPrinter.buildStr(sb, "", status);
+ getPrintStream().print(sb);
+ }
+
+ public void addStatusEvent(Status status) {
+ if (!isStarted)
+ return;
+ print(status);
+ }
+
+ /**
+ * Print status messages retrospectively
+ */
+ private void retrospectivePrint() {
+ if(context == null)
+ return;
+ long now = System.currentTimeMillis();
+ StatusManager sm = context.getStatusManager();
+ List<Status> statusList = sm.getCopyOfStatusList();
+ for (Status status : statusList) {
+ long timestamp = status.getDate();
+ if (now - timestamp < retrospective) {
print(status);
+ }
}
+ }
- /**
- * Print status messages retrospectively
- */
- private void retrospectivePrint() {
- if (context == null)
- return;
- long now = System.currentTimeMillis();
- StatusManager sm = context.getStatusManager();
- List<Status> statusList = sm.getCopyOfStatusList();
- for (Status status : statusList) {
- long timestampOfStatusMesage = status.getDate();
- if (isElapsedTimeLongerThanThreshold(now, timestampOfStatusMesage)) {
- print(status);
- }
- }
+ public void start() {
+ isStarted = true;
+ if (retrospective > 0) {
+ retrospectivePrint();
}
+ }
- private boolean isElapsedTimeLongerThanThreshold(long now, long timestamp) {
- long elapsedTime = now - timestamp;
- return elapsedTime < retrospectiveThresold;
- }
+ public void setRetrospective(long retrospective) {
+ this.retrospective = retrospective;
+ }
- /**
- * Invoking the start method can cause the instance to print status messages created less than
- * value of retrospectiveThresold.
- */
- public void start() {
- isStarted = true;
- if (retrospectiveThresold > 0) {
- retrospectivePrint();
- }
- }
+ public long getRetrospective() {
+ return retrospective;
+ }
- public void setRetrospective(long retrospective) {
- this.retrospectiveThresold = retrospective;
- }
-
- public long getRetrospective() {
- return retrospectiveThresold;
- }
+ public void stop() {
+ isStarted = false;
+ }
- public void stop() {
- isStarted = false;
- }
-
- public boolean isStarted() {
- return isStarted;
- }
+ public boolean isStarted() {
+ return isStarted;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/Status.java b/logback-core/src/main/java/ch/qos/logback/core/status/Status.java
index 39467ec..d571d8d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/Status.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/Status.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,30 +15,23 @@ package ch.qos.logback.core.status;
import java.util.Iterator;
-public interface Status {
- int INFO = 0;
- int WARN = 1;
- int ERROR = 2;
-
- int getLevel();
-
- int getEffectiveLevel();
-
- Object getOrigin();
-
- String getMessage();
-
- Throwable getThrowable();
-
- Long getDate();
-
- boolean hasChildren();
-
- void add(Status child);
-
- boolean remove(Status child);
-
- Iterator<Status> iterator();
+public interface Status {
+
+ int INFO = 0;
+ int WARN = 1;
+ int ERROR = 2;
+
+ int getLevel();
+ int getEffectiveLevel();
+ Object getOrigin();
+ String getMessage();
+ Throwable getThrowable();
+ Long getDate();
+
+ boolean hasChildren();
+ void add(Status child);
+ boolean remove(Status child);
+ Iterator<Status> iterator();
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/StatusBase.java b/logback-core/src/main/java/ch/qos/logback/core/status/StatusBase.java
index 69162b0..67d0da1 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/StatusBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/StatusBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,156 +19,157 @@ import java.util.List;
abstract public class StatusBase implements Status {
- static private final List<Status> EMPTY_LIST = new ArrayList<Status>(0);
-
- int level;
- final String message;
- final Object origin;
- List<Status> childrenList;
- Throwable throwable;
- long date;
-
- StatusBase(int level, String msg, Object origin) {
- this(level, msg, origin, null);
- }
-
- StatusBase(int level, String msg, Object origin, Throwable t) {
- this.level = level;
- this.message = msg;
- this.origin = origin;
- this.throwable = t;
- this.date = System.currentTimeMillis();
- }
-
- public synchronized void add(Status child) {
- if (child == null) {
- throw new NullPointerException("Null values are not valid Status.");
- }
- if (childrenList == null) {
- childrenList = new ArrayList<Status>();
- }
- childrenList.add(child);
- }
-
- public synchronized boolean hasChildren() {
- return ((childrenList != null) && (childrenList.size() > 0));
- }
-
- public synchronized Iterator<Status> iterator() {
- if (childrenList != null) {
- return childrenList.iterator();
- } else {
- return EMPTY_LIST.iterator();
- }
+ static private final List<Status> EMPTY_LIST = new ArrayList<Status>(0);
+
+ int level;
+ final String message;
+ final Object origin;
+ List<Status> childrenList;
+ Throwable throwable;
+ long date;
+
+ StatusBase(int level, String msg, Object origin) {
+ this(level, msg, origin, null);
+ }
+
+ StatusBase(int level, String msg, Object origin, Throwable t) {
+ this.level = level;
+ this.message = msg;
+ this.origin = origin;
+ this.throwable = t;
+ this.date = System.currentTimeMillis();
+ }
+
+ public synchronized void add(Status child) {
+ if (child == null) {
+ throw new NullPointerException("Null values are not valid Status.");
}
-
- public synchronized boolean remove(Status statusToRemove) {
- if (childrenList == null) {
- return false;
- }
- // TODO also search in childrens' children
- return childrenList.remove(statusToRemove);
- }
-
- public int getLevel() {
- return level;
- }
-
- // status messages are not supposed to contains cycles.
- // cyclic status arrangements are like to cause deadlocks
- // when this method is called from different thread on
- // different status objects lying on the same cycle
- public synchronized int getEffectiveLevel() {
- int result = level;
- int effLevel;
-
- Iterator<Status> it = iterator();
- Status s;
- while (it.hasNext()) {
- s = (Status) it.next();
- effLevel = s.getEffectiveLevel();
- if (effLevel > result) {
- result = effLevel;
- }
- }
- return result;
+ if (childrenList == null) {
+ childrenList = new ArrayList<Status>();
}
-
- public String getMessage() {
- return message;
+ childrenList.add(child);
+ }
+
+ public synchronized boolean hasChildren() {
+ return ((childrenList != null) && (childrenList.size() > 0));
+ }
+
+ public synchronized Iterator<Status> iterator() {
+ if (childrenList != null) {
+ return childrenList.iterator();
+ } else {
+ return EMPTY_LIST.iterator();
}
+ }
- public Object getOrigin() {
- return origin;
+ public synchronized boolean remove(Status statusToRemove) {
+ if (childrenList == null) {
+ return false;
}
-
- public Throwable getThrowable() {
- return throwable;
+ // TODO also search in childrens' children
+ return childrenList.remove(statusToRemove);
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ // status messages are not supposed to contains cycles.
+ // cyclic status arrangements are like to cause deadlocks
+ // when this method is called from different thread on
+ // different status objects lying on the same cycle
+ public synchronized int getEffectiveLevel() {
+ int result = level;
+ int effLevel;
+
+ Iterator it = iterator();
+ Status s;
+ while (it.hasNext()) {
+ s = (Status) it.next();
+ effLevel = s.getEffectiveLevel();
+ if (effLevel > result) {
+ result = effLevel;
+ }
}
-
- public Long getDate() {
- return date;
+ return result;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public Object getOrigin() {
+ return origin;
+ }
+
+ public Throwable getThrowable() {
+ return throwable;
+ }
+
+ public Long getDate() {
+ return date;
+ }
+
+ /**
+ * @Override
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ switch (getEffectiveLevel()) {
+ case INFO:
+ buf.append("INFO");
+ break;
+ case WARN:
+ buf.append("WARN");
+ break;
+ case ERROR:
+ buf.append("ERROR");
+ break;
}
-
- /**
- * @Override
- */
- public String toString() {
- StringBuilder buf = new StringBuilder();
- switch (getEffectiveLevel()) {
- case INFO:
- buf.append("INFO");
- break;
- case WARN:
- buf.append("WARN");
- break;
- case ERROR:
- buf.append("ERROR");
- break;
- }
- if (origin != null) {
- buf.append(" in ");
- buf.append(origin);
- buf.append(" -");
- }
-
- buf.append(" ");
- buf.append(message);
-
- if (throwable != null) {
- buf.append(" ");
- buf.append(throwable);
- }
-
- return buf.toString();
+ if (origin != null) {
+ buf.append(" in ");
+ buf.append(origin);
+ buf.append(" -");
}
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + level;
- result = prime * result + ((message == null) ? 0 : message.hashCode());
- return result;
- }
+ buf.append(" ");
+ buf.append(message);
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final StatusBase other = (StatusBase) obj;
- if (level != other.level)
- return false;
- if (message == null) {
- if (other.message != null)
- return false;
- } else if (!message.equals(other.message))
- return false;
- return true;
+ if (throwable != null) {
+ buf.append(" ");
+ buf.append(throwable);
}
+ return buf.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + level;
+ result = prime * result + ((message == null) ? 0 : message.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final StatusBase other = (StatusBase) obj;
+ if (level != other.level)
+ return false;
+ if (message == null) {
+ if (other.message != null)
+ return false;
+ } else if (!message.equals(other.message))
+ return false;
+ return true;
+ }
+
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/StatusListener.java b/logback-core/src/main/java/ch/qos/logback/core/status/StatusListener.java
index a210822..5d209ce 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/StatusListener.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/StatusListener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,5 +20,5 @@ package ch.qos.logback.core.status;
* @author Ceki Gülcü
*/
public interface StatusListener {
- void addStatusEvent(Status status);
+ void addStatusEvent(Status status);
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/StatusListenerAsList.java b/logback-core/src/main/java/ch/qos/logback/core/status/StatusListenerAsList.java
index 49bb555..f1618b9 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/StatusListenerAsList.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/StatusListenerAsList.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,14 +24,15 @@ import java.util.List;
*/
public class StatusListenerAsList implements StatusListener {
- List<Status> statusList = new ArrayList<Status>();
+ List<Status> statusList = new ArrayList<Status>();
- public void addStatusEvent(Status status) {
- statusList.add(status);
- }
-
- public List<Status> getStatusList() {
- return statusList;
- }
+ public void addStatusEvent(Status status) {
+ statusList.add(status);
+ }
+ public List<Status> getStatusList() {
+ return statusList;
+ }
+
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/StatusManager.java b/logback-core/src/main/java/ch/qos/logback/core/status/StatusManager.java
index a499158..75c50bc 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/StatusManager.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/StatusManager.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,69 +18,63 @@ import java.util.List;
/**
* Internal error messages (statii) are managed by instances of this interface.
*
- * @author Ceki Gülcü
+ * @author Ceki Gulcu
*/
public interface StatusManager {
- /**
- * Add a new status message.
- *
- * @param status
- */
- void add(Status status);
+ /**
+ * Add a new status message.
+ *
+ * @param status
+ */
+ void add(Status status);
- /**
- * Obtain a copy of the status list maintained by this StatusManager.
- *
- * @return
- */
- List<Status> getCopyOfStatusList();
+ /**
+ * Obtain a copy of the status list maintained by this StatusManager.
+ *
+ * @return
+ */
+ List<Status> getCopyOfStatusList();
- /**
- * Return the highest level of all the statii.
- *
- * @return
- */
- // int getLevel();
+ /**
+ * Return the highest level of all the statii.
+ *
+ * @return
+ */
+ //int getLevel();
- /**
- * Return the number of status entries.
- *
- * @return
- */
- int getCount();
+ /**
+ * Return the number of status entries.
+ *
+ * @return
+ */
+ int getCount();
- /**
- * Add a status listener.
- * @param listener
- */
+ /**
+ * Add a status listener.
+ * @param listener
+ */
+ void add(StatusListener listener);
+
+ /**
+ * Remove a status listener.
+ *
+ * @param listener
+ */
+ void remove(StatusListener listener);
- /**
- * Add a status listener. The StatusManager may decide to skip installation if an
- * earlier instance was already installed.
- *
- * @param listener
- * @return true if actually added, false if skipped
- */
- boolean add(StatusListener listener);
- /**);
- * Remove a status listener.
- *
- * @param listener
- */
- void remove(StatusListener listener);
+ /**
+ * Clear the list of status messages.
+ */
+ void clear();
- /**
- * Clear the list of status messages.
- */
- void clear();
-
- /**
- * Obtain a copy of the status listener list maintained by this StatusManager
- *
- * @return
- */
- List<StatusListener> getCopyOfStatusListenerList();
+
+ /**
+ * Obtain a copy of the status listener list maintained by this StatusManager
+ *
+ * @return
+ */
+ List<StatusListener> getCopyOfStatusListenerList();
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/StatusUtil.java b/logback-core/src/main/java/ch/qos/logback/core/status/StatusUtil.java
index 482c8f8..f8c803f 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/StatusUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/StatusUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,168 +24,162 @@ import java.util.regex.Pattern;
public class StatusUtil {
- StatusManager sm;
-
- public StatusUtil(StatusManager sm) {
- this.sm = sm;
- }
-
- public StatusUtil(Context context) {
- this.sm = context.getStatusManager();
- }
-
- /**
- * Returns true if the StatusManager associated with the context passed
- * as parameter has one or more StatusListener instances registered. Returns
- * false otherwise.
- *
- * @param context
- * @return true if one or more StatusListeners registered, false otherwise
- * @since 1.0.8
- */
- static public boolean contextHasStatusListener(Context context) {
- StatusManager sm = context.getStatusManager();
- if (sm == null)
- return false;
- List<StatusListener> listeners = sm.getCopyOfStatusListenerList();
- if (listeners == null || listeners.size() == 0)
- return false;
- else
- return true;
- }
-
- static public List<Status> filterStatusListByTimeThreshold(List<Status> rawList, long threshold) {
- List<Status> filteredList = new ArrayList<Status>();
- for (Status s : rawList) {
- if (s.getDate() >= threshold)
- filteredList.add(s);
- }
- return filteredList;
- }
-
- public void addStatus(Status status) {
- if (sm != null) {
- sm.add(status);
- }
- }
-
- public void addInfo(Object caller, String msg) {
- addStatus(new InfoStatus(msg, caller));
- }
-
- public void addWarn(Object caller, String msg) {
- addStatus(new WarnStatus(msg, caller));
- }
-
- public void addError(Object caller, String msg, Throwable t) {
- addStatus(new ErrorStatus(msg, caller, t));
- }
-
- public boolean hasXMLParsingErrors(long threshold) {
- return containsMatch(threshold, Status.ERROR, CoreConstants.XML_PARSING);
- }
-
- public boolean noXMLParsingErrorsOccurred(long threshold) {
- return !hasXMLParsingErrors(threshold);
- }
-
- public int getHighestLevel(long threshold) {
- List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
- int maxLevel = Status.INFO;
- for (Status s : filteredList) {
- if (s.getLevel() > maxLevel)
- maxLevel = s.getLevel();
- }
- return maxLevel;
- }
-
- public boolean isErrorFree(long threshold) {
- return Status.ERROR > getHighestLevel(threshold);
- }
-
- public boolean isWarningOrErrorFree(long threshold) {
- return Status.WARN > getHighestLevel(threshold);
- }
-
- public boolean containsMatch(long threshold, int level, String regex) {
- List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
- Pattern p = Pattern.compile(regex);
-
- for (Status status : filteredList) {
- if (level != status.getLevel()) {
- continue;
- }
- String msg = status.getMessage();
- Matcher matcher = p.matcher(msg);
- if (matcher.lookingAt()) {
- return true;
- }
- }
- return false;
- }
-
- public boolean containsMatch(int level, String regex) {
- return containsMatch(0, level, regex);
- }
-
- public boolean containsMatch(String regex) {
- Pattern p = Pattern.compile(regex);
- for (Status status : sm.getCopyOfStatusList()) {
- String msg = status.getMessage();
- Matcher matcher = p.matcher(msg);
- if (matcher.lookingAt()) {
- return true;
- }
- }
- return false;
- }
-
- public int matchCount(String regex) {
- int count = 0;
- Pattern p = Pattern.compile(regex);
- for (Status status : sm.getCopyOfStatusList()) {
- String msg = status.getMessage();
- Matcher matcher = p.matcher(msg);
- if (matcher.lookingAt()) {
- count++;
- }
- }
- return count;
- }
-
- public boolean containsException(Class<?> exceptionType) {
- Iterator<Status> stati = sm.getCopyOfStatusList().iterator();
- while (stati.hasNext()) {
- Status status = stati.next();
- Throwable t = status.getThrowable();
- while (t != null) {
- if (t.getClass().getName().equals(exceptionType.getName())) {
- return true;
- }
- t = t.getCause();
- }
- }
- return false;
- }
-
- /**
- * Return the time of last reset. -1 if last reset time could not be found
- *
- * @return time of last reset or -1
- */
- public long timeOfLastReset() {
- List<Status> statusList = sm.getCopyOfStatusList();
- if (statusList == null)
- return -1;
-
- int len = statusList.size();
- for (int i = len - 1; i >= 0; i--) {
- Status s = statusList.get(i);
- if (CoreConstants.RESET_MSG_PREFIX.equals(s.getMessage())) {
- return s.getDate();
- }
- }
- return -1;
- }
+ StatusManager sm;
+
+ public StatusUtil(StatusManager sm) {
+ this.sm = sm;
+ }
+
+ public StatusUtil(Context context) {
+ this.sm = context.getStatusManager();
+ }
+
+ /**
+ * Returns true if the StatusManager associated with the context passed
+ * as parameter has one or more StatusListener instances registered. Returns
+ * false otherwise.
+ *
+ * @param context
+ * @return true if one or more StatusListeners registered, false otherwise
+ * @since 1.0.8
+ */
+ static public boolean contextHasStatusListener(Context context) {
+ StatusManager sm = context.getStatusManager();
+ if(sm == null)
+ return false;
+ List<StatusListener> listeners = sm.getCopyOfStatusListenerList();
+ if(listeners == null || listeners.size() == 0)
+ return false;
+ else
+ return true;
+ }
+
+ static public List<Status> filterStatusListByTimeThreshold(List<Status> rawList, long threshold) {
+ List<Status> filteredList = new ArrayList<Status>();
+ for (Status s : rawList) {
+ if (s.getDate() >= threshold)
+ filteredList.add(s);
+ }
+ return filteredList;
+ }
+
+ public void addStatus(Status status) {
+ if (sm != null) {
+ sm.add(status);
+ }
+ }
+
+ public void addInfo(Object caller, String msg) {
+ addStatus(new InfoStatus(msg, caller));
+ }
+
+ public void addWarn(Object caller, String msg) {
+ addStatus(new WarnStatus(msg, caller));
+ }
+
+ public void addError(Object caller, String msg,
+ Throwable t) {
+ addStatus(new ErrorStatus(msg, caller, t));
+ }
+
+ public boolean hasXMLParsingErrors(long threshold) {
+ return containsMatch(threshold, Status.ERROR, CoreConstants.XML_PARSING);
+ }
+
+ public boolean noXMLParsingErrorsOccurred(long threshold) {
+ return !hasXMLParsingErrors(threshold);
+ }
+
+ public int getHighestLevel(long threshold) {
+ List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
+ int maxLevel = Status.INFO;
+ for (Status s : filteredList) {
+ if (s.getLevel() > maxLevel)
+ maxLevel = s.getLevel();
+ }
+ return maxLevel;
+ }
+
+ public boolean isErrorFree(long threshold) {
+ return Status.ERROR > getHighestLevel(threshold);
+ }
+
+ public boolean containsMatch(long threshold, int level, String regex) {
+ List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
+ Pattern p = Pattern.compile(regex);
+
+ for (Status status : filteredList) {
+ if (level != status.getLevel()) {
+ continue;
+ }
+ String msg = status.getMessage();
+ Matcher matcher = p.matcher(msg);
+ if (matcher.lookingAt()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean containsMatch(int level, String regex) {
+ return containsMatch(0, level, regex);
+ }
+
+ public boolean containsMatch(String regex) {
+ Pattern p = Pattern.compile(regex);
+ for (Status status : sm.getCopyOfStatusList()) {
+ String msg = status.getMessage();
+ Matcher matcher = p.matcher(msg);
+ if (matcher.lookingAt()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public int matchCount(String regex) {
+ int count = 0;
+ Pattern p = Pattern.compile(regex);
+ for (Status status : sm.getCopyOfStatusList()) {
+ String msg = status.getMessage();
+ Matcher matcher = p.matcher(msg);
+ if (matcher.lookingAt()) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ public boolean containsException(Class<?> exceptionType) {
+ Iterator<Status> stati = sm.getCopyOfStatusList().iterator();
+ while (stati.hasNext()) {
+ Status status = stati.next();
+ Throwable t = status.getThrowable();
+ if (t != null && t.getClass().getName().equals(exceptionType.getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return the time of last reset. -1 if last reset time could not be found
+ *
+ * @return time of last reset or -1
+ */
+ public long timeOfLastReset() {
+ List<Status> statusList = sm.getCopyOfStatusList();
+ if (statusList == null)
+ return -1;
+
+ int len = statusList.size();
+ for (int i = len - 1; i >= 0; i--) {
+ Status s = statusList.get(i);
+ if (CoreConstants.RESET_MSG_PREFIX.equals(s.getMessage())) {
+ return s.getDate();
+ }
+ }
+ return -1;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/ViewStatusMessagesServletBase.java b/logback-core/src/main/java/ch/qos/logback/core/status/ViewStatusMessagesServletBase.java
index 3f7f861..59f2581 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/ViewStatusMessagesServletBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/ViewStatusMessagesServletBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,155 +31,165 @@ import ch.qos.logback.core.util.CachingDateFormatter;
abstract public class ViewStatusMessagesServletBase extends HttpServlet {
- private static final long serialVersionUID = -3551928133801157219L;
- private static CachingDateFormatter SDF = new CachingDateFormatter("yyyy-MM-dd HH:mm:ss");
+ private static final long serialVersionUID = -3551928133801157219L;
+ private static CachingDateFormatter SDF = new CachingDateFormatter(
+ "yyyy-MM-dd HH:mm:ss");
- static String SUBMIT = "submit";
- static String CLEAR = "Clear";
+ static String SUBMIT = "submit";
+ static String CLEAR = "Clear";
- protected abstract StatusManager getStatusManager(HttpServletRequest req, HttpServletResponse resp);
+ protected abstract StatusManager getStatusManager(HttpServletRequest req, HttpServletResponse resp);
- protected abstract String getPageTitle(HttpServletRequest req, HttpServletResponse resp);
+ protected abstract String getPageTitle(HttpServletRequest req, HttpServletResponse resp);
- int count;
+ int count;
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ protected void service(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
- count = 0;
- StatusManager sm = getStatusManager(req, resp);
+ count = 0;
+ StatusManager sm = getStatusManager(req, resp);
- resp.setContentType("text/html");
- PrintWriter output = resp.getWriter();
+ resp.setContentType("text/html");
+ PrintWriter output = resp.getWriter();
- output.append("<html>\r\n");
- output.append("<head>\r\n");
- printCSS(req.getContextPath(), output);
- output.append("</head>\r\n");
- output.append("<body>\r\n");
- output.append(getPageTitle(req, resp));
+ output.append("<html>\r\n");
+ output.append("<head>\r\n");
+ printCSS(req.getContextPath(), output);
+ output.append("</head>\r\n");
+ output.append("<body>\r\n");
+ output.append(getPageTitle(req, resp));
- output.append("<form method=\"POST\">\r\n");
- output.append("<input type=\"submit\" name=\"" + SUBMIT + "\" value=\"" + CLEAR + "\">");
- output.append("</form>\r\n");
- if (CLEAR.equalsIgnoreCase(req.getParameter(SUBMIT))) {
- sm.clear();
- sm.add(new InfoStatus("Cleared all status messages", this));
- }
+ output.append("<form method=\"POST\">\r\n");
+ output.append("<input type=\"submit\" name=\""+SUBMIT+"\" value=\""+CLEAR+"\">");
+ output.append("</form>\r\n");
- output.append("<table>");
- StringBuilder buf = new StringBuilder();
- if (sm != null) {
- printList(buf, sm);
- } else {
- output.append("Could not find status manager");
- }
- output.append(buf);
- output.append("</table>");
- output.append("</body>\r\n");
- output.append("</html>\r\n");
- output.flush();
- output.close();
- }
-
- public void printCSS(String localRef, PrintWriter output) {
- output.append(" <STYLE TYPE=\"text/css\">\r\n");
- output.append(" .warn { font-weight: bold; color: #FF6600;} \r\n"); // orange
- output.append(" .error { font-weight: bold; color: #CC0000;} \r\n");
- output.append(" table { margin-left: 2em; margin-right: 2em; border-left: 2px solid #AAA; }\r\n");
- output.append(" tr.even { background: #FFFFFF; }\r\n");
- output.append(" tr.odd { background: #EAEAEA; }\r\n");
- output.append(" td { padding-right: 1ex; padding-left: 1ex; border-right: 2px solid #AAA; }\r\n");
- output.append(" td.date { text-align: right; font-family: courier, monospace; font-size: smaller; }");
- output.append(LINE_SEPARATOR);
-
- output.append(" td.level { text-align: right; }");
- output.append(LINE_SEPARATOR);
- output.append(" tr.header { background: #596ED5; color: #FFF; font-weight: bold; font-size: larger; }");
- output.append(CoreConstants.LINE_SEPARATOR);
-
- output.append(" td.exception { background: #A2AEE8; white-space: pre; font-family: courier, monospace;}");
- output.append(LINE_SEPARATOR);
-
- output.append(" </STYLE>\r\n");
+ if(CLEAR.equalsIgnoreCase(req.getParameter(SUBMIT))) {
+ sm.clear();
+ sm.add(new InfoStatus("Cleared all status messages", this));
}
-
- public void printList(StringBuilder buf, StatusManager sm) {
- buf.append("<table>\r\n");
- printHeader(buf);
- List<Status> statusList = sm.getCopyOfStatusList();
- for (Status s : statusList) {
- count++;
- printStatus(buf, s);
- }
- buf.append("</table>\r\n");
+
+ output.append("<table>");
+ StringBuilder buf = new StringBuilder();
+ if(sm != null) {
+ printList(buf, sm);
+ } else {
+ output.append("Could not find status manager");
}
-
- public void printHeader(StringBuilder buf) {
- buf.append(" <tr class=\"header\">\r\n");
- buf.append(" <th>Date </th>\r\n");
- buf.append(" <th>Level</th>\r\n");
- buf.append(" <th>Origin</th>\r\n");
- buf.append(" <th>Message</th>\r\n");
- buf.append(" </tr>\r\n");
-
+ output.append(buf);
+ output.append("</table>");
+ output.append("</body>\r\n");
+ output.append("</html>\r\n");
+ output.flush();
+ output.close();
+ }
+
+ public void printCSS(String localRef, PrintWriter output) {
+ output.append(" <STYLE TYPE=\"text/css\">\r\n");
+ output.append(" .warn { font-weight: bold; color: #FF6600;} \r\n"); // orange
+ output.append(" .error { font-weight: bold; color: #CC0000;} \r\n");
+ output
+ .append(" table { margin-left: 2em; margin-right: 2em; border-left: 2px solid #AAA; }\r\n");
+ output.append(" tr.even { background: #FFFFFF; }\r\n");
+ output.append(" tr.odd { background: #EAEAEA; }\r\n");
+ output
+ .append(" td { padding-right: 1ex; padding-left: 1ex; border-right: 2px solid #AAA; }\r\n");
+ output
+ .append(" td.date { text-align: right; font-family: courier, monospace; font-size: smaller; }");
+ output.append(LINE_SEPARATOR);
+
+ output.append(" td.level { text-align: right; }");
+ output.append(LINE_SEPARATOR);
+ output
+ .append(" tr.header { background: #596ED5; color: #FFF; font-weight: bold; font-size: larger; }");
+ output.append(CoreConstants.LINE_SEPARATOR);
+
+ output
+ .append(" td.exception { background: #A2AEE8; white-space: pre; font-family: courier, monospace;}");
+ output.append(LINE_SEPARATOR);
+
+ output.append(" </STYLE>\r\n");
+
+ }
+
+ public void printList(StringBuilder buf, StatusManager sm) {
+ buf.append("<table>\r\n");
+ printHeader(buf);
+ List<Status> statusList = sm.getCopyOfStatusList();
+ for (Status s : statusList) {
+ count++;
+ printStatus(buf, s);
}
-
- String statusLevelAsString(Status s) {
- switch (s.getEffectiveLevel()) {
- case Status.INFO:
- return "INFO";
- case Status.WARN:
- return "<span class=\"warn\">WARN</span>";
- case Status.ERROR:
- return "<span class=\"error\">ERROR</span>";
- }
- return null;
+ buf.append("</table>\r\n");
+ }
+
+ public void printHeader(StringBuilder buf) {
+ buf.append(" <tr class=\"header\">\r\n");
+ buf.append(" <th>Date </th>\r\n");
+ buf.append(" <th>Level</th>\r\n");
+ buf.append(" <th>Origin</th>\r\n");
+ buf.append(" <th>Message</th>\r\n");
+ buf.append(" </tr>\r\n");
+
+ }
+
+ String statusLevelAsString(Status s) {
+ switch (s.getEffectiveLevel()) {
+ case Status.INFO:
+ return "INFO";
+ case Status.WARN:
+ return "<span class=\"warn\">WARN</span>";
+ case Status.ERROR:
+ return "<span class=\"error\">ERROR</span>";
}
+ return null;
+ }
- String abbreviatedOrigin(Status s) {
- Object o = s.getOrigin();
- if (o == null) {
- return null;
- }
- String fqClassName = o.getClass().getName();
- int lastIndex = fqClassName.lastIndexOf(CoreConstants.DOT);
- if (lastIndex != -1) {
- return fqClassName.substring(lastIndex + 1, fqClassName.length());
- } else {
- return fqClassName;
- }
+ String abbreviatedOrigin(Status s) {
+ Object o = s.getOrigin();
+ if (o == null) {
+ return null;
}
-
- private void printStatus(StringBuilder buf, Status s) {
- String trClass;
- if (count % 2 == 0) {
- trClass = "even";
- } else {
- trClass = "odd";
- }
- buf.append(" <tr class=\"").append(trClass).append("\">\r\n");
- String dateStr = SDF.format(s.getDate());
- buf.append(" <td class=\"date\">").append(dateStr).append("</td>\r\n");
- buf.append(" <td class=\"level\">").append(statusLevelAsString(s)).append("</td>\r\n");
- buf.append(" <td>").append(abbreviatedOrigin(s)).append("</td>\r\n");
- buf.append(" <td>").append(s.getMessage()).append("</td>\r\n");
- buf.append(" </tr>\r\n");
- if (s.getThrowable() != null) {
- printThrowable(buf, s.getThrowable());
- }
+ String fqClassName = o.getClass().getName();
+ int lastIndex = fqClassName.lastIndexOf(CoreConstants.DOT);
+ if (lastIndex != -1) {
+ return fqClassName.substring(lastIndex + 1, fqClassName.length());
+ } else {
+ return fqClassName;
}
-
- private void printThrowable(StringBuilder buf, Throwable t) {
- buf.append(" <tr>\r\n");
- buf.append(" <td colspan=\"4\" class=\"exception\"><pre>");
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- t.printStackTrace(pw);
- buf.append(Transform.escapeTags(sw.getBuffer()));
- buf.append(" </pre></td>\r\n");
- buf.append(" </tr>\r\n");
-
+ }
+
+ private void printStatus(StringBuilder buf, Status s) {
+ String trClass;
+ if (count % 2 == 0) {
+ trClass = "even";
+ } else {
+ trClass = "odd";
+ }
+ buf.append(" <tr class=\"").append(trClass).append("\">\r\n");
+ String dateStr = SDF.format(s.getDate());
+ buf.append(" <td class=\"date\">").append(dateStr).append("</td>\r\n");
+ buf.append(" <td class=\"level\">").append(statusLevelAsString(s))
+ .append("</td>\r\n");
+ buf.append(" <td>").append(abbreviatedOrigin(s)).append("</td>\r\n");
+ buf.append(" <td>").append(s.getMessage()).append("</td>\r\n");
+ buf.append(" </tr>\r\n");
+ if (s.getThrowable() != null) {
+ printThrowable(buf, s.getThrowable());
}
+ }
+
+ private void printThrowable(StringBuilder buf, Throwable t) {
+ buf.append(" <tr>\r\n");
+ buf.append(" <td colspan=\"4\" class=\"exception\"><pre>");
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ t.printStackTrace(pw);
+ buf.append(Transform.escapeTags(sw.getBuffer()));
+ buf.append(" </pre></td>\r\n");
+ buf.append(" </tr>\r\n");
+
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/status/WarnStatus.java b/logback-core/src/main/java/ch/qos/logback/core/status/WarnStatus.java
index 069671a..6280dd5 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/status/WarnStatus.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/status/WarnStatus.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,14 +13,17 @@
*/
package ch.qos.logback.core.status;
+
+
public class WarnStatus extends StatusBase {
- public WarnStatus(String msg, Object origin) {
- super(Status.WARN, msg, origin);
- }
+
+ public WarnStatus(String msg, Object origin) {
+ super(Status.WARN, msg, origin);
+ }
- public WarnStatus(String msg, Object origin, Throwable t) {
- super(Status.WARN, msg, origin, t);
- }
+ public WarnStatus( String msg, Object origin, Throwable t) {
+ super(Status.WARN, msg, origin, t);
+ }
-}
+ }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/subst/Node.java b/logback-core/src/main/java/ch/qos/logback/core/subst/Node.java
index d7e986c..e98758a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/subst/Node.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/subst/Node.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,110 +15,110 @@ package ch.qos.logback.core.subst;
public class Node {
- enum Type {
- LITERAL, VARIABLE
- }
+ enum Type {LITERAL, VARIABLE}
- Type type;
- Object payload;
- Object defaultPart;
- Node next;
+ Type type;
+ Object payload;
+ Object defaultPart;
+ Node next;
- public Node(Type type, Object payload) {
- this.type = type;
- this.payload = payload;
- }
- public Node(Type type, Object payload, Object defaultPart) {
- this.type = type;
- this.payload = payload;
- this.defaultPart = defaultPart;
- }
+ public Node(Type type, Object payload) {
+ this.type = type;
+ this.payload = payload;
+ }
- void append(Node newNode) {
- if (newNode == null)
- return;
- Node n = this;
- while (true) {
- if (n.next == null) {
- n.next = newNode;
- return;
- }
- n = n.next;
- }
- }
- @Override
- public String toString() {
- switch (type) {
- case LITERAL:
- return "Node{" + "type=" + type + ", payload='" + payload + "'}";
- case VARIABLE:
- StringBuilder payloadBuf = new StringBuilder();
- StringBuilder defaultPartBuf2 = new StringBuilder();
- if (defaultPart != null)
- recursive((Node) defaultPart, defaultPartBuf2);
-
- recursive((Node) payload, payloadBuf);
- String r = "Node{" + "type=" + type + ", payload='" + payloadBuf.toString() + "'";
- if (defaultPart != null)
- r += ", defaultPart=" + defaultPartBuf2.toString();
- r += '}';
- return r;
- }
- return null;
- }
+ public Node(Type type, Object payload, Object defaultPart) {
+ this.type = type;
+ this.payload = payload;
+ this.defaultPart = defaultPart;
+ }
- public void dump() {
- System.out.print(this.toString());
- System.out.print(" -> ");
- if (next != null) {
- next.dump();
- } else {
- System.out.print(" null");
- }
+ void append(Node newNode) {
+ if(newNode == null)
+ return;
+ Node n = this;
+ while(true) {
+ if(n.next == null) {
+ n.next = newNode;
+ return;
+ }
+ n = n.next;
}
-
- void recursive(Node n, StringBuilder sb) {
- Node c = n;
- while (c != null) {
- sb.append(c.toString()).append(" --> ");
- c = c.next;
- }
- sb.append("null ");
+ }
+
+ @Override
+ public String toString() {
+ switch (type) {
+ case LITERAL:
+ return "Node{" +
+ "type=" + type +
+ ", payload='" + payload +
+ "'}";
+ case VARIABLE:
+ StringBuilder payloadBuf = new StringBuilder();
+ StringBuilder defaultPartBuf2 = new StringBuilder();
+ if (defaultPart != null)
+ recursive((Node) defaultPart, defaultPartBuf2);
+
+ recursive((Node) payload, payloadBuf);
+ String r = "Node{" +
+ "type=" + type +
+ ", payload='" + payloadBuf.toString()+"'";
+ if (defaultPart != null)
+ r += ", defaultPart=" + defaultPartBuf2.toString();
+ r += '}';
+ return r;
}
-
- public void setNext(Node n) {
- this.next = n;
+ return null;
+ }
+
+ public void dump() {
+ System.out.print(this.toString());
+ System.out.print(" -> ");
+ if(next != null) {
+ next.dump();
+ } else {
+ System.out.print(" null");
}
+ }
- @Override
- public boolean equals(Object o) {
- if (this == o)
- return true;
- if (o == null || getClass() != o.getClass())
- return false;
-
- Node node = (Node) o;
-
- if (type != node.type)
- return false;
- if (payload != null ? !payload.equals(node.payload) : node.payload != null)
- return false;
- if (defaultPart != null ? !defaultPart.equals(node.defaultPart) : node.defaultPart != null)
- return false;
- if (next != null ? !next.equals(node.next) : node.next != null)
- return false;
-
- return true;
+ void recursive(Node n, StringBuilder sb) {
+ Node c = n;
+ while (c != null) {
+ sb.append(c.toString()).append(" --> ");
+ c = c.next;
}
+ sb.append("null ");
+ }
- @Override
- public int hashCode() {
- int result = type != null ? type.hashCode() : 0;
- result = 31 * result + (payload != null ? payload.hashCode() : 0);
- result = 31 * result + (defaultPart != null ? defaultPart.hashCode() : 0);
- result = 31 * result + (next != null ? next.hashCode() : 0);
- return result;
- }
+ public void setNext(Node n) {
+ this.next = n;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Node node = (Node) o;
+
+ if (type != node.type) return false;
+ if (payload != null ? !payload.equals(node.payload) : node.payload != null) return false;
+ if (defaultPart != null ? !defaultPart.equals(node.defaultPart) : node.defaultPart != null) return false;
+ if (next != null ? !next.equals(node.next) : node.next != null) return false;
+
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = type != null ? type.hashCode() : 0;
+ result = 31 * result + (payload != null ? payload.hashCode() : 0);
+ result = 31 * result + (defaultPart != null ? defaultPart.hashCode() : 0);
+ result = 31 * result + (next != null ? next.hashCode() : 0);
+ return result;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/subst/NodeToStringTransformer.java b/logback-core/src/main/java/ch/qos/logback/core/subst/NodeToStringTransformer.java
index 197c633..2847bc2 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/subst/NodeToStringTransformer.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/subst/NodeToStringTransformer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,163 +24,160 @@ import java.util.Stack;
/**
* Compiles a previously parsed Node chain into a String.
*
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class NodeToStringTransformer {
- final Node node;
- final PropertyContainer propertyContainer0;
- final PropertyContainer propertyContainer1;
-
- public NodeToStringTransformer(Node node, PropertyContainer propertyContainer0, PropertyContainer propertyContainer1) {
- this.node = node;
- this.propertyContainer0 = propertyContainer0;
- this.propertyContainer1 = propertyContainer1;
+ final Node node;
+ final PropertyContainer propertyContainer0;
+ final PropertyContainer propertyContainer1;
+
+ public NodeToStringTransformer(Node node, PropertyContainer propertyContainer0, PropertyContainer propertyContainer1) {
+ this.node = node;
+ this.propertyContainer0 = propertyContainer0;
+ this.propertyContainer1 = propertyContainer1;
+ }
+
+ public NodeToStringTransformer(Node node, PropertyContainer propertyContainer0) {
+ this(node, propertyContainer0, null);
+ }
+
+ public static String substituteVariable(String input, PropertyContainer pc0, PropertyContainer pc1) throws ScanException {
+ Node node = tokenizeAndParseString(input);
+ NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, pc0, pc1);
+ return nodeToStringTransformer.transform();
+ }
+
+ private static Node tokenizeAndParseString(String value) throws ScanException {
+ Tokenizer tokenizer = new Tokenizer(value);
+ List<Token> tokens = tokenizer.tokenize();
+ Parser parser = new Parser(tokens);
+ return parser.parse();
+ }
+
+ public String transform() throws ScanException {
+ StringBuilder stringBuilder = new StringBuilder();
+ compileNode(node, stringBuilder, new Stack<Node>());
+ return stringBuilder.toString();
+ }
+
+ private void compileNode(Node inputNode, StringBuilder stringBuilder, Stack<Node> cycleCheckStack) throws ScanException {
+ Node n = inputNode;
+ while (n != null) {
+ switch (n.type) {
+ case LITERAL:
+ handleLiteral(n, stringBuilder);
+ break;
+ case VARIABLE:
+ handleVariable(n, stringBuilder, cycleCheckStack);
+ break;
+ }
+ n = n.next;
}
+ }
- public NodeToStringTransformer(Node node, PropertyContainer propertyContainer0) {
- this(node, propertyContainer0, null);
- }
+ private void handleVariable(Node n, StringBuilder stringBuilder, Stack<Node> cycleCheckStack) throws ScanException {
- public static String substituteVariable(String input, PropertyContainer pc0, PropertyContainer pc1) throws ScanException {
- Node node = tokenizeAndParseString(input);
- NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, pc0, pc1);
- return nodeToStringTransformer.transform();
+ // Check for recursion
+ if (haveVisitedNodeAlready(n, cycleCheckStack)) {
+ cycleCheckStack.push(n);
+ String error = constructRecursionErrorMessage(cycleCheckStack);
+ throw new IllegalArgumentException(error);
}
-
- private static Node tokenizeAndParseString(String value) throws ScanException {
- Tokenizer tokenizer = new Tokenizer(value);
- List<Token> tokens = tokenizer.tokenize();
- Parser parser = new Parser(tokens);
- return parser.parse();
+ cycleCheckStack.push(n);
+
+ StringBuilder keyBuffer = new StringBuilder();
+ Node payload = (Node) n.payload;
+ compileNode(payload, keyBuffer, cycleCheckStack);
+ String key = keyBuffer.toString();
+ String value = lookupKey(key);
+
+ if (value != null) {
+ Node innerNode = tokenizeAndParseString(value);
+ compileNode(innerNode, stringBuilder, cycleCheckStack);
+ cycleCheckStack.pop();
+ return;
}
- public String transform() throws ScanException {
- StringBuilder stringBuilder = new StringBuilder();
- compileNode(node, stringBuilder, new Stack<Node>());
- return stringBuilder.toString();
+ if (n.defaultPart == null) {
+ stringBuilder.append(key + CoreConstants.UNDEFINED_PROPERTY_SUFFIX);
+ cycleCheckStack.pop();
+ return;
}
- private void compileNode(Node inputNode, StringBuilder stringBuilder, Stack<Node> cycleCheckStack) throws ScanException {
- Node n = inputNode;
- while (n != null) {
- switch (n.type) {
- case LITERAL:
- handleLiteral(n, stringBuilder);
- break;
- case VARIABLE:
- handleVariable(n, stringBuilder, cycleCheckStack);
- break;
- }
- n = n.next;
- }
+ Node defaultPart = (Node) n.defaultPart;
+ StringBuilder defaultPartBuffer = new StringBuilder();
+ compileNode(defaultPart, defaultPartBuffer, cycleCheckStack);
+ cycleCheckStack.pop();
+ String defaultVal = defaultPartBuffer.toString();
+ stringBuilder.append(defaultVal);
+ }
+
+ private String lookupKey(String key) {
+ String value = propertyContainer0.getProperty(key);
+ if (value != null)
+ return value;
+
+ if (propertyContainer1 != null) {
+ value = propertyContainer1.getProperty(key);
+ if (value != null)
+ return value;
}
- private void handleVariable(Node n, StringBuilder stringBuilder, Stack<Node> cycleCheckStack) throws ScanException {
-
- // Check for recursion
- if (haveVisitedNodeAlready(n, cycleCheckStack)) {
- cycleCheckStack.push(n);
- String error = constructRecursionErrorMessage(cycleCheckStack);
- throw new IllegalArgumentException(error);
- }
- cycleCheckStack.push(n);
-
- StringBuilder keyBuffer = new StringBuilder();
- Node payload = (Node) n.payload;
- compileNode(payload, keyBuffer, cycleCheckStack);
- String key = keyBuffer.toString();
- String value = lookupKey(key);
-
- if (value != null) {
- Node innerNode = tokenizeAndParseString(value);
- compileNode(innerNode, stringBuilder, cycleCheckStack);
- cycleCheckStack.pop();
- return;
- }
-
- if (n.defaultPart == null) {
- stringBuilder.append(key + CoreConstants.UNDEFINED_PROPERTY_SUFFIX);
- cycleCheckStack.pop();
- return;
- }
-
- Node defaultPart = (Node) n.defaultPart;
- StringBuilder defaultPartBuffer = new StringBuilder();
- compileNode(defaultPart, defaultPartBuffer, cycleCheckStack);
- cycleCheckStack.pop();
- String defaultVal = defaultPartBuffer.toString();
- stringBuilder.append(defaultVal);
- }
-
- private String lookupKey(String key) {
- String value = propertyContainer0.getProperty(key);
- if (value != null)
- return value;
-
- if (propertyContainer1 != null) {
- value = propertyContainer1.getProperty(key);
- if (value != null)
- return value;
- }
-
- value = OptionHelper.getSystemProperty(key, null);
- if (value != null)
- return value;
+ value = OptionHelper.getSystemProperty(key, null);
+ if (value != null)
+ return value;
- value = OptionHelper.getEnv(key);
- if (value != null) {
- return value;
- }
-
- return null;
+ value = OptionHelper.getEnv(key);
+ if (value != null) {
+ return value;
}
- private void handleLiteral(Node n, StringBuilder stringBuilder) {
- stringBuilder.append((String) n.payload);
- }
+ return null;
+ }
- private String variableNodeValue(Node variableNode) {
- Node literalPayload = (Node) variableNode.payload;
- return (String) literalPayload.payload;
- }
- private String constructRecursionErrorMessage(Stack<Node> recursionNodes) {
- StringBuilder errorBuilder = new StringBuilder("Circular variable reference detected while parsing input [");
-
- for (Node stackNode : recursionNodes) {
- errorBuilder.append("${").append(variableNodeValue(stackNode)).append("}");
- if (recursionNodes.lastElement() != stackNode) {
- errorBuilder.append(" --> ");
- }
- }
- errorBuilder.append("]");
- return errorBuilder.toString();
- }
+ private void handleLiteral(Node n, StringBuilder stringBuilder) {
+ stringBuilder.append((String) n.payload);
+ }
- /**
- * Determine if a node has already been visited already by checking the cycleDetectionStack
- * for it's existence. This method is used -- rather than Stack.contains() -- because
- * we want to ignore the Node's 'next' attribute when comparing for equality.
- */
- private boolean haveVisitedNodeAlready(Node node, Stack<Node> cycleDetectionStack) {
- for (Node cycleNode : cycleDetectionStack) {
- if (equalNodes(node, cycleNode)) {
- return true;
- }
- }
- return false;
- }
+ private String variableNodeValue(Node variableNode) {
+ Node literalPayload = (Node) variableNode.payload;
+ return (String) literalPayload.payload;
+ }
- private boolean equalNodes(Node node1, Node node2) {
- if (node1.type != null && !node1.type.equals(node2.type))
- return false;
- if (node1.payload != null && !node1.payload.equals(node2.payload))
- return false;
- if (node1.defaultPart != null && !node1.defaultPart.equals(node2.defaultPart))
- return false;
+ private String constructRecursionErrorMessage(Stack<Node> recursionNodes) {
+ StringBuilder errorBuilder = new StringBuilder("Circular variable reference detected while parsing input [");
+ for (Node stackNode : recursionNodes) {
+ errorBuilder.append("${").append(variableNodeValue(stackNode)).append("}");
+ if (recursionNodes.lastElement() != stackNode) {
+ errorBuilder.append(" --> ");
+ }
+ }
+ errorBuilder.append("]");
+ return errorBuilder.toString();
+ }
+
+ /**
+ * Determine if a node has already been visited already by checking the cycleDetectionStack
+ * for it's existence. This method is used -- rather than Stack.contains() -- because
+ * we want to ignore the Node's 'next' attribute when comparing for equality.
+ */
+ private boolean haveVisitedNodeAlready(Node node, Stack<Node> cycleDetectionStack) {
+ for (Node cycleNode : cycleDetectionStack) {
+ if (equalNodes(node, cycleNode)) {
return true;
+ }
}
+ return false;
+ }
+ private boolean equalNodes(Node node1, Node node2) {
+ if (node1.type != null && !node1.type.equals(node2.type)) return false;
+ if (node1.payload != null && !node1.payload.equals(node2.payload)) return false;
+ if (node1.defaultPart != null && !node1.defaultPart.equals(node2.defaultPart)) return false;
+
+ return true;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/subst/Parser.java b/logback-core/src/main/java/ch/qos/logback/core/subst/Parser.java
index 6211eaf..5cff9d9 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/subst/Parser.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/subst/Parser.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.subst;
+
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.spi.ScanException;
@@ -34,128 +35,129 @@ import java.util.List;
*/
public class Parser {
- final List<Token> tokenList;
- int pointer = 0;
+ final List<Token> tokenList;
+ int pointer = 0;
- public Parser(List<Token> tokenList) {
- this.tokenList = tokenList;
- }
+ public Parser(List<Token> tokenList) {
+ this.tokenList = tokenList;
+ }
- public Node parse() throws ScanException {
- if (tokenList == null || tokenList.isEmpty())
- return null;
- return E();
- }
+ public Node parse() throws ScanException {
+ if(tokenList == null || tokenList.isEmpty())
+ return null;
+ return E();
+ }
- private Node E() throws ScanException {
- Node t = T();
- if (t == null) {
- return null;
- }
- Node eOpt = Eopt();
- if (eOpt != null) {
- t.append(eOpt);
- }
- return t;
+ private Node E() throws ScanException {
+ Node t = T();
+ if (t == null) {
+ return null;
}
-
- // Eopt = E|~
- private Node Eopt() throws ScanException {
- Token next = peekAtCurentToken();
- if (next == null) {
- return null;
- } else {
- return E();
- }
+ Node eOpt = Eopt();
+ if (eOpt != null) {
+ t.append(eOpt);
}
-
- // T = LITERAL | '${' V '}'
- private Node T() throws ScanException {
- Token t = peekAtCurentToken();
-
- switch (t.type) {
- case LITERAL:
- advanceTokenPointer();
- return makeNewLiteralNode(t.payload);
- case CURLY_LEFT:
- advanceTokenPointer();
- Node innerNode = C();
- Token right = peekAtCurentToken();
- expectCurlyRight(right);
- advanceTokenPointer();
- Node curlyLeft = makeNewLiteralNode(CoreConstants.LEFT_ACCOLADE);
- curlyLeft.append(innerNode);
- curlyLeft.append(makeNewLiteralNode(CoreConstants.RIGHT_ACCOLADE));
- return curlyLeft;
- case START:
- advanceTokenPointer();
- Node v = V();
- Token w = peekAtCurentToken();
- expectCurlyRight(w);
- advanceTokenPointer();
- return v;
- default:
- return null;
- }
+ return t;
+ }
+
+ // Eopt = E|~
+ private Node Eopt() throws ScanException {
+ Token next = peekAtCurentToken();
+ if (next == null) {
+ return null;
+ } else {
+ return E();
}
-
- private Node makeNewLiteralNode(String s) {
- return new Node(Node.Type.LITERAL, s);
+ }
+
+ // T = LITERAL | '${' V '}'
+ private Node T() throws ScanException {
+ Token t = peekAtCurentToken();
+
+ switch (t.type) {
+ case LITERAL:
+ advanceTokenPointer();
+ return makeNewLiteralNode(t.payload);
+ case CURLY_LEFT:
+ advanceTokenPointer();
+ Node innerNode = C();
+ Token right = peekAtCurentToken();
+ expectCurlyRight(right);
+ advanceTokenPointer();
+ Node curlyLeft = makeNewLiteralNode(CoreConstants.LEFT_ACCOLADE);
+ curlyLeft.append(innerNode);
+ curlyLeft.append(makeNewLiteralNode(CoreConstants.RIGHT_ACCOLADE));
+ return curlyLeft;
+ case START:
+ advanceTokenPointer();
+ Node v = V();
+ Token w = peekAtCurentToken();
+ expectCurlyRight(w);
+ advanceTokenPointer();
+ return v;
+ default:
+ return null;
}
-
- // V = E(':='E|~)
- private Node V() throws ScanException {
- Node e = E();
- Node variable = new Node(Node.Type.VARIABLE, e);
- Token t = peekAtCurentToken();
- if (isDefaultToken(t)) {
- advanceTokenPointer();
- Node def = E();
- variable.defaultPart = def;
- }
- return variable;
+ }
+
+ private Node makeNewLiteralNode(String s) {
+ return new Node(Node.Type.LITERAL, s);
+ }
+
+ // V = E(':='E|~)
+ private Node V() throws ScanException {
+ Node e = E();
+ Node variable = new Node(Node.Type.VARIABLE, e);
+ Token t = peekAtCurentToken();
+ if (isDefaultToken(t)) {
+ advanceTokenPointer();
+ Node def = E();
+ variable.defaultPart = def;
}
-
- // C = E(':='E|~)
- private Node C() throws ScanException {
- Node e0 = E();
- Token t = peekAtCurentToken();
- if (isDefaultToken(t)) {
- advanceTokenPointer();
- Node literal = makeNewLiteralNode(CoreConstants.DEFAULT_VALUE_SEPARATOR);
- e0.append(literal);
- Node e1 = E();
- e0.append(e1);
- }
- return e0;
+ return variable;
+ }
+
+ // C = E(':='E|~)
+ private Node C() throws ScanException {
+ Node e0 = E();
+ Token t = peekAtCurentToken();
+ if (isDefaultToken(t)) {
+ advanceTokenPointer();
+ Node literal = makeNewLiteralNode(CoreConstants.DEFAULT_VALUE_SEPARATOR);
+ e0.append(literal);
+ Node e1 = E();
+ e0.append(e1);
}
+ return e0;
+ }
- private boolean isDefaultToken(Token t) {
- return t != null && t.type == Token.Type.DEFAULT;
- }
+ private boolean isDefaultToken(Token t) {
+ return t != null && t.type == Token.Type.DEFAULT;
+ }
- void advanceTokenPointer() {
- pointer++;
- }
+ void advanceTokenPointer() {
+ pointer++;
+ }
- void expectNotNull(Token t, String expected) {
- if (t == null) {
- throw new IllegalArgumentException("All tokens consumed but was expecting \"" + expected + "\"");
- }
+ void expectNotNull(Token t, String expected) {
+ if (t == null) {
+ throw new IllegalArgumentException("All tokens consumed but was expecting \""
+ + expected + "\"");
}
+ }
- void expectCurlyRight(Token t) throws ScanException {
- expectNotNull(t, "}");
- if (t.type != Token.Type.CURLY_RIGHT) {
- throw new ScanException("Expecting }");
- }
+ void expectCurlyRight(Token t) throws ScanException {
+ expectNotNull(t, "}");
+ if (t.type != Token.Type.CURLY_RIGHT) {
+ throw new ScanException("Expecting }");
}
+ }
- Token peekAtCurentToken() {
- if (pointer < tokenList.size()) {
- return tokenList.get(pointer);
- }
- return null;
+ Token peekAtCurentToken() {
+ if (pointer < tokenList.size()) {
+ return tokenList.get(pointer);
}
+ return null;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/subst/Token.java b/logback-core/src/main/java/ch/qos/logback/core/subst/Token.java
index 7a7854e..16964b5 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/subst/Token.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/subst/Token.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,54 +15,49 @@ package ch.qos.logback.core.subst;
public class Token {
- static public final Token START_TOKEN = new Token(Type.START, null);
- static public final Token CURLY_LEFT_TOKEN = new Token(Type.CURLY_LEFT, null);
- static public final Token CURLY_RIGHT_TOKEN = new Token(Type.CURLY_RIGHT, null);
- static public final Token DEFAULT_SEP_TOKEN = new Token(Type.DEFAULT, null);
+ static public final Token START_TOKEN = new Token(Type.START, null);
+ static public final Token CURLY_LEFT_TOKEN = new Token(Type.CURLY_LEFT, null);
+ static public final Token CURLY_RIGHT_TOKEN = new Token(Type.CURLY_RIGHT, null);
+ static public final Token DEFAULT_SEP_TOKEN = new Token(Type.DEFAULT, null);
- public enum Type {
- LITERAL, START, CURLY_LEFT, CURLY_RIGHT, DEFAULT
- }
+ public enum Type {LITERAL, START, CURLY_LEFT, CURLY_RIGHT, DEFAULT}
- Type type;
- String payload;
+ Type type;
+ String payload;
- public Token(Type type, String payload) {
- this.type = type;
- this.payload = payload;
- }
+ public Token(Type type, String payload) {
+ this.type = type;
+ this.payload = payload;
+ }
- @Override
- public boolean equals(Object o) {
- if (this == o)
- return true;
- if (o == null || getClass() != o.getClass())
- return false;
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
- Token token = (Token) o;
+ Token token = (Token) o;
- if (type != token.type)
- return false;
- if (payload != null ? !payload.equals(token.payload) : token.payload != null)
- return false;
+ if (type != token.type) return false;
+ if (payload != null ? !payload.equals(token.payload) : token.payload != null) return false;
- return true;
- }
+ return true;
+ }
- @Override
- public int hashCode() {
- int result = type != null ? type.hashCode() : 0;
- result = 31 * result + (payload != null ? payload.hashCode() : 0);
- return result;
- }
+ @Override
+ public int hashCode() {
+ int result = type != null ? type.hashCode() : 0;
+ result = 31 * result + (payload != null ? payload.hashCode() : 0);
+ return result;
+ }
- @Override
- public String toString() {
- String result = "Token{" + "type=" + type;
- if (payload != null)
- result += ", payload='" + payload + '\'';
+ @Override
+ public String toString() {
+ String result = "Token{" +
+ "type=" + type;
+ if (payload != null)
+ result += ", payload='" + payload + '\'';
- result += '}';
- return result;
- }
+ result += '}';
+ return result;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/subst/Tokenizer.java b/logback-core/src/main/java/ch/qos/logback/core/subst/Tokenizer.java
index c35987b..31a00c2 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/subst/Tokenizer.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/subst/Tokenizer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,115 +21,108 @@ import java.util.List;
public class Tokenizer {
- enum TokenizerState {
- LITERAL_STATE, START_STATE, DEFAULT_VAL_STATE
- }
+ enum TokenizerState {LITERAL_STATE, START_STATE, DEFAULT_VAL_STATE}
- final String pattern;
- final int patternLength;
+ final String pattern;
+ final int patternLength;
- public Tokenizer(String pattern) {
- this.pattern = pattern;
- patternLength = pattern.length();
- }
+ public Tokenizer(String pattern) {
+ this.pattern = pattern;
+ patternLength = pattern.length();
+ }
+
+ TokenizerState state = TokenizerState.LITERAL_STATE;
+ int pointer = 0;
+
+ List<Token> tokenize() throws ScanException {
+ List<Token> tokenList = new ArrayList<Token>();
+ StringBuilder buf = new StringBuilder();
+
+ while (pointer < patternLength) {
+ char c = pattern.charAt(pointer);
+ pointer++;
- TokenizerState state = TokenizerState.LITERAL_STATE;
- int pointer = 0;
-
- List<Token> tokenize() throws ScanException {
- List<Token> tokenList = new ArrayList<Token>();
- StringBuilder buf = new StringBuilder();
-
- while (pointer < patternLength) {
- char c = pattern.charAt(pointer);
- pointer++;
-
- switch (state) {
- case LITERAL_STATE:
- handleLiteralState(c, tokenList, buf);
- break;
- case START_STATE:
- handleStartState(c, tokenList, buf);
- break;
- case DEFAULT_VAL_STATE:
- handleDefaultValueState(c, tokenList, buf);
- default:
- }
- }
- // EOS
- switch (state) {
+ switch (state) {
case LITERAL_STATE:
- addLiteralToken(tokenList, buf);
- break;
- case DEFAULT_VAL_STATE:
- // trailing colon. see also LOGBACK-1140
- buf.append(CoreConstants.COLON_CHAR);
- addLiteralToken(tokenList, buf);
- break;
+ handleLiteralState(c, tokenList, buf);
+ break;
case START_STATE:
- // trailing $. see also LOGBACK-1149
- buf.append(CoreConstants.DOLLAR);
- addLiteralToken(tokenList, buf);
- break;
- }
- return tokenList;
- }
-
- private void handleDefaultValueState(char c, List<Token> tokenList, StringBuilder stringBuilder) {
- switch (c) {
- case CoreConstants.DASH_CHAR:
- tokenList.add(Token.DEFAULT_SEP_TOKEN);
- state = TokenizerState.LITERAL_STATE;
- break;
- case CoreConstants.DOLLAR:
- stringBuilder.append(CoreConstants.COLON_CHAR);
- addLiteralToken(tokenList, stringBuilder);
- stringBuilder.setLength(0);
- state = TokenizerState.START_STATE;
- break;
+ handleStartState(c, tokenList, buf);
+ break;
+ case DEFAULT_VAL_STATE:
+ handleDefaultValueState(c, tokenList, buf);
default:
- stringBuilder.append(CoreConstants.COLON_CHAR).append(c);
- state = TokenizerState.LITERAL_STATE;
- break;
- }
+ }
}
+ // EOS
+ switch (state) {
+ case LITERAL_STATE:
+ addLiteralToken(tokenList, buf);
+ break;
+ case START_STATE:
+ throw new ScanException("Unexpected end of pattern string");
+ }
+ return tokenList;
+ }
- private void handleStartState(char c, List<Token> tokenList, StringBuilder stringBuilder) {
- if (c == CoreConstants.CURLY_LEFT) {
- tokenList.add(Token.START_TOKEN);
- } else {
- stringBuilder.append(CoreConstants.DOLLAR).append(c);
- }
+ private void handleDefaultValueState(char c, List<Token> tokenList, StringBuilder stringBuilder) {
+ switch(c) {
+ case CoreConstants.DASH_CHAR:
+ tokenList.add(Token.DEFAULT_SEP_TOKEN);
+ state = TokenizerState.LITERAL_STATE;
+ break;
+ case CoreConstants.DOLLAR:
+ stringBuilder.append(CoreConstants.COLON_CHAR);
+ addLiteralToken(tokenList, stringBuilder);
+ stringBuilder.setLength(0);
+ state = TokenizerState.START_STATE;
+ break;
+ default:
+ stringBuilder.append(CoreConstants.COLON_CHAR).append(c);
state = TokenizerState.LITERAL_STATE;
+ break;
}
+ }
- private void handleLiteralState(char c, List<Token> tokenList, StringBuilder stringBuilder) {
- if (c == CoreConstants.DOLLAR) {
- addLiteralToken(tokenList, stringBuilder);
- stringBuilder.setLength(0);
- state = TokenizerState.START_STATE;
- } else if (c == CoreConstants.COLON_CHAR) {
- addLiteralToken(tokenList, stringBuilder);
- stringBuilder.setLength(0);
- state = TokenizerState.DEFAULT_VAL_STATE;
- } else if (c == CoreConstants.CURLY_LEFT) {
- addLiteralToken(tokenList, stringBuilder);
- tokenList.add(Token.CURLY_LEFT_TOKEN);
- stringBuilder.setLength(0);
- } else if (c == CoreConstants.CURLY_RIGHT) {
- addLiteralToken(tokenList, stringBuilder);
- tokenList.add(Token.CURLY_RIGHT_TOKEN);
- stringBuilder.setLength(0);
- } else {
- stringBuilder.append(c);
- }
-
+ private void handleStartState(char c, List<Token> tokenList, StringBuilder stringBuilder) {
+ if (c == CoreConstants.CURLY_LEFT) {
+ tokenList.add(Token.START_TOKEN);
+ } else {
+ stringBuilder.append(CoreConstants.DOLLAR).append(c);
}
-
- private void addLiteralToken(List<Token> tokenList, StringBuilder stringBuilder) {
- if (stringBuilder.length() == 0)
- return;
- tokenList.add(new Token(Token.Type.LITERAL, stringBuilder.toString()));
+ state = TokenizerState.LITERAL_STATE;
+ }
+
+ private void handleLiteralState(char c, List<Token> tokenList, StringBuilder stringBuilder) {
+ if (c == CoreConstants.DOLLAR) {
+ addLiteralToken(tokenList, stringBuilder);
+ stringBuilder.setLength(0);
+ state = TokenizerState.START_STATE;
+ } else if (c == CoreConstants.COLON_CHAR) {
+ addLiteralToken(tokenList, stringBuilder);
+ stringBuilder.setLength(0);
+ state = TokenizerState.DEFAULT_VAL_STATE;
+ } else if (c == CoreConstants.CURLY_LEFT) {
+ addLiteralToken(tokenList, stringBuilder);
+ tokenList.add(Token.CURLY_LEFT_TOKEN);
+ stringBuilder.setLength(0);
+ } else if (c == CoreConstants.CURLY_RIGHT) {
+ addLiteralToken(tokenList, stringBuilder);
+ tokenList.add(Token.CURLY_RIGHT_TOKEN);
+ stringBuilder.setLength(0);
+ } else {
+ stringBuilder.append(c);
}
+ }
+
+ private void addLiteralToken(List<Token> tokenList, StringBuilder stringBuilder) {
+ if (stringBuilder.length() == 0)
+ return;
+ tokenList.add(new Token(Token.Type.LITERAL, stringBuilder.toString()));
+ }
+
+
}
+
+
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/AggregationType.java b/logback-core/src/main/java/ch/qos/logback/core/util/AggregationType.java
index 2511c49..c287684 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/AggregationType.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/AggregationType.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,11 +25,12 @@ package ch.qos.logback.core.util;
* @author Ceki Gulcu
*/
public enum AggregationType {
- NOT_FOUND, AS_BASIC_PROPERTY, // Long, Integer, Double,..., java primitive, String,
- // Duration or FileSize
- AS_COMPLEX_PROPERTY, // a complex property, a.k.a. attribute, is any attribute
- // not covered by basic attributes, i.e.
- // object types defined by the user
- AS_BASIC_PROPERTY_COLLECTION, // a collection of basic attributes
- AS_COMPLEX_PROPERTY_COLLECTION; // a collection of complex attributes
+ NOT_FOUND,
+ AS_BASIC_PROPERTY, // Long, Integer, Double,..., java primitive, String,
+ // Duration or FileSize
+ AS_COMPLEX_PROPERTY, // a complex property, a.k.a. attribute, is any attribute
+ // not covered by basic attributes, i.e.
+ // object types defined by the user
+ AS_BASIC_PROPERTY_COLLECTION, // a collection of basic attributes
+ AS_COMPLEX_PROPERTY_COLLECTION; // a collection of complex attributes
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/CachingDateFormatter.java b/logback-core/src/main/java/ch/qos/logback/core/util/CachingDateFormatter.java
index 68d2928..549234b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/CachingDateFormatter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/CachingDateFormatter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,38 +20,39 @@ import java.util.TimeZone;
/**
* A synchronized implementation of SimpleDateFormat which uses caching internally.
*
- * @author Ceki Gülcü
+ * @author Ceki Gücü
* @since 0.9.29
*/
public class CachingDateFormatter {
- long lastTimestamp = -1;
- String cachedStr = null;
- final SimpleDateFormat sdf;
- public CachingDateFormatter(String pattern) {
- sdf = new SimpleDateFormat(pattern);
- }
+ long lastTimestamp = -1;
+ String cachedStr = null;
+ final SimpleDateFormat sdf;
- public final String format(long now) {
+ public CachingDateFormatter(String pattern) {
+ sdf = new SimpleDateFormat(pattern);
+ }
- // SimpleDateFormat is not thread safe.
+ public final String format(long now) {
- // See also the discussion in http://jira.qos.ch/browse/LBCLASSIC-36
- // DateFormattingThreadedThroughputCalculator and SelectiveDateFormattingRunnable
- // are also noteworthy
+ // SimpleDateFormat is not thread safe.
- // The now == lastTimestamp guard minimizes synchronization
- synchronized (this) {
- if (now != lastTimestamp) {
- lastTimestamp = now;
- cachedStr = sdf.format(new Date(now));
- }
- return cachedStr;
- }
- }
+ // See also the discussion in http://jira.qos.ch/browse/LBCLASSIC-36
+ // DateFormattingThreadedThroughputCalculator and SelectiveDateFormattingRunnable
+ // are also note worthy
- public void setTimeZone(TimeZone tz) {
- sdf.setTimeZone(tz);
+ // The now == lastTimestamp guard minimizes synchronization
+ synchronized (this) {
+ if (now != lastTimestamp) {
+ lastTimestamp = now;
+ cachedStr = sdf.format(new Date(now));
+ }
+ return cachedStr;
}
+ }
+
+ public void setTimeZone(TimeZone tz) {
+ sdf.setTimeZone(tz);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/CharSequenceState.java b/logback-core/src/main/java/ch/qos/logback/core/util/CharSequenceState.java
index e085dfa..b7903df 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/CharSequenceState.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/CharSequenceState.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,15 +18,15 @@ package ch.qos.logback.core.util;
* @author Ceki Gulcu
*/
class CharSequenceState {
- final char c;
- int occurrences;
+ final char c;
+ int occurrences;
- public CharSequenceState(char c) {
- this.c = c;
- this.occurrences = 1;
- }
+ public CharSequenceState(char c) {
+ this.c = c;
+ this.occurrences = 1;
+ }
- void incrementOccurrences() {
- occurrences++;
- }
+ void incrementOccurrences() {
+ occurrences++;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/CharSequenceToRegexMapper.java b/logback-core/src/main/java/ch/qos/logback/core/util/CharSequenceToRegexMapper.java
index ceba7f6..068f572 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/CharSequenceToRegexMapper.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/CharSequenceToRegexMapper.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,114 +13,67 @@
*/
package ch.qos.logback.core.util;
-import java.text.DateFormatSymbols;
-
/**
* This class supports mapping character sequences to
* regular expressions as appropriate for SimpleDateFormatter.
- *
+ *
* @author Ceki
+ *
*/
class CharSequenceToRegexMapper {
- DateFormatSymbols symbols = DateFormatSymbols.getInstance();
-
- String toRegex(CharSequenceState css) {
- final int occurrences = css.occurrences;
- final char c = css.c;
- switch (css.c) {
- case 'G':
- case 'z':
- return ".*";
- case 'M':
- if (occurrences <= 2)
- return number(occurrences);
- else if (occurrences == 3)
- return getRegexForShortMonths();
- else
- return getRegexForLongMonths();
- case 'y':
- case 'w':
- case 'W':
- case 'D':
- case 'd':
- case 'F':
- case 'H':
- case 'k':
- case 'K':
- case 'h':
- case 'm':
- case 's':
- case 'S':
- return number(occurrences);
- case 'E':
- if (occurrences >= 4) {
- return getRegexForLongDaysOfTheWeek();
- } else {
- return getRegexForShortDaysOfTheWeek();
- }
- case 'a':
- return getRegexForAmPms();
- case 'Z':
- return "(\\+|-)\\d{4}";
- case '.':
- return "\\.";
- case '\\':
- throw new IllegalStateException("Forward slashes are not allowed");
- case '\'':
- if (occurrences == 1) {
- return "";
- }
- throw new IllegalStateException("Too many single quotes");
- default:
- if (occurrences == 1) {
- return "" + c;
- } else {
- return c + "{" + occurrences + "}";
- }
- }
- }
-
- private String number(int occurrences) {
- return "\\d{" + occurrences + "}";
- }
-
- private String getRegexForAmPms() {
- return symbolArrayToRegex(symbols.getAmPmStrings());
- }
-
- private String getRegexForLongDaysOfTheWeek() {
- return symbolArrayToRegex(symbols.getWeekdays());
+ String toRegex(CharSequenceState css) {
+ final int occurrences = css.occurrences;
+ final char c = css.c;
+ switch (css.c) {
+ case 'G':
+ case 'z':
+ return ".*";
+ case 'M':
+ if (occurrences >= 3) {
+ return ".{3,12}";
+ } else {
+ return number(occurrences);
+ }
+ case 'y':
+ case 'w':
+ case 'W':
+ case 'D':
+ case 'd':
+ case 'F':
+ case 'H':
+ case 'k':
+ case 'K':
+ case 'h':
+ case 'm':
+ case 's':
+ case 'S':
+ return number(occurrences);
+ case 'E':
+ return ".{2,12}";
+ case 'a':
+ return ".{2}";
+ case 'Z':
+ return "(\\+|-)\\d{4}";
+ case '.':
+ return "\\.";
+ case '\\':
+ throw new IllegalStateException("Forward slashes are not allowed");
+ case '\'':
+ if (occurrences == 1) {
+ return "";
+ }
+ throw new IllegalStateException("Too many single quotes");
+ default:
+ if (occurrences == 1) {
+ return "" + c;
+ } else {
+ return c + "{" + occurrences + "}";
+ }
}
+ }
- private String getRegexForShortDaysOfTheWeek() {
- return symbolArrayToRegex(symbols.getShortWeekdays());
- }
-
- private String getRegexForLongMonths() {
- return symbolArrayToRegex(symbols.getMonths());
- }
-
- String getRegexForShortMonths() {
- return symbolArrayToRegex(symbols.getShortMonths());
- }
-
- private String symbolArrayToRegex(String[] symbolArray) {
- int[] minMax = findMinMaxLengthsInSymbols(symbolArray);
- return ".{" + minMax[0] + "," + minMax[1] + "}";
- }
-
- static int[] findMinMaxLengthsInSymbols(String[] symbols) {
- int min = Integer.MAX_VALUE;
- int max = 0;
- for (String symbol : symbols) {
- int len = symbol.length();
- // some SENTINEL values can be empty strings, the month at index 12 or the weekday at index 0
- if (len == 0)
- continue;
- min = Math.min(min, len);
- max = Math.max(max, len);
- }
- return new int[] { min, max };
- }
+ private String number(int occurrences) {
+ return "\\d{" + occurrences + "}";
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/CloseUtil.java b/logback-core/src/main/java/ch/qos/logback/core/util/CloseUtil.java
index c2f870c..d0a5918 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/CloseUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/CloseUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,47 +25,47 @@ import java.net.Socket;
*/
public class CloseUtil {
- /**
- * Closes a closeable while suppressing any {@code IOException} that occurs.
- * @param closeable the socket to close
- */
- public static void closeQuietly(Closeable closeable) {
- if (closeable == null)
- return;
- try {
- closeable.close();
- } catch (IOException ex) {
- assert true; // avoid an empty catch
- }
+ /**
+ * Closes a closeable while suppressing any {@code IOException} that occurs.
+ * @param closeable the socket to close
+ */
+ public static void closeQuietly(Closeable closeable) {
+ if (closeable == null) return;
+ try {
+ closeable.close();
}
+ catch (IOException ex) {
+ assert true; // avoid an empty catch
+ }
+ }
- /**
- * Closes a socket while suppressing any {@code IOException} that occurs.
- * @param socket the socket to close
- */
- public static void closeQuietly(Socket socket) {
- if (socket == null)
- return;
- try {
- socket.close();
- } catch (IOException ex) {
- assert true; // avoid an empty catch
- }
+ /**
+ * Closes a socket while suppressing any {@code IOException} that occurs.
+ * @param socket the socket to close
+ */
+ public static void closeQuietly(Socket socket) {
+ if (socket == null) return;
+ try {
+ socket.close();
+ }
+ catch (IOException ex) {
+ assert true; // avoid an empty catch
}
+ }
- /**
- * Closes a server socket while suppressing any {@code IOException} that
- * occurs.
- * @param serverSocket the socket to close
- */
- public static void closeQuietly(ServerSocket serverSocket) {
- if (serverSocket == null)
- return;
- try {
- serverSocket.close();
- } catch (IOException ex) {
- assert true; // avoid an empty catch
- }
+ /**
+ * Closes a server socket while suppressing any {@code IOException} that
+ * occurs.
+ * @param serverSocket the socket to close
+ */
+ public static void closeQuietly(ServerSocket serverSocket) {
+ if (serverSocket == null) return;
+ try {
+ serverSocket.close();
+ }
+ catch (IOException ex) {
+ assert true; // avoid an empty catch
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/ContentTypeUtil.java b/logback-core/src/main/java/ch/qos/logback/core/util/ContentTypeUtil.java
index df75dcc..cffd070 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/ContentTypeUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/ContentTypeUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,27 +21,27 @@ package ch.qos.logback.core.util;
*/
public class ContentTypeUtil {
- public static boolean isTextual(String contextType) {
- if (contextType == null) {
- return false;
- }
- return contextType.startsWith("text");
+ public static boolean isTextual(String contextType) {
+ if (contextType == null) {
+ return false;
}
+ return contextType.startsWith("text");
+ }
- public static String getSubType(String contextType) {
- if (contextType == null) {
- return null;
- }
- int index = contextType.indexOf('/');
- if (index == -1) {
- return null;
- } else {
- int subTypeStartIndex = index + 1;
- if (subTypeStartIndex < contextType.length()) {
- return contextType.substring(subTypeStartIndex);
- } else {
- return null;
- }
- }
+ public static String getSubType(String contextType) {
+ if (contextType == null) {
+ return null;
}
+ int index = contextType.indexOf('/');
+ if (index == -1) {
+ return null;
+ } else {
+ int subTypeStartIndex = index + 1;
+ if (subTypeStartIndex < contextType.length()) {
+ return contextType.substring(subTypeStartIndex);
+ } else {
+ return null;
+ }
+ }
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/ContextUtil.java b/logback-core/src/main/java/ch/qos/logback/core/util/ContextUtil.java
index de97543..2032ed2 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/ContextUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/ContextUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,12 +15,8 @@ package ch.qos.logback.core.util;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.CoreConstants;
-import ch.qos.logback.core.rolling.helper.FileNamePattern;
import ch.qos.logback.core.spi.ContextAwareBase;
-import static ch.qos.logback.core.CoreConstants.FA_FILENAME_COLLISION_MAP;
-import static ch.qos.logback.core.CoreConstants.RFA_FILENAME_PATTERN_COLLISION_MAP;
-
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
@@ -28,95 +24,86 @@ import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.Properties;
public class ContextUtil extends ContextAwareBase {
- public ContextUtil(Context context) {
- setContext(context);
- }
+ public ContextUtil(Context context) {
+ setContext(context);
+ }
- public static String getLocalHostName() throws UnknownHostException, SocketException {
- try {
- InetAddress localhost = InetAddress.getLocalHost();
- return localhost.getHostName();
- } catch (UnknownHostException e) {
- return getLocalAddressAsString();
- }
+ public static String getLocalHostName() throws UnknownHostException,
+ SocketException {
+ try {
+ InetAddress localhost = InetAddress.getLocalHost();
+ return localhost.getHostName();
+ } catch (UnknownHostException e) {
+ return getLocalAddressAsString();
}
+ }
- private static String getLocalAddressAsString() throws UnknownHostException, SocketException {
- Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
- while (interfaces != null && interfaces.hasMoreElements()) {
- Enumeration<InetAddress> addresses = interfaces.nextElement().getInetAddresses();
- while (addresses != null && addresses.hasMoreElements()) {
- InetAddress address = addresses.nextElement();
- if (acceptableAddress(address)) {
- return address.getHostAddress();
- }
- }
+ private static String getLocalAddressAsString() throws UnknownHostException,
+ SocketException {
+ Enumeration<NetworkInterface> interfaces =
+ NetworkInterface.getNetworkInterfaces();
+ while (interfaces != null && interfaces.hasMoreElements()) {
+ Enumeration<InetAddress> addresses =
+ interfaces.nextElement().getInetAddresses();
+ while (addresses != null && addresses.hasMoreElements()) {
+ InetAddress address = addresses.nextElement();
+ if (acceptableAddress(address)) {
+ return address.getHostAddress();
}
- throw new UnknownHostException();
+ }
}
+ throw new UnknownHostException();
+ }
- private static boolean acceptableAddress(InetAddress address) {
- return address != null && !address.isLoopbackAddress() && !address.isAnyLocalAddress() && !address.isLinkLocalAddress();
- }
+ private static boolean acceptableAddress(InetAddress address) {
+ return address != null
+ && !address.isLoopbackAddress()
+ && !address.isAnyLocalAddress()
+ && !address.isLinkLocalAddress();
+ }
- /**
- * Add the local host's name as a property
- */
- public void addHostNameAsProperty() {
- try {
- String localhostName = getLocalHostName();
- context.putProperty(CoreConstants.HOSTNAME_KEY, localhostName);
- } catch (UnknownHostException e) {
- addError("Failed to get local hostname", e);
- } catch (SocketException e) {
- addError("Failed to get local hostname", e);
- } catch (SecurityException e) {
- addError("Failed to get local hostname", e);
- }
+ /**
+ * Add the local host's name as a property
+ */
+ public void addHostNameAsProperty() {
+ try {
+ String localhostName = getLocalHostName();
+ context.putProperty(CoreConstants.HOSTNAME_KEY, localhostName);
+ } catch (UnknownHostException e) {
+ addError("Failed to get local hostname", e);
+ } catch (SocketException e) {
+ addError("Failed to get local hostname", e);
+ } catch (SecurityException e) {
+ addError("Failed to get local hostname", e);
}
+ }
- public void addProperties(Properties props) {
- if (props == null) {
- return;
- }
- @SuppressWarnings("rawtypes")
- Iterator i = props.keySet().iterator();
- while (i.hasNext()) {
- String key = (String) i.next();
- context.putProperty(key, props.getProperty(key));
- }
+ public void addProperties(Properties props) {
+ if (props == null) {
+ return;
}
-
- public static Map<String, String> getFilenameCollisionMap(Context context) {
- if (context == null)
- return null;
- @SuppressWarnings("unchecked")
- Map<String, String> map = (Map<String, String>) context.getObject(FA_FILENAME_COLLISION_MAP);
- return map;
+ Iterator i = props.keySet().iterator();
+ while (i.hasNext()) {
+ String key = (String) i.next();
+ context.putProperty(key, props.getProperty(key));
}
+ }
- public static Map<String, FileNamePattern> getFilenamePatternCollisionMap(Context context) {
- if (context == null)
- return null;
- @SuppressWarnings("unchecked")
- Map<String, FileNamePattern> map = (Map<String, FileNamePattern>) context.getObject(RFA_FILENAME_PATTERN_COLLISION_MAP);
- return map;
- }
-
- public void addGroovyPackages(List<String> frameworkPackages) {
- // addFrameworkPackage(frameworkPackages, "groovy.lang");
- addFrameworkPackage(frameworkPackages, "org.codehaus.groovy.runtime");
- }
- public void addFrameworkPackage(List<String> frameworkPackages, String packageName) {
- if (!frameworkPackages.contains(packageName)) {
- frameworkPackages.add(packageName);
- }
+ public void addGroovyPackages(List<String> frameworkPackages) {
+ //addFrameworkPackage(frameworkPackages, "groovy.lang");
+ addFrameworkPackage(frameworkPackages, "org.codehaus.groovy.runtime");
+ }
+
+ public void addFrameworkPackage(List<String> frameworkPackages, String packageName) {
+ if (!frameworkPackages.contains(packageName)) {
+ frameworkPackages.add(packageName);
}
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/DatePatternToRegexUtil.java b/logback-core/src/main/java/ch/qos/logback/core/util/DatePatternToRegexUtil.java
index 4b0ea98..414aa53 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/DatePatternToRegexUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/DatePatternToRegexUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,38 +25,38 @@ import java.util.List;
*/
public class DatePatternToRegexUtil {
- final String datePattern;
- final int datePatternLength;
- final CharSequenceToRegexMapper regexMapper = new CharSequenceToRegexMapper();
+ final String datePattern;
+ final int datePatternLength;
+ final CharSequenceToRegexMapper regexMapper = new CharSequenceToRegexMapper();
- public DatePatternToRegexUtil(String datePattern) {
- this.datePattern = datePattern;
- datePatternLength = datePattern.length();
- }
+ public DatePatternToRegexUtil(String datePattern) {
+ this.datePattern = datePattern;
+ datePatternLength = datePattern.length();
+ }
- public String toRegex() {
- List<CharSequenceState> charSequenceList = tokenize();
- StringBuilder sb = new StringBuilder();
- for (CharSequenceState seq : charSequenceList) {
- sb.append(regexMapper.toRegex(seq));
- }
- return sb.toString();
+ public String toRegex() {
+ List<CharSequenceState> charSequenceList = tokenize();
+ StringBuilder sb = new StringBuilder();
+ for (CharSequenceState seq : charSequenceList) {
+ sb.append(regexMapper.toRegex(seq));
}
-
- private List<CharSequenceState> tokenize() {
- List<CharSequenceState> sequenceList = new ArrayList<CharSequenceState>();
-
- CharSequenceState lastCharSequenceState = null;
-
- for (int i = 0; i < datePatternLength; i++) {
- char t = datePattern.charAt(i);
- if (lastCharSequenceState == null || lastCharSequenceState.c != t) {
- lastCharSequenceState = new CharSequenceState(t);
- sequenceList.add(lastCharSequenceState);
- } else {
- lastCharSequenceState.incrementOccurrences();
- }
- }
- return sequenceList;
+ return sb.toString();
+ }
+
+ private List<CharSequenceState> tokenize() {
+ List<CharSequenceState> sequenceList = new ArrayList<CharSequenceState>();
+
+ CharSequenceState lastCharSequenceState = null;
+
+ for (int i = 0; i < datePatternLength; i++) {
+ char t = datePattern.charAt(i);
+ if (lastCharSequenceState == null || lastCharSequenceState.c != t) {
+ lastCharSequenceState = new CharSequenceState(t);
+ sequenceList.add(lastCharSequenceState);
+ } else {
+ lastCharSequenceState.incrementOccurrences();
+ }
}
+ return sequenceList;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/DefaultInvocationGate.java b/logback-core/src/main/java/ch/qos/logback/core/util/DefaultInvocationGate.java
deleted file mode 100644
index 819f509..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/util/DefaultInvocationGate.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.util;
-
-/**
- * This class serves as a gateway for invocations of a "costly" operation on a critical execution path.
- *
- * @author Ceki Gülcü
- */
-public class DefaultInvocationGate implements InvocationGate {
-
- static final int MASK_DECREASE_RIGHT_SHIFT_COUNT = 2;
-
- // experiments indicate that even for the most CPU intensive applications with 200 or more threads MASK
- // values in the order of 0xFFFF is appropriate
- private static final int MAX_MASK = 0xFFFF;
- static final int DEFAULT_MASK = 0xF;
-
- private volatile long mask = DEFAULT_MASK;
- //private volatile long lastMaskCheck = System.currentTimeMillis();
-
- // IMPORTANT: This field can be updated by multiple threads. It follows that
- // its values may *not* be incremented sequentially. However, we don't care
- // about the actual value of the field except that from time to time the
- // expression (invocationCounter++ & mask) == mask) should be true.
- private long invocationCounter = 0;
-
- // if less than thresholdForMaskIncrease milliseconds elapse between invocations of updateMaskIfNecessary()
- // method, then the mask should be increased
- private static final long MASK_INCREASE_THRESHOLD = 100;
-
- // if more than thresholdForMaskDecrease milliseconds elapse between invocations of updateMaskIfNecessary() method,
- // then the mask should be decreased
- private static final long MASK_DECREASE_THRESHOLD = MASK_INCREASE_THRESHOLD * 8;
-
-
- public DefaultInvocationGate() {
- this(MASK_INCREASE_THRESHOLD, MASK_DECREASE_THRESHOLD, System.currentTimeMillis());
- }
-
- public DefaultInvocationGate(long minDelayThreshold, long maxDelayThreshold, long currentTime) {
- this.minDelayThreshold = minDelayThreshold;
- this.maxDelayThreshold = maxDelayThreshold;
- this.lowerLimitForMaskMatch = currentTime + minDelayThreshold;
- this.upperLimitForNoMaskMatch = currentTime + maxDelayThreshold;
- }
-
- private long minDelayThreshold;
- private long maxDelayThreshold;
-
- long lowerLimitForMaskMatch;
- long upperLimitForNoMaskMatch;
-
- /*
- * (non-Javadoc)
- *
- * @see ch.qos.logback.core.util.InvocationGate#skipFurtherWork()
- */
- @Override
- final public boolean isTooSoon(long currentTime) {
- boolean maskMatch = ((invocationCounter++) & mask) == mask;
-
- if (maskMatch) {
- if (currentTime < this.lowerLimitForMaskMatch) {
- increaseMask();
- }
- updateLimits(currentTime);
- } else {
- if (currentTime > this.upperLimitForNoMaskMatch) {
- decreaseMask();
- updateLimits(currentTime);
- return false;
- }
- }
- return !maskMatch;
- }
-
- private void updateLimits(long currentTime) {
- this.lowerLimitForMaskMatch = currentTime + minDelayThreshold;
- this.upperLimitForNoMaskMatch = currentTime + maxDelayThreshold;
- }
-
-
- // package private, for testing purposes only
- long getMask() {
- return mask;
- }
-
- private void increaseMask() {
- if (mask >= MAX_MASK)
- return;
- mask = (mask << 1) | 1;
- }
-
- private void decreaseMask() {
- mask = mask >>> MASK_DECREASE_RIGHT_SHIFT_COUNT;
- }
-
- public long getInvocationCounter() {
- return invocationCounter;
- }
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/DelayStrategy.java b/logback-core/src/main/java/ch/qos/logback/core/util/DelayStrategy.java
index d534a20..66313ea 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/DelayStrategy.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/DelayStrategy.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,9 +20,9 @@ package ch.qos.logback.core.util;
* @since 1.1.0
*/
public interface DelayStrategy {
- /**
- * The value computed by this {@code DelayStrategy} for the next delay.
- * @return a delay value
- */
- long nextDelay();
+ /**
+ * The value computed by this {@code DelayStrategy} for the next delay.
+ * @return a delay value
+ */
+ long nextDelay();
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/Duration.java b/logback-core/src/main/java/ch/qos/logback/core/util/Duration.java
index 535f23a..8a86bff 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/Duration.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/Duration.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -33,90 +33,94 @@ import java.util.regex.Pattern;
*/
public class Duration {
- private final static String DOUBLE_PART = "([0-9]*(.[0-9]+)?)";
- private final static int DOUBLE_GROUP = 1;
-
- private final static String UNIT_PART = "(|milli(second)?|second(e)?|minute|hour|day)s?";
- private final static int UNIT_GROUP = 3;
-
- private static final Pattern DURATION_PATTERN = Pattern.compile(DOUBLE_PART + "\\s*" + UNIT_PART, Pattern.CASE_INSENSITIVE);
-
- static final long SECONDS_COEFFICIENT = 1000;
- static final long MINUTES_COEFFICIENT = 60 * SECONDS_COEFFICIENT;
- static final long HOURS_COEFFICIENT = 60 * MINUTES_COEFFICIENT;
- static final long DAYS_COEFFICIENT = 24 * HOURS_COEFFICIENT;
-
- final long millis;
-
- public Duration(long millis) {
- this.millis = millis;
- }
-
- public static Duration buildByMilliseconds(double value) {
- return new Duration((long) (value));
- }
-
- public static Duration buildBySeconds(double value) {
- return new Duration((long) (SECONDS_COEFFICIENT * value));
- }
-
- public static Duration buildByMinutes(double value) {
- return new Duration((long) (MINUTES_COEFFICIENT * value));
+ private final static String DOUBLE_PART = "([0-9]*(.[0-9]+)?)";
+ private final static int DOUBLE_GROUP = 1;
+
+ private final static String UNIT_PART = "(|milli(second)?|second(e)?|minute|hour|day)s?";
+ private final static int UNIT_GROUP = 3;
+
+ private static final Pattern DURATION_PATTERN = Pattern.compile(DOUBLE_PART
+ + "\\s*" + UNIT_PART, Pattern.CASE_INSENSITIVE);
+
+ static final long SECONDS_COEFFICIENT = 1000;
+ static final long MINUTES_COEFFICIENT = 60 * SECONDS_COEFFICIENT;
+ static final long HOURS_COEFFICIENT = 60 * MINUTES_COEFFICIENT;
+ static final long DAYS_COEFFICIENT = 24 * HOURS_COEFFICIENT;
+
+ final long millis;
+
+ public Duration(long millis) {
+ this.millis = millis;
+ }
+
+ public static Duration buildByMilliseconds(double value) {
+ return new Duration((long) (value));
+ }
+
+ public static Duration buildBySeconds(double value) {
+ return new Duration((long) (SECONDS_COEFFICIENT * value));
+ }
+
+ public static Duration buildByMinutes(double value) {
+ return new Duration((long) (MINUTES_COEFFICIENT * value));
+ }
+
+ public static Duration buildByHours(double value) {
+ return new Duration((long) (HOURS_COEFFICIENT * value));
+ }
+
+ public static Duration buildByDays(double value) {
+ return new Duration((long) (DAYS_COEFFICIENT * value));
+ }
+
+ public static Duration buildUnbounded() {
+ return new Duration(Long.MAX_VALUE);
+ }
+
+ public long getMilliseconds() {
+ return millis;
+ }
+
+ public static Duration valueOf(String durationStr) {
+ Matcher matcher = DURATION_PATTERN.matcher(durationStr);
+
+ if (matcher.matches()) {
+ String doubleStr = matcher.group(DOUBLE_GROUP);
+ String unitStr = matcher.group(UNIT_GROUP);
+
+ double doubleValue = Double.valueOf(doubleStr);
+ if (unitStr.equalsIgnoreCase("milli")
+ || unitStr.equalsIgnoreCase("millisecond") || unitStr.length() == 0) {
+ return buildByMilliseconds(doubleValue);
+ } else if (unitStr.equalsIgnoreCase("second")
+ || unitStr.equalsIgnoreCase("seconde")) {
+ return buildBySeconds(doubleValue);
+ } else if (unitStr.equalsIgnoreCase("minute")) {
+ return buildByMinutes(doubleValue);
+ } else if (unitStr.equalsIgnoreCase("hour")) {
+ return buildByHours(doubleValue);
+ } else if (unitStr.equalsIgnoreCase("day")) {
+ return buildByDays(doubleValue);
+ } else {
+ throw new IllegalStateException("Unexpected " + unitStr);
+ }
+ } else {
+ throw new IllegalArgumentException("String value [" + durationStr
+ + "] is not in the expected format.");
}
-
- public static Duration buildByHours(double value) {
- return new Duration((long) (HOURS_COEFFICIENT * value));
- }
-
- public static Duration buildByDays(double value) {
- return new Duration((long) (DAYS_COEFFICIENT * value));
+ }
+
+ @Override
+ public String toString() {
+ if (millis < SECONDS_COEFFICIENT) {
+ return millis + " milliseconds";
+ } else if (millis < MINUTES_COEFFICIENT) {
+ return millis / SECONDS_COEFFICIENT + " seconds";
+ } else if (millis < HOURS_COEFFICIENT) {
+ return millis / MINUTES_COEFFICIENT + " minutes";
+ } else {
+ return millis / HOURS_COEFFICIENT + " hours";
}
- public static Duration buildUnbounded() {
- return new Duration(Long.MAX_VALUE);
- }
-
- public long getMilliseconds() {
- return millis;
- }
-
- public static Duration valueOf(String durationStr) {
- Matcher matcher = DURATION_PATTERN.matcher(durationStr);
-
- if (matcher.matches()) {
- String doubleStr = matcher.group(DOUBLE_GROUP);
- String unitStr = matcher.group(UNIT_GROUP);
-
- double doubleValue = Double.valueOf(doubleStr);
- if (unitStr.equalsIgnoreCase("milli") || unitStr.equalsIgnoreCase("millisecond") || unitStr.length() == 0) {
- return buildByMilliseconds(doubleValue);
- } else if (unitStr.equalsIgnoreCase("second") || unitStr.equalsIgnoreCase("seconde")) {
- return buildBySeconds(doubleValue);
- } else if (unitStr.equalsIgnoreCase("minute")) {
- return buildByMinutes(doubleValue);
- } else if (unitStr.equalsIgnoreCase("hour")) {
- return buildByHours(doubleValue);
- } else if (unitStr.equalsIgnoreCase("day")) {
- return buildByDays(doubleValue);
- } else {
- throw new IllegalStateException("Unexpected " + unitStr);
- }
- } else {
- throw new IllegalArgumentException("String value [" + durationStr + "] is not in the expected format.");
- }
- }
-
- @Override
- public String toString() {
- if (millis < SECONDS_COEFFICIENT) {
- return millis + " milliseconds";
- } else if (millis < MINUTES_COEFFICIENT) {
- return millis / SECONDS_COEFFICIENT + " seconds";
- } else if (millis < HOURS_COEFFICIENT) {
- return millis / MINUTES_COEFFICIENT + " minutes";
- } else {
- return millis / HOURS_COEFFICIENT + " hours";
- }
-
- }
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/DynamicClassLoadingException.java b/logback-core/src/main/java/ch/qos/logback/core/util/DynamicClassLoadingException.java
index e2693a7..1c3bfb4 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/DynamicClassLoadingException.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/DynamicClassLoadingException.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,9 +15,9 @@ package ch.qos.logback.core.util;
public class DynamicClassLoadingException extends Exception {
- private static final long serialVersionUID = 4962278449162476114L;
+ private static final long serialVersionUID = 4962278449162476114L;
- public DynamicClassLoadingException(String desc, Throwable root) {
- super(desc, root);
- }
+ public DynamicClassLoadingException(String desc, Throwable root ) {
+ super(desc, root);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/EnvUtil.java b/logback-core/src/main/java/ch/qos/logback/core/util/EnvUtil.java
index 6cd1405..ea7916b 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/EnvUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/EnvUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,54 +17,55 @@ import java.util.ArrayList;
import java.util.List;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class EnvUtil {
- static private boolean isJDK_N_OrHigher(int n) {
- List<String> versionList = new ArrayList<String>();
- // this code should work at least until JDK 10 (assuming n parameter is
- // always 6 or more)
- for (int i = 0; i < 5; i++) {
- versionList.add("1." + (n + i));
- }
- String javaVersion = System.getProperty("java.version");
- if (javaVersion == null) {
- return false;
- }
- for (String v : versionList) {
- if (javaVersion.startsWith(v))
- return true;
- }
- return false;
- }
+ static private boolean isJDK_N_OrHigher(int n) {
+ List<String> versionList = new ArrayList<String>();
+ // this code should work at least until JDK 10 (assuming n parameter is
+ // always 6 or more)
+ for (int i = 0; i < 5; i++) {
+ versionList.add("1." + (n + i));
+ }
- static public boolean isJDK5() {
- return isJDK_N_OrHigher(5);
- }
+ String javaVersion = System.getProperty("java.version");
+ if (javaVersion == null) {
+ return false;
+ }
+ for (String v : versionList) {
+ if (javaVersion.startsWith(v))
+ return true;
+ }
+ return false;
+ }
- static public boolean isJDK6OrHigher() {
- return isJDK_N_OrHigher(6);
- }
+ static public boolean isJDK5() {
+ return isJDK_N_OrHigher(5);
+ }
- static public boolean isJDK7OrHigher() {
- return isJDK_N_OrHigher(7);
- }
+ static public boolean isJDK6OrHigher() {
+ return isJDK_N_OrHigher(6);
+ }
- static public boolean isJaninoAvailable() {
- ClassLoader classLoader = EnvUtil.class.getClassLoader();
- try {
- Class<?> bindingClass = classLoader.loadClass("org.codehaus.janino.ScriptEvaluator");
- return (bindingClass != null);
- } catch (ClassNotFoundException e) {
- return false;
- }
- }
+ static public boolean isJDK7OrHigher() {
+ return isJDK_N_OrHigher(7);
+ }
- public static boolean isWindows() {
- String os = System.getProperty("os.name");
- return os.startsWith("Windows");
+ static public boolean isJaninoAvailable() {
+ ClassLoader classLoader = EnvUtil.class.getClassLoader();
+ try {
+ Class<?> bindingClass = classLoader.loadClass("org.codehaus.janino.ScriptEvaluator");
+ return (bindingClass != null);
+ } catch (ClassNotFoundException e) {
+ return false;
}
+ }
+
+ public static boolean isWindows() {
+ String os = System.getProperty("os.name");
+ return os.startsWith("Windows");
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/ExecutorServiceUtil.java b/logback-core/src/main/java/ch/qos/logback/core/util/ExecutorServiceUtil.java
index 6332636..771545a 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/ExecutorServiceUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/ExecutorServiceUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2011, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -11,17 +11,13 @@
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
+
package ch.qos.logback.core.util;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
import ch.qos.logback.core.CoreConstants;
@@ -29,46 +25,27 @@ import ch.qos.logback.core.CoreConstants;
* Static utility methods for manipulating an {@link ExecutorService}.
*
* @author Carl Harris
- * @author Mikhail Mazursky
*/
public class ExecutorServiceUtil {
- private static final ThreadFactory THREAD_FACTORY = new ThreadFactory() {
-
- private final ThreadFactory defaultFactory = Executors.defaultThreadFactory();
- private final AtomicInteger threadNumber = new AtomicInteger(1);
-
- public Thread newThread(Runnable r) {
- Thread thread = defaultFactory.newThread(r);
- if (!thread.isDaemon()) {
- thread.setDaemon(true);
- }
- thread.setName("logback-" + threadNumber.getAndIncrement());
- return thread;
- }
- };
-
- static public ScheduledExecutorService newScheduledExecutorService() {
- return new ScheduledThreadPoolExecutor(CoreConstants.SCHEDULED_EXECUTOR_POOL_SIZE, THREAD_FACTORY);
- }
-
-
- /**
- * Creates an executor service suitable for use by logback components.
- * @return executor service
- */
- static public ExecutorService newExecutorService() {
- return new ThreadPoolExecutor(CoreConstants.CORE_POOL_SIZE, CoreConstants.MAX_POOL_SIZE, 0L, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>(),
- THREAD_FACTORY);
- }
-
- /**
- * Shuts down an executor service.
- * <p>
- * @param executorService the executor service to shut down
- */
- static public void shutdown(ExecutorService executorService) {
- executorService.shutdownNow();
- }
+ /**
+ * Creates an executor service suitable for use by logback components.
+ * @return executor service
+ */
+ static public ExecutorService newExecutorService() {
+ return new ThreadPoolExecutor(CoreConstants.CORE_POOL_SIZE,
+ CoreConstants.MAX_POOL_SIZE,
+ 0L, TimeUnit.MILLISECONDS,
+ new SynchronousQueue<Runnable>());
+ }
+
+ /**
+ * Shuts down an executor service.
+ * <p>
+ * @param executorService the executor service to shut down
+ */
+ static public void shutdown(ExecutorService executorService) {
+ executorService.shutdownNow();
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/FileSize.java b/logback-core/src/main/java/ch/qos/logback/core/util/FileSize.java
index ba73e52..d1e8435 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/FileSize.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/FileSize.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,66 +31,54 @@ import java.util.regex.Pattern;
*/
public class FileSize {
- private final static String LENGTH_PART = "([0-9]+)";
- private final static int DOUBLE_GROUP = 1;
+ private final static String LENGTH_PART = "([0-9]+)";
+ private final static int DOUBLE_GROUP = 1;
- private final static String UNIT_PART = "(|kb|mb|gb)s?";
- private final static int UNIT_GROUP = 2;
+ private final static String UNIT_PART = "(|kb|mb|gb)s?";
+ private final static int UNIT_GROUP = 2;
- private static final Pattern FILE_SIZE_PATTERN = Pattern.compile(LENGTH_PART + "\\s*" + UNIT_PART, Pattern.CASE_INSENSITIVE);
+ private static final Pattern FILE_SIZE_PATTERN = Pattern.compile(LENGTH_PART
+ + "\\s*" + UNIT_PART, Pattern.CASE_INSENSITIVE);
- static public final long KB_COEFFICIENT = 1024;
- static public final long MB_COEFFICIENT = 1024 * KB_COEFFICIENT;
- static public final long GB_COEFFICIENT = 1024 * MB_COEFFICIENT;
+ static final long KB_COEFFICIENT = 1024;
+ static final long MB_COEFFICIENT = 1024 * KB_COEFFICIENT;
+ static final long GB_COEFFICIENT = 1024 * MB_COEFFICIENT;
- final long size;
+ final long size;
- public FileSize(long size) {
- this.size = size;
- }
+ FileSize(long size) {
+ this.size = size;
+ }
- public long getSize() {
- return size;
- }
+ public long getSize() {
+ return size;
+ }
- static public FileSize valueOf(String fileSizeStr) {
- Matcher matcher = FILE_SIZE_PATTERN.matcher(fileSizeStr);
+ static public FileSize valueOf(String fileSizeStr) {
+ Matcher matcher = FILE_SIZE_PATTERN.matcher(fileSizeStr);
- long coefficient;
- if (matcher.matches()) {
- String lenStr = matcher.group(DOUBLE_GROUP);
- String unitStr = matcher.group(UNIT_GROUP);
+ long coefficient;
+ if (matcher.matches()) {
+ String lenStr = matcher.group(DOUBLE_GROUP);
+ String unitStr = matcher.group(UNIT_GROUP);
- long lenValue = Long.valueOf(lenStr);
- if (unitStr.equalsIgnoreCase("")) {
- coefficient = 1;
- } else if (unitStr.equalsIgnoreCase("kb")) {
- coefficient = KB_COEFFICIENT;
- } else if (unitStr.equalsIgnoreCase("mb")) {
- coefficient = MB_COEFFICIENT;
- } else if (unitStr.equalsIgnoreCase("gb")) {
- coefficient = GB_COEFFICIENT;
- } else {
- throw new IllegalStateException("Unexpected " + unitStr);
- }
- return new FileSize(lenValue * coefficient);
- } else {
- throw new IllegalArgumentException("String value [" + fileSizeStr + "] is not in the expected format.");
- }
- }
-
- @Override
- public String toString() {
- long inKB = size / KB_COEFFICIENT;
-
- if(inKB == 0)
- return size + " Bytes";
-
- long inMB = size / MB_COEFFICIENT;
- if(inMB == 0) {
- return inKB + " KB";
- }
-
- return inMB + " MB";
+ long lenValue = Long.valueOf(lenStr);
+ if (unitStr.equalsIgnoreCase("")) {
+ coefficient = 1;
+ } else if (unitStr.equalsIgnoreCase("kb")) {
+ coefficient = KB_COEFFICIENT;
+ } else if (unitStr.equalsIgnoreCase("mb")) {
+ coefficient = MB_COEFFICIENT;
+ } else if (unitStr.equalsIgnoreCase("gb")) {
+ coefficient = GB_COEFFICIENT;
+ } else {
+ throw new IllegalStateException("Unexpected " + unitStr);
+ }
+ return new FileSize(lenValue * coefficient);
+ } else {
+ throw new IllegalArgumentException("String value [" + fileSizeStr
+ + "] is not in the expected format.");
}
+
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/FileUtil.java b/logback-core/src/main/java/ch/qos/logback/core/util/FileUtil.java
index d56ce09..e308767 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/FileUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/FileUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,112 +24,110 @@ import java.net.URLConnection;
public class FileUtil extends ContextAwareBase {
- public FileUtil(Context context) {
- setContext(context);
- }
+ public FileUtil(Context context) {
+ setContext(context);
+ }
- public static URL fileToURL(File file) {
- try {
- return file.toURI().toURL();
- } catch (MalformedURLException e) {
- throw new RuntimeException("Unexpected exception on file [" + file + "]", e);
- }
+ public static URL fileToURL(File file) {
+ try {
+ return file.toURI().toURL();
+ } catch (MalformedURLException e) {
+ throw new RuntimeException("Unexpected exception on file [" + file + "]", e);
}
+ }
- /**
- * Creates the parent directories of a file. If parent directories not
- * specified in file's path, then nothing is done and this returns
- * gracefully.
- *
- * @param file file whose parent directories (if any) should be created
- * @return {@code true} if either no parents were specified, or if all
- * parent directories were created successfully; {@code false} otherwise
- */
- static public boolean createMissingParentDirectories(File file) {
- File parent = file.getParentFile();
- if (parent == null) {
- // Parent directory not specified, therefore it's a request to
- // create nothing. Done! ;)
- return true;
- }
+ static public boolean isParentDirectoryCreationRequired(File file) {
+ File parent = file.getParentFile();
+ if (parent != null && !parent.exists()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
- // File.mkdirs() creates the parent directories only if they don't
- // already exist; and it's okay if they do.
- parent.mkdirs();
- return parent.exists();
+ static public boolean createMissingParentDirectories(File file) {
+ File parent = file.getParentFile();
+ if (parent == null) {
+ throw new IllegalStateException(file + " should not have a null parent");
+ }
+ if (parent.exists()) {
+ throw new IllegalStateException(file + " should not have existing parent directory");
}
+ return parent.mkdirs();
+ }
- public String resourceAsString(ClassLoader classLoader, String resourceName) {
- URL url = classLoader.getResource(resourceName);
- if (url == null) {
- addError("Failed to find resource [" + resourceName + "]");
- return null;
- }
- InputStreamReader isr = null;
+ public String resourceAsString(ClassLoader classLoader, String resourceName) {
+ URL url = classLoader.getResource(resourceName);
+ if (url == null) {
+ addError("Failed to find resource [" + resourceName + "]");
+ return null;
+ }
+
+ InputStreamReader isr = null;
+ try {
+ URLConnection urlConnection = url.openConnection();
+ urlConnection.setUseCaches(false);
+ isr = new InputStreamReader(urlConnection.getInputStream());
+ char[] buf = new char[128];
+ StringBuilder builder = new StringBuilder();
+ int count = -1;
+ while ((count = isr.read(buf, 0, buf.length)) != -1) {
+ builder.append(buf, 0, count);
+ }
+ return builder.toString();
+ } catch (IOException e) {
+ addError("Failed to open " + resourceName, e);
+ } finally {
+ if (isr != null) {
try {
- URLConnection urlConnection = url.openConnection();
- urlConnection.setUseCaches(false);
- isr = new InputStreamReader(urlConnection.getInputStream());
- char[] buf = new char[128];
- StringBuilder builder = new StringBuilder();
- int count = -1;
- while ((count = isr.read(buf, 0, buf.length)) != -1) {
- builder.append(buf, 0, count);
- }
- return builder.toString();
+ isr.close();
} catch (IOException e) {
- addError("Failed to open " + resourceName, e);
- } finally {
- if (isr != null) {
- try {
- isr.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ // ignore
}
- return null;
+ }
}
+ return null;
+ }
- static final int BUF_SIZE = 32 * 1024;
+ static final int BUF_SIZE = 32 * 1024;
- public void copy(String src, String destination) throws RolloverFailure {
- BufferedInputStream bis = null;
- BufferedOutputStream bos = null;
- try {
- bis = new BufferedInputStream(new FileInputStream(src));
- bos = new BufferedOutputStream(new FileOutputStream(destination));
- byte[] inbuf = new byte[BUF_SIZE];
- int n;
+ public void copy(String src, String destination) throws RolloverFailure {
+ BufferedInputStream bis = null;
+ BufferedOutputStream bos = null;
+ try {
+ bis = new BufferedInputStream(new FileInputStream(src));
+ bos = new BufferedOutputStream(new FileOutputStream(destination));
+ byte[] inbuf = new byte[BUF_SIZE];
+ int n;
- while ((n = bis.read(inbuf)) != -1) {
- bos.write(inbuf, 0, n);
- }
+ while ((n = bis.read(inbuf)) != -1) {
+ bos.write(inbuf, 0, n);
+ }
- bis.close();
- bis = null;
- bos.close();
- bos = null;
- } catch (IOException ioe) {
- String msg = "Failed to copy [" + src + "] to [" + destination + "]";
- addError(msg, ioe);
- throw new RolloverFailure(msg);
- } finally {
- if (bis != null) {
- try {
- bis.close();
- } catch (IOException e) {
- // ignore
- }
- }
- if (bos != null) {
- try {
- bos.close();
- } catch (IOException e) {
- // ignore
- }
- }
+ bis.close();
+ bis = null;
+ bos.close();
+ bos = null;
+ } catch (IOException ioe) {
+ String msg = "Failed to copy [" + src + "] to [" + destination + "]";
+ addError(msg, ioe);
+ throw new RolloverFailure(msg);
+ } finally {
+ if (bis != null) {
+ try {
+ bis.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ if (bos != null) {
+ try {
+ bos.close();
+ } catch (IOException e) {
+ // ignore
}
+ }
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/FixedDelay.java b/logback-core/src/main/java/ch/qos/logback/core/util/FixedDelay.java
index 946f411..e53b108 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/FixedDelay.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/FixedDelay.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,39 +21,39 @@ package ch.qos.logback.core.util;
*/
public class FixedDelay implements DelayStrategy {
- private final long subsequentDelay;
- private long nextDelay;
+ private final long subsequentDelay;
+ private long nextDelay;
- /**
- * Initialize a new {@code FixedDelay} with a given {@code initialDelay} and
- * {@code subsequentDelay}.
- *
- * @param initialDelay value for the initial delay
- * @param subsequentDelay value for all other delays
- */
- public FixedDelay(long initialDelay, long subsequentDelay) {
- String s = new String();
- this.nextDelay = initialDelay;
- this.subsequentDelay = subsequentDelay;
- }
+ /**
+ * Initialize a new {@code FixedDelay} with a given {@code initialDelay} and
+ * {@code subsequentDelay}.
+ *
+ * @param initialDelay value for the initial delay
+ * @param subsequentDelay value for all other delays
+ */
+ public FixedDelay(long initialDelay, long subsequentDelay) {
+ String s = new String();
+ this.nextDelay = initialDelay;
+ this.subsequentDelay = subsequentDelay;
+ }
- /**
- * Initialize a new {@code FixedDelay} with fixed delay value given by {@code delay}
- * parameter.
- *
- * @param delay value for all delays
- */
- public FixedDelay(int delay) {
- this(delay, delay);
- }
+ /**
+ * Initialize a new {@code FixedDelay} with fixed delay value given by {@code delay}
+ * parameter.
+ *
+ * @param delay value for all delays
+ */
+ public FixedDelay(int delay) {
+ this(delay, delay);
+ }
- /**
- * {@inheritDoc}
- */
- public long nextDelay() {
- long delay = nextDelay;
- nextDelay = subsequentDelay;
- return delay;
- }
+ /**
+ * {@inheritDoc}
+ */
+ public long nextDelay() {
+ long delay = nextDelay;
+ nextDelay = subsequentDelay;
+ return delay;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/IncompatibleClassException.java b/logback-core/src/main/java/ch/qos/logback/core/util/IncompatibleClassException.java
index 18108d3..5449ce1 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/IncompatibleClassException.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/IncompatibleClassException.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,14 +15,14 @@ package ch.qos.logback.core.util;
public class IncompatibleClassException extends Exception {
- private static final long serialVersionUID = -5823372159561159549L;
+ private static final long serialVersionUID = -5823372159561159549L;
- Class<?> requestedClass;
- Class<?> obtainedClass;
-
- IncompatibleClassException(Class<?> requestedClass, Class<?> obtainedClass) {
- super();
- this.requestedClass = requestedClass;
- this.obtainedClass = obtainedClass;
- }
+ Class<?> requestedClass;
+ Class<?> obtainedClass;
+
+ IncompatibleClassException(Class<?> requestedClass, Class<?> obtainedClass) {
+ super();
+ this.requestedClass = requestedClass;
+ this.obtainedClass = obtainedClass;
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/InvocationGate.java b/logback-core/src/main/java/ch/qos/logback/core/util/InvocationGate.java
index fc9e42b..a474997 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/InvocationGate.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/InvocationGate.java
@@ -1,17 +1,61 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
package ch.qos.logback.core.util;
-public interface InvocationGate {
+/**
+ * This class serves as a gateway for invocations of a "costly" operation on a critical execution path.
+ *
+ * @author Ceki Gülcü
+ */
+public class InvocationGate {
- final long TIME_UNAVAILABLE = -1;
+ // experiments indicate that even for the most CPU intensive applications with 200 or more threads MASK
+ // values in the order of 0xFFFF is appropriate
+ private static final int MAX_MASK = 0xFFFF;
- /**
- * The caller of this method can decide to skip further work if the returned value is true.
- *
- * Implementations should be able to give a reasonable answer even if current time date is unavailable.
- *
- * @param now can be TIME_UNAVAILABLE (-1) to signal that time is not available
- * @return if true, caller should skip further work
- */
- public abstract boolean isTooSoon(long currentTime);
+ private volatile long mask = 0xF;
+ private volatile long lastMaskCheck = System.currentTimeMillis();
-}
\ No newline at end of file
+
+ // IMPORTANT: This field can be updated by multiple threads. It follows that
+ // its values may *not* be incremented sequentially. However, we don't care
+ // about the actual value of the field except that from time to time the
+ // expression (invocationCounter++ & mask) == mask) should be true.
+ private long invocationCounter = 0;
+
+
+ // if less than thresholdForMaskIncrease milliseconds elapse between invocations of updateMaskIfNecessary()
+ // method, then the mask should be increased
+ private static final long thresholdForMaskIncrease = 100;
+
+ // if more than thresholdForMaskDecrease milliseconds elapse between invocations of updateMaskIfNecessary() method,
+ // then the mask should be decreased
+ private final long thresholdForMaskDecrease = thresholdForMaskIncrease*8;
+
+
+ public boolean skipFurtherWork() {
+ return ((invocationCounter++) & mask) != mask;
+ }
+
+ // update the mask so as to execute change detection code about once every 100 to 8000 milliseconds.
+ public void updateMaskIfNecessary(long now) {
+ final long timeElapsedSinceLastMaskUpdateCheck = now - lastMaskCheck;
+ lastMaskCheck = now;
+ if (timeElapsedSinceLastMaskUpdateCheck < thresholdForMaskIncrease && (mask < MAX_MASK)) {
+ mask = (mask << 1) | 1;
+ } else if (timeElapsedSinceLastMaskUpdateCheck > thresholdForMaskDecrease) {
+ mask = mask >>> 2;
+ }
+ }
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/Loader.java b/logback-core/src/main/java/ch/qos/logback/core/util/Loader.java
index 82f1d15..db14afa 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/Loader.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/Loader.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,163 +29,169 @@ import ch.qos.logback.core.Context;
* @author Ceki Gülcü
*/
public class Loader {
- static final String TSTR = "Caught Exception while in Loader.getResource. This may be innocuous.";
+ static final String TSTR = "Caught Exception while in Loader.getResource. This may be innocuous.";
- private static boolean ignoreTCL = false;
- public static final String IGNORE_TCL_PROPERTY_NAME = "logback.ignoreTCL";
- private static boolean HAS_GET_CLASS_LOADER_PERMISSION = false;
+ private static boolean ignoreTCL = false;
+ public static final String IGNORE_TCL_PROPERTY_NAME = "logback.ignoreTCL";
+ private static boolean HAS_GET_CLASS_LOADER_PERMISSION = false;
- static {
- String ignoreTCLProp = OptionHelper.getSystemProperty(IGNORE_TCL_PROPERTY_NAME, null);
+ static {
+ String ignoreTCLProp = OptionHelper.getSystemProperty(
+ IGNORE_TCL_PROPERTY_NAME, null);
- if (ignoreTCLProp != null) {
- ignoreTCL = OptionHelper.toBoolean(ignoreTCLProp, true);
- }
+ if (ignoreTCLProp != null) {
+ ignoreTCL = OptionHelper.toBoolean(ignoreTCLProp, true);
+ }
- HAS_GET_CLASS_LOADER_PERMISSION = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
- public Boolean run() {
+ HAS_GET_CLASS_LOADER_PERMISSION =
+ AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+ public Boolean run() {
try {
- AccessController.checkPermission(new RuntimePermission("getClassLoader"));
- return true;
+ AccessController.checkPermission(
+ new RuntimePermission("getClassLoader"));
+ return true;
} catch (SecurityException e) {
- // Using SecurityException instead of AccessControlException.
- // See bug LOGBACK-760.
- return false;
+ // Using SecurityException instead of AccessControlException.
+ // See bug LOGBACK-760.
+ return false;
}
- }
- });
- }
-
- /**
- * Compute the number of occurrences a resource can be found by a class
- * loader.
- *
- * @param resource
- * @param classLoader
- * @return
- * @throws IOException
- */
-
- public static Set<URL> getResources(String resource, ClassLoader classLoader) throws IOException {
- // See LBCLASSIC-159
- Set<URL> urlSet = new HashSet<URL>();
- Enumeration<URL> urlEnum = classLoader.getResources(resource);
- while (urlEnum.hasMoreElements()) {
- URL url = urlEnum.nextElement();
- urlSet.add(url);
- }
- return urlSet;
- }
-
- /**
- * Search for a resource using the classloader passed as parameter.
- *
- * @param resource the resource name to look for
- * @param classLoader the classloader used for the search
- */
- public static URL getResource(String resource, ClassLoader classLoader) {
- try {
- return classLoader.getResource(resource);
- } catch (Throwable t) {
- return null;
- }
- }
-
- /**
- * Attempt to find a resource by using the classloader that loaded this class,
- * namely Loader.class.
- *
- * @param resource
- * @return
- */
- public static URL getResourceBySelfClassLoader(String resource) {
- return getResource(resource, getClassLoaderOfClass(Loader.class));
- }
-
- // private static URL getResourceByTCL(String resource) {
- // return getResource(resource, getTCL());
- // }
-
- /**
- * Get the Thread Context Loader which is a JDK 1.2 feature. If we are running
- * under JDK 1.1 or anything else goes wrong the method returns
- * <code>null<code>.
- */
- public static ClassLoader getTCL() {
- return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ }
+
+ /**
+ * Compute the number of occurrences a resource can be found by a class
+ * loader.
+ *
+ * @param resource
+ * @param classLoader
+ * @return
+ * @throws IOException
+ */
+
+ public static Set<URL> getResourceOccurrenceCount(String resource,
+ ClassLoader classLoader) throws IOException {
+ // See LBCLASSIC-159
+ Set<URL> urlSet = new HashSet<URL>();
+ Enumeration<URL> urlEnum = classLoader.getResources(resource);
+ while (urlEnum.hasMoreElements()) {
+ URL url = urlEnum.nextElement();
+ urlSet.add(url);
}
-
- public static Class<?> loadClass(String clazz, Context context) throws ClassNotFoundException {
- ClassLoader cl = getClassLoaderOfObject(context);
- return cl.loadClass(clazz);
+ return urlSet;
+ }
+
+ /**
+ * Search for a resource using the classloader passed as parameter.
+ *
+ * @param resource the resource name to look for
+ * @param classLoader the classloader used for the search
+ */
+ public static URL getResource(String resource, ClassLoader classLoader) {
+ try {
+ return classLoader.getResource(resource);
+ } catch (Throwable t) {
+ return null;
}
-
- /**
- * Get the class loader of the object passed as argument. Return the system
- * class loader if appropriate.
- *
- * @param o
- * @return
- */
- public static ClassLoader getClassLoaderOfObject(Object o) {
- if (o == null) {
- throw new NullPointerException("Argument cannot be null");
- }
- return getClassLoaderOfClass(o.getClass());
+ }
+
+ /**
+ * Attempt to find a resource by using the classloader that loaded this class,
+ * namely Loader.class.
+ *
+ * @param resource
+ * @return
+ */
+ public static URL getResourceBySelfClassLoader(String resource) {
+ return getResource(resource, getClassLoaderOfClass(Loader.class));
+ }
+
+ // private static URL getResourceByTCL(String resource) {
+ // return getResource(resource, getTCL());
+ // }
+
+ /**
+ * Get the Thread Context Loader which is a JDK 1.2 feature. If we are running
+ * under JDK 1.1 or anything else goes wrong the method returns
+ * <code>null<code>.
+ */
+ public static ClassLoader getTCL() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+
+ public static Class<?> loadClass(String clazz, Context context)
+ throws ClassNotFoundException {
+ ClassLoader cl = getClassLoaderOfObject(context);
+ return cl.loadClass(clazz);
+ }
+
+ /**
+ * Get the class loader of the object passed as argument. Return the system
+ * class loader if appropriate.
+ *
+ * @param o
+ * @return
+ */
+ public static ClassLoader getClassLoaderOfObject(Object o) {
+ if (o == null) {
+ throw new NullPointerException("Argument cannot be null");
}
-
- /**
- * Returns the class loader of clazz in an access privileged section.
- *
- * @param clazz
- * @return
- */
- public static ClassLoader getClassLoaderAsPrivileged(final Class<?> clazz) {
- if (!HAS_GET_CLASS_LOADER_PERMISSION)
- return null;
- else
- return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ return getClassLoaderOfClass(o.getClass());
+ }
+
+ /**
+ * Returns the class loader of clazz in an access privileged section.
+ *
+ * @param clazz
+ * @return
+ */
+ public static ClassLoader getClassLoaderAsPrivileged(final Class<?> clazz) {
+ if (!HAS_GET_CLASS_LOADER_PERMISSION)
+ return null;
+ else
+ return AccessController.doPrivileged(
+ new PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
- return clazz.getClassLoader();
+ return clazz.getClassLoader();
}
- });
- }
-
- /**
- * Return the class loader which loaded the class passed as argument. Return
- * the system class loader if appropriate.
- *
- * @param clazz
- * @return
- */
- public static ClassLoader getClassLoaderOfClass(final Class<?> clazz) {
- ClassLoader cl = clazz.getClassLoader();
- if (cl == null) {
- return ClassLoader.getSystemClassLoader();
- } else {
- return cl;
- }
+ });
+ }
+
+ /**
+ * Return the class loader which loaded the class passed as argument. Return
+ * the system class loader if appropriate.
+ *
+ * @param clazz
+ * @return
+ */
+ public static ClassLoader getClassLoaderOfClass(final Class<?> clazz) {
+ ClassLoader cl = clazz.getClassLoader();
+ if (cl == null) {
+ return ClassLoader.getSystemClassLoader();
+ } else {
+ return cl;
}
-
- /**
- * If running under JDK 1.2 load the specified class using the
- * <code>Thread</code> <code>contextClassLoader</code> if that fails try
- * Class.forname. Under JDK 1.1 only Class.forName is used.
- */
- public static Class<?> loadClass(String clazz) throws ClassNotFoundException {
- // Just call Class.forName(clazz) if we are running under JDK 1.1
- // or if we are instructed to ignore the TCL.
- if (ignoreTCL) {
- return Class.forName(clazz);
- } else {
- try {
- return getTCL().loadClass(clazz);
- } catch (Throwable e) {
- // we reached here because tcl was null or because of a
- // security exception, or because clazz could not be loaded...
- // In any case we now try one more time
- return Class.forName(clazz);
- }
- }
+ }
+
+ /**
+ * If running under JDK 1.2 load the specified class using the
+ * <code>Thread</code> <code>contextClassLoader</code> if that fails try
+ * Class.forname. Under JDK 1.1 only Class.forName is used.
+ */
+ public static Class<?> loadClass(String clazz) throws ClassNotFoundException {
+ // Just call Class.forName(clazz) if we are running under JDK 1.1
+ // or if we are instructed to ignore the TCL.
+ if (ignoreTCL) {
+ return Class.forName(clazz);
+ } else {
+ try {
+ return getTCL().loadClass(clazz);
+ } catch (Throwable e) {
+ // we reached here because tcl was null or because of a
+ // security exception, or because clazz could not be loaded...
+ // In any case we now try one more time
+ return Class.forName(clazz);
+ }
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/LocationUtil.java b/logback-core/src/main/java/ch/qos/logback/core/util/LocationUtil.java
index 65785ce..65c0aa4 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/LocationUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/LocationUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,6 +17,7 @@ import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.net.URL;
+
/**
* A static utility method that converts a string that describes the
* location of a resource into a {@link URL} object.
@@ -25,45 +26,50 @@ import java.net.URL;
*/
public class LocationUtil {
- /** Regex pattern for a URL scheme (reference RFC 2396 section 3) */
- public static final String SCHEME_PATTERN = "^\\p{Alpha}[\\p{Alnum}+.-]*:.*$";
-
- /** Scheme name for a classpath resource */
- public static final String CLASSPATH_SCHEME = "classpath:";
+
+ /** Regex pattern for a URL scheme (reference RFC 2396 section 3) */
+ public static final String SCHEME_PATTERN =
+ "^\\p{Alpha}[\\p{Alnum}+.-]*:.*$";
- /**
- * Converts a string describing the location of a resource into a URL object.
- * @param location String describing the location
- * @return URL object that refers to {@code location}
- * @throws MalformedURLException if {@code location} is not a syntatically
- * valid URL
- * @throws FileNotFoundException if {@code location} specifies a non-existent
- * classpath resource
- * @throws NullPointerException if {@code location} is {@code null}
- */
- public static URL urlForResource(String location) throws MalformedURLException, FileNotFoundException {
- if (location == null) {
- throw new NullPointerException("location is required");
- }
- URL url = null;
- if (!location.matches(SCHEME_PATTERN)) {
- url = Loader.getResourceBySelfClassLoader(location);
- } else if (location.startsWith(CLASSPATH_SCHEME)) {
- String path = location.substring(CLASSPATH_SCHEME.length());
- if (path.startsWith("/")) {
- path = path.substring(1);
- }
- if (path.length() == 0) {
- throw new MalformedURLException("path is required");
- }
- url = Loader.getResourceBySelfClassLoader(path);
- } else {
- url = new URL(location);
- }
- if (url == null) {
- throw new FileNotFoundException(location);
- }
- return url;
+ /** Scheme name for a classpath resource */
+ public static final String CLASSPATH_SCHEME = "classpath:";
+
+ /**
+ * Converts a string describing the location of a resource into a URL object.
+ * @param location String describing the location
+ * @return URL object that refers to {@code location}
+ * @throws MalformedURLException if {@code location} is not a syntatically
+ * valid URL
+ * @throws FileNotFoundException if {@code location} specifies a non-existent
+ * classpath resource
+ * @throws NullPointerException if {@code location} is {@code null}
+ */
+ public static URL urlForResource(String location)
+ throws MalformedURLException, FileNotFoundException {
+ if (location == null) {
+ throw new NullPointerException("location is required");
}
-
+ URL url = null;
+ if (!location.matches(SCHEME_PATTERN)) {
+ url = Loader.getResourceBySelfClassLoader(location);
+ }
+ else if (location.startsWith(CLASSPATH_SCHEME)) {
+ String path = location.substring(CLASSPATH_SCHEME.length());
+ if (path.startsWith("/")) {
+ path = path.substring(1);
+ }
+ if (path.length() == 0) {
+ throw new MalformedURLException("path is required");
+ }
+ url = Loader.getResourceBySelfClassLoader(path);
+ }
+ else {
+ url = new URL(location);
+ }
+ if (url == null) {
+ throw new FileNotFoundException(location);
+ }
+ return url;
+ }
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java b/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java
index b9b1b85..0bc01d8 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,237 +28,245 @@ import ch.qos.logback.core.subst.NodeToStringTransformer;
*/
public class OptionHelper {
- public static Object instantiateByClassName(String className, Class<?> superClass, Context context) throws IncompatibleClassException,
- DynamicClassLoadingException {
- ClassLoader classLoader = Loader.getClassLoaderOfObject(context);
- return instantiateByClassName(className, superClass, classLoader);
- }
+ public static Object instantiateByClassName(String className,
+ Class<?> superClass, Context context) throws IncompatibleClassException,
+ DynamicClassLoadingException {
+ ClassLoader classLoader = Loader.getClassLoaderOfObject(context);
+ return instantiateByClassName(className, superClass, classLoader);
+ }
- public static Object instantiateByClassNameAndParameter(String className, Class<?> superClass, Context context, Class<?> type, Object param)
- throws IncompatibleClassException, DynamicClassLoadingException {
- ClassLoader classLoader = Loader.getClassLoaderOfObject(context);
- return instantiateByClassNameAndParameter(className, superClass, classLoader, type, param);
- }
+ public static Object instantiateByClassNameAndParameter(String className,
+ Class<?> superClass, Context context, Class<?> type, Object param) throws IncompatibleClassException,
+ DynamicClassLoadingException {
+ ClassLoader classLoader = Loader.getClassLoaderOfObject(context);
+ return instantiateByClassNameAndParameter(className, superClass, classLoader, type, param);
+ }
- public static Object instantiateByClassName(String className, Class<?> superClass, ClassLoader classLoader) throws IncompatibleClassException,
- DynamicClassLoadingException {
- return instantiateByClassNameAndParameter(className, superClass, classLoader, null, null);
- }
+ public static Object instantiateByClassName(String className,
+ Class<?> superClass, ClassLoader classLoader)
+ throws IncompatibleClassException, DynamicClassLoadingException {
+ return instantiateByClassNameAndParameter(className, superClass, classLoader, null, null);
+ }
- public static Object instantiateByClassNameAndParameter(String className, Class<?> superClass, ClassLoader classLoader, Class<?> type, Object parameter)
- throws IncompatibleClassException, DynamicClassLoadingException {
-
- if (className == null) {
- throw new NullPointerException();
- }
- try {
- Class<?> classObj = null;
- classObj = classLoader.loadClass(className);
- if (!superClass.isAssignableFrom(classObj)) {
- throw new IncompatibleClassException(superClass, classObj);
- }
- if (type == null) {
- return classObj.newInstance();
- } else {
- Constructor<?> constructor = classObj.getConstructor(type);
- return constructor.newInstance(parameter);
- }
- } catch (IncompatibleClassException ice) {
- throw ice;
- } catch (Throwable t) {
- throw new DynamicClassLoadingException("Failed to instantiate type " + className, t);
- }
+ public static Object instantiateByClassNameAndParameter(String className,
+ Class<?> superClass, ClassLoader classLoader, Class<?> type, Object parameter)
+ throws IncompatibleClassException, DynamicClassLoadingException {
+
+ if (className == null) {
+ throw new NullPointerException();
+ }
+ try {
+ Class<?> classObj = null;
+ classObj = classLoader.loadClass(className);
+ if (!superClass.isAssignableFrom(classObj)) {
+ throw new IncompatibleClassException(superClass, classObj);
+ }
+ if (type == null) {
+ return classObj.newInstance();
+ } else {
+ Constructor<?> constructor = classObj.getConstructor(type);
+ return constructor.newInstance(parameter);
+ }
+ } catch (IncompatibleClassException ice) {
+ throw ice;
+ } catch (Throwable t) {
+ throw new DynamicClassLoadingException("Failed to instantiate type "
+ + className, t);
}
+ }
+
+ /**
+ * Find the value corresponding to <code>key</code> in <code>props</code>.
+ * Then perform variable substitution on the found value.
+ */
+ // public static String findAndSubst(String key, Properties props) {
+ // String value = props.getProperty(key);
+ //
+ // if (value == null) {
+ // return null;
+ // }
+ //
+ // try {
+ // return substVars(value, props);
+ // } catch (IllegalArgumentException e) {
+ // return value;
+ // }
+ // }
+ final static String DELIM_START = "${";
+ final static char DELIM_STOP = '}';
+ final static String DELIM_DEFAULT = ":-";
+
+ final static int DELIM_START_LEN = 2;
+ final static int DELIM_STOP_LEN = 1;
+ final static int DELIM_DEFAULT_LEN = 2;
+
+ final static String _IS_UNDEFINED = "_IS_UNDEFINED";
+
+ /**
+ * @see #substVars(String, PropertyContainer, PropertyContainer)
+ */
+ public static String substVars(String val, PropertyContainer pc1) {
+ return substVars(val, pc1, null);
+ }
- /**
- * Find the value corresponding to <code>key</code> in <code>props</code>.
- * Then perform variable substitution on the found value.
- */
- // public static String findAndSubst(String key, Properties props) {
- // String value = props.getProperty(key);
- //
- // if (value == null) {
- // return null;
- // }
- //
- // try {
- // return substVars(value, props);
- // } catch (IllegalArgumentException e) {
- // return value;
- // }
- // }
- final static String DELIM_START = "${";
- final static char DELIM_STOP = '}';
- final static String DELIM_DEFAULT = ":-";
-
- final static int DELIM_START_LEN = 2;
- final static int DELIM_STOP_LEN = 1;
- final static int DELIM_DEFAULT_LEN = 2;
-
- final static String _IS_UNDEFINED = "_IS_UNDEFINED";
-
- /**
- * @see #substVars(String, PropertyContainer, PropertyContainer)
- */
- public static String substVars(String val, PropertyContainer pc1) {
- return substVars(val, pc1, null);
+ /**
+ * See http://logback.qos.ch/manual/configuration.html#variableSubstitution
+ */
+ public static String substVars(String input, PropertyContainer pc0, PropertyContainer pc1) {
+ try {
+ return NodeToStringTransformer.substituteVariable(input, pc0, pc1);
+ } catch (ScanException e) {
+ throw new IllegalArgumentException("Failed to parse input [" + input + "]", e);
}
+ }
- /**
- * See http://logback.qos.ch/manual/configuration.html#variableSubstitution
- */
- public static String substVars(String input, PropertyContainer pc0, PropertyContainer pc1) {
- try {
- return NodeToStringTransformer.substituteVariable(input, pc0, pc1);
- } catch (ScanException e) {
- throw new IllegalArgumentException("Failed to parse input [" + input + "]", e);
- }
+ public static String propertyLookup(String key, PropertyContainer pc1,
+ PropertyContainer pc2) {
+ String value = null;
+ // first try the props passed as parameter
+ value = pc1.getProperty(key);
+
+ // then try the pc2
+ if (value == null && pc2 != null) {
+ value = pc2.getProperty(key);
+ }
+ // then try in System properties
+ if (value == null) {
+ value = getSystemProperty(key, null);
+ }
+ if (value == null) {
+ value = getEnv(key);
}
+ return value;
+ }
- public static String propertyLookup(String key, PropertyContainer pc1, PropertyContainer pc2) {
- String value = null;
- // first try the props passed as parameter
- value = pc1.getProperty(key);
-
- // then try the pc2
- if (value == null && pc2 != null) {
- value = pc2.getProperty(key);
- }
- // then try in System properties
- if (value == null) {
- value = getSystemProperty(key, null);
- }
- if (value == null) {
- value = getEnv(key);
- }
- return value;
+ /**
+ * Very similar to <code>System.getProperty</code> except that the
+ * {@link SecurityException} is absorbed.
+ *
+ * @param key The key to search for.
+ * @param def The default value to return.
+ * @return the string value of the system property, or the default value if
+ * there is no property with that key.
+ */
+ public static String getSystemProperty(String key, String def) {
+ try {
+ return System.getProperty(key, def);
+ } catch (SecurityException e) {
+ return def;
}
+ }
- /**
- * Very similar to <code>System.getProperty</code> except that the
- * {@link SecurityException} is absorbed.
- *
- * @param key The key to search for.
- * @param def The default value to return.
- * @return the string value of the system property, or the default value if
- * there is no property with that key.
- */
- public static String getSystemProperty(String key, String def) {
- try {
- return System.getProperty(key, def);
- } catch (SecurityException e) {
- return def;
- }
+ /**
+ * Lookup a key from the environment.
+ *
+ * @param key
+ * @return value corresponding to key from the OS environment
+ */
+ public static String getEnv(String key) {
+ try {
+ return System.getenv(key);
+ } catch (SecurityException e) {
+ return null;
}
+ }
- /**
- * Lookup a key from the environment.
- *
- * @param key
- * @return value corresponding to key from the OS environment
- */
- public static String getEnv(String key) {
- try {
- return System.getenv(key);
- } catch (SecurityException e) {
- return null;
- }
+
+ /**
+ * Very similar to <code>System.getProperty</code> except that the
+ * {@link SecurityException} is absorbed.
+ *
+ * @param key The key to search for.
+ * @return the string value of the system property.
+ */
+ public static String getSystemProperty(String key) {
+ try {
+ return System.getProperty(key);
+ } catch (SecurityException e) {
+ return null;
}
+ }
- /**
- * Very similar to <code>System.getProperty</code> except that the
- * {@link SecurityException} is absorbed.
- *
- * @param key The key to search for.
- * @return the string value of the system property.
- */
- public static String getSystemProperty(String key) {
- try {
- return System.getProperty(key);
- } catch (SecurityException e) {
- return null;
- }
+ public static void setSystemProperties(ContextAware contextAware, Properties props) {
+ for (Object o : props.keySet()) {
+ String key = (String) o;
+ String value = props.getProperty(key);
+ setSystemProperty(contextAware, key, value);
}
+ }
- public static void setSystemProperties(ContextAware contextAware, Properties props) {
- for (Object o : props.keySet()) {
- String key = (String) o;
- String value = props.getProperty(key);
- setSystemProperty(contextAware, key, value);
- }
+ public static void setSystemProperty(ContextAware contextAware, String key, String value) {
+ try {
+ System.setProperty(key, value);
+ } catch (SecurityException e) {
+ contextAware.addError("Failed to set system property [" + key + "]", e);
}
+ }
- public static void setSystemProperty(ContextAware contextAware, String key, String value) {
- try {
- System.setProperty(key, value);
- } catch (SecurityException e) {
- contextAware.addError("Failed to set system property [" + key + "]", e);
- }
+ /**
+ * Very similar to {@link System#getProperties()} except that the
+ * {@link SecurityException} is absorbed.
+ *
+ * @return the system properties
+ */
+ public static Properties getSystemProperties() {
+ try {
+ return System.getProperties();
+ } catch (SecurityException e) {
+ return new Properties();
}
+ }
+
+ /**
+ * Return a String[] of size two. The first item containing the key part and the second item
+ * containing a default value specified by the user. The second item will be null if no default value
+ * is specified.
+ *
+ * @param key
+ * @return
+ */
+ static public String[] extractDefaultReplacement(String key) {
+ String[] result = new String[2];
+ if(key == null)
+ return result;
- /**
- * Very similar to {@link System#getProperties()} except that the
- * {@link SecurityException} is absorbed.
- *
- * @return the system properties
- */
- public static Properties getSystemProperties() {
- try {
- return System.getProperties();
- } catch (SecurityException e) {
- return new Properties();
- }
+ result[0] = key;
+ int d = key.indexOf(DELIM_DEFAULT);
+ if (d != -1) {
+ result[0] = key.substring(0, d);
+ result[1] = key.substring(d + DELIM_DEFAULT_LEN);
}
+ return result;
+ }
- /**
- * Return a String[] of size two. The first item containing the key part and the second item
- * containing a default value specified by the user. The second item will be null if no default value
- * is specified.
- *
- * @param key
- * @return
- */
- static public String[] extractDefaultReplacement(String key) {
- String[] result = new String[2];
- if (key == null)
- return result;
-
- result[0] = key;
- int d = key.indexOf(DELIM_DEFAULT);
- if (d != -1) {
- result[0] = key.substring(0, d);
- result[1] = key.substring(d + DELIM_DEFAULT_LEN);
- }
- return result;
+ /**
+ * If <code>value</code> is "true", then <code>true</code> is returned. If
+ * <code>value</code> is "false", then <code>true</code> is returned.
+ * Otherwise, <code>default</code> is returned.
+ * <p/>
+ * <p> Case of value is unimportant.
+ */
+ public static boolean toBoolean(String value, boolean dEfault) {
+ if (value == null) {
+ return dEfault;
}
- /**
- * If <code>value</code> is "true", then <code>true</code> is returned. If
- * <code>value</code> is "false", then <code>true</code> is returned.
- * Otherwise, <code>default</code> is returned.
- * <p/>
- * <p> Case of value is unimportant.
- */
- public static boolean toBoolean(String value, boolean dEfault) {
- if (value == null) {
- return dEfault;
- }
-
- String trimmedVal = value.trim();
-
- if ("true".equalsIgnoreCase(trimmedVal)) {
- return true;
- }
-
- if ("false".equalsIgnoreCase(trimmedVal)) {
- return false;
- }
-
- return dEfault;
+ String trimmedVal = value.trim();
+
+ if ("true".equalsIgnoreCase(trimmedVal)) {
+ return true;
}
- public static boolean isEmpty(String str) {
- return ((str == null) || CoreConstants.EMPTY_STRING.equals(str));
+ if ("false".equalsIgnoreCase(trimmedVal)) {
+ return false;
}
+ return dEfault;
+ }
+
+ public static boolean isEmpty(String str) {
+ return ((str == null) || CoreConstants.EMPTY_STRING.equals(str));
+ }
+
+
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetterException.java b/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetterException.java
index 0857edd..ddc57ae 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetterException.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetterException.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,17 +21,17 @@ package ch.qos.logback.core.util;
*/
public class PropertySetterException extends Exception {
- private static final long serialVersionUID = -2771077768281663949L;
+ private static final long serialVersionUID = -2771077768281663949L;
- public PropertySetterException(String msg) {
- super(msg);
- }
+ public PropertySetterException(String msg) {
+ super(msg);
+ }
- public PropertySetterException(Throwable rootCause) {
- super(rootCause);
- }
+ public PropertySetterException(Throwable rootCause) {
+ super(rootCause);
+ }
- public PropertySetterException(String message, Throwable cause) {
- super(message, cause);
- }
+ public PropertySetterException(String message, Throwable cause) {
+ super(message, cause);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/StatusListenerConfigHelper.java b/logback-core/src/main/java/ch/qos/logback/core/util/StatusListenerConfigHelper.java
deleted file mode 100644
index 5055ddc..0000000
--- a/logback-core/src/main/java/ch/qos/logback/core/util/StatusListenerConfigHelper.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.util;
-
-import ch.qos.logback.core.Context;
-import ch.qos.logback.core.CoreConstants;
-import ch.qos.logback.core.spi.ContextAware;
-import ch.qos.logback.core.spi.LifeCycle;
-import ch.qos.logback.core.status.OnConsoleStatusListener;
-import ch.qos.logback.core.status.StatusListener;
-
-public class StatusListenerConfigHelper {
-
- public static void installIfAsked(Context context) {
- String slClass = OptionHelper.getSystemProperty(CoreConstants.STATUS_LISTENER_CLASS);
- if (!OptionHelper.isEmpty(slClass)) {
- addStatusListener(context, slClass);
- }
- }
-
- private static void addStatusListener(Context context, String listenerClassName) {
- StatusListener listener = null;
- if (CoreConstants.SYSOUT.equalsIgnoreCase(listenerClassName)) {
- listener = new OnConsoleStatusListener();
- } else {
- listener = createListenerPerClassName(context, listenerClassName);
- }
- initAndAddListener(context, listener);
- }
-
- private static void initAndAddListener(Context context, StatusListener listener) {
- if (listener != null) {
- if (listener instanceof ContextAware) // LOGBACK-767
- ((ContextAware) listener).setContext(context);
-
- boolean effectivelyAdded = context.getStatusManager().add(listener);
- effectivelyAdded = true;
- if (effectivelyAdded && (listener instanceof LifeCycle)) {
- ((LifeCycle) listener).start(); // LOGBACK-767
- }
- }
- }
-
- private static StatusListener createListenerPerClassName(Context context, String listenerClass) {
- try {
- return (StatusListener) OptionHelper.instantiateByClassName(listenerClass, StatusListener.class, context);
- } catch (Exception e) {
- // printing on the console is the best we can do
- e.printStackTrace();
- return null;
- }
- }
-
- /**
- * This utility method adds a new OnConsoleStatusListener to the context
- * passed as parameter.
- *
- * @param context
- * @since 1.0.1
- */
- static public void addOnConsoleListenerInstance(Context context, OnConsoleStatusListener onConsoleStatusListener) {
- onConsoleStatusListener.setContext(context);
- boolean effectivelyAdded = context.getStatusManager().add(onConsoleStatusListener);
- if (effectivelyAdded) {
- onConsoleStatusListener.start();
- }
- }
-}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java b/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java
index 91c441b..6fdce15 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/StatusPrinter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,163 +26,170 @@ import static ch.qos.logback.core.status.StatusUtil.filterStatusListByTimeThresh
public class StatusPrinter {
- private static PrintStream ps = System.out;
-
- static CachingDateFormatter cachingDateFormat = new CachingDateFormatter("HH:mm:ss,SSS");
-
- public static void setPrintStream(PrintStream printStream) {
- ps = printStream;
+ private static PrintStream ps = System.out;
+
+ static CachingDateFormatter cachingDateFormat = new CachingDateFormatter(
+ "HH:mm:ss,SSS");
+
+ public static void setPrintStream(PrintStream printStream) {
+ ps = printStream;
+ }
+
+ /**
+ * Print the contents of the context statuses, but only if they contain
+ * warnings or errors.
+ *
+ * @param context
+ */
+ public static void printInCaseOfErrorsOrWarnings(Context context) {
+ printInCaseOfErrorsOrWarnings(context, 0);
+ }
+
+ /**
+ * Print the contents of the context status, but only if they contain
+ * warnings or errors occurring later then the threshold.
+ *
+ * @param context
+ */
+ public static void printInCaseOfErrorsOrWarnings(Context context, long threshold) {
+ if (context == null) {
+ throw new IllegalArgumentException("Context argument cannot be null");
}
- /**
- * Print the contents of the context statuses, but only if they contain
- * warnings or errors.
- *
- * @param context
- */
- public static void printInCaseOfErrorsOrWarnings(Context context) {
- printInCaseOfErrorsOrWarnings(context, 0);
+ StatusManager sm = context.getStatusManager();
+ if (sm == null) {
+ ps.println("WARN: Context named \"" + context.getName()
+ + "\" has no status manager");
+ } else {
+ StatusUtil statusUtil = new StatusUtil(context);
+ if (statusUtil.getHighestLevel(threshold) >= ErrorStatus.WARN) {
+ print(sm, threshold);
+ }
}
-
- /**
- * Print the contents of the context status, but only if they contain
- * warnings or errors occurring later then the threshold.
- *
- * @param context
- */
- public static void printInCaseOfErrorsOrWarnings(Context context, long threshold) {
- if (context == null) {
- throw new IllegalArgumentException("Context argument cannot be null");
- }
-
- StatusManager sm = context.getStatusManager();
- if (sm == null) {
- ps.println("WARN: Context named \"" + context.getName() + "\" has no status manager");
- } else {
- StatusUtil statusUtil = new StatusUtil(context);
- if (statusUtil.getHighestLevel(threshold) >= ErrorStatus.WARN) {
- print(sm, threshold);
- }
- }
+ }
+
+ /**
+ * Print the contents of the context statuses, but only if they contain
+ * errors.
+ *
+ * @param context
+ */
+ public static void printIfErrorsOccured(Context context) {
+ if (context == null) {
+ throw new IllegalArgumentException("Context argument cannot be null");
}
- /**
- * Print the contents of the context statuses, but only if they contain
- * errors.
- *
- * @param context
- */
- public static void printIfErrorsOccured(Context context) {
- if (context == null) {
- throw new IllegalArgumentException("Context argument cannot be null");
- }
-
- StatusManager sm = context.getStatusManager();
- if (sm == null) {
- ps.println("WARN: Context named \"" + context.getName() + "\" has no status manager");
- } else {
- StatusUtil statusUtil = new StatusUtil(context);
- if (statusUtil.getHighestLevel(0) == ErrorStatus.ERROR) {
- print(sm);
- }
- }
+ StatusManager sm = context.getStatusManager();
+ if (sm == null) {
+ ps.println("WARN: Context named \"" + context.getName()
+ + "\" has no status manager");
+ } else {
+ StatusUtil statusUtil = new StatusUtil(context);
+ if (statusUtil.getHighestLevel(0) == ErrorStatus.ERROR) {
+ print(sm);
+ }
}
-
- /**
- * Print the contents of the context's status data.
- *
- * @param context
- */
- public static void print(Context context) {
- print(context, 0);
+ }
+
+ /**
+ * Print the contents of the context's status data.
+ *
+ * @param context
+ */
+ public static void print(Context context) {
+ print(context, 0);
+ }
+
+ /**
+ * Print context's status data with a timestamp higher than the threshold.
+ * @param context
+ */
+ public static void print(Context context, long threshold) {
+ if (context == null) {
+ throw new IllegalArgumentException("Context argument cannot be null");
+ }
+
+ StatusManager sm = context.getStatusManager();
+ if (sm == null) {
+ ps.println("WARN: Context named \"" + context.getName()
+ + "\" has no status manager");
+ } else {
+ print(sm, threshold);
+ }
+ }
+
+ public static void print(StatusManager sm) {
+ print(sm, 0);
+ }
+
+ public static void print(StatusManager sm, long threshold) {
+ StringBuilder sb = new StringBuilder();
+ List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
+ buildStrFromStatusList(sb, filteredList);
+ ps.println(sb.toString());
+ }
+
+
+ public static void print(List<Status> statusList) {
+ StringBuilder sb = new StringBuilder();
+ buildStrFromStatusList(sb, statusList);
+ ps.println(sb.toString());
+ }
+
+
+ private static void buildStrFromStatusList(StringBuilder sb, List<Status> statusList) {
+ if(statusList == null)
+ return;
+ for(Status s : statusList) {
+ buildStr(sb, "", s);
}
-
- /**
- * Print context's status data with a timestamp higher than the threshold.
- * @param context
- */
- public static void print(Context context, long threshold) {
- if (context == null) {
- throw new IllegalArgumentException("Context argument cannot be null");
- }
-
- StatusManager sm = context.getStatusManager();
- if (sm == null) {
- ps.println("WARN: Context named \"" + context.getName() + "\" has no status manager");
- } else {
- print(sm, threshold);
- }
+ }
+
+// private static void buildStrFromStatusManager(StringBuilder sb, StatusManager sm) {
+// }
+
+
+ private static void appendThrowable(StringBuilder sb, Throwable t) {
+ String[] stringRep = ThrowableToStringArray.convert(t);
+
+ for (String s : stringRep) {
+ if (s.startsWith(CoreConstants.CAUSED_BY)) {
+ // nothing
+ } else if (Character.isDigit(s.charAt(0))) {
+ // if line resembles "48 common frames omitted"
+ sb.append("\t... ");
+ } else {
+ // most of the time. just add a tab+"at"
+ sb.append("\tat ");
+ }
+ sb.append(s).append(CoreConstants.LINE_SEPARATOR);
}
-
- public static void print(StatusManager sm) {
- print(sm, 0);
+ }
+
+ public static void buildStr(StringBuilder sb, String indentation, Status s) {
+ String prefix;
+ if (s.hasChildren()) {
+ prefix = indentation + "+ ";
+ } else {
+ prefix = indentation + "|-";
}
- public static void print(StatusManager sm, long threshold) {
- StringBuilder sb = new StringBuilder();
- List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
- buildStrFromStatusList(sb, filteredList);
- ps.println(sb.toString());
+ if (cachingDateFormat != null) {
+ String dateStr = cachingDateFormat.format(s.getDate());
+ sb.append(dateStr).append(" ");
}
+ sb.append(prefix).append(s).append(CoreConstants.LINE_SEPARATOR);
- public static void print(List<Status> statusList) {
- StringBuilder sb = new StringBuilder();
- buildStrFromStatusList(sb, statusList);
- ps.println(sb.toString());
+ if (s.getThrowable() != null) {
+ appendThrowable(sb, s.getThrowable());
}
-
- private static void buildStrFromStatusList(StringBuilder sb, List<Status> statusList) {
- if (statusList == null)
- return;
- for (Status s : statusList) {
- buildStr(sb, "", s);
- }
- }
-
- // private static void buildStrFromStatusManager(StringBuilder sb, StatusManager sm) {
- // }
-
- private static void appendThrowable(StringBuilder sb, Throwable t) {
- String[] stringRep = ThrowableToStringArray.convert(t);
-
- for (String s : stringRep) {
- if (s.startsWith(CoreConstants.CAUSED_BY)) {
- // nothing
- } else if (Character.isDigit(s.charAt(0))) {
- // if line resembles "48 common frames omitted"
- sb.append("\t... ");
- } else {
- // most of the time. just add a tab+"at"
- sb.append("\tat ");
- }
- sb.append(s).append(CoreConstants.LINE_SEPARATOR);
- }
- }
-
- public static void buildStr(StringBuilder sb, String indentation, Status s) {
- String prefix;
- if (s.hasChildren()) {
- prefix = indentation + "+ ";
- } else {
- prefix = indentation + "|-";
- }
-
- if (cachingDateFormat != null) {
- String dateStr = cachingDateFormat.format(s.getDate());
- sb.append(dateStr).append(" ");
- }
- sb.append(prefix).append(s).append(CoreConstants.LINE_SEPARATOR);
-
- if (s.getThrowable() != null) {
- appendThrowable(sb, s.getThrowable());
- }
- if (s.hasChildren()) {
- Iterator<Status> ite = s.iterator();
- while (ite.hasNext()) {
- Status child = ite.next();
- buildStr(sb, indentation + " ", child);
- }
- }
+ if (s.hasChildren()) {
+ Iterator<Status> ite = s.iterator();
+ while (ite.hasNext()) {
+ Status child = ite.next();
+ buildStr(sb, indentation + " ", child);
+ }
}
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/StringCollectionUtil.java b/logback-core/src/main/java/ch/qos/logback/core/util/StringCollectionUtil.java
index d13792a..524de77 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/StringCollectionUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/StringCollectionUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,84 +26,87 @@ import java.util.regex.Pattern;
*/
public class StringCollectionUtil {
- /**
- * Retains all values in the subject collection that are matched by
- * at least one of a collection of regular expressions.
- * <p>
- * This method is a convenience overload for
- * {@link #retainMatching(Collection, Collection)}.
- *
- * @param values subject value collection
- * @param patterns patterns to match
- */
- @SuppressWarnings("unchecked")
- public static void retainMatching(Collection<String> values, String... patterns) {
- retainMatching(values, Arrays.asList(patterns));
- }
+ /**
+ * Retains all values in the subject collection that are matched by
+ * at least one of a collection of regular expressions.
+ * <p>
+ * This method is a convenience overload for
+ * {@link #retainMatching(Collection, Collection)}.
+ *
+ * @param values subject value collection
+ * @param patterns patterns to match
+ */
+ @SuppressWarnings("unchecked")
+ public static void retainMatching(Collection<String> values,
+ String... patterns) {
+ retainMatching(values, Arrays.asList(patterns));
+ }
- /**
- * Retains all values in the subject collection that are matched by
- * at least one of a collection of regular expressions.
- * <p>
- * The semantics of this method are conceptually similar to
- * {@link Collection#retainAll(Collection)}, but uses pattern matching
- * instead of exact matching.
- *
- * @param values subject value collection
- * @param patterns patterns to match
- */
- public static void retainMatching(Collection<String> values, Collection<String> patterns) {
- if (patterns.isEmpty())
- return;
- List<String> matches = new ArrayList<String>(values.size());
- for (String p : patterns) {
- Pattern pattern = Pattern.compile(p);
- for (String value : values) {
- if (pattern.matcher(value).matches()) {
- matches.add(value);
- }
- }
+ /**
+ * Retains all values in the subject collection that are matched by
+ * at least one of a collection of regular expressions.
+ * <p>
+ * The semantics of this method are conceptually similar to
+ * {@link Collection#retainAll(Collection)}, but uses pattern matching
+ * instead of exact matching.
+ *
+ * @param values subject value collection
+ * @param patterns patterns to match
+ */
+ public static void retainMatching(Collection<String> values,
+ Collection<String> patterns) {
+ if (patterns.isEmpty()) return;
+ List<String> matches = new ArrayList<String>(values.size());
+ for (String p : patterns) {
+ Pattern pattern = Pattern.compile(p);
+ for (String value : values) {
+ if (pattern.matcher(value).matches()) {
+ matches.add(value);
}
- values.retainAll(matches);
- }
-
- /**
- * Removes all values in the subject collection that are matched by
- * at least one of a collection of regular expressions.
- * <p>
- * This method is a convenience overload for
- * {@link #removeMatching(Collection, Collection)}.
- *
- * @param values subject value collection
- * @param patterns patterns to match
- */
- @SuppressWarnings("unchecked")
- public static void removeMatching(Collection<String> values, String... patterns) {
- removeMatching(values, Arrays.asList(patterns));
+ }
}
+ values.retainAll(matches);
+ }
+
+ /**
+ * Removes all values in the subject collection that are matched by
+ * at least one of a collection of regular expressions.
+ * <p>
+ * This method is a convenience overload for
+ * {@link #removeMatching(Collection, Collection)}.
+ *
+ * @param values subject value collection
+ * @param patterns patterns to match
+ */
+ @SuppressWarnings("unchecked")
+ public static void removeMatching(Collection<String> values,
+ String... patterns) {
+ removeMatching(values, Arrays.asList(patterns));
+ }
- /**
- * Removes all values in the subject collection that are matched by
- * at least one of a collection of regular expressions.
- * <p>
- * The semantics of this method are conceptually similar to
- * {@link Collection#removeAll(Collection)}, but uses pattern matching
- * instead of exact matching.
- *
- * @param values subject value collection
- * @param patterns patterns to match
- */
- public static void removeMatching(Collection<String> values, Collection<String> patterns) {
- List<String> matches = new ArrayList<String>(values.size());
- for (String p : patterns) {
- Pattern pattern = Pattern.compile(p);
- for (String value : values) {
- if (pattern.matcher(value).matches()) {
- matches.add(value);
- }
- }
+ /**
+ * Removes all values in the subject collection that are matched by
+ * at least one of a collection of regular expressions.
+ * <p>
+ * The semantics of this method are conceptually similar to
+ * {@link Collection#removeAll(Collection)}, but uses pattern matching
+ * instead of exact matching.
+ *
+ * @param values subject value collection
+ * @param patterns patterns to match
+ */
+ public static void removeMatching(Collection<String> values,
+ Collection<String> patterns) {
+ List<String> matches = new ArrayList<String>(values.size());
+ for (String p : patterns) {
+ Pattern pattern = Pattern.compile(p);
+ for (String value : values) {
+ if (pattern.matcher(value).matches()) {
+ matches.add(value);
}
- values.removeAll(matches);
+ }
}
+ values.removeAll(matches);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/SystemInfo.java b/logback-core/src/main/java/ch/qos/logback/core/util/SystemInfo.java
index b980203..a53a0b8 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/SystemInfo.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/SystemInfo.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,10 +13,12 @@
*/
package ch.qos.logback.core.util;
-public class SystemInfo {
- public static String getJavaVendor() {
- return OptionHelper.getSystemProperty("java.vendor", null);
- }
+
+public class SystemInfo {
+
+ public static String getJavaVendor() {
+ return OptionHelper.getSystemProperty("java.vendor", null);
+ }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/TimeUtil.java b/logback-core/src/main/java/ch/qos/logback/core/util/TimeUtil.java
index f203ad5..f9890ff 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/TimeUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/TimeUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,69 +18,72 @@ import java.util.Date;
public class TimeUtil {
- public static long computeStartOfNextSecond(long now) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date(now));
- cal.set(Calendar.MILLISECOND, 0);
- cal.add(Calendar.SECOND, 1);
- return cal.getTime().getTime();
- }
+
+ public static long computeStartOfNextSecond(long now) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(new Date(now));
+ cal.set(Calendar.MILLISECOND, 0);
+ cal.add(Calendar.SECOND, 1);
+ return cal.getTime().getTime();
+ }
- public static long computeStartOfNextMinute(long now) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date(now));
- cal.set(Calendar.MILLISECOND, 0);
- cal.set(Calendar.SECOND, 0);
- cal.add(Calendar.MINUTE, 1);
- return cal.getTime().getTime();
- }
+ public static long computeStartOfNextMinute(long now) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(new Date(now));
+ cal.set(Calendar.MILLISECOND, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.add(Calendar.MINUTE, 1);
+ return cal.getTime().getTime();
+ }
- public static long computeStartOfNextHour(long now) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date(now));
- cal.set(Calendar.MILLISECOND, 0);
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MINUTE, 0);
- cal.add(Calendar.HOUR, 1);
- return cal.getTime().getTime();
- }
+ public static long computeStartOfNextHour(long now) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(new Date(now));
+ cal.set(Calendar.MILLISECOND, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.add(Calendar.HOUR, 1);
+ return cal.getTime().getTime();
+ }
+
+ public static long computeStartOfNextDay(long now) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(new Date(now));
- public static long computeStartOfNextDay(long now) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date(now));
+ cal.add(Calendar.DAY_OF_MONTH, 1);
+ cal.set(Calendar.MILLISECOND, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ return cal.getTime().getTime();
+ }
+
+ public static long computeStartOfNextWeek(long now) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(new Date(now));
+
+ cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+ cal.add(Calendar.WEEK_OF_YEAR, 1);
+ return cal.getTime().getTime();
+ }
- cal.add(Calendar.DAY_OF_MONTH, 1);
- cal.set(Calendar.MILLISECOND, 0);
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.HOUR_OF_DAY, 0);
- return cal.getTime().getTime();
- }
+ public static long computeStartOfNextMonth(long now) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(new Date(now));
- public static long computeStartOfNextWeek(long now) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date(now));
-
- cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
- cal.set(Calendar.HOUR_OF_DAY, 0);
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MILLISECOND, 0);
- cal.add(Calendar.WEEK_OF_YEAR, 1);
- return cal.getTime().getTime();
- }
-
- public static long computeStartOfNextMonth(long now) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date(now));
-
- cal.set(Calendar.DATE, 1);
- cal.set(Calendar.HOUR_OF_DAY, 0);
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MILLISECOND, 0);
- cal.add(Calendar.MONTH, 1);
- return cal.getTime().getTime();
- }
+ cal.set(Calendar.DATE, 1);
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+ cal.add(Calendar.MONTH, 1);
+ return cal.getTime().getTime();
+ }
+
+
}
diff --git a/logback-core/src/test/input/.gitignore b/logback-core/src/test/input/.gitignore
new file mode 100644
index 0000000..4097700
--- /dev/null
+++ b/logback-core/src/test/input/.gitignore
@@ -0,0 +1 @@
+compress?.txt
diff --git a/logback-core/src/test/input/compress2.txt b/logback-core/src/test/input/compress2.txt
new file mode 100644
index 0000000..8b206a4
--- /dev/null
+++ b/logback-core/src/test/input/compress2.txt
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<document>
+
+ <properties>
+ <title>LOGBack Home</title>
+ </properties>
+
+
+<body>
+
+ <h1>LOGBack project</h1>
+
+ <p>LOGBack is intended as a successor to the popular log4j
+ project. It was also designed by Ceki Gülcü, the founder
+ of the log4j project. It builds upon exerience gained in building
+ industrial-strength logging systems going back as far as 1999.
+ </p>
+
+ <p>LOGBack's basic architecture is sufficiently generic so as to
+ apply under different circumstances. At present time, LOGBack is
+ divided into three modules, Core, Classic and Access.
+ </p>
+
+ <p>The Core module lays the groundwork for the other two
+ modules. The Classic module can be assimilated to an improved
+ version of log4j. The Access module integrates with Servlet
+ containers to provide HTPP-access log functionality. Note that you
+ can easily build your own modules on top of the Core module.
+ </p>
+
+
+</body>
+</document>
+
diff --git a/logback-core/src/test/input/compress3.txt b/logback-core/src/test/input/compress3.txt
deleted file mode 100644
index d627e48..0000000
--- a/logback-core/src/test/input/compress3.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-
- LOGBack: the generic, reliable, fast and flexible logging framework.
-
- Copyright (C) 1999-2006, QOS.ch
-
- This library is free software, you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License as published by the Free
- Software Foundation.
-<?xml version="1.0"?>
-<document>
-
- <properties>
- <title>LOGBack Home</title>
- </properties>
-
-
-<body>
-
- <h1>LOGBack project</h1>
-
- <p>LOGBack is intended as a successor to the popular log4j
- project. It was also designed by Ceki Gülcü, the founder
- of the log4j project. It builds upon exerience gained in building
- industrial-strength logging systems going back as far as 1999.
- </p>
-
- <p>LOGBack's basic architecture is sufficiently generic so as to
- apply under different circumstances. At present time, LOGBack is
- divided into three modules, Core, Classic and Access.
- </p>
-
- <p>The Core module lays the groundwork for the other two
- modules. The Classic module can be assimilated to an improved
- version of log4j. The Access module integrates with Servlet
- containers to provide HTPP-access log functionality. Note that you
- can easily build your own modules on top of the Core module.
- </p>
-
-
-</body>
-</document>
-
diff --git a/logback-core/src/test/java/ch/qos/logback/core/AllCoreTest.java b/logback-core/src/test/java/ch/qos/logback/core/AllCoreTest.java
index 8948f08..fef936a 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/AllCoreTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/AllCoreTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,10 +18,20 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ BasicStatusManagerTest.class, ch.qos.logback.core.status.PackageTest.class, ch.qos.logback.core.util.PackageTest.class,
- ch.qos.logback.core.helpers.PackageTest.class, ch.qos.logback.core.subst.PackageTest.class, ch.qos.logback.core.pattern.PackageTest.class,
- ch.qos.logback.core.PackageTest.class, ch.qos.logback.core.joran.PackageTest.class, ch.qos.logback.core.appender.PackageTest.class,
- ch.qos.logback.core.spi.PackageTest.class, ch.qos.logback.core.rolling.PackageTest.class, ch.qos.logback.core.net.PackageTest.class,
- ch.qos.logback.core.sift.PackageTest.class, ch.qos.logback.core.encoder.PackageTest.class, ch.qos.logback.core.recovery.PackageTest.class })
+ at SuiteClasses({BasicStatusManagerTest.class,
+ ch.qos.logback.core.status.PackageTest.class,
+ ch.qos.logback.core.util.PackageTest.class,
+ ch.qos.logback.core.helpers.PackageTest.class,
+ ch.qos.logback.core.subst.PackageTest.class,
+ ch.qos.logback.core.pattern.PackageTest.class,
+ ch.qos.logback.core.PackageTest.class,
+ ch.qos.logback.core.joran.PackageTest.class,
+ ch.qos.logback.core.appender.PackageTest.class,
+ ch.qos.logback.core.spi.PackageTest.class,
+ ch.qos.logback.core.rolling.PackageTest.class,
+ ch.qos.logback.core.net.PackageTest.class,
+ ch.qos.logback.core.sift.PackageTest.class,
+ ch.qos.logback.core.encoder.PackageTest.class,
+ ch.qos.logback.core.recovery.PackageTest.class})
public class AllCoreTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/AsyncAppenderBaseTest.java b/logback-core/src/test/java/ch/qos/logback/core/AsyncAppenderBaseTest.java
index 1b7ac7d..ca757cb 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/AsyncAppenderBaseTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/AsyncAppenderBaseTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,19 +13,18 @@
*/
package ch.qos.logback.core;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Before;
-import org.junit.Test;
-
import ch.qos.logback.core.helpers.NOPAppender;
import ch.qos.logback.core.read.ListAppender;
+import ch.qos.logback.core.testUtil.DelayingListAppender;
import ch.qos.logback.core.status.OnConsoleStatusListener;
import ch.qos.logback.core.status.StatusChecker;
-import ch.qos.logback.core.testUtil.DelayingListAppender;
import ch.qos.logback.core.testUtil.NPEAppender;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
/**
* @author Ceki Gülcü
@@ -33,250 +32,144 @@ import ch.qos.logback.core.testUtil.NPEAppender;
*/
public class AsyncAppenderBaseTest {
- Context context = new ContextBase();
- AsyncAppenderBase<Integer> asyncAppenderBase = new AsyncAppenderBase<Integer>();
- LossyAsyncAppender lossyAsyncAppender = new LossyAsyncAppender();
- DelayingListAppender<Integer> delayingListAppender = new DelayingListAppender<Integer>();
- ListAppender<Integer> listAppender = new ListAppender<Integer>();
- OnConsoleStatusListener onConsoleStatusListener = new OnConsoleStatusListener();
- StatusChecker statusChecker = new StatusChecker(context);
-
- @Before
- public void setUp() {
- onConsoleStatusListener.setContext(context);
- context.getStatusManager().add(onConsoleStatusListener);
- onConsoleStatusListener.start();
-
- asyncAppenderBase.setContext(context);
- lossyAsyncAppender.setContext(context);
-
- listAppender.setContext(context);
- listAppender.setName("list");
- listAppender.start();
-
- delayingListAppender.setContext(context);
- delayingListAppender.setName("list");
- delayingListAppender.start();
- }
-
- @Test(timeout = 2000)
- public void smoke() {
- asyncAppenderBase.addAppender(listAppender);
- asyncAppenderBase.start();
- asyncAppenderBase.doAppend(0);
- asyncAppenderBase.stop();
- verify(listAppender, 1);
- }
-
- @Test
- public void exceptionsShouldNotCauseHalting() throws InterruptedException {
- NPEAppender<Integer> npeAppender = new NPEAppender<Integer>();
- npeAppender.setName("bad");
- npeAppender.setContext(context);
- npeAppender.start();
-
- asyncAppenderBase.addAppender(npeAppender);
- asyncAppenderBase.start();
- assertTrue(asyncAppenderBase.isStarted());
- for (int i = 0; i < 10; i++)
- asyncAppenderBase.append(i);
-
- asyncAppenderBase.stop();
- assertFalse(asyncAppenderBase.isStarted());
- assertEquals(AppenderBase.ALLOWED_REPEATS, statusChecker.matchCount("Appender \\[bad\\] failed to append."));
- }
-
- @Test(timeout = 2000)
- public void emptyQueueShouldBeStoppable() {
- asyncAppenderBase.addAppender(listAppender);
- asyncAppenderBase.start();
- asyncAppenderBase.stop();
- verify(listAppender, 0);
- }
-
- @Test(timeout = 2000)
- public void workerShouldStopEvenIfInterruptExceptionConsumedWithinSubappender() {
- delayingListAppender.delay = 100;
- asyncAppenderBase.addAppender(delayingListAppender);
- asyncAppenderBase.start();
- asyncAppenderBase.doAppend(0);
- asyncAppenderBase.stop();
- verify(delayingListAppender, 1);
- assertTrue(delayingListAppender.interrupted);
- }
-
- @Test(timeout = 2000)
- public void noEventLoss() {
- int bufferSize = 10;
- int loopLen = bufferSize * 2;
- asyncAppenderBase.addAppender(delayingListAppender);
- asyncAppenderBase.setQueueSize(bufferSize);
- asyncAppenderBase.start();
- for (int i = 0; i < loopLen; i++) {
- asyncAppenderBase.doAppend(i);
- }
- asyncAppenderBase.stop();
- verify(delayingListAppender, loopLen);
- }
- @Test(timeout = 2000)
- public void eventLossIfNeverBlock() {
- int bufferSize = 10;
- int loopLen = bufferSize * 200;
- delayingListAppender.setDelay(5); // (loopLen*delay) much bigger than test timeout
- asyncAppenderBase.addAppender(delayingListAppender);
- asyncAppenderBase.setQueueSize(bufferSize);
- asyncAppenderBase.setNeverBlock(true);
- asyncAppenderBase.start();
- for (int i = 0; i < loopLen; i++) {
- asyncAppenderBase.doAppend(i);
- }
- asyncAppenderBase.stop();
- // ListAppender size isn't a reliable test here, so just make sure we didn't
- // have any errors, and that we could complete the test in time.
- statusChecker.assertIsErrorFree();
- }
-
- @Test(timeout = 2000)
- public void lossyAppenderShouldOnlyLoseCertainEvents() {
- int bufferSize = 5;
- int loopLen = bufferSize * 2;
- lossyAsyncAppender.addAppender(delayingListAppender);
- lossyAsyncAppender.setQueueSize(bufferSize);
- lossyAsyncAppender.setDiscardingThreshold(1);
- lossyAsyncAppender.start();
- for (int i = 0; i < loopLen; i++) {
- lossyAsyncAppender.doAppend(i);
- }
- lossyAsyncAppender.stop();
- // events 0, 3, 6 and 9 are discardable. However, for events 0 and 3
- // the buffer is not not yet full. Thus, only events 6 and 9 will be
- // effectively discarded.
- verify(delayingListAppender, loopLen - 2);
- }
-
- @Test(timeout = 2000)
- public void lossyAppenderShouldBeNonLossyIfDiscardingThresholdIsZero() {
- int bufferSize = 5;
- int loopLen = bufferSize * 2;
- lossyAsyncAppender.addAppender(delayingListAppender);
- lossyAsyncAppender.setQueueSize(bufferSize);
- lossyAsyncAppender.setDiscardingThreshold(0);
- lossyAsyncAppender.start();
- for (int i = 0; i < loopLen; i++) {
- lossyAsyncAppender.doAppend(i);
- }
- lossyAsyncAppender.stop();
- verify(delayingListAppender, loopLen);
- }
-
- @Test
- public void invalidQueueCapacityShouldResultInNonStartedAppender() {
- asyncAppenderBase.addAppender(new NOPAppender<Integer>());
- asyncAppenderBase.setQueueSize(0);
- assertEquals(0, asyncAppenderBase.getQueueSize());
- asyncAppenderBase.start();
- assertFalse(asyncAppenderBase.isStarted());
- statusChecker.assertContainsMatch("Invalid queue size");
- }
-
- @SuppressWarnings("deprecation")
- @Test
- public void workerThreadFlushesOnStop() {
- int loopLen = 5;
- int maxRuntime = (loopLen + 1) * Math.max(1000, delayingListAppender.delay);
- ListAppender<Integer> la = delayingListAppender;
- asyncAppenderBase.addAppender(la);
- asyncAppenderBase.setDiscardingThreshold(0);
- asyncAppenderBase.setMaxFlushTime(maxRuntime);
- asyncAppenderBase.start();
- asyncAppenderBase.worker.suspend();
-
- for (int i = 0; i < loopLen; i++) {
- asyncAppenderBase.doAppend(i);
- }
- assertEquals(loopLen, asyncAppenderBase.getNumberOfElementsInQueue());
- assertEquals(0, la.list.size());
-
- asyncAppenderBase.worker.resume();
- asyncAppenderBase.stop();
-
- assertEquals(0, asyncAppenderBase.getNumberOfElementsInQueue());
- verify(la, loopLen);
- }
-
- // @SuppressWarnings("deprecation")
- @Test
- public void stopExitsWhenMaxRuntimeReached() throws InterruptedException {
- int maxFlushTime = 1; // runtime of 0 means wait forever, so use 1 ms instead
- int loopLen = 10;
- ListAppender<Integer> la = delayingListAppender;
- asyncAppenderBase.addAppender(la);
- asyncAppenderBase.setMaxFlushTime(maxFlushTime);
- asyncAppenderBase.start();
-
- for (int i = 0; i < loopLen; i++) {
- asyncAppenderBase.doAppend(i);
- }
-
- asyncAppenderBase.stop();
-
- // confirms that stop exited when runtime reached
- statusChecker.assertContainsMatch("Max queue flush timeout \\(" + maxFlushTime + " ms\\) exceeded.");
-
- asyncAppenderBase.worker.join();
-
- // confirms that all entries do end up being flushed if we wait long enough
- verify(la, loopLen);
- }
-
- // Interruption of current thread when in doAppend method should not be
- // consumed by async appender. See also http://jira.qos.ch/browse/LOGBACK-910
- @Test
- public void verifyInterruptionIsNotSwallowed() {
- asyncAppenderBase.addAppender(delayingListAppender);
- asyncAppenderBase.start();
- Thread.currentThread().interrupt();
- asyncAppenderBase.doAppend(new Integer(0));
- assertTrue(Thread.currentThread().isInterrupted());
- // clear flag for next test
- Thread.interrupted();
- }
-
- @Test
- public void verifyInterruptionOfWorkerIsSwallowed() {
- asyncAppenderBase.addAppender(delayingListAppender);
- asyncAppenderBase.start();
- asyncAppenderBase.stop();
- assertFalse(asyncAppenderBase.worker.isInterrupted());
- }
-
- private void verify(ListAppender<Integer> la, int atLeast) {
- assertFalse(la.isStarted());
- assertTrue(atLeast + " <= " + la.list.size(), atLeast <= la.list.size());
- statusChecker.assertIsErrorFree();
- statusChecker.assertContainsMatch("Worker thread will flush remaining events before exiting.");
- }
-
- static class LossyAsyncAppender extends AsyncAppenderBase<Integer> {
- @Override
- protected boolean isDiscardable(Integer i) {
- return (i % 3 == 0);
- }
- }
-
- @Test
- public void checkThatStartMethodIsIdempotent() {
- asyncAppenderBase.addAppender(lossyAsyncAppender);
- asyncAppenderBase.start();
-
- // we don't need mockito for this test, but if we did here is how it would look
- // AsyncAppenderBase<Integer> spied = Mockito.spy(asyncAppenderBase);
- // Mockito.doThrow(new IllegalStateException("non idempotent start")).when((UnsynchronizedAppenderBase<Integer>)
- // spied).start();
-
- // a second invocation of start will cause a IllegalThreadStateException thrown by the asyncAppenderBase.worker
- // thread
- asyncAppenderBase.start();
- }
+ Context context = new ContextBase();
+ AsyncAppenderBase<Integer> asyncAppenderBase = new AsyncAppenderBase<Integer>();
+ LossyAsyncAppender lossyAsyncAppender = new LossyAsyncAppender();
+ DelayingListAppender<Integer> delayingListAppender = new DelayingListAppender<Integer>();
+ ListAppender<Integer> listAppender = new ListAppender<Integer>();
+ OnConsoleStatusListener onConsoleStatusListener = new OnConsoleStatusListener();
+ StatusChecker statusChecker = new StatusChecker(context);
+
+ @Before
+ public void setUp() {
+ onConsoleStatusListener.setContext(context);
+ context.getStatusManager().add(onConsoleStatusListener);
+ onConsoleStatusListener.start();
+
+ asyncAppenderBase.setContext(context);
+ lossyAsyncAppender.setContext(context);
+
+ listAppender.setContext(context);
+ listAppender.setName("list");
+ listAppender.start();
+
+ delayingListAppender.setContext(context);
+ delayingListAppender.setName("list");
+ delayingListAppender.start();
+ }
+
+ @Test(timeout = 2000)
+ public void smoke() {
+ asyncAppenderBase.addAppender(listAppender);
+ asyncAppenderBase.start();
+ asyncAppenderBase.doAppend(0);
+ asyncAppenderBase.stop();
+ verify(listAppender, 1);
+ }
+
+ @Test
+ public void exceptionsShouldNotCauseHalting() throws InterruptedException {
+ NPEAppender npeAppender = new NPEAppender<Integer>();
+ npeAppender.setName("bad");
+ npeAppender.setContext(context);
+ npeAppender.start();
+
+ asyncAppenderBase.addAppender(npeAppender);
+ asyncAppenderBase.start();
+ assertTrue(asyncAppenderBase.isStarted());
+ for (int i = 0; i < 10; i++)
+ asyncAppenderBase.append(i);
+
+ asyncAppenderBase.stop();
+ assertFalse(asyncAppenderBase.isStarted());
+ assertEquals(AppenderBase.ALLOWED_REPEATS, statusChecker.matchCount("Appender \\[bad\\] failed to append."));
+ }
+
+ @Test(timeout = 2000)
+ public void emptyQueueShouldBeStoppable() {
+ asyncAppenderBase.addAppender(listAppender);
+ asyncAppenderBase.start();
+ asyncAppenderBase.stop();
+ verify(listAppender, 0);
+ }
+
+ @Test(timeout = 2000)
+ public void workerShouldStopEvenIfInterruptExceptionConsumedWithinSubappender() {
+ delayingListAppender.delay = 100;
+ asyncAppenderBase.addAppender(delayingListAppender);
+ asyncAppenderBase.start();
+ asyncAppenderBase.doAppend(0);
+ asyncAppenderBase.stop();
+ verify(delayingListAppender, 1);
+ assertTrue(delayingListAppender.interrupted);
+ }
+
+ @Test(timeout = 2000)
+ public void noEventLoss() {
+ int bufferSize = 10;
+ int loopLen = bufferSize * 2;
+ asyncAppenderBase.addAppender(delayingListAppender);
+ asyncAppenderBase.setQueueSize(bufferSize);
+ asyncAppenderBase.start();
+ for (int i = 0; i < loopLen; i++) {
+ asyncAppenderBase.doAppend(i);
+ }
+ asyncAppenderBase.stop();
+ verify(delayingListAppender, loopLen);
+ }
+
+ @Test(timeout = 2000)
+ public void lossyAppenderShouldOnlyLooseCertainEvents() {
+ int bufferSize = 5;
+ int loopLen = bufferSize * 2;
+ lossyAsyncAppender.addAppender(delayingListAppender);
+ lossyAsyncAppender.setQueueSize(bufferSize);
+ lossyAsyncAppender.setDiscardingThreshold(1);
+ lossyAsyncAppender.start();
+ for (int i = 0; i < loopLen; i++) {
+ lossyAsyncAppender.doAppend(i);
+ }
+ lossyAsyncAppender.stop();
+ verify(delayingListAppender, loopLen - 2);
+ }
+
+ @Test(timeout = 2000)
+ public void lossyAppenderShouldBeNonLossyIfDiscardingThresholdIsZero() {
+ int bufferSize = 5;
+ int loopLen = bufferSize * 2;
+ lossyAsyncAppender.addAppender(delayingListAppender);
+ lossyAsyncAppender.setQueueSize(bufferSize);
+ lossyAsyncAppender.setDiscardingThreshold(0);
+ lossyAsyncAppender.start();
+ for (int i = 0; i < loopLen; i++) {
+ lossyAsyncAppender.doAppend(i);
+ }
+ lossyAsyncAppender.stop();
+ verify(delayingListAppender, loopLen);
+ }
+
+ @Test
+ public void invalidQueueCapacityShouldResultInNonStartedAppender() {
+ asyncAppenderBase.addAppender(new NOPAppender<Integer>());
+ asyncAppenderBase.setQueueSize(0);
+ assertEquals(0, asyncAppenderBase.getQueueSize());
+ asyncAppenderBase.start();
+ assertFalse(asyncAppenderBase.isStarted());
+ statusChecker.assertContainsMatch("Invalid queue size");
+ }
+
+ private void verify(ListAppender la, int expectedSize) {
+ assertFalse(la.isStarted());
+ assertEquals(expectedSize, la.list.size());
+ statusChecker.assertIsErrorFree();
+ statusChecker.assertContainsMatch("Worker thread will flush remaining events before exiting.");
+ }
+
+ static class LossyAsyncAppender extends AsyncAppenderBase<Integer> {
+ @Override
+ protected boolean isDiscardable(Integer i) {
+ return (i % 3 == 0);
+ }
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/BasicStatusManagerTest.java b/logback-core/src/test/java/ch/qos/logback/core/BasicStatusManagerTest.java
index b7b3f61..98bd4be 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/BasicStatusManagerTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/BasicStatusManagerTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,74 +15,52 @@ package ch.qos.logback.core;
import static ch.qos.logback.core.BasicStatusManager.MAX_HEADER_COUNT;
import static ch.qos.logback.core.BasicStatusManager.TAIL_SIZE;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.List;
-import ch.qos.logback.core.status.OnConsoleStatusListener;
-import ch.qos.logback.core.status.StatusListener;
-
import org.junit.Test;
import ch.qos.logback.core.status.ErrorStatus;
import ch.qos.logback.core.status.Status;
-public class BasicStatusManagerTest {
-
- BasicStatusManager bsm = new BasicStatusManager();
- @Test
- public void smoke() {
- bsm.add(new ErrorStatus("hello", this));
- assertEquals(Status.ERROR, bsm.getLevel());
+public class BasicStatusManagerTest {
- List<Status> statusList = bsm.getCopyOfStatusList();
- assertNotNull(statusList);
- assertEquals(1, statusList.size());
- assertEquals("hello", statusList.get(0).getMessage());
+
+ BasicStatusManager bsm = new BasicStatusManager();
+
+ @Test
+ public void smoke() {
+ bsm.add(new ErrorStatus("hello", this));
+ assertEquals(Status.ERROR, bsm.getLevel());
+
+ List<Status> statusList = bsm.getCopyOfStatusList();
+ assertNotNull(statusList);
+ assertEquals(1, statusList.size());
+ assertEquals("hello", statusList.get(0).getMessage());
+ }
+
+ @Test
+ public void many() {
+ int margin = 300;
+ int len = MAX_HEADER_COUNT+TAIL_SIZE+margin;
+ for(int i = 0; i < len; i++) {
+ bsm.add(new ErrorStatus(""+i, this));
}
-
- @Test
- public void many() {
- int margin = 300;
- int len = MAX_HEADER_COUNT + TAIL_SIZE + margin;
- for (int i = 0; i < len; i++) {
- bsm.add(new ErrorStatus("" + i, this));
- }
-
- List<Status> statusList = bsm.getCopyOfStatusList();
- assertNotNull(statusList);
- assertEquals(MAX_HEADER_COUNT + TAIL_SIZE, statusList.size());
- List<Status> witness = new ArrayList<Status>();
- for (int i = 0; i < MAX_HEADER_COUNT; i++) {
- witness.add(new ErrorStatus("" + i, this));
- }
- for (int i = 0; i < TAIL_SIZE; i++) {
- witness.add(new ErrorStatus("" + (MAX_HEADER_COUNT + margin + i), this));
- }
- assertEquals(witness, statusList);
+
+ List<Status> statusList = bsm.getCopyOfStatusList();
+ assertNotNull(statusList);
+ assertEquals(MAX_HEADER_COUNT+TAIL_SIZE, statusList.size());
+ List<Status> witness = new ArrayList<Status>();
+ for(int i = 0; i < MAX_HEADER_COUNT; i++) {
+ witness.add(new ErrorStatus(""+i, this));
}
-
- @Test
- public void duplicateInstallationsOfOnConsoleListener() {
- OnConsoleStatusListener sl0 = new OnConsoleStatusListener();
- sl0.start();
- OnConsoleStatusListener sl1 = new OnConsoleStatusListener();
- sl1.start();
-
- assertTrue(bsm.add(sl0));
-
- {
- List<StatusListener> listeners = bsm.getCopyOfStatusListenerList();
- assertEquals(1, listeners.size());
- }
-
- assertFalse(bsm.add(sl1));
- {
- List<StatusListener> listeners = bsm.getCopyOfStatusListenerList();
- assertEquals(1, listeners.size());
- }
+ for(int i = 0; i < TAIL_SIZE; i++) {
+ witness.add(new ErrorStatus(""+(MAX_HEADER_COUNT+margin+i), this));
}
-
+ assertEquals(witness, statusList);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/ContextBaseTest.java b/logback-core/src/test/java/ch/qos/logback/core/ContextBaseTest.java
index a0a83ee..b6b94f1 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/ContextBaseTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/ContextBaseTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,125 +23,104 @@ import org.junit.Test;
import ch.qos.logback.core.spi.LifeCycle;
-import java.util.ArrayList;
-import java.util.concurrent.ExecutorService;
-
public class ContextBaseTest {
- private InstrumentedLifeCycleManager lifeCycleManager = new InstrumentedLifeCycleManager();
-
- private InstrumentedContextBase context = new InstrumentedContextBase(lifeCycleManager);
-
- @Test
- public void renameDefault() {
- context.setName(CoreConstants.DEFAULT_CONTEXT_NAME);
- context.setName("hello");
+ private InstrumentedLifeCycleManager lifeCycleManager =
+ new InstrumentedLifeCycleManager();
+
+ private InstrumentedContextBase context =
+ new InstrumentedContextBase(lifeCycleManager);
+
+ @Test
+ public void renameDefault() {
+ context.setName(CoreConstants.DEFAULT_CONTEXT_NAME);
+ context.setName("hello");
+ }
+
+
+ @Test
+ public void idempotentNameTest() {
+ context.setName("hello");
+ context.setName("hello");
+ }
+
+ @Test
+ public void renameTest() {
+ context.setName("hello");
+ try {
+ context.setName("x");
+ fail("renaming is not allowed");
+ } catch (IllegalStateException ise) {
}
-
- @Test
- public void idempotentNameTest() {
- context.setName("hello");
- context.setName("hello");
+ }
+
+ @Test
+ public void resetTest() {
+ context.setName("hello");
+ context.putProperty("keyA", "valA");
+ context.putObject("keyA", "valA");
+ assertEquals("valA", context.getProperty("keyA"));
+ assertEquals("valA", context.getObject("keyA"));
+ MockLifeCycleComponent component = new MockLifeCycleComponent();
+ context.register(component);
+ assertSame(component, lifeCycleManager.getLastComponent());
+ context.reset();
+ assertNull(context.getProperty("keyA"));
+ assertNull(context.getObject("keyA"));
+ assertTrue(lifeCycleManager.isReset());
+ }
+
+ @Test
+ public void contextNameProperty() {
+ assertNull(context.getProperty(CoreConstants.CONTEXT_NAME_KEY));
+ String HELLO = "hello";
+ context.setName(HELLO);
+ assertEquals(HELLO, context.getProperty(CoreConstants.CONTEXT_NAME_KEY));
+ // good to have a raw reference to the "CONTEXT_NAME" as most clients would
+ // not go through CoreConstants
+ assertEquals(HELLO, context.getProperty("CONTEXT_NAME"));
+ }
+
+ private static class InstrumentedContextBase extends ContextBase {
+
+ private final LifeCycleManager lifeCycleManager;
+
+ public InstrumentedContextBase(LifeCycleManager lifeCycleManager) {
+ this.lifeCycleManager = lifeCycleManager;
}
-
- @Test
- public void renameTest() {
- context.setName("hello");
- try {
- context.setName("x");
- fail("renaming is not allowed");
- } catch (IllegalStateException ise) {
- }
+
+ @Override
+ protected LifeCycleManager getLifeCycleManager() {
+ return lifeCycleManager;
}
-
- @Test
- public void resetTest() {
- context.setName("hello");
- context.putProperty("keyA", "valA");
- context.putObject("keyA", "valA");
- assertEquals("valA", context.getProperty("keyA"));
- assertEquals("valA", context.getObject("keyA"));
- MockLifeCycleComponent component = new MockLifeCycleComponent();
- context.register(component);
- assertSame(component, lifeCycleManager.getLastComponent());
- context.reset();
- assertNull(context.getProperty("keyA"));
- assertNull(context.getObject("keyA"));
- assertTrue(lifeCycleManager.isReset());
+
+ }
+
+ private static class InstrumentedLifeCycleManager extends LifeCycleManager {
+
+ private LifeCycle lastComponent;
+ private boolean reset;
+
+ @Override
+ public void register(LifeCycle component) {
+ lastComponent = component;
+ super.register(component);
}
-
- @Test
- public void contextNameProperty() {
- assertNull(context.getProperty(CoreConstants.CONTEXT_NAME_KEY));
- String HELLO = "hello";
- context.setName(HELLO);
- assertEquals(HELLO, context.getProperty(CoreConstants.CONTEXT_NAME_KEY));
- // good to have a raw reference to the "CONTEXT_NAME" as most clients would
- // not go through CoreConstants
- assertEquals(HELLO, context.getProperty("CONTEXT_NAME"));
+
+ @Override
+ public void reset() {
+ reset = true;
+ super.reset();
}
- private static class InstrumentedContextBase extends ContextBase {
-
- private final LifeCycleManager lifeCycleManager;
-
- public InstrumentedContextBase(LifeCycleManager lifeCycleManager) {
- this.lifeCycleManager = lifeCycleManager;
- }
-
- @Override
- protected LifeCycleManager getLifeCycleManager() {
- return lifeCycleManager;
- }
-
- }
-
- private static class InstrumentedLifeCycleManager extends LifeCycleManager {
-
- private LifeCycle lastComponent;
- private boolean reset;
-
- @Override
- public void register(LifeCycle component) {
- lastComponent = component;
- super.register(component);
- }
-
- @Override
- public void reset() {
- reset = true;
- super.reset();
- }
-
- public LifeCycle getLastComponent() {
- return lastComponent;
- }
-
- public boolean isReset() {
- return reset;
- }
-
+ public LifeCycle getLastComponent() {
+ return lastComponent;
}
- @Test
- public void contextThreadpoolIsDaemonized() throws InterruptedException {
- ExecutorService execSvc = context.getExecutorService();
- final ArrayList<Thread> executingThreads = new ArrayList<Thread>();
- execSvc.execute(new Runnable() {
- @Override
- public void run() {
- synchronized (executingThreads) {
- executingThreads.add(Thread.currentThread());
- executingThreads.notifyAll();
- }
- }
- });
- synchronized (executingThreads) {
- while (executingThreads.isEmpty()) {
- executingThreads.wait();
- }
- }
- assertTrue("executing thread should be a daemon thread.", executingThreads.get(0).isDaemon());
+ public boolean isReset() {
+ return reset;
}
+
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java b/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java
index d2fcd7e..b64126b 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,6 +17,7 @@ import java.io.File;
import java.io.IOException;
import java.nio.channels.FileChannel;
+import ch.qos.logback.core.util.StatusPrinter;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -32,89 +33,90 @@ import ch.qos.logback.core.util.ResilienceUtil;
public class FileAppenderResilienceTest {
- FileAppender<Object> fa = new FileAppender<Object>();
- Context context = new ContextBase();
- int diff = RandomUtil.getPositiveInt();
- String outputDirStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "resilience-" + diff + "/";
+ FileAppender<Object> fa = new FileAppender<Object>();
+ Context context = new ContextBase();
+ int diff = RandomUtil.getPositiveInt();
+ String outputDirStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "resilience-"
+ + diff + "/";
- // String outputDirStr = "\\\\192.168.1.3\\lbtest\\" + "resilience-"+ diff +
- // "/";;
- String logfileStr = outputDirStr + "output.log";
+ // String outputDirStr = "\\\\192.168.1.3\\lbtest\\" + "resilience-"+ diff +
+ // "/";;
+ String logfileStr = outputDirStr + "output.log";
- @Before
- public void setUp() throws InterruptedException {
+ @Before
+ public void setUp() throws InterruptedException {
- context.getStatusManager().add(new OnConsoleStatusListener());
+ context.getStatusManager().add(new OnConsoleStatusListener());
- File outputDir = new File(outputDirStr);
- outputDir.mkdirs();
+ File outputDir = new File(outputDirStr);
+ outputDir.mkdirs();
- fa.setContext(context);
- fa.setName("FILE");
- fa.setEncoder(new EchoEncoder<Object>());
- fa.setFile(logfileStr);
- fa.start();
- }
-
- @Test
- @Ignore
- public void manual() throws InterruptedException, IOException {
- Runner runner = new Runner(fa);
- Thread t = new Thread(runner);
- t.start();
+ fa.setContext(context);
+ fa.setName("FILE");
+ fa.setEncoder(new EchoEncoder<Object>());
+ fa.setFile(logfileStr);
+ fa.start();
+ }
- while (true) {
- Thread.sleep(110);
- }
- }
+ @Test
+ @Ignore
+ public void manual() throws InterruptedException, IOException {
+ Runner runner = new Runner(fa);
+ Thread t = new Thread(runner);
+ t.start();
- @Test
- public void smoke() throws InterruptedException, IOException {
- Runner runner = new Runner(fa);
- Thread t = new Thread(runner);
- t.start();
-
- double delayCoefficient = 2.0;
- for (int i = 0; i < 5; i++) {
- Thread.sleep((int) (RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN * delayCoefficient));
- closeLogFileOnPurpose();
- }
- runner.setDone(true);
- t.join();
-
- double bestCaseSuccessRatio = 1 / delayCoefficient;
- // expect to loose at most 35% of the events
- double lossinessFactor = 0.35;
- double resilianceFactor = (1 - lossinessFactor);
-
- ResilienceUtil.verify(logfileStr, "^hello (\\d{1,5})$", runner.getCounter(), bestCaseSuccessRatio * resilianceFactor);
+ while (true) {
+ Thread.sleep(110);
}
-
- private void closeLogFileOnPurpose() throws IOException {
- ResilientFileOutputStream resilientFOS = (ResilientFileOutputStream) fa.getOutputStream();
- FileChannel fileChannel = resilientFOS.getChannel();
- fileChannel.close();
+ }
+
+ @Test
+ public void smoke() throws InterruptedException, IOException {
+ Runner runner = new Runner(fa);
+ Thread t = new Thread(runner);
+ t.start();
+
+ double delayCoefficient = 2.0;
+ for (int i = 0; i < 5; i++) {
+ Thread.sleep((int)(RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN * delayCoefficient));
+ closeLogFileOnPurpose();
}
+ runner.setDone(true);
+ t.join();
+
+ double bestCaseSuccessRatio = 1/delayCoefficient;
+ // expect to loose at most 35% of the events
+ double lossinessFactor = 0.35;
+ double resilianceFactor = (1-lossinessFactor);
+
+ ResilienceUtil
+ .verify(logfileStr, "^hello (\\d{1,5})$", runner.getCounter(), bestCaseSuccessRatio * resilianceFactor);
+ }
+
+ private void closeLogFileOnPurpose() throws IOException {
+ ResilientFileOutputStream resilientFOS = (ResilientFileOutputStream) fa
+ .getOutputStream();
+ FileChannel fileChannel = resilientFOS.getChannel();
+ fileChannel.close();
+ }
}
class Runner extends RunnableWithCounterAndDone {
- FileAppender<Object> fa;
-
- Runner(FileAppender<Object> fa) {
- this.fa = fa;
- }
-
- public void run() {
- while (!isDone()) {
- counter++;
- fa.doAppend("hello " + counter);
- if (counter % 128 == 0) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- }
- }
- }
+ FileAppender<Object> fa;
+
+ Runner(FileAppender<Object> fa) {
+ this.fa = fa;
+ }
+
+ public void run() {
+ while (!isDone()) {
+ counter++;
+ fa.doAppend("hello " + counter);
+ if (counter % 128 == 0) {
+ try { Thread.sleep(10);
+ } catch (InterruptedException e) { }
+ }
}
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilience_AS_ROOT_Test.java b/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilience_AS_ROOT_Test.java
index 41d75e6..19ca57e 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilience_AS_ROOT_Test.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilience_AS_ROOT_Test.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,107 +29,109 @@ import ch.qos.logback.core.util.StatusPrinter;
public class FileAppenderResilience_AS_ROOT_Test {
- static String MOUNT_POINT = "/mnt/loop/";
+ static String MOUNT_POINT = "/mnt/loop/";
- static String LONG_STR = " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+ static String LONG_STR = " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
- static String PATH_LOOPFS_SCRIPT = "/home/ceki/java/logback/logback-core/src/test/loopfs.sh";
+ static String PATH_LOOPFS_SCRIPT = "/home/ceki/java/logback/logback-core/src/test/loopfs.sh";
- enum LoopFSCommand {
- setup, shake, teardown;
- }
+ enum LoopFSCommand {
+ setup, shake, teardown;
+ }
- Context context = new ContextBase();
- int diff = RandomUtil.getPositiveInt();
- String outputDirStr = MOUNT_POINT + "resilience-" + diff + "/";
- String logfileStr = outputDirStr + "output.log";
+ Context context = new ContextBase();
+ int diff = RandomUtil.getPositiveInt();
+ String outputDirStr = MOUNT_POINT + "resilience-" + diff + "/";
+ String logfileStr = outputDirStr + "output.log";
- FileAppender<Object> fa = new FileAppender<Object>();
+ FileAppender<Object> fa = new FileAppender<Object>();
- static boolean isConformingHost() {
- return EnvUtilForTests.isLocalHostNameInList(new String[] { "haro" });
- }
+ static boolean isConformingHost() {
+ return EnvUtilForTests.isLocalHostNameInList(new String[]{"haro"});
+ }
- @Before
- public void setUp() throws IOException, InterruptedException {
- if (!isConformingHost()) {
- return;
- }
- Process p = runLoopFSScript(LoopFSCommand.setup);
- p.waitFor();
-
- dump("/tmp/loopfs.log");
-
- fa.setContext(context);
- File outputDir = new File(outputDirStr);
- outputDir.mkdirs();
- System.out.println("FileAppenderResilienceTest output dir [" + outputDirStr + "]");
-
- fa.setName("FILE");
- fa.setEncoder(new EchoEncoder<Object>());
- fa.setFile(logfileStr);
- fa.start();
+ @Before
+ public void setUp() throws IOException, InterruptedException {
+ if (!isConformingHost()) {
+ return;
}
-
- void dump(String file) throws IOException {
- FileInputStream fis = null;
- try {
- fis = new FileInputStream(file);
- int r;
- while ((r = fis.read()) != -1) {
- char c = (char) r;
- System.out.print(c);
- }
- } finally {
- if (fis != null) {
- fis.close();
- }
- }
+ Process p = runLoopFSScript(LoopFSCommand.setup);
+ p.waitFor();
+
+ dump("/tmp/loopfs.log");
+
+ fa.setContext(context);
+ File outputDir = new File(outputDirStr);
+ outputDir.mkdirs();
+ System.out.println("FileAppenderResilienceTest output dir [" + outputDirStr
+ + "]");
+
+ fa.setName("FILE");
+ fa.setEncoder(new EchoEncoder<Object>());
+ fa.setFile(logfileStr);
+ fa.start();
+ }
+
+ void dump(String file) throws IOException {
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(file);
+ int r;
+ while ((r = fis.read()) != -1) {
+ char c = (char) r;
+ System.out.print(c);
+ }
+ } finally {
+ if (fis != null) {
+ fis.close();
+ }
}
+ }
- @After
- public void tearDown() throws IOException, InterruptedException {
- if (!isConformingHost()) {
- return;
- }
- StatusPrinter.print(context);
- fa.stop();
- Process p = runLoopFSScript(LoopFSCommand.teardown);
- p.waitFor();
- System.out.println("Tearing down");
+ @After
+ public void tearDown() throws IOException, InterruptedException {
+ if (!isConformingHost()) {
+ return;
}
-
- static int TOTAL_DURATION = 5000;
- static int NUM_STEPS = 500;
- static int DELAY = TOTAL_DURATION / NUM_STEPS;
-
- @Test
- public void go() throws IOException, InterruptedException {
- if (!isConformingHost()) {
- return;
- }
- Process p = runLoopFSScript(LoopFSCommand.shake);
- for (int i = 0; i < NUM_STEPS; i++) {
- fa.append(String.valueOf(i) + LONG_STR);
- Thread.sleep(DELAY);
- }
- p.waitFor();
- // the extrernal script has the file system ready for IO 50% of the time
- double bestCase = 0.5;
- ResilienceUtil.verify(logfileStr, "^(\\d{1,3}) x*$", NUM_STEPS, bestCase * 0.6);
- System.out.println("Done go");
+ StatusPrinter.print(context);
+ fa.stop();
+ Process p = runLoopFSScript(LoopFSCommand.teardown);
+ p.waitFor();
+ System.out.println("Tearing down");
+ }
+
+ static int TOTAL_DURATION = 5000;
+ static int NUM_STEPS = 500;
+ static int DELAY = TOTAL_DURATION / NUM_STEPS;
+
+ @Test
+ public void go() throws IOException, InterruptedException {
+ if (!isConformingHost()) {
+ return;
}
-
- // the loopfs script is tightly coupled with the host machine
- // it needs to be Unix, with sudo privileges granted to the script
- Process runLoopFSScript(LoopFSCommand cmd) throws IOException, InterruptedException {
- // causing a NullPointerException is better than locking the whole
- // machine which the next operation can and will do.
- if (!isConformingHost()) {
- return null;
- }
- ProcessBuilder pb = new ProcessBuilder();
- pb.command("/usr/bin/sudo", PATH_LOOPFS_SCRIPT, cmd.toString());
- return pb.start();
+ Process p = runLoopFSScript(LoopFSCommand.shake);
+ for (int i = 0; i < NUM_STEPS; i++) {
+ fa.append(String.valueOf(i) + LONG_STR);
+ Thread.sleep(DELAY);
+ }
+ p.waitFor();
+ // the extrernal script has the file system ready for IO 50% of the time
+ double bestCase = 0.5;
+ ResilienceUtil.verify(logfileStr, "^(\\d{1,3}) x*$", NUM_STEPS, bestCase*0.6);
+ System.out.println("Done go");
+ }
+
+ // the loopfs script is tightly coupled with the host machine
+ // it needs to be Unix, with sudo privileges granted to the script
+ Process runLoopFSScript(LoopFSCommand cmd) throws IOException,
+ InterruptedException {
+ // causing a NullPointerException is better than locking the whole
+ // machine which the next operation can and will do.
+ if (!isConformingHost()) {
+ return null;
}
+ ProcessBuilder pb = new ProcessBuilder();
+ pb.command("/usr/bin/sudo", PATH_LOOPFS_SCRIPT, cmd.toString());
+ return pb.start();
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/LifeCycleManagerTest.java b/logback-core/src/test/java/ch/qos/logback/core/LifeCycleManagerTest.java
index f431671..08a0371 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/LifeCycleManagerTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/LifeCycleManagerTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2011, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -11,12 +11,14 @@
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
+
package ch.qos.logback.core;
import static org.junit.Assert.assertFalse;
import org.junit.Test;
+
/**
* Unit tests for {@link LifeCycleManager}.
*
@@ -24,15 +26,15 @@ import org.junit.Test;
*/
public class LifeCycleManagerTest {
- private LifeCycleManager manager = new LifeCycleManager();
-
- @Test
- public void testRegisterAndReset() {
- MockLifeCycleComponent component = new MockLifeCycleComponent();
- manager.register(component);
- component.start();
- manager.reset();
- assertFalse(component.isStarted());
- }
+ private LifeCycleManager manager = new LifeCycleManager();
+
+ @Test
+ public void testRegisterAndReset() {
+ MockLifeCycleComponent component = new MockLifeCycleComponent();
+ manager.register(component);
+ component.start();
+ manager.reset();
+ assertFalse(component.isStarted());
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/MockLifeCycleComponent.java b/logback-core/src/test/java/ch/qos/logback/core/MockLifeCycleComponent.java
index 83bfb46..3f0ad8c 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/MockLifeCycleComponent.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/MockLifeCycleComponent.java
@@ -1,34 +1,21 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
package ch.qos.logback.core;
import ch.qos.logback.core.spi.LifeCycle;
public class MockLifeCycleComponent implements LifeCycle {
- private boolean started;
+ private boolean started;
+
+ public void start() {
+ started = true;
+ }
- public void start() {
- started = true;
- }
-
- public void stop() {
- started = false;
- }
-
- public boolean isStarted() {
- return started;
- }
+ public void stop() {
+ started = false;
+ }
+ public boolean isStarted() {
+ return started;
+ }
+
}
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/OutputStreamAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/OutputStreamAppenderTest.java
index a990f02..c4d0ddd 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/OutputStreamAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/OutputStreamAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core;
+
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
@@ -26,96 +27,96 @@ import ch.qos.logback.core.pattern.parser.SamplePatternLayout;
public class OutputStreamAppenderTest {
- Context context = new ContextBase();
-
- @Before
- public void setUp() throws Exception {
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
- @Test
- public void smoke() {
- String FILE_HEADER = "FILE_HEADER ";
- String PRESENTATION_HEADER = "PRESENTATION_HEADER";
- String PRESENTATION_FOOTER = "PRESENTATION_FOOTER ";
- String FILE_FOOTER = "FILE_FOOTER";
- headerFooterCheck(FILE_HEADER, PRESENTATION_HEADER, PRESENTATION_FOOTER, FILE_FOOTER);
- }
-
- @Test
- public void nullFileHeader() {
- String FILE_HEADER = null;
- String PRESENTATION_HEADER = "PRESENTATION_HEADER";
- String PRESENTATION_FOOTER = "PRESENTATION_FOOTER ";
- String FILE_FOOTER = "FILE_FOOTER";
- headerFooterCheck(FILE_HEADER, PRESENTATION_HEADER, PRESENTATION_FOOTER, FILE_FOOTER);
- }
-
- @Test
- public void nullPresentationHeader() {
- String FILE_HEADER = "FILE_HEADER ";
- String PRESENTATION_HEADER = null;
- String PRESENTATION_FOOTER = "PRESENTATION_FOOTER ";
- String FILE_FOOTER = "FILE_FOOTER";
- headerFooterCheck(FILE_HEADER, PRESENTATION_HEADER, PRESENTATION_FOOTER, FILE_FOOTER);
- }
-
- @Test
- public void nullPresentationFooter() {
- String FILE_HEADER = "FILE_HEADER ";
- String PRESENTATION_HEADER = "PRESENTATION_HEADER";
- String PRESENTATION_FOOTER = null;
- String FILE_FOOTER = "FILE_FOOTER";
- headerFooterCheck(FILE_HEADER, PRESENTATION_HEADER, PRESENTATION_FOOTER, FILE_FOOTER);
- }
-
- @Test
- public void nullFileFooter() {
- String FILE_HEADER = "FILE_HEADER ";
- String PRESENTATION_HEADER = "PRESENTATION_HEADER";
- String PRESENTATION_FOOTER = "PRESENTATION_FOOTER ";
- String FILE_FOOTER = null;
- headerFooterCheck(FILE_HEADER, PRESENTATION_HEADER, PRESENTATION_FOOTER, FILE_FOOTER);
- }
-
- public void headerFooterCheck(String fileHeader, String presentationHeader, String presentationFooter, String fileFooter) {
- OutputStreamAppender<Object> wa = new OutputStreamAppender<Object>();
- wa.setContext(context);
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
- SamplePatternLayout<Object> spl = new SamplePatternLayout<Object>();
- spl.setContext(context);
-
- spl.setFileHeader(fileHeader);
- spl.setPresentationHeader(presentationHeader);
- spl.setPresentationFooter(presentationFooter);
- spl.setFileFooter(fileFooter);
-
- spl.start();
- LayoutWrappingEncoder<Object> encoder = new LayoutWrappingEncoder<Object>();
- encoder.setLayout(spl);
- encoder.setContext(context);
-
- wa.setEncoder(encoder);
- wa.setOutputStream(baos);
- wa.start();
-
- wa.stop();
- String result = baos.toString();
-
- String expectedHeader = emtptyIfNull(fileHeader) + emtptyIfNull(presentationHeader);
-
- System.out.println(result);
- assertTrue(result, result.startsWith(expectedHeader));
-
- String expectedFooter = emtptyIfNull(presentationFooter) + emtptyIfNull(fileFooter);
- assertTrue(result, result.endsWith(expectedFooter));
- }
-
- String emtptyIfNull(String s) {
- return s == null ? "" : s;
- }
+ Context context = new ContextBase();
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void smoke() {
+ String FILE_HEADER = "FILE_HEADER ";
+ String PRESENTATION_HEADER = "PRESENTATION_HEADER";
+ String PRESENTATION_FOOTER = "PRESENTATION_FOOTER ";
+ String FILE_FOOTER = "FILE_FOOTER";
+ headerFooterCheck(FILE_HEADER, PRESENTATION_HEADER, PRESENTATION_FOOTER, FILE_FOOTER);
+ }
+
+ @Test
+ public void nullFileHeader() {
+ String FILE_HEADER = null;
+ String PRESENTATION_HEADER = "PRESENTATION_HEADER";
+ String PRESENTATION_FOOTER = "PRESENTATION_FOOTER ";
+ String FILE_FOOTER = "FILE_FOOTER";
+ headerFooterCheck(FILE_HEADER, PRESENTATION_HEADER, PRESENTATION_FOOTER, FILE_FOOTER);
+ }
+
+ @Test
+ public void nullPresentationHeader() {
+ String FILE_HEADER = "FILE_HEADER ";
+ String PRESENTATION_HEADER = null;
+ String PRESENTATION_FOOTER = "PRESENTATION_FOOTER ";
+ String FILE_FOOTER = "FILE_FOOTER";
+ headerFooterCheck(FILE_HEADER, PRESENTATION_HEADER, PRESENTATION_FOOTER, FILE_FOOTER);
+ }
+
+ @Test
+ public void nullPresentationFooter() {
+ String FILE_HEADER = "FILE_HEADER ";
+ String PRESENTATION_HEADER = "PRESENTATION_HEADER";
+ String PRESENTATION_FOOTER = null;
+ String FILE_FOOTER = "FILE_FOOTER";
+ headerFooterCheck(FILE_HEADER, PRESENTATION_HEADER, PRESENTATION_FOOTER, FILE_FOOTER);
+ }
+
+ @Test
+ public void nullFileFooter() {
+ String FILE_HEADER = "FILE_HEADER ";
+ String PRESENTATION_HEADER = "PRESENTATION_HEADER";
+ String PRESENTATION_FOOTER = "PRESENTATION_FOOTER ";
+ String FILE_FOOTER = null;
+ headerFooterCheck(FILE_HEADER, PRESENTATION_HEADER, PRESENTATION_FOOTER, FILE_FOOTER);
+ }
+
+ public void headerFooterCheck(String fileHeader, String presentationHeader, String presentationFooter, String fileFooter) {
+ OutputStreamAppender<Object> wa = new OutputStreamAppender<Object>();
+ wa.setContext(context);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ SamplePatternLayout<Object> spl = new SamplePatternLayout<Object>();
+ spl.setContext(context);
+
+ spl.setFileHeader(fileHeader);
+ spl.setPresentationHeader(presentationHeader);
+ spl.setPresentationFooter(presentationFooter);
+ spl.setFileFooter(fileFooter);
+
+ spl.start();
+ LayoutWrappingEncoder<Object> encoder = new LayoutWrappingEncoder<Object>();
+ encoder.setLayout(spl);
+ encoder.setContext(context);
+
+ wa.setEncoder(encoder);
+ wa.setOutputStream(baos);
+ wa.start();
+
+ wa.stop();
+ String result = baos.toString();
+
+ String expectedHeader = emtptyIfNull(fileHeader) + emtptyIfNull(presentationHeader);
+
+ System.out.println(result);
+ assertTrue(result, result.startsWith(expectedHeader));
+
+ String expectedFooter = emtptyIfNull(presentationFooter) + emtptyIfNull(fileFooter);
+ assertTrue(result, result.endsWith(expectedFooter));
+ }
+
+ String emtptyIfNull(String s) {
+ return s == null ? "" : s;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/PackageTest.java
index c86947f..36593a4 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,7 +18,10 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ ContextBaseTest.class, OutputStreamAppenderTest.class, FileAppenderResilienceTest.class, FileAppenderResilience_AS_ROOT_Test.class,
- AsyncAppenderBaseTest.class })
+ at SuiteClasses({ContextBaseTest.class,
+ OutputStreamAppenderTest.class,
+ FileAppenderResilienceTest.class,
+ FileAppenderResilience_AS_ROOT_Test.class,
+ AsyncAppenderBaseTest.class})
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/PrudentFileAppenderInterruptTest.java b/logback-core/src/test/java/ch/qos/logback/core/PrudentFileAppenderInterruptTest.java
deleted file mode 100644
index e9de80b..0000000
--- a/logback-core/src/test/java/ch/qos/logback/core/PrudentFileAppenderInterruptTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.concurrent.CountDownLatch;
-import org.junit.Before;
-import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-
-import ch.qos.logback.core.contention.RunnableWithCounterAndDone;
-import ch.qos.logback.core.encoder.EchoEncoder;
-import ch.qos.logback.core.status.OnConsoleStatusListener;
-import ch.qos.logback.core.testUtil.RandomUtil;
-import ch.qos.logback.core.util.CoreTestConstants;
-
-public class PrudentFileAppenderInterruptTest {
-
- FileAppender<Object> fa = new FileAppender<Object>();
- Context context = new ContextBase();
- int diff = RandomUtil.getPositiveInt();
- String outputDirStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "resilience-" + diff + "/";
- String logfileStr = outputDirStr + "output.log";
-
- @Before
- public void setUp() throws InterruptedException {
- context.getStatusManager().add(new OnConsoleStatusListener());
-
- File outputDir = new File(outputDirStr);
- outputDir.mkdirs();
-
- fa.setContext(context);
- fa.setName("FILE");
- fa.setPrudent(true);
- fa.setEncoder(new EchoEncoder<Object>());
- fa.setFile(logfileStr);
- fa.start();
- }
-
- @Test
- public void smoke() throws InterruptedException, IOException {
- Runner runner = new Runner(fa);
- Thread t = new Thread(runner);
- t.start();
-
- runner.latch.await();
-
- fa.doAppend("hello not interrupted");
-
- FileReader fr = new FileReader(logfileStr);
- BufferedReader br = new BufferedReader(fr);
-
- int totalLines = 0;
- while (br.readLine() != null) {
- totalLines++; // In this test, the content of the file does not matter
- }
- fr.close();
- br.close();
-
- assertEquals("Incorrect number of logged lines", 2, totalLines);
- }
-
- class Runner extends RunnableWithCounterAndDone {
- FileAppender<Object> fa;
- CountDownLatch latch = new CountDownLatch(1); // Just to make sure this is executed before we log in the test
- // method
-
- Runner(FileAppender<Object> fa) {
- this.fa = fa;
- }
-
- public void run() {
- Thread.currentThread().interrupt();
- fa.doAppend("hello interrupted");
- latch.countDown();
- }
- }
-
-}
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/appender/AbstractAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/appender/AbstractAppenderTest.java
index 798f3b7..d2cec92 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/appender/AbstractAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/appender/AbstractAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.appender;
+
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -24,41 +25,44 @@ import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.status.StatusChecker;
import ch.qos.logback.core.util.StatusPrinter;
-abstract public class AbstractAppenderTest<E> {
-
- abstract protected Appender<E> getAppender();
-
- abstract protected Appender<E> getConfiguredAppender();
-
- Context context = new ContextBase();
- @Test
- public void testNewAppender() {
- // new appenders should be inactive
- Appender<E> appender = getAppender();
- assertFalse(appender.isStarted());
- }
- @Test
- public void testConfiguredAppender() {
- Appender<E> appender = getConfiguredAppender();
- appender.start();
- assertTrue(appender.isStarted());
-
- appender.stop();
- assertFalse(appender.isStarted());
+abstract public class AbstractAppenderTest<E> {
+
+
+ abstract protected Appender<E> getAppender();
+ abstract protected Appender<E> getConfiguredAppender();
+ Context context = new ContextBase();
+
+ @Test
+ public void testNewAppender() {
+ // new appenders should be inactive
+ Appender<E> appender = getAppender();
+ assertFalse( appender.isStarted());
+ }
+
+ @Test
+ public void testConfiguredAppender() {
+ Appender<E> appender = getConfiguredAppender();
+ appender.start();
+ assertTrue(appender.isStarted());
+
+ appender.stop();
+ assertFalse(appender.isStarted());
+
+ }
+
+ @Test
+ public void testNoStart() {
+ Appender<E> appender = getAppender();
+ appender.setContext(context);
+ appender.setName("doh");
+ // is null OK?
+ appender.doAppend(null);
+ StatusChecker checker = new StatusChecker(context.getStatusManager());
+ StatusPrinter.print(context);
+ checker.assertContainsMatch("Attempted to append to non started appender \\[doh\\].");
+ }
+}
- }
- @Test
- public void testNoStart() {
- Appender<E> appender = getAppender();
- appender.setContext(context);
- appender.setName("doh");
- // is null OK?
- appender.doAppend(null);
- StatusChecker checker = new StatusChecker(context.getStatusManager());
- StatusPrinter.print(context);
- checker.assertContainsMatch("Attempted to append to non started appender \\[doh\\].");
- }
-}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/appender/ConsoleAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/appender/ConsoleAppenderTest.java
index 12224bb..4e85e39 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/appender/ConsoleAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/appender/ConsoleAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -37,124 +37,123 @@ import static org.junit.Assert.assertFalse;
*/
public class ConsoleAppenderTest extends AbstractAppenderTest<Object> {
- XTeeOutputStream tee;
- PrintStream original;
-
- @Before
- public void setUp() {
- original = System.out;
- // tee will output bytes on System out but it will also
- // collect them so that the output can be compared against
- // some expected output data
- // tee = new TeeOutputStream(original);
-
- // keep the console quiet
- tee = new XTeeOutputStream(null);
-
- // redirect System.out to tee
- System.setOut(new PrintStream(tee));
- }
-
- @After
- public void tearDown() {
- System.setOut(original);
- }
-
- @Override
- public Appender<Object> getAppender() {
- return new ConsoleAppender<Object>();
- }
-
- protected Appender<Object> getConfiguredAppender() {
- ConsoleAppender<Object> ca = new ConsoleAppender<Object>();
- ca.setEncoder(new NopEncoder<Object>());
- ca.start();
- return ca;
- }
-
- @Test
- public void smoke() {
- ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
- ca.setEncoder(new DummyEncoder<Object>());
- ca.start();
- ca.doAppend(new Object());
- assertEquals(DummyLayout.DUMMY, tee.toString());
- }
-
- @Test
- public void open() {
- ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
- DummyEncoder<Object> dummyEncoder = new DummyEncoder<Object>();
- dummyEncoder.setFileHeader("open");
- ca.setEncoder(dummyEncoder);
- ca.start();
- ca.doAppend(new Object());
- ca.stop();
- assertEquals("open" + CoreConstants.LINE_SEPARATOR + DummyLayout.DUMMY, tee.toString());
- }
-
- @Test
- public void testClose() {
- ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
- DummyEncoder<Object> dummyEncoder = new DummyEncoder<Object>();
- dummyEncoder.setFileFooter("CLOSED");
- ca.setEncoder(dummyEncoder);
- ca.start();
- ca.doAppend(new Object());
- ca.stop();
- // ConsoleAppender must keep the underlying stream open.
- // The console is not ours to close.
- assertFalse(tee.isClosed());
- assertEquals(DummyLayout.DUMMY + "CLOSED", tee.toString());
- }
-
- // See http://jira.qos.ch/browse/LBCORE-143
- @Test
- public void changeInConsole() {
- ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
- EchoEncoder<Object> encoder = new EchoEncoder<Object>();
- ca.setEncoder(encoder);
- ca.start();
- ca.doAppend("a");
- assertEquals("a" + CoreConstants.LINE_SEPARATOR, tee.toString());
-
- XTeeOutputStream newTee = new XTeeOutputStream(null);
- System.setOut(new PrintStream(newTee));
- ca.doAppend("b");
- assertEquals("b" + CoreConstants.LINE_SEPARATOR, newTee.toString());
- }
-
- @Test
- public void testUTF16BE() throws UnsupportedEncodingException {
- ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
- DummyEncoder<Object> dummyEncoder = new DummyEncoder<Object>();
- String encodingName = "UTF-16BE";
- dummyEncoder.setEncodingName(encodingName);
- ca.setEncoder(dummyEncoder);
- ca.start();
- ca.doAppend(new Object());
- assertEquals(DummyLayout.DUMMY, new String(tee.toByteArray(), encodingName));
- }
-
- @Test
- public void wrongTarget() {
- ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
- EchoEncoder<Object> encoder = new EchoEncoder<Object>();
- encoder.setContext(context);
- ca.setContext(context);
- ca.setTarget("foo");
- ca.setEncoder(encoder);
- ca.start();
- ca.doAppend("a");
- StatusChecker checker = new StatusChecker(context);
- // 21:28:01,246 + WARN in ch.qos.logback.core.ConsoleAppender[null] - [foo] should be one of [System.out,
- // System.err]
- // 21:28:01,246 |-WARN in ch.qos.logback.core.ConsoleAppender[null] - Using previously set target, System.out by
- // default.
- // StatusPrinter.print(context);
-
- checker.assertContainsMatch(Status.WARN, "\\[foo\\] should be one of \\[System.out, System.err\\]");
-
- }
+ XTeeOutputStream tee;
+ PrintStream original;
+
+ @Before
+ public void setUp() {
+ original = System.out;
+ // tee will output bytes on System out but it will also
+ // collect them so that the output can be compared against
+ // some expected output data
+ // tee = new TeeOutputStream(original);
+
+ // keep the console quiet
+ tee = new XTeeOutputStream(null);
+
+ // redirect System.out to tee
+ System.setOut(new PrintStream(tee));
+ }
+
+ @After
+ public void tearDown() {
+ System.setOut(original);
+ }
+
+ @Override
+ public Appender<Object> getAppender() {
+ return new ConsoleAppender<Object>();
+ }
+
+ protected Appender<Object> getConfiguredAppender() {
+ ConsoleAppender<Object> ca = new ConsoleAppender<Object>();
+ ca.setEncoder(new NopEncoder<Object>());
+ ca.start();
+ return ca;
+ }
+
+ @org.junit.Test
+ public void testBasic() {
+ ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
+ ca.setEncoder(new DummyEncoder<Object>());
+ ca.start();
+ ca.doAppend(new Object());
+ assertEquals(DummyLayout.DUMMY, tee.toString());
+ }
+
+ @org.junit.Test
+ public void testOpen() {
+ ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
+ DummyEncoder<Object> dummyEncoder = new DummyEncoder<Object>();
+ dummyEncoder.setFileHeader("open");
+ ca.setEncoder(dummyEncoder);
+ ca.start();
+ ca.doAppend(new Object());
+ ca.stop();
+ assertEquals("open" + CoreConstants.LINE_SEPARATOR + DummyLayout.DUMMY, tee
+ .toString());
+ }
+
+ @Test
+ public void testClose() {
+ ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
+ DummyEncoder<Object> dummyEncoder = new DummyEncoder<Object>();
+ dummyEncoder.setFileFooter("CLOSED");
+ ca.setEncoder(dummyEncoder);
+ ca.start();
+ ca.doAppend(new Object());
+ ca.stop();
+ // ConsoleAppender must keep the underlying stream open.
+ // The console is not ours to close.
+ assertFalse(tee.isClosed());
+ assertEquals(DummyLayout.DUMMY + "CLOSED", tee.toString());
+ }
+
+ // See http://jira.qos.ch/browse/LBCORE-143
+ @Test
+ public void changeInConsole() {
+ ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
+ EchoEncoder<Object> encoder = new EchoEncoder<Object>();
+ ca.setEncoder(encoder);
+ ca.start();
+ ca.doAppend("a");
+ assertEquals("a" + CoreConstants.LINE_SEPARATOR, tee.toString());
+
+ XTeeOutputStream newTee = new XTeeOutputStream(null);
+ System.setOut(new PrintStream(newTee));
+ ca.doAppend("b");
+ assertEquals("b" + CoreConstants.LINE_SEPARATOR, newTee.toString());
+ }
+
+ @Test
+ public void testUTF16BE() throws UnsupportedEncodingException {
+ ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
+ DummyEncoder<Object> dummyEncoder = new DummyEncoder<Object>();
+ String encodingName = "UTF-16BE";
+ dummyEncoder.setEncodingName(encodingName);
+ ca.setEncoder(dummyEncoder);
+ ca.start();
+ ca.doAppend(new Object());
+ assertEquals(DummyLayout.DUMMY, new String(tee.toByteArray(), encodingName));
+ }
+
+ @Test
+ public void wrongTarget() {
+ ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
+ EchoEncoder<Object> encoder = new EchoEncoder<Object>();
+ encoder.setContext(context);
+ ca.setContext(context);
+ ca.setTarget("foo");
+ ca.setEncoder(encoder);
+ ca.start();
+ ca.doAppend("a");
+ StatusChecker checker = new StatusChecker(context);
+ //21:28:01,246 + WARN in ch.qos.logback.core.ConsoleAppender[null] - [foo] should be one of [SystemOut, SystemErr]
+ //21:28:01,246 |-WARN in ch.qos.logback.core.ConsoleAppender[null] - Using previously set target, System.out by default.
+// StatusPrinter.print(context);
+
+ checker.assertContainsMatch(Status.WARN, "\\[foo\\] should be one of \\[SystemOut, SystemErr\\]");
+
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppenderTest.java
index 84dbd4c..79ff995 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,29 +25,30 @@ import ch.qos.logback.core.encoder.DummyEncoder;
import ch.qos.logback.core.encoder.Encoder;
import ch.qos.logback.core.layout.DummyLayout;
-public class DummyAppenderTest extends AbstractAppenderTest<Object> {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DummyWriterAppender<Object> da = new DummyWriterAppender<Object>(baos);
-
- protected Appender<Object> getAppender() {
- return da;
- }
-
- protected Appender<Object> getConfiguredAppender() {
- da.setEncoder(new DummyEncoder<Object>());
- da.start();
- return da;
- }
-
- @Test
- public void testBasic() throws IOException {
- Encoder<Object> encoder = new DummyEncoder<Object>();
- encoder.init(baos);
- da.setEncoder(encoder);
- da.start();
- da.doAppend(new Object());
- assertEquals(DummyLayout.DUMMY, baos.toString());
- }
+public class DummyAppenderTest extends AbstractAppenderTest<Object> {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DummyWriterAppender<Object> da = new DummyWriterAppender<Object>(baos);
+
+ protected Appender<Object> getAppender() {
+ return da;
+ }
+
+ protected Appender<Object> getConfiguredAppender() {
+ da.setEncoder(new DummyEncoder<Object>());
+ da.start();
+ return da;
+ }
+
+ @Test
+ public void testBasic() throws IOException {
+ Encoder<Object> encoder = new DummyEncoder<Object>();
+ encoder.init(baos);
+ da.setEncoder(encoder);
+ da.start();
+ da.doAppend(new Object());
+ assertEquals(DummyLayout.DUMMY, baos.toString());
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/appender/DummyWriterAppender.java b/logback-core/src/test/java/ch/qos/logback/core/appender/DummyWriterAppender.java
index 95191da..671e9cc 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/appender/DummyWriterAppender.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/appender/DummyWriterAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,9 +17,10 @@ import java.io.OutputStream;
import ch.qos.logback.core.OutputStreamAppender;
-public class DummyWriterAppender<E> extends OutputStreamAppender<E> {
+public class DummyWriterAppender<E> extends
+ OutputStreamAppender<E> {
- DummyWriterAppender(OutputStream os) {
- this.setOutputStream(os);
- }
+ DummyWriterAppender(OutputStream os) {
+ this.setOutputStream(os);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java
index f354471..293dbbb 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,7 +21,6 @@ import java.io.File;
import java.util.List;
import ch.qos.logback.core.status.StatusChecker;
-
import org.junit.Test;
import ch.qos.logback.core.Appender;
@@ -32,126 +31,99 @@ import ch.qos.logback.core.status.Status;
import ch.qos.logback.core.status.StatusManager;
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.util.CoreTestConstants;
-import ch.qos.logback.core.util.StatusPrinter;
+import ch.qos.logback.core.util.FileUtil;
public class FileAppenderTest extends AbstractAppenderTest<Object> {
- int diff = RandomUtil.getPositiveInt();
-
- protected Appender<Object> getAppender() {
- return new FileAppender<Object>();
- }
-
- protected Appender<Object> getConfiguredAppender() {
- FileAppender<Object> appender = new FileAppender<Object>();
- appender.setEncoder(new NopEncoder<Object>());
- appender.setFile(CoreTestConstants.OUTPUT_DIR_PREFIX + "temp.log");
- appender.setName("test");
- appender.setContext(context);
- appender.start();
- return appender;
- }
-
- @Test
- public void smoke() {
- String filename = CoreTestConstants.OUTPUT_DIR_PREFIX + "/fat-smoke.log";
-
- FileAppender<Object> appender = new FileAppender<Object>();
- appender.setEncoder(new DummyEncoder<Object>());
- appender.setAppend(false);
- appender.setFile(filename);
- appender.setName("smoke");
- appender.setContext(context);
- appender.start();
- appender.doAppend(new Object());
- appender.stop();
-
- File file = new File(filename);
- assertTrue(file.exists());
- assertTrue("failed to delete " + file.getAbsolutePath(), file.delete());
- }
-
- @Test
- public void testCreateParentFolders() {
- String filename = CoreTestConstants.OUTPUT_DIR_PREFIX + "/fat-testCreateParentFolders-" + diff + "/testCreateParentFolders.txt";
- File file = new File(filename);
- assertFalse(file.getParentFile().exists());
- assertFalse(file.exists());
-
- FileAppender<Object> appender = new FileAppender<Object>();
- appender.setEncoder(new DummyEncoder<Object>());
- appender.setAppend(false);
- appender.setFile(filename);
- appender.setName("testCreateParentFolders");
- appender.setContext(context);
- appender.start();
- appender.doAppend(new Object());
- appender.stop();
- assertTrue(file.getParentFile().exists());
- assertTrue(file.exists());
-
- // cleanup
- assertTrue("failed to delete " + file.getAbsolutePath(), file.delete());
- File parent = file.getParentFile();
- assertTrue("failed to delete " + parent.getAbsolutePath(), parent.delete());
- }
-
- @Test
- public void testPrudentModeLogicalImplications() {
- String filename = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "fat-testPrudentModeLogicalImplications.txt";
- File file = new File(filename);
- FileAppender<Object> appender = new FileAppender<Object>();
- appender.setEncoder(new DummyEncoder<Object>());
- appender.setFile(filename);
- appender.setName("testPrudentModeLogicalImplications");
- appender.setContext(context);
-
- appender.setAppend(false);
- appender.setPrudent(true);
- appender.start();
-
- assertTrue(appender.isAppend());
-
- StatusManager sm = context.getStatusManager();
- // StatusPrinter.print(context);
- StatusChecker statusChecker = new StatusChecker(context);
- assertEquals(Status.WARN, statusChecker.getHighestLevel(0));
- List<Status> statusList = sm.getCopyOfStatusList();
- assertTrue("Expecting status list size to be 2 or larger, but was " + statusList.size(), statusList.size() >= 2);
- String msg1 = statusList.get(1).getMessage();
-
- assertTrue("Got message [" + msg1 + "]", msg1.startsWith("Setting \"Append\" property"));
-
- appender.doAppend(new Object());
- appender.stop();
- assertTrue(file.exists());
- assertTrue("failed to delete " + file.getAbsolutePath(), file.delete());
- }
-
- @Test
- public void fileNameCollision() {
- String fileName = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "fileNameCollision";
-
- FileAppender<Object> appender0 = new FileAppender<Object>();
- appender0.setName("FA0");
- appender0.setFile(fileName);
- appender0.setContext(context);
- appender0.setEncoder(new DummyEncoder<Object>());
- appender0.start();
- assertTrue(appender0.isStarted());
-
- FileAppender<Object> appender1 = new FileAppender<Object>();
- appender1.setName("FA1");
- appender1.setFile(fileName);
- appender1.setContext(context);
- appender1.setEncoder(new DummyEncoder<Object>());
- appender1.start();
-
- assertFalse(appender1.isStarted());
-
- StatusPrinter.print(context);
- StatusChecker checker = new StatusChecker(context);
- checker.assertContainsMatch(Status.ERROR, "'File' option has the same value");
-
- }
+ int diff = RandomUtil.getPositiveInt();
+
+ protected Appender<Object> getAppender() {
+ return new FileAppender<Object>();
+ }
+
+ protected Appender<Object> getConfiguredAppender() {
+ FileAppender<Object> appender = new FileAppender<Object>();
+ appender.setEncoder(new NopEncoder<Object>());
+ appender.setFile(CoreTestConstants.OUTPUT_DIR_PREFIX+"temp.log");
+ appender.setName("test");
+ appender.setContext(context);
+ appender.start();
+ return appender;
+ }
+
+ @Test
+ public void smoke() {
+ String filename = CoreTestConstants.OUTPUT_DIR_PREFIX + "/fat-smoke.log";
+
+ FileAppender<Object> appender = new FileAppender<Object>();
+ appender.setEncoder(new DummyEncoder<Object>());
+ appender.setAppend(false);
+ appender.setFile(filename);
+ appender.setName("smoke");
+ appender.setContext(context);
+ appender.start();
+ appender.doAppend(new Object());
+ appender.stop();
+
+ File file = new File(filename);
+ assertTrue(file.exists());
+ assertTrue("failed to delete " + file.getAbsolutePath(), file.delete());
+ }
+
+ @Test
+ public void testCreateParentFolders() {
+ String filename = CoreTestConstants.OUTPUT_DIR_PREFIX + "/fat-testCreateParentFolders-" + diff
+ + "/testCreateParentFolders.txt";
+ File file = new File(filename);
+ FileAppender<Object> appender = new FileAppender<Object>();
+ appender.setEncoder(new DummyEncoder<Object>());
+ appender.setAppend(false);
+ appender.setFile(filename);
+ appender.setName("testCreateParentFolders");
+ appender.setContext(context);
+ appender.start();
+ appender.doAppend(new Object());
+ appender.stop();
+ assertFalse(FileUtil.isParentDirectoryCreationRequired(file));
+ assertTrue(file.exists());
+
+ // cleanup
+ assertTrue("failed to delete " + file.getAbsolutePath(), file.delete());
+ File parent = file.getParentFile();
+ assertTrue("failed to delete " + parent.getAbsolutePath(), parent.delete());
+ }
+
+ @Test
+ public void testPrudentModeLogicalImplications() {
+ String filename = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "fat-testPrudentModeLogicalImplications.txt";
+ File file = new File(filename);
+ FileAppender<Object> appender = new FileAppender<Object>();
+ appender.setEncoder(new DummyEncoder<Object>());
+ appender.setFile(filename);
+ appender.setName("testPrudentModeLogicalImplications");
+ appender.setContext(context);
+
+ appender.setAppend(false);
+ appender.setPrudent(true);
+ appender.start();
+
+ assertTrue(appender.isAppend());
+
+ StatusManager sm = context.getStatusManager();
+ //StatusPrinter.print(context);
+ StatusChecker statusChecker = new StatusChecker(context);
+ assertEquals(Status.WARN, statusChecker.getHighestLevel(0));
+ List<Status> statusList = sm.getCopyOfStatusList();
+ assertTrue("Expecting status list size to be 2 or larger, but was "
+ + statusList.size(), statusList.size() >= 2);
+ String msg1 = statusList.get(1).getMessage();
+
+ assertTrue("Got message [" + msg1 + "]", msg1
+ .startsWith("Setting \"Append\" property"));
+
+ appender.doAppend(new Object());
+ appender.stop();
+ assertTrue(file.exists());
+ assertTrue("failed to delete " + file.getAbsolutePath(), file.delete());
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/appender/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/appender/PackageTest.java
index f1e4607..316a587 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/appender/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/appender/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,7 +16,11 @@ package ch.qos.logback.core.appender;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
+
@RunWith(Suite.class)
- at Suite.SuiteClasses({ DummyAppenderTest.class, ConsoleAppenderTest.class, FileAppenderTest.class })
+ at Suite.SuiteClasses({DummyAppenderTest.class,
+ ConsoleAppenderTest.class,
+ FileAppenderTest.class})
+
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/appender/XTeeOutputStream.java b/logback-core/src/test/java/ch/qos/logback/core/appender/XTeeOutputStream.java
index 344253c..be99c56 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/appender/XTeeOutputStream.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/appender/XTeeOutputStream.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,19 +20,19 @@ import ch.qos.logback.core.util.TeeOutputStream;
public class XTeeOutputStream extends TeeOutputStream {
- boolean closed = false;
+ boolean closed = false;
+ public XTeeOutputStream(PrintStream targetPS) {
+ super(targetPS);
+ }
- public XTeeOutputStream(PrintStream targetPS) {
- super(targetPS);
- }
-
- @Override
- public void close() throws IOException {
- closed = true;
- super.close();
- }
-
- public boolean isClosed() {
- return closed;
- }
+ @Override
+ public void close() throws IOException {
+ closed = true;
+ super.close();
+ }
+
+
+ public boolean isClosed() {
+ return closed;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/boolex/MatcherTest.java b/logback-core/src/test/java/ch/qos/logback/core/boolex/MatcherTest.java
index 5b807d3..938c72c 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/boolex/MatcherTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/boolex/MatcherTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,59 +19,59 @@ import ch.qos.logback.core.ContextBase;
public class MatcherTest extends TestCase {
- Context context;
- Matcher matcher;
-
- public void setUp() throws Exception {
- context = new ContextBase();
- matcher = new Matcher();
- matcher.setContext(context);
- matcher.setName("testMatcher");
- super.setUp();
- }
-
- public void tearDown() throws Exception {
- matcher = null;
- super.tearDown();
- }
-
- public void testFullRegion() throws Exception {
- matcher.setRegex(".*test.*");
- matcher.start();
- assertTrue(matcher.matches("test"));
- assertTrue(matcher.matches("xxxxtest"));
- assertTrue(matcher.matches("testxxxx"));
- assertTrue(matcher.matches("xxxxtestxxxx"));
- }
-
- public void testPartRegion() throws Exception {
- matcher.setRegex("test");
- matcher.start();
- assertTrue(matcher.matches("test"));
- assertTrue(matcher.matches("xxxxtest"));
- assertTrue(matcher.matches("testxxxx"));
- assertTrue(matcher.matches("xxxxtestxxxx"));
- }
-
- public void testCaseInsensitive() throws Exception {
- matcher.setRegex("test");
- matcher.setCaseSensitive(false);
- matcher.start();
-
- assertTrue(matcher.matches("TEST"));
- assertTrue(matcher.matches("tEst"));
- assertTrue(matcher.matches("tESt"));
- assertTrue(matcher.matches("TesT"));
- }
-
- public void testCaseSensitive() throws Exception {
- matcher.setRegex("test");
- matcher.setCaseSensitive(true);
- matcher.start();
-
- assertFalse(matcher.matches("TEST"));
- assertFalse(matcher.matches("tEst"));
- assertFalse(matcher.matches("tESt"));
- assertFalse(matcher.matches("TesT"));
- }
+ Context context;
+ Matcher matcher;
+
+ public void setUp() throws Exception {
+ context = new ContextBase();
+ matcher = new Matcher();
+ matcher.setContext(context);
+ matcher.setName("testMatcher");
+ super.setUp();
+ }
+
+ public void tearDown() throws Exception {
+ matcher = null;
+ super.tearDown();
+ }
+
+ public void testFullRegion() throws Exception {
+ matcher.setRegex(".*test.*");
+ matcher.start();
+ assertTrue(matcher.matches("test"));
+ assertTrue(matcher.matches("xxxxtest"));
+ assertTrue(matcher.matches("testxxxx"));
+ assertTrue(matcher.matches("xxxxtestxxxx"));
+ }
+
+ public void testPartRegion() throws Exception {
+ matcher.setRegex("test");
+ matcher.start();
+ assertTrue(matcher.matches("test"));
+ assertTrue(matcher.matches("xxxxtest"));
+ assertTrue(matcher.matches("testxxxx"));
+ assertTrue(matcher.matches("xxxxtestxxxx"));
+ }
+
+ public void testCaseInsensitive() throws Exception {
+ matcher.setRegex("test");
+ matcher.setCaseSensitive(false);
+ matcher.start();
+
+ assertTrue(matcher.matches("TEST"));
+ assertTrue(matcher.matches("tEst"));
+ assertTrue(matcher.matches("tESt"));
+ assertTrue(matcher.matches("TesT"));
+ }
+
+ public void testCaseSensitive() throws Exception {
+ matcher.setRegex("test");
+ matcher.setCaseSensitive(true);
+ matcher.start();
+
+ assertFalse(matcher.matches("TEST"));
+ assertFalse(matcher.matches("tEst"));
+ assertFalse(matcher.matches("tESt"));
+ assertFalse(matcher.matches("TesT"));
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/contention/AbstractMultiThreadedHarness.java b/logback-core/src/test/java/ch/qos/logback/core/contention/AbstractMultiThreadedHarness.java
index 3a433d5..a8526b3 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/contention/AbstractMultiThreadedHarness.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/contention/AbstractMultiThreadedHarness.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,27 +15,28 @@ package ch.qos.logback.core.contention;
abstract public class AbstractMultiThreadedHarness {
- RunnableWithCounterAndDone[] runnableArray;
+ RunnableWithCounterAndDone[] runnableArray;
- abstract public void waitUntilEndCondition() throws InterruptedException;
+ abstract void waitUntilEndCondition() throws InterruptedException;
- public void execute(RunnableWithCounterAndDone[] runnableArray) throws InterruptedException {
- this.runnableArray = runnableArray;
- Thread[] threadArray = new Thread[runnableArray.length];
+ public void execute(RunnableWithCounterAndDone[] runnableArray)
+ throws InterruptedException {
+ this.runnableArray = runnableArray;
+ Thread[] threadArray = new Thread[runnableArray.length];
- for (int i = 0; i < runnableArray.length; i++) {
- threadArray[i] = new Thread(runnableArray[i], "Harness[" + i + "]");
- }
- for (Thread t : threadArray) {
- t.start();
- }
+ for (int i = 0; i < runnableArray.length; i++) {
+ threadArray[i] = new Thread(runnableArray[i], "Harness["+i+"]");
+ }
+ for (Thread t : threadArray) {
+ t.start();
+ }
- waitUntilEndCondition();
- for (RunnableWithCounterAndDone r : runnableArray) {
- r.setDone(true);
- }
- for (Thread t : threadArray) {
- t.join();
- }
+ waitUntilEndCondition();
+ for (RunnableWithCounterAndDone r : runnableArray) {
+ r.setDone(true);
+ }
+ for (Thread t : threadArray) {
+ t.join();
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/contention/MultiThreadedHarness.java b/logback-core/src/test/java/ch/qos/logback/core/contention/MultiThreadedHarness.java
index eb5f649..792f62b 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/contention/MultiThreadedHarness.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/contention/MultiThreadedHarness.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.contention;
+
/**
* Useful scaffolding/harness to start and processPriorToRemoval multiple threads.
*
@@ -22,22 +23,27 @@ package ch.qos.logback.core.contention;
*/
public class MultiThreadedHarness extends AbstractMultiThreadedHarness {
- final long overallDurationInMillis;
+ final long overallDurationInMillis;
- public MultiThreadedHarness(long overallDurationInMillis) {
- this.overallDurationInMillis = overallDurationInMillis;
- }
+ public MultiThreadedHarness(long overallDurationInMillis) {
+ this.overallDurationInMillis = overallDurationInMillis;
+ }
- public void printEnvironmentInfo(String msg) {
- System.out.println("=== " + msg + " ===");
- System.out.println("java.runtime.version = " + System.getProperty("java.runtime.version"));
- System.out.println("java.vendor = " + System.getProperty("java.vendor"));
- System.out.println("java.version = " + System.getProperty("java.version"));
- System.out.println("os.name = " + System.getProperty("os.name"));
- System.out.println("os.version = " + System.getProperty("os.version"));
- }
+ public void printEnvironmentInfo(String msg) {
+ System.out.println("=== " + msg + " ===");
+ System.out.println("java.runtime.version = "
+ + System.getProperty("java.runtime.version"));
+ System.out.println("java.vendor = "
+ + System.getProperty("java.vendor"));
+ System.out.println("java.version = "
+ + System.getProperty("java.version"));
+ System.out.println("os.name = "
+ + System.getProperty("os.name"));
+ System.out.println("os.version = "
+ + System.getProperty("os.version"));
+ }
- public void waitUntilEndCondition() throws InterruptedException {
- Thread.sleep(overallDurationInMillis);
- }
+ void waitUntilEndCondition() throws InterruptedException {
+ Thread.sleep(overallDurationInMillis);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/contention/RunnableWithCounterAndDone.java b/logback-core/src/test/java/ch/qos/logback/core/contention/RunnableWithCounterAndDone.java
index b0997ee..1e1993c 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/contention/RunnableWithCounterAndDone.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/contention/RunnableWithCounterAndDone.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,19 +21,19 @@ package ch.qos.logback.core.contention;
*/
abstract public class RunnableWithCounterAndDone implements Runnable {
- protected boolean done = false;
- protected long counter = 0;
+ protected boolean done = false;
+ protected long counter = 0;
+
+ public long getCounter() {
+ return counter;
+ }
- public long getCounter() {
- return counter;
- }
-
- public void setDone(boolean done) {
- this.done = done;
- }
-
- public boolean isDone() {
- return done;
- }
+ public void setDone(boolean done) {
+ this.done = done;
+ }
+ public boolean isDone() {
+ return done;
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/contention/ThreadedThroughputCalculator.java b/logback-core/src/test/java/ch/qos/logback/core/contention/ThreadedThroughputCalculator.java
index af41148..3149a43 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/contention/ThreadedThroughputCalculator.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/contention/ThreadedThroughputCalculator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.contention;
+
/**
* Useful scaffolding to measure the throughput of certain operations when
* invoked by multiple threads.
@@ -23,23 +24,25 @@ package ch.qos.logback.core.contention;
*/
public class ThreadedThroughputCalculator extends MultiThreadedHarness {
- public ThreadedThroughputCalculator(long overallDurationInMillis) {
- super(overallDurationInMillis);
- }
-
- public void printThroughput(String msg) throws InterruptedException {
- printThroughput(msg, false);
- }
- public void printThroughput(String msg, boolean detailed) throws InterruptedException {
- long sum = 0;
- for (RunnableWithCounterAndDone r : runnableArray) {
- if (detailed) {
- System.out.println(r + " count=" + r.getCounter());
- }
- sum += r.getCounter();
- }
+ public ThreadedThroughputCalculator(long overallDurationInMillis) {
+ super(overallDurationInMillis);
+ }
- System.out.println(msg + "total of " + sum + " operations, or " + ((sum) / overallDurationInMillis) + " operations per millisecond");
+ public void printThroughput(String msg) throws InterruptedException {
+ printThroughput(msg, false);
+ }
+
+ public void printThroughput(String msg, boolean detailed) throws InterruptedException {
+ long sum = 0;
+ for (RunnableWithCounterAndDone r : runnableArray) {
+ if(detailed) {
+ System.out.println(r +" count="+r.getCounter());
+ }
+ sum += r.getCounter();
}
+
+ System.out.println(msg + "total of " + sum + " operations, or "
+ + ((sum) / overallDurationInMillis) + " operations per millisecond");
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/contention/WaitOnExecutionMultiThreadedHarness.java b/logback-core/src/test/java/ch/qos/logback/core/contention/WaitOnExecutionMultiThreadedHarness.java
index cd128a8..e9b87e4 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/contention/WaitOnExecutionMultiThreadedHarness.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/contention/WaitOnExecutionMultiThreadedHarness.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,11 +24,10 @@ public class WaitOnExecutionMultiThreadedHarness extends AbstractMultiThreadedHa
this.count = count;
}
-
@Override
- public void waitUntilEndCondition() throws InterruptedException {
- while (threadPoolExecutor.getCompletedTaskCount() < count) {
- Thread.yield();
- }
+ void waitUntilEndCondition() throws InterruptedException {
+ while(threadPoolExecutor.getCompletedTaskCount() < count) {
+ Thread.yield();
+ }
}
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/encoder/ByteArrayUtilTest.java b/logback-core/src/test/java/ch/qos/logback/core/encoder/ByteArrayUtilTest.java
index 41620ac..56f28cf 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/encoder/ByteArrayUtilTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/encoder/ByteArrayUtilTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,33 +21,33 @@ import org.junit.Test;
public class ByteArrayUtilTest {
- int BA_SIZE = 16;
- byte[] byteArray = new byte[BA_SIZE];
-
- Random random = new Random(18532235);
-
- @Test
- public void smoke() {
- verifyLoop(byteArray, 0, 0);
- verifyLoop(byteArray, 0, 10);
- verifyLoop(byteArray, 0, Integer.MAX_VALUE);
- verifyLoop(byteArray, 0, Integer.MIN_VALUE);
- }
-
- @Test
- public void random() {
- for (int i = 0; i < 100000; i++) {
- int rOffset = random.nextInt(BA_SIZE - 4);
- int rInt = random.nextInt();
- verifyLoop(byteArray, rOffset, rInt);
- }
- }
-
- void verifyLoop(byte[] ba, int offset, int expected) {
- ByteArrayUtil.writeInt(byteArray, offset, expected);
- int back = ByteArrayUtil.readInt(byteArray, offset);
- assertEquals(expected, back);
-
+ int BA_SIZE = 16;
+ byte[] byteArray = new byte[BA_SIZE];
+
+ Random random = new Random(18532235);
+
+ @Test
+ public void smoke() {
+ verifyLoop(byteArray, 0, 0);
+ verifyLoop(byteArray, 0, 10);
+ verifyLoop(byteArray, 0, Integer.MAX_VALUE);
+ verifyLoop(byteArray, 0, Integer.MIN_VALUE);
+ }
+
+ @Test
+ public void random() {
+ for(int i = 0; i < 100000; i++) {
+ int rOffset = random.nextInt(BA_SIZE-4);
+ int rInt = random.nextInt();
+ verifyLoop(byteArray, rOffset, rInt);
}
+ }
+
+ void verifyLoop(byte[] ba, int offset, int expected) {
+ ByteArrayUtil.writeInt(byteArray, offset, expected);
+ int back = ByteArrayUtil.readInt(byteArray, offset);
+ assertEquals(expected, back);
+
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/encoder/DummyEncoder.java b/logback-core/src/test/java/ch/qos/logback/core/encoder/DummyEncoder.java
index 385bfc9..58669ee 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/encoder/DummyEncoder.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/encoder/DummyEncoder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,87 +20,87 @@ import ch.qos.logback.core.CoreConstants;
public class DummyEncoder<E> extends EncoderBase<E> {
- public static final String DUMMY = "dummy" + CoreConstants.LINE_SEPARATOR;
- String val = DUMMY;
- String fileHeader;
- String fileFooter;
- String encodingName;
+ public static final String DUMMY = "dummy" + CoreConstants.LINE_SEPARATOR;
+ String val = DUMMY;
+ String fileHeader;
+ String fileFooter;
+ String encodingName;
- public String getEncodingName() {
- return encodingName;
- }
+ public String getEncodingName() {
+ return encodingName;
+ }
- public void setEncodingName(String encodingName) {
- this.encodingName = encodingName;
- }
+ public void setEncodingName(String encodingName) {
+ this.encodingName = encodingName;
+ }
- public DummyEncoder() {
- }
+ public DummyEncoder() {
+ }
- public DummyEncoder(String val) {
- this.val = val;
- }
+ public DummyEncoder(String val) {
+ this.val = val;
+ }
- public void doEncode(E event) throws IOException {
- writeOut(val);
- }
+ public void doEncode(E event) throws IOException {
+ writeOut(val);
+ }
- private void appendIfNotNull(StringBuilder sb, String s) {
- if (s != null) {
- sb.append(s);
- }
+ private void appendIfNotNull(StringBuilder sb, String s) {
+ if (s != null) {
+ sb.append(s);
}
+ }
- void writeOut(String s) throws IOException {
- if (encodingName == null) {
- outputStream.write(s.getBytes());
- } else {
- outputStream.write(s.getBytes(encodingName));
- }
+ void writeOut(String s) throws IOException {
+ if (encodingName == null) {
+ outputStream.write(s.getBytes());
+ } else {
+ outputStream.write(s.getBytes(encodingName));
}
-
- void writeHeader() throws IOException {
- StringBuilder sb = new StringBuilder();
- appendIfNotNull(sb, fileHeader);
- if (sb.length() > 0) {
- sb.append(CoreConstants.LINE_SEPARATOR);
- // If at least one of file header or presentation header were not
- // null, then append a line separator.
- // This should be useful in most cases and should not hurt.
- writeOut(sb.toString());
- }
+ }
+
+ void writeHeader() throws IOException {
+ StringBuilder sb = new StringBuilder();
+ appendIfNotNull(sb, fileHeader);
+ if (sb.length() > 0) {
+ sb.append(CoreConstants.LINE_SEPARATOR);
+ // If at least one of file header or presentation header were not
+ // null, then append a line separator.
+ // This should be useful in most cases and should not hurt.
+ writeOut(sb.toString());
}
+ }
- public void init(OutputStream os) throws IOException {
- super.init(os);
- writeHeader();
- }
+ public void init(OutputStream os) throws IOException {
+ super.init(os);
+ writeHeader();
+ }
- public void close() throws IOException {
- if (fileFooter == null) {
- return;
- }
- if (encodingName == null) {
- outputStream.write(fileFooter.getBytes());
- } else {
- outputStream.write(fileFooter.getBytes(encodingName));
- }
+ public void close() throws IOException {
+ if (fileFooter == null) {
+ return;
}
-
- public String getFileHeader() {
- return fileHeader;
+ if (encodingName == null) {
+ outputStream.write(fileFooter.getBytes());
+ } else {
+ outputStream.write(fileFooter.getBytes(encodingName));
}
+ }
- public void setFileHeader(String fileHeader) {
- this.fileHeader = fileHeader;
- }
+ public String getFileHeader() {
+ return fileHeader;
+ }
- public String getFileFooter() {
- return fileFooter;
- }
+ public void setFileHeader(String fileHeader) {
+ this.fileHeader = fileHeader;
+ }
- public void setFileFooter(String fileFooter) {
- this.fileFooter = fileFooter;
- }
+ public String getFileFooter() {
+ return fileFooter;
+ }
+
+ public void setFileFooter(String fileFooter) {
+ this.fileFooter = fileFooter;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/encoder/NopEncoder.java b/logback-core/src/test/java/ch/qos/logback/core/encoder/NopEncoder.java
index eab6ab0..e36da99 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/encoder/NopEncoder.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/encoder/NopEncoder.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,13 +17,13 @@ import java.io.IOException;
import java.io.OutputStream;
public class NopEncoder<E> extends EncoderBase<E> {
+
+ public void close() throws IOException {
+ }
- public void close() throws IOException {
- }
+ public void doEncode(E event) throws IOException {
+ }
- public void doEncode(E event) throws IOException {
- }
-
- public void init(OutputStream os) throws IOException {
- }
+ public void init(OutputStream os) throws IOException {
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/encoder/ObjectEncodeDecodeTest.java b/logback-core/src/test/java/ch/qos/logback/core/encoder/ObjectEncodeDecodeTest.java
index 9a78b2a..586e0ee 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/encoder/ObjectEncodeDecodeTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/encoder/ObjectEncodeDecodeTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,63 +30,65 @@ import ch.qos.logback.core.util.CoreTestConstants;
public class ObjectEncodeDecodeTest {
- ObjectStreamEncoder<String> encoder = new ObjectStreamEncoder<String>();
- EventObjectInputStream<String> eventStream;
+ ObjectStreamEncoder<String> encoder = new ObjectStreamEncoder<String>();
+ EventObjectInputStream<String> eventStream;
- int diff = RandomUtil.getPositiveInt();
- protected String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "/";
+ int diff = RandomUtil.getPositiveInt();
+ protected String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff
+ + "/";
- @Before
- public void setUp() {
- File randomOupurDirFile = new File(randomOutputDir);
- randomOupurDirFile.mkdirs();
- }
+ @Before
+ public void setUp() {
+ File randomOupurDirFile = new File(randomOutputDir);
+ randomOupurDirFile.mkdirs();
+ }
- void encodeList(File file, List<String> list) throws IOException {
- FileOutputStream fos = new FileOutputStream(file);
- encoder.init(fos);
- for (String s : list) {
- encoder.doEncode(s);
- }
- encoder.close();
- fos.close();
+ void encodeList(File file, List<String> list) throws IOException {
+ FileOutputStream fos = new FileOutputStream(file);
+ encoder.init(fos);
+ for (String s: list) {
+ encoder.doEncode(s);
}
-
- List<String> decodeList(File file) throws IOException {
- FileInputStream fis = new FileInputStream(file);
- eventStream = new EventObjectInputStream<String>(fis);
- List<String> back = new ArrayList<String>();
- String e;
- while ((e = eventStream.readEvent()) != null) {
- back.add(e);
- }
- return back;
+ encoder.close();
+ fos.close();
+ }
+
+
+ List<String> decodeList(File file) throws IOException {
+ FileInputStream fis = new FileInputStream(file);
+ eventStream = new EventObjectInputStream<String>(fis);
+ List<String> back = new ArrayList<String>();
+ String e;
+ while((e=eventStream.readEvent()) != null) {
+ back.add(e);
}
+ return back;
+ }
- @Test
- public void singleBatch() throws IOException {
- File file = new File(randomOutputDir + "x.lbo");
+ @Test
+ public void singleBatch() throws IOException {
+ File file = new File(randomOutputDir + "x.lbo");
- List<String> witness = new ArrayList<String>();
- for (int i = 0; i < 10; i++) {
- witness.add("hello" + i);
- }
- encodeList(file, witness);
- List<String> back = decodeList(file);
- assertEquals(witness, back);
+ List<String> witness = new ArrayList<String>();
+ for (int i = 0; i < 10; i++) {
+ witness.add("hello" + i);
}
+ encodeList(file, witness);
+ List<String> back = decodeList(file);
+ assertEquals(witness, back);
+ }
- @Test
- public void multipleBatches() throws IOException {
- File file = new File(randomOutputDir + "m.lbo");
+ @Test
+ public void multipleBatches() throws IOException {
+ File file = new File(randomOutputDir + "m.lbo");
- List<String> witness = new ArrayList<String>();
- for (int i = 0; i < 100 * 10; i++) {
- witness.add("hello" + i);
- }
- encodeList(file, witness);
- List<String> back = decodeList(file);
- assertEquals(witness, back);
+ List<String> witness = new ArrayList<String>();
+ for (int i = 0; i < 100*10; i++) {
+ witness.add("hello" + i);
}
+ encodeList(file, witness);
+ List<String> back = decodeList(file);
+ assertEquals(witness, back);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/encoder/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/encoder/PackageTest.java
index fb54a8f..1c32e3e 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/encoder/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/encoder/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,6 +17,6 @@ import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
- at Suite.SuiteClasses({ ByteArrayUtilTest.class, ObjectEncodeDecodeTest.class })
+ at Suite.SuiteClasses( { ByteArrayUtilTest.class, ObjectEncodeDecodeTest.class })
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/helpers/CyclicBufferTest.java b/logback-core/src/test/java/ch/qos/logback/core/helpers/CyclicBufferTest.java
index 08713b6..103059c 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/helpers/CyclicBufferTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/helpers/CyclicBufferTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,39 +22,40 @@ import static org.junit.Assert.assertEquals;
public class CyclicBufferTest {
- void assertSize(CyclicBuffer<String> cb, int size) {
- assertEquals(size, cb.length());
- }
-
- @Test
- public void smoke() {
- CyclicBuffer<String> cb = new CyclicBuffer<String>(2);
- assertSize(cb, 0);
- cb.add("zero");
- assertSize(cb, 1);
- cb.add("one");
- assertSize(cb, 2);
- cb.add("two");
- assertSize(cb, 2);
- assertEquals("one", cb.get());
- assertSize(cb, 1);
- assertEquals("two", cb.get());
- assertSize(cb, 0);
- }
-
- @Test
- public void cloning() {
- CyclicBuffer<String> cb = new CyclicBuffer<String>(2);
- cb.add("zero");
- cb.add("one");
-
- CyclicBuffer<String> clone = new CyclicBuffer<String>(cb);
- assertSize(clone, 2);
- cb.clear();
- assertSize(cb, 0);
-
- List<String> witness = Arrays.asList("zero", "one");
- assertEquals(witness, clone.asList());
-
- }
+
+ void assertSize(CyclicBuffer<String> cb, int size) {
+ assertEquals(size, cb.length());
+ }
+ @Test
+ public void smoke() {
+ CyclicBuffer<String> cb = new CyclicBuffer<String>(2);
+ assertSize(cb, 0);
+ cb.add("zero");
+ assertSize(cb, 1);
+ cb.add("one");
+ assertSize(cb, 2);
+ cb.add("two");
+ assertSize(cb, 2);
+ assertEquals("one", cb.get());
+ assertSize(cb, 1);
+ assertEquals("two",cb.get());
+ assertSize(cb, 0);
+ }
+
+
+ @Test
+ public void cloning() {
+ CyclicBuffer<String> cb = new CyclicBuffer<String>(2);
+ cb.add("zero");
+ cb.add("one");
+
+ CyclicBuffer<String> clone = new CyclicBuffer<String>(cb);
+ assertSize(clone, 2);
+ cb.clear();
+ assertSize(cb, 0);
+
+ List<String> witness = Arrays.asList("zero", "one");
+ assertEquals(witness, clone.asList());
+
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/helpers/FileFilterUtilTest.java b/logback-core/src/test/java/ch/qos/logback/core/helpers/FileFilterUtilTest.java
index 463cf6e..6ab8f26 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/helpers/FileFilterUtilTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/helpers/FileFilterUtilTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,27 +27,30 @@ import static junit.framework.Assert.assertEquals;
public class FileFilterUtilTest {
- Context context = new ContextBase();
-
- // see also http://jira.qos.ch/browse/LBCORE-164
- @Test
- public void findHighestCounterTest() throws ParseException {
- String[] sa = new String[] { "c:/log/debug-old-2010-08-10.0.log", "c:/log/debug-old-2010-08-10.1.log", "c:/log/debug-old-2010-08-10.10.log",
- "c:/log/debug-old-2010-08-10.11.log", "c:/log/debug-old-2010-08-10.12.log", "c:/log/debug-old-2010-08-10.2.log",
- "c:/log/debug-old-2010-08-10.3.log", "c:/log/debug-old-2010-08-10.4.log", "c:/log/debug-old-2010-08-10.5.log",
- "c:/log/debug-old-2010-08-10.6.log", "c:/log/debug-old-2010-08-10.7.log", "c:/log/debug-old-2010-08-10.8.log",
- "c:/log/debug-old-2010-08-10.9.log" };
-
- File[] matchingFileArray = new File[sa.length];
- for (int i = 0; i < sa.length; i++) {
- matchingFileArray[i] = new File(sa[i]);
- }
- FileNamePattern fnp = new FileNamePattern("c:/log/debug-old-%d{yyyy-MM-dd}.%i.log", context);
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
- String rexexp = null;
- rexexp = fnp.toRegexForFixedDate(sdf.parse("2010-08-10"));
- String stemRegex = FileFilterUtil.afterLastSlash(rexexp);
- int result = FileFilterUtil.findHighestCounter(matchingFileArray, stemRegex);
- assertEquals(12, result);
+
+ Context context = new ContextBase();
+
+ // see also http://jira.qos.ch/browse/LBCORE-164
+ @Test
+ public void findHighestCounterTest() throws ParseException {
+ String[] sa = new String[]{"c:/log/debug-old-2010-08-10.0.log",
+ "c:/log/debug-old-2010-08-10.1.log", "c:/log/debug-old-2010-08-10.10.log",
+ "c:/log/debug-old-2010-08-10.11.log", "c:/log/debug-old-2010-08-10.12.log",
+ "c:/log/debug-old-2010-08-10.2.log", "c:/log/debug-old-2010-08-10.3.log",
+ "c:/log/debug-old-2010-08-10.4.log", "c:/log/debug-old-2010-08-10.5.log",
+ "c:/log/debug-old-2010-08-10.6.log", "c:/log/debug-old-2010-08-10.7.log",
+ "c:/log/debug-old-2010-08-10.8.log", "c:/log/debug-old-2010-08-10.9.log"};
+
+ File[] matchingFileArray = new File[sa.length];
+ for (int i = 0; i < sa.length; i++) {
+ matchingFileArray[i] = new File(sa[i]);
}
+ FileNamePattern fnp = new FileNamePattern("c:/log/debug-old-%d{yyyy-MM-dd}.%i.log", context);
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ String rexexp = null;
+ rexexp = fnp.toRegexForFixedDate(sdf.parse("2010-08-10"));
+ String stemRegex = FileFilterUtil.afterLastSlash(rexexp);
+ int result = FileFilterUtil.findHighestCounter(matchingFileArray, stemRegex);
+ assertEquals(12, result);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/helpers/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/helpers/PackageTest.java
index f127a7c..029c8b4 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/helpers/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/helpers/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,7 +19,7 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ ThrowableToStringArrayTest.class, FileUtilTest.class, CyclicBufferTest.class })
+ at SuiteClasses({ThrowableToStringArrayTest.class, FileUtilTest.class, CyclicBufferTest.class})
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/helpers/ThrowableToStringArrayTest.java b/logback-core/src/test/java/ch/qos/logback/core/helpers/ThrowableToStringArrayTest.java
index da7c6a3..20cddc9 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/helpers/ThrowableToStringArrayTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/helpers/ThrowableToStringArrayTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,68 +26,68 @@ import ch.qos.logback.core.CoreConstants;
public class ThrowableToStringArrayTest {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
- @Before
- public void setUp() throws Exception {
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
- public void verify(Throwable t) {
- t.printStackTrace(pw);
+ @Before
+ public void setUp() throws Exception {
+ }
- String[] sa = ThrowableToStringArray.convert(t);
- StringBuilder sb = new StringBuilder();
- for (String tdp : sa) {
- sb.append(tdp);
- sb.append(CoreConstants.LINE_SEPARATOR);
- }
- String expected = sw.toString();
- String result = sb.toString().replace("common frames omitted", "more");
- assertEquals(expected, result);
- }
-
- @Test
- public void smoke() {
- Exception e = new Exception("smoke");
- verify(e);
- }
+ @After
+ public void tearDown() throws Exception {
+ }
- @Test
- public void nested() {
- Exception w = null;
- try {
- someMethod();
- } catch (Exception e) {
- w = new Exception("wrapping", e);
- }
- verify(w);
+ public void verify(Throwable t) {
+ t.printStackTrace(pw);
+
+ String[] sa = ThrowableToStringArray.convert(t);
+ StringBuilder sb = new StringBuilder();
+ for (String tdp : sa) {
+ sb.append(tdp);
+ sb.append(CoreConstants.LINE_SEPARATOR);
}
+ String expected = sw.toString();
+ String result = sb.toString().replace("common frames omitted", "more");
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void smoke() {
+ Exception e = new Exception("smoke");
+ verify(e);
+ }
- @Test
- public void multiNested() {
- Exception w = null;
- try {
- someOtherMethod();
- } catch (Exception e) {
- w = new Exception("wrapping", e);
- }
- verify(w);
+ @Test
+ public void nested() {
+ Exception w = null;
+ try {
+ someMethod();
+ } catch (Exception e) {
+ w = new Exception("wrapping", e);
}
+ verify(w);
+ }
- void someMethod() throws Exception {
- throw new Exception("someMethod");
+ @Test
+ public void multiNested() {
+ Exception w = null;
+ try {
+ someOtherMethod();
+ } catch (Exception e) {
+ w = new Exception("wrapping", e);
}
+ verify(w);
+ }
+
+ void someMethod() throws Exception {
+ throw new Exception("someMethod");
+ }
- void someOtherMethod() throws Exception {
- try {
- someMethod();
- } catch (Exception e) {
- throw new Exception("someOtherMethod", e);
- }
+ void someOtherMethod() throws Exception {
+ try {
+ someMethod();
+ } catch (Exception e) {
+ throw new Exception("someOtherMethod", e);
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/issue/LBCORE97.java b/logback-core/src/test/java/ch/qos/logback/core/issue/LBCORE97.java
index 56b934c..36de894 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/issue/LBCORE97.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/issue/LBCORE97.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,155 +24,168 @@ import java.util.concurrent.locks.ReentrantLock;
*/
public class LBCORE97 {
- static int THREAD_COUNT = 10;
-
- public static void main(String args[]) throws InterruptedException {
-
- System.out.println("Environment:");
- System.out.println("java.runtime.name = " + System.getProperty("java.runtime.name"));
- System.out.println("java.runtime.version = " + System.getProperty("java.runtime.version"));
- System.out.println("java.vendor = " + System.getProperty("java.vendor"));
- System.out.println("java.version = " + System.getProperty("java.version"));
- System.out.println("java.vm.name = " + System.getProperty("java.vm.name"));
- System.out.println("java.vm.info = " + System.getProperty("java.vm.info"));
-
- System.out.println("os.name = " + System.getProperty("os.name"));
- System.out.println("os.version = " + System.getProperty("os.version"));
- System.out.println("os.arch = " + System.getProperty("os.arch"));
- System.out.println("##########################################");
-
- usingSynchronized(THREAD_COUNT);
- usingUnfairLock(THREAD_COUNT);
- usingFairLock(THREAD_COUNT);
+ static int THREAD_COUNT = 10;
+
+ public static void main(String args[]) throws InterruptedException {
+
+ System.out.println("Environment:");
+ System.out.println("java.runtime.name = "
+ + System.getProperty("java.runtime.name"));
+ System.out.println("java.runtime.version = "
+ + System.getProperty("java.runtime.version"));
+ System.out.println("java.vendor = "
+ + System.getProperty("java.vendor"));
+ System.out.println("java.version = "
+ + System.getProperty("java.version"));
+ System.out.println("java.vm.name = "
+ + System.getProperty("java.vm.name"));
+ System.out.println("java.vm.info = "
+ + System.getProperty("java.vm.info"));
+
+ System.out.println("os.name = "
+ + System.getProperty("os.name"));
+ System.out.println("os.version = "
+ + System.getProperty("os.version"));
+ System.out.println("os.arch = "
+ + System.getProperty("os.arch"));
+ System.out.println("##########################################");
+
+ usingSynchronized(THREAD_COUNT);
+ usingUnfairLock(THREAD_COUNT);
+ usingFairLock(THREAD_COUNT);
+ }
+
+ public static void execute(String text, Thread[] threads)
+ throws InterruptedException {
+ System.out.println("About to execute " + text + "...");
+ int threadCount = threads.length;
+ for (int i = 0; i < threadCount; i++) {
+ threads[i].start();
}
- public static void execute(String text, Thread[] threads) throws InterruptedException {
- System.out.println("About to execute " + text + "...");
- int threadCount = threads.length;
- for (int i = 0; i < threadCount; i++) {
- threads[i].start();
- }
-
- Thread.sleep(10000);
+ Thread.sleep(10000);
- for (int i = 0; i < threadCount; i++) {
- threads[i].interrupt();
- }
- Thread.sleep(1000); // wait a moment for termination, to lazy for join ;)
+ for (int i = 0; i < threadCount; i++) {
+ threads[i].interrupt();
}
+ Thread.sleep(1000); // wait a moment for termination, to lazy for join ;)
+ }
- public static void print(String text, Runnable[] runnables) {
- System.out.println("Results for " + text + ":");
- for (int i = 0; i < runnables.length; i++) {
- System.out.println("runnables[" + i + "]: " + runnables[i]);
- }
- System.out.println("##########################################");
+ public static void print(String text, Runnable[] runnables) {
+ System.out.println("Results for " + text + ":");
+ for (int i = 0; i < runnables.length; i++) {
+ System.out.println("runnables[" + i + "]: " + runnables[i]);
}
-
- public static void usingSynchronized(int threadCount) throws InterruptedException {
- Object lockObject = new Object();
- Runnable[] runnables = new Runnable[threadCount];
- Thread[] threads = new Thread[threadCount];
-
- for (int i = 0; i < threadCount; i++) {
- runnables[i] = new SynchronizedRunnable(lockObject);
- threads[i] = new Thread(runnables[i]);
- }
- String text = "usingSynchronized";
- execute(text, threads);
- print(text, runnables);
+ System.out.println("##########################################");
+ }
+
+ public static void usingSynchronized(int threadCount)
+ throws InterruptedException {
+ Object lockObject = new Object();
+ Runnable[] runnables = new Runnable[threadCount];
+ Thread[] threads = new Thread[threadCount];
+
+ for (int i = 0; i < threadCount; i++) {
+ runnables[i] = new SynchronizedRunnable(lockObject);
+ threads[i] = new Thread(runnables[i]);
+ }
+ String text = "usingSynchronized";
+ execute(text, threads);
+ print(text, runnables);
+ }
+
+ public static void usingUnfairLock(int threadCount)
+ throws InterruptedException {
+ Lock lock = new ReentrantLock();
+ Runnable[] runnables = new Runnable[threadCount];
+ Thread[] threads = new Thread[threadCount];
+
+ for (int i = 0; i < threadCount; i++) {
+ runnables[i] = new LockRunnable(lock);
+ threads[i] = new Thread(runnables[i]);
}
- public static void usingUnfairLock(int threadCount) throws InterruptedException {
- Lock lock = new ReentrantLock();
- Runnable[] runnables = new Runnable[threadCount];
- Thread[] threads = new Thread[threadCount];
+ String text = "usingUnfairLock";
+ execute(text, threads);
+ print(text, runnables);
+ }
- for (int i = 0; i < threadCount; i++) {
- runnables[i] = new LockRunnable(lock);
- threads[i] = new Thread(runnables[i]);
- }
+ public static void usingFairLock(int threadCount) throws InterruptedException {
+ Lock lock = new ReentrantLock(true);
+ Runnable[] runnables = new Runnable[threadCount];
+ Thread[] threads = new Thread[threadCount];
- String text = "usingUnfairLock";
- execute(text, threads);
- print(text, runnables);
+ for (int i = 0; i < threadCount; i++) {
+ runnables[i] = new LockRunnable(lock);
+ threads[i] = new Thread(runnables[i]);
}
- public static void usingFairLock(int threadCount) throws InterruptedException {
- Lock lock = new ReentrantLock(true);
- Runnable[] runnables = new Runnable[threadCount];
- Thread[] threads = new Thread[threadCount];
+ String text = "usingFairLock";
+ execute(text, threads);
+ print(text, runnables);
+ }
- for (int i = 0; i < threadCount; i++) {
- runnables[i] = new LockRunnable(lock);
- threads[i] = new Thread(runnables[i]);
- }
+ public static class SynchronizedRunnable implements Runnable {
+ private final Object lockObject;
+ private int counter;
+ private boolean running;
- String text = "usingFairLock";
- execute(text, threads);
- print(text, runnables);
+ public SynchronizedRunnable(Object lockObject) {
+ this.lockObject = lockObject;
+ this.counter = 0;
+ this.running = false;
}
- public static class SynchronizedRunnable implements Runnable {
- private final Object lockObject;
- private int counter;
- private boolean running;
-
- public SynchronizedRunnable(Object lockObject) {
- this.lockObject = lockObject;
- this.counter = 0;
- this.running = false;
- }
-
- public void run() {
- running = true;
- for (;;) {
- synchronized (lockObject) {
- counter++;
- try {
- Thread.sleep(10);
- } catch (InterruptedException ex) {
- break;
- }
- }
- }
- running = false;
+ public void run() {
+ running = true;
+ for (;;) {
+ synchronized (lockObject) {
+ counter++;
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException ex) {
+ break;
+ }
}
+ }
+ running = false;
+ }
- public String toString() {
- return "SynchronizedRunnable[counter=" + counter + ", running=" + running + "]";
- }
+ public String toString() {
+ return "SynchronizedRunnable[counter=" + counter + ", running=" + running
+ + "]";
}
+ }
- public static class LockRunnable implements Runnable {
- private final Lock lock;
- private int counter;
- private boolean running;
+ public static class LockRunnable implements Runnable {
+ private final Lock lock;
+ private int counter;
+ private boolean running;
- public LockRunnable(Lock lock) {
- this.lock = lock;
- this.counter = 0;
- this.running = false;
- }
+ public LockRunnable(Lock lock) {
+ this.lock = lock;
+ this.counter = 0;
+ this.running = false;
+ }
- public void run() {
- running = true;
- for (;;) {
- lock.lock();
- try {
- counter++;
- Thread.sleep(10);
- } catch (InterruptedException ex) {
- break;
- } finally {
- lock.unlock();
- }
- }
- running = false;
+ public void run() {
+ running = true;
+ for (;;) {
+ lock.lock();
+ try {
+ counter++;
+ Thread.sleep(10);
+ } catch (InterruptedException ex) {
+ break;
+ } finally {
+ lock.unlock();
}
+ }
+ running = false;
+ }
- public String toString() {
- return "LockRunnable[counter=" + counter + ", running=" + running + "]";
- }
+ public String toString() {
+ return "LockRunnable[counter=" + counter + ", running=" + running + "]";
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/issue/LOGBACK_849/Basic.java b/logback-core/src/test/java/ch/qos/logback/core/issue/LOGBACK_849/Basic.java
index d6131c8..a07f525 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/issue/LOGBACK_849/Basic.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/issue/LOGBACK_849/Basic.java
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
package ch.qos.logback.core.issue.LOGBACK_849;
import java.util.concurrent.ExecutorService;
@@ -23,51 +10,53 @@ import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.util.ExecutorServiceUtil;
+
public class Basic {
- ExecutorService executor = ExecutorServiceUtil.newScheduledExecutorService();
- Context context = new ContextBase();
+ ExecutorService executor = ExecutorServiceUtil.newExecutorService();
+ Context context = new ContextBase();
- @Test(timeout = 100)
- public void withNoSubmittedTasksShutdownNowShouldReturnImmediately() throws InterruptedException {
- executor.shutdownNow();
- executor.awaitTermination(5000, TimeUnit.MILLISECONDS);
- }
+ @Test(timeout = 100)
+ public void withNoSubmittedTasksShutdownNowShouldReturnImmediately() throws InterruptedException {
+ executor.shutdownNow();
+ executor.awaitTermination(5000, TimeUnit.MILLISECONDS);
+ }
- @Ignore
- @Test
- public void withOneSlowTask() throws InterruptedException {
- executor.execute(new InterruptIgnoring(1000));
- Thread.sleep(100);
- ExecutorServiceUtil.shutdown(executor);
- }
+ @Ignore
+ @Test
+ public void withOneSlowTask() throws InterruptedException {
+ executor.execute(new InterruptIgnoring(1000));
+ Thread.sleep(100);
+ ExecutorServiceUtil.shutdown(executor);
+ }
- // InterruptIgnoring ===========================================
- static class InterruptIgnoring implements Runnable {
+ // InterruptIgnoring ===========================================
+ static class InterruptIgnoring implements Runnable {
- int delay;
+ int delay;
- InterruptIgnoring(int delay) {
- this.delay = delay;
- }
-
- public void run() {
- long runUntil = System.currentTimeMillis() + delay;
+ InterruptIgnoring(int delay) {
+ this.delay = delay;
+ }
- while (true) {
- try {
- long sleep = runUntil - System.currentTimeMillis();
- System.out.println("will sleep " + sleep);
- if (sleep > 0) {
- Thread.currentThread().sleep(delay);
- } else {
- return;
- }
- } catch (InterruptedException e) {
- // ignore the exception
- }
- }
+ public void run() {
+ long runUntil = System.currentTimeMillis() + delay;
+
+ while (true) {
+ try {
+ long sleep = runUntil - System.currentTimeMillis();
+ System.out.println("will sleep " + sleep);
+ if (sleep > 0) {
+ Thread.currentThread().sleep(delay);
+ } else {
+ return;
+ }
+ } catch (InterruptedException e) {
+ // ignore the exception
}
+ }
}
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/issue/LockThroughput.java b/logback-core/src/test/java/ch/qos/logback/core/issue/LockThroughput.java
index 30d15b5..b78b605 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/issue/LockThroughput.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/issue/LockThroughput.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,36 +24,37 @@ import ch.qos.logback.core.issue.SelectiveLockRunnable.LockingModel;
*/
public class LockThroughput {
- static int THREAD_COUNT = 10;
- static long OVERALL_DURATION_IN_MILLIS = 5000;
+ static int THREAD_COUNT = 10;
+ static long OVERALL_DURATION_IN_MILLIS = 5000;
- public static void main(String args[]) throws InterruptedException {
+ public static void main(String args[]) throws InterruptedException {
- ThreadedThroughputCalculator tp = new ThreadedThroughputCalculator(OVERALL_DURATION_IN_MILLIS);
- tp.printEnvironmentInfo("LockThroughput");
+ ThreadedThroughputCalculator tp = new ThreadedThroughputCalculator(
+ OVERALL_DURATION_IN_MILLIS);
+ tp.printEnvironmentInfo("LockThroughput");
- for (int i = 0; i < 2; i++) {
- tp.execute(buildArray(LockingModel.SYNC));
- tp.execute(buildArray(LockingModel.UNFAIR));
- tp.execute(buildArray(LockingModel.FAIR));
- }
-
- tp.execute(buildArray(LockingModel.SYNC));
- tp.printThroughput("Sync: ");
+ for (int i = 0; i < 2; i++) {
+ tp.execute(buildArray(LockingModel.SYNC));
+ tp.execute(buildArray(LockingModel.UNFAIR));
+ tp.execute(buildArray(LockingModel.FAIR));
+ }
+
+ tp.execute(buildArray(LockingModel.SYNC));
+ tp.printThroughput("Sync: ");
- tp.execute(buildArray(LockingModel.UNFAIR));
- tp.printThroughput("Unfair: ");
+ tp.execute(buildArray(LockingModel.UNFAIR));
+ tp.printThroughput("Unfair: ");
- tp.execute(buildArray(LockingModel.FAIR));
- tp.printThroughput("Fair: ");
- }
+ tp.execute(buildArray(LockingModel.FAIR));
+ tp.printThroughput("Fair: ");
+ }
- static SelectiveLockRunnable[] buildArray(LockingModel model) {
- SelectiveLockRunnable[] array = new SelectiveLockRunnable[THREAD_COUNT];
- for (int i = 0; i < THREAD_COUNT; i++) {
- array[i] = new SelectiveLockRunnable(model);
- }
- return array;
+ static SelectiveLockRunnable[] buildArray(LockingModel model) {
+ SelectiveLockRunnable[] array = new SelectiveLockRunnable[THREAD_COUNT];
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ array[i] = new SelectiveLockRunnable(model);
}
+ return array;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/issue/LockingInJava.java b/logback-core/src/test/java/ch/qos/logback/core/issue/LockingInJava.java
index 5db191e..53e0273 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/issue/LockingInJava.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/issue/LockingInJava.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,68 +22,73 @@ package ch.qos.logback.core.issue;
*/
public class LockingInJava implements Runnable {
- static int THREAD_COUNT = 5;
- static Object LOCK = new Object();
- static LockingInJava[] RUNNABLE_ARRAY = new LockingInJava[THREAD_COUNT];
- static Thread[] THREAD_ARRAY = new Thread[THREAD_COUNT];
+ static int THREAD_COUNT = 5;
+ static Object LOCK = new Object();
+ static LockingInJava[] RUNNABLE_ARRAY = new LockingInJava[THREAD_COUNT];
+ static Thread[] THREAD_ARRAY = new Thread[THREAD_COUNT];
- private int counter = 0;
- private boolean done = false;
+ private int counter = 0;
+ private boolean done = false;
+
+ public static void main(String args[]) throws InterruptedException {
+ printEnvironmentInfo();
+ execute();
+ printResults();
+ }
- public static void main(String args[]) throws InterruptedException {
- printEnvironmentInfo();
- execute();
- printResults();
- }
+ public static void printEnvironmentInfo() {
+ System.out.println("java.runtime.version = "
+ + System.getProperty("java.runtime.version"));
+ System.out.println("java.vendor = "
+ + System.getProperty("java.vendor"));
+ System.out.println("java.version = "
+ + System.getProperty("java.version"));
+ System.out.println("os.name = "
+ + System.getProperty("os.name"));
+ System.out.println("os.version = "
+ + System.getProperty("os.version"));
+ }
- public static void printEnvironmentInfo() {
- System.out.println("java.runtime.version = " + System.getProperty("java.runtime.version"));
- System.out.println("java.vendor = " + System.getProperty("java.vendor"));
- System.out.println("java.version = " + System.getProperty("java.version"));
- System.out.println("os.name = " + System.getProperty("os.name"));
- System.out.println("os.version = " + System.getProperty("os.version"));
+ public static void execute() throws InterruptedException {
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ RUNNABLE_ARRAY[i] = new LockingInJava();
+ THREAD_ARRAY[i] = new Thread(RUNNABLE_ARRAY[i]);
}
-
- public static void execute() throws InterruptedException {
- for (int i = 0; i < THREAD_COUNT; i++) {
- RUNNABLE_ARRAY[i] = new LockingInJava();
- THREAD_ARRAY[i] = new Thread(RUNNABLE_ARRAY[i]);
- }
- for (Thread t : THREAD_ARRAY) {
- t.start();
- }
- // let the threads run for a while
- Thread.sleep(10000);
-
- for (int i = THREAD_COUNT - 1; i <= 0; i--) {
- RUNNABLE_ARRAY[i].done = true;
- }
-
+ for (Thread t : THREAD_ARRAY) {
+ t.start();
+ }
+ // let the threads run for a while
+ Thread.sleep(10000);
+
+ for (int i = THREAD_COUNT - 1; i <= 0; i--) {
+ RUNNABLE_ARRAY[i].done = true;
}
+
+ }
- public static void printResults() {
- for (int i = 0; i < RUNNABLE_ARRAY.length; i++) {
- System.out.println("runnable[" + i + "]: " + RUNNABLE_ARRAY[i]);
- }
+ public static void printResults() {
+ for (int i = 0; i < RUNNABLE_ARRAY.length; i++) {
+ System.out.println("runnable[" + i + "]: " + RUNNABLE_ARRAY[i]);
}
+ }
- public void run() {
- for (;;) {
- synchronized (LOCK) {
- counter++;
- try {
- Thread.sleep(10);
- } catch (InterruptedException ex) {
- }
- if (done) {
- return;
- }
- }
+ public void run() {
+ for (;;) {
+ synchronized (LOCK) {
+ counter++;
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException ex) {
}
+ if(done) {
+ return;
+ }
+ }
}
+ }
- public String toString() {
- return "counter=" + counter;
- }
+ public String toString() {
+ return "counter=" + counter;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/issue/NoLockThroughput.java b/logback-core/src/test/java/ch/qos/logback/core/issue/NoLockThroughput.java
index 25dd412..2c2f4fc 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/issue/NoLockThroughput.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/issue/NoLockThroughput.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,28 +24,29 @@ import ch.qos.logback.core.issue.SelectiveLockRunnable.LockingModel;
*/
public class NoLockThroughput {
- static int THREAD_COUNT = 3;
- static long OVERALL_DURATION_IN_MILLIS = 2000;
+ static int THREAD_COUNT = 3;
+ static long OVERALL_DURATION_IN_MILLIS = 2000;
- public static void main(String args[]) throws InterruptedException {
+ public static void main(String args[]) throws InterruptedException {
- ThreadedThroughputCalculator tp = new ThreadedThroughputCalculator(OVERALL_DURATION_IN_MILLIS);
- tp.printEnvironmentInfo("NoLockThroughput");
+ ThreadedThroughputCalculator tp = new ThreadedThroughputCalculator(
+ OVERALL_DURATION_IN_MILLIS);
+ tp.printEnvironmentInfo("NoLockThroughput");
- for (int i = 0; i < 2; i++) {
- tp.execute(buildArray(LockingModel.NOLOCK));
- }
-
- tp.execute(buildArray(LockingModel.NOLOCK));
- tp.printThroughput("No lock: ", true);
+ for (int i = 0; i < 2; i++) {
+ tp.execute(buildArray(LockingModel.NOLOCK));
}
- static SelectiveLockRunnable[] buildArray(LockingModel model) {
- SelectiveLockRunnable[] array = new SelectiveLockRunnable[THREAD_COUNT];
- for (int i = 0; i < THREAD_COUNT; i++) {
- array[i] = new SelectiveLockRunnable(model);
- }
- return array;
+ tp.execute(buildArray(LockingModel.NOLOCK));
+ tp.printThroughput("No lock: ", true);
+ }
+
+ static SelectiveLockRunnable[] buildArray(LockingModel model) {
+ SelectiveLockRunnable[] array = new SelectiveLockRunnable[THREAD_COUNT];
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ array[i] = new SelectiveLockRunnable(model);
}
+ return array;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/issue/NoLockingInJava.java b/logback-core/src/test/java/ch/qos/logback/core/issue/NoLockingInJava.java
index 3d093c4..ea350a1 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/issue/NoLockingInJava.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/issue/NoLockingInJava.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,62 +21,67 @@ package ch.qos.logback.core.issue;
*/
public class NoLockingInJava implements Runnable {
- static int THREAD_COUNT = 5;
- static Object LOCK = new Object();
- static NoLockingInJava[] RUNNABLE_ARRAY = new NoLockingInJava[THREAD_COUNT];
- static Thread[] THREAD_ARRAY = new Thread[THREAD_COUNT];
+ static int THREAD_COUNT = 5;
+ static Object LOCK = new Object();
+ static NoLockingInJava[] RUNNABLE_ARRAY = new NoLockingInJava[THREAD_COUNT];
+ static Thread[] THREAD_ARRAY = new Thread[THREAD_COUNT];
- private int counter = 0;
- private boolean done = false;
+ private int counter = 0;
+ private boolean done = false;
- public static void main(String args[]) throws InterruptedException {
- printEnvironmentInfo();
- execute();
- printResults();
- }
-
- public static void printEnvironmentInfo() {
- System.out.println("java.runtime.version = " + System.getProperty("java.runtime.version"));
- System.out.println("java.vendor = " + System.getProperty("java.vendor"));
- System.out.println("java.version = " + System.getProperty("java.version"));
- System.out.println("os.name = " + System.getProperty("os.name"));
- System.out.println("os.version = " + System.getProperty("os.version"));
- }
-
- public static void execute() throws InterruptedException {
- for (int i = 0; i < THREAD_COUNT; i++) {
- RUNNABLE_ARRAY[i] = new NoLockingInJava();
- THREAD_ARRAY[i] = new Thread(RUNNABLE_ARRAY[i]);
- }
- for (Thread t : THREAD_ARRAY) {
- t.start();
- }
- // let the threads run for a while
- Thread.sleep(10000);
+ public static void main(String args[]) throws InterruptedException {
+ printEnvironmentInfo();
+ execute();
+ printResults();
+ }
- for (int i = THREAD_COUNT - 1; i <= 0; i--) {
- RUNNABLE_ARRAY[i].done = true;
- }
+ public static void printEnvironmentInfo() {
+ System.out.println("java.runtime.version = "
+ + System.getProperty("java.runtime.version"));
+ System.out.println("java.vendor = "
+ + System.getProperty("java.vendor"));
+ System.out.println("java.version = "
+ + System.getProperty("java.version"));
+ System.out.println("os.name = "
+ + System.getProperty("os.name"));
+ System.out.println("os.version = "
+ + System.getProperty("os.version"));
+ }
+ public static void execute() throws InterruptedException {
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ RUNNABLE_ARRAY[i] = new NoLockingInJava();
+ THREAD_ARRAY[i] = new Thread(RUNNABLE_ARRAY[i]);
}
+ for (Thread t : THREAD_ARRAY) {
+ t.start();
+ }
+ // let the threads run for a while
+ Thread.sleep(10000);
- public static void printResults() {
- for (int i = 0; i < RUNNABLE_ARRAY.length; i++) {
- System.out.println("runnable[" + i + "]: " + RUNNABLE_ARRAY[i]);
- }
+ for (int i = THREAD_COUNT - 1; i <= 0; i--) {
+ RUNNABLE_ARRAY[i].done = true;
}
- public void run() {
- for (;;) {
- counter++;
- if (done) {
- return;
- }
- }
+ }
+
+ public static void printResults() {
+ for (int i = 0; i < RUNNABLE_ARRAY.length; i++) {
+ System.out.println("runnable[" + i + "]: " + RUNNABLE_ARRAY[i]);
}
+ }
- public String toString() {
- return "counter=" + counter;
+ public void run() {
+ for (;;) {
+ counter++;
+ if (done) {
+ return;
+ }
}
+ }
+
+ public String toString() {
+ return "counter=" + counter;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/issue/SelectiveLockRunnable.java b/logback-core/src/test/java/ch/qos/logback/core/issue/SelectiveLockRunnable.java
index c96e416..66c6992 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/issue/SelectiveLockRunnable.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/issue/SelectiveLockRunnable.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,81 +26,81 @@ import ch.qos.logback.core.contention.RunnableWithCounterAndDone;
*/
public class SelectiveLockRunnable extends RunnableWithCounterAndDone {
- enum LockingModel {
- NOLOCK, SYNC, FAIR, UNFAIR;
- }
-
- static Object LOCK = new Object();
- static Lock FAIR_LOCK = new ReentrantLock(true);
- static Lock UNFAIR_LOCK = new ReentrantLock(false);
+ enum LockingModel {
+ NOLOCK, SYNC, FAIR, UNFAIR;
+ }
- LockingModel model;
+ static Object LOCK = new Object();
+ static Lock FAIR_LOCK = new ReentrantLock(true);
+ static Lock UNFAIR_LOCK = new ReentrantLock(false);
- SelectiveLockRunnable(LockingModel model) {
- this.model = model;
- }
+ LockingModel model;
- public void run() {
- switch (model) {
- case NOLOCK:
- nolockRun();
- break;
- case SYNC:
- synchronizedRun();
- break;
- case FAIR:
- fairLockRun();
- break;
- case UNFAIR:
- unfairLockRun();
- break;
- }
- }
+ SelectiveLockRunnable(LockingModel model) {
+ this.model = model;
+ }
- void fairLockRun() {
- for (;;) {
- FAIR_LOCK.lock();
- counter++;
- FAIR_LOCK.unlock();
- if (done) {
- return;
- }
- }
+ public void run() {
+ switch (model) {
+ case NOLOCK:
+ nolockRun();
+ break;
+ case SYNC:
+ synchronizedRun();
+ break;
+ case FAIR:
+ fairLockRun();
+ break;
+ case UNFAIR:
+ unfairLockRun();
+ break;
}
+ }
- void unfairLockRun() {
- for (;;) {
- UNFAIR_LOCK.lock();
- counter++;
- UNFAIR_LOCK.unlock();
- if (done) {
- return;
- }
- }
+ void fairLockRun() {
+ for (;;) {
+ FAIR_LOCK.lock();
+ counter++;
+ FAIR_LOCK.unlock();
+ if (done) {
+ return;
+ }
}
+ }
- void nolockRun() {
- for (;;) {
- counter++;
- if (done) {
- return;
- }
- }
+ void unfairLockRun() {
+ for (;;) {
+ UNFAIR_LOCK.lock();
+ counter++;
+ UNFAIR_LOCK.unlock();
+ if (done) {
+ return;
+ }
}
+ }
- void synchronizedRun() {
- for (;;) {
- synchronized (LOCK) {
- counter++;
- }
- if (done) {
- return;
- }
- }
+ void nolockRun() {
+ for (;;) {
+ counter++;
+ if (done) {
+ return;
+ }
}
+ }
- @Override
- public String toString() {
- return "SelectiveLockRunnable " + model;
+ void synchronizedRun() {
+ for (;;) {
+ synchronized (LOCK) {
+ counter++;
+ }
+ if (done) {
+ return;
+ }
}
+ }
+
+ @Override
+ public String toString() {
+ return "SelectiveLockRunnable "+model;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/issue/lbcore258/FileLockSimulator.java b/logback-core/src/test/java/ch/qos/logback/core/issue/lbcore258/FileLockSimulator.java
index 0e8143b..d6eb0a3 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/issue/lbcore258/FileLockSimulator.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/issue/lbcore258/FileLockSimulator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,7 @@ import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
+
/**
* FileLockSimulator is a small application intended to simulate FileAppender in prudent mode.
* In this mode, the application obtains an exclusive lock on the file, writes to the file and
@@ -42,61 +43,60 @@ import java.nio.channels.FileLock;
* lock to the point of appearing deadlocked.
*
*/
-public class FileLockSimulator {
+public class FileLockSimulator {
- static String LINE_SEPARATOR = System.getProperty("line.separator");
- static final int DOT_FREQ = 128;
- static final int DOT_WITH_NEW_LINE_FREQ = DOT_FREQ * 80;
+ static String LINE_SEPARATOR = System.getProperty("line.separator");
+ static final int DOT_FREQ = 128;
+ static final int DOT_WITH_NEW_LINE_FREQ = DOT_FREQ * 80;
- static String instanceName;
- static int delay;
- static FileOutputStream fos;
- static FileChannel fileChannel;
+ static String instanceName;
+ static int delay;
+ static FileOutputStream fos;
+ static FileChannel fileChannel;
- public static void main(String[] args) throws IOException, InterruptedException {
+ public static void main(String[] args) throws IOException, InterruptedException {
- String instanceName = args[0];
- System.out.println("Instance named as [" + instanceName + "]");
+ String instanceName = args[0];
+ System.out.println("Instance named as [" + instanceName + "]");
- String fileStr = args[1];
- System.out.println("Output target specified as [" + fileStr + "]");
+ String fileStr = args[1];
+ System.out.println("Output target specified as [" + fileStr + "]");
- int delay = Integer.parseInt(args[2]);
- System.out.println("Sleep delay specified as [" + delay + "] milliseconds");
+ int delay = Integer.parseInt(args[2]);
+ System.out.println("Sleep delay specified as [" + delay + "] milliseconds");
- fos = new FileOutputStream(fileStr, true);
- fileChannel = fos.getChannel();
+ fos = new FileOutputStream(fileStr, true);
+ fileChannel = fos.getChannel();
- for (int i = 1;; i++) {
- printDotAndSleep(i);
- lockAndWrite(i);
- }
+ for (int i = 1; ; i++) {
+ printDotAndSleep(i);
+ lockAndWrite(i);
}
+ }
- static void lockAndWrite(int i) throws InterruptedException, IOException {
- FileLock fileLock = null;
- try {
- fileLock = fileChannel.lock();
- long position = fileChannel.position();
- long size = fileChannel.size();
- if (size != position) {
- fileChannel.position(size);
- }
- String msg = "hello from" + instanceName + " " + i + LINE_SEPARATOR;
- fos.write(msg.getBytes());
- } finally {
- if (fileLock != null) {
- fileLock.release();
- }
- }
+ static void lockAndWrite(int i) throws InterruptedException, IOException {
+ FileLock fileLock = null;
+ try {
+ fileLock = fileChannel.lock();
+ long position = fileChannel.position();
+ long size = fileChannel.size();
+ if (size != position) {
+ fileChannel.position(size);
+ }
+ String msg = "hello from" + instanceName + " " + i + LINE_SEPARATOR;
+ fos.write(msg.getBytes());
+ } finally {
+ if (fileLock != null) {
+ fileLock.release();
+ }
}
+ }
- static void printDotAndSleep(int i) throws InterruptedException {
- if (i % DOT_FREQ == 0) {
- System.out.print(".");
- Thread.sleep(delay);
- }
- if (i % DOT_WITH_NEW_LINE_FREQ == 0)
- System.out.println("");
+ static void printDotAndSleep(int i) throws InterruptedException {
+ if (i % DOT_FREQ == 0) {
+ System.out.print(".");
+ Thread.sleep(delay);
}
+ if (i % DOT_WITH_NEW_LINE_FREQ == 0) System.out.println("");
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java
index c1b2cbd..bd183e6 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,10 +18,16 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ SkippingInInterpreterTest.class, TrivialConfiguratorTest.class, ch.qos.logback.core.joran.action.PackageTest.class,
- ch.qos.logback.core.joran.event.PackageTest.class, ch.qos.logback.core.joran.util.PackageTest.class, ch.qos.logback.core.joran.spi.PackageTest.class,
- ch.qos.logback.core.joran.replay.PackageTest.class, ch.qos.logback.core.joran.implicitAction.PackageTest.class,
- ch.qos.logback.core.joran.conditional.PackageTest.class })
+ at SuiteClasses( { SkippingInInterpreterTest.class,
+ TrivialConfiguratorTest.class,
+ ch.qos.logback.core.joran.action.PackageTest.class,
+ ch.qos.logback.core.joran.event.PackageTest.class,
+ ch.qos.logback.core.joran.util.PackageTest.class,
+ ch.qos.logback.core.joran.spi.PackageTest.class,
+ ch.qos.logback.core.joran.replay.PackageTest.class,
+ ch.qos.logback.core.joran.implicitAction.PackageTest.class,
+ ch.qos.logback.core.joran.conditional.PackageTest.class
+ })
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/SimpleConfigurator.java b/logback-core/src/test/java/ch/qos/logback/core/joran/SimpleConfigurator.java
index 07a358c..677222a 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/SimpleConfigurator.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/SimpleConfigurator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,41 +16,41 @@ package ch.qos.logback.core.joran;
import java.util.HashMap;
import ch.qos.logback.core.joran.action.Action;
-import ch.qos.logback.core.joran.action.NestedBasicPropertyIA;
import ch.qos.logback.core.joran.action.NestedComplexPropertyIA;
-import ch.qos.logback.core.joran.spi.ElementSelector;
+import ch.qos.logback.core.joran.action.NestedBasicPropertyIA;
import ch.qos.logback.core.joran.spi.Interpreter;
+import ch.qos.logback.core.joran.spi.ElementSelector;
import ch.qos.logback.core.joran.spi.RuleStore;
public class SimpleConfigurator extends GenericConfigurator {
- HashMap<ElementSelector, Action> rulesMap;
-
- public SimpleConfigurator(HashMap<ElementSelector, Action> rules) {
- this.rulesMap = rules;
- }
-
- @Override
- protected void addImplicitRules(Interpreter interpreter) {
- NestedComplexPropertyIA nestedIA = new NestedComplexPropertyIA(getBeanDescriptionCache());
- nestedIA.setContext(context);
- interpreter.addImplicitAction(nestedIA);
-
- NestedBasicPropertyIA nestedSimpleIA = new NestedBasicPropertyIA(getBeanDescriptionCache());
- nestedSimpleIA.setContext(context);
- interpreter.addImplicitAction(nestedSimpleIA);
- }
-
- public Interpreter getInterpreter() {
- return interpreter;
- }
-
- @Override
- protected void addInstanceRules(RuleStore rs) {
- for (ElementSelector elementSelector : rulesMap.keySet()) {
- Action action = rulesMap.get(elementSelector);
- rs.addRule(elementSelector, action);
- }
+ HashMap<ElementSelector, Action> rulesMap;
+
+ public SimpleConfigurator(HashMap<ElementSelector, Action> rules) {
+ this.rulesMap = rules;
+ }
+
+ @Override
+ protected void addImplicitRules(Interpreter interpreter) {
+ NestedComplexPropertyIA nestedIA = new NestedComplexPropertyIA();
+ nestedIA.setContext(context);
+ interpreter.addImplicitAction(nestedIA);
+
+ NestedBasicPropertyIA nestedSimpleIA = new NestedBasicPropertyIA();
+ nestedSimpleIA.setContext(context);
+ interpreter.addImplicitAction(nestedSimpleIA);
+ }
+
+ public Interpreter getInterpreter() {
+ return interpreter;
+ }
+
+ @Override
+ protected void addInstanceRules(RuleStore rs) {
+ for(ElementSelector elementSelector : rulesMap.keySet()) {
+ Action action = rulesMap.get(elementSelector);
+ rs.addRule(elementSelector, action);
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/SkippingInInterpreterTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/SkippingInInterpreterTest.java
index 92ea100..68f8484 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/SkippingInInterpreterTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/SkippingInInterpreterTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -47,68 +47,69 @@ import ch.qos.logback.core.util.CoreTestConstants;
*/
public class SkippingInInterpreterTest {
- HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
- Context context = new ContextBase();
- StatusManager sm = context.getStatusManager();
-
- SAXParser createParser() throws Exception {
- SAXParserFactory spf = SAXParserFactory.newInstance();
- return spf.newSAXParser();
- }
-
- void doTest(String filename, Integer expectedInt, Class<?> exceptionClass) throws Exception {
-
- rulesMap.put(new ElementSelector("test"), new NOPAction());
- rulesMap.put(new ElementSelector("test/badBegin"), new BadBeginAction());
- rulesMap.put(new ElementSelector("test/badBegin/touch"), new TouchAction());
- rulesMap.put(new ElementSelector("test/badEnd"), new BadEndAction());
- rulesMap.put(new ElementSelector("test/badEnd/touch"), new TouchAction());
- rulesMap.put(new ElementSelector("test/hello"), new HelloAction());
-
- rulesMap.put(new ElementSelector("test/isolate"), new NOPAction());
- rulesMap.put(new ElementSelector("test/isolate/badEnd"), new BadEndAction());
- rulesMap.put(new ElementSelector("test/isolate/badEnd/touch"), new TouchAction());
- rulesMap.put(new ElementSelector("test/isolate/touch"), new TouchAction());
- rulesMap.put(new ElementSelector("test/hello"), new HelloAction());
-
- TrivialConfigurator tc = new TrivialConfigurator(rulesMap);
- tc.setContext(context);
- tc.doConfigure(CoreTestConstants.TEST_SRC_PREFIX + "input/joran/skip/" + filename);
-
- String str = context.getProperty(HelloAction.PROPERTY_KEY);
- assertEquals("Hello John Doe.", str);
-
- Integer i = (Integer) context.getObject(TouchAction.KEY);
- if (expectedInt == null) {
- assertNull(i);
- } else {
- assertEquals(expectedInt, i);
- }
-
- // check the existence of an ERROR status
- List<Status> statusList = sm.getCopyOfStatusList();
- Status s0 = statusList.get(0);
- assertEquals(Status.ERROR, s0.getLevel());
- assertTrue(s0.getThrowable().getClass() == exceptionClass);
- }
-
- @Test
- public void testSkippingRuntimeExInBadBegin() throws Exception {
- doTest("badBegin1.xml", null, IllegalStateException.class);
+ HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
+ Context context = new ContextBase();
+ StatusManager sm = context.getStatusManager();
+
+ SAXParser createParser() throws Exception {
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ return spf.newSAXParser();
+ }
+
+ void doTest(String filename, Integer expectedInt, Class<?> exceptionClass)
+ throws Exception {
+
+ rulesMap.put(new ElementSelector("test"), new NOPAction());
+ rulesMap.put(new ElementSelector("test/badBegin"), new BadBeginAction());
+ rulesMap.put(new ElementSelector("test/badBegin/touch"), new TouchAction());
+ rulesMap.put(new ElementSelector("test/badEnd"), new BadEndAction());
+ rulesMap.put(new ElementSelector("test/badEnd/touch"), new TouchAction());
+ rulesMap.put(new ElementSelector("test/hello"), new HelloAction());
+
+ rulesMap.put(new ElementSelector("test/isolate"), new NOPAction());
+ rulesMap.put(new ElementSelector("test/isolate/badEnd"), new BadEndAction());
+ rulesMap.put(new ElementSelector("test/isolate/badEnd/touch"), new TouchAction());
+ rulesMap.put(new ElementSelector("test/isolate/touch"), new TouchAction());
+ rulesMap.put(new ElementSelector("test/hello"), new HelloAction());
+
+ TrivialConfigurator tc = new TrivialConfigurator(rulesMap);
+ tc.setContext(context);
+ tc.doConfigure(CoreTestConstants.TEST_SRC_PREFIX + "input/joran/skip/" + filename);
+
+ String str = context.getProperty(HelloAction.PROPERTY_KEY);
+ assertEquals("Hello John Doe.", str);
+
+ Integer i = (Integer) context.getObject(TouchAction.KEY);
+ if (expectedInt == null) {
+ assertNull(i);
+ } else {
+ assertEquals(expectedInt, i);
}
- @Test
- public void testSkippingActionExInBadBegin() throws Exception {
- doTest("badBegin2.xml", null, ActionException.class);
- }
-
- @Test
- public void testSkippingRuntimeExInBadEnd() throws Exception {
- doTest("badEnd1.xml", new Integer(2), IllegalStateException.class);
- }
-
- @Test
- public void testSkippingActionExInBadEnd() throws Exception {
- doTest("badEnd2.xml", new Integer(2), ActionException.class);
- }
+ // check the existence of an ERROR status
+ List<Status> statusList = sm.getCopyOfStatusList();
+ Status s0 = statusList.get(0);
+ assertEquals(Status.ERROR, s0.getLevel());
+ assertTrue(s0.getThrowable().getClass() == exceptionClass);
+ }
+
+ @Test
+ public void testSkippingRuntimeExInBadBegin() throws Exception {
+ doTest("badBegin1.xml", null, IllegalStateException.class);
+ }
+
+ @Test
+ public void testSkippingActionExInBadBegin() throws Exception {
+ doTest("badBegin2.xml", null, ActionException.class);
+ }
+
+ @Test
+ public void testSkippingRuntimeExInBadEnd() throws Exception {
+ doTest("badEnd1.xml", new Integer(2), IllegalStateException.class);
+ }
+
+ @Test
+ public void testSkippingActionExInBadEnd() throws Exception {
+ doTest("badEnd2.xml", new Integer(2), ActionException.class);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfigurator.java b/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfigurator.java
index cbdf025..df947d5 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfigurator.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfigurator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,22 +22,22 @@ import ch.qos.logback.core.joran.spi.RuleStore;
public class TrivialConfigurator extends GenericConfigurator {
- HashMap<ElementSelector, Action> rulesMap;
-
- public TrivialConfigurator(HashMap<ElementSelector, Action> rules) {
- this.rulesMap = rules;
- }
-
- @Override
- protected void addImplicitRules(Interpreter interpreter) {
- }
-
- @Override
- protected void addInstanceRules(RuleStore rs) {
- for (ElementSelector elementSelector : rulesMap.keySet()) {
- Action action = rulesMap.get(elementSelector);
- rs.addRule(elementSelector, action);
- }
+ HashMap<ElementSelector, Action> rulesMap;
+
+ public TrivialConfigurator(HashMap<ElementSelector, Action> rules) {
+ this.rulesMap = rules;
+ }
+
+ @Override
+ protected void addImplicitRules(Interpreter interpreter) {
+ }
+
+ @Override
+ protected void addInstanceRules(RuleStore rs) {
+ for(ElementSelector elementSelector : rulesMap.keySet()) {
+ Action action = rulesMap.get(elementSelector);
+ rs.addRule(elementSelector, action);
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java
index 5422c94..21fa65f 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,15 +27,15 @@ import java.util.HashMap;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
+import ch.qos.logback.core.CoreConstants;
import org.junit.Test;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
-import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.action.ext.IncAction;
-import ch.qos.logback.core.joran.spi.ElementSelector;
import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.joran.spi.ElementSelector;
import ch.qos.logback.core.status.Status;
import ch.qos.logback.core.status.TrivialStatusListener;
import ch.qos.logback.core.testUtil.RandomUtil;
@@ -43,130 +43,135 @@ import ch.qos.logback.core.util.CoreTestConstants;
public class TrivialConfiguratorTest {
- Context context = new ContextBase();
- HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
-
- public void doTest(String filename) throws Exception {
-
- // rule store is case insensitve
- rulesMap.put(new ElementSelector("x/inc"), new IncAction());
-
- TrivialConfigurator trivialConfigurator = new TrivialConfigurator(rulesMap);
-
- trivialConfigurator.setContext(context);
- trivialConfigurator.doConfigure(filename);
+ Context context = new ContextBase();
+ HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
+
+ public void doTest(String filename) throws Exception {
+
+ // rule store is case insensitve
+ rulesMap.put(new ElementSelector("x/inc"), new IncAction());
+
+ TrivialConfigurator trivialConfigurator = new TrivialConfigurator(rulesMap);
+
+ trivialConfigurator.setContext(context);
+ trivialConfigurator.doConfigure(filename);
+ }
+
+ @Test
+ public void smoke() throws Exception {
+ int oldBeginCount = IncAction.beginCount;
+ int oldEndCount = IncAction.endCount;
+ int oldErrorCount = IncAction.errorCount;
+ doTest(CoreTestConstants.TEST_SRC_PREFIX + "input/joran/" + "inc.xml");
+ assertEquals(oldErrorCount, IncAction.errorCount);
+ assertEquals(oldBeginCount + 1, IncAction.beginCount);
+ assertEquals(oldEndCount + 1, IncAction.endCount);
+ }
+
+ @Test
+ public void inexistentFile() {
+ TrivialStatusListener tsl = new TrivialStatusListener();
+ tsl.start();
+ String filename = CoreTestConstants.TEST_SRC_PREFIX + "input/joran/"
+ + "nothereBLAH.xml";
+ context.getStatusManager().add(tsl);
+ try {
+ doTest(filename);
+ } catch (Exception e) {
+ assertTrue(e.getMessage().startsWith("Could not open ["));
}
-
- @Test
- public void smoke() throws Exception {
- int oldBeginCount = IncAction.beginCount;
- int oldEndCount = IncAction.endCount;
- int oldErrorCount = IncAction.errorCount;
- doTest(CoreTestConstants.TEST_SRC_PREFIX + "input/joran/" + "inc.xml");
- assertEquals(oldErrorCount, IncAction.errorCount);
- assertEquals(oldBeginCount + 1, IncAction.beginCount);
- assertEquals(oldEndCount + 1, IncAction.endCount);
- }
-
- @Test
- public void inexistentFile() {
- TrivialStatusListener tsl = new TrivialStatusListener();
- tsl.start();
- String filename = CoreTestConstants.TEST_SRC_PREFIX + "input/joran/" + "nothereBLAH.xml";
- context.getStatusManager().add(tsl);
- try {
- doTest(filename);
- } catch (Exception e) {
- assertTrue(e.getMessage().startsWith("Could not open ["));
- }
- assertTrue(tsl.list.size() + " should be greater than or equal to 1", tsl.list.size() >= 1);
- Status s0 = tsl.list.get(0);
- assertTrue(s0.getMessage().startsWith("Could not open ["));
+ assertTrue(tsl.list.size() + " should be greater than or equal to 1",
+ tsl.list.size() >= 1);
+ Status s0 = tsl.list.get(0);
+ assertTrue(s0.getMessage().startsWith("Could not open ["));
+ }
+
+ @Test
+ public void illFormedXML() {
+ TrivialStatusListener tsl = new TrivialStatusListener();
+ tsl.start();
+ String filename = CoreTestConstants.TEST_SRC_PREFIX + "input/joran/" + "illformed.xml";
+ context.getStatusManager().add(tsl);
+ try {
+ doTest(filename);
+ } catch (Exception e) {
}
-
- @Test
- public void illFormedXML() {
- TrivialStatusListener tsl = new TrivialStatusListener();
- tsl.start();
- String filename = CoreTestConstants.TEST_SRC_PREFIX + "input/joran/" + "illformed.xml";
- context.getStatusManager().add(tsl);
- try {
- doTest(filename);
- } catch (Exception e) {
- }
- assertEquals(2, tsl.list.size());
- Status s0 = tsl.list.get(0);
- assertTrue(s0.getMessage().startsWith(CoreConstants.XML_PARSING));
+ assertEquals(1, tsl.list.size());
+ Status s0 = tsl.list.get(0);
+ assertTrue(s0.getMessage().startsWith(CoreConstants.XML_PARSING));
+ }
+
+ @Test
+ public void lbcore105() throws IOException, JoranException {
+ String jarEntry = "buzz.xml";
+ File jarFile = makeRandomJarFile();
+ fillInJarFile(jarFile, jarEntry);
+ URL url = asURL(jarFile, jarEntry);
+ TrivialConfigurator tc = new TrivialConfigurator(rulesMap);
+ tc.setContext(context);
+ tc.doConfigure(url);
+ // deleting an open file fails
+ assertTrue(jarFile.delete());
+ assertFalse(jarFile.exists());
+ }
+
+ @Test
+ public void lbcore127() throws IOException, JoranException {
+ String jarEntry = "buzz.xml";
+ String jarEntry2 = "lightyear.xml";
+
+ File jarFile = makeRandomJarFile();
+ fillInJarFile(jarFile, jarEntry, jarEntry2);
+
+ URL url1 = asURL(jarFile, jarEntry);
+ URL url2 = asURL(jarFile, jarEntry2);
+
+ URLConnection urlConnection2 = url2.openConnection();
+ urlConnection2.setUseCaches(false);
+ InputStream is = urlConnection2.getInputStream();
+
+ TrivialConfigurator tc = new TrivialConfigurator(rulesMap);
+ tc.setContext(context);
+ tc.doConfigure(url1);
+
+ is.read();
+ is.close();
+
+ // deleting an open file fails
+ assertTrue(jarFile.delete());
+ assertFalse(jarFile.exists());
+ }
+
+ File makeRandomJarFile() {
+ File outputDir = new File(CoreTestConstants.OUTPUT_DIR_PREFIX);
+ outputDir.mkdirs();
+ int randomPart = RandomUtil.getPositiveInt();
+ return new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "foo-" + randomPart
+ + ".jar");
+ }
+
+ private void fillInJarFile(File jarFile, String jarEntryName)
+ throws IOException {
+ fillInJarFile(jarFile, jarEntryName, null);
+ }
+
+ private void fillInJarFile(File jarFile, String jarEntryName1,
+ String jarEntryName2) throws IOException {
+ JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarFile));
+ jos.putNextEntry(new ZipEntry(jarEntryName1));
+ jos.write("<x/>".getBytes());
+ jos.closeEntry();
+ if (jarEntryName2 != null) {
+ jos.putNextEntry(new ZipEntry(jarEntryName2));
+ jos.write("<y/>".getBytes());
+ jos.closeEntry();
}
+ jos.close();
+ }
- @Test
- public void lbcore105() throws IOException, JoranException {
- String jarEntry = "buzz.xml";
- File jarFile = makeRandomJarFile();
- fillInJarFile(jarFile, jarEntry);
- URL url = asURL(jarFile, jarEntry);
- TrivialConfigurator tc = new TrivialConfigurator(rulesMap);
- tc.setContext(context);
- tc.doConfigure(url);
- // deleting an open file fails
- assertTrue(jarFile.delete());
- assertFalse(jarFile.exists());
- }
-
- @Test
- public void lbcore127() throws IOException, JoranException {
- String jarEntry = "buzz.xml";
- String jarEntry2 = "lightyear.xml";
-
- File jarFile = makeRandomJarFile();
- fillInJarFile(jarFile, jarEntry, jarEntry2);
-
- URL url1 = asURL(jarFile, jarEntry);
- URL url2 = asURL(jarFile, jarEntry2);
-
- URLConnection urlConnection2 = url2.openConnection();
- urlConnection2.setUseCaches(false);
- InputStream is = urlConnection2.getInputStream();
-
- TrivialConfigurator tc = new TrivialConfigurator(rulesMap);
- tc.setContext(context);
- tc.doConfigure(url1);
-
- is.read();
- is.close();
-
- // deleting an open file fails
- assertTrue(jarFile.delete());
- assertFalse(jarFile.exists());
- }
-
- File makeRandomJarFile() {
- File outputDir = new File(CoreTestConstants.OUTPUT_DIR_PREFIX);
- outputDir.mkdirs();
- int randomPart = RandomUtil.getPositiveInt();
- return new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "foo-" + randomPart + ".jar");
- }
-
- private void fillInJarFile(File jarFile, String jarEntryName) throws IOException {
- fillInJarFile(jarFile, jarEntryName, null);
- }
-
- private void fillInJarFile(File jarFile, String jarEntryName1, String jarEntryName2) throws IOException {
- JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarFile));
- jos.putNextEntry(new ZipEntry(jarEntryName1));
- jos.write("<x/>".getBytes());
- jos.closeEntry();
- if (jarEntryName2 != null) {
- jos.putNextEntry(new ZipEntry(jarEntryName2));
- jos.write("<y/>".getBytes());
- jos.closeEntry();
- }
- jos.close();
- }
-
- URL asURL(File jarFile, String jarEntryName) throws IOException {
- URL innerURL = jarFile.toURI().toURL();
- return new URL("jar:" + innerURL + "!/" + jarEntryName);
- }
+ URL asURL(File jarFile, String jarEntryName) throws IOException {
+ URL innerURL = jarFile.toURI().toURL();
+ return new URL("jar:" + innerURL + "!/" + jarEntryName);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/AsLowerCasePropertyDefiner.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/AsLowerCasePropertyDefiner.java
index 24515c8..e162cab 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/AsLowerCasePropertyDefiner.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/AsLowerCasePropertyDefiner.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,17 +17,17 @@ import ch.qos.logback.core.PropertyDefinerBase;
public class AsLowerCasePropertyDefiner extends PropertyDefinerBase {
- String val;
+ String val;
- public String getPropertyValue() {
- if (val == null) {
- return null;
- } else {
- return val.toLowerCase();
- }
+ public String getPropertyValue() {
+ if (val == null) {
+ return null;
+ } else {
+ return val.toLowerCase();
}
+ }
- public void setValue(String val) {
- this.val = val;
- }
+ public void setValue(String val) {
+ this.val = val;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/DefinePropertyActionTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/DefinePropertyActionTest.java
index f24ac17..01d2685 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/DefinePropertyActionTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/DefinePropertyActionTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -40,66 +40,69 @@ import ch.qos.logback.core.util.CoreTestConstants;
*/
public class DefinePropertyActionTest {
- private static final String DEFINE_INPUT_DIR = CoreTestConstants.JORAN_INPUT_PREFIX + "define/";
- private static final String GOOD_XML = "good.xml";
- private static final String NONAME_XML = "noname.xml";
- private static final String NOCLASS_XML = "noclass.xml";
- private static final String BADCLASS_XML = "badclass.xml";
+ private static final String DEFINE_INPUT_DIR = CoreTestConstants.JORAN_INPUT_PREFIX
+ + "define/";
+ private static final String GOOD_XML = "good.xml";
+ private static final String NONAME_XML = "noname.xml";
+ private static final String NOCLASS_XML = "noclass.xml";
+ private static final String BADCLASS_XML = "badclass.xml";
- SimpleConfigurator simpleConfigurator;
- Context context = new ContextBase();
- DefinePropertyAction definerAction;
- InterpretationContext ic;
- StatusChecker checker = new StatusChecker(context);
+ SimpleConfigurator simpleConfigurator;
+ Context context = new ContextBase();
+ DefinePropertyAction definerAction;
+ InterpretationContext ic;
+ StatusChecker checker = new StatusChecker(context);
- @Before
- public void setUp() throws Exception {
+ @Before
+ public void setUp() throws Exception {
- HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
- rulesMap.put(new ElementSelector("define"), new DefinePropertyAction());
- simpleConfigurator = new SimpleConfigurator(rulesMap);
- simpleConfigurator.setContext(context);
- }
+ HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
+ rulesMap.put(new ElementSelector("define"), new DefinePropertyAction());
+ simpleConfigurator = new SimpleConfigurator(rulesMap);
+ simpleConfigurator.setContext(context);
+ }
- @After
- public void tearDown() throws Exception {
- // StatusPrinter.printInCaseOfErrorsOrWarnings(context);
- }
+ @After
+ public void tearDown() throws Exception {
+ //StatusPrinter.printInCaseOfErrorsOrWarnings(context);
+ }
- @Test
- public void good() throws JoranException {
- simpleConfigurator.doConfigure(DEFINE_INPUT_DIR + GOOD_XML);
- InterpretationContext ic = simpleConfigurator.getInterpreter().getInterpretationContext();
- String inContextFoo = ic.getProperty("foo");
- assertEquals("monster", inContextFoo);
- }
+ @Test
+ public void good() throws JoranException {
+ simpleConfigurator.doConfigure(DEFINE_INPUT_DIR + GOOD_XML);
+ InterpretationContext ic = simpleConfigurator.getInterpreter().getInterpretationContext();
+ String inContextFoo = ic.getProperty("foo");
+ assertEquals("monster", inContextFoo);
+ }
- @Test
- public void noName() throws JoranException {
- simpleConfigurator.doConfigure(DEFINE_INPUT_DIR + NONAME_XML);
- // get from context
- String inContextFoo = context.getProperty("foo");
- assertNull(inContextFoo);
- // check context errors
- checker.assertContainsMatch(Status.ERROR, "Missing property name for property definer. Near \\[define\\] line 1");
- }
+ @Test
+ public void noName() throws JoranException {
+ simpleConfigurator.doConfigure(DEFINE_INPUT_DIR + NONAME_XML);
+ // get from context
+ String inContextFoo = context.getProperty("foo");
+ assertNull(inContextFoo);
+ // check context errors
+ checker.assertContainsMatch(Status.ERROR,
+ "Missing property name for property definer. Near \\[define\\] line 1");
+ }
- @Test
- public void noClass() throws JoranException {
- simpleConfigurator.doConfigure(DEFINE_INPUT_DIR + NOCLASS_XML);
- String inContextFoo = context.getProperty("foo");
- assertNull(inContextFoo);
- checker.assertContainsMatch(Status.ERROR, "Missing class name for property definer. Near \\[define\\] line 1");
- }
+ @Test
+ public void noClass() throws JoranException {
+ simpleConfigurator.doConfigure(DEFINE_INPUT_DIR + NOCLASS_XML);
+ String inContextFoo = context.getProperty("foo");
+ assertNull(inContextFoo);
+ checker.assertContainsMatch(Status.ERROR,
+ "Missing class name for property definer. Near \\[define\\] line 1");
+ }
- @Test
- public void testBadClass() throws JoranException {
- simpleConfigurator.doConfigure(DEFINE_INPUT_DIR + BADCLASS_XML);
- // get from context
- String inContextFoo = context.getProperty("foo");
- assertNull(inContextFoo);
- // check context errors
- checker.assertContainsMatch(Status.ERROR, "Could not create an PropertyDefiner of type");
- }
+ @Test
+ public void testBadClass() throws JoranException {
+ simpleConfigurator.doConfigure(DEFINE_INPUT_DIR + BADCLASS_XML);
+ // get from context
+ String inContextFoo = context.getProperty("foo");
+ assertNull(inContextFoo);
+ // check context errors
+ checker.assertContainsMatch(Status.ERROR, "Could not create an PropertyDefiner of type");
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/DummyAttributes.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/DummyAttributes.java
index 957b9e1..6b37ff3 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/DummyAttributes.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/DummyAttributes.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,58 +19,58 @@ import org.xml.sax.Attributes;
public class DummyAttributes implements Attributes {
- HashMap<String, String> atts = new HashMap<String, String>();
+ HashMap<String, String> atts = new HashMap<String, String>();
- public int getIndex(String qName) {
- return 0;
- }
+ public int getIndex(String qName) {
+ return 0;
+ }
- public int getIndex(String uri, String localName) {
- return 0;
- }
+ public int getIndex(String uri, String localName) {
+ return 0;
+ }
- public int getLength() {
- return 0;
- }
+ public int getLength() {
+ return 0;
+ }
- public String getLocalName(int index) {
- return null;
- }
+ public String getLocalName(int index) {
+ return null;
+ }
- public String getQName(int index) {
- return null;
- }
+ public String getQName(int index) {
+ return null;
+ }
- public String getType(int index) {
- return null;
- }
+ public String getType(int index) {
+ return null;
+ }
- public String getType(String qName) {
- return null;
- }
+ public String getType(String qName) {
+ return null;
+ }
- public String getType(String uri, String localName) {
- return null;
- }
+ public String getType(String uri, String localName) {
+ return null;
+ }
- public String getURI(int index) {
- return null;
- }
+ public String getURI(int index) {
+ return null;
+ }
- public String getValue(int index) {
- return null;
- }
+ public String getValue(int index) {
+ return null;
+ }
- public String getValue(String qName) {
- return atts.get(qName);
- }
+ public String getValue(String qName) {
+ return atts.get(qName);
+ }
- public void setValue(String key, String value) {
- atts.put(key, value);
- }
+ public void setValue(String key, String value) {
+ atts.put(key, value);
+ }
- public String getValue(String uri, String localName) {
- return null;
- }
+ public String getValue(String uri, String localName) {
+ return null;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java
index bcbaa7e..ef56bac 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,13 +18,16 @@ import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
+import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Stack;
+import ch.qos.logback.core.testUtil.FileTestUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -34,190 +37,198 @@ import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.joran.TrivialConfigurator;
import ch.qos.logback.core.joran.action.ext.StackAction;
-import ch.qos.logback.core.joran.spi.ElementSelector;
import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.joran.spi.ElementSelector;
import ch.qos.logback.core.status.Status;
import ch.qos.logback.core.status.StatusChecker;
-import ch.qos.logback.core.testUtil.FileTestUtil;
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.util.CoreTestConstants;
import ch.qos.logback.core.util.StatusPrinter;
public class IncludeActionTest {
- final static String INCLUDE_KEY = "includeKey";
- final static String SUB_FILE_KEY = "subFileKey";
- final static String SECOND_FILE_KEY = "secondFileKey";
-
- Context context = new ContextBase();
- StatusChecker statusChecker = new StatusChecker(context);
- TrivialConfigurator tc;
-
- static final String INCLUSION_DIR_PREFIX = CoreTestConstants.JORAN_INPUT_PREFIX + "inclusion/";
-
- static final String TOP_BY_FILE = INCLUSION_DIR_PREFIX + "topByFile.xml";
-
- static final String TOP_OPTIONAL = INCLUSION_DIR_PREFIX + "topOptional.xml";
-
- static final String TOP_OPTIONAL_RESOURCE = INCLUSION_DIR_PREFIX + "topOptionalResource.xml";
-
- static final String INTERMEDIARY_FILE = INCLUSION_DIR_PREFIX + "intermediaryByFile.xml";
-
- static final String SUB_FILE = INCLUSION_DIR_PREFIX + "subByFile.xml";
-
- static final String MULTI_INCLUDE_BY_FILE = INCLUSION_DIR_PREFIX + "multiIncludeByFile.xml";
-
- static final String SECOND_FILE = INCLUSION_DIR_PREFIX + "second.xml";
-
- static final String TOP_BY_URL = INCLUSION_DIR_PREFIX + "topByUrl.xml";
-
- static final String INCLUDE_BY_RESOURCE = INCLUSION_DIR_PREFIX + "topByResource.xml";
-
- static final String INCLUDED_FILE = INCLUSION_DIR_PREFIX + "included.xml";
- static final String URL_TO_INCLUDE = "file:./" + INCLUDED_FILE;
-
- static final String INVALID = INCLUSION_DIR_PREFIX + "invalid.xml";
-
- static final String INCLUDED_AS_RESOURCE = "asResource/joran/inclusion/includedAsResource.xml";
-
- int diff = RandomUtil.getPositiveInt();
-
- StackAction stackAction = new StackAction();
-
- @Before
- public void setUp() throws Exception {
- FileTestUtil.makeTestOutputDir();
- HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
- rulesMap.put(new ElementSelector("x"), new NOPAction());
- rulesMap.put(new ElementSelector("x/include"), new IncludeAction());
- rulesMap.put(new ElementSelector("x/stack"), stackAction);
-
- tc = new TrivialConfigurator(rulesMap);
- tc.setContext(context);
- }
-
- @After
- public void tearDown() throws Exception {
- StatusPrinter.printInCaseOfErrorsOrWarnings(context);
- context = null;
- System.clearProperty(INCLUDE_KEY);
- System.clearProperty(SECOND_FILE_KEY);
- System.clearProperty(SUB_FILE_KEY);
- // StackAction.reset();
- }
-
- @Test
- public void basicFile() throws JoranException {
- System.setProperty(INCLUDE_KEY, INCLUDED_FILE);
- tc.doConfigure(TOP_BY_FILE);
- verifyConfig(new String[] { "IA", "IB" });
- }
-
- @Test
- public void optionalFile() throws JoranException {
- tc.doConfigure(TOP_OPTIONAL);
- verifyConfig(new String[] { "IA", "IB" });
- StatusPrinter.print(context);
- }
-
- @Test
- public void optionalResource() throws JoranException {
- tc.doConfigure(TOP_OPTIONAL_RESOURCE);
- verifyConfig(new String[] { "IA", "IB" });
- StatusPrinter.print(context);
- assertEquals(Status.INFO, statusChecker.getHighestLevel(0));
- }
-
- @Test
- public void basicResource() throws JoranException {
- System.setProperty(INCLUDE_KEY, INCLUDED_AS_RESOURCE);
- tc.doConfigure(INCLUDE_BY_RESOURCE);
- verifyConfig(new String[] { "AR_A", "AR_B" });
- }
-
- @Test
- public void basicURL() throws JoranException {
- System.setProperty(INCLUDE_KEY, URL_TO_INCLUDE);
- tc.doConfigure(TOP_BY_URL);
- verifyConfig(new String[] { "IA", "IB" });
- }
-
- @Test
- public void noFileFound() throws JoranException {
- System.setProperty(INCLUDE_KEY, "toto");
- tc.doConfigure(TOP_BY_FILE);
- assertEquals(Status.WARN, statusChecker.getHighestLevel(0));
- }
-
- @Test
- public void withCorruptFile() throws JoranException, IOException {
- String tmpOut = copyToTemp(INVALID);
- System.setProperty(INCLUDE_KEY, tmpOut);
- tc.doConfigure(TOP_BY_FILE);
- assertEquals(Status.ERROR, statusChecker.getHighestLevel(0));
- StatusPrinter.print(context);
- assertTrue(statusChecker.containsException(SAXParseException.class));
-
- // we like to erase the temp file in order to see
- // if http://jira.qos.ch/browse/LBCORE-122 was fixed
- File f = new File(tmpOut);
- assertTrue(f.exists());
- assertTrue(f.delete());
-
- }
-
- String copyToTemp(String in) throws IOException {
- FileInputStream fis = new FileInputStream(in);
- String out = CoreTestConstants.OUTPUT_DIR_PREFIX + "out" + diff;
- FileOutputStream fos = new FileOutputStream(out);
- int b;
- while ((b = fis.read()) != -1) {
- fos.write(b);
- }
- fis.close();
- fos.close();
- return out;
- }
-
- @Test
- public void malformedURL() throws JoranException {
- System.setProperty(INCLUDE_KEY, "htp://logback.qos.ch");
- tc.doConfigure(TOP_BY_URL);
- assertEquals(Status.ERROR, statusChecker.getHighestLevel(0));
- assertTrue(statusChecker.containsException(MalformedURLException.class));
- }
-
- @Test
- public void unknownURL() throws JoranException {
- System.setProperty(INCLUDE_KEY, "http://logback2345.qos.ch");
- tc.doConfigure(TOP_BY_URL);
- assertEquals(Status.WARN, statusChecker.getHighestLevel(0));
- }
-
- @Test
- public void nestedInclude() throws JoranException {
- System.setProperty(SUB_FILE_KEY, SUB_FILE);
- System.setProperty(INCLUDE_KEY, INTERMEDIARY_FILE);
- tc.doConfigure(TOP_BY_FILE);
- Stack<String> witness = new Stack<String>();
- witness.push("a");
- witness.push("b");
- witness.push("c");
- assertEquals(witness, stackAction.getStack());
- }
-
- @Test
- public void multiInclude() throws JoranException {
- System.setProperty(INCLUDE_KEY, INCLUDED_FILE);
- System.setProperty(SECOND_FILE_KEY, SECOND_FILE);
- tc.doConfigure(MULTI_INCLUDE_BY_FILE);
- verifyConfig(new String[] { "IA", "IB", "SECOND" });
- }
+ final static String INCLUDE_KEY = "includeKey";
+ final static String SUB_FILE_KEY = "subFileKey";
+ final static String SECOND_FILE_KEY = "secondFileKey";
- void verifyConfig(String[] expected) {
- Stack<String> witness = new Stack<String>();
- witness.addAll(Arrays.asList(expected));
- assertEquals(witness, stackAction.getStack());
+ Context context = new ContextBase();
+ StatusChecker statusChecker = new StatusChecker(context);
+ TrivialConfigurator tc;
+
+ static final String INCLUSION_DIR_PREFIX = CoreTestConstants.JORAN_INPUT_PREFIX
+ + "inclusion/";
+
+ static final String TOP_BY_FILE = INCLUSION_DIR_PREFIX + "topByFile.xml";
+
+ static final String TOP_OPTIONAL = INCLUSION_DIR_PREFIX + "topOptional.xml";
+
+ static final String TOP_OPTIONAL_RESOURCE = INCLUSION_DIR_PREFIX + "topOptionalResource.xml";
+
+ static final String INTERMEDIARY_FILE = INCLUSION_DIR_PREFIX
+ + "intermediaryByFile.xml";
+
+ static final String SUB_FILE = INCLUSION_DIR_PREFIX + "subByFile.xml";
+
+ static final String MULTI_INCLUDE_BY_FILE = INCLUSION_DIR_PREFIX
+ + "multiIncludeByFile.xml";
+
+ static final String SECOND_FILE = INCLUSION_DIR_PREFIX + "second.xml";
+
+ static final String TOP_BY_URL = INCLUSION_DIR_PREFIX + "topByUrl.xml";
+
+ static final String INCLUDE_BY_RESOURCE = INCLUSION_DIR_PREFIX
+ + "topByResource.xml";
+
+ static final String INCLUDED_FILE = INCLUSION_DIR_PREFIX + "included.xml";
+ static final String URL_TO_INCLUDE = "file:./" + INCLUDED_FILE;
+
+ static final String INVALID = INCLUSION_DIR_PREFIX + "invalid.xml";
+
+ static final String INCLUDED_AS_RESOURCE = "asResource/joran/inclusion/includedAsResource.xml";
+
+ int diff = RandomUtil.getPositiveInt();
+
+ StackAction stackAction = new StackAction();
+
+ @Before
+ public void setUp() throws Exception {
+ FileTestUtil.makeTestOutputDir();
+ HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
+ rulesMap.put(new ElementSelector("x"), new NOPAction());
+ rulesMap.put(new ElementSelector("x/include"), new IncludeAction());
+ rulesMap.put(new ElementSelector("x/stack"), stackAction);
+
+ tc = new TrivialConfigurator(rulesMap);
+ tc.setContext(context);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ StatusPrinter.printInCaseOfErrorsOrWarnings(context);
+ context = null;
+ System.clearProperty(INCLUDE_KEY);
+ System.clearProperty(SECOND_FILE_KEY);
+ System.clearProperty(SUB_FILE_KEY);
+ //StackAction.reset();
+ }
+
+ @Test
+ public void basicFile() throws JoranException {
+ System.setProperty(INCLUDE_KEY, INCLUDED_FILE);
+ tc.doConfigure(TOP_BY_FILE);
+ verifyConfig(new String[] { "IA", "IB" });
+ }
+
+ @Test
+ public void optionalFile() throws JoranException {
+ tc.doConfigure(TOP_OPTIONAL);
+ verifyConfig(new String[] { "IA", "IB" });
+ StatusPrinter.print(context);
+ }
+
+ @Test
+ public void optionalResource() throws JoranException {
+ tc.doConfigure(TOP_OPTIONAL_RESOURCE);
+ verifyConfig(new String[] { "IA", "IB" });
+ StatusPrinter.print(context);
+ assertEquals(Status.INFO, statusChecker.getHighestLevel(0));
+ }
+
+ @Test
+ public void basicResource() throws JoranException {
+ System.setProperty(INCLUDE_KEY, INCLUDED_AS_RESOURCE);
+ tc.doConfigure(INCLUDE_BY_RESOURCE);
+ verifyConfig(new String[] { "AR_A", "AR_B" });
+ }
+
+ @Test
+ public void basicURL() throws JoranException {
+ System.setProperty(INCLUDE_KEY, URL_TO_INCLUDE);
+ tc.doConfigure(TOP_BY_URL);
+ verifyConfig(new String[] { "IA", "IB" });
+ }
+
+ @Test
+ public void noFileFound() throws JoranException {
+ System.setProperty(INCLUDE_KEY, "toto");
+ tc.doConfigure(TOP_BY_FILE);
+ assertEquals(Status.ERROR, statusChecker.getHighestLevel(0));
+ assertTrue(statusChecker.containsException(FileNotFoundException.class));
+ }
+
+ @Test
+ public void withCorruptFile() throws JoranException, IOException {
+ String tmpOut = copyToTemp(INVALID);
+ System.setProperty(INCLUDE_KEY, tmpOut);
+ tc.doConfigure(TOP_BY_FILE);
+ assertEquals(Status.ERROR, statusChecker.getHighestLevel(0));
+ assertTrue(statusChecker.containsException(SAXParseException.class));
+
+ // we like to erase the temp file in order to see
+ // if http://jira.qos.ch/browse/LBCORE-122 was fixed
+ File f = new File(tmpOut);
+ assertTrue(f.exists());
+ assertTrue(f.delete());
+
+ }
+
+ String copyToTemp(String in) throws IOException {
+ FileInputStream fis = new FileInputStream(in);
+ String out = CoreTestConstants.OUTPUT_DIR_PREFIX + "out" + diff;
+ FileOutputStream fos = new FileOutputStream(out);
+ int b;
+ while ((b = fis.read()) != -1) {
+ fos.write(b);
}
+ fis.close();
+ fos.close();
+ return out;
+ }
+
+ @Test
+ public void malformedURL() throws JoranException {
+ System.setProperty(INCLUDE_KEY, "htp://logback.qos.ch");
+ tc.doConfigure(TOP_BY_URL);
+ assertEquals(Status.ERROR, statusChecker.getHighestLevel(0));
+ assertTrue(statusChecker.containsException(MalformedURLException.class));
+ }
+
+ @Test
+ public void unknownURL() throws JoranException {
+ System.setProperty(INCLUDE_KEY, "http://logback2345.qos.ch");
+ tc.doConfigure(TOP_BY_URL);
+ assertEquals(Status.ERROR, statusChecker.getHighestLevel(0));
+ // OS X throws IOException instead of UnknownHostException
+ // http://jira.qos.ch/browse/LBCORE-129
+ // This behavior has been observed on Windows XP as well
+ assertTrue(statusChecker.containsException(UnknownHostException.class)
+ || statusChecker.containsException(IOException.class));
+ }
+
+ @Test
+ public void nestedInclude() throws JoranException {
+ System.setProperty(SUB_FILE_KEY, SUB_FILE);
+ System.setProperty(INCLUDE_KEY, INTERMEDIARY_FILE);
+ tc.doConfigure(TOP_BY_FILE);
+ Stack<String> witness = new Stack<String>();
+ witness.push("a");
+ witness.push("b");
+ witness.push("c");
+ assertEquals(witness, stackAction.getStack());
+ }
+
+ @Test
+ public void multiInclude() throws JoranException {
+ System.setProperty(INCLUDE_KEY, INCLUDED_FILE);
+ System.setProperty(SECOND_FILE_KEY, SECOND_FILE);
+ tc.doConfigure(MULTI_INCLUDE_BY_FILE);
+ verifyConfig(new String[] { "IA", "IB", "SECOND" });
+ }
+
+ void verifyConfig(String[] expected) {
+ Stack<String> witness = new Stack<String>();
+ witness.addAll(Arrays.asList(expected));
+ assertEquals(witness, stackAction.getStack());
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/PackageTest.java
index efb1447..255e7fa 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ PropertyActionTest.class, IncludeActionTest.class })
-public class PackageTest {
+ at SuiteClasses({PropertyActionTest.class, IncludeActionTest.class})
+public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/PropertyActionTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/PropertyActionTest.java
index 732c07b..169f17d 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/PropertyActionTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/PropertyActionTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -33,129 +33,129 @@ import ch.qos.logback.core.util.StatusPrinter;
* Test {@link PropertyAction}.
* @author Ceki Gülcü
*/
-public class PropertyActionTest {
-
- Context context;
- InterpretationContext ec;
- PropertyAction propertyAction;
- DummyAttributes atts = new DummyAttributes();
-
- @Before
- public void setUp() throws Exception {
- context = new ContextBase();
- ec = new InterpretationContext(context, null);
- propertyAction = new PropertyAction();
- propertyAction.setContext(context);
- }
-
- @After
- public void tearDown() throws Exception {
- context = null;
- propertyAction = null;
- atts = null;
- }
-
- @Test
- public void nameValuePair() {
- atts.setValue("name", "v1");
- atts.setValue("value", "work");
- propertyAction.begin(ec, null, atts);
- assertEquals("work", ec.getProperty("v1"));
- }
-
- @Test
- public void nameValuePairWithPrerequisiteSubsitution() {
- context.putProperty("w", "wor");
- atts.setValue("name", "v1");
- atts.setValue("value", "${w}k");
- propertyAction.begin(ec, null, atts);
- assertEquals("work", ec.getProperty("v1"));
- }
-
- @Test
- public void noValue() {
- atts.setValue("name", "v1");
- propertyAction.begin(ec, null, atts);
- assertEquals(1, context.getStatusManager().getCount());
- assertTrue(checkError());
- }
-
- @Test
- public void noName() {
- atts.setValue("value", "v1");
- propertyAction.begin(ec, null, atts);
- assertEquals(1, context.getStatusManager().getCount());
- assertTrue(checkError());
- }
-
- @Test
- public void noAttributes() {
- propertyAction.begin(ec, null, atts);
- assertEquals(1, context.getStatusManager().getCount());
- assertTrue(checkError());
- StatusPrinter.print(context);
- }
-
- @Test
- public void testFileNotLoaded() {
- atts.setValue("file", "toto");
- atts.setValue("value", "work");
- propertyAction.begin(ec, null, atts);
- assertEquals(1, context.getStatusManager().getCount());
- assertTrue(checkError());
- }
-
- @Test
- public void testLoadFileWithPrerequisiteSubsitution() {
- context.putProperty("STEM", CoreTestConstants.TEST_SRC_PREFIX + "input/joran");
- atts.setValue("file", "${STEM}/propertyActionTest.properties");
- propertyAction.begin(ec, null, atts);
- assertEquals("tata", ec.getProperty("v1"));
- assertEquals("toto", ec.getProperty("v2"));
- }
-
- @Test
- public void testLoadFile() {
- atts.setValue("file", CoreTestConstants.TEST_SRC_PREFIX + "input/joran/propertyActionTest.properties");
- propertyAction.begin(ec, null, atts);
- assertEquals("tata", ec.getProperty("v1"));
- assertEquals("toto", ec.getProperty("v2"));
- }
-
- @Test
- public void testLoadResource() {
- atts.setValue("resource", "asResource/joran/propertyActionTest.properties");
- propertyAction.begin(ec, null, atts);
- assertEquals("tata", ec.getProperty("r1"));
- assertEquals("toto", ec.getProperty("r2"));
- }
-
- @Test
- public void testLoadResourceWithPrerequisiteSubsitution() {
- context.putProperty("STEM", "asResource/joran");
- atts.setValue("resource", "${STEM}/propertyActionTest.properties");
- propertyAction.begin(ec, null, atts);
- assertEquals("tata", ec.getProperty("r1"));
- assertEquals("toto", ec.getProperty("r2"));
- }
-
- @Test
- public void testLoadNotPossible() {
- atts.setValue("file", "toto");
- propertyAction.begin(ec, null, atts);
- assertEquals(1, context.getStatusManager().getCount());
- assertTrue(checkFileErrors());
- }
-
- private boolean checkError() {
- Iterator it = context.getStatusManager().getCopyOfStatusList().iterator();
- ErrorStatus es = (ErrorStatus) it.next();
- return PropertyAction.INVALID_ATTRIBUTES.equals(es.getMessage());
- }
-
- private boolean checkFileErrors() {
- Iterator it = context.getStatusManager().getCopyOfStatusList().iterator();
- ErrorStatus es1 = (ErrorStatus) it.next();
- return "Could not find properties file [toto].".equals(es1.getMessage());
- }
+public class PropertyActionTest {
+
+ Context context;
+ InterpretationContext ec;
+ PropertyAction propertyAction;
+ DummyAttributes atts = new DummyAttributes();
+
+ @Before
+ public void setUp() throws Exception {
+ context = new ContextBase();
+ ec = new InterpretationContext(context, null);
+ propertyAction = new PropertyAction();
+ propertyAction.setContext(context);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ context = null;
+ propertyAction = null;
+ atts = null;
+ }
+
+ @Test
+ public void nameValuePair() {
+ atts.setValue("name", "v1");
+ atts.setValue("value", "work");
+ propertyAction.begin(ec, null, atts);
+ assertEquals("work", ec.getProperty("v1"));
+ }
+
+ @Test
+ public void nameValuePairWithPrerequisiteSubsitution() {
+ context.putProperty("w", "wor");
+ atts.setValue("name", "v1");
+ atts.setValue("value", "${w}k");
+ propertyAction.begin(ec, null, atts);
+ assertEquals("work", ec.getProperty("v1"));
+ }
+
+ @Test
+ public void noValue() {
+ atts.setValue("name", "v1");
+ propertyAction.begin(ec, null, atts);
+ assertEquals(1, context.getStatusManager().getCount());
+ assertTrue(checkError());
+ }
+
+ @Test
+ public void noName() {
+ atts.setValue("value", "v1");
+ propertyAction.begin(ec, null, atts);
+ assertEquals(1, context.getStatusManager().getCount());
+ assertTrue(checkError());
+ }
+
+ @Test
+ public void noAttributes() {
+ propertyAction.begin(ec, null, atts);
+ assertEquals(1, context.getStatusManager().getCount());
+ assertTrue(checkError());
+ StatusPrinter.print(context);
+ }
+
+ @Test
+ public void testFileNotLoaded() {
+ atts.setValue("file", "toto");
+ atts.setValue("value", "work");
+ propertyAction.begin(ec, null, atts);
+ assertEquals(1, context.getStatusManager().getCount());
+ assertTrue(checkError());
+ }
+
+ @Test
+ public void testLoadFileWithPrerequisiteSubsitution() {
+ context.putProperty("STEM", CoreTestConstants.TEST_SRC_PREFIX + "input/joran");
+ atts.setValue("file", "${STEM}/propertyActionTest.properties");
+ propertyAction.begin(ec, null, atts);
+ assertEquals("tata", ec.getProperty("v1"));
+ assertEquals("toto", ec.getProperty("v2"));
+ }
+
+ @Test
+ public void testLoadFile() {
+ atts.setValue("file", CoreTestConstants.TEST_SRC_PREFIX + "input/joran/propertyActionTest.properties");
+ propertyAction.begin(ec, null, atts);
+ assertEquals("tata", ec.getProperty("v1"));
+ assertEquals("toto", ec.getProperty("v2"));
+ }
+
+ @Test
+ public void testLoadResource() {
+ atts.setValue("resource", "asResource/joran/propertyActionTest.properties");
+ propertyAction.begin(ec, null, atts);
+ assertEquals("tata", ec.getProperty("r1"));
+ assertEquals("toto", ec.getProperty("r2"));
+ }
+
+ @Test
+ public void testLoadResourceWithPrerequisiteSubsitution() {
+ context.putProperty("STEM", "asResource/joran");
+ atts.setValue("resource", "${STEM}/propertyActionTest.properties");
+ propertyAction.begin(ec, null, atts);
+ assertEquals("tata", ec.getProperty("r1"));
+ assertEquals("toto", ec.getProperty("r2"));
+ }
+
+ @Test
+ public void testLoadNotPossible() {
+ atts.setValue("file", "toto");
+ propertyAction.begin(ec, null, atts);
+ assertEquals(1, context.getStatusManager().getCount());
+ assertTrue(checkFileErrors());
+ }
+
+ private boolean checkError() {
+ Iterator it = context.getStatusManager().getCopyOfStatusList().iterator();
+ ErrorStatus es = (ErrorStatus)it.next();
+ return PropertyAction.INVALID_ATTRIBUTES.equals(es.getMessage());
+ }
+
+ private boolean checkFileErrors() {
+ Iterator it = context.getStatusManager().getCopyOfStatusList().iterator();
+ ErrorStatus es1 = (ErrorStatus)it.next();
+ return "Could not find properties file [toto].".equals(es1.getMessage());
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/BadBeginAction.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/BadBeginAction.java
index 8a0b4d2..449a269 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/BadBeginAction.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/BadBeginAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,31 +19,34 @@ import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.ActionException;
import ch.qos.logback.core.joran.spi.InterpretationContext;
-public class BadBeginAction extends Action {
-
- static String EXCEPTION_TYPE = "type";
- static final int RUNTIME_EDXCEPTION = 0;
- static final int ACTION_EXCEPTION = 1;
-
- int type;
- public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
- String exType = attributes.getValue(EXCEPTION_TYPE);
- type = RUNTIME_EDXCEPTION;
- if ("ActionException".equals(exType)) {
- type = ACTION_EXCEPTION;
- }
+public class BadBeginAction extends Action {
- switch (type) {
- case ACTION_EXCEPTION:
- throw new ActionException();
- default:
- throw new IllegalStateException("bad begin");
- }
+ static String EXCEPTION_TYPE = "type";
+ static final int RUNTIME_EDXCEPTION = 0;
+ static final int ACTION_EXCEPTION = 1;
+
+ int type;
+
+ public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
+
+ String exType = attributes.getValue(EXCEPTION_TYPE);
+ type = RUNTIME_EDXCEPTION;
+ if("ActionException".equals(exType)) {
+ type = ACTION_EXCEPTION;
}
-
- public void end(InterpretationContext ec, String name) {
+
+ switch(type) {
+ case ACTION_EXCEPTION:
+ throw new ActionException();
+ default:
+ throw new IllegalStateException("bad begin");
}
+
+ }
+
+ public void end(InterpretationContext ec, String name) {
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/BadEndAction.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/BadEndAction.java
index fc87811..4574a5b 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/BadEndAction.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/BadEndAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,34 +13,39 @@
*/
package ch.qos.logback.core.joran.action.ext;
+
+
import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.ActionException;
import ch.qos.logback.core.joran.spi.InterpretationContext;
-public class BadEndAction extends Action {
- static String EXCEPTION_TYPE = "type";
- static final int RUNTIME_EXCEPTION = 0;
- static final int ACTION_EXCEPTION = 1;
- int type;
+public class BadEndAction extends Action {
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- String exType = attributes.getValue(EXCEPTION_TYPE);
- type = RUNTIME_EXCEPTION;
- if ("ActionException".equals(exType)) {
- type = ACTION_EXCEPTION;
- }
+ static String EXCEPTION_TYPE = "type";
+ static final int RUNTIME_EXCEPTION = 0;
+ static final int ACTION_EXCEPTION = 1;
+
+ int type;
+
+
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ String exType = attributes.getValue(EXCEPTION_TYPE);
+ type = RUNTIME_EXCEPTION;
+ if("ActionException".equals(exType)) {
+ type = ACTION_EXCEPTION;
}
+ }
- public void end(InterpretationContext ec, String name) throws ActionException {
- switch (type) {
- case ACTION_EXCEPTION:
- throw new ActionException();
- default:
- throw new IllegalStateException("bad end");
- }
+ public void end(InterpretationContext ec, String name) throws ActionException {
+ switch(type) {
+ case ACTION_EXCEPTION:
+ throw new ActionException();
+ default:
+ throw new IllegalStateException("bad end");
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/HelloAction.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/HelloAction.java
index 3dceb0f..48e14d9 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/HelloAction.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/HelloAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,23 +18,26 @@ import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.InterpretationContext;
+
+
public class HelloAction extends Action {
- static final public String PROPERTY_KEY = "name";
-
- /**
- * Instantiates an layout of the given class and sets its name.
- *
- */
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- String str = "Hello " + attributes.getValue("name") + ".";
- ec.getContext().putProperty(PROPERTY_KEY, str);
- }
-
- /**
- * Once the children elements are also parsed, now is the time to activate
- * the appender options.
- */
- public void end(InterpretationContext ec, String name) {
- }
+
+ static final public String PROPERTY_KEY = "name";
+
+ /**
+ * Instantiates an layout of the given class and sets its name.
+ *
+ */
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ String str = "Hello "+attributes.getValue("name")+".";
+ ec.getContext().putProperty(PROPERTY_KEY, str);
+ }
+
+ /**
+ * Once the children elements are also parsed, now is the time to activate
+ * the appender options.
+ */
+ public void end(InterpretationContext ec, String name) {
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/IncAction.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/IncAction.java
index 434350c..9815388 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/IncAction.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/IncAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,37 +19,38 @@ import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.ActionException;
import ch.qos.logback.core.joran.spi.InterpretationContext;
-public class IncAction extends Action {
- static public int beginCount;
- static public int endCount;
- static public int errorCount;
- static public void reset() {
- beginCount = 0;
- endCount = 0;
- errorCount = 0;
- }
+public class IncAction extends Action {
- /**
- * Instantiates an layout of the given class and sets its name.
- *
- */
- public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
- // System.out.println("IncAction Begin called");
- beginCount++;
- String val = attributes.getValue("increment");
- if (!"1".equals(val)) {
- errorCount++;
- throw new ActionException();
- }
- }
+ static public int beginCount;
+ static public int endCount;
+ static public int errorCount;
- /**
- * Once the children elements are also parsed, now is the time to activate
- * the appender options.
- */
- public void end(InterpretationContext ec, String name) {
- endCount++;
+ static public void reset() {
+ beginCount = 0;
+ endCount = 0;
+ errorCount = 0;
+ }
+ /**
+ * Instantiates an layout of the given class and sets its name.
+ *
+ */
+ public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
+ //System.out.println("IncAction Begin called");
+ beginCount++;
+ String val = attributes.getValue("increment");
+ if(!"1".equals(val)) {
+ errorCount++;
+ throw new ActionException();
}
+ }
+
+ /**
+ * Once the children elements are also parsed, now is the time to activate
+ * the appender options.
+ */
+ public void end(InterpretationContext ec, String name) {
+ endCount++;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/StackAction.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/StackAction.java
index c729c44..a691aed 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/StackAction.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/StackAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.joran.action.ext;
+
import java.util.Stack;
import org.xml.sax.Attributes;
@@ -20,8 +21,10 @@ import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.InterpretationContext;
+
public class StackAction extends Action {
+
Stack<String> stack = new Stack<String>();
public Stack<String> getStack() {
@@ -35,7 +38,7 @@ public class StackAction extends Action {
public void end(InterpretationContext ec, String name) {
}
- // static public void reset() {
- // stack.clear();
- // }
+// static public void reset() {
+// stack.clear();
+// }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/TouchAction.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/TouchAction.java
index bfb3c32..6dfb4e7 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/TouchAction.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/TouchAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,32 +13,35 @@
*/
package ch.qos.logback.core.joran.action.ext;
+
import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.InterpretationContext;
+
+
public class TouchAction extends Action {
- public static final String KEY = "touched";
-
- /**
- * Instantiates an layout of the given class and sets its name.
- *
- */
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- Integer i = (Integer) ec.getContext().getObject(KEY);
- if (i == null) {
- ec.getContext().putObject(KEY, new Integer(1));
- } else {
- ec.getContext().putObject(KEY, new Integer(i.intValue() + 1));
- }
+ public static final String KEY = "touched";
+
+ /**
+ * Instantiates an layout of the given class and sets its name.
+ *
+ */
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ Integer i = (Integer) ec.getContext().getObject(KEY);
+ if(i == null) {
+ ec.getContext().putObject(KEY, new Integer(1));
+ } else {
+ ec.getContext().putObject(KEY, new Integer(i.intValue()+1));
}
+ }
- /**
- * Once the children elements are also parsed, now is the time to activate
- * the appender options.
- */
- public void end(InterpretationContext ec, String name) {
- }
+ /**
+ * Once the children elements are also parsed, now is the time to activate
+ * the appender options.
+ */
+ public void end(InterpretationContext ec, String name) {
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseAndIncludeCompositionTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseAndIncludeCompositionTest.java
index 487caff..a03d936 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseAndIncludeCompositionTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseAndIncludeCompositionTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -38,55 +38,58 @@ import ch.qos.logback.core.util.StatusPrinter;
public class IfThenElseAndIncludeCompositionTest {
- Context context = new ContextBase();
- TrivialConfigurator tc;
- int diff = RandomUtil.getPositiveInt();
- static final String CONDITIONAL_DIR_PREFIX = CoreTestConstants.JORAN_INPUT_PREFIX + "conditional/";
+ Context context = new ContextBase();
+ TrivialConfigurator tc;
+ int diff = RandomUtil.getPositiveInt();
+ static final String CONDITIONAL_DIR_PREFIX = CoreTestConstants.JORAN_INPUT_PREFIX
+ + "conditional/";
- final static String THEN_FILE_TO_INCLUDE_KEY = "thenFileToInclude";
- final static String ELSE_FILE_TO_INCLUDE_KEY = "elseFileToInclude";
+ final static String THEN_FILE_TO_INCLUDE_KEY = "thenFileToInclude";
+ final static String ELSE_FILE_TO_INCLUDE_KEY = "elseFileToInclude";
+
+ static final String NESTED_INCLUDE_FILE = CONDITIONAL_DIR_PREFIX+"nestedInclude.xml";
+ static final String THEN_FILE_TO_INCLUDE = CONDITIONAL_DIR_PREFIX+"includedA.xml";
+ static final String ELSE_FILE_TO_INCLUDE = CONDITIONAL_DIR_PREFIX+"includedB.xml";
- static final String NESTED_INCLUDE_FILE = CONDITIONAL_DIR_PREFIX + "nestedInclude.xml";
- static final String THEN_FILE_TO_INCLUDE = CONDITIONAL_DIR_PREFIX + "includedA.xml";
- static final String ELSE_FILE_TO_INCLUDE = CONDITIONAL_DIR_PREFIX + "includedB.xml";
+ StackAction stackAction = new StackAction();
- StackAction stackAction = new StackAction();
-
- @Before
- public void setUp() throws Exception {
- HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
- rulesMap.put(new ElementSelector("x"), new NOPAction());
- rulesMap.put(new ElementSelector("x/stack"), stackAction);
- rulesMap.put(new ElementSelector("*/if"), new IfAction());
- rulesMap.put(new ElementSelector("*/if/then"), new ThenAction());
- rulesMap.put(new ElementSelector("*/if/then/*"), new NOPAction());
- rulesMap.put(new ElementSelector("*/if/else"), new ElseAction());
- rulesMap.put(new ElementSelector("*/if/else/*"), new NOPAction());
- rulesMap.put(new ElementSelector("x/include"), new IncludeAction());
-
- tc = new TrivialConfigurator(rulesMap);
- tc.setContext(context);
- }
-
- @After
- public void tearDown() throws Exception {
- StatusPrinter.printInCaseOfErrorsOrWarnings(context);
- context = null;
- // StackAction.reset();
- }
-
- @Test
- public void includeNestedWithinIf() throws JoranException {
- context.putProperty(THEN_FILE_TO_INCLUDE_KEY, THEN_FILE_TO_INCLUDE);
- context.putProperty(ELSE_FILE_TO_INCLUDE_KEY, ELSE_FILE_TO_INCLUDE);
- tc.doConfigure(NESTED_INCLUDE_FILE);
- verifyConfig(new String[] { "BEGIN", "e0", "IncludedB0", "e1", "END" });
- }
-
- void verifyConfig(String[] expected) {
- Stack<String> witness = new Stack<String>();
- witness.addAll(Arrays.asList(expected));
- assertEquals(witness, stackAction.getStack());
- }
+
+ @Before
+ public void setUp() throws Exception {
+ HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
+ rulesMap.put(new ElementSelector("x"), new NOPAction());
+ rulesMap.put(new ElementSelector("x/stack"), stackAction);
+ rulesMap.put(new ElementSelector("*/if"), new IfAction());
+ rulesMap.put(new ElementSelector("*/if/then"), new ThenAction());
+ rulesMap.put(new ElementSelector("*/if/then/*"), new NOPAction());
+ rulesMap.put(new ElementSelector("*/if/else"), new ElseAction());
+ rulesMap.put(new ElementSelector("*/if/else/*"), new NOPAction());
+ rulesMap.put(new ElementSelector("x/include"), new IncludeAction());
+
+ tc = new TrivialConfigurator(rulesMap);
+ tc.setContext(context);
+ }
+ @After
+ public void tearDown() throws Exception {
+ StatusPrinter.printInCaseOfErrorsOrWarnings(context);
+ context = null;
+ //StackAction.reset();
+ }
+
+ @Test
+ public void includeNestedWithinIf() throws JoranException {
+ context.putProperty(THEN_FILE_TO_INCLUDE_KEY, THEN_FILE_TO_INCLUDE);
+ context.putProperty(ELSE_FILE_TO_INCLUDE_KEY, ELSE_FILE_TO_INCLUDE);
+ tc.doConfigure(NESTED_INCLUDE_FILE);
+ verifyConfig(new String[] {"BEGIN", "e0", "IncludedB0", "e1", "END"});
+ }
+
+
+ void verifyConfig(String[] expected) {
+ Stack<String> witness = new Stack<String>();
+ witness.addAll(Arrays.asList(expected));
+ assertEquals(witness, stackAction.getStack());
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java
index 166c342..51af795 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.joran.conditional;
+
import java.util.Arrays;
import java.util.HashMap;
import java.util.Stack;
@@ -39,104 +40,106 @@ import static org.junit.Assert.*;
public class IfThenElseTest {
- Context context = new ContextBase();
- StatusChecker checker = new StatusChecker(context);
- TrivialConfigurator tc;
- int diff = RandomUtil.getPositiveInt();
- static final String CONDITIONAL_DIR_PREFIX = CoreTestConstants.JORAN_INPUT_PREFIX + "conditional/";
-
- String ki1 = "ki1";
- String val1 = "val1";
- String sysKey = "sysKey";
- String dynaKey = "dynaKey";
-
- StackAction stackAction = new StackAction();
-
- @Before
- public void setUp() throws Exception {
- HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
- rulesMap.put(new ElementSelector("x"), new NOPAction());
- rulesMap.put(new ElementSelector("x/stack"), stackAction);
- rulesMap.put(new ElementSelector("x/property"), new PropertyAction());
- rulesMap.put(new ElementSelector("*/if"), new IfAction());
- rulesMap.put(new ElementSelector("*/if/then"), new ThenAction());
- rulesMap.put(new ElementSelector("*/if/then/*"), new NOPAction());
- rulesMap.put(new ElementSelector("*/if/else"), new ElseAction());
- rulesMap.put(new ElementSelector("*/if/else/*"), new NOPAction());
-
- tc = new TrivialConfigurator(rulesMap);
- tc.setContext(context);
- }
-
- @After
- public void tearDown() throws Exception {
- StatusPrinter.printIfErrorsOccured(context);
- System.clearProperty(sysKey);
- }
-
- @Test
- public void whenContextPropertyIsSet_IfThenBranchIsEvaluated() throws JoranException {
- context.putProperty(ki1, val1);
- tc.doConfigure(CONDITIONAL_DIR_PREFIX + "if0.xml");
- verifyConfig(new String[] { "BEGIN", "a", "END" });
- }
-
- @Test
- public void whenLocalPropertyIsSet_IfThenBranchIsEvaluated() throws JoranException {
- tc.doConfigure(CONDITIONAL_DIR_PREFIX + "if_localProperty.xml");
- verifyConfig(new String[] { "BEGIN", "a", "END" });
- }
-
- @Test
- public void whenNoPropertyIsDefined_ElseBranchIsEvaluated() throws JoranException {
- tc.doConfigure(CONDITIONAL_DIR_PREFIX + "if0.xml");
- verifyConfig(new String[] { "BEGIN", "b", "END" });
- }
-
- @Test
- public void whenContextPropertyIsSet_IfThenBranchIsEvaluated_NO_ELSE_DEFINED() throws JoranException {
- context.putProperty(ki1, val1);
- tc.doConfigure(CONDITIONAL_DIR_PREFIX + "ifWithoutElse.xml");
- verifyConfig(new String[] { "BEGIN", "a", "END" });
- }
-
- @Test
- public void whenNoPropertyIsDefined_IfThenBranchIsNotEvaluated_NO_ELSE_DEFINED() throws JoranException {
- tc.doConfigure(CONDITIONAL_DIR_PREFIX + "ifWithoutElse.xml");
- verifyConfig(new String[] { "BEGIN", "END" });
- assertTrue(checker.isErrorFree(0));
- }
-
- @Test
- public void nestedIf() throws JoranException {
- tc.doConfigure(CONDITIONAL_DIR_PREFIX + "nestedIf.xml");
- verifyConfig(new String[] { "BEGIN", "a", "c", "END" });
- assertTrue(checker.isErrorFree(0));
- }
-
- @Test
- public void useNonExistenceOfSystemPropertyToDefineAContextProperty() throws JoranException {
- assertNull(System.getProperty(sysKey));
- assertNull(context.getProperty(dynaKey));
- tc.doConfigure(CONDITIONAL_DIR_PREFIX + "ifSystem.xml");
- System.out.println(dynaKey + "=" + context.getProperty(dynaKey));
- assertNotNull(context.getProperty(dynaKey));
- }
-
- @Test
- public void noContextPropertyShouldBeDefinedIfSystemPropertyExists() throws JoranException {
- System.setProperty(sysKey, "a");
- assertNull(context.getProperty(dynaKey));
- System.out.println("before " + dynaKey + "=" + context.getProperty(dynaKey));
- tc.doConfigure(CONDITIONAL_DIR_PREFIX + "ifSystem.xml");
- System.out.println(dynaKey + "=" + context.getProperty(dynaKey));
- assertNull(context.getProperty(dynaKey));
- }
-
- private void verifyConfig(String[] expected) {
- Stack<String> witness = new Stack<String>();
- witness.addAll(Arrays.asList(expected));
- assertEquals(witness, stackAction.getStack());
- }
+ Context context = new ContextBase();
+ StatusChecker checker = new StatusChecker(context);
+ TrivialConfigurator tc;
+ int diff = RandomUtil.getPositiveInt();
+ static final String CONDITIONAL_DIR_PREFIX = CoreTestConstants.JORAN_INPUT_PREFIX
+ + "conditional/";
+
+ String ki1 = "ki1";
+ String val1 = "val1";
+ String sysKey = "sysKey";
+ String dynaKey = "dynaKey";
+
+ StackAction stackAction = new StackAction();
+
+ @Before
+ public void setUp() throws Exception {
+ HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
+ rulesMap.put(new ElementSelector("x"), new NOPAction());
+ rulesMap.put(new ElementSelector("x/stack"), stackAction);
+ rulesMap.put(new ElementSelector("x/property"), new PropertyAction());
+ rulesMap.put(new ElementSelector("*/if"), new IfAction());
+ rulesMap.put(new ElementSelector("*/if/then"), new ThenAction());
+ rulesMap.put(new ElementSelector("*/if/then/*"), new NOPAction());
+ rulesMap.put(new ElementSelector("*/if/else"), new ElseAction());
+ rulesMap.put(new ElementSelector("*/if/else/*"), new NOPAction());
+
+ tc = new TrivialConfigurator(rulesMap);
+ tc.setContext(context);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ StatusPrinter.printIfErrorsOccured(context);
+ System.clearProperty(sysKey);
+ }
+
+ @Test
+ public void whenContextPropertyIsSet_IfThenBranchIsEvaluated() throws JoranException {
+ context.putProperty(ki1, val1);
+ tc.doConfigure(CONDITIONAL_DIR_PREFIX+"if0.xml");
+ verifyConfig(new String[] {"BEGIN", "a", "END"});
+ }
+
+ @Test
+ public void whenLocalPropertyIsSet_IfThenBranchIsEvaluated() throws JoranException {
+ tc.doConfigure(CONDITIONAL_DIR_PREFIX+"if_localProperty.xml");
+ verifyConfig(new String[] {"BEGIN", "a", "END"});
+ }
+
+
+ @Test
+ public void whenNoPropertyIsDefined_ElseBranchIsEvaluated() throws JoranException {
+ tc.doConfigure(CONDITIONAL_DIR_PREFIX+"if0.xml");
+ verifyConfig(new String[] {"BEGIN", "b", "END"});
+ }
+
+ @Test
+ public void whenContextPropertyIsSet_IfThenBranchIsEvaluated_NO_ELSE_DEFINED() throws JoranException {
+ context.putProperty(ki1, val1);
+ tc.doConfigure(CONDITIONAL_DIR_PREFIX+"ifWithoutElse.xml");
+ verifyConfig(new String[] {"BEGIN", "a", "END"});
+ }
+
+ @Test
+ public void whenNoPropertyIsDefined_IfThenBranchIsNotEvaluated_NO_ELSE_DEFINED() throws JoranException {
+ tc.doConfigure(CONDITIONAL_DIR_PREFIX+"ifWithoutElse.xml");
+ verifyConfig(new String[] {"BEGIN", "END"});
+ assertTrue(checker.isErrorFree(0));
+ }
+
+ @Test
+ public void nestedIf() throws JoranException {
+ tc.doConfigure(CONDITIONAL_DIR_PREFIX+"nestedIf.xml");
+ verifyConfig(new String[] {"BEGIN", "a", "c", "END"});
+ assertTrue(checker.isErrorFree(0));
+ }
+
+ @Test
+ public void useNonExistenceOfSystemPropertyToDefineAContextProperty() throws JoranException {
+ assertNull(System.getProperty(sysKey));
+ assertNull(context.getProperty(dynaKey));
+ tc.doConfigure(CONDITIONAL_DIR_PREFIX+"ifSystem.xml");
+ System.out.println(dynaKey+"="+context.getProperty(dynaKey));
+ assertNotNull(context.getProperty(dynaKey));
+ }
+
+ @Test
+ public void noContextPropertyShouldBeDefinedIfSystemPropertyExists() throws JoranException {
+ System.setProperty(sysKey, "a");
+ assertNull(context.getProperty(dynaKey));
+ System.out.println("before "+dynaKey+"="+context.getProperty(dynaKey));
+ tc.doConfigure(CONDITIONAL_DIR_PREFIX+"ifSystem.xml");
+ System.out.println(dynaKey+"="+context.getProperty(dynaKey));
+ assertNull(context.getProperty(dynaKey));
+ }
+
+ private void verifyConfig(String[] expected) {
+ Stack<String> witness = new Stack<String>();
+ witness.addAll(Arrays.asList(expected));
+ assertEquals(witness, stackAction.getStack());
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/PackageTest.java
index 22b8f35..fcbac71 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,7 +18,8 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ PropertyEvalScriptBuilderTest.class, IfThenElseTest.class, IfThenElseAndIncludeCompositionTest.class })
+ at SuiteClasses( { PropertyEvalScriptBuilderTest.class, IfThenElseTest.class,
+ IfThenElseAndIncludeCompositionTest.class })
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/PropertyEvalScriptBuilderTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/PropertyEvalScriptBuilderTest.java
index 6498635..92e5eba 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/PropertyEvalScriptBuilderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/PropertyEvalScriptBuilderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,95 +27,96 @@ import ch.qos.logback.core.testUtil.RandomUtil;
public class PropertyEvalScriptBuilderTest {
- Context context = new ContextBase();
- InterpretationContext localPropContainer = new InterpretationContext(context, null);
- PropertyEvalScriptBuilder pesb = new PropertyEvalScriptBuilder(localPropContainer);
- int diff = RandomUtil.getPositiveInt();
-
- String k = "ka" + diff;
- String v = "va";
- String containsScript = "p(\"" + k + "\").contains(\"" + v + "\")";
-
- String isNullScriptStr = "isNull(\"" + k + "\")";
- String isDefiedScriptStr = "isDefined(\"" + k + "\")";
-
- @Before
- public void setUp() {
- context.setName("c" + diff);
- pesb.setContext(context);
- }
-
- @After
- public void tearDown() {
- System.clearProperty(k);
- }
-
- void buildAndAssertTrue(String scriptStr) throws Exception {
- Condition condition = pesb.build(scriptStr);
- assertNotNull(condition);
- assertTrue(condition.evaluate());
- }
-
- void buildAndAssertFalse(String scriptStr) throws Exception {
- Condition condition = pesb.build(scriptStr);
- assertNotNull(condition);
- assertFalse(condition.evaluate());
- }
-
- @Test
- public void existingLocalPropertyShouldEvaluateToTrue() throws Exception {
- localPropContainer.addSubstitutionProperty(k, v);
- buildAndAssertTrue(containsScript);
- }
-
- @Test
- public void existingContextPropertyShouldEvaluateToTrue() throws Exception {
- context.putProperty(k, v);
- buildAndAssertTrue(containsScript);
- }
-
- @Test
- public void existingSystemPropertyShouldEvaluateToTrue() throws Exception {
- System.setProperty(k, v);
- buildAndAssertTrue(containsScript);
- }
-
- @Test
- public void isNullForExistingLocalProperty() throws Exception {
- localPropContainer.addSubstitutionProperty(k, v);
- buildAndAssertFalse(isNullScriptStr);
- }
-
- @Test
- public void isNullForExistingContextProperty() throws Exception {
- context.putProperty(k, v);
- buildAndAssertFalse(isNullScriptStr);
- }
-
- @Test
- public void isNullForExistingSystemProperty() throws Exception {
- System.setProperty(k, v);
- buildAndAssertFalse(isNullScriptStr);
- }
-
- @Test
- public void inexistentPropertyShouldEvaluateToFalse() throws Exception {
- buildAndAssertFalse(containsScript);
- }
-
- @Test
- public void isNullForInexistentPropertyShouldEvaluateToTrue() throws Exception {
- buildAndAssertTrue(isNullScriptStr);
- }
-
- public void isDefinedForIExistimgtPropertyShouldEvaluateToTrue() throws Exception {
- localPropContainer.addSubstitutionProperty(k, v);
- buildAndAssertTrue(isDefiedScriptStr);
- }
-
- @Test
- public void isDefinedForInexistentPropertyShouldEvaluateToTrue() throws Exception {
- buildAndAssertFalse(isDefiedScriptStr);
- }
+
+ Context context = new ContextBase();
+ InterpretationContext localPropContainer = new InterpretationContext(context, null);
+ PropertyEvalScriptBuilder pesb = new PropertyEvalScriptBuilder(localPropContainer);
+ int diff = RandomUtil.getPositiveInt();
+
+ String k = "ka" + diff;
+ String v = "va";
+ String containsScript = "p(\"" + k + "\").contains(\"" + v + "\")";
+
+ String isNullScriptStr = "isNull(\"" + k + "\")";
+ String isDefiedScriptStr = "isDefined(\"" + k + "\")";
+
+ @Before
+ public void setUp() {
+ context.setName("c" + diff);
+ pesb.setContext(context);
+ }
+
+ @After
+ public void tearDown() {
+ System.clearProperty(k);
+ }
+
+
+ void buildAndAssertTrue(String scriptStr) throws Exception {
+ Condition condition = pesb.build(scriptStr);
+ assertNotNull(condition);
+ assertTrue(condition.evaluate());
+ }
+
+ void buildAndAssertFalse(String scriptStr) throws Exception {
+ Condition condition = pesb.build(scriptStr);
+ assertNotNull(condition);
+ assertFalse(condition.evaluate());
+ }
+
+ @Test
+ public void existingLocalPropertyShouldEvaluateToTrue() throws Exception {
+ localPropContainer.addSubstitutionProperty(k, v);
+ buildAndAssertTrue(containsScript);
+ }
+
+ @Test
+ public void existingContextPropertyShouldEvaluateToTrue() throws Exception {
+ context.putProperty(k, v);
+ buildAndAssertTrue(containsScript);
+ }
+
+ @Test
+ public void existingSystemPropertyShouldEvaluateToTrue() throws Exception {
+ System.setProperty(k, v);
+ buildAndAssertTrue(containsScript);
+ }
+
+ @Test
+ public void isNullForExistingLocalProperty() throws Exception {
+ localPropContainer.addSubstitutionProperty(k, v);
+ buildAndAssertFalse(isNullScriptStr);
+ }
+ @Test
+ public void isNullForExistingContextProperty() throws Exception {
+ context.putProperty(k, v);
+ buildAndAssertFalse(isNullScriptStr);
+ }
+ @Test
+ public void isNullForExistingSystemProperty() throws Exception {
+ System.setProperty(k, v);
+ buildAndAssertFalse(isNullScriptStr);
+ }
+
+ @Test
+ public void inexistentPropertyShouldEvaluateToFalse() throws Exception {
+ buildAndAssertFalse(containsScript);
+ }
+
+ @Test
+ public void isNullForInexistentPropertyShouldEvaluateToTrue() throws Exception {
+ buildAndAssertTrue(isNullScriptStr);
+ }
+
+ public void isDefinedForIExistimgtPropertyShouldEvaluateToTrue() throws Exception {
+ localPropContainer.addSubstitutionProperty(k, v);
+ buildAndAssertTrue(isDefiedScriptStr);
+ }
+
+ @Test
+ public void isDefinedForInexistentPropertyShouldEvaluateToTrue() throws Exception {
+ buildAndAssertFalse(isDefiedScriptStr);
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/event/InPlayFireTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/event/InPlayFireTest.java
index 72c02d1..4558f68 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/event/InPlayFireTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/event/InPlayFireTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,49 +29,51 @@ import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.util.CoreTestConstants;
-public class InPlayFireTest {
+public class InPlayFireTest {
- Context context = new ContextBase();
- HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
+ Context context = new ContextBase();
+ HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
- @Test
- public void testBasic() throws JoranException {
- ListenAction listenAction = new ListenAction();
+ @Test
+ public void testBasic() throws JoranException {
+ ListenAction listenAction = new ListenAction();
+
+ rulesMap.put(new ElementSelector("fire"), listenAction);
+ TrivialConfigurator gc = new TrivialConfigurator(rulesMap);
- rulesMap.put(new ElementSelector("fire"), listenAction);
- TrivialConfigurator gc = new TrivialConfigurator(rulesMap);
+ gc.setContext(context);
+ gc.doConfigure(CoreTestConstants.TEST_SRC_PREFIX + "input/joran/fire1.xml");
+
+ //for(SaxEvent se: listenAction.getSeList()) {
+ // System.out.println(se);
+ //}
+ assertEquals(5, listenAction.getSeList().size());
+ assertTrue(listenAction.getSeList().get(0) instanceof StartEvent);
+ assertTrue(listenAction.getSeList().get(1) instanceof StartEvent);
+ assertTrue(listenAction.getSeList().get(2) instanceof BodyEvent);
+ assertTrue(listenAction.getSeList().get(3) instanceof EndEvent);
+ }
- gc.setContext(context);
- gc.doConfigure(CoreTestConstants.TEST_SRC_PREFIX + "input/joran/fire1.xml");
-
- // for(SaxEvent se: listenAction.getSeList()) {
- // System.out.println(se);
- // }
- assertEquals(5, listenAction.getSeList().size());
- assertTrue(listenAction.getSeList().get(0) instanceof StartEvent);
- assertTrue(listenAction.getSeList().get(1) instanceof StartEvent);
- assertTrue(listenAction.getSeList().get(2) instanceof BodyEvent);
- assertTrue(listenAction.getSeList().get(3) instanceof EndEvent);
- }
-
- @Test
- public void testReplay() throws JoranException {
- ListenAction listenAction = new ListenAction();
-
- rulesMap.put(new ElementSelector("fire"), listenAction);
- TrivialConfigurator gc = new TrivialConfigurator(rulesMap);
-
- gc.setContext(context);
- gc.doConfigure(CoreTestConstants.TEST_SRC_PREFIX + "input/joran/fire1.xml");
-
- // for(SaxEvent se: listenAction.getSeList()) {
- // System.out.println(se);
- // }
- assertEquals(5, listenAction.getSeList().size());
- assertTrue(listenAction.getSeList().get(0) instanceof StartEvent);
- assertTrue(listenAction.getSeList().get(1) instanceof StartEvent);
- assertTrue(listenAction.getSeList().get(2) instanceof BodyEvent);
- assertTrue(listenAction.getSeList().get(3) instanceof EndEvent);
- }
+ @Test
+ public void testReplay() throws JoranException {
+ ListenAction listenAction = new ListenAction();
+
+ rulesMap.put(new ElementSelector("fire"), listenAction);
+ TrivialConfigurator gc = new TrivialConfigurator(rulesMap);
+ gc.setContext(context);
+ gc.doConfigure(CoreTestConstants.TEST_SRC_PREFIX + "input/joran/fire1.xml");
+
+// for(SaxEvent se: listenAction.getSeList()) {
+// System.out.println(se);
+// }
+ assertEquals(5, listenAction.getSeList().size());
+ assertTrue(listenAction.getSeList().get(0) instanceof StartEvent);
+ assertTrue(listenAction.getSeList().get(1) instanceof StartEvent);
+ assertTrue(listenAction.getSeList().get(2) instanceof BodyEvent);
+ assertTrue(listenAction.getSeList().get(3) instanceof EndEvent);
+ }
+
+
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/event/ListenAction.java b/logback-core/src/test/java/ch/qos/logback/core/joran/event/ListenAction.java
index 8da2972..c448a7c 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/event/ListenAction.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/event/ListenAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,25 +24,26 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
public class ListenAction extends Action implements InPlayListener {
- List<SaxEvent> seList = new ArrayList<SaxEvent>();
+ List<SaxEvent> seList = new ArrayList<SaxEvent>();
- @Override
- public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
- ec.addInPlayListener(this);
- }
+ @Override
+ public void begin(InterpretationContext ec, String name, Attributes attributes)
+ throws ActionException {
+ ec.addInPlayListener(this);
+ }
- @Override
- public void end(InterpretationContext ec, String name) throws ActionException {
- ec.removeInPlayListener(this);
+ @Override
+ public void end(InterpretationContext ec, String name) throws ActionException {
+ ec.removeInPlayListener(this);
- }
+ }
- public void inPlay(SaxEvent event) {
- seList.add(event);
- }
+ public void inPlay(SaxEvent event) {
+ seList.add(event);
+ }
- public List<SaxEvent> getSeList() {
- return seList;
- }
+ public List<SaxEvent> getSeList() {
+ return seList;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/event/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/event/PackageTest.java
index f277cf6..b32bca2 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/event/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/event/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ SaxEventRecorderTest.class, InPlayFireTest.class })
+ at SuiteClasses({SaxEventRecorderTest.class, InPlayFireTest.class})
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/event/SaxEventRecorderTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/event/SaxEventRecorderTest.java
index 66c2b4e..b5493b6 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/event/SaxEventRecorderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/event/SaxEventRecorderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -38,68 +38,72 @@ import ch.qos.logback.core.util.CoreTestConstants;
*/
public class SaxEventRecorderTest {
- Context context = new ContextBase();
- StatusChecker statusChecker = new StatusChecker(context);
-
- SAXParser createParser() throws Exception {
- SAXParserFactory spf = SAXParserFactory.newInstance();
- return spf.newSAXParser();
- }
-
- public List<SaxEvent> doTest(String filename) throws Exception {
- SaxEventRecorder recorder = new SaxEventRecorder(context);
- FileInputStream fis = new FileInputStream(CoreTestConstants.TEST_SRC_PREFIX + "input/joran/" + filename);
- recorder.recordEvents(fis);
- return recorder.getSaxEventList();
-
- }
-
- public void dump(List<SaxEvent> seList) {
- for (SaxEvent se : seList) {
- System.out.println(se);
- }
- }
-
- @Test
- public void test1() throws Exception {
- List<SaxEvent> seList = doTest("event1.xml");
- assertTrue(statusChecker.getHighestLevel(0) == Status.INFO);
- // dump(seList);
- assertEquals(11, seList.size());
- }
-
- @Test
- public void test2() throws Exception {
- List<SaxEvent> seList = doTest("ampEvent.xml");
- StatusManager sm = context.getStatusManager();
- assertTrue(statusChecker.getHighestLevel(0) == Status.INFO);
- // dump(seList);
- assertEquals(3, seList.size());
-
- BodyEvent be = (BodyEvent) seList.get(1);
- assertEquals("xxx & yyy", be.getText());
- }
-
- @Test
- public void test3() throws Exception {
- List<SaxEvent> seList = doTest("inc.xml");
- StatusManager sm = context.getStatusManager();
- assertTrue(statusChecker.getHighestLevel(0) == Status.INFO);
- // dump(seList);
- assertEquals(4, seList.size());
-
- StartEvent se = (StartEvent) seList.get(1);
- Attributes attr = se.getAttributes();
- assertNotNull(attr);
- assertEquals("1", attr.getValue("increment"));
- }
-
- @Test
- public void bodyWithSpacesAndQuotes() throws Exception {
- List<SaxEvent> seList = doTest("spacesAndQuotes.xml");
- assertEquals(3, seList.size());
- BodyEvent be = (BodyEvent) seList.get(1);
- assertEquals("[x][x] \"xyz\"%n", be.getText());
+ Context context = new ContextBase();
+ StatusChecker statusChecker = new StatusChecker(context);
+
+ SAXParser createParser() throws Exception {
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ return spf.newSAXParser();
+ }
+
+ public List<SaxEvent> doTest(String filename) throws Exception {
+ SaxEventRecorder recorder = new SaxEventRecorder(context);
+ FileInputStream fis = new FileInputStream(CoreTestConstants.TEST_SRC_PREFIX
+ + "input/joran/"+ filename);
+ recorder.recordEvents(fis);
+ return recorder.getSaxEventList();
+
+
+ }
+
+ public void dump(List<SaxEvent> seList) {
+ for (SaxEvent se : seList) {
+ System.out.println(se);
}
+ }
+
+ @Test
+ public void test1() throws Exception {
+ List<SaxEvent> seList = doTest("event1.xml");
+ assertTrue(statusChecker.getHighestLevel(0) == Status.INFO);
+ //dump(seList);
+ assertEquals(11, seList.size());
+ }
+
+ @Test
+ public void test2() throws Exception {
+ List<SaxEvent> seList = doTest("ampEvent.xml");
+ StatusManager sm = context.getStatusManager();
+ assertTrue(statusChecker.getHighestLevel(0) == Status.INFO);
+ //dump(seList);
+ assertEquals(3, seList.size());
+
+ BodyEvent be = (BodyEvent) seList.get(1);
+ assertEquals("xxx & yyy", be.getText());
+ }
+
+ @Test
+ public void test3() throws Exception {
+ List<SaxEvent> seList = doTest("inc.xml");
+ StatusManager sm = context.getStatusManager();
+ assertTrue(statusChecker.getHighestLevel(0) == Status.INFO);
+ //dump(seList);
+ assertEquals(4, seList.size());
+
+ StartEvent se = (StartEvent) seList.get(1);
+ Attributes attr = se.getAttributes();
+ assertNotNull(attr);
+ assertEquals("1", attr.getValue("increment"));
+ }
+
+ @Test
+ public void bodyWithSpacesAndQuotes() throws Exception {
+ List<SaxEvent> seList = doTest("spacesAndQuotes.xml");
+ assertEquals(3, seList.size());
+ BodyEvent be = (BodyEvent) seList.get(1);
+ assertEquals("[x][x] \"xyz\"%n", be.getText());
+ }
+
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/event/stax/StaxEventRecorderTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/event/stax/StaxEventRecorderTest.java
index 39155ec..266e933 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/event/stax/StaxEventRecorderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/event/stax/StaxEventRecorderTest.java
@@ -1,16 +1,3 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
package ch.qos.logback.core.joran.event.stax;
import ch.qos.logback.core.Context;
@@ -29,64 +16,69 @@ import static org.junit.Assert.*;
public class StaxEventRecorderTest {
- Context context = new ContextBase();
- StatusChecker statusChecker = new StatusChecker(context);
- public List<StaxEvent> doTest(String filename) throws Exception {
- StaxEventRecorder recorder = new StaxEventRecorder(context);
- FileInputStream fis = new FileInputStream(CoreTestConstants.TEST_SRC_PREFIX + "input/joran/" + filename);
- recorder.recordEvents(fis);
- return recorder.getEventList();
- }
+ Context context = new ContextBase();
+ StatusChecker statusChecker = new StatusChecker(context);
- public void dump(List<StaxEvent> seList) {
- for (StaxEvent se : seList) {
- System.out.println(se);
- }
- }
- @Test
- public void testParsingOfXMLWithAttributesAndBodyText() throws Exception {
- List<StaxEvent> seList = doTest("event1.xml");
- assertTrue(statusChecker.getHighestLevel(0) == Status.INFO);
- // dump(seList);
- assertEquals(11, seList.size());
- assertEquals("test", seList.get(0).getName());
- assertEquals("badBegin", seList.get(1).getName());
- StartEvent startEvent = (StartEvent) seList.get(7);
- assertEquals("John Doe", startEvent.getAttributeByName("name").getValue());
- assertEquals("XXX&", ((BodyEvent) seList.get(8)).getText());
+ public List<StaxEvent> doTest(String filename) throws Exception {
+ StaxEventRecorder recorder = new StaxEventRecorder(context);
+ FileInputStream fis = new FileInputStream(CoreTestConstants.TEST_SRC_PREFIX
+ + "input/joran/" + filename);
+ recorder.recordEvents(fis);
+ return recorder.getEventList();
+ }
+
+ public void dump(List<StaxEvent> seList) {
+ for (StaxEvent se : seList) {
+ System.out.println(se);
}
+ }
- @Test
- public void testProcessingOfTextWithEntityCharacters() throws Exception {
- List<StaxEvent> seList = doTest("ampEvent.xml");
- StatusManager sm = context.getStatusManager();
- assertTrue(statusChecker.getHighestLevel(0) == Status.INFO);
- // dump(seList);
- assertEquals(3, seList.size());
+ @Test
+ public void testParsingOfXMLWithAttributesAndBodyText() throws Exception {
+ List<StaxEvent> seList = doTest("event1.xml");
+ assertTrue(statusChecker.getHighestLevel(0) == Status.INFO);
+ //dump(seList);
+ assertEquals(11, seList.size());
+ assertEquals("test", seList.get(0).getName());
+ assertEquals("badBegin", seList.get(1).getName());
+ StartEvent startEvent = (StartEvent) seList.get(7);
+ assertEquals("John Doe", startEvent.getAttributeByName("name").getValue());
+ assertEquals("XXX&", ((BodyEvent) seList.get(8)).getText());
+ }
- BodyEvent be = (BodyEvent) seList.get(1);
- assertEquals("xxx & yyy", be.getText());
- }
+ @Test
+ public void testProcessingOfTextWithEntityCharacters() throws Exception {
+ List<StaxEvent> seList = doTest("ampEvent.xml");
+ StatusManager sm = context.getStatusManager();
+ assertTrue(statusChecker.getHighestLevel(0) == Status.INFO);
+ //dump(seList);
+ assertEquals(3, seList.size());
- @Test
- public void testAttributeProcessing() throws Exception {
- List<StaxEvent> seList = doTest("inc.xml");
- StatusManager sm = context.getStatusManager();
- assertTrue(statusChecker.getHighestLevel(0) == Status.INFO);
- assertEquals(4, seList.size());
- StartEvent se = (StartEvent) seList.get(1);
- Attribute attr = se.getAttributeByName("increment");
- assertNotNull(attr);
- assertEquals("1", attr.getValue());
- }
+ BodyEvent be = (BodyEvent) seList.get(1);
+ assertEquals("xxx & yyy", be.getText());
+ }
- @Test
- public void bodyWithSpacesAndQuotes() throws Exception {
- List<StaxEvent> seList = doTest("spacesAndQuotes.xml");
- assertEquals(3, seList.size());
- BodyEvent be = (BodyEvent) seList.get(1);
- assertEquals("[x][x] \"xyz\"%n", be.getText());
- }
+ @Test
+ public void testAttributeProcessing() throws Exception {
+ List<StaxEvent> seList = doTest("inc.xml");
+ StatusManager sm = context.getStatusManager();
+ assertTrue(statusChecker.getHighestLevel(0) == Status.INFO);
+ assertEquals(4, seList.size());
+ StartEvent se = (StartEvent) seList.get(1);
+ Attribute attr = se.getAttributeByName("increment");
+ assertNotNull(attr);
+ assertEquals("1", attr.getValue());
+ }
+
+ @Test
+ public void bodyWithSpacesAndQuotes() throws Exception {
+ List<StaxEvent> seList = doTest("spacesAndQuotes.xml");
+ assertEquals(3, seList.size());
+ BodyEvent be = (BodyEvent) seList.get(1);
+ assertEquals("[x][x] \"xyz\"%n", be.getText());
+ }
}
+
+
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/Cake.java b/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/Cake.java
index 804de73..e08434a 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/Cake.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/Cake.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,23 +15,21 @@ package ch.qos.logback.core.joran.implicitAction;
public class Cake {
- String type;
- int code;
-
- public String getType() {
- return type;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-
- public int getCode() {
- return code;
- }
-
- public void setCode(int code) {
- this.code = code;
- }
-
+ String type;
+ int code;
+
+ public String getType() {
+ return type;
+ }
+ public void setType(String type) {
+ this.type = type;
+ }
+ public int getCode() {
+ return code;
+ }
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/Fruit.java b/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/Fruit.java
index 589f5b2..0348c14 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/Fruit.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/Fruit.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,23 +18,23 @@ import java.util.List;
public class Fruit {
- String name;
- List<String> textList = new ArrayList<String>();
- List<Cake> cakeList = new ArrayList<Cake>();
+ String name;
+ List<String> textList = new ArrayList<String>();
+ List<Cake> cakeList = new ArrayList<Cake>();
+
+ public void setName(String n) {
+ this.name = n;
+ }
- public void setName(String n) {
- this.name = n;
- }
-
- public String getName() {
- return name;
- }
-
- public void addText(String s) {
- textList.add(s);
- }
-
- public void addCake(Cake c) {
- cakeList.add(c);
- }
+ public String getName() {
+ return name;
+ }
+
+ public void addText(String s) {
+ textList.add(s);
+ }
+
+ public void addCake(Cake c) {
+ cakeList.add(c);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/FruitContext.java b/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/FruitContext.java
index 7a90623..6b37993 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/FruitContext.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/FruitContext.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,17 +20,17 @@ import ch.qos.logback.core.ContextBase;
public class FruitContext extends ContextBase {
- List<Fruit> fruitList = new ArrayList<Fruit>();
+ List<Fruit> fruitList = new ArrayList<Fruit>();
+
+ public void addFruit(Fruit fs) {
+ fruitList.add(fs);
+ }
- public void addFruit(Fruit fs) {
- fruitList.add(fs);
- }
+ public List<Fruit> getFruitList() {
+ return fruitList;
+ }
- public List<Fruit> getFruitList() {
- return fruitList;
- }
-
- public void setFruitShellList(List<Fruit> fruitList) {
- this.fruitList = fruitList;
- }
+ public void setFruitShellList(List<Fruit> fruitList) {
+ this.fruitList = fruitList;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/FruitContextAction.java b/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/FruitContextAction.java
index de4a318..b2e4083 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/FruitContextAction.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/FruitContextAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,36 +21,44 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
public class FruitContextAction extends Action {
- private boolean inError = false;
+ private boolean inError = false;
- @Override
- public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
+
+ @Override
+ public void begin(InterpretationContext ec, String name, Attributes attributes)
+ throws ActionException {
- inError = false;
-
- try {
- ec.pushObject(context);
- } catch (Exception oops) {
- inError = true;
- addError("Could not push context", oops);
- throw new ActionException(oops);
- }
+ inError = false;
+
+ try {
+ ec.pushObject(context);
+ } catch (Exception oops) {
+ inError = true;
+ addError(
+ "Could not push context", oops);
+ throw new ActionException(oops);
}
+ }
- @Override
- public void end(InterpretationContext ec, String name) throws ActionException {
- if (inError) {
- return;
- }
+ @Override
+ public void end(InterpretationContext ec, String name) throws ActionException {
+ if (inError) {
+ return;
+ }
- Object o = ec.peekObject();
+ Object o = ec.peekObject();
- if (o != context) {
- addWarn("The object at the of the stack is not the context named [" + context.getName() + "] pushed earlier.");
- } else {
- addInfo("Popping context named [" + context.getName() + "] from the object stack");
- ec.popObject();
- }
+ if (o != context) {
+ addWarn(
+ "The object at the of the stack is not the context named ["
+ + context.getName() + "] pushed earlier.");
+ } else {
+ addInfo(
+ "Popping context named [" + context.getName()
+ + "] from the object stack");
+ ec.popObject();
}
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/ImplicitActionTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/ImplicitActionTest.java
index 799f1eb..e31d7c6 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/ImplicitActionTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/ImplicitActionTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,92 +30,97 @@ import ch.qos.logback.core.util.StatusPrinter;
public class ImplicitActionTest {
- static final String IMPLCIT_DIR = CoreTestConstants.TEST_SRC_PREFIX + "input/joran/implicitAction/";
-
- FruitContext fruitContext = new FruitContext();
- SimpleConfigurator simpleConfigurator;
-
- @Before
- public void setUp() throws Exception {
- fruitContext.setName("fruits");
- HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
- rulesMap.put(new ElementSelector("/context/"), new FruitContextAction());
- simpleConfigurator = new SimpleConfigurator(rulesMap);
- simpleConfigurator.setContext(fruitContext);
+ static final String IMPLCIT_DIR = CoreTestConstants.TEST_SRC_PREFIX
+ + "input/joran/implicitAction/";
+
+ FruitContext fruitContext = new FruitContext();
+ SimpleConfigurator simpleConfigurator;
+
+ @Before
+ public void setUp() throws Exception {
+ fruitContext.setName("fruits");
+ HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
+ rulesMap.put(new ElementSelector("/context/"), new FruitContextAction());
+ simpleConfigurator = new SimpleConfigurator(rulesMap);
+ simpleConfigurator.setContext(fruitContext);
+ }
+
+ void verifyFruit() {
+ List<Fruit> fList = fruitContext.getFruitList();
+ assertNotNull(fList);
+ assertEquals(1, fList.size());
+
+ Fruit f0 = fList.get(0);
+ assertEquals("blue", f0.getName());
+ assertEquals(2, f0.textList.size());
+ assertEquals("hello", f0.textList.get(0));
+ assertEquals("world", f0.textList.get(1));
+ }
+
+ @Test
+ public void nestedComplex() throws Exception {
+ try {
+ simpleConfigurator.doConfigure(IMPLCIT_DIR + "nestedComplex.xml");
+ verifyFruit();
+
+ } catch (Exception je) {
+ StatusPrinter.print(fruitContext);
+ throw je;
}
+ }
- void verifyFruit() {
- List<Fruit> fList = fruitContext.getFruitList();
- assertNotNull(fList);
- assertEquals(1, fList.size());
-
- Fruit f0 = fList.get(0);
- assertEquals("blue", f0.getName());
- assertEquals(2, f0.textList.size());
- assertEquals("hello", f0.textList.get(0));
- assertEquals("world", f0.textList.get(1));
- }
+ @Test
+ public void nestedComplexWithoutClassAtrribute() throws Exception {
+ try {
+ simpleConfigurator.doConfigure(IMPLCIT_DIR
+ + "nestedComplexWithoutClassAtrribute.xml");
- @Test
- public void nestedComplex() throws Exception {
- try {
- simpleConfigurator.doConfigure(IMPLCIT_DIR + "nestedComplex.xml");
- verifyFruit();
+ verifyFruit();
- } catch (Exception je) {
- StatusPrinter.print(fruitContext);
- throw je;
- }
+ } catch (Exception je) {
+ StatusPrinter.print(fruitContext);
+ throw je;
}
-
- @Test
- public void nestedComplexWithoutClassAtrribute() throws Exception {
- try {
- simpleConfigurator.doConfigure(IMPLCIT_DIR + "nestedComplexWithoutClassAtrribute.xml");
-
- verifyFruit();
-
- } catch (Exception je) {
- StatusPrinter.print(fruitContext);
- throw je;
- }
+ }
+
+
+ void verifyFruitList() {
+ List<Fruit> fList = fruitContext.getFruitList();
+ assertNotNull(fList);
+ assertEquals(1, fList.size());
+
+ Fruit f0 = fList.get(0);
+ assertEquals(2, f0.cakeList.size());
+
+ Cake cakeA = f0.cakeList.get(0);
+ assertEquals("A", cakeA.getType());
+
+ Cake cakeB = f0.cakeList.get(1);
+ assertEquals("B", cakeB.getType());
+ }
+ @Test
+ public void nestedComplexCollection() throws Exception {
+ try {
+ simpleConfigurator.doConfigure(IMPLCIT_DIR
+ + "nestedComplexCollection.xml");
+ verifyFruitList();
+ } catch (Exception je) {
+ StatusPrinter.print(fruitContext);
+ throw je;
}
-
- void verifyFruitList() {
- List<Fruit> fList = fruitContext.getFruitList();
- assertNotNull(fList);
- assertEquals(1, fList.size());
-
- Fruit f0 = fList.get(0);
- assertEquals(2, f0.cakeList.size());
-
- Cake cakeA = f0.cakeList.get(0);
- assertEquals("A", cakeA.getType());
-
- Cake cakeB = f0.cakeList.get(1);
- assertEquals("B", cakeB.getType());
- }
-
- @Test
- public void nestedComplexCollection() throws Exception {
- try {
- simpleConfigurator.doConfigure(IMPLCIT_DIR + "nestedComplexCollection.xml");
- verifyFruitList();
- } catch (Exception je) {
- StatusPrinter.print(fruitContext);
- throw je;
- }
- }
-
- @Test
- public void nestedComplexCollectionWithoutClassAtrribute() throws Exception {
- try {
- simpleConfigurator.doConfigure(IMPLCIT_DIR + "nestedComplexCollectionWithoutClassAtrribute.xml");
- verifyFruitList();
- } catch (Exception je) {
- StatusPrinter.print(fruitContext);
- throw je;
- }
+ }
+
+
+ @Test
+ public void nestedComplexCollectionWithoutClassAtrribute() throws Exception {
+ try {
+ simpleConfigurator.doConfigure(IMPLCIT_DIR
+ + "nestedComplexCollectionWithoutClassAtrribute.xml");
+ verifyFruitList();
+ } catch (Exception je) {
+ StatusPrinter.print(fruitContext);
+ throw je;
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/PackageTest.java
index f499b9e..20500f4 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/implicitAction/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ ImplicitActionTest.class })
+ at SuiteClasses({ImplicitActionTest.class})
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/Fruit.java b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/Fruit.java
index e90f237..58e1fd8 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/Fruit.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/Fruit.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,29 +18,29 @@ import java.util.List;
public class Fruit {
- String name;
- List<String> textList = new ArrayList<String>();
+ String name;
+ List<String> textList = new ArrayList<String>();
+
+ public void setName(String name) {
+ this.name = name;
+ }
- public void setName(String name) {
- this.name = name;
- }
+ public String getName() {
+ return name;
+ }
- public String getName() {
- return name;
- }
+ public String toString() {
+ final String TAB = " ";
- public String toString() {
- final String TAB = " ";
+ StringBuilder retValue = new StringBuilder();
- StringBuilder retValue = new StringBuilder();
-
- retValue.append("xFruit ( ").append("name = ").append(this.name).append(TAB).append(" )");
-
- return retValue.toString();
- }
-
- public void addText(String s) {
- textList.add(s);
- }
+ retValue.append("xFruit ( ").append("name = ").append(this.name).append(TAB).append(" )");
+ return retValue.toString();
+ }
+
+ public void addText(String s) {
+ textList.add(s);
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurationTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurationTest.java
index 3b9e689..704b164 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurationTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurationTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -32,80 +32,83 @@ import ch.qos.logback.core.util.StatusPrinter;
/**
* The Fruit* code is intended to test Joran's replay capability
* */
-public class FruitConfigurationTest {
+public class FruitConfigurationTest {
- FruitContext fruitContext = new FruitContext();
+ FruitContext fruitContext = new FruitContext();
- public List<FruitShell> doFirstPart(String filename) throws Exception {
+ public List<FruitShell> doFirstPart(String filename) throws Exception {
- try {
- HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
- rulesMap.put(new ElementSelector("group/fruitShell"), new FruitShellAction());
- rulesMap.put(new ElementSelector("group/fruitShell/fruit"), new FruitFactoryAction());
- rulesMap.put(new ElementSelector("group/fruitShell/fruit/*"), new NOPAction());
- SimpleConfigurator simpleConfigurator = new SimpleConfigurator(rulesMap);
+ try {
+ HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
+ rulesMap.put(new ElementSelector("group/fruitShell"), new FruitShellAction());
+ rulesMap.put(new ElementSelector("group/fruitShell/fruit"),
+ new FruitFactoryAction());
+ rulesMap.put(new ElementSelector("group/fruitShell/fruit/*"), new NOPAction());
+ SimpleConfigurator simpleConfigurator = new SimpleConfigurator(rulesMap);
- simpleConfigurator.setContext(fruitContext);
+ simpleConfigurator.setContext(fruitContext);
- simpleConfigurator.doConfigure(CoreTestConstants.TEST_SRC_PREFIX + "input/joran/replay/" + filename);
+ simpleConfigurator.doConfigure(CoreTestConstants.TEST_SRC_PREFIX + "input/joran/replay/"
+ + filename);
- return fruitContext.getFruitShellList();
- } catch (Exception je) {
- StatusPrinter.print(fruitContext);
- throw je;
- }
- }
-
- @Test
- public void fruit1() throws Exception {
- List<FruitShell> fsList = doFirstPart("fruit1.xml");
- assertNotNull(fsList);
- assertEquals(1, fsList.size());
-
- FruitShell fs0 = fsList.get(0);
- assertNotNull(fs0);
- assertEquals("fs0", fs0.getName());
- Fruit fruit0 = fs0.fruitFactory.buildFruit();
- assertTrue(fruit0 instanceof Fruit);
- assertEquals("blue", fruit0.getName());
- }
-
- @Test
- public void fruit2() throws Exception {
- List<FruitShell> fsList = doFirstPart("fruit2.xml");
- assertNotNull(fsList);
- assertEquals(2, fsList.size());
-
- FruitShell fs0 = fsList.get(0);
- assertNotNull(fs0);
- assertEquals("fs0", fs0.getName());
- Fruit fruit0 = fs0.fruitFactory.buildFruit();
- assertTrue(fruit0 instanceof Fruit);
- assertEquals("blue", fruit0.getName());
-
- FruitShell fs1 = fsList.get(1);
- assertNotNull(fs1);
- assertEquals("fs1", fs1.getName());
- Fruit fruit1 = fs1.fruitFactory.buildFruit();
- assertTrue(fruit1 instanceof WeightytFruit);
- assertEquals("orange", fruit1.getName());
- assertEquals(1.2, ((WeightytFruit) fruit1).getWeight(), 0.01);
- }
-
- @Test
- public void withSubst() throws Exception {
- List<FruitShell> fsList = doFirstPart("fruitWithSubst.xml");
- assertNotNull(fsList);
- assertEquals(1, fsList.size());
-
- FruitShell fs0 = fsList.get(0);
- assertNotNull(fs0);
- assertEquals("fs0", fs0.getName());
- int oldCount = FruitFactory.count;
- Fruit fruit0 = fs0.fruitFactory.buildFruit();
- assertTrue(fruit0 instanceof WeightytFruit);
- assertEquals("orange-" + oldCount, fruit0.getName());
- assertEquals(1.2, ((WeightytFruit) fruit0).getWeight(), 0.01);
+ return fruitContext.getFruitShellList();
+ } catch (Exception je) {
+ StatusPrinter.print(fruitContext);
+ throw je;
}
+ }
+
+ @Test
+ public void fruit1() throws Exception {
+ List<FruitShell> fsList = doFirstPart("fruit1.xml");
+ assertNotNull(fsList);
+ assertEquals(1, fsList.size());
+
+ FruitShell fs0 = fsList.get(0);
+ assertNotNull(fs0);
+ assertEquals("fs0", fs0.getName());
+ Fruit fruit0 = fs0.fruitFactory.buildFruit();
+ assertTrue(fruit0 instanceof Fruit);
+ assertEquals("blue", fruit0.getName());
+ }
+
+
+ @Test
+ public void fruit2() throws Exception {
+ List<FruitShell> fsList = doFirstPart("fruit2.xml");
+ assertNotNull(fsList);
+ assertEquals(2, fsList.size());
+
+ FruitShell fs0 = fsList.get(0);
+ assertNotNull(fs0);
+ assertEquals("fs0", fs0.getName());
+ Fruit fruit0 = fs0.fruitFactory.buildFruit();
+ assertTrue(fruit0 instanceof Fruit);
+ assertEquals("blue", fruit0.getName());
+
+ FruitShell fs1 = fsList.get(1);
+ assertNotNull(fs1);
+ assertEquals("fs1", fs1.getName());
+ Fruit fruit1 = fs1.fruitFactory.buildFruit();
+ assertTrue(fruit1 instanceof WeightytFruit);
+ assertEquals("orange", fruit1.getName());
+ assertEquals(1.2, ((WeightytFruit) fruit1).getWeight(), 0.01);
+ }
+
+ @Test
+ public void withSubst() throws Exception {
+ List<FruitShell> fsList = doFirstPart("fruitWithSubst.xml");
+ assertNotNull(fsList);
+ assertEquals(1, fsList.size());
+
+ FruitShell fs0 = fsList.get(0);
+ assertNotNull(fs0);
+ assertEquals("fs0", fs0.getName());
+ int oldCount = FruitFactory.count;
+ Fruit fruit0 = fs0.fruitFactory.buildFruit();
+ assertTrue(fruit0 instanceof WeightytFruit);
+ assertEquals("orange-" + oldCount, fruit0.getName());
+ assertEquals(1.2, ((WeightytFruit) fruit0).getWeight(), 0.01);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurator.java b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurator.java
index 884ee02..4cb7de5 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurator.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,45 +17,46 @@ import java.util.List;
import ch.qos.logback.core.joran.GenericConfigurator;
import ch.qos.logback.core.joran.action.NOPAction;
-import ch.qos.logback.core.joran.action.NestedBasicPropertyIA;
import ch.qos.logback.core.joran.action.NestedComplexPropertyIA;
+import ch.qos.logback.core.joran.action.NestedBasicPropertyIA;
import ch.qos.logback.core.joran.event.SaxEvent;
-import ch.qos.logback.core.joran.spi.ElementSelector;
import ch.qos.logback.core.joran.spi.EventPlayer;
import ch.qos.logback.core.joran.spi.Interpreter;
import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.joran.spi.ElementSelector;
import ch.qos.logback.core.joran.spi.RuleStore;
public class FruitConfigurator extends GenericConfigurator {
- FruitFactory ff;
-
- public FruitConfigurator(FruitFactory ff) {
- this.ff = ff;
- }
-
- @Override
- final public void doConfigure(final List<SaxEvent> eventList) throws JoranException {
- buildInterpreter();
- interpreter.getInterpretationContext().pushObject(ff);
- EventPlayer player = new EventPlayer(interpreter);
- player.play(eventList);
- }
-
- @Override
- protected void addImplicitRules(Interpreter interpreter) {
- NestedComplexPropertyIA nestedIA = new NestedComplexPropertyIA(getBeanDescriptionCache());
- nestedIA.setContext(context);
- interpreter.addImplicitAction(nestedIA);
-
- NestedBasicPropertyIA nestedSimpleIA = new NestedBasicPropertyIA(getBeanDescriptionCache());
- nestedIA.setContext(context);
- interpreter.addImplicitAction(nestedSimpleIA);
- }
-
- @Override
- protected void addInstanceRules(RuleStore rs) {
- rs.addRule(new ElementSelector("fruitShell"), new NOPAction());
- }
+ FruitFactory ff;
+ public FruitConfigurator(FruitFactory ff) {
+ this.ff = ff;
+ }
+
+ @Override
+ final public void doConfigure(final List<SaxEvent> eventList)
+ throws JoranException {
+ buildInterpreter();
+ interpreter.getInterpretationContext().pushObject(ff);
+ EventPlayer player = new EventPlayer(interpreter);
+ player.play(eventList);
+ }
+
+ @Override
+ protected void addImplicitRules(Interpreter interpreter) {
+ NestedComplexPropertyIA nestedIA = new NestedComplexPropertyIA();
+ nestedIA.setContext(context);
+ interpreter.addImplicitAction(nestedIA);
+
+ NestedBasicPropertyIA nestedSimpleIA = new NestedBasicPropertyIA();
+ nestedIA.setContext(context);
+ interpreter.addImplicitAction(nestedSimpleIA);
+ }
+
+
+ @Override
+ protected void addInstanceRules(RuleStore rs) {
+ rs.addRule(new ElementSelector("fruitShell"), new NOPAction());
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitContext.java b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitContext.java
index ac82a83..2ae6d0d 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitContext.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitContext.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,17 +20,17 @@ import ch.qos.logback.core.ContextBase;
public class FruitContext extends ContextBase {
- List<FruitShell> fruitShellList = new ArrayList<FruitShell>();
+ List<FruitShell> fruitShellList = new ArrayList<FruitShell>();
+
+ public void addFruitShell(FruitShell fs) {
+ fruitShellList.add(fs);
+ }
- public void addFruitShell(FruitShell fs) {
- fruitShellList.add(fs);
- }
+ public List<FruitShell> getFruitShellList() {
+ return fruitShellList;
+ }
- public List<FruitShell> getFruitShellList() {
- return fruitShellList;
- }
-
- public void setFruitShellList(List<FruitShell> fruitShellList) {
- this.fruitShellList = fruitShellList;
- }
+ public void setFruitShellList(List<FruitShell> fruitShellList) {
+ this.fruitShellList = fruitShellList;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitFactory.java b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitFactory.java
index e73b373..5d6bacd 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitFactory.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitFactory.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,48 +22,48 @@ import ch.qos.logback.core.joran.spi.JoranException;
public class FruitFactory {
- static int count = 0;
+ static int count = 0;
+
+ private List<SaxEvent> eventList;
+ Fruit fruit;
+
+ public void setFruit(Fruit fruit) {
+ this.fruit = fruit;
+ }
- private List<SaxEvent> eventList;
- Fruit fruit;
-
- public void setFruit(Fruit fruit) {
- this.fruit = fruit;
- }
-
- public Fruit buildFruit() {
-
- Context context = new ContextBase();
- this.fruit = null;
- context.putProperty("fruitKey", "orange-" + count);
- // for next round
- count++;
- FruitConfigurator fruitConfigurator = new FruitConfigurator(this);
- fruitConfigurator.setContext(context);
- try {
- fruitConfigurator.doConfigure(eventList);
- } catch (JoranException je) {
- je.printStackTrace();
- }
- return fruit;
+ public Fruit buildFruit() {
+
+ Context context = new ContextBase();
+ this.fruit = null;
+ context.putProperty("fruitKey", "orange-"+count);
+ // for next round
+ count++;
+ FruitConfigurator fruitConfigurator = new FruitConfigurator(this);
+ fruitConfigurator.setContext(context);
+ try {
+ fruitConfigurator.doConfigure(eventList);
+ } catch(JoranException je) {
+ je.printStackTrace();
}
+ return fruit;
+ }
- public String toString() {
- final String TAB = " ";
+ public String toString() {
+ final String TAB = " ";
- StringBuilder retValue = new StringBuilder();
+ StringBuilder retValue = new StringBuilder();
- retValue.append("FruitFactory ( ");
- if (eventList != null && eventList.size() > 0) {
- retValue.append("event1 = ").append(eventList.get(0)).append(TAB);
- }
- retValue.append(" )");
-
- return retValue.toString();
+ retValue.append("FruitFactory ( ");
+ if (eventList != null && eventList.size() > 0) {
+ retValue.append("event1 = ").append(eventList.get(0)).append(TAB);
}
+ retValue.append(" )");
- public void setEventList(List<SaxEvent> eventList) {
- this.eventList = eventList;
- }
+ return retValue.toString();
+ }
+
+ public void setEventList(List<SaxEvent> eventList) {
+ this.eventList = eventList;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitFactoryAction.java b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitFactoryAction.java
index d96b107..54a8edd 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitFactoryAction.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitFactoryAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,32 +26,33 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
public class FruitFactoryAction extends Action implements InPlayListener {
- List<SaxEvent> seList = new ArrayList<SaxEvent>();
-
- @Override
- public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
- ec.addInPlayListener(this);
+ List<SaxEvent> seList = new ArrayList<SaxEvent>();
+
+ @Override
+ public void begin(InterpretationContext ec, String name, Attributes attributes)
+ throws ActionException {
+ ec.addInPlayListener(this);
+ }
+
+ @Override
+ public void end(InterpretationContext ec, String name) throws ActionException {
+ ec.removeInPlayListener(this);
+
+ Object o = ec.peekObject();
+ if(o instanceof FruitShell) {
+ FruitShell fs = (FruitShell) o;
+ FruitFactory fruitFactory = new FruitFactory();
+ fruitFactory.setEventList(new ArrayList<SaxEvent>(seList));
+ fs.setFruitFactory(fruitFactory);
}
+ }
- @Override
- public void end(InterpretationContext ec, String name) throws ActionException {
- ec.removeInPlayListener(this);
-
- Object o = ec.peekObject();
- if (o instanceof FruitShell) {
- FruitShell fs = (FruitShell) o;
- FruitFactory fruitFactory = new FruitFactory();
- fruitFactory.setEventList(new ArrayList<SaxEvent>(seList));
- fs.setFruitFactory(fruitFactory);
- }
- }
+ public void inPlay(SaxEvent event) {
+ seList.add(event);
+ }
- public void inPlay(SaxEvent event) {
- seList.add(event);
- }
-
- public List<SaxEvent> getSeList() {
- return seList;
- }
+ public List<SaxEvent> getSeList() {
+ return seList;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitShell.java b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitShell.java
index 394b883..bbd5539 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitShell.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitShell.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,42 +17,46 @@ import ch.qos.logback.core.spi.ContextAwareBase;
public class FruitShell extends ContextAwareBase {
- FruitFactory fruitFactory;
- String name;
-
- public void setFruitFactory(FruitFactory fruitFactory) {
- this.fruitFactory = fruitFactory;
- }
-
- void testFruit() {
-
- Fruit fruit = fruitFactory.buildFruit();
- System.out.println(fruit);
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * Constructs a <code>String</code> with all attributes
- * in name = value format.
- *
- * @return a <code>String</code> representation
- * of this object.
- */
- public String toString() {
- final String TAB = " ";
-
- String retValue = "";
-
- retValue = "FruitShell ( " + "fruitFactory = " + this.fruitFactory + TAB + "name = " + this.name + TAB + " )";
-
- return retValue;
- }
-
+ FruitFactory fruitFactory;
+ String name;
+
+ public void setFruitFactory(FruitFactory fruitFactory) {
+ this.fruitFactory = fruitFactory;
+ }
+
+ void testFruit() {
+
+ Fruit fruit = fruitFactory.buildFruit();
+ System.out.println(fruit);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Constructs a <code>String</code> with all attributes
+ * in name = value format.
+ *
+ * @return a <code>String</code> representation
+ * of this object.
+ */
+ public String toString()
+ {
+ final String TAB = " ";
+
+ String retValue = "";
+
+ retValue = "FruitShell ( "
+ + "fruitFactory = " + this.fruitFactory + TAB
+ + "name = " + this.name + TAB
+ + " )";
+
+ return retValue;
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitShellAction.java b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitShellAction.java
index f0f3202..6d4e023 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitShellAction.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitShellAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,53 +25,63 @@ import ch.qos.logback.core.util.OptionHelper;
* */
public class FruitShellAction extends Action {
- FruitShell fruitShell;
- private boolean inError = false;
+ FruitShell fruitShell;
+ private boolean inError = false;
- @Override
- public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
+
+ @Override
+ public void begin(InterpretationContext ec, String name, Attributes attributes)
+ throws ActionException {
- // We are just beginning, reset variables
- fruitShell = new FruitShell();
- inError = false;
+ // We are just beginning, reset variables
+ fruitShell = new FruitShell();
+ inError = false;
+
+ try {
- try {
- fruitShell.setContext(context);
+ fruitShell.setContext(context);
- String shellName = attributes.getValue(NAME_ATTRIBUTE);
+ String shellName = attributes.getValue(NAME_ATTRIBUTE);
- if (OptionHelper.isEmpty(shellName)) {
- addWarn("No appender name given for fruitShell].");
- } else {
- fruitShell.setName(shellName);
- addInfo("FruitShell named as [" + shellName + "]");
- }
+ if (OptionHelper.isEmpty(shellName)) {
+ addWarn(
+ "No appender name given for fruitShell].");
+ } else {
+ fruitShell.setName(shellName);
+ addInfo("FruitShell named as [" + shellName + "]");
+ }
- ec.pushObject(fruitShell);
- } catch (Exception oops) {
- inError = true;
- addError("Could not create an FruitShell", oops);
- throw new ActionException(oops);
- }
+ ec.pushObject(fruitShell);
+ } catch (Exception oops) {
+ inError = true;
+ addError(
+ "Could not create an FruitShell", oops);
+ throw new ActionException(oops);
}
+ }
- @Override
- public void end(InterpretationContext ec, String name) throws ActionException {
- if (inError) {
- return;
- }
+ @Override
+ public void end(InterpretationContext ec, String name) throws ActionException {
+ if (inError) {
+ return;
+ }
- Object o = ec.peekObject();
+ Object o = ec.peekObject();
- if (o != fruitShell) {
- addWarn("The object at the of the stack is not the fruitShell named [" + fruitShell.getName() + "] pushed earlier.");
- } else {
- addInfo("Popping fruitSHell named [" + fruitShell.getName() + "] from the object stack");
- ec.popObject();
- FruitContext fruitContext = (FruitContext) ec.getContext();
- fruitContext.addFruitShell(fruitShell);
- }
+ if (o != fruitShell) {
+ addWarn(
+ "The object at the of the stack is not the fruitShell named ["
+ + fruitShell.getName() + "] pushed earlier.");
+ } else {
+ addInfo(
+ "Popping fruitSHell named [" + fruitShell.getName()
+ + "] from the object stack");
+ ec.popObject();
+ FruitContext fruitContext = (FruitContext) ec.getContext();
+ fruitContext.addFruitShell(fruitShell);
}
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/PackageTest.java
index 027b499..606b097 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,7 +18,7 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ FruitConfigurationTest.class })
+ at SuiteClasses({FruitConfigurationTest.class})
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/WeightytFruit.java b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/WeightytFruit.java
index 56b51f9..bc3bfbd 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/replay/WeightytFruit.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/replay/WeightytFruit.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,14 +15,15 @@ package ch.qos.logback.core.joran.replay;
public class WeightytFruit extends Fruit {
- double weight;
+ double weight;
- public double getWeight() {
- return weight;
- }
-
- public void setWeight(double weight) {
- this.weight = weight;
- }
+ public double getWeight() {
+ return weight;
+ }
+ public void setWeight(double weight) {
+ this.weight = weight;
+ }
+
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/CaseCombinator.java b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/CaseCombinator.java
index 7c7a1f4..8011357 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/CaseCombinator.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/CaseCombinator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,83 +18,84 @@ import java.util.List;
public class CaseCombinator {
- List<String> combinations(String in) {
- int length = in.length();
- List<String> permutationsList = new ArrayList<String>();
- int totalCombinations = computeTotalNumerOfCombinations(in, length);
+ List<String> combinations(String in) {
+ int length = in.length();
+ List<String> permutationsList = new ArrayList<String>();
- for (int j = 0; j < totalCombinations; j++) {
- StringBuilder newCombination = new StringBuilder();
- int pos = 0;
- for (int i = 0; i < length; i++) {
- char c = in.charAt(i);
- if (isEnglishLetter(c)) {
- c = permute(c, j, pos);
- pos++;
- }
- newCombination.append(c);
- }
- permutationsList.add(newCombination.toString());
- }
- return permutationsList;
+ int totalCombinations = computeTotalNumerOfCombinations(in, length);
+ for (int j = 0; j < totalCombinations; j++) {
+ StringBuilder newCombination = new StringBuilder();
+ int pos = 0;
+ for (int i = 0; i < length; i++) {
+ char c = in.charAt(i);
+ if (isEnglishLetter(c)) {
+ c = permute(c, j, pos);
+ pos++;
+ }
+ newCombination.append(c);
+ }
+ permutationsList.add(newCombination.toString());
}
+ return permutationsList;
- private char permute(char c, int permutation, int position) {
- int mask = 1 << position;
- boolean shouldBeInUpperCase = (permutation & mask) != 0;
- boolean isEffectivelyUpperCase = isUpperCase(c);
- if (shouldBeInUpperCase && !isEffectivelyUpperCase)
- return toUpperCase(c);
- if (!shouldBeInUpperCase && isEffectivelyUpperCase)
- return toLowerCase(c);
- return c;
- }
+ }
- private int computeTotalNumerOfCombinations(String in, int length) {
- int count = 0;
- for (int i = 0; i < length; i++) {
- char c = in.charAt(i);
- if (isEnglishLetter(c))
- count++;
- }
- // return 2^count (2 to the power of count)
- return (1 << count);
+ private char permute(char c, int permutation, int position) {
+ int mask = 1 << position;
+ boolean shouldBeInUpperCase = (permutation & mask) != 0;
+ boolean isEffectivelyUpperCase = isUpperCase(c);
+ if (shouldBeInUpperCase && !isEffectivelyUpperCase)
+ return toUpperCase(c);
+ if (!shouldBeInUpperCase && isEffectivelyUpperCase)
+ return toLowerCase(c);
+ return c;
+ }
+
+ private int computeTotalNumerOfCombinations(String in, int length) {
+ int count = 0;
+ for (int i = 0; i < length; i++) {
+ char c = in.charAt(i);
+ if (isEnglishLetter(c))
+ count++;
}
+ // return 2^count (2 to the power of count)
+ return (1 << count);
+ }
- private char toUpperCase(char c) {
- if ('A' <= c && c <= 'Z') {
- return c;
- }
- if ('a' <= c && c <= 'z') {
- return (char) ((int) c + 'A' - 'a');
- }
- // code should never reach this point
- return c;
+ private char toUpperCase(char c) {
+ if ('A' <= c && c <= 'Z') {
+ return c;
}
+ if ('a' <= c && c <= 'z') {
+ return (char) ((int) c + 'A' - 'a');
+ }
+ // code should never reach this point
+ return c;
+ }
- private char toLowerCase(char c) {
- if ('a' <= c && c <= 'z') {
- return c;
- }
- if ('A' <= c && c <= 'Z') {
- return (char) ((int) c + 'a' - 'A');
- }
- // code should never reach this point
- return c;
+ private char toLowerCase(char c) {
+ if ('a' <= c && c <= 'z') {
+ return c;
}
+ if ('A' <= c && c <= 'Z') {
+ return (char) ((int) c + 'a' - 'A');
+ }
+ // code should never reach this point
+ return c;
+ }
- private boolean isEnglishLetter(char c) {
- if ('a' <= c && c <= 'z')
- return true;
+ private boolean isEnglishLetter(char c) {
+ if ('a' <= c && c <= 'z')
+ return true;
- if ('A' <= c && c <= 'Z')
- return true;
- return false;
- }
+ if ('A' <= c && c <= 'Z')
+ return true;
+ return false;
+ }
- private boolean isUpperCase(char c) {
- return ('A' <= c && c <= 'Z');
- }
+ private boolean isUpperCase(char c) {
+ return ('A' <= c && c <= 'Z');
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/CaseCombinatorTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/CaseCombinatorTest.java
index bf5f156..ca87412 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/CaseCombinatorTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/CaseCombinatorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,30 +22,32 @@ import java.util.Set;
import org.junit.Test;
+
public class CaseCombinatorTest {
+ CaseCombinator p = new CaseCombinator();
+
+
+ @Test
+ public void smoke() {
CaseCombinator p = new CaseCombinator();
-
- @Test
- public void smoke() {
- CaseCombinator p = new CaseCombinator();
-
- List<String> result = p.combinations("a-B=");
-
- List<String> witness = new ArrayList<String>();
- witness.add("a-b=");
- witness.add("A-b=");
- witness.add("a-B=");
- witness.add("A-B=");
- assertEquals(witness, result);
- }
-
- @Test
- public void other() {
- List<String> result = p.combinations("aBCd");
- assertEquals(16, result.size());
- Set<String> witness = new HashSet<String>(result);
- // check that there are no duplicates
- assertEquals(16, witness.size());
- }
+
+ List<String> result = p.combinations("a-B=");
+
+ List<String> witness = new ArrayList<String>();
+ witness.add("a-b=");
+ witness.add("A-b=");
+ witness.add("a-B=");
+ witness.add("A-B=");
+ assertEquals(witness, result);
+ }
+
+ @Test
+ public void other() {
+ List<String> result = p.combinations("aBCd");
+ assertEquals(16, result.size());
+ Set<String> witness = new HashSet<String>(result);
+ // check that there are no duplicates
+ assertEquals(16, witness.size());
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/ConfigurationWatchListTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/ConfigurationWatchListTest.java
index 01dfcac..e3be755 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/ConfigurationWatchListTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/ConfigurationWatchListTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,17 +22,17 @@ import java.net.URL;
import static org.junit.Assert.assertEquals;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class ConfigurationWatchListTest {
- @Test
- // See http://jira.qos.ch/browse/LBCORE-119
- public void fileToURLAndBack() throws MalformedURLException {
- File file = new File("a b.xml");
- URL url = file.toURI().toURL();
- ConfigurationWatchList cwl = new ConfigurationWatchList();
- File back = cwl.convertToFile(url);
- assertEquals(file.getName(), back.getName());
- }
+ @Test
+ // See http://jira.qos.ch/browse/LBCORE-119
+ public void fileToURLAndBack() throws MalformedURLException {
+ File file = new File("a b.xml");
+ URL url = file.toURI().toURL();
+ ConfigurationWatchList cwl = new ConfigurationWatchList();
+ File back = cwl.convertToFile(url);
+ assertEquals(file.getName(), back.getName());
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/DefaultNestedComponentRegistryTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/DefaultNestedComponentRegistryTest.java
index b8f6bea..f3b3faf 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/DefaultNestedComponentRegistryTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/DefaultNestedComponentRegistryTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,29 +26,29 @@ import ch.qos.logback.core.joran.util.House;
public class DefaultNestedComponentRegistryTest {
- DefaultNestedComponentRegistry registry = new DefaultNestedComponentRegistry();
+ DefaultNestedComponentRegistry registry = new DefaultNestedComponentRegistry();
- @Before
- public void setUp() throws Exception {
+ @Before
+ public void setUp() throws Exception {
- }
+ }
- @After
- public void tearDown() throws Exception {
- }
+ @After
+ public void tearDown() throws Exception {
+ }
- @Test
- public void smoke() {
- String propertyName = "window";
- registry.add(House.class, propertyName, Window.class);
- Class<?> result = registry.findDefaultComponentType(House.class, propertyName);
- assertEquals(Window.class, result);
- }
+ @Test
+ public void smoke() {
+ String propertyName = "window";
+ registry.add(House.class, propertyName, Window.class);
+ Class<?> result = registry.findDefaultComponentType(House.class, propertyName);
+ assertEquals(Window.class, result);
+ }
- @Test
- public void absent() {
- registry.add(House.class, "a", Window.class);
- Class<?> result = registry.findDefaultComponentType(House.class, "other");
- assertNull(result);
- }
+ @Test
+ public void absent() {
+ registry.add(House.class, "a", Window.class);
+ Class<?> result = registry.findDefaultComponentType(House.class, "other");
+ assertNull(result);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/DoNotAutoStart.java b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/DoNotAutoStart.java
index 3f2e6de..fc03c56 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/DoNotAutoStart.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/DoNotAutoStart.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,18 +18,17 @@ import ch.qos.logback.core.spi.LifeCycle;
@NoAutoStart
public class DoNotAutoStart implements LifeCycle {
- boolean started = false;
+ boolean started = false;
+ public boolean isStarted() {
+ return started;
+ }
- public boolean isStarted() {
- return started;
- }
+ public void start() {
+ started = true;
+ }
- public void start() {
- started = true;
- }
-
- public void stop() {
- started = false;
- }
+ public void stop() {
+ started = false;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/ElementSelectorTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/ElementSelectorTest.java
index 960982f..cb8c67d 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/ElementSelectorTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/ElementSelectorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,154 +24,156 @@ import org.junit.Test;
*/
public class ElementSelectorTest {
- @Test
- public void test1() {
- ElementSelector p = new ElementSelector("a");
- assertEquals(1, p.size());
- assertEquals("a", p.peekLast());
- assertEquals("a", p.get(0));
+ @Test
+ public void test1() {
+ ElementSelector p = new ElementSelector("a");
+ assertEquals(1, p.size());
+ assertEquals("a", p.peekLast());
+ assertEquals("a", p.get(0));
+ }
+
+ @Test
+ public void testSuffix() {
+ ElementSelector p = new ElementSelector("a/");
+ assertEquals(1, p.size());
+ assertEquals("a", p.peekLast());
+ assertEquals("a", p.get(0));
+ }
+
+ @Test
+ public void test2() {
+ ElementSelector p = new ElementSelector("a/b");
+ assertEquals(2, p.size());
+ assertEquals("b", p.peekLast());
+ assertEquals("a", p.get(0));
+ assertEquals("b", p.get(1));
+ }
+
+ @Test
+ public void test3() {
+ ElementSelector p = new ElementSelector("a123/b1234/cvvsdf");
+ assertEquals(3, p.size());
+ assertEquals("a123", p.get(0));
+ assertEquals("b1234", p.get(1));
+ assertEquals("cvvsdf", p.get(2));
+ }
+
+ @Test
+ public void test4() {
+ ElementSelector p = new ElementSelector("/a123/b1234/cvvsdf");
+ assertEquals(3, p.size());
+ assertEquals("a123", p.get(0));
+ assertEquals("b1234", p.get(1));
+ assertEquals("cvvsdf", p.get(2));
+ }
+
+ @Test
+ public void test5() {
+ ElementSelector p = new ElementSelector("//a");
+ assertEquals(1, p.size());
+ assertEquals("a", p.get(0));
+ }
+
+ @Test
+ public void test6() {
+ ElementSelector p = new ElementSelector("//a//b");
+ assertEquals(2, p.size());
+ assertEquals("a", p.get(0));
+ assertEquals("b", p.get(1));
+ }
+
+
+ // test tail matching
+ @Test
+ public void testTailMatch() {
+ {
+ ElementPath p = new ElementPath("/a/b");
+ ElementSelector ruleElementSelector = new ElementSelector("*");
+ assertEquals(0, ruleElementSelector.getTailMatchLength(p));
}
- @Test
- public void testSuffix() {
- ElementSelector p = new ElementSelector("a/");
- assertEquals(1, p.size());
- assertEquals("a", p.peekLast());
- assertEquals("a", p.get(0));
+ {
+ ElementPath p = new ElementPath("/a");
+ ElementSelector ruleElementSelector = new ElementSelector("*/a");
+ assertEquals(1, ruleElementSelector.getTailMatchLength(p));
}
- @Test
- public void test2() {
- ElementSelector p = new ElementSelector("a/b");
- assertEquals(2, p.size());
- assertEquals("b", p.peekLast());
- assertEquals("a", p.get(0));
- assertEquals("b", p.get(1));
+ {
+ ElementPath p = new ElementPath("/A");
+ ElementSelector ruleElementSelector = new ElementSelector("*/a");
+ assertEquals(1, ruleElementSelector.getTailMatchLength(p));
}
-
- @Test
- public void test3() {
- ElementSelector p = new ElementSelector("a123/b1234/cvvsdf");
- assertEquals(3, p.size());
- assertEquals("a123", p.get(0));
- assertEquals("b1234", p.get(1));
- assertEquals("cvvsdf", p.get(2));
+
+ {
+ ElementPath p = new ElementPath("/a");
+ ElementSelector ruleElementSelector = new ElementSelector("*/A");
+ assertEquals(1, ruleElementSelector.getTailMatchLength(p));
}
-
- @Test
- public void test4() {
- ElementSelector p = new ElementSelector("/a123/b1234/cvvsdf");
- assertEquals(3, p.size());
- assertEquals("a123", p.get(0));
- assertEquals("b1234", p.get(1));
- assertEquals("cvvsdf", p.get(2));
+
+
+ {
+ ElementPath p = new ElementPath("/a/b");
+ ElementSelector ruleElementSelector = new ElementSelector("*/b");
+ assertEquals(1, ruleElementSelector.getTailMatchLength(p));
}
-
- @Test
- public void test5() {
- ElementSelector p = new ElementSelector("//a");
- assertEquals(1, p.size());
- assertEquals("a", p.get(0));
+
+ {
+ ElementPath p = new ElementPath("/a/B");
+ ElementSelector ruleElementSelector = new ElementSelector("*/b");
+ assertEquals(1, ruleElementSelector.getTailMatchLength(p));
+ }
+
+ {
+ ElementPath p = new ElementPath("/a/b/c");
+ ElementSelector ruleElementSelector = new ElementSelector("*/b/c");
+ assertEquals(2, ruleElementSelector.getTailMatchLength(p));
+ }
+ }
+
+ // test prefix matching
+ @Test
+ public void testPrefixMatch() {
+ {
+ ElementPath p = new ElementPath("/a/b");
+ ElementSelector ruleElementSelector = new ElementSelector("/x/*");
+ assertEquals(0, ruleElementSelector.getPrefixMatchLength(p));
}
- @Test
- public void test6() {
- ElementSelector p = new ElementSelector("//a//b");
- assertEquals(2, p.size());
- assertEquals("a", p.get(0));
- assertEquals("b", p.get(1));
+ {
+ ElementPath p = new ElementPath("/a");
+ ElementSelector ruleElementSelector = new ElementSelector("/x/*");
+ assertEquals(0, ruleElementSelector.getPrefixMatchLength(p));
}
- // test tail matching
- @Test
- public void testTailMatch() {
- {
- ElementPath p = new ElementPath("/a/b");
- ElementSelector ruleElementSelector = new ElementSelector("*");
- assertEquals(0, ruleElementSelector.getTailMatchLength(p));
- }
-
- {
- ElementPath p = new ElementPath("/a");
- ElementSelector ruleElementSelector = new ElementSelector("*/a");
- assertEquals(1, ruleElementSelector.getTailMatchLength(p));
- }
-
- {
- ElementPath p = new ElementPath("/A");
- ElementSelector ruleElementSelector = new ElementSelector("*/a");
- assertEquals(1, ruleElementSelector.getTailMatchLength(p));
- }
-
- {
- ElementPath p = new ElementPath("/a");
- ElementSelector ruleElementSelector = new ElementSelector("*/A");
- assertEquals(1, ruleElementSelector.getTailMatchLength(p));
- }
-
- {
- ElementPath p = new ElementPath("/a/b");
- ElementSelector ruleElementSelector = new ElementSelector("*/b");
- assertEquals(1, ruleElementSelector.getTailMatchLength(p));
- }
-
- {
- ElementPath p = new ElementPath("/a/B");
- ElementSelector ruleElementSelector = new ElementSelector("*/b");
- assertEquals(1, ruleElementSelector.getTailMatchLength(p));
- }
-
- {
- ElementPath p = new ElementPath("/a/b/c");
- ElementSelector ruleElementSelector = new ElementSelector("*/b/c");
- assertEquals(2, ruleElementSelector.getTailMatchLength(p));
- }
+ {
+ ElementPath p = new ElementPath("/a/b");
+ ElementSelector ruleElementSelector = new ElementSelector("/a/*");
+ assertEquals(1, ruleElementSelector.getPrefixMatchLength(p));
}
- // test prefix matching
- @Test
- public void testPrefixMatch() {
- {
- ElementPath p = new ElementPath("/a/b");
- ElementSelector ruleElementSelector = new ElementSelector("/x/*");
- assertEquals(0, ruleElementSelector.getPrefixMatchLength(p));
- }
-
- {
- ElementPath p = new ElementPath("/a");
- ElementSelector ruleElementSelector = new ElementSelector("/x/*");
- assertEquals(0, ruleElementSelector.getPrefixMatchLength(p));
- }
-
- {
- ElementPath p = new ElementPath("/a/b");
- ElementSelector ruleElementSelector = new ElementSelector("/a/*");
- assertEquals(1, ruleElementSelector.getPrefixMatchLength(p));
- }
-
- {
- ElementPath p = new ElementPath("/a/b");
- ElementSelector ruleElementSelector = new ElementSelector("/A/*");
- assertEquals(1, ruleElementSelector.getPrefixMatchLength(p));
- }
-
- {
- ElementPath p = new ElementPath("/A/b");
- ElementSelector ruleElementSelector = new ElementSelector("/a/*");
- assertEquals(1, ruleElementSelector.getPrefixMatchLength(p));
- }
-
- {
- ElementPath p = new ElementPath("/a/b");
- ElementSelector ruleElementSelector = new ElementSelector("/a/b/*");
- assertEquals(2, ruleElementSelector.getPrefixMatchLength(p));
- }
-
- {
- ElementPath p = new ElementPath("/a/b");
- ElementSelector ruleElementSelector = new ElementSelector("/*");
- assertEquals(0, ruleElementSelector.getPrefixMatchLength(p));
- }
+ {
+ ElementPath p = new ElementPath("/a/b");
+ ElementSelector ruleElementSelector = new ElementSelector("/A/*");
+ assertEquals(1, ruleElementSelector.getPrefixMatchLength(p));
+ }
+
+ {
+ ElementPath p = new ElementPath("/A/b");
+ ElementSelector ruleElementSelector = new ElementSelector("/a/*");
+ assertEquals(1, ruleElementSelector.getPrefixMatchLength(p));
+ }
+
+ {
+ ElementPath p = new ElementPath("/a/b");
+ ElementSelector ruleElementSelector = new ElementSelector("/a/b/*");
+ assertEquals(2, ruleElementSelector.getPrefixMatchLength(p));
+ }
+
+ {
+ ElementPath p = new ElementPath("/a/b");
+ ElementSelector ruleElementSelector = new ElementSelector("/*");
+ assertEquals(0, ruleElementSelector.getPrefixMatchLength(p));
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/NoAutoStartUtilTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/NoAutoStartUtilTest.java
index f862690..8d88168 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/NoAutoStartUtilTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/NoAutoStartUtilTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,17 +18,19 @@ import static org.junit.Assert.assertTrue;
import org.junit.Test;
-public class NoAutoStartUtilTest {
- @Test
- public void commonObject() {
- Object o = new Object();
- assertTrue(NoAutoStartUtil.notMarkedWithNoAutoStart(o));
- }
+public class NoAutoStartUtilTest {
- @Test
- public void markedWithNoAutoStart() {
- DoNotAutoStart o = new DoNotAutoStart();
- assertFalse(NoAutoStartUtil.notMarkedWithNoAutoStart(o));
- }
+
+ @Test
+ public void commonObject() {
+ Object o = new Object();
+ assertTrue(NoAutoStartUtil.notMarkedWithNoAutoStart(o));
+ }
+
+ @Test
+ public void markedWithNoAutoStart() {
+ DoNotAutoStart o = new DoNotAutoStart();
+ assertFalse(NoAutoStartUtil.notMarkedWithNoAutoStart(o));
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PackageTest.java
index 7cd6af3..2e9c8d0 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,7 +18,8 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ ElementSelectorTest.class, SimpleRuleStoreTest.class, NoAutoStartUtilTest.class, ConfigurationWatchListTest.class,
- DefaultNestedComponentRegistryTest.class, CaseCombinatorTest.class })
+ at SuiteClasses( { ElementSelectorTest.class, SimpleRuleStoreTest.class,
+ NoAutoStartUtilTest.class, ConfigurationWatchListTest.class,
+ DefaultNestedComponentRegistryTest.class, CaseCombinatorTest.class })
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleRuleStoreTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleRuleStoreTest.java
index 8da0e97..0251343 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleRuleStoreTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleRuleStoreTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -36,228 +36,231 @@ import ch.qos.logback.core.joran.action.Action;
*/
public class SimpleRuleStoreTest {
- SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
- CaseCombinator cc = new CaseCombinator();
-
- @Test
- public void smoke() throws Exception {
- srs.addRule(new ElementSelector("a/b"), new XAction());
-
- // test for all possible case combinations of "a/b"
- for (String s : cc.combinations("a/b")) {
- System.out.println("s=" + s);
- List<Action> r = srs.matchActions(new ElementPath(s));
- assertNotNull(r);
- assertEquals(1, r.size());
-
- if (!(r.get(0) instanceof XAction)) {
- fail("Wrong type");
- }
- }
+ SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
+ CaseCombinator cc = new CaseCombinator();
+
+ @Test
+ public void smoke() throws Exception {
+ srs.addRule(new ElementSelector("a/b"), new XAction());
+
+ // test for all possible case combinations of "a/b"
+ for (String s : cc.combinations("a/b")) {
+ System.out.println("s="+s);
+ List<Action> r = srs.matchActions(new ElementPath(s));
+ assertNotNull(r);
+ assertEquals(1, r.size());
+
+ if (!(r.get(0) instanceof XAction)) {
+ fail("Wrong type");
+ }
}
+ }
- @Test
- public void smokeII() throws Exception {
- srs.addRule(new ElementSelector("a/b"), new XAction());
- srs.addRule(new ElementSelector("a/b"), new YAction());
+ @Test
+ public void smokeII() throws Exception {
+ srs.addRule(new ElementSelector("a/b"), new XAction());
+ srs.addRule(new ElementSelector("a/b"), new YAction());
- for (String s : cc.combinations("a/b")) {
- List<Action> r = srs.matchActions(new ElementPath(s));
- assertNotNull(r);
- assertEquals(2, r.size());
+ for (String s : cc.combinations("a/b")) {
+ List<Action> r = srs.matchActions(new ElementPath(s));
+ assertNotNull(r);
+ assertEquals(2, r.size());
- if (!(r.get(0) instanceof XAction)) {
- fail("Wrong type");
- }
+ if (!(r.get(0) instanceof XAction)) {
+ fail("Wrong type");
+ }
- if (!(r.get(1) instanceof YAction)) {
- fail("Wrong type");
- }
- }
+ if (!(r.get(1) instanceof YAction)) {
+ fail("Wrong type");
+ }
}
+ }
- @Test
- public void testSlashSuffix() throws Exception {
- ElementSelector pa = new ElementSelector("a/");
- srs.addRule(pa, new XAction());
-
- for (String s : cc.combinations("a")) {
- List<Action> r = srs.matchActions(new ElementPath(s));
- assertNotNull(r);
- assertEquals(1, r.size());
+ @Test
+ public void testSlashSuffix() throws Exception {
+ ElementSelector pa = new ElementSelector("a/");
+ srs.addRule(pa, new XAction());
- if (!(r.get(0) instanceof XAction)) {
- fail("Wrong type");
- }
- }
+ for (String s : cc.combinations("a")) {
+ List<Action> r = srs.matchActions(new ElementPath(s));
+ assertNotNull(r);
+ assertEquals(1, r.size());
+ if (!(r.get(0) instanceof XAction)) {
+ fail("Wrong type");
+ }
}
- @Test
- public void testTail1() throws Exception {
- srs.addRule(new ElementSelector("*/b"), new XAction());
+ }
- for (String s : cc.combinations("a/b")) {
- List<Action> r = srs.matchActions(new ElementPath(s));
- assertNotNull(r);
+ @Test
+ public void testTail1() throws Exception {
+ srs.addRule(new ElementSelector("*/b"), new XAction());
- assertEquals(1, r.size());
+ for (String s : cc.combinations("a/b")) {
+ List<Action> r = srs.matchActions(new ElementPath(s));
+ assertNotNull(r);
- if (!(r.get(0) instanceof XAction)) {
- fail("Wrong type");
- }
- }
+ assertEquals(1, r.size());
+
+ if (!(r.get(0) instanceof XAction)) {
+ fail("Wrong type");
+ }
}
+ }
- @Test
- public void testTail2() throws Exception {
- SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
- srs.addRule(new ElementSelector("*/c"), new XAction());
+ @Test
+ public void testTail2() throws Exception {
+ SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
+ srs.addRule(new ElementSelector("*/c"), new XAction());
- for (String s : cc.combinations("a/b/c")) {
- List<Action> r = srs.matchActions(new ElementPath(s));
- assertNotNull(r);
+ for (String s : cc.combinations("a/b/c")) {
+ List<Action> r = srs.matchActions(new ElementPath(s));
+ assertNotNull(r);
- assertEquals(1, r.size());
+ assertEquals(1, r.size());
- if (!(r.get(0) instanceof XAction)) {
- fail("Wrong type");
- }
- }
+ if (!(r.get(0) instanceof XAction)) {
+ fail("Wrong type");
+ }
}
+ }
- @Test
- public void testTail3() throws Exception {
- srs.addRule(new ElementSelector("*/b"), new XAction());
- srs.addRule(new ElementSelector("*/a/b"), new YAction());
+ @Test
+ public void testTail3() throws Exception {
+ srs.addRule(new ElementSelector("*/b"), new XAction());
+ srs.addRule(new ElementSelector("*/a/b"), new YAction());
- for (String s : cc.combinations("a/b")) {
- List<Action> r = srs.matchActions(new ElementPath(s));
- assertNotNull(r);
- assertEquals(1, r.size());
+ for (String s : cc.combinations("a/b")) {
+ List<Action> r = srs.matchActions(new ElementPath(s));
+ assertNotNull(r);
+ assertEquals(1, r.size());
- if (!(r.get(0) instanceof YAction)) {
- fail("Wrong type");
- }
- }
+ if (!(r.get(0) instanceof YAction)) {
+ fail("Wrong type");
+ }
}
-
- @Test
- public void testTail4() throws Exception {
- srs.addRule(new ElementSelector("*/b"), new XAction());
- srs.addRule(new ElementSelector("*/a/b"), new YAction());
- srs.addRule(new ElementSelector("a/b"), new ZAction());
-
- for (String s : cc.combinations("a/b")) {
- List<Action> r = srs.matchActions(new ElementPath(s));
- assertNotNull(r);
- assertEquals(1, r.size());
-
- if (!(r.get(0) instanceof ZAction)) {
- fail("Wrong type");
- }
- }
+ }
+
+ @Test
+ public void testTail4() throws Exception {
+ srs.addRule(new ElementSelector("*/b"), new XAction());
+ srs.addRule(new ElementSelector("*/a/b"), new YAction());
+ srs.addRule(new ElementSelector("a/b"), new ZAction());
+
+ for (String s : cc.combinations("a/b")) {
+ List<Action> r = srs.matchActions(new ElementPath(s));
+ assertNotNull(r);
+ assertEquals(1, r.size());
+
+ if (!(r.get(0) instanceof ZAction)) {
+ fail("Wrong type");
+ }
}
-
- @Test
- public void testSuffix() throws Exception {
- srs.addRule(new ElementSelector("a"), new XAction());
- srs.addRule(new ElementSelector("a/*"), new YAction());
-
- for (String s : cc.combinations("a/b")) {
- List<Action> r = srs.matchActions(new ElementPath(s));
- assertNotNull(r);
- assertEquals(1, r.size());
- assertTrue(r.get(0) instanceof YAction);
- }
+ }
+
+ @Test
+ public void testSuffix() throws Exception {
+ srs.addRule(new ElementSelector("a"), new XAction());
+ srs.addRule(new ElementSelector("a/*"), new YAction());
+
+ for (String s : cc.combinations("a/b")) {
+ List<Action> r = srs.matchActions(new ElementPath(s));
+ assertNotNull(r);
+ assertEquals(1, r.size());
+ assertTrue(r.get(0) instanceof YAction);
}
+ }
- @Test
- public void testDeepSuffix() throws Exception {
- srs.addRule(new ElementSelector("a"), new XAction(1));
- srs.addRule(new ElementSelector("a/b/*"), new XAction(2));
+ @Test
+ public void testDeepSuffix() throws Exception {
+ srs.addRule(new ElementSelector("a"), new XAction(1));
+ srs.addRule(new ElementSelector("a/b/*"), new XAction(2));
- for (String s : cc.combinations("a/other")) {
- List<Action> r = srs.matchActions(new ElementPath(s));
- assertNull(r);
- }
+ for (String s : cc.combinations("a/other")) {
+ List<Action> r = srs.matchActions(new ElementPath(s));
+ assertNull(r);
}
+ }
- @Test
- public void testPrefixSuffixInteraction1() throws Exception {
- srs.addRule(new ElementSelector("a"), new ZAction());
- srs.addRule(new ElementSelector("a/*"), new YAction());
- srs.addRule(new ElementSelector("*/a/b"), new XAction(3));
+ @Test
+ public void testPrefixSuffixInteraction1() throws Exception {
+ srs.addRule(new ElementSelector("a"), new ZAction());
+ srs.addRule(new ElementSelector("a/*"), new YAction());
+ srs.addRule(new ElementSelector("*/a/b"), new XAction(3));
- for (String s : cc.combinations("a/b")) {
- List<Action> r = srs.matchActions(new ElementPath(s));
- assertNotNull(r);
+ for (String s : cc.combinations("a/b")) {
+ List<Action> r = srs.matchActions(new ElementPath(s));
+ assertNotNull(r);
- assertEquals(1, r.size());
+ assertEquals(1, r.size());
- assertTrue(r.get(0) instanceof XAction);
- XAction xaction = (XAction) r.get(0);
- assertEquals(3, xaction.id);
- }
+ assertTrue(r.get(0) instanceof XAction);
+ XAction xaction = (XAction) r.get(0);
+ assertEquals(3, xaction.id);
}
-
- @Test
- public void testPrefixSuffixInteraction2() throws Exception {
- srs.addRule(new ElementSelector("tG"), new XAction());
- srs.addRule(new ElementSelector("tG/tS"), new YAction());
- srs.addRule(new ElementSelector("tG/tS/test"), new ZAction());
- srs.addRule(new ElementSelector("tG/tS/test/*"), new XAction(9));
-
- for (String s : cc.combinations("tG/tS/toto")) {
- List<Action> r = srs.matchActions(new ElementPath(s));
- assertNull(r);
- }
+ }
+
+ @Test
+ public void testPrefixSuffixInteraction2() throws Exception {
+ srs.addRule(new ElementSelector("tG"), new XAction());
+ srs.addRule(new ElementSelector("tG/tS"), new YAction());
+ srs.addRule(new ElementSelector("tG/tS/test"), new ZAction());
+ srs.addRule(new ElementSelector("tG/tS/test/*"), new XAction(9));
+
+ for (String s : cc.combinations("tG/tS/toto")) {
+ List<Action> r = srs.matchActions(new ElementPath(s));
+ assertNull(r);
}
+ }
- class XAction extends Action {
- int id = 0;
+ class XAction extends Action {
+ int id = 0;
- XAction() {
- }
+ XAction() {
+ }
- XAction(int id) {
- this.id = id;
- }
+ XAction(int id) {
+ this.id = id;
+ }
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- }
+ public void begin(InterpretationContext ec, String name,
+ Attributes attributes) {
+ }
- public void end(InterpretationContext ec, String name) {
- }
+ public void end(InterpretationContext ec, String name) {
+ }
- public void finish(InterpretationContext ec) {
- }
+ public void finish(InterpretationContext ec) {
+ }
- public String toString() {
- return "XAction(" + id + ")";
- }
+ public String toString() {
+ return "XAction(" + id + ")";
}
+ }
- class YAction extends Action {
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- }
+ class YAction extends Action {
+ public void begin(InterpretationContext ec, String name,
+ Attributes attributes) {
+ }
- public void end(InterpretationContext ec, String name) {
- }
+ public void end(InterpretationContext ec, String name) {
+ }
- public void finish(InterpretationContext ec) {
- }
+ public void finish(InterpretationContext ec) {
}
+ }
- class ZAction extends Action {
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- }
+ class ZAction extends Action {
+ public void begin(InterpretationContext ec, String name,
+ Attributes attributes) {
+ }
- public void end(InterpretationContext ec, String name) {
- }
+ public void end(InterpretationContext ec, String name) {
+ }
- public void finish(InterpretationContext ec) {
- }
+ public void finish(InterpretationContext ec) {
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/util/Citrus.java b/logback-core/src/test/java/ch/qos/logback/core/joran/util/Citrus.java
deleted file mode 100644
index 97b2a4f..0000000
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/util/Citrus.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package ch.qos.logback.core.joran.util;
-
-public class Citrus<T> {
-
- // should match name of the single property of this class
- public static final String PRECARP_PROPERTY_NAME = "pericarp";
- @SuppressWarnings("unused")
- private T pericarp;
-
- public void setPericarp(T pericarp) {
- this.pericarp = pericarp;
- }
-
-
-}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/util/House.java b/logback-core/src/test/java/ch/qos/logback/core/joran/util/House.java
index a53c064..62a46bb 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/util/House.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/util/House.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,165 +23,160 @@ import ch.qos.logback.core.util.Duration;
import ch.qos.logback.core.util.FileSize;
public class House {
- Door mainDoor;
- int count;
- Double temperature;
- boolean open;
- String name;
- String camelCase;
- SwimmingPool pool;
- Duration duration;
- FileSize fs;
- HouseColor houseColor;
- FilterReply reply;
-
- Charset charset;
-
- List<String> adjectiveList = new ArrayList<String>();
- List<Window> windowList = new ArrayList<Window>();
- List<SwimmingPool> largePoolList = new ArrayList<SwimmingPool>();
-
- Orange orange;
-
- public String getCamelCase() {
- return camelCase;
- }
-
-
- public void setCamelCase(String camelCase) {
- this.camelCase = camelCase;
- }
-
- public int getCount() {
- return count;
- }
-
- public void setCount(int c) {
- this.count = c;
- }
-
- public Double getTemperature() {
- return temperature;
- }
-
- public void setTemperature(Double temperature) {
- this.temperature = temperature;
- }
-
- public Door getDoor() {
- return mainDoor;
- }
-
- public void setDoor(Door door) {
- this.mainDoor = door;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public boolean isOpen() {
- return open;
- }
-
- public void setOpen(boolean open) {
- this.open = open;
- }
-
- @DefaultClass(LargeSwimmingPoolImpl.class)
- public void addLargeSwimmingPool(SwimmingPool pool) {
- this.pool = pool;
- }
-
- @DefaultClass(SwimmingPoolImpl.class)
- public void setSwimmingPool(SwimmingPool pool) {
- this.pool = pool;
- }
-
- public SwimmingPool getSwimmingPool() {
- return pool;
- }
-
- public void addWindow(Window w) {
- windowList.add(w);
- }
-
- public void addAdjective(String s) {
- adjectiveList.add(s);
- }
-
- public Duration getDuration() {
- return duration;
- }
-
- public void setDuration(Duration duration) {
- this.duration = duration;
- }
-
- public FileSize getFs() {
- return fs;
- }
-
- public void setFs(FileSize fs) {
- this.fs = fs;
- }
-
- public void setHouseColor(HouseColor color) {
- this.houseColor = color;
- }
-
- public HouseColor getHouseColor() {
- return houseColor;
- }
-
- public void setFilterReply(FilterReply reply) {
- this.reply = reply;
- }
-
- public FilterReply getFilterReply() {
- return reply;
- }
-
- public Charset getCharset() {
- return charset;
- }
-
- public void setCharset(Charset charset) {
- this.charset = charset;
- }
-
- public void setOrange(Orange o) {
- this.orange = o;
- }
+ Door mainDoor;
+ int count;
+ Double temperature;
+ boolean open;
+ String name;
+ String camelCase;
+ SwimmingPool pool;
+ Duration duration;
+ FileSize fs;
+ HouseColor houseColor;
+ FilterReply reply;
+
+
+ Charset charset;
+
+ List<String> adjectiveList = new ArrayList<String>();
+ List<Window> windowList = new ArrayList<Window>();
+ List<SwimmingPool> largePoolList = new ArrayList<SwimmingPool>();
+
+ public String getCamelCase() {
+ return camelCase;
+ }
+
+ public void setCamelCase(String camelCase) {
+ this.camelCase = camelCase;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public void setCount(int c) {
+ this.count = c;
+ }
+
+
+ public Double getTemperature() {
+ return temperature;
+ }
+
+ public void setTemperature(Double temperature) {
+ this.temperature = temperature;
+ }
+
+ public Door getDoor() {
+ return mainDoor;
+ }
+
+ public void setDoor(Door door) {
+ this.mainDoor = door;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public boolean isOpen() {
+ return open;
+ }
+
+ public void setOpen(boolean open) {
+ this.open = open;
+ }
+
+ @DefaultClass(LargeSwimmingPoolImpl.class)
+ public void addLargeSwimmingPool(SwimmingPool pool) {
+ this.pool = pool;
+ }
+
+ @DefaultClass(SwimmingPoolImpl.class)
+ public void setSwimmingPool(SwimmingPool pool) {
+ this.pool = pool;
+ }
+
+ public SwimmingPool getSwimmingPool() {
+ return pool;
+ }
+
+ public void addWindow(Window w) {
+ windowList.add(w);
+ }
+
+ public void addAdjective(String s) {
+ adjectiveList.add(s);
+ }
+
+ public Duration getDuration() {
+ return duration;
+ }
+
+ public void setDuration(Duration duration) {
+ this.duration = duration;
+ }
+
+ public FileSize getFs() {
+ return fs;
+ }
+
+ public void setFs(FileSize fs) {
+ this.fs = fs;
+ }
+
+ public void setHouseColor(HouseColor color) {
+ this.houseColor = color;
+ }
+
+ public HouseColor getHouseColor() {
+ return houseColor;
+ }
+
+ public void setFilterReply(FilterReply reply) {
+ this.reply = reply;
+ }
+
+ public FilterReply getFilterReply() {
+ return reply;
+ }
+
+ public Charset getCharset() {
+ return charset;
+ }
+
+ public void setCharset(Charset charset) {
+ this.charset = charset;
+ }
}
class Door {
- int handle;
+ int handle;
}
class Window {
- int handle;
+ int handle;
}
interface SwimmingPool {
}
class SwimmingPoolImpl implements SwimmingPool {
- int length;
- int width;
- int depth;
+ int length;
+ int width;
+ int depth;
}
class LargeSwimmingPoolImpl implements SwimmingPool {
- int length;
- int width;
- int depth;
+ int length;
+ int width;
+ int depth;
}
enum HouseColor {
- WHITE, BLUE
-}
+ WHITE, BLUE
+}
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/util/Orange.java b/logback-core/src/test/java/ch/qos/logback/core/joran/util/Orange.java
deleted file mode 100644
index 90f22bf..0000000
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/util/Orange.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package ch.qos.logback.core.joran.util;
-
-public class Orange extends Citrus<Integer> {
-
- public void setPericarp(Integer pericarp) {
- System.out.println("Orange.setPericarp");
- super.setPericarp(pericarp);
- }
-}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/util/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/util/PackageTest.java
index 6daa95d..5211635 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/util/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/util/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ PropertySetterTest.class })
+ at SuiteClasses( { PropertySetterTest.class })
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/util/PropertySetterTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/util/PropertySetterTest.java
index d925c08..acc3306 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/util/PropertySetterTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/util/PropertySetterTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,219 +22,226 @@ import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
-import ch.qos.logback.core.joran.util.beans.BeanDescriptionCache;
import ch.qos.logback.core.spi.FilterReply;
import ch.qos.logback.core.status.StatusChecker;
import ch.qos.logback.core.util.AggregationType;
public class PropertySetterTest {
- DefaultNestedComponentRegistry defaultComponentRegistry = new DefaultNestedComponentRegistry();
-
- Context context = new ContextBase();
- StatusChecker checker = new StatusChecker(context);
- House house = new House();
+ DefaultNestedComponentRegistry defaultComponentRegistry = new DefaultNestedComponentRegistry();
+
+ Context context = new ContextBase();
+ House house = new House();
+ PropertySetter setter = new PropertySetter(house);
+
+
+ @Before
+ public void setUp() {
+ setter.setContext(context);
+ }
+
+ @Test
+ public void testCanAggregateComponent() {
+ assertEquals(AggregationType.AS_COMPLEX_PROPERTY, setter
+ .computeAggregationType("door"));
+
+ assertEquals(AggregationType.AS_BASIC_PROPERTY, setter
+ .computeAggregationType("count"));
+ assertEquals(AggregationType.AS_BASIC_PROPERTY, setter
+ .computeAggregationType("Count"));
+
+ assertEquals(AggregationType.AS_BASIC_PROPERTY, setter
+ .computeAggregationType("name"));
+ assertEquals(AggregationType.AS_BASIC_PROPERTY, setter
+ .computeAggregationType("Name"));
+
+ assertEquals(AggregationType.AS_BASIC_PROPERTY, setter
+ .computeAggregationType("Duration"));
+ assertEquals(AggregationType.AS_BASIC_PROPERTY, setter
+ .computeAggregationType("fs"));
+
+ assertEquals(AggregationType.AS_BASIC_PROPERTY, setter
+ .computeAggregationType("open"));
+ assertEquals(AggregationType.AS_BASIC_PROPERTY, setter
+ .computeAggregationType("Open"));
+
+ assertEquals(AggregationType.AS_COMPLEX_PROPERTY_COLLECTION, setter
+ .computeAggregationType("Window"));
+ assertEquals(AggregationType.AS_BASIC_PROPERTY_COLLECTION, setter
+ .computeAggregationType("adjective"));
+
+ assertEquals(AggregationType.AS_BASIC_PROPERTY, setter
+ .computeAggregationType("filterReply"));
+ assertEquals(AggregationType.AS_BASIC_PROPERTY, setter
+ .computeAggregationType("houseColor"));
+
+ System.out.println();
+ }
+
+ @Test
+ public void testSetProperty() {
+ {
+ House house = new House();
+ PropertySetter setter = new PropertySetter(house);
+ setter.setProperty("count", "10");
+ setter.setProperty("temperature", "33.1");
+
+ setter.setProperty("name", "jack");
+ setter.setProperty("open", "true");
+
+ assertEquals(10, house.getCount());
+ assertEquals(33.1d, (double) house.getTemperature(), 0.01);
+ assertEquals("jack", house.getName());
+ assertTrue(house.isOpen());
+ }
+
+ {
+ House house = new House();
+ PropertySetter setter = new PropertySetter(house);
+ setter.setProperty("Count", "10");
+ setter.setProperty("Name", "jack");
+ setter.setProperty("Open", "true");
+
+ assertEquals(10, house.getCount());
+ assertEquals("jack", house.getName());
+ assertTrue(house.isOpen());
+ }
+ }
+
+ @Test
+ public void testSetCamelProperty() {
+ setter.setProperty("camelCase", "trot");
+ assertEquals("trot", house.getCamelCase());
+
+ setter.setProperty("camelCase", "gh");
+ assertEquals("gh", house.getCamelCase());
+ }
+
+ @Test
+ public void testSetComplexProperty() {
+ Door door = new Door();
+ setter.setComplexProperty("door", door);
+ assertEquals(door, house.getDoor());
+ }
+
+ @Test
+ public void testgetClassNameViaImplicitRules() {
+ Class<?> compClass = setter.getClassNameViaImplicitRules("door",
+ AggregationType.AS_COMPLEX_PROPERTY, defaultComponentRegistry);
+ assertEquals(Door.class, compClass);
+ }
+
+ @Test
+ public void testgetComplexPropertyColleClassNameViaImplicitRules() {
+ Class<?> compClass = setter.getClassNameViaImplicitRules("window",
+ AggregationType.AS_COMPLEX_PROPERTY_COLLECTION,
+ defaultComponentRegistry);
+ assertEquals(Window.class, compClass);
+ }
+
+ @Test
+ public void testPropertyCollection() {
+ setter.addBasicProperty("adjective", "nice");
+ setter.addBasicProperty("adjective", "big");
+
+ assertEquals(2, house.adjectiveList.size());
+ assertEquals("nice", house.adjectiveList.get(0));
+ assertEquals("big", house.adjectiveList.get(1));
+ }
+
+ @Test
+ public void testComplexCollection() {
+ Window w1 = new Window();
+ w1.handle = 10;
+ Window w2 = new Window();
+ w2.handle = 20;
+
+ setter.addComplexProperty("window", w1);
+ setter.addComplexProperty("window", w2);
+ assertEquals(2, house.windowList.size());
+ assertEquals(10, house.windowList.get(0).handle);
+ assertEquals(20, house.windowList.get(1).handle);
+ }
+
+ @Test
+ public void testSetComplexWithCamelCaseName() {
+ SwimmingPool pool = new SwimmingPoolImpl();
+ setter.setComplexProperty("swimmingPool", pool);
+ assertEquals(pool, house.getSwimmingPool());
+ }
+
+ @Test
+ public void testDuration() {
+ setter.setProperty("duration", "1.4 seconds");
+ assertEquals(1400, house.getDuration().getMilliseconds());
+ }
+
+ @Test
+ public void testFileSize() {
+ setter.setProperty("fs", "2 kb");
+ assertEquals(2 * 1024, house.getFs().getSize());
+ }
+
+ @Test
+ public void testFilterReply() {
+ // test case reproducing bug #52
+ setter.setProperty("filterReply", "ACCEPT");
+ assertEquals(FilterReply.ACCEPT, house.getFilterReply());
+ }
+
+ @Test
+ public void testEnum() {
+ setter.setProperty("houseColor", "BLUE");
+ assertEquals(HouseColor.BLUE, house.getHouseColor());
+ }
+
+ @Test
+ public void testDefaultClassAnnonation() {
+ Method relevantMethod = setter.getRelevantMethod("SwimmingPool",
+ AggregationType.AS_COMPLEX_PROPERTY);
+ assertNotNull(relevantMethod);
+ Class<?> spClass = setter.getDefaultClassNameByAnnonation("SwimmingPool",
+ relevantMethod);
+ assertEquals(SwimmingPoolImpl.class, spClass);
+
+ Class<?> classViaImplicitRules = setter.getClassNameViaImplicitRules(
+ "SwimmingPool", AggregationType.AS_COMPLEX_PROPERTY,
+ defaultComponentRegistry);
+ assertEquals(SwimmingPoolImpl.class, classViaImplicitRules);
+ }
+
+ @Test
+ public void testDefaultClassAnnotationForLists() {
+ Method relevantMethod = setter.getRelevantMethod("LargeSwimmingPool",
+ AggregationType.AS_COMPLEX_PROPERTY_COLLECTION);
+ assertNotNull(relevantMethod);
+ Class<?> spClass = setter.getDefaultClassNameByAnnonation("LargeSwimmingPool",
+ relevantMethod);
+ assertEquals(LargeSwimmingPoolImpl.class, spClass);
+
+ Class<?> classViaImplicitRules = setter.getClassNameViaImplicitRules(
+ "LargeSwimmingPool", AggregationType.AS_COMPLEX_PROPERTY_COLLECTION,
+ defaultComponentRegistry);
+ assertEquals(LargeSwimmingPoolImpl.class, classViaImplicitRules);
+ }
+
+ @Test
+ public void charset() {
+ setter.setProperty("charset", "UTF-8");
+ assertEquals(Charset.forName("UTF-8"), house.getCharset());
- PropertySetter setter = new PropertySetter(new BeanDescriptionCache(context), house);
-
- @Before
- public void setUp() {
- setter.setContext(context);
- }
-
- @After
- public void tearDown() {
- }
-
- @Test
- public void testCanAggregateComponent() {
- assertEquals(AggregationType.AS_COMPLEX_PROPERTY, setter.computeAggregationType("door"));
-
- assertEquals(AggregationType.AS_BASIC_PROPERTY, setter.computeAggregationType("count"));
- assertEquals(AggregationType.AS_BASIC_PROPERTY, setter.computeAggregationType("Count"));
-
- assertEquals(AggregationType.AS_BASIC_PROPERTY, setter.computeAggregationType("name"));
- assertEquals(AggregationType.AS_BASIC_PROPERTY, setter.computeAggregationType("Name"));
-
- assertEquals(AggregationType.AS_BASIC_PROPERTY, setter.computeAggregationType("Duration"));
- assertEquals(AggregationType.AS_BASIC_PROPERTY, setter.computeAggregationType("fs"));
-
- assertEquals(AggregationType.AS_BASIC_PROPERTY, setter.computeAggregationType("open"));
- assertEquals(AggregationType.AS_BASIC_PROPERTY, setter.computeAggregationType("Open"));
-
- assertEquals(AggregationType.AS_COMPLEX_PROPERTY_COLLECTION, setter.computeAggregationType("Window"));
- assertEquals(AggregationType.AS_BASIC_PROPERTY_COLLECTION, setter.computeAggregationType("adjective"));
-
- assertEquals(AggregationType.AS_BASIC_PROPERTY, setter.computeAggregationType("filterReply"));
- assertEquals(AggregationType.AS_BASIC_PROPERTY, setter.computeAggregationType("houseColor"));
- }
+ house.setCharset(null);
+ setter.setProperty("charset", "UTF");
+ assertNull(house.getCharset());
- @Test
- public void testSetProperty() {
- {
- House house = new House();
- PropertySetter setter = new PropertySetter(new BeanDescriptionCache(context), house);
- setter.setProperty("count", "10");
- setter.setProperty("temperature", "33.1");
-
- setter.setProperty("name", "jack");
- setter.setProperty("open", "true");
-
- assertEquals(10, house.getCount());
- assertEquals(33.1d, (double) house.getTemperature(), 0.01);
- assertEquals("jack", house.getName());
- assertTrue(house.isOpen());
- }
-
- {
- House house = new House();
- PropertySetter setter = new PropertySetter(new BeanDescriptionCache(context), house);
- setter.setProperty("Count", "10");
- setter.setProperty("Name", "jack");
- setter.setProperty("Open", "true");
-
- assertEquals(10, house.getCount());
- assertEquals("jack", house.getName());
- assertTrue(house.isOpen());
- }
- }
-
- @Test
- public void testSetCamelProperty() {
- setter.setProperty("camelCase", "trot");
- assertEquals("trot", house.getCamelCase());
-
- setter.setProperty("camelCase", "gh");
- assertEquals("gh", house.getCamelCase());
- }
-
- @Test
- public void testSetComplexProperty() {
- Door door = new Door();
- setter.setComplexProperty("door", door);
- assertEquals(door, house.getDoor());
- }
-
- @Test
- public void testgetClassNameViaImplicitRules() {
- Class<?> compClass = setter.getClassNameViaImplicitRules("door", AggregationType.AS_COMPLEX_PROPERTY, defaultComponentRegistry);
- assertEquals(Door.class, compClass);
- }
-
- @Test
- public void testgetComplexPropertyColleClassNameViaImplicitRules() {
- Class<?> compClass = setter.getClassNameViaImplicitRules("window", AggregationType.AS_COMPLEX_PROPERTY_COLLECTION, defaultComponentRegistry);
- assertEquals(Window.class, compClass);
- }
-
- @Test
- public void testPropertyCollection() {
- setter.addBasicProperty("adjective", "nice");
- setter.addBasicProperty("adjective", "big");
-
- assertEquals(2, house.adjectiveList.size());
- assertEquals("nice", house.adjectiveList.get(0));
- assertEquals("big", house.adjectiveList.get(1));
- }
-
- @Test
- public void testComplexCollection() {
- Window w1 = new Window();
- w1.handle = 10;
- Window w2 = new Window();
- w2.handle = 20;
-
- setter.addComplexProperty("window", w1);
- setter.addComplexProperty("window", w2);
- assertEquals(2, house.windowList.size());
- assertEquals(10, house.windowList.get(0).handle);
- assertEquals(20, house.windowList.get(1).handle);
- }
-
- @Test
- public void testSetComplexWithCamelCaseName() {
- SwimmingPool pool = new SwimmingPoolImpl();
- setter.setComplexProperty("swimmingPool", pool);
- assertEquals(pool, house.getSwimmingPool());
- }
-
- @Test
- public void testDuration() {
- setter.setProperty("duration", "1.4 seconds");
- assertEquals(1400, house.getDuration().getMilliseconds());
- }
-
- @Test
- public void testFileSize() {
- setter.setProperty("fs", "2 kb");
- assertEquals(2 * 1024, house.getFs().getSize());
- }
-
- @Test
- public void testFilterReply() {
- // test case reproducing bug #52
- setter.setProperty("filterReply", "ACCEPT");
- assertEquals(FilterReply.ACCEPT, house.getFilterReply());
- }
-
- @Test
- public void testEnum() {
- setter.setProperty("houseColor", "BLUE");
- assertEquals(HouseColor.BLUE, house.getHouseColor());
- }
-
- @Test
- public void testDefaultClassAnnonation() {
- Method relevantMethod = setter.getRelevantMethod("SwimmingPool", AggregationType.AS_COMPLEX_PROPERTY);
- assertNotNull(relevantMethod);
- Class<?> spClass = setter.getDefaultClassNameByAnnonation("SwimmingPool", relevantMethod);
- assertEquals(SwimmingPoolImpl.class, spClass);
-
- Class<?> classViaImplicitRules = setter.getClassNameViaImplicitRules("SwimmingPool", AggregationType.AS_COMPLEX_PROPERTY, defaultComponentRegistry);
- assertEquals(SwimmingPoolImpl.class, classViaImplicitRules);
- }
-
- @Test
- public void testDefaultClassAnnotationForLists() {
- Method relevantMethod = setter.getRelevantMethod("LargeSwimmingPool", AggregationType.AS_COMPLEX_PROPERTY_COLLECTION);
- assertNotNull(relevantMethod);
- Class<?> spClass = setter.getDefaultClassNameByAnnonation("LargeSwimmingPool", relevantMethod);
- assertEquals(LargeSwimmingPoolImpl.class, spClass);
-
- Class<?> classViaImplicitRules = setter.getClassNameViaImplicitRules("LargeSwimmingPool", AggregationType.AS_COMPLEX_PROPERTY_COLLECTION,
- defaultComponentRegistry);
- assertEquals(LargeSwimmingPoolImpl.class, classViaImplicitRules);
- }
-
- @Test
- public void charset() {
- setter.setProperty("charset", "UTF-8");
- assertEquals(Charset.forName("UTF-8"), house.getCharset());
-
- house.setCharset(null);
- setter.setProperty("charset", "UTF");
- assertNull(house.getCharset());
-
- StatusChecker checker = new StatusChecker(context);
- checker.containsException(UnsupportedCharsetException.class);
- }
-
- // see also http://jira.qos.ch/browse/LOGBACK-1164
- @Test
- public void bridgeMethodsShouldBeIgnored() {
- Orange orange = new Orange();
-
- PropertySetter orangeSetter = new PropertySetter(new BeanDescriptionCache(context), orange);
- assertEquals(AggregationType.AS_BASIC_PROPERTY, orangeSetter.computeAggregationType(Citrus.PRECARP_PROPERTY_NAME));
-
-
- checker.assertIsWarningOrErrorFree();
- }
+ StatusChecker checker = new StatusChecker(context);
+ checker.containsException(UnsupportedCharsetException.class);
+ }
}
+
diff --git a/logback-core/src/test/java/ch/qos/logback/core/layout/DummyLayout.java b/logback-core/src/test/java/ch/qos/logback/core/layout/DummyLayout.java
index b5d11af..f82e411 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/layout/DummyLayout.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/layout/DummyLayout.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,18 +18,19 @@ import ch.qos.logback.core.LayoutBase;
public class DummyLayout<E> extends LayoutBase<E> {
- public static final String DUMMY = "dummy" + CoreConstants.LINE_SEPARATOR;
- String val = DUMMY;
-
- public DummyLayout() {
- }
-
- public DummyLayout(String val) {
- this.val = val;
- }
-
- public String doLayout(E event) {
- return val;
- }
+ public static final String DUMMY = "dummy"+CoreConstants.LINE_SEPARATOR;
+ String val = DUMMY;
+
+ public DummyLayout() {
+ }
+
+ public DummyLayout(String val) {
+ this.val = val;
+ }
+
+ public String doLayout(E event) {
+ return val;
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/layout/NopLayout.java b/logback-core/src/test/java/ch/qos/logback/core/layout/NopLayout.java
index b04c50f..2162465 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/layout/NopLayout.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/layout/NopLayout.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,8 +16,8 @@ package ch.qos.logback.core.layout;
import ch.qos.logback.core.LayoutBase;
public class NopLayout<E> extends LayoutBase<E> {
-
- public String doLayout(E event) {
- return "";
- }
+
+ public String doLayout(E event) {
+ return "";
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/AbstractSSLSocketAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/AbstractSSLSocketAppenderTest.java
index 0f0630b..59e66c7 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/AbstractSSLSocketAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/AbstractSSLSocketAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,36 +27,38 @@ import ch.qos.logback.core.spi.PreSerializationTransformer;
* @author Carl Harris
*/
public class AbstractSSLSocketAppenderTest {
+
+ private MockContext context = new MockContext();
- private MockContext context = new MockContext();
+ private InstrumentedSSLSocketAppenderBase appender =
+ new InstrumentedSSLSocketAppenderBase();
+
+ @Before
+ public void setUp() throws Exception {
+ appender.setContext(context);
+ }
+
+ @Test
+ public void testUsingDefaultConfig() throws Exception {
+ // should be able to start and stop successfully with no SSL
+ // configuration at all
+ appender.start();
+ assertNotNull(appender.getSocketFactory());
+ appender.stop();
+ }
+
+ private static class InstrumentedSSLSocketAppenderBase
+ extends AbstractSSLSocketAppender<Object> {
- private InstrumentedSSLSocketAppenderBase appender = new InstrumentedSSLSocketAppenderBase();
-
- @Before
- public void setUp() throws Exception {
- appender.setContext(context);
- }
-
- @Test
- public void testUsingDefaultConfig() throws Exception {
- // should be able to start and stop successfully with no SSL
- // configuration at all
- appender.start();
- assertNotNull(appender.getSocketFactory());
- appender.stop();
+ @Override
+ protected void postProcessEvent(Object event) {
+ throw new UnsupportedOperationException();
}
- private static class InstrumentedSSLSocketAppenderBase extends AbstractSSLSocketAppender<Object> {
-
- @Override
- protected void postProcessEvent(Object event) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected PreSerializationTransformer<Object> getPST() {
- throw new UnsupportedOperationException();
- }
-
+ @Override
+ protected PreSerializationTransformer<Object> getPST() {
+ throw new UnsupportedOperationException();
}
+
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/AbstractSocketAppenderIntegrationTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/AbstractSocketAppenderIntegrationTest.java
deleted file mode 100644
index 1a734f8..0000000
--- a/logback-core/src/test/java/ch/qos/logback/core/net/AbstractSocketAppenderIntegrationTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.net;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.concurrent.LinkedBlockingDeque;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import ch.qos.logback.core.net.mock.MockContext;
-import ch.qos.logback.core.net.server.ServerSocketUtil;
-import ch.qos.logback.core.spi.PreSerializationTransformer;
-import ch.qos.logback.core.util.ExecutorServiceUtil;
-
-/**
- * Integration tests for {@link ch.qos.logback.core.net.AbstractSocketAppender}.
- *
- * @author Carl Harris
- * @author Sebastian Gröbler
- */
-public class AbstractSocketAppenderIntegrationTest {
-
- private static final int TIMEOUT = 2000;
-
- private ScheduledExecutorService executorService = ExecutorServiceUtil.newScheduledExecutorService();
- private MockContext mockContext = new MockContext(executorService);
- private AutoFlushingObjectWriter objectWriter;
- private ObjectWriterFactory objectWriterFactory = new SpyProducingObjectWriterFactory();
- private LinkedBlockingDeque<String> deque = spy(new LinkedBlockingDeque<String>(1));
- private QueueFactory queueFactory = mock(QueueFactory.class);
- private InstrumentedSocketAppender instrumentedAppender = new InstrumentedSocketAppender(queueFactory, objectWriterFactory);
-
- @Before
- public void setUp() throws Exception {
- when(queueFactory.<String> newLinkedBlockingDeque(anyInt())).thenReturn(deque);
- instrumentedAppender.setContext(mockContext);
- }
-
- @After
- public void tearDown() throws Exception {
- instrumentedAppender.stop();
- assertFalse(instrumentedAppender.isStarted());
- executorService.shutdownNow();
- assertTrue(executorService.awaitTermination(TIMEOUT, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void dispatchesEvents() throws Exception {
-
- // given
- ServerSocket serverSocket = ServerSocketUtil.createServerSocket();
- instrumentedAppender.setRemoteHost(serverSocket.getInetAddress().getHostAddress());
- instrumentedAppender.setPort(serverSocket.getLocalPort());
- instrumentedAppender.start();
-
- Socket appenderSocket = serverSocket.accept();
- serverSocket.close();
-
- // when
- instrumentedAppender.append("some event");
-
- // wait for event to be taken from deque and being written into the stream
- verify(deque, timeout(TIMEOUT).atLeastOnce()).takeFirst();
- verify(objectWriter, timeout(TIMEOUT)).write("some event");
-
- // then
- ObjectInputStream ois = new ObjectInputStream(appenderSocket.getInputStream());
- assertEquals("some event", ois.readObject());
- appenderSocket.close();
- }
-
- private static class InstrumentedSocketAppender extends AbstractSocketAppender<String> {
-
- public InstrumentedSocketAppender(QueueFactory queueFactory, ObjectWriterFactory objectWriterFactory) {
- super(queueFactory, objectWriterFactory);
- }
-
- @Override
- protected void postProcessEvent(String event) {
- }
-
- @Override
- protected PreSerializationTransformer<String> getPST() {
- return new PreSerializationTransformer<String>() {
- public Serializable transform(String event) {
- return event;
- }
- };
- }
- }
-
- private class SpyProducingObjectWriterFactory extends ObjectWriterFactory {
-
- @Override
- public AutoFlushingObjectWriter newAutoFlushingObjectWriter(OutputStream outputStream) throws IOException {
- objectWriter = spy(super.newAutoFlushingObjectWriter(outputStream));
- return objectWriter;
- }
- }
-}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/AbstractSocketAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/AbstractSocketAppenderTest.java
index e863cc0..9487fa4 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/AbstractSocketAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/AbstractSocketAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2011, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -11,517 +11,245 @@
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
+
package ch.qos.logback.core.net;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.contains;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-import java.io.OutputStream;
+
+import java.io.ObjectInputStream;
import java.io.Serializable;
-import java.net.InetAddress;
+import java.net.ServerSocket;
import java.net.Socket;
-import java.util.concurrent.LinkedBlockingDeque;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
+import java.util.List;
+import java.util.concurrent.*;
+
+import ch.qos.logback.core.BasicStatusManager;
+import ch.qos.logback.core.status.Status;
+import ch.qos.logback.core.status.StatusListener;
+import ch.qos.logback.core.status.StatusManager;
+import ch.qos.logback.core.util.StatusPrinter;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
-import org.mockito.InOrder;
import ch.qos.logback.core.net.mock.MockContext;
+import ch.qos.logback.core.net.server.ServerSocketUtil;
import ch.qos.logback.core.spi.PreSerializationTransformer;
-import ch.qos.logback.core.util.Duration;
-import ch.qos.logback.core.util.ExecutorServiceUtil;
/**
* Unit tests for {@link AbstractSocketAppender}.
*
* @author Carl Harris
- * @author Sebastian Gröbler
*/
public class AbstractSocketAppenderTest {
- /**
- * Timeout used for all blocking operations in multi-threading contexts.
- */
- private static final int TIMEOUT = 1000;
-
- private ScheduledExecutorService executorService = spy((ScheduledExecutorService) ExecutorServiceUtil.newScheduledExecutorService());
- private MockContext mockContext = new MockContext(executorService);
- private PreSerializationTransformer<String> preSerializationTransformer = spy(new StringPreSerializationTransformer());
- private Socket socket = mock(Socket.class);
- private SocketConnector socketConnector = mock(SocketConnector.class);
- private AutoFlushingObjectWriter objectWriter = mock(AutoFlushingObjectWriter.class);
- private ObjectWriterFactory objectWriterFactory = mock(ObjectWriterFactory.class);
- private LinkedBlockingDeque<String> deque = spy(new LinkedBlockingDeque<String>(1));
- private QueueFactory queueFactory = mock(QueueFactory.class);
- private InstrumentedSocketAppender appender = spy(new InstrumentedSocketAppender(preSerializationTransformer, queueFactory, objectWriterFactory,
- socketConnector));
-
- @Before
- public void setupValidAppenderWithMockDependencies() throws Exception {
-
- doReturn(objectWriter).when(objectWriterFactory).newAutoFlushingObjectWriter(any(OutputStream.class));
- doReturn(deque).when(queueFactory).<String> newLinkedBlockingDeque(anyInt());
-
- appender.setContext(mockContext);
- appender.setRemoteHost("localhost");
- }
-
- @After
- public void tearDown() throws Exception {
- appender.stop();
- assertFalse(appender.isStarted());
-
- executorService.shutdownNow();
- assertTrue(executorService.awaitTermination(TIMEOUT, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void failsToStartWithoutValidPort() throws Exception {
-
- // given
- appender.setPort(-1);
-
- // when
- appender.start();
-
- // then
- assertFalse(appender.isStarted());
- verify(appender).addError(contains("port"));
- }
-
- @Test
- public void failsToStartWithoutValidRemoteHost() throws Exception {
-
- // given
- appender.setRemoteHost(null);
-
- // when
- appender.start();
-
- // then
- assertFalse(appender.isStarted());
- verify(appender).addError(contains("remote host"));
- }
-
- @Test
- public void failsToStartWithNegativeQueueSize() throws Exception {
-
- // given
- appender.setQueueSize(-1);
-
- // when
- appender.start();
-
- // then
- assertFalse(appender.isStarted());
- verify(appender).addError(contains("Queue size must be greater than zero"));
- }
-
- @Test
- public void failsToStartWithUnresolvableRemoteHost() throws Exception {
-
- // given
- appender.setRemoteHost("NOT.A.VALID.REMOTE.HOST.NAME");
-
- // when
- appender.start();
-
- // then
- assertFalse(appender.isStarted());
- verify(appender).addError(contains("unknown host"));
- }
-
- @Test
- public void startsButOutputsWarningWhenQueueSizeIsZero() throws Exception {
-
- // given
- appender.setQueueSize(0);
-
- // when
- appender.start();
-
- // then
- assertTrue(appender.isStarted());
- verify(appender).addWarn("Queue size of zero is deprecated, use a size of one to indicate synchronous processing");
- }
-
- @Test
- public void startsWithValidParameters() throws Exception {
-
- // when
- appender.start();
-
- // then
- assertTrue(appender.isStarted());
- }
-
- @Test
- public void createsSocketConnectorWithConfiguredParameters() throws Exception {
-
- // given
- appender.setReconnectionDelay(new Duration(42));
- appender.setRemoteHost("localhost");
- appender.setPort(21);
-
- // when
- appender.start();
-
- // then
- verify(appender, timeout(TIMEOUT)).newConnector(InetAddress.getByName("localhost"), 21, 0, 42);
- }
-
- @Test
- public void addsInfoMessageWhenSocketConnectionWasEstablished() throws Exception {
-
- // when
- mockOneSuccessfulSocketConnection();
- appender.start();
-
- // then
- verify(appender, timeout(TIMEOUT)).addInfo(contains("connection established"));
- }
-
- @Test
- public void addsInfoMessageWhenSocketConnectionFailed() throws Exception {
-
- // given
- mockOneSuccessfulSocketConnection();
- doThrow(new IOException()).when(objectWriterFactory).newAutoFlushingObjectWriter(any(OutputStream.class));
- appender.start();
-
- // when
- appender.append("some event");
-
- // then
- verify(appender, timeout(TIMEOUT).atLeastOnce()).addInfo(contains("connection failed"));
- }
-
- @Test
- public void closesSocketOnException() throws Exception {
-
- // given
- mockOneSuccessfulSocketConnection();
- doThrow(new IOException()).when(objectWriterFactory).newAutoFlushingObjectWriter(any(OutputStream.class));
- appender.start();
-
- // when
- appender.append("some event");
-
- // then
- verify(socket, timeout(TIMEOUT).atLeastOnce()).close();
- }
-
- @Test
- public void addsInfoMessageWhenSocketConnectionClosed() throws Exception {
-
- // given
- mockOneSuccessfulSocketConnection();
- doThrow(new IOException()).when(objectWriterFactory).newAutoFlushingObjectWriter(any(OutputStream.class));
- appender.start();
-
- // when
- appender.append("some event");
-
- // then
- verify(appender, timeout(TIMEOUT).atLeastOnce()).addInfo(contains("connection closed"));
- }
-
- @Test
- public void shutsDownOnInterruptWhileWaitingForEvent() throws Exception {
-
- // given
- mockOneSuccessfulSocketConnection();
- doThrow(new InterruptedException()).when(deque).takeFirst();
-
- // when
- appender.start();
-
- // then
- verify(deque, timeout(TIMEOUT)).takeFirst();
- }
-
- @Test
- public void shutsDownOnInterruptWhileWaitingForSocketConnection() throws Exception {
-
- // given
- doThrow(new InterruptedException()).when(socketConnector).call();
-
- // when
- appender.start();
-
- // then
- verify(socketConnector, timeout(TIMEOUT)).call();
- }
-
- @Test
- public void addsInfoMessageWhenShuttingDownDueToInterrupt() throws Exception {
-
- // given
- doThrow(new InterruptedException()).when(socketConnector).call();
-
- // when
- appender.start();
-
- // then
- verify(appender, timeout(TIMEOUT)).addInfo(contains("shutting down"));
- }
-
- @Test
- public void offersEventsToTheEndOfTheDeque() throws Exception {
-
- // given
- appender.start();
-
- // when
- appender.append("some event");
-
- // then
- verify(deque).offer(eq("some event"), anyLong(), any(TimeUnit.class));
- }
-
- @Test
- public void doesNotQueueAnyEventsWhenStopped() throws Exception {
-
- // given
- appender.start();
- appender.stop();
-
- // when
- appender.append("some event");
-
- // then
- verifyZeroInteractions(deque);
- }
-
- @Test
- public void addsInfoMessageWhenEventCouldNotBeQueuedInConfiguredTimeoutDueToQueueSizeLimitation() throws Exception {
-
- // given
- long eventDelayLimit = 42;
- doReturn(false).when(deque).offer("some event", eventDelayLimit, TimeUnit.MILLISECONDS);
- appender.setEventDelayLimit(new Duration(eventDelayLimit));
- appender.start();
-
- // when
- appender.append("some event");
-
- // then
- verify(appender).addInfo("Dropping event due to timeout limit of [" + eventDelayLimit + " milliseconds] being exceeded");
- }
-
- @Test
- public void takesEventsFromTheFrontOfTheDeque() throws Exception {
-
- // given
- mockOneSuccessfulSocketConnection();
- appender.start();
- awaitStartOfEventDispatching();
-
- // when
- appender.append("some event");
-
- // then
- verify(deque, timeout(TIMEOUT).atLeastOnce()).takeFirst();
- }
-
- @Test
- public void reAddsEventAtTheFrontOfTheDequeWhenTransmissionFails() throws Exception {
-
- // given
- mockOneSuccessfulSocketConnection();
- doThrow(new IOException()).when(objectWriter).write(anyObject());
- appender.start();
- awaitStartOfEventDispatching();
-
- // when
- appender.append("some event");
-
- // then
- verify(deque, timeout(TIMEOUT).atLeastOnce()).offerFirst("some event");
- }
-
- @Test
- public void addsErrorMessageWhenAppendingIsInterruptedWhileWaitingForTheQueueToAcceptTheEvent() throws Exception {
-
- // given
- final InterruptedException interruptedException = new InterruptedException();
- doThrow(interruptedException).when(deque).offer(eq("some event"), anyLong(), any(TimeUnit.class));
- appender.start();
-
- // when
- appender.append("some event");
-
- // then
- verify(appender).addError("Interrupted while appending event to SocketAppender", interruptedException);
- }
-
- @Test
- public void postProcessesEventsBeforeTransformingItToASerializable() throws Exception {
-
- // given
- mockOneSuccessfulSocketConnection();
- appender.start();
- awaitStartOfEventDispatching();
-
- // when
- appender.append("some event");
- awaitAtLeastOneEventToBeDispatched();
-
- // then
- InOrder inOrder = inOrder(appender, preSerializationTransformer);
- inOrder.verify(appender).postProcessEvent("some event");
- inOrder.verify(preSerializationTransformer).transform("some event");
- }
-
- @Test
- public void writesSerializedEventToStream() throws Exception {
-
- // given
- mockOneSuccessfulSocketConnection();
- when(preSerializationTransformer.transform("some event")).thenReturn("some serialized event");
- appender.start();
- awaitStartOfEventDispatching();
-
- // when
- appender.append("some event");
-
- // then
- verify(objectWriter, timeout(TIMEOUT)).write("some serialized event");
- }
-
- @Test
- public void addsInfoMessageWhenEventIsBeingDroppedBecauseOfConnectionProblemAndDequeCapacityLimitReached() throws Exception {
-
- // given
- mockOneSuccessfulSocketConnection();
- doThrow(new IOException()).when(objectWriter).write(anyObject());
- doReturn(false).when(deque).offerFirst("some event");
- appender.start();
- awaitStartOfEventDispatching();
- reset(appender);
-
- // when
- appender.append("some event");
-
- // then
- verify(appender, timeout(TIMEOUT)).addInfo("Dropping event due to socket connection error and maxed out deque capacity");
- }
-
- @Test
- public void reEstablishesSocketConnectionOnConnectionDropWhenWritingEvent() throws Exception {
-
- // given
- mockTwoSuccessfulSocketConnections();
- doThrow(new IOException()).when(objectWriter).write(anyObject());
- appender.start();
- awaitStartOfEventDispatching();
-
- // when
- appender.append("some event");
-
- // then
- verify(objectWriterFactory, timeout(TIMEOUT).atLeast(2)).newAutoFlushingObjectWriter(any(OutputStream.class));
- }
-
- @Test
- public void triesToReEstablishSocketConnectionIfItFailed() throws Exception {
-
- // given
- mockOneSuccessfulSocketConnection();
- doThrow(new IOException()).when(socket).getOutputStream();
- appender.start();
-
- // when
- appender.append("some event");
-
- // then
- verify(socketConnector, timeout(TIMEOUT).atLeast(2)).call();
- }
-
- @Test
- public void usesConfiguredAcceptConnectionTimeoutAndResetsSocketTimeoutAfterSuccessfulConnection() throws Exception {
-
- // when
- mockOneSuccessfulSocketConnection();
- appender.setAcceptConnectionTimeout(42);
- appender.start();
- awaitStartOfEventDispatching();
-
- // then
- InOrder inOrder = inOrder(socket);
- inOrder.verify(socket).setSoTimeout(42);
- inOrder.verify(socket).setSoTimeout(0);
- }
-
- private void awaitAtLeastOneEventToBeDispatched() throws IOException {
- verify(objectWriter, timeout(TIMEOUT)).write(anyString());
- }
-
- private void awaitStartOfEventDispatching() throws InterruptedException {
- verify(deque, timeout(TIMEOUT)).takeFirst();
+ private static final int DELAY = 10000;
+
+ private ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newCachedThreadPool();
+ private MockContext mockContext = new MockContext(executorService);
+ private InstrumentedSocketAppender instrumentedAppender = new InstrumentedSocketAppender();
+
+ @Before
+ public void setUp() throws Exception {
+ instrumentedAppender.setContext(mockContext);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ instrumentedAppender.stop();
+ assertFalse(instrumentedAppender.isStarted());
+ executorService.shutdownNow();
+ assertTrue(executorService.awaitTermination(DELAY, TimeUnit.MILLISECONDS));
+ }
+
+ @Test
+ public void appenderShouldFailToStartWithoutValidPort() throws Exception {
+ instrumentedAppender.setPort(-1);
+ instrumentedAppender.setRemoteHost("localhost");
+ instrumentedAppender.setQueueSize(0);
+ instrumentedAppender.start();
+ assertFalse(instrumentedAppender.isStarted());
+ assertTrue(mockContext.getLastStatus().getMessage().contains("port"));
+ }
+
+ @Test
+ public void appenderShouldFailToStartWithoutValidRemoteHost() throws Exception {
+ instrumentedAppender.setPort(1);
+ instrumentedAppender.setRemoteHost(null);
+ instrumentedAppender.setQueueSize(0);
+ instrumentedAppender.start();
+ assertFalse(instrumentedAppender.isStarted());
+ assertTrue(mockContext.getLastStatus().getMessage().contains("remote host"));
+ }
+
+ @Test
+ public void appenderShouldFailToStartWithNegativeQueueSize() throws Exception {
+ instrumentedAppender.setPort(1);
+ instrumentedAppender.setRemoteHost("localhost");
+ instrumentedAppender.setQueueSize(-1);
+ instrumentedAppender.start();
+ assertFalse(instrumentedAppender.isStarted());
+ assertTrue(mockContext.getLastStatus().getMessage().contains("Queue"));
+ }
+
+ @Test
+ public void appenderShouldFailToStartWithUnresolvableRemoteHost() throws Exception {
+ instrumentedAppender.setPort(1);
+ instrumentedAppender.setRemoteHost("NOT.A.VALID.REMOTE.HOST.NAME");
+ instrumentedAppender.setQueueSize(0);
+ instrumentedAppender.start();
+ assertFalse(instrumentedAppender.isStarted());
+ assertTrue(mockContext.getLastStatus().getMessage().contains("unknown host"));
+ }
+
+ @Test
+ public void appenderShouldFailToStartWithZeroQueueLength() throws Exception {
+ instrumentedAppender.setPort(1);
+ instrumentedAppender.setRemoteHost("localhost");
+ instrumentedAppender.setQueueSize(0);
+ instrumentedAppender.start();
+ assertTrue(instrumentedAppender.isStarted());
+ assertTrue(instrumentedAppender.lastQueue instanceof SynchronousQueue);
+ }
+
+ @Test
+ public void appenderShouldStartWithValidParameters() throws Exception {
+ instrumentedAppender.setPort(1);
+ instrumentedAppender.setRemoteHost("localhost");
+ instrumentedAppender.setQueueSize(1);
+ instrumentedAppender.start();
+ assertTrue(instrumentedAppender.isStarted());
+ assertTrue(instrumentedAppender.lastQueue instanceof ArrayBlockingQueue);
+ assertEquals(1, instrumentedAppender.lastQueue.remainingCapacity());
+ }
+
+ // this test takes 1 second and is deemed too long
+ @Ignore
+ @Test(timeout = 2000)
+ public void appenderShouldCleanupTasksWhenStopped() throws Exception {
+ mockContext.setStatusManager(new BasicStatusManager());
+ instrumentedAppender.setPort(1);
+ instrumentedAppender.setRemoteHost("localhost");
+ instrumentedAppender.setQueueSize(1);
+ instrumentedAppender.start();
+ assertTrue(instrumentedAppender.isStarted());
+
+ waitForActiveCountToEqual(executorService, 2);
+ instrumentedAppender.stop();
+ waitForActiveCountToEqual(executorService, 0);
+ StatusPrinter.print(mockContext);
+ assertEquals(0, executorService.getActiveCount());
+
+ }
+
+ private void waitForActiveCountToEqual(ThreadPoolExecutor executorService, int i) {
+ while (executorService.getActiveCount() != i) {
+ try {
+ Thread.yield();
+ Thread.sleep(1);
+ System.out.print(".");
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+
+ @Test
+ public void testAppendWhenNotStarted() throws Exception {
+ instrumentedAppender.setRemoteHost("localhost");
+ instrumentedAppender.start();
+ instrumentedAppender.stop();
+
+ // make sure the appender task has stopped
+ executorService.shutdownNow();
+ assertTrue(executorService.awaitTermination(DELAY, TimeUnit.MILLISECONDS));
+
+ instrumentedAppender.append("some event");
+ assertTrue(instrumentedAppender.lastQueue.isEmpty());
+ }
+
+ @Test(timeout = 1000)
+ public void testAppendSingleEvent() throws Exception {
+ instrumentedAppender.setRemoteHost("localhost");
+ instrumentedAppender.start();
+
+ instrumentedAppender.latch.await();
+ instrumentedAppender.append("some event");
+ assertTrue(instrumentedAppender.lastQueue.size() == 1);
+ }
+
+ @Test
+ public void testAppendEvent() throws Exception {
+ instrumentedAppender.setRemoteHost("localhost");
+ instrumentedAppender.setQueueSize(1);
+ instrumentedAppender.start();
+
+ // stop the appender task, but don't stop the appender
+ executorService.shutdownNow();
+ assertTrue(executorService.awaitTermination(DELAY, TimeUnit.MILLISECONDS));
+
+ instrumentedAppender.append("some event");
+ assertEquals("some event", instrumentedAppender.lastQueue.poll());
+ }
+
+ @Test
+ public void testDispatchEvent() throws Exception {
+ ServerSocket serverSocket = ServerSocketUtil.createServerSocket();
+ instrumentedAppender.setRemoteHost(serverSocket.getInetAddress().getHostAddress());
+ instrumentedAppender.setPort(serverSocket.getLocalPort());
+ instrumentedAppender.setQueueSize(1);
+ instrumentedAppender.start();
+
+ Socket appenderSocket = serverSocket.accept();
+ serverSocket.close();
+
+ instrumentedAppender.append("some event");
+
+ final int shortDelay = 100;
+ for (int i = 0, retries = DELAY / shortDelay;
+ !instrumentedAppender.lastQueue.isEmpty() && i < retries;
+ i++) {
+ Thread.sleep(shortDelay);
+ }
+ assertTrue(instrumentedAppender.lastQueue.isEmpty());
+
+ ObjectInputStream ois = new ObjectInputStream(appenderSocket.getInputStream());
+ assertEquals("some event", ois.readObject());
+ appenderSocket.close();
+
+ }
+
+ private static class InstrumentedSocketAppender extends AbstractSocketAppender<String> {
+
+ private BlockingQueue<String> lastQueue;
+ CountDownLatch latch = new CountDownLatch(1);
+ @Override
+ protected void postProcessEvent(String event) {
+ }
+
+ @Override
+ protected PreSerializationTransformer<String> getPST() {
+ return new PreSerializationTransformer<String>() {
+ public Serializable transform(String event) {
+ return event;
+ }
+ };
}
- private void mockOneSuccessfulSocketConnection() throws InterruptedException {
- doReturn(socket).doReturn(null).when(socketConnector).call();
+ @Override
+ protected void signalEntryInRunMethod() {
+ latch.countDown();
}
- private void mockTwoSuccessfulSocketConnections() throws InterruptedException {
- doReturn(socket).doReturn(socket).doReturn(null).when(socketConnector).call();
+ @Override
+ BlockingQueue<String> newBlockingQueue(int queueSize) {
+ lastQueue = super.newBlockingQueue(queueSize);
+ return lastQueue;
}
- private static class InstrumentedSocketAppender extends AbstractSocketAppender<String> {
-
- private PreSerializationTransformer<String> preSerializationTransformer;
- private SocketConnector socketConnector;
-
- public InstrumentedSocketAppender(PreSerializationTransformer<String> preSerializationTransformer, QueueFactory queueFactory,
- ObjectWriterFactory objectWriterFactory, SocketConnector socketConnector) {
- super(queueFactory, objectWriterFactory);
- this.preSerializationTransformer = preSerializationTransformer;
- this.socketConnector = socketConnector;
- }
-
- @Override
- protected void postProcessEvent(String event) {
- }
+ }
- @Override
- protected PreSerializationTransformer<String> getPST() {
- return preSerializationTransformer;
- }
-
- @Override
- protected SocketConnector newConnector(InetAddress address, int port, long initialDelay, long retryDelay) {
- return socketConnector;
- }
- }
-
- private static class StringPreSerializationTransformer implements PreSerializationTransformer<String> {
-
- @Override
- public Serializable transform(String event) {
- return event;
- }
- }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/AutoFlushingObjectWriterTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/AutoFlushingObjectWriterTest.java
deleted file mode 100644
index d1546f8..0000000
--- a/logback-core/src/test/java/ch/qos/logback/core/net/AutoFlushingObjectWriterTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.net;
-
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.InOrder;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
-/**
- * Unit tests for {@link ch.qos.logback.core.net.AutoFlushingObjectWriter}.
- *
- * @author Sebastian Gröbler
- */
-public class AutoFlushingObjectWriterTest {
-
- private InstrumentedObjectOutputStream objectOutputStream;
-
- @Before
- public void beforeEachTest() throws IOException {
- objectOutputStream = spy(new InstrumentedObjectOutputStream());
- }
-
- @Test
- public void writesToUnderlyingObjectOutputStream() throws IOException {
-
- // given
- ObjectWriter objectWriter = new AutoFlushingObjectWriter(objectOutputStream, 2);
- String object = "foo";
-
- // when
- objectWriter.write(object);
-
- // then
- verify(objectOutputStream).writeObjectOverride(object);
- }
-
- @Test
- public void flushesAfterWrite() throws IOException {
-
- // given
- ObjectWriter objectWriter = new AutoFlushingObjectWriter(objectOutputStream, 2);
- String object = "foo";
-
- // when
- objectWriter.write(object);
-
- // then
- InOrder inOrder = inOrder(objectOutputStream);
- inOrder.verify(objectOutputStream).writeObjectOverride(object);
- inOrder.verify(objectOutputStream).flush();
- }
-
- @Test
- public void resetsObjectOutputStreamAccordingToGivenResetFrequency() throws IOException {
-
- // given
- ObjectWriter objectWriter = new AutoFlushingObjectWriter(objectOutputStream, 2);
- String object = "foo";
-
- // when
- objectWriter.write(object);
- objectWriter.write(object);
- objectWriter.write(object);
- objectWriter.write(object);
-
- // then
- InOrder inOrder = inOrder(objectOutputStream);
- inOrder.verify(objectOutputStream).writeObjectOverride(object);
- inOrder.verify(objectOutputStream).writeObjectOverride(object);
- inOrder.verify(objectOutputStream).reset();
- inOrder.verify(objectOutputStream).writeObjectOverride(object);
- inOrder.verify(objectOutputStream).writeObjectOverride(object);
- inOrder.verify(objectOutputStream).reset();
- }
-
- private static class InstrumentedObjectOutputStream extends ObjectOutputStream {
-
- protected InstrumentedObjectOutputStream() throws IOException, SecurityException {
- }
-
- @Override
- protected void writeObjectOverride(final Object obj) throws IOException {
- // nop
- }
-
- @Override
- public void flush() throws IOException {
- // nop
- }
-
- @Override
- public void reset() throws IOException {
- // nop
- }
- }
-}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/DefaultSocketConnectorTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/DefaultSocketConnectorTest.java
index a665e82..6985aa3 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/DefaultSocketConnectorTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/DefaultSocketConnectorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -39,6 +39,7 @@ import static org.junit.Assert.fail;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+
/**
* Unit tests for {@link DefaultSocketConnector}.
*
@@ -46,123 +47,126 @@ import static org.junit.Assert.assertTrue;
*/
public class DefaultSocketConnectorTest {
- private static final int DELAY = 1000;
- private static final int SHORT_DELAY = 10;
- private static final int RETRY_DELAY = 10;
-
- private MockExceptionHandler exceptionHandler = new MockExceptionHandler();
-
- private ServerSocket serverSocket;
- private DefaultSocketConnector connector;
-
- ExecutorService executor = Executors.newSingleThreadExecutor();
-
- @Before
- public void setUp() throws Exception {
- serverSocket = ServerSocketUtil.createServerSocket();
- connector = new DefaultSocketConnector(serverSocket.getInetAddress(), serverSocket.getLocalPort(), 0, RETRY_DELAY);
- connector.setExceptionHandler(exceptionHandler);
+ private static final int DELAY = 1000;
+ private static final int SHORT_DELAY = 10;
+ private static final int RETRY_DELAY = 10;
+
+ private MockExceptionHandler exceptionHandler = new MockExceptionHandler();
+
+ private ServerSocket serverSocket;
+ private DefaultSocketConnector connector;
+
+ ExecutorService executor = Executors.newSingleThreadExecutor();
+
+ @Before
+ public void setUp() throws Exception {
+ serverSocket = ServerSocketUtil.createServerSocket();
+ connector = new DefaultSocketConnector(serverSocket.getInetAddress(),
+ serverSocket.getLocalPort(), 0, RETRY_DELAY);
+ connector.setExceptionHandler(exceptionHandler);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (serverSocket != null) {
+ serverSocket.close();
}
-
- @After
- public void tearDown() throws Exception {
- if (serverSocket != null) {
- serverSocket.close();
- }
+ }
+
+ @Test
+ public void testConnect() throws Exception {
+ Future<Socket> connectorTask = executor.submit(connector);
+
+ Socket socket = connectorTask.get(2 * DELAY, TimeUnit.MILLISECONDS);
+ assertNotNull(socket);
+ connectorTask.cancel(true);
+
+ assertTrue(connectorTask.isDone());
+ socket.close();
+ }
+
+ @Test
+ public void testConnectionFails() throws Exception {
+ serverSocket.close();
+ Future<Socket> connectorTask = executor.submit(connector);
+
+ // this connection attempt will always timeout
+ try {
+ connectorTask.get(SHORT_DELAY, TimeUnit.MILLISECONDS);
+ fail();
+ } catch(TimeoutException e) {
}
-
- @Test
- public void testConnect() throws Exception {
- Future<Socket> connectorTask = executor.submit(connector);
-
- Socket socket = connectorTask.get(2 * DELAY, TimeUnit.MILLISECONDS);
- assertNotNull(socket);
- connectorTask.cancel(true);
-
- assertTrue(connectorTask.isDone());
- socket.close();
+ Exception lastException = exceptionHandler.awaitConnectionFailed(DELAY);
+ assertTrue(lastException instanceof ConnectException);
+ assertFalse(connectorTask.isDone());
+ connectorTask.cancel(true);
+
+ //thread.join(4 * DELAY);
+ assertTrue(connectorTask.isCancelled());
+ }
+
+ @Test(timeout = 5000)
+ public void testConnectEventually() throws Exception {
+ serverSocket.close();
+
+ Future<Socket> connectorTask = executor.submit(connector);
+ // this connection attempt will always timeout
+ try {
+ connectorTask.get(SHORT_DELAY, TimeUnit.MILLISECONDS);
+ fail();
+ } catch(TimeoutException e) {
}
- @Test
- public void testConnectionFails() throws Exception {
- serverSocket.close();
- Future<Socket> connectorTask = executor.submit(connector);
- // this connection attempt will always timeout
- try {
- connectorTask.get(SHORT_DELAY, TimeUnit.MILLISECONDS);
- fail();
- } catch (TimeoutException e) {
- }
- Exception lastException = exceptionHandler.awaitConnectionFailed(DELAY);
- assertTrue(lastException instanceof ConnectException);
- assertFalse(connectorTask.isDone());
- connectorTask.cancel(true);
+ // on Ceki's machine (Windows 7) this always takes 1second regardless of the value of DELAY
+ Exception lastException = exceptionHandler.awaitConnectionFailed(DELAY);
+ assertNotNull(lastException);
+ assertTrue(lastException instanceof ConnectException);
- // thread.join(4 * DELAY);
- assertTrue(connectorTask.isCancelled());
- }
+ // now rebind to the same local address
+ SocketAddress address = serverSocket.getLocalSocketAddress();
+ serverSocket = new ServerSocket();
+ serverSocket.setReuseAddress(true);
+ serverSocket.bind(address);
- @Test(timeout = 5000)
- public void testConnectEventually() throws Exception {
- serverSocket.close();
+ // now we should be able to connect
+ Socket socket = connectorTask.get(2 * DELAY, TimeUnit.MILLISECONDS);
- Future<Socket> connectorTask = executor.submit(connector);
- // this connection attempt will always timeout
- try {
- connectorTask.get(SHORT_DELAY, TimeUnit.MILLISECONDS);
- fail();
- } catch (TimeoutException e) {
- }
-
- // on Ceki's machine (Windows 7) this always takes 1second regardless of the value of DELAY
- Exception lastException = exceptionHandler.awaitConnectionFailed(DELAY);
- assertNotNull(lastException);
- assertTrue(lastException instanceof ConnectException);
-
- // now rebind to the same local address
- SocketAddress address = serverSocket.getLocalSocketAddress();
- serverSocket = new ServerSocket();
- serverSocket.setReuseAddress(true);
- serverSocket.bind(address);
+ assertNotNull(socket);
- // now we should be able to connect
- Socket socket = connectorTask.get(2 * DELAY, TimeUnit.MILLISECONDS);
+ assertFalse(connectorTask.isCancelled());
+ socket.close();
+ }
+
+ private static class MockExceptionHandler implements ExceptionHandler {
- assertNotNull(socket);
-
- assertFalse(connectorTask.isCancelled());
- socket.close();
+ private final Lock lock = new ReentrantLock();
+ private final Condition failedCondition = lock.newCondition();
+
+ private Exception lastException;
+
+ public void connectionFailed(SocketConnector connector, Exception ex) {
+ lastException = ex;
}
+
+ public Exception awaitConnectionFailed(long delay)
+ throws InterruptedException {
+ lock.lock();
+ try {
+ long increment = 10;
+ while (lastException == null && delay > 0) {
+ boolean success = failedCondition.await(increment, TimeUnit.MILLISECONDS);
+ delay -= increment;
+ if(success) break;
- private static class MockExceptionHandler implements ExceptionHandler {
-
- private final Lock lock = new ReentrantLock();
- private final Condition failedCondition = lock.newCondition();
-
- private Exception lastException;
-
- public void connectionFailed(SocketConnector connector, Exception ex) {
- lastException = ex;
- }
-
- public Exception awaitConnectionFailed(long delay) throws InterruptedException {
- lock.lock();
- try {
- long increment = 10;
- while (lastException == null && delay > 0) {
- boolean success = failedCondition.await(increment, TimeUnit.MILLISECONDS);
- delay -= increment;
- if (success)
- break;
-
- }
- return lastException;
- } finally {
- lock.unlock();
- }
}
-
+ return lastException;
+ }
+ finally {
+ lock.unlock();
+ }
}
-
+
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/PackageTest.java
index f6317bd..f77ed33 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -11,13 +11,18 @@
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
+
package ch.qos.logback.core.net;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
+
@RunWith(Suite.class)
- at Suite.SuiteClasses({ AbstractSocketAppenderTest.class, DefaultSocketConnectorTest.class, AbstractSSLSocketAppenderTest.class,
- ch.qos.logback.core.net.server.PackageTest.class, ch.qos.logback.core.net.ssl.PackageTest.class })
+ at Suite.SuiteClasses({AbstractSocketAppenderTest.class,
+ DefaultSocketConnectorTest.class,
+ AbstractSSLSocketAppenderTest.class,
+ ch.qos.logback.core.net.server.PackageTest.class,
+ ch.qos.logback.core.net.ssl.PackageTest.class})
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/SyslogAppenderBaseTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/SyslogAppenderBaseTest.java
index 490da40..c612997 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/SyslogAppenderBaseTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/SyslogAppenderBaseTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2011, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,32 +17,34 @@ import org.junit.Test;
import static org.junit.Assert.assertEquals;
-public class SyslogAppenderBaseTest {
- @Test
- public void testFacilityStringToint() throws InterruptedException {
- assertEquals(SyslogConstants.LOG_KERN, SyslogAppenderBase.facilityStringToint("KERN"));
- assertEquals(SyslogConstants.LOG_USER, SyslogAppenderBase.facilityStringToint("USER"));
- assertEquals(SyslogConstants.LOG_MAIL, SyslogAppenderBase.facilityStringToint("MAIL"));
- assertEquals(SyslogConstants.LOG_DAEMON, SyslogAppenderBase.facilityStringToint("DAEMON"));
- assertEquals(SyslogConstants.LOG_AUTH, SyslogAppenderBase.facilityStringToint("AUTH"));
- assertEquals(SyslogConstants.LOG_SYSLOG, SyslogAppenderBase.facilityStringToint("SYSLOG"));
- assertEquals(SyslogConstants.LOG_LPR, SyslogAppenderBase.facilityStringToint("LPR"));
- assertEquals(SyslogConstants.LOG_NEWS, SyslogAppenderBase.facilityStringToint("NEWS"));
- assertEquals(SyslogConstants.LOG_UUCP, SyslogAppenderBase.facilityStringToint("UUCP"));
- assertEquals(SyslogConstants.LOG_CRON, SyslogAppenderBase.facilityStringToint("CRON"));
- assertEquals(SyslogConstants.LOG_AUTHPRIV, SyslogAppenderBase.facilityStringToint("AUTHPRIV"));
- assertEquals(SyslogConstants.LOG_FTP, SyslogAppenderBase.facilityStringToint("FTP"));
- assertEquals(SyslogConstants.LOG_NTP, SyslogAppenderBase.facilityStringToint("NTP"));
- assertEquals(SyslogConstants.LOG_AUDIT, SyslogAppenderBase.facilityStringToint("AUDIT"));
- assertEquals(SyslogConstants.LOG_ALERT, SyslogAppenderBase.facilityStringToint("ALERT"));
- assertEquals(SyslogConstants.LOG_CLOCK, SyslogAppenderBase.facilityStringToint("CLOCK"));
- assertEquals(SyslogConstants.LOG_LOCAL0, SyslogAppenderBase.facilityStringToint("LOCAL0"));
- assertEquals(SyslogConstants.LOG_LOCAL1, SyslogAppenderBase.facilityStringToint("LOCAL1"));
- assertEquals(SyslogConstants.LOG_LOCAL2, SyslogAppenderBase.facilityStringToint("LOCAL2"));
- assertEquals(SyslogConstants.LOG_LOCAL3, SyslogAppenderBase.facilityStringToint("LOCAL3"));
- assertEquals(SyslogConstants.LOG_LOCAL4, SyslogAppenderBase.facilityStringToint("LOCAL4"));
- assertEquals(SyslogConstants.LOG_LOCAL5, SyslogAppenderBase.facilityStringToint("LOCAL5"));
- assertEquals(SyslogConstants.LOG_LOCAL6, SyslogAppenderBase.facilityStringToint("LOCAL6"));
- assertEquals(SyslogConstants.LOG_LOCAL7, SyslogAppenderBase.facilityStringToint("LOCAL7"));
- }
+public class SyslogAppenderBaseTest
+{
+ @Test
+ public void testFacilityStringToint() throws InterruptedException
+ {
+ assertEquals(SyslogConstants.LOG_KERN, SyslogAppenderBase.facilityStringToint("KERN"));
+ assertEquals(SyslogConstants.LOG_USER, SyslogAppenderBase.facilityStringToint("USER"));
+ assertEquals(SyslogConstants.LOG_MAIL, SyslogAppenderBase.facilityStringToint("MAIL"));
+ assertEquals(SyslogConstants.LOG_DAEMON, SyslogAppenderBase.facilityStringToint("DAEMON"));
+ assertEquals(SyslogConstants.LOG_AUTH, SyslogAppenderBase.facilityStringToint("AUTH"));
+ assertEquals(SyslogConstants.LOG_SYSLOG, SyslogAppenderBase.facilityStringToint("SYSLOG"));
+ assertEquals(SyslogConstants.LOG_LPR, SyslogAppenderBase.facilityStringToint("LPR"));
+ assertEquals(SyslogConstants.LOG_NEWS, SyslogAppenderBase.facilityStringToint("NEWS"));
+ assertEquals(SyslogConstants.LOG_UUCP, SyslogAppenderBase.facilityStringToint("UUCP"));
+ assertEquals(SyslogConstants.LOG_CRON, SyslogAppenderBase.facilityStringToint("CRON"));
+ assertEquals(SyslogConstants.LOG_AUTHPRIV, SyslogAppenderBase.facilityStringToint("AUTHPRIV"));
+ assertEquals(SyslogConstants.LOG_FTP, SyslogAppenderBase.facilityStringToint("FTP"));
+ assertEquals(SyslogConstants.LOG_NTP, SyslogAppenderBase.facilityStringToint("NTP"));
+ assertEquals(SyslogConstants.LOG_AUDIT, SyslogAppenderBase.facilityStringToint("AUDIT"));
+ assertEquals(SyslogConstants.LOG_ALERT, SyslogAppenderBase.facilityStringToint("ALERT"));
+ assertEquals(SyslogConstants.LOG_CLOCK, SyslogAppenderBase.facilityStringToint("CLOCK"));
+ assertEquals(SyslogConstants.LOG_LOCAL0, SyslogAppenderBase.facilityStringToint("LOCAL0"));
+ assertEquals(SyslogConstants.LOG_LOCAL1, SyslogAppenderBase.facilityStringToint("LOCAL1"));
+ assertEquals(SyslogConstants.LOG_LOCAL2, SyslogAppenderBase.facilityStringToint("LOCAL2"));
+ assertEquals(SyslogConstants.LOG_LOCAL3, SyslogAppenderBase.facilityStringToint("LOCAL3"));
+ assertEquals(SyslogConstants.LOG_LOCAL4, SyslogAppenderBase.facilityStringToint("LOCAL4"));
+ assertEquals(SyslogConstants.LOG_LOCAL5, SyslogAppenderBase.facilityStringToint("LOCAL5"));
+ assertEquals(SyslogConstants.LOG_LOCAL6, SyslogAppenderBase.facilityStringToint("LOCAL6"));
+ assertEquals(SyslogConstants.LOG_LOCAL7, SyslogAppenderBase.facilityStringToint("LOCAL7"));
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/mock/MockContext.java b/logback-core/src/test/java/ch/qos/logback/core/net/mock/MockContext.java
index 0bbda62..83d5197 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/mock/MockContext.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/mock/MockContext.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,7 +14,7 @@
package ch.qos.logback.core.net.mock;
import java.util.List;
-import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ExecutorService;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
@@ -29,62 +29,62 @@ import ch.qos.logback.core.status.StatusManager;
*/
public class MockContext extends ContextBase {
- private final ScheduledExecutorService scheduledExecutorService;
-
- private Status lastStatus;
-
- public MockContext() {
- this(new MockScheduledExecutorService());
+ private final ExecutorService executorService;
+
+ private Status lastStatus;
+
+ public MockContext() {
+ this(new MockExecutorService());
+ }
+
+ public MockContext(ExecutorService executorService) {
+ this.setStatusManager(new MockStatusManager());
+ this.executorService = executorService;
+ }
+
+ @Override
+ public ExecutorService getExecutorService() {
+ return executorService;
+ }
+
+ public Status getLastStatus() {
+ return lastStatus;
+ }
+
+ public void setLastStatus(Status lastStatus) {
+ this.lastStatus = lastStatus;
+ }
+
+ private class MockStatusManager implements StatusManager {
+
+ public void add(Status status) {
+ lastStatus = status;
}
- public MockContext(ScheduledExecutorService executorService) {
- this.setStatusManager(new MockStatusManager());
- this.scheduledExecutorService = executorService;
+ public List<Status> getCopyOfStatusList() {
+ throw new UnsupportedOperationException();
}
- @Override
- public ScheduledExecutorService getScheduledExecutorService() {
- return scheduledExecutorService;
+ public int getCount() {
+ throw new UnsupportedOperationException();
}
- public Status getLastStatus() {
- return lastStatus;
+ public void add(StatusListener listener) {
+ throw new UnsupportedOperationException();
}
- public void setLastStatus(Status lastStatus) {
- this.lastStatus = lastStatus;
+ public void remove(StatusListener listener) {
+ throw new UnsupportedOperationException();
}
- private class MockStatusManager implements StatusManager {
-
- public void add(Status status) {
- lastStatus = status;
- }
-
- public List<Status> getCopyOfStatusList() {
- throw new UnsupportedOperationException();
- }
-
- public int getCount() {
- throw new UnsupportedOperationException();
- }
-
- public boolean add(StatusListener listener) {
- throw new UnsupportedOperationException();
- }
-
- public void remove(StatusListener listener) {
- throw new UnsupportedOperationException();
- }
-
- public void clear() {
- throw new UnsupportedOperationException();
- }
-
- public List<StatusListener> getCopyOfStatusListenerList() {
- throw new UnsupportedOperationException();
- }
-
+ public void clear() {
+ throw new UnsupportedOperationException();
}
+ public List<StatusListener> getCopyOfStatusListenerList() {
+ throw new UnsupportedOperationException();
+ }
+
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/mock/MockExecutorService.java b/logback-core/src/test/java/ch/qos/logback/core/net/mock/MockExecutorService.java
new file mode 100644
index 0000000..750fd83
--- /dev/null
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/mock/MockExecutorService.java
@@ -0,0 +1,61 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.core.net.mock;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * An {@link ExecutorService} with instrumentation for unit testing.
+ * <p>
+ * This service is synchronous; submitted jobs are run on the calling thread.
+ *
+ * @author Carl Harris
+ */
+public class MockExecutorService extends AbstractExecutorService {
+
+ private Runnable lastCommand;
+
+ public Runnable getLastCommand() {
+ return lastCommand;
+ }
+
+ public void shutdown() {
+ }
+
+ public List<Runnable> shutdownNow() {
+ return Collections.emptyList();
+ }
+
+ public boolean isShutdown() {
+ return true;
+ }
+
+ public boolean isTerminated() {
+ return true;
+ }
+
+ public boolean awaitTermination(long timeout, TimeUnit unit)
+ throws InterruptedException {
+ return true;
+ }
+
+ public void execute(Runnable command) {
+ command.run();
+ lastCommand = command;
+ }
+
+}
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/mock/MockScheduledExecutorService.java b/logback-core/src/test/java/ch/qos/logback/core/net/mock/MockScheduledExecutorService.java
deleted file mode 100644
index 29ef79b..0000000
--- a/logback-core/src/test/java/ch/qos/logback/core/net/mock/MockScheduledExecutorService.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.net.mock;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.AbstractExecutorService;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-
-/**
- * An {@link ExecutorService} with instrumentation for unit testing.
- * <p>
- * This service is synchronous; submitted jobs are run on the calling thread.
- *
- * @author Carl Harris
- */
-public class MockScheduledExecutorService extends AbstractExecutorService implements ScheduledExecutorService {
-
- private Runnable lastCommand;
-
- public Runnable getLastCommand() {
- return lastCommand;
- }
-
- public void shutdown() {
- }
-
- public List<Runnable> shutdownNow() {
- return Collections.emptyList();
- }
-
- public boolean isShutdown() {
- return true;
- }
-
- public boolean isTerminated() {
- return true;
- }
-
- public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
- return true;
- }
-
- public void execute(Runnable command) {
- command.run();
- lastCommand = command;
- }
-
- @Override
- public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
- throw new UnsupportedOperationException();
- }
-
-}
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/server/AbstractServerSocketAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/server/AbstractServerSocketAppenderTest.java
index 0c6a7ee..ccaef3d 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/server/AbstractServerSocketAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/server/AbstractServerSocketAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -37,64 +37,67 @@ import ch.qos.logback.core.status.Status;
*/
public class AbstractServerSocketAppenderTest {
- private MockContext context = new MockContext();
- private MockServerRunner<RemoteReceiverClient> runner = new MockServerRunner<RemoteReceiverClient>();
-
- private MockServerListener<RemoteReceiverClient> listener = new MockServerListener<RemoteReceiverClient>();
-
- private ServerSocket serverSocket;
- private InstrumentedServerSocketAppenderBase appender;
-
- @Before
- public void setUp() throws Exception {
- serverSocket = ServerSocketUtil.createServerSocket();
- appender = new InstrumentedServerSocketAppenderBase(serverSocket, listener, runner);
- appender.setContext(context);
- }
-
- @After
- public void tearDown() throws Exception {
- serverSocket.close();
- }
-
- @Test
- public void testStartStop() throws Exception {
- appender.start();
- assertTrue(runner.isContextInjected());
- assertTrue(runner.isRunning());
- assertSame(listener, appender.getLastListener());
-
- appender.stop();
- assertFalse(runner.isRunning());
- }
-
- @Test
- public void testStartWhenAlreadyStarted() throws Exception {
- appender.start();
- appender.start();
- assertEquals(1, runner.getStartCount());
- }
-
- @Test
- public void testStopThrowsException() throws Exception {
- appender.start();
- assertTrue(appender.isStarted());
- IOException ex = new IOException("test exception");
- runner.setStopException(ex);
- appender.stop();
-
- Status status = context.getLastStatus();
- assertNotNull(status);
- assertTrue(status instanceof ErrorStatus);
- assertTrue(status.getMessage().contains(ex.getMessage()));
- assertSame(ex, status.getThrowable());
- }
-
- @Test
- public void testStopWhenNotStarted() throws Exception {
- appender.stop();
- assertEquals(0, runner.getStartCount());
- }
+ private MockContext context = new MockContext();
+
+ private MockServerRunner<RemoteReceiverClient> runner =
+ new MockServerRunner<RemoteReceiverClient>();
+
+ private MockServerListener<RemoteReceiverClient> listener =
+ new MockServerListener<RemoteReceiverClient>();
+
+ private ServerSocket serverSocket;
+ private InstrumentedServerSocketAppenderBase appender;
+
+ @Before
+ public void setUp() throws Exception {
+ serverSocket = ServerSocketUtil.createServerSocket();
+ appender = new InstrumentedServerSocketAppenderBase(serverSocket, listener, runner);
+ appender.setContext(context);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ serverSocket.close();
+ }
+
+ @Test
+ public void testStartStop() throws Exception {
+ appender.start();
+ assertTrue(runner.isContextInjected());
+ assertTrue(runner.isRunning());
+ assertSame(listener, appender.getLastListener());
+
+ appender.stop();
+ assertFalse(runner.isRunning());
+ }
+
+ @Test
+ public void testStartWhenAlreadyStarted() throws Exception {
+ appender.start();
+ appender.start();
+ assertEquals(1, runner.getStartCount());
+ }
+
+ @Test
+ public void testStopThrowsException() throws Exception {
+ appender.start();
+ assertTrue(appender.isStarted());
+ IOException ex = new IOException("test exception");
+ runner.setStopException(ex);
+ appender.stop();
+
+ Status status = context.getLastStatus();
+ assertNotNull(status);
+ assertTrue(status instanceof ErrorStatus);
+ assertTrue(status.getMessage().contains(ex.getMessage()));
+ assertSame(ex, status.getThrowable());
+ }
+
+ @Test
+ public void testStopWhenNotStarted() throws Exception {
+ appender.stop();
+ assertEquals(0, runner.getStartCount());
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/server/ConcurrentServerRunnerTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/server/ConcurrentServerRunnerTest.java
index a4e174f..b29d896 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/server/ConcurrentServerRunnerTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/server/ConcurrentServerRunnerTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -32,133 +32,142 @@ import org.junit.Test;
import ch.qos.logback.core.net.mock.MockContext;
-public class ConcurrentServerRunnerTest {
-
- private static final int DELAY = 10000;
- private static final int SHORT_DELAY = 10;
-
- private MockContext context = new MockContext();
- private MockServerListener<MockClient> listener = new MockServerListener<MockClient>();
- private ExecutorService executor = Executors.newCachedThreadPool();
- private InstrumentedConcurrentServerRunner runner = new InstrumentedConcurrentServerRunner(listener, executor);
+public class ConcurrentServerRunnerTest {
- @Before
- public void setUp() throws Exception {
- runner.setContext(context);
+ private static final int DELAY = 10000;
+ private static final int SHORT_DELAY = 10;
+
+ private MockContext context = new MockContext();
+ private MockServerListener<MockClient> listener =
+ new MockServerListener<MockClient>();
+
+ private ExecutorService executor = Executors.newCachedThreadPool();
+ private InstrumentedConcurrentServerRunner runner =
+ new InstrumentedConcurrentServerRunner(listener, executor);
+
+ @Before
+ public void setUp() throws Exception {
+ runner.setContext(context);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ executor.shutdownNow();
+ assertTrue(executor.awaitTermination(DELAY, TimeUnit.MILLISECONDS));
+ }
+
+ @Test
+ public void testStartStop() throws Exception {
+ assertFalse(runner.isRunning());
+ executor.execute(runner);
+ assertTrue(runner.awaitRunState(true, DELAY));
+ int retries = DELAY / SHORT_DELAY;
+ synchronized (listener) {
+ while (retries-- > 0 && listener.getWaiter() == null) {
+ listener.wait(SHORT_DELAY);
+ }
}
-
- @After
- public void tearDown() throws Exception {
- executor.shutdownNow();
- assertTrue(executor.awaitTermination(DELAY, TimeUnit.MILLISECONDS));
+ assertNotNull(listener.getWaiter());
+ runner.stop();
+ assertTrue(listener.isClosed());
+ assertFalse(runner.awaitRunState(false, DELAY));
+ }
+
+ @Test
+ public void testRunOneClient() throws Exception {
+ executor.execute(runner);
+ MockClient client = new MockClient();
+ listener.addClient(client);
+ int retries = DELAY / SHORT_DELAY;
+ synchronized (client) {
+ while (retries-- > 0 && !client.isRunning()) {
+ client.wait(SHORT_DELAY);
+ }
}
-
- @Test
- public void testStartStop() throws Exception {
- assertFalse(runner.isRunning());
- executor.execute(runner);
- assertTrue(runner.awaitRunState(true, DELAY));
- int retries = DELAY / SHORT_DELAY;
- synchronized (listener) {
- while (retries-- > 0 && listener.getWaiter() == null) {
- listener.wait(SHORT_DELAY);
- }
+ assertTrue(runner.awaitRunState(true, DELAY));
+ client.close();
+ runner.stop();
+ }
+
+ @Test
+ public void testRunManyClients() throws Exception {
+ executor.execute(runner);
+ int count = 10;
+ while (count-- > 0) {
+ MockClient client = new MockClient();
+ listener.addClient(client);
+ int retries = DELAY / SHORT_DELAY;
+ synchronized (client) {
+ while (retries-- > 0 && !client.isRunning()) {
+ client.wait(SHORT_DELAY);
}
- assertNotNull(listener.getWaiter());
- runner.stop();
- assertTrue(listener.isClosed());
- assertFalse(runner.awaitRunState(false, DELAY));
+ }
+ assertTrue(runner.awaitRunState(true, DELAY));
}
-
- @Test
- public void testRunOneClient() throws Exception {
- executor.execute(runner);
- MockClient client = new MockClient();
- listener.addClient(client);
- int retries = DELAY / SHORT_DELAY;
- synchronized (client) {
- while (retries-- > 0 && !client.isRunning()) {
- client.wait(SHORT_DELAY);
- }
- }
- assertTrue(runner.awaitRunState(true, DELAY));
- client.close();
- runner.stop();
+ runner.stop();
+ }
+
+ @Test
+ public void testRunClientAndVisit() throws Exception {
+ executor.execute(runner);
+ MockClient client = new MockClient();
+ listener.addClient(client);
+ int retries = DELAY / SHORT_DELAY;
+ synchronized (client) {
+ while (retries-- > 0 && !client.isRunning()) {
+ client.wait(SHORT_DELAY);
+ }
}
-
- @Test
- public void testRunManyClients() throws Exception {
- executor.execute(runner);
- int count = 10;
- while (count-- > 0) {
- MockClient client = new MockClient();
- listener.addClient(client);
- int retries = DELAY / SHORT_DELAY;
- synchronized (client) {
- while (retries-- > 0 && !client.isRunning()) {
- client.wait(SHORT_DELAY);
- }
- }
- assertTrue(runner.awaitRunState(true, DELAY));
- }
- runner.stop();
+ assertTrue(runner.awaitRunState(true, DELAY));
+ MockClientVisitor visitor = new MockClientVisitor();
+ runner.accept(visitor);
+ assertSame(client, visitor.getLastVisited());
+ runner.stop();
+ }
+
+
+ static class InstrumentedConcurrentServerRunner
+ extends ConcurrentServerRunner<MockClient> {
+
+ private final Lock lock = new ReentrantLock();
+ private final Condition runningCondition = lock.newCondition();
+
+ public InstrumentedConcurrentServerRunner(
+ ServerListener<MockClient> listener, Executor executor) {
+ super(listener, executor);
}
- @Test
- public void testRunClientAndVisit() throws Exception {
- executor.execute(runner);
- MockClient client = new MockClient();
- listener.addClient(client);
- int retries = DELAY / SHORT_DELAY;
- synchronized (client) {
- while (retries-- > 0 && !client.isRunning()) {
- client.wait(SHORT_DELAY);
- }
- }
- assertTrue(runner.awaitRunState(true, DELAY));
- MockClientVisitor visitor = new MockClientVisitor();
- runner.accept(visitor);
- assertSame(client, visitor.getLastVisited());
- runner.stop();
+ @Override
+ protected boolean configureClient(MockClient client) {
+ return true;
}
- static class InstrumentedConcurrentServerRunner extends ConcurrentServerRunner<MockClient> {
-
- private final Lock lock = new ReentrantLock();
- private final Condition runningCondition = lock.newCondition();
-
- public InstrumentedConcurrentServerRunner(ServerListener<MockClient> listener, Executor executor) {
- super(listener, executor);
- }
-
- @Override
- protected boolean configureClient(MockClient client) {
- return true;
- }
-
- @Override
- protected void setRunning(boolean running) {
- lock.lock();
- try {
- super.setRunning(running);
- runningCondition.signalAll();
- } finally {
- lock.unlock();
- }
- }
+ @Override
+ protected void setRunning(boolean running) {
+ lock.lock();
+ try {
+ super.setRunning(running);
+ runningCondition.signalAll();
+ }
+ finally {
+ lock.unlock();
+ }
+ }
- public boolean awaitRunState(boolean state, long delay) throws InterruptedException {
- lock.lock();
- try {
- while (isRunning() != state) {
- runningCondition.await(delay, TimeUnit.MILLISECONDS);
- }
- return isRunning();
- } finally {
- lock.unlock();
- }
+ public boolean awaitRunState(boolean state,
+ long delay) throws InterruptedException {
+ lock.lock();
+ try {
+ while (isRunning() != state) {
+ runningCondition.await(delay, TimeUnit.MILLISECONDS);
}
+ return isRunning();
+ }
+ finally {
+ lock.unlock();
+ }
}
-
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/server/InstrumentedServerSocketAppenderBase.java b/logback-core/src/test/java/ch/qos/logback/core/net/server/InstrumentedServerSocketAppenderBase.java
index b631fb3..d439b4d 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/server/InstrumentedServerSocketAppenderBase.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/server/InstrumentedServerSocketAppenderBase.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,72 +28,78 @@ import ch.qos.logback.core.spi.PreSerializationTransformer;
*
* @author Carl Harris
*/
-public class InstrumentedServerSocketAppenderBase extends AbstractServerSocketAppender<Serializable> {
-
- private final ServerSocket serverSocket;
- private final ServerListener<RemoteReceiverClient> listener;
- private final ServerRunner<RemoteReceiverClient> runner;
-
- private ServerListener lastListener;
-
- public InstrumentedServerSocketAppenderBase(ServerSocket serverSocket) {
- this(serverSocket, new RemoteReceiverServerListener(serverSocket), null);
- }
-
- public InstrumentedServerSocketAppenderBase(ServerSocket serverSocket, ServerListener<RemoteReceiverClient> listener,
- ServerRunner<RemoteReceiverClient> runner) {
- this.serverSocket = serverSocket;
- this.listener = listener;
- this.runner = runner;
- }
-
- @Override
- protected void postProcessEvent(Serializable event) {
- }
-
- @Override
- protected PreSerializationTransformer<Serializable> getPST() {
- return new PreSerializationTransformer<Serializable>() {
- public Serializable transform(Serializable event) {
- return event;
- }
- };
- }
-
- @Override
- protected ServerSocketFactory getServerSocketFactory() throws Exception {
- return new ServerSocketFactory() {
-
- @Override
- public ServerSocket createServerSocket(int port) throws IOException {
- return serverSocket;
- }
-
- @Override
- public ServerSocket createServerSocket(int port, int backlog) throws IOException {
- return serverSocket;
- }
-
- @Override
- public ServerSocket createServerSocket(int port, int backlog, InetAddress ifAddress) throws IOException {
- return serverSocket;
- }
- };
- }
-
- @Override
- protected ServerRunner<RemoteReceiverClient> createServerRunner(ServerListener<RemoteReceiverClient> listener, Executor executor) {
- lastListener = listener;
- return runner != null ? runner : super.createServerRunner(listener, executor);
- }
-
- @Override
- protected ServerListener<RemoteReceiverClient> createServerListener(ServerSocket socket) {
- return listener;
- }
-
- public ServerListener getLastListener() {
- return lastListener;
- }
+public class InstrumentedServerSocketAppenderBase
+ extends AbstractServerSocketAppender<Serializable> {
+
+ private final ServerSocket serverSocket;
+ private final ServerListener<RemoteReceiverClient> listener;
+ private final ServerRunner<RemoteReceiverClient> runner;
+
+ private ServerListener lastListener;
+
+ public InstrumentedServerSocketAppenderBase(ServerSocket serverSocket) {
+ this(serverSocket, new RemoteReceiverServerListener(serverSocket), null);
+ }
+
+ public InstrumentedServerSocketAppenderBase(ServerSocket serverSocket,
+ ServerListener<RemoteReceiverClient> listener,
+ ServerRunner<RemoteReceiverClient> runner) {
+ this.serverSocket = serverSocket;
+ this.listener = listener;
+ this.runner = runner;
+ }
+
+ @Override
+ protected void postProcessEvent(Serializable event) {
+ }
+
+ @Override
+ protected PreSerializationTransformer<Serializable> getPST() {
+ return new PreSerializationTransformer<Serializable>() {
+ public Serializable transform(Serializable event) {
+ return event;
+ }
+ };
+ }
+
+ @Override
+ protected ServerSocketFactory getServerSocketFactory() throws Exception {
+ return new ServerSocketFactory() {
+
+ @Override
+ public ServerSocket createServerSocket(int port) throws IOException {
+ return serverSocket;
+ }
+
+ @Override
+ public ServerSocket createServerSocket(int port, int backlog)
+ throws IOException {
+ return serverSocket;
+ }
+
+ @Override
+ public ServerSocket createServerSocket(int port, int backlog,
+ InetAddress ifAddress) throws IOException {
+ return serverSocket;
+ }
+ };
+ }
+
+ @Override
+ protected ServerRunner<RemoteReceiverClient> createServerRunner(
+ ServerListener<RemoteReceiverClient> listener, Executor executor) {
+ lastListener = listener;
+ return runner != null ? runner : super.createServerRunner(listener, executor);
+ }
+
+ @Override
+ protected ServerListener<RemoteReceiverClient> createServerListener(
+ ServerSocket socket) {
+ return listener;
+ }
+
+ public ServerListener getLastListener() {
+ return lastListener;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/server/MockClient.java b/logback-core/src/test/java/ch/qos/logback/core/net/server/MockClient.java
index 2c2deda..b1b6aa6 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/server/MockClient.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/server/MockClient.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,6 +15,8 @@ package ch.qos.logback.core.net.server;
import ch.qos.logback.core.net.server.Client;
+
+
/**
*
* A mock {@link Client} that notifies waiting thread when it has started,
@@ -24,37 +26,38 @@ import ch.qos.logback.core.net.server.Client;
*/
class MockClient implements Client {
- private boolean running;
- private boolean closed;
-
- public void run() {
- synchronized (this) {
- running = true;
- notifyAll();
- while (running && !Thread.currentThread().isInterrupted()) {
- try {
- wait();
- } catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- }
- }
+ private boolean running;
+ private boolean closed;
+
+ public void run() {
+ synchronized (this) {
+ running = true;
+ notifyAll();
+ while (running && !Thread.currentThread().isInterrupted()) {
+ try {
+ wait();
}
- }
-
- public void close() {
- synchronized (this) {
- running = false;
- closed = true;
- notifyAll();
+ catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
}
+ }
}
+ }
- public synchronized boolean isRunning() {
- return running;
+ public void close() {
+ synchronized (this) {
+ running = false;
+ closed = true;
+ notifyAll();
}
+ }
- public synchronized boolean isClosed() {
- return closed;
- }
+ public synchronized boolean isRunning() {
+ return running;
+ }
+
+ public synchronized boolean isClosed() {
+ return closed;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/server/MockClientVisitor.java b/logback-core/src/test/java/ch/qos/logback/core/net/server/MockClientVisitor.java
index f63120e..842d6e1 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/server/MockClientVisitor.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/server/MockClientVisitor.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,17 +20,17 @@ package ch.qos.logback.core.net.server;
*/
public class MockClientVisitor implements ClientVisitor<MockClient> {
- private MockClient lastVisited;
+ private MockClient lastVisited;
+
+ /**
+ * {@inheritDoc}
+ */
+ public void visit(MockClient client) {
+ lastVisited = client;
+ }
- /**
- * {@inheritDoc}
- */
- public void visit(MockClient client) {
- lastVisited = client;
- }
-
- public MockClient getLastVisited() {
- return lastVisited;
- }
+ public MockClient getLastVisited() {
+ return lastVisited;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/server/MockEventQueue.java b/logback-core/src/test/java/ch/qos/logback/core/net/server/MockEventQueue.java
index 556627e..a1018c8 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/server/MockEventQueue.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/server/MockEventQueue.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,14 +23,14 @@ import java.util.concurrent.LinkedBlockingQueue;
*/
class MockEventQueue extends LinkedBlockingQueue<Serializable> {
- private static final long serialVersionUID = 1L;
-
- @Override
- public Serializable take() throws InterruptedException {
- if (isEmpty()) {
- Thread.currentThread().interrupt();
- }
- return super.take();
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public Serializable take() throws InterruptedException {
+ if (isEmpty()) {
+ Thread.currentThread().interrupt();
}
+ return super.take();
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/server/MockServerListener.java b/logback-core/src/test/java/ch/qos/logback/core/net/server/MockServerListener.java
index 20e12b4..da5c436 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/server/MockServerListener.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/server/MockServerListener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,6 +20,7 @@ import java.util.concurrent.LinkedBlockingQueue;
import ch.qos.logback.core.net.server.Client;
import ch.qos.logback.core.net.server.ServerListener;
+
/**
* A mock {@link ServerListener} that has a blocking queue to pass a client
* to a {@link #acceptClient()} caller. If the {@link #close()} method is
@@ -30,49 +31,51 @@ import ch.qos.logback.core.net.server.ServerListener;
*/
public class MockServerListener<T extends Client> implements ServerListener<T> {
- private final BlockingQueue<T> queue = new LinkedBlockingQueue<T>();
-
- private boolean closed;
- private Thread waiter;
-
- public synchronized Thread getWaiter() {
- return waiter;
- }
-
- public synchronized void setWaiter(Thread waiter) {
- this.waiter = waiter;
- }
+ private final BlockingQueue<T> queue =
+ new LinkedBlockingQueue<T>();
+
+ private boolean closed;
+ private Thread waiter;
+
+ public synchronized Thread getWaiter() {
+ return waiter;
+ }
+
+ public synchronized void setWaiter(Thread waiter) {
+ this.waiter = waiter;
+ }
+
+ public synchronized boolean isClosed() {
+ return closed;
+ }
- public synchronized boolean isClosed() {
- return closed;
- }
+ public synchronized void setClosed(boolean closed) {
+ this.closed = closed;
+ }
- public synchronized void setClosed(boolean closed) {
- this.closed = closed;
+ public T acceptClient() throws IOException, InterruptedException {
+ if (isClosed()) {
+ throw new IOException("closed");
}
-
- public T acceptClient() throws IOException, InterruptedException {
- if (isClosed()) {
- throw new IOException("closed");
- }
- setWaiter(Thread.currentThread());
- try {
- return queue.take();
- } finally {
- setWaiter(null);
- }
+ setWaiter(Thread.currentThread());
+ try {
+ return queue.take();
}
-
- public void addClient(T client) {
- queue.offer(client);
+ finally {
+ setWaiter(null);
}
+ }
- public synchronized void close() {
- setClosed(true);
- Thread waiter = getWaiter();
- if (waiter != null) {
- waiter.interrupt();
- }
- }
+ public void addClient(T client) {
+ queue.offer(client);
+ }
+
+ public synchronized void close() {
+ setClosed(true);
+ Thread waiter = getWaiter();
+ if (waiter != null) {
+ waiter.interrupt();
+ }
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/server/MockServerRunner.java b/logback-core/src/test/java/ch/qos/logback/core/net/server/MockServerRunner.java
index 465e346..c0d83c6 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/server/MockServerRunner.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/server/MockServerRunner.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,47 +23,48 @@ import ch.qos.logback.core.spi.ContextAwareBase;
*
* @author Carl Harris
*/
-public class MockServerRunner<T extends Client> extends ContextAwareBase implements ServerRunner<T> {
+public class MockServerRunner<T extends Client> extends ContextAwareBase
+ implements ServerRunner<T> {
- private IOException stopException;
- private int startCount;
- private boolean contextInjected;
+ private IOException stopException;
+ private int startCount;
+ private boolean contextInjected;
+
+ @Override
+ public void setContext(Context context) {
+ contextInjected = true;
+ super.setContext(context);
+ }
- @Override
- public void setContext(Context context) {
- contextInjected = true;
- super.setContext(context);
- }
-
- public void run() {
- startCount++;
- }
-
- public void stop() throws IOException {
- if (stopException != null) {
- throw stopException;
- }
- startCount--;
- }
+ public void run() {
+ startCount++;
+ }
- public boolean isRunning() {
- return startCount > 0;
+ public void stop() throws IOException {
+ if (stopException != null) {
+ throw stopException;
}
+ startCount--;
+ }
- public void accept(ClientVisitor visitor) {
- throw new UnsupportedOperationException();
- }
+ public boolean isRunning() {
+ return startCount > 0;
+ }
+
+ public void accept(ClientVisitor visitor) {
+ throw new UnsupportedOperationException();
+ }
- public int getStartCount() {
- return startCount;
- }
+ public int getStartCount() {
+ return startCount;
+ }
- public boolean isContextInjected() {
- return contextInjected;
- }
-
- public void setStopException(IOException stopException) {
- this.stopException = stopException;
- }
+ public boolean isContextInjected() {
+ return contextInjected;
+ }
+ public void setStopException(IOException stopException) {
+ this.stopException = stopException;
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/server/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/server/PackageTest.java
index 397279f..14a4786 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/server/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/server/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,8 +16,12 @@ package ch.qos.logback.core.net.server;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
+
@RunWith(Suite.class)
- at Suite.SuiteClasses({ ConcurrentServerRunnerTest.class, RemoteReceiverStreamClientTest.class, ServerSocketAppenderBaseFunctionalTest.class,
- AbstractServerSocketAppenderTest.class, SSLServerSocketAppenderBaseTest.class })
+ at Suite.SuiteClasses({ConcurrentServerRunnerTest.class,
+ RemoteReceiverStreamClientTest.class,
+ ServerSocketAppenderBaseFunctionalTest.class,
+ AbstractServerSocketAppenderTest.class,
+ SSLServerSocketAppenderBaseTest.class})
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/server/RemoteReceiverStreamClientTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/server/RemoteReceiverStreamClientTest.java
index 4d800de..cbea2de 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/server/RemoteReceiverStreamClientTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/server/RemoteReceiverStreamClientTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,6 +25,7 @@ import org.junit.Test;
import ch.qos.logback.core.net.mock.MockContext;
+
/**
* Unit tests for {@link RemoteReceiverStreamClient}.
*
@@ -32,52 +33,56 @@ import ch.qos.logback.core.net.mock.MockContext;
*/
public class RemoteReceiverStreamClientTest {
- private static final String TEST_EVENT = "test event";
-
- private MockContext context = new MockContext();
-
- private MockEventQueue queue = new MockEventQueue();
-
- private ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-
- private RemoteReceiverStreamClient client = new RemoteReceiverStreamClient("someId", outputStream);
-
- @Before
- public void setUp() throws Exception {
- client.setContext(context);
- client.setQueue(queue);
+ private static final String TEST_EVENT = "test event";
+
+ private MockContext context = new MockContext();
+
+ private MockEventQueue queue = new MockEventQueue();
+
+ private ByteArrayOutputStream outputStream =
+ new ByteArrayOutputStream();
+
+ private RemoteReceiverStreamClient client =
+ new RemoteReceiverStreamClient("someId", outputStream);
+
+ @Before
+ public void setUp() throws Exception {
+ client.setContext(context);
+ client.setQueue(queue);
+ }
+
+ @Test
+ public void testOfferEventAndRun() throws Exception {
+ client.offer(TEST_EVENT);
+
+ Thread thread = new Thread(client);
+ thread.start();
+
+ // MockEventQueue will interrupt the thread when the queue is drained
+ thread.join(1000);
+ assertFalse(thread.isAlive());
+
+ ObjectInputStream ois = new ObjectInputStream(
+ new ByteArrayInputStream(outputStream.toByteArray()));
+ assertEquals(TEST_EVENT, ois.readObject());
+ }
+
+ @Test
+ public void testOfferEventSequenceAndRun() throws Exception {
+ for (int i = 0; i < 10; i++) {
+ client.offer(TEST_EVENT + i);
}
- @Test
- public void testOfferEventAndRun() throws Exception {
- client.offer(TEST_EVENT);
-
- Thread thread = new Thread(client);
- thread.start();
-
- // MockEventQueue will interrupt the thread when the queue is drained
- thread.join(1000);
- assertFalse(thread.isAlive());
-
- ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(outputStream.toByteArray()));
- assertEquals(TEST_EVENT, ois.readObject());
- }
-
- @Test
- public void testOfferEventSequenceAndRun() throws Exception {
- for (int i = 0; i < 10; i++) {
- client.offer(TEST_EVENT + i);
- }
-
- Thread thread = new Thread(client);
- thread.start();
- thread.join(1000);
- assertFalse(thread.isAlive());
-
- ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(outputStream.toByteArray()));
- for (int i = 0; i < 10; i++) {
- assertEquals(TEST_EVENT + i, ois.readObject());
- }
+ Thread thread = new Thread(client);
+ thread.start();
+ thread.join(1000);
+ assertFalse(thread.isAlive());
+
+ ObjectInputStream ois = new ObjectInputStream(
+ new ByteArrayInputStream(outputStream.toByteArray()));
+ for (int i = 0; i < 10; i++) {
+ assertEquals(TEST_EVENT + i, ois.readObject());
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/server/SSLServerSocketAppenderBaseTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/server/SSLServerSocketAppenderBaseTest.java
index 0d93841..e537788 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/server/SSLServerSocketAppenderBaseTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/server/SSLServerSocketAppenderBaseTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,12 +15,13 @@ package ch.qos.logback.core.net.server;
import static org.junit.Assert.assertNotNull;
+import java.util.concurrent.Executors;
+
import org.junit.Before;
import org.junit.Test;
import ch.qos.logback.core.net.mock.MockContext;
import ch.qos.logback.core.spi.PreSerializationTransformer;
-import ch.qos.logback.core.util.ExecutorServiceUtil;
/**
* Unit tests for {@link SSLServerSocketAppenderBase}.
@@ -29,35 +30,37 @@ import ch.qos.logback.core.util.ExecutorServiceUtil;
*/
public class SSLServerSocketAppenderBaseTest {
- private MockContext context = new MockContext(ExecutorServiceUtil.newScheduledExecutorService());
+ private MockContext context = new MockContext(Executors.newCachedThreadPool());
+
+ private SSLServerSocketAppenderBase appender =
+ new InstrumentedSSLServerSocketAppenderBase();
+
+ @Before
+ public void setUp() throws Exception {
+ appender.setContext(context);
+ }
+
+ @Test
+ public void testUsingDefaultConfig() throws Exception {
+ // should be able to start successfully with no SSL configuration at all
+ appender.start();
+ assertNotNull(appender.getServerSocketFactory());
+ appender.stop();
+ }
- private SSLServerSocketAppenderBase appender = new InstrumentedSSLServerSocketAppenderBase();
+ private static class InstrumentedSSLServerSocketAppenderBase
+ extends SSLServerSocketAppenderBase<Object> {
- @Before
- public void setUp() throws Exception {
- appender.setContext(context);
+ @Override
+ protected void postProcessEvent(Object event) {
+ throw new UnsupportedOperationException();
}
- @Test
- public void testUsingDefaultConfig() throws Exception {
- // should be able to start successfully with no SSL configuration at all
- appender.start();
- assertNotNull(appender.getServerSocketFactory());
- appender.stop();
+ @Override
+ protected PreSerializationTransformer<Object> getPST() {
+ throw new UnsupportedOperationException();
}
-
- private static class InstrumentedSSLServerSocketAppenderBase extends SSLServerSocketAppenderBase<Object> {
-
- @Override
- protected void postProcessEvent(Object event) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected PreSerializationTransformer<Object> getPST() {
- throw new UnsupportedOperationException();
- }
-
- }
-
+
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/server/ServerSocketAppenderBaseFunctionalTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/server/ServerSocketAppenderBaseFunctionalTest.java
index bca082d..bc64830 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/server/ServerSocketAppenderBaseFunctionalTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/server/ServerSocketAppenderBaseFunctionalTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,7 +20,8 @@ import java.io.ObjectInputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
-import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.junit.After;
@@ -28,7 +29,6 @@ import org.junit.Before;
import org.junit.Test;
import ch.qos.logback.core.net.mock.MockContext;
-import ch.qos.logback.core.util.ExecutorServiceUtil;
/**
* A functional test for {@link AbstractServerSocketAppender}.
@@ -37,46 +37,47 @@ import ch.qos.logback.core.util.ExecutorServiceUtil;
*/
public class ServerSocketAppenderBaseFunctionalTest {
- private static final String TEST_EVENT = "test event";
-
- private static final int EVENT_COUNT = 10;
-
- private ScheduledExecutorService executor = ExecutorServiceUtil.newScheduledExecutorService();
- private MockContext context = new MockContext(executor);
- private ServerSocket serverSocket;
- private InstrumentedServerSocketAppenderBase appender;
-
- @Before
- public void setUp() throws Exception {
-
- serverSocket = ServerSocketUtil.createServerSocket();
-
- appender = new InstrumentedServerSocketAppenderBase(serverSocket);
- appender.setContext(context);
- }
-
- @After
- public void tearDown() throws Exception {
- executor.shutdownNow();
- executor.awaitTermination(10000, TimeUnit.MILLISECONDS);
- assertTrue(executor.isTerminated());
- }
-
- @Test
- public void testLogEventClient() throws Exception {
- appender.start();
- Socket socket = new Socket(InetAddress.getLocalHost(), serverSocket.getLocalPort());
-
- socket.setSoTimeout(1000);
- ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
-
- for (int i = 0; i < EVENT_COUNT; i++) {
- appender.append(TEST_EVENT + i);
- assertEquals(TEST_EVENT + i, ois.readObject());
- }
-
- socket.close();
- appender.stop();
+ private static final String TEST_EVENT = "test event";
+
+ private static final int EVENT_COUNT = 10;
+
+ private ExecutorService executor = Executors.newCachedThreadPool();
+ private MockContext context = new MockContext(executor);
+ private ServerSocket serverSocket;
+ private InstrumentedServerSocketAppenderBase appender;
+
+ @Before
+ public void setUp() throws Exception {
+
+ serverSocket = ServerSocketUtil.createServerSocket();
+
+ appender = new InstrumentedServerSocketAppenderBase(serverSocket);
+ appender.setContext(context);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ executor.shutdownNow();
+ executor.awaitTermination(10000, TimeUnit.MILLISECONDS);
+ assertTrue(executor.isTerminated());
+ }
+
+ @Test
+ public void testLogEventClient() throws Exception {
+ appender.start();
+ Socket socket = new Socket(InetAddress.getLocalHost(),
+ serverSocket.getLocalPort());
+
+ socket.setSoTimeout(1000);
+ ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
+
+ for (int i = 0; i < EVENT_COUNT; i++) {
+ appender.append(TEST_EVENT + i);
+ assertEquals(TEST_EVENT + i, ois.readObject());
}
+
+ socket.close();
+ appender.stop();
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/server/ServerSocketListenerTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/server/ServerSocketListenerTest.java
index 86a8caf..8f46ce7 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/server/ServerSocketListenerTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/server/ServerSocketListenerTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,6 +27,7 @@ import org.junit.Test;
import ch.qos.logback.core.net.server.Client;
import ch.qos.logback.core.net.server.ServerSocketListener;
+
/**
* Unit tests for {@link ServerSocketListener}.
*
@@ -34,115 +35,121 @@ import ch.qos.logback.core.net.server.ServerSocketListener;
*/
public class ServerSocketListenerTest {
- private ServerSocket serverSocket;
- private ServerSocketListener listener;
-
- @Before
- public void setUp() throws Exception {
- serverSocket = ServerSocketUtil.createServerSocket();
- assertNotNull(serverSocket);
- listener = new InstrumentedServerSocketListener(serverSocket);
+ private ServerSocket serverSocket;
+ private ServerSocketListener listener;
+
+ @Before
+ public void setUp() throws Exception {
+ serverSocket = ServerSocketUtil.createServerSocket();
+ assertNotNull(serverSocket);
+ listener = new InstrumentedServerSocketListener(serverSocket);
+ }
+
+ @Test
+ public void testAcceptClient() throws Exception {
+ RunnableClient localClient = new RunnableClient(
+ InetAddress.getLocalHost(), serverSocket.getLocalPort());
+ Thread thread = new Thread(localClient);
+ thread.start();
+ synchronized (localClient) {
+ int retries = 200;
+ while (retries-- > 0 && !localClient.isConnected()) {
+ localClient.wait(10);
+ }
}
-
- @Test
- public void testAcceptClient() throws Exception {
- RunnableClient localClient = new RunnableClient(InetAddress.getLocalHost(), serverSocket.getLocalPort());
- Thread thread = new Thread(localClient);
- thread.start();
- synchronized (localClient) {
- int retries = 200;
- while (retries-- > 0 && !localClient.isConnected()) {
- localClient.wait(10);
- }
- }
- assertTrue(localClient.isConnected());
- localClient.close();
-
- serverSocket.setSoTimeout(5000);
- Client client = listener.acceptClient();
- assertNotNull(client);
- client.close();
+ assertTrue(localClient.isConnected());
+ localClient.close();
+
+ serverSocket.setSoTimeout(5000);
+ Client client = listener.acceptClient();
+ assertNotNull(client);
+ client.close();
+ }
+
+ private static class InstrumentedServerSocketListener
+ extends ServerSocketListener<RemoteClient> {
+
+ public InstrumentedServerSocketListener(ServerSocket serverSocket) {
+ super(serverSocket);
}
- private static class InstrumentedServerSocketListener extends ServerSocketListener<RemoteClient> {
-
- public InstrumentedServerSocketListener(ServerSocket serverSocket) {
- super(serverSocket);
- }
-
- @Override
- protected RemoteClient createClient(String id, Socket socket) throws IOException {
- return new RemoteClient(socket);
- }
-
+ @Override
+ protected RemoteClient createClient(String id, Socket socket)
+ throws IOException {
+ return new RemoteClient(socket);
}
-
- private static class RemoteClient implements Client {
-
- private final Socket socket;
-
- public RemoteClient(Socket socket) {
- this.socket = socket;
- }
-
- public void run() {
- }
-
- public void close() {
- try {
- socket.close();
- } catch (IOException ex) {
- ex.printStackTrace(System.err);
- }
- }
-
+
+ }
+
+ private static class RemoteClient implements Client {
+
+ private final Socket socket;
+
+ public RemoteClient(Socket socket) {
+ this.socket = socket;
}
- private static class RunnableClient implements Client {
-
- private final InetAddress inetAddress;
- private final int port;
- private boolean connected;
- private boolean closed;
-
- public RunnableClient(InetAddress inetAddress, int port) {
- super();
- this.inetAddress = inetAddress;
- this.port = port;
- }
+ public void run() {
+ }
+
+ public void close() {
+ try {
+ socket.close();
+ }
+ catch (IOException ex) {
+ ex.printStackTrace(System.err);
+ }
+ }
+
+ }
+
+ private static class RunnableClient implements Client {
+
+ private final InetAddress inetAddress;
+ private final int port;
+ private boolean connected;
+ private boolean closed;
+
+ public RunnableClient(InetAddress inetAddress, int port) {
+ super();
+ this.inetAddress = inetAddress;
+ this.port = port;
+ }
- public synchronized boolean isConnected() {
- return connected;
- }
+ public synchronized boolean isConnected() {
+ return connected;
+ }
- public synchronized void setConnected(boolean connected) {
- this.connected = connected;
- }
+ public synchronized void setConnected(boolean connected) {
+ this.connected = connected;
+ }
- public void run() {
+ public void run() {
+ try {
+ Socket socket = new Socket(inetAddress, port);
+ synchronized (this) {
+ setConnected(true);
+ notifyAll();
+ while (!closed && !Thread.currentThread().isInterrupted()) {
try {
- Socket socket = new Socket(inetAddress, port);
- synchronized (this) {
- setConnected(true);
- notifyAll();
- while (!closed && !Thread.currentThread().isInterrupted()) {
- try {
- wait();
- } catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- }
- }
- socket.close();
- }
- } catch (IOException ex) {
- ex.printStackTrace(System.err);
+ wait();
}
+ catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ socket.close();
}
+ }
+ catch (IOException ex) {
+ ex.printStackTrace(System.err);
+ }
+ }
- public synchronized void close() {
- closed = true;
- notifyAll();
- }
-
+ public synchronized void close() {
+ closed = true;
+ notifyAll();
}
+
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/server/ServerSocketUtil.java b/logback-core/src/test/java/ch/qos/logback/core/net/server/ServerSocketUtil.java
index 5e07e7d..d403748 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/server/ServerSocketUtil.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/server/ServerSocketUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,41 +27,43 @@ import javax.net.ServerSocketFactory;
*/
public class ServerSocketUtil {
- /**
- * Creates a new {@link ServerSocket} bound to a random unused port.
- * <p>
- * This method is a convenience overload for
- * {@link #createServerSocket(ServerSocketFactory)} using the platform's
- * default {@link ServerSocketFactory}.
- * @return socket
- * @throws IOException
- */
- public static ServerSocket createServerSocket() throws IOException {
- return createServerSocket(ServerSocketFactory.getDefault());
+ /**
+ * Creates a new {@link ServerSocket} bound to a random unused port.
+ * <p>
+ * This method is a convenience overload for
+ * {@link #createServerSocket(ServerSocketFactory)} using the platform's
+ * default {@link ServerSocketFactory}.
+ * @return socket
+ * @throws IOException
+ */
+ public static ServerSocket createServerSocket() throws IOException {
+ return createServerSocket(ServerSocketFactory.getDefault());
+ }
+
+ /**
+ * Creates a new {@link ServerSocket} bound to a random unused port.
+ * @param socketFactory socket factory that will be used to create the
+ * socket
+ * @return socket
+ * @throws IOException
+ */
+ public static ServerSocket createServerSocket(
+ ServerSocketFactory socketFactory) throws IOException {
+ ServerSocket socket = null;
+ int retries = 10;
+ while (retries-- > 0 && socket == null) {
+ int port = (int)((65536 - 1024) * Math.random()) + 1024;
+ try {
+ socket = socketFactory.createServerSocket(port);
+ }
+ catch (BindException ex) {
+ // try again with different port
+ }
}
-
- /**
- * Creates a new {@link ServerSocket} bound to a random unused port.
- * @param socketFactory socket factory that will be used to create the
- * socket
- * @return socket
- * @throws IOException
- */
- public static ServerSocket createServerSocket(ServerSocketFactory socketFactory) throws IOException {
- ServerSocket socket = null;
- int retries = 10;
- while (retries-- > 0 && socket == null) {
- int port = (int) ((65536 - 1024) * Math.random()) + 1024;
- try {
- socket = socketFactory.createServerSocket(port);
- } catch (BindException ex) {
- // try again with different port
- }
- }
- if (socket == null) {
- throw new BindException("cannot find an unused port to bind");
- }
- return socket;
+ if (socket == null) {
+ throw new BindException("cannot find an unused port to bind");
}
-
+ return socket;
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/KeyManagerFactoryFactoryBeanTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/KeyManagerFactoryFactoryBeanTest.java
index 02a68e3..0b53cd3 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/KeyManagerFactoryFactoryBeanTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/KeyManagerFactoryFactoryBeanTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,6 +21,7 @@ import org.junit.Test;
import ch.qos.logback.core.net.ssl.KeyManagerFactoryFactoryBean;
+
/**
* Unit tests for {@link KeyManagerFactoryFactoryBean}.
*
@@ -28,24 +29,26 @@ import ch.qos.logback.core.net.ssl.KeyManagerFactoryFactoryBean;
*/
public class KeyManagerFactoryFactoryBeanTest {
- private KeyManagerFactoryFactoryBean factoryBean = new KeyManagerFactoryFactoryBean();
-
- @Test
- public void testDefaults() throws Exception {
- assertNotNull(factoryBean.createKeyManagerFactory());
- }
-
- @Test
- public void testExplicitAlgorithm() throws Exception {
- factoryBean.setAlgorithm(KeyManagerFactory.getDefaultAlgorithm());
- assertNotNull(factoryBean.createKeyManagerFactory());
- }
-
- @Test
- public void testExplicitProvider() throws Exception {
- KeyManagerFactory factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
- factoryBean.setProvider(factory.getProvider().getName());
- assertNotNull(factoryBean.createKeyManagerFactory());
- }
-
+ private KeyManagerFactoryFactoryBean factoryBean =
+ new KeyManagerFactoryFactoryBean();
+
+ @Test
+ public void testDefaults() throws Exception {
+ assertNotNull(factoryBean.createKeyManagerFactory());
+ }
+
+ @Test
+ public void testExplicitAlgorithm() throws Exception {
+ factoryBean.setAlgorithm(KeyManagerFactory.getDefaultAlgorithm());
+ assertNotNull(factoryBean.createKeyManagerFactory());
+ }
+
+ @Test
+ public void testExplicitProvider() throws Exception {
+ KeyManagerFactory factory = KeyManagerFactory.getInstance(
+ KeyManagerFactory.getDefaultAlgorithm());
+ factoryBean.setProvider(factory.getProvider().getName());
+ assertNotNull(factoryBean.createKeyManagerFactory());
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/KeyStoreFactoryBeanTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/KeyStoreFactoryBeanTest.java
index 87cb2b1..f0eea80 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/KeyStoreFactoryBeanTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/KeyStoreFactoryBeanTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,6 +22,7 @@ import org.junit.Test;
import ch.qos.logback.core.net.ssl.KeyStoreFactoryBean;
import ch.qos.logback.core.net.ssl.SSL;
+
/**
* Unit tests for {@link KeyStoreFactoryBean}.
*
@@ -29,41 +30,41 @@ import ch.qos.logback.core.net.ssl.SSL;
*/
public class KeyStoreFactoryBeanTest {
- private KeyStoreFactoryBean factoryBean = new KeyStoreFactoryBean();
-
- @Test
- public void testDefaults() throws Exception {
- factoryBean.setLocation(SSLTestConstants.KEYSTORE_JKS_RESOURCE);
- assertNotNull(factoryBean.createKeyStore());
- }
-
- @Test
- public void testExplicitProvider() throws Exception {
- factoryBean.setLocation(SSLTestConstants.KEYSTORE_JKS_RESOURCE);
- KeyStore keyStore = factoryBean.createKeyStore();
- factoryBean.setProvider(keyStore.getProvider().getName());
- assertNotNull(factoryBean.createKeyStore());
- }
+ private KeyStoreFactoryBean factoryBean = new KeyStoreFactoryBean();
+
+ @Test
+ public void testDefaults() throws Exception {
+ factoryBean.setLocation(SSLTestConstants.KEYSTORE_JKS_RESOURCE);
+ assertNotNull(factoryBean.createKeyStore());
+ }
- @Test
- public void testExplicitType() throws Exception {
- factoryBean.setLocation(SSLTestConstants.KEYSTORE_JKS_RESOURCE);
- factoryBean.setType(SSL.DEFAULT_KEYSTORE_TYPE);
- assertNotNull(factoryBean.createKeyStore());
- }
+ @Test
+ public void testExplicitProvider() throws Exception {
+ factoryBean.setLocation(SSLTestConstants.KEYSTORE_JKS_RESOURCE);
+ KeyStore keyStore = factoryBean.createKeyStore();
+ factoryBean.setProvider(keyStore.getProvider().getName());
+ assertNotNull(factoryBean.createKeyStore());
+ }
+
+ @Test
+ public void testExplicitType() throws Exception {
+ factoryBean.setLocation(SSLTestConstants.KEYSTORE_JKS_RESOURCE);
+ factoryBean.setType(SSL.DEFAULT_KEYSTORE_TYPE);
+ assertNotNull(factoryBean.createKeyStore());
+ }
- @Test
- public void testPKCS12Type() throws Exception {
- factoryBean.setLocation(SSLTestConstants.KEYSTORE_PKCS12_RESOURCE);
- factoryBean.setType(SSLTestConstants.PKCS12_TYPE);
- assertNotNull(factoryBean.createKeyStore());
- }
+ @Test
+ public void testPKCS12Type() throws Exception {
+ factoryBean.setLocation(SSLTestConstants.KEYSTORE_PKCS12_RESOURCE);
+ factoryBean.setType(SSLTestConstants.PKCS12_TYPE);
+ assertNotNull(factoryBean.createKeyStore());
+ }
- @Test
- public void testExplicitPassphrase() throws Exception {
- factoryBean.setLocation(SSLTestConstants.KEYSTORE_JKS_RESOURCE);
- factoryBean.setPassword(SSL.DEFAULT_KEYSTORE_PASSWORD);
- assertNotNull(factoryBean.createKeyStore());
- }
+ @Test
+ public void testExplicitPassphrase() throws Exception {
+ factoryBean.setLocation(SSLTestConstants.KEYSTORE_JKS_RESOURCE);
+ factoryBean.setPassword(SSL.DEFAULT_KEYSTORE_PASSWORD);
+ assertNotNull(factoryBean.createKeyStore());
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/PackageTest.java
index 4f83637..82b866a 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -12,14 +12,21 @@
* as published by the Free Software Foundation.
*/
+
package ch.qos.logback.core.net.ssl;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
+
@RunWith(Suite.class)
- at Suite.SuiteClasses({ KeyManagerFactoryFactoryBeanTest.class, KeyStoreFactoryBeanTest.class, SecureRandomFactoryBeanTest.class, SSLConfigurationTest.class,
- SSLContextFactoryBeanTest.class, SSLParametersConfigurationTest.class, TrustManagerFactoryFactoryBeanTest.class })
+ at Suite.SuiteClasses({KeyManagerFactoryFactoryBeanTest.class,
+ KeyStoreFactoryBeanTest.class,
+ SecureRandomFactoryBeanTest.class,
+ SSLConfigurationTest.class,
+ SSLContextFactoryBeanTest.class,
+ SSLParametersConfigurationTest.class,
+ TrustManagerFactoryFactoryBeanTest.class})
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLConfigurationTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLConfigurationTest.java
index 829373e..db3c4b9 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLConfigurationTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLConfigurationTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,11 +24,11 @@ import org.junit.Test;
*/
public class SSLConfigurationTest {
- private SSLConfiguration configuration = new SSLConfiguration();
-
- @Test
- public void testParameters() throws Exception {
- assertNotNull(configuration.getParameters());
- }
-
+ private SSLConfiguration configuration = new SSLConfiguration();
+
+ @Test
+ public void testParameters() throws Exception {
+ assertNotNull(configuration.getParameters());
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLContextFactoryBeanTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLContextFactoryBeanTest.java
index 445f3da..97d9bdc 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLContextFactoryBeanTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLContextFactoryBeanTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -32,71 +32,82 @@ import ch.qos.logback.core.net.ssl.mock.MockTrustManagerFactoryFactoryBean;
*/
public class SSLContextFactoryBeanTest {
- private static final String SSL_CONFIGURATION_MESSAGE_PATTERN = "SSL protocol '.*?' provider '.*?'";
-
- private static final String KEY_MANAGER_FACTORY_MESSAGE_PATTERN = "key manager algorithm '.*?' provider '.*?'";
-
- private static final String TRUST_MANAGER_FACTORY_MESSAGE_PATTERN = "trust manager algorithm '.*?' provider '.*?'";
-
- private static final String KEY_STORE_MESSAGE_PATTERN = "key store of type '.*?' provider '.*?': .*";
-
- private static final String TRUST_STORE_MESSAGE_PATTERN = "trust store of type '.*?' provider '.*?': .*";
-
- private static final String SECURE_RANDOM_MESSAGE_PATTERN = "secure random algorithm '.*?' provider '.*?'";
-
- private MockKeyManagerFactoryFactoryBean keyManagerFactory = new MockKeyManagerFactoryFactoryBean();
-
- private MockTrustManagerFactoryFactoryBean trustManagerFactory = new MockTrustManagerFactoryFactoryBean();
-
- private MockKeyStoreFactoryBean keyStore = new MockKeyStoreFactoryBean();
-
- private MockKeyStoreFactoryBean trustStore = new MockKeyStoreFactoryBean();
-
- private MockSecureRandomFactoryBean secureRandom = new MockSecureRandomFactoryBean();
-
- private MockContextAware context = new MockContextAware();
- private SSLContextFactoryBean factoryBean = new SSLContextFactoryBean();
-
- @Before
- public void setUp() throws Exception {
- keyStore.setLocation(SSLTestConstants.KEYSTORE_JKS_RESOURCE);
- trustStore.setLocation(SSLTestConstants.KEYSTORE_JKS_RESOURCE);
- }
-
- @Test
- public void testCreateDefaultContext() throws Exception {
- // should be able to create a context with no configuration at all
- assertNotNull(factoryBean.createContext(context));
- assertTrue(context.hasInfoMatching(SSL_CONFIGURATION_MESSAGE_PATTERN));
- }
-
- @Test
- public void testCreateContext() throws Exception {
- factoryBean.setKeyManagerFactory(keyManagerFactory);
- factoryBean.setKeyStore(keyStore);
- factoryBean.setTrustManagerFactory(trustManagerFactory);
- factoryBean.setTrustStore(trustStore);
- factoryBean.setSecureRandom(secureRandom);
-
- assertNotNull(factoryBean.createContext(context));
-
- assertTrue(keyManagerFactory.isFactoryCreated());
- assertTrue(trustManagerFactory.isFactoryCreated());
- assertTrue(keyStore.isKeyStoreCreated());
- assertTrue(trustStore.isKeyStoreCreated());
- assertTrue(secureRandom.isSecureRandomCreated());
-
- // it's important that each configured component output an appropriate
- // informational message to the context; i.e. this logging is not just
- // for programmers, it's there for systems administrators to use in
- // verifying that SSL is configured properly
-
- assertTrue(context.hasInfoMatching(SSL_CONFIGURATION_MESSAGE_PATTERN));
- assertTrue(context.hasInfoMatching(KEY_MANAGER_FACTORY_MESSAGE_PATTERN));
- assertTrue(context.hasInfoMatching(TRUST_MANAGER_FACTORY_MESSAGE_PATTERN));
- assertTrue(context.hasInfoMatching(KEY_STORE_MESSAGE_PATTERN));
- assertTrue(context.hasInfoMatching(TRUST_STORE_MESSAGE_PATTERN));
- assertTrue(context.hasInfoMatching(SECURE_RANDOM_MESSAGE_PATTERN));
- }
-
+ private static final String SSL_CONFIGURATION_MESSAGE_PATTERN =
+ "SSL protocol '.*?' provider '.*?'";
+
+ private static final String KEY_MANAGER_FACTORY_MESSAGE_PATTERN =
+ "key manager algorithm '.*?' provider '.*?'";
+
+ private static final String TRUST_MANAGER_FACTORY_MESSAGE_PATTERN =
+ "trust manager algorithm '.*?' provider '.*?'";
+
+ private static final String KEY_STORE_MESSAGE_PATTERN =
+ "key store of type '.*?' provider '.*?': .*";
+
+ private static final String TRUST_STORE_MESSAGE_PATTERN =
+ "trust store of type '.*?' provider '.*?': .*";
+
+ private static final String SECURE_RANDOM_MESSAGE_PATTERN =
+ "secure random algorithm '.*?' provider '.*?'";
+
+ private MockKeyManagerFactoryFactoryBean keyManagerFactory =
+ new MockKeyManagerFactoryFactoryBean();
+
+ private MockTrustManagerFactoryFactoryBean trustManagerFactory =
+ new MockTrustManagerFactoryFactoryBean();
+
+ private MockKeyStoreFactoryBean keyStore =
+ new MockKeyStoreFactoryBean();
+
+ private MockKeyStoreFactoryBean trustStore =
+ new MockKeyStoreFactoryBean();
+
+ private MockSecureRandomFactoryBean secureRandom =
+ new MockSecureRandomFactoryBean();
+
+ private MockContextAware context = new MockContextAware();
+ private SSLContextFactoryBean factoryBean = new SSLContextFactoryBean();
+
+ @Before
+ public void setUp() throws Exception {
+ keyStore.setLocation(SSLTestConstants.KEYSTORE_JKS_RESOURCE);
+ trustStore.setLocation(SSLTestConstants.KEYSTORE_JKS_RESOURCE);
+ }
+
+ @Test
+ public void testCreateDefaultContext() throws Exception {
+ // should be able to create a context with no configuration at all
+ assertNotNull(factoryBean.createContext(context));
+ assertTrue(context.hasInfoMatching(SSL_CONFIGURATION_MESSAGE_PATTERN));
+ }
+
+ @Test
+ public void testCreateContext() throws Exception {
+ factoryBean.setKeyManagerFactory(keyManagerFactory);
+ factoryBean.setKeyStore(keyStore);
+ factoryBean.setTrustManagerFactory(trustManagerFactory);
+ factoryBean.setTrustStore(trustStore);
+ factoryBean.setSecureRandom(secureRandom);
+
+ assertNotNull(factoryBean.createContext(context));
+
+ assertTrue(keyManagerFactory.isFactoryCreated());
+ assertTrue(trustManagerFactory.isFactoryCreated());
+ assertTrue(keyStore.isKeyStoreCreated());
+ assertTrue(trustStore.isKeyStoreCreated());
+ assertTrue(secureRandom.isSecureRandomCreated());
+
+ // it's important that each configured component output an appropriate
+ // informational message to the context; i.e. this logging is not just
+ // for programmers, it's there for systems administrators to use in
+ // verifying that SSL is configured properly
+
+ assertTrue(context.hasInfoMatching(SSL_CONFIGURATION_MESSAGE_PATTERN));
+ assertTrue(context.hasInfoMatching(KEY_MANAGER_FACTORY_MESSAGE_PATTERN));
+ assertTrue(context.hasInfoMatching(TRUST_MANAGER_FACTORY_MESSAGE_PATTERN));
+ assertTrue(context.hasInfoMatching(KEY_STORE_MESSAGE_PATTERN));
+ assertTrue(context.hasInfoMatching(TRUST_STORE_MESSAGE_PATTERN));
+ assertTrue(context.hasInfoMatching(SECURE_RANDOM_MESSAGE_PATTERN));
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLParametersConfigurationTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLParametersConfigurationTest.java
index ffaf113..55738b3 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLParametersConfigurationTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLParametersConfigurationTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,6 +23,7 @@ import org.junit.Test;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.net.ssl.mock.MockSSLConfigurable;
+
/**
* Unit tests for {@link SSLParametersConfiguration}.
*
@@ -30,107 +31,115 @@ import ch.qos.logback.core.net.ssl.mock.MockSSLConfigurable;
*/
public class SSLParametersConfigurationTest {
- private MockSSLConfigurable configurable = new MockSSLConfigurable();
-
- private SSLParametersConfiguration configuration = new SSLParametersConfiguration();
-
- @Before
- public void setUp() throws Exception {
- configuration.setContext(new ContextBase());
- }
-
- @Test
- public void testSetIncludedProtocols() throws Exception {
- configurable.setSupportedProtocols(new String[] { "A", "B", "C", "D" });
- configuration.setIncludedProtocols("A,B ,C, D");
- configuration.configure(configurable);
- assertTrue(Arrays.equals(new String[] { "A", "B", "C", "D" }, configurable.getEnabledProtocols()));
- }
-
- @Test
- public void testSetExcludedProtocols() throws Exception {
- configurable.setSupportedProtocols(new String[] { "A", "B" });
- configuration.setExcludedProtocols("A");
- configuration.configure(configurable);
- assertTrue(Arrays.equals(new String[] { "B" }, configurable.getEnabledProtocols()));
- }
-
- @Test
- public void testSetIncludedAndExcludedProtocols() throws Exception {
- configurable.setSupportedProtocols(new String[] { "A", "B", "C" });
- configuration.setIncludedProtocols("A, B");
- configuration.setExcludedProtocols("B");
- configuration.configure(configurable);
- assertTrue(Arrays.equals(new String[] { "A" }, configurable.getEnabledProtocols()));
- }
-
- @Test
- public void testSetIncludedCipherSuites() throws Exception {
- configurable.setSupportedCipherSuites(new String[] { "A", "B", "C", "D" });
- configuration.setIncludedCipherSuites("A,B ,C, D");
- configuration.configure(configurable);
- assertTrue(Arrays.equals(new String[] { "A", "B", "C", "D" }, configurable.getEnabledCipherSuites()));
- }
-
- @Test
- public void testSetExcludedCipherSuites() throws Exception {
- configurable.setSupportedCipherSuites(new String[] { "A", "B" });
- configuration.setExcludedCipherSuites("A");
- configuration.configure(configurable);
- assertTrue(Arrays.equals(new String[] { "B" }, configurable.getEnabledCipherSuites()));
- }
-
- @Test
- public void testSetExcludedAndIncludedCipherSuites() throws Exception {
- configurable.setSupportedCipherSuites(new String[] { "A", "B", "C" });
- configuration.setIncludedCipherSuites("A, B");
- configuration.setExcludedCipherSuites("B");
- configuration.configure(configurable);
- assertTrue(Arrays.equals(new String[] { "A" }, configurable.getEnabledCipherSuites()));
- }
-
- @Test
- public void testSetNeedClientAuth() throws Exception {
- configuration.setNeedClientAuth(true);
- configuration.configure(configurable);
- assertTrue(configurable.isNeedClientAuth());
- }
-
- @Test
- public void testSetWantClientAuth() throws Exception {
- configuration.setWantClientAuth(true);
- configuration.configure(configurable);
- assertTrue(configurable.isWantClientAuth());
- }
-
- @Test
- public void testPassDefaultProtocols() throws Exception {
- final String[] protocols = new String[] { "A" };
- configurable.setDefaultProtocols(protocols);
- configuration.configure(configurable);
- assertTrue(Arrays.equals(protocols, configurable.getEnabledProtocols()));
- }
-
- @Test
- public void testPassDefaultCipherSuites() throws Exception {
- final String[] cipherSuites = new String[] { "A" };
- configurable.setDefaultCipherSuites(cipherSuites);
- configuration.configure(configurable);
- assertTrue(Arrays.equals(cipherSuites, configurable.getEnabledCipherSuites()));
- }
-
- @Test
- public void testPassDefaultNeedClientAuth() throws Exception {
- configurable.setNeedClientAuth(true);
- configuration.configure(configurable);
- assertTrue(configurable.isNeedClientAuth());
- }
-
- @Test
- public void testPassDefaultWantClientAuth() throws Exception {
- configurable.setWantClientAuth(true);
- configuration.configure(configurable);
- assertTrue(configurable.isWantClientAuth());
- }
+ private MockSSLConfigurable configurable = new MockSSLConfigurable();
+
+ private SSLParametersConfiguration configuration =
+ new SSLParametersConfiguration();
+
+ @Before
+ public void setUp() throws Exception {
+ configuration.setContext(new ContextBase());
+ }
+
+ @Test
+ public void testSetIncludedProtocols() throws Exception {
+ configurable.setSupportedProtocols(new String[] { "A", "B", "C", "D" });
+ configuration.setIncludedProtocols("A,B ,C, D");
+ configuration.configure(configurable);
+ assertTrue(Arrays.equals(new String[] { "A", "B", "C", "D" },
+ configurable.getEnabledProtocols()));
+ }
+
+ @Test
+ public void testSetExcludedProtocols() throws Exception {
+ configurable.setSupportedProtocols(new String[] { "A", "B" });
+ configuration.setExcludedProtocols("A");
+ configuration.configure(configurable);
+ assertTrue(Arrays.equals(new String[] { "B" },
+ configurable.getEnabledProtocols()));
+ }
+
+ @Test
+ public void testSetIncludedAndExcludedProtocols() throws Exception {
+ configurable.setSupportedProtocols(new String[] { "A", "B", "C" });
+ configuration.setIncludedProtocols("A, B");
+ configuration.setExcludedProtocols("B");
+ configuration.configure(configurable);
+ assertTrue(Arrays.equals(new String[] { "A" },
+ configurable.getEnabledProtocols()));
+ }
+
+ @Test
+ public void testSetIncludedCipherSuites() throws Exception {
+ configurable.setSupportedCipherSuites(new String[] { "A", "B", "C", "D" });
+ configuration.setIncludedCipherSuites("A,B ,C, D");
+ configuration.configure(configurable);
+ assertTrue(Arrays.equals(new String[] { "A", "B", "C", "D" },
+ configurable.getEnabledCipherSuites()));
+ }
+
+ @Test
+ public void testSetExcludedCipherSuites() throws Exception {
+ configurable.setSupportedCipherSuites(new String[] { "A", "B" });
+ configuration.setExcludedCipherSuites("A");
+ configuration.configure(configurable);
+ assertTrue(Arrays.equals(new String[]{ "B" },
+ configurable.getEnabledCipherSuites()));
+ }
+
+ @Test
+ public void testSetExcludedAndIncludedCipherSuites() throws Exception {
+ configurable.setSupportedCipherSuites(new String[] { "A", "B", "C" });
+ configuration.setIncludedCipherSuites("A, B");
+ configuration.setExcludedCipherSuites("B");
+ configuration.configure(configurable);
+ assertTrue(Arrays.equals(new String[] { "A" },
+ configurable.getEnabledCipherSuites()));
+ }
+
+ @Test
+ public void testSetNeedClientAuth() throws Exception {
+ configuration.setNeedClientAuth(true);
+ configuration.configure(configurable);
+ assertTrue(configurable.isNeedClientAuth());
+ }
+
+ @Test
+ public void testSetWantClientAuth() throws Exception {
+ configuration.setWantClientAuth(true);
+ configuration.configure(configurable);
+ assertTrue(configurable.isWantClientAuth());
+ }
+
+ @Test
+ public void testPassDefaultProtocols() throws Exception {
+ final String[] protocols = new String[] { "A" };
+ configurable.setDefaultProtocols(protocols);
+ configuration.configure(configurable);
+ assertTrue(Arrays.equals(protocols, configurable.getEnabledProtocols()));
+ }
+
+ @Test
+ public void testPassDefaultCipherSuites() throws Exception {
+ final String[] cipherSuites = new String[] { "A" };
+ configurable.setDefaultCipherSuites(cipherSuites);
+ configuration.configure(configurable);
+ assertTrue(Arrays.equals(cipherSuites,
+ configurable.getEnabledCipherSuites()));
+ }
+
+ @Test
+ public void testPassDefaultNeedClientAuth() throws Exception {
+ configurable.setNeedClientAuth(true);
+ configuration.configure(configurable);
+ assertTrue(configurable.isNeedClientAuth());
+ }
+
+ @Test
+ public void testPassDefaultWantClientAuth() throws Exception {
+ configurable.setWantClientAuth(true);
+ configuration.configure(configurable);
+ assertTrue(configurable.isWantClientAuth());
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLTestConstants.java b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLTestConstants.java
index fdbc2d0..903de6f 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLTestConstants.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SSLTestConstants.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,14 +20,14 @@ package ch.qos.logback.core.net.ssl;
*/
public interface SSLTestConstants {
- String KEYSTORE_JKS_RESOURCE = "net/ssl/keystore.jks";
+ String KEYSTORE_JKS_RESOURCE = "net/ssl/keystore.jks";
+
+ String KEYSTORE_PKCS12_RESOURCE = "net/ssl/keystore.p12";
- String KEYSTORE_PKCS12_RESOURCE = "net/ssl/keystore.p12";
+ String PKCS12_TYPE = "PKCS12";
- String PKCS12_TYPE = "PKCS12";
+ String FAKE_ALGORITHM_NAME = "A_FAKE_ALGORITHM_NAME";
- String FAKE_ALGORITHM_NAME = "A_FAKE_ALGORITHM_NAME";
-
- String FAKE_PROVIDER_NAME = "A_FAKE_PROVIDER_NAME";
+ String FAKE_PROVIDER_NAME = "A_FAKE_PROVIDER_NAME";
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SecureRandomFactoryBeanTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SecureRandomFactoryBeanTest.java
index 41ce22e..25acd0b 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SecureRandomFactoryBeanTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/SecureRandomFactoryBeanTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,6 +26,7 @@ import org.junit.Test;
import ch.qos.logback.core.net.ssl.SSL;
import ch.qos.logback.core.net.ssl.SecureRandomFactoryBean;
+
/**
* Unit tests for {@link SecureRandomFactoryBean}.
*
@@ -33,40 +34,43 @@ import ch.qos.logback.core.net.ssl.SecureRandomFactoryBean;
*/
public class SecureRandomFactoryBeanTest {
- private SecureRandomFactoryBean factoryBean = new SecureRandomFactoryBean();
+ private SecureRandomFactoryBean factoryBean = new SecureRandomFactoryBean();
+
+ @Test
+ public void testDefaults() throws Exception {
+ assertNotNull(factoryBean.createSecureRandom());
+ }
- @Test
- public void testDefaults() throws Exception {
- assertNotNull(factoryBean.createSecureRandom());
- }
+ @Test
+ public void testExplicitProvider() throws Exception {
+ SecureRandom secureRandom = SecureRandom.getInstance(
+ SSL.DEFAULT_SECURE_RANDOM_ALGORITHM);
+ factoryBean.setProvider(secureRandom.getProvider().getName());
+ assertNotNull(factoryBean.createSecureRandom());
+ }
- @Test
- public void testExplicitProvider() throws Exception {
- SecureRandom secureRandom = SecureRandom.getInstance(SSL.DEFAULT_SECURE_RANDOM_ALGORITHM);
- factoryBean.setProvider(secureRandom.getProvider().getName());
- assertNotNull(factoryBean.createSecureRandom());
+ @Test
+ public void testUnknownProvider() throws Exception {
+ factoryBean.setProvider(SSLTestConstants.FAKE_PROVIDER_NAME);
+ try {
+ factoryBean.createSecureRandom();
+ fail("expected NoSuchProviderException");
}
-
- @Test
- public void testUnknownProvider() throws Exception {
- factoryBean.setProvider(SSLTestConstants.FAKE_PROVIDER_NAME);
- try {
- factoryBean.createSecureRandom();
- fail("expected NoSuchProviderException");
- } catch (NoSuchProviderException ex) {
- assertTrue(ex.getMessage().contains(SSLTestConstants.FAKE_PROVIDER_NAME));
- }
+ catch (NoSuchProviderException ex) {
+ assertTrue(ex.getMessage().contains(SSLTestConstants.FAKE_PROVIDER_NAME));
}
+ }
- @Test
- public void testUnknownAlgorithm() throws Exception {
- factoryBean.setAlgorithm(SSLTestConstants.FAKE_ALGORITHM_NAME);
- try {
- factoryBean.createSecureRandom();
- fail("expected NoSuchAlgorithmException");
- } catch (NoSuchAlgorithmException ex) {
- assertTrue(ex.getMessage().contains(SSLTestConstants.FAKE_ALGORITHM_NAME));
- }
+ @Test
+ public void testUnknownAlgorithm() throws Exception {
+ factoryBean.setAlgorithm(SSLTestConstants.FAKE_ALGORITHM_NAME);
+ try {
+ factoryBean.createSecureRandom();
+ fail("expected NoSuchAlgorithmException");
+ }
+ catch (NoSuchAlgorithmException ex) {
+ assertTrue(ex.getMessage().contains(SSLTestConstants.FAKE_ALGORITHM_NAME));
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/TrustManagerFactoryFactoryBeanTest.java b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/TrustManagerFactoryFactoryBeanTest.java
index e49a377..694ecb5 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/TrustManagerFactoryFactoryBeanTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/TrustManagerFactoryFactoryBeanTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,6 +21,7 @@ import org.junit.Test;
import ch.qos.logback.core.net.ssl.TrustManagerFactoryFactoryBean;
+
/**
* Unit tests for {@link TrustManagerFactoryFactoryBean}.
*
@@ -28,24 +29,26 @@ import ch.qos.logback.core.net.ssl.TrustManagerFactoryFactoryBean;
*/
public class TrustManagerFactoryFactoryBeanTest {
- private TrustManagerFactoryFactoryBean factoryBean = new TrustManagerFactoryFactoryBean();
-
- @Test
- public void testDefaults() throws Exception {
- assertNotNull(factoryBean.createTrustManagerFactory());
- }
-
- @Test
- public void testExplicitAlgorithm() throws Exception {
- factoryBean.setAlgorithm(TrustManagerFactory.getDefaultAlgorithm());
- assertNotNull(factoryBean.createTrustManagerFactory());
- }
-
- @Test
- public void testExplicitProvider() throws Exception {
- TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
- factoryBean.setProvider(factory.getProvider().getName());
- assertNotNull(factoryBean.createTrustManagerFactory());
- }
-
+ private TrustManagerFactoryFactoryBean factoryBean =
+ new TrustManagerFactoryFactoryBean();
+
+ @Test
+ public void testDefaults() throws Exception {
+ assertNotNull(factoryBean.createTrustManagerFactory());
+ }
+
+ @Test
+ public void testExplicitAlgorithm() throws Exception {
+ factoryBean.setAlgorithm(TrustManagerFactory.getDefaultAlgorithm());
+ assertNotNull(factoryBean.createTrustManagerFactory());
+ }
+
+ @Test
+ public void testExplicitProvider() throws Exception {
+ TrustManagerFactory factory = TrustManagerFactory.getInstance(
+ TrustManagerFactory.getDefaultAlgorithm());
+ factoryBean.setProvider(factory.getProvider().getName());
+ assertNotNull(factoryBean.createTrustManagerFactory());
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockContextAware.java b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockContextAware.java
index d5fc8d8..c46113e 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockContextAware.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockContextAware.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,45 +24,45 @@ import ch.qos.logback.core.spi.ContextAwareBase;
*
* @author Carl Harris
*/
-public class MockContextAware extends ContextAwareBase implements ContextAware {
+public class MockContextAware extends ContextAwareBase
+ implements ContextAware {
- private final List<String> info = new LinkedList<String>();
- private final List<String> warn = new LinkedList<String>();
- private final List<String> error = new LinkedList<String>();
+ private final List<String> info = new LinkedList<String>();
+ private final List<String> warn = new LinkedList<String>();
+ private final List<String> error = new LinkedList<String>();
+
+ @Override
+ public void addInfo(String msg) {
+ info.add(msg);
+ }
- @Override
- public void addInfo(String msg) {
- info.add(msg);
- }
-
- @Override
- public void addWarn(String msg) {
- warn.add(msg);
- }
+ @Override
+ public void addWarn(String msg) {
+ warn.add(msg);
+ }
- @Override
- public void addError(String msg) {
- error.add(msg);
- }
-
- public boolean hasInfoMatching(String regex) {
- return hasMatching(info, regex);
- }
+ @Override
+ public void addError(String msg) {
+ error.add(msg);
+ }
- public boolean hasWarnMatching(String regex) {
- return hasMatching(info, regex);
+ public boolean hasInfoMatching(String regex) {
+ return hasMatching(info, regex);
+ }
+
+ public boolean hasWarnMatching(String regex) {
+ return hasMatching(info, regex);
+ }
+
+ public boolean hasErrorMatching(String regex) {
+ return hasMatching(info, regex);
+ }
+
+ private boolean hasMatching(List<String> messages, String regex) {
+ for (String message : messages) {
+ if (message.matches(regex)) return true;
}
-
- public boolean hasErrorMatching(String regex) {
- return hasMatching(info, regex);
- }
-
- private boolean hasMatching(List<String> messages, String regex) {
- for (String message : messages) {
- if (message.matches(regex))
- return true;
- }
- return false;
- }
-
+ return false;
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockKeyManagerFactoryFactoryBean.java b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockKeyManagerFactoryFactoryBean.java
index 2afa935..50979d9 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockKeyManagerFactoryFactoryBean.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockKeyManagerFactoryFactoryBean.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,18 +25,20 @@ import ch.qos.logback.core.net.ssl.KeyManagerFactoryFactoryBean;
*
* @author Carl Harris
*/
-public class MockKeyManagerFactoryFactoryBean extends KeyManagerFactoryFactoryBean {
-
- private boolean factoryCreated;
-
- @Override
- public KeyManagerFactory createKeyManagerFactory() throws NoSuchProviderException, NoSuchAlgorithmException {
- factoryCreated = true;
- return super.createKeyManagerFactory();
- }
-
- public boolean isFactoryCreated() {
- return factoryCreated;
- }
-
+public class MockKeyManagerFactoryFactoryBean
+ extends KeyManagerFactoryFactoryBean {
+
+ private boolean factoryCreated;
+
+ @Override
+ public KeyManagerFactory createKeyManagerFactory()
+ throws NoSuchProviderException, NoSuchAlgorithmException {
+ factoryCreated = true;
+ return super.createKeyManagerFactory();
+ }
+
+ public boolean isFactoryCreated() {
+ return factoryCreated;
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockKeyStoreFactoryBean.java b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockKeyStoreFactoryBean.java
index 4f206c3..e097411 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockKeyStoreFactoryBean.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockKeyStoreFactoryBean.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,16 +27,17 @@ import ch.qos.logback.core.net.ssl.KeyStoreFactoryBean;
*/
public class MockKeyStoreFactoryBean extends KeyStoreFactoryBean {
- private boolean keyStoreCreated;
+ private boolean keyStoreCreated;
+
+ @Override
+ public KeyStore createKeyStore() throws NoSuchProviderException,
+ NoSuchAlgorithmException, KeyStoreException {
+ keyStoreCreated = true;
+ return super.createKeyStore();
+ }
- @Override
- public KeyStore createKeyStore() throws NoSuchProviderException, NoSuchAlgorithmException, KeyStoreException {
- keyStoreCreated = true;
- return super.createKeyStore();
- }
-
- public boolean isKeyStoreCreated() {
- return keyStoreCreated;
- }
+ public boolean isKeyStoreCreated() {
+ return keyStoreCreated;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockSSLConfigurable.java b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockSSLConfigurable.java
index 09c9a4c..fea4210 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockSSLConfigurable.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockSSLConfigurable.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,79 +17,79 @@ import ch.qos.logback.core.net.ssl.SSLConfigurable;
public class MockSSLConfigurable implements SSLConfigurable {
- private static final String[] EMPTY = new String[0];
-
- private String[] defaultProtocols = EMPTY;
- private String[] supportedProtocols = EMPTY;
- private String[] enabledProtocols = EMPTY;
- private String[] defaultCipherSuites = EMPTY;
- private String[] supportedCipherSuites = EMPTY;
- private String[] enabledCipherSuites = EMPTY;
- private boolean needClientAuth;
- private boolean wantClientAuth;
-
- public String[] getDefaultProtocols() {
- return defaultProtocols;
- }
-
- public void setDefaultProtocols(String[] defaultProtocols) {
- this.defaultProtocols = defaultProtocols;
- }
-
- public String[] getSupportedProtocols() {
- return supportedProtocols;
- }
-
- public void setSupportedProtocols(String[] supportedProtocols) {
- this.supportedProtocols = supportedProtocols;
- }
-
- public String[] getEnabledProtocols() {
- return enabledProtocols;
- }
-
- public void setEnabledProtocols(String[] enabledProtocols) {
- this.enabledProtocols = enabledProtocols;
- }
-
- public String[] getDefaultCipherSuites() {
- return defaultCipherSuites;
- }
-
- public void setDefaultCipherSuites(String[] defaultCipherSuites) {
- this.defaultCipherSuites = defaultCipherSuites;
- }
-
- public String[] getSupportedCipherSuites() {
- return supportedCipherSuites;
- }
-
- public void setSupportedCipherSuites(String[] supportedCipherSuites) {
- this.supportedCipherSuites = supportedCipherSuites;
- }
-
- public String[] getEnabledCipherSuites() {
- return enabledCipherSuites;
- }
-
- public void setEnabledCipherSuites(String[] enabledCipherSuites) {
- this.enabledCipherSuites = enabledCipherSuites;
- }
-
- public boolean isNeedClientAuth() {
- return needClientAuth;
- }
-
- public void setNeedClientAuth(boolean needClientAuth) {
- this.needClientAuth = needClientAuth;
- }
-
- public boolean isWantClientAuth() {
- return wantClientAuth;
- }
-
- public void setWantClientAuth(boolean wantClientAuth) {
- this.wantClientAuth = wantClientAuth;
- }
+ private static final String[] EMPTY = new String[0];
+
+ private String[] defaultProtocols = EMPTY;
+ private String[] supportedProtocols = EMPTY;
+ private String[] enabledProtocols = EMPTY;
+ private String[] defaultCipherSuites = EMPTY;
+ private String[] supportedCipherSuites = EMPTY;
+ private String[] enabledCipherSuites = EMPTY;
+ private boolean needClientAuth;
+ private boolean wantClientAuth;
+
+ public String[] getDefaultProtocols() {
+ return defaultProtocols;
+ }
+
+ public void setDefaultProtocols(String[] defaultProtocols) {
+ this.defaultProtocols = defaultProtocols;
+ }
+
+ public String[] getSupportedProtocols() {
+ return supportedProtocols;
+ }
+
+ public void setSupportedProtocols(String[] supportedProtocols) {
+ this.supportedProtocols = supportedProtocols;
+ }
+
+ public String[] getEnabledProtocols() {
+ return enabledProtocols;
+ }
+
+ public void setEnabledProtocols(String[] enabledProtocols) {
+ this.enabledProtocols = enabledProtocols;
+ }
+
+ public String[] getDefaultCipherSuites() {
+ return defaultCipherSuites;
+ }
+
+ public void setDefaultCipherSuites(String[] defaultCipherSuites) {
+ this.defaultCipherSuites = defaultCipherSuites;
+ }
+
+ public String[] getSupportedCipherSuites() {
+ return supportedCipherSuites;
+ }
+
+ public void setSupportedCipherSuites(String[] supportedCipherSuites) {
+ this.supportedCipherSuites = supportedCipherSuites;
+ }
+
+ public String[] getEnabledCipherSuites() {
+ return enabledCipherSuites;
+ }
+
+ public void setEnabledCipherSuites(String[] enabledCipherSuites) {
+ this.enabledCipherSuites = enabledCipherSuites;
+ }
+
+ public boolean isNeedClientAuth() {
+ return needClientAuth;
+ }
+
+ public void setNeedClientAuth(boolean needClientAuth) {
+ this.needClientAuth = needClientAuth;
+ }
+
+ public boolean isWantClientAuth() {
+ return wantClientAuth;
+ }
+
+ public void setWantClientAuth(boolean wantClientAuth) {
+ this.wantClientAuth = wantClientAuth;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockSecureRandomFactoryBean.java b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockSecureRandomFactoryBean.java
index 9be89e0..1d30140 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockSecureRandomFactoryBean.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockSecureRandomFactoryBean.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,16 +26,17 @@ import ch.qos.logback.core.net.ssl.SecureRandomFactoryBean;
*/
public class MockSecureRandomFactoryBean extends SecureRandomFactoryBean {
- private boolean secureRandomCreated;
+ private boolean secureRandomCreated;
- @Override
- public SecureRandom createSecureRandom() throws NoSuchProviderException, NoSuchAlgorithmException {
- secureRandomCreated = true;
- return super.createSecureRandom();
- }
-
- public boolean isSecureRandomCreated() {
- return secureRandomCreated;
- }
+ @Override
+ public SecureRandom createSecureRandom() throws NoSuchProviderException,
+ NoSuchAlgorithmException {
+ secureRandomCreated = true;
+ return super.createSecureRandom();
+ }
+ public boolean isSecureRandomCreated() {
+ return secureRandomCreated;
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockTrustManagerFactoryFactoryBean.java b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockTrustManagerFactoryFactoryBean.java
index c704ebf..15a6934 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockTrustManagerFactoryFactoryBean.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/net/ssl/mock/MockTrustManagerFactoryFactoryBean.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,18 +25,21 @@ import ch.qos.logback.core.net.ssl.TrustManagerFactoryFactoryBean;
*
* @author Carl Harris
*/
-public class MockTrustManagerFactoryFactoryBean extends TrustManagerFactoryFactoryBean {
-
- private boolean factoryCreated;
-
- @Override
- public TrustManagerFactory createTrustManagerFactory() throws NoSuchProviderException, NoSuchAlgorithmException {
- factoryCreated = true;
- return super.createTrustManagerFactory();
- }
-
- public boolean isFactoryCreated() {
- return factoryCreated;
- }
-
+public class MockTrustManagerFactoryFactoryBean
+ extends TrustManagerFactoryFactoryBean {
+
+ private boolean factoryCreated;
+
+ @Override
+ public TrustManagerFactory createTrustManagerFactory()
+ throws NoSuchProviderException, NoSuchAlgorithmException {
+ factoryCreated = true;
+ return super.createTrustManagerFactory();
+ }
+
+ public boolean isFactoryCreated() {
+ return factoryCreated;
+ }
+
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/pattern/Converter123.java b/logback-core/src/test/java/ch/qos/logback/core/pattern/Converter123.java
index b933755..0b092f2 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/pattern/Converter123.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/pattern/Converter123.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,8 +17,8 @@ import ch.qos.logback.core.pattern.DynamicConverter;
public class Converter123 extends DynamicConverter {
- public String convert(Object event) {
- return "123";
- }
+ public String convert(Object event) {
+ return "123";
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/pattern/ConverterHello.java b/logback-core/src/test/java/ch/qos/logback/core/pattern/ConverterHello.java
index 61024f1..58884d1 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/pattern/ConverterHello.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/pattern/ConverterHello.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,8 +17,8 @@ import ch.qos.logback.core.pattern.DynamicConverter;
public class ConverterHello extends DynamicConverter {
- public String convert(Object event) {
- return "Hello";
- }
+ public String convert(Object event) {
+ return "Hello";
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/pattern/ExceptionalConverter.java b/logback-core/src/test/java/ch/qos/logback/core/pattern/ExceptionalConverter.java
index 58806fb..39a92c7 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/pattern/ExceptionalConverter.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/pattern/ExceptionalConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,12 +16,12 @@ package ch.qos.logback.core.pattern;
import ch.qos.logback.core.pattern.DynamicConverter;
public class ExceptionalConverter extends DynamicConverter {
-
- public String convert(Object event) {
- if (!isStarted()) {
- throw new IllegalStateException("this converter must be started before use");
- }
- return "";
+
+ public String convert(Object event) {
+ if(!isStarted()) {
+ throw new IllegalStateException("this converter must be started before use");
}
+ return "";
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/pattern/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/pattern/PackageTest.java
index 30fce53..b580ea9 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/pattern/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/pattern/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ SpacePadderTest.class, ch.qos.logback.core.pattern.parser.PackageTest.class })
-public class PackageTest {
+ at SuiteClasses({SpacePadderTest.class, ch.qos.logback.core.pattern.parser.PackageTest.class})
+public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/pattern/SpacePadderTest.java b/logback-core/src/test/java/ch/qos/logback/core/pattern/SpacePadderTest.java
index a2bf24f..277b8d8 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/pattern/SpacePadderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/pattern/SpacePadderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,85 +23,85 @@ import org.junit.Test;
public class SpacePadderTest {
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- }
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ }
- @AfterClass
- public static void tearDownAfterClass() throws Exception {
- }
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ }
- @Before
- public void setUp() throws Exception {
- }
+ @Before
+ public void setUp() throws Exception {
+ }
- @After
- public void tearDown() throws Exception {
- }
+ @After
+ public void tearDown() throws Exception {
+ }
- @Test
- public void smoke() {
- {
- StringBuilder buf = new StringBuilder();
- String s = "a";
- SpacePadder.leftPad(buf, s, 4);
- assertEquals(" a", buf.toString());
- }
- {
- StringBuilder buf = new StringBuilder();
- String s = "a";
- SpacePadder.rightPad(buf, s, 4);
- assertEquals("a ", buf.toString());
- }
+ @Test
+ public void smoke() {
+ {
+ StringBuilder buf = new StringBuilder();
+ String s = "a";
+ SpacePadder.leftPad(buf, s, 4);
+ assertEquals(" a", buf.toString());
}
-
- @Test
- public void nullString() {
- String s = null;
- {
- StringBuilder buf = new StringBuilder();
- SpacePadder.leftPad(buf, s, 2);
- assertEquals(" ", buf.toString());
- }
- {
- StringBuilder buf = new StringBuilder();
- SpacePadder.rightPad(buf, s, 2);
- assertEquals(" ", buf.toString());
- }
+ {
+ StringBuilder buf = new StringBuilder();
+ String s = "a";
+ SpacePadder.rightPad(buf, s, 4);
+ assertEquals("a ", buf.toString());
}
+ }
- @Test
- public void longString() {
- {
- StringBuilder buf = new StringBuilder();
- String s = "abc";
- SpacePadder.leftPad(buf, s, 2);
- assertEquals(s, buf.toString());
- }
-
- {
- StringBuilder buf = new StringBuilder();
- String s = "abc";
- SpacePadder.rightPad(buf, s, 2);
- assertEquals(s, buf.toString());
- }
+ @Test
+ public void nullString() {
+ String s = null;
+ {
+ StringBuilder buf = new StringBuilder();
+ SpacePadder.leftPad(buf, s, 2);
+ assertEquals(" ", buf.toString());
+ }
+ {
+ StringBuilder buf = new StringBuilder();
+ SpacePadder.rightPad(buf, s, 2);
+ assertEquals(" ", buf.toString());
}
+ }
- @Test
- public void lengthyPad() {
- {
- StringBuilder buf = new StringBuilder();
- String s = "abc";
- SpacePadder.leftPad(buf, s, 33);
- assertEquals(" abc", buf.toString());
- }
- {
- StringBuilder buf = new StringBuilder();
- String s = "abc";
- SpacePadder.rightPad(buf, s, 33);
- assertEquals("abc ", buf.toString());
- }
+ @Test
+ public void longString() {
+ {
+ StringBuilder buf = new StringBuilder();
+ String s = "abc";
+ SpacePadder.leftPad(buf, s, 2);
+ assertEquals(s, buf.toString());
+ }
+ {
+ StringBuilder buf = new StringBuilder();
+ String s = "abc";
+ SpacePadder.rightPad(buf, s, 2);
+ assertEquals(s, buf.toString());
+ }
+ }
+
+ @Test
+ public void lengthyPad() {
+ {
+ StringBuilder buf = new StringBuilder();
+ String s = "abc";
+ SpacePadder.leftPad(buf, s, 33);
+ assertEquals(" abc", buf.toString());
+ }
+ {
+ StringBuilder buf = new StringBuilder();
+ String s = "abc";
+ SpacePadder.rightPad(buf, s, 33);
+ assertEquals("abc ", buf.toString());
}
+
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/AbstractPatternLayoutBaseTest.java b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/AbstractPatternLayoutBaseTest.java
index 6dae324..e79fcec 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/AbstractPatternLayoutBaseTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/AbstractPatternLayoutBaseTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,81 +27,80 @@ import ch.qos.logback.core.status.StatusChecker;
import ch.qos.logback.core.status.StatusManager;
import ch.qos.logback.core.util.StatusPrinter;
-abstract public class AbstractPatternLayoutBaseTest<E> {
-
- abstract public PatternLayoutBase<E> getPatternLayoutBase();
-
- abstract public E getEventObject();
- abstract public Context getContext();
-
- @Test
- public void testUnStarted() {
- PatternLayoutBase<E> plb = getPatternLayoutBase();
- Context context = new ContextBase();
- plb.setContext(context);
- String s = plb.doLayout(getEventObject());
- assertEquals("", s);
- StatusManager sm = context.getStatusManager();
- StatusPrinter.print(sm);
- }
+abstract public class AbstractPatternLayoutBaseTest<E> {
+
+ abstract public PatternLayoutBase<E> getPatternLayoutBase();
+ abstract public E getEventObject();
+ abstract public Context getContext();
+
+ @Test
+ public void testUnStarted() {
+ PatternLayoutBase<E> plb = getPatternLayoutBase();
+ Context context = new ContextBase();
+ plb.setContext(context);
+ String s = plb.doLayout(getEventObject());
+ assertEquals("", s);
+ StatusManager sm = context.getStatusManager();
+ StatusPrinter.print(sm);
+ }
- /**
- * This test checks that the pattern layout implementation starts its
- * converters. ExceptionalConverter throws an exception if it's convert
- * method is called before being started.
- */
- @Test
- public void testConverterStart() {
- PatternLayoutBase<E> plb = getPatternLayoutBase();
- plb.setContext(getContext());
- plb.getInstanceConverterMap().put("EX", ExceptionalConverter.class.getName());
- plb.setPattern("%EX");
- plb.start();
- String result = plb.doLayout(getEventObject());
- assertFalse(result.contains("%PARSER_ERROR_EX"));
- // System.out.println("========="+result);
- }
+ /**
+ * This test checks that the pattern layout implementation starts its
+ * converters. ExceptionalConverter throws an exception if it's convert
+ * method is called before being started.
+ */
+ @Test
+ public void testConverterStart() {
+ PatternLayoutBase<E> plb = getPatternLayoutBase();
+ plb.setContext(getContext());
+ plb.getInstanceConverterMap().put("EX", ExceptionalConverter.class.getName());
+ plb.setPattern("%EX");
+ plb.start();
+ String result = plb.doLayout(getEventObject());
+ assertFalse(result.contains("%PARSER_ERROR_EX"));
+ //System.out.println("========="+result);
+ }
- @Test
- public void testStarted() {
- PatternLayoutBase<E> plb = getPatternLayoutBase();
- Context context = new ContextBase();
- plb.setContext(context);
- String s = plb.doLayout(getEventObject());
- assertEquals("", s);
- StatusManager sm = context.getStatusManager();
- StatusPrinter.print(sm);
- }
+ @Test
+ public void testStarted() {
+ PatternLayoutBase<E> plb = getPatternLayoutBase();
+ Context context = new ContextBase();
+ plb.setContext(context);
+ String s = plb.doLayout(getEventObject());
+ assertEquals("", s);
+ StatusManager sm = context.getStatusManager();
+ StatusPrinter.print(sm);
+ }
- @Test
- public void testNullPattern() {
- // System.out.println("testNullPattern");
- PatternLayoutBase<E> plb = getPatternLayoutBase();
- Context context = new ContextBase();
- plb.setContext(context);
- plb.setPattern(null);
- plb.start();
- String s = plb.doLayout(getEventObject());
- assertEquals("", s);
- StatusChecker checker = new StatusChecker(context.getStatusManager());
- // StatusPrinter.print(context);
- checker.assertContainsMatch("Empty or null pattern.");
- }
+ @Test
+ public void testNullPattern() {
+ //System.out.println("testNullPattern");
+ PatternLayoutBase<E> plb = getPatternLayoutBase();
+ Context context = new ContextBase();
+ plb.setContext(context);
+ plb.setPattern(null);
+ plb.start();
+ String s = plb.doLayout(getEventObject());
+ assertEquals("", s);
+ StatusChecker checker = new StatusChecker(context.getStatusManager());
+ //StatusPrinter.print(context);
+ checker.assertContainsMatch("Empty or null pattern.");
+ }
- @Test
- public void testEmptyPattern() {
- // System.out.println("testNullPattern");
- PatternLayoutBase<E> plb = getPatternLayoutBase();
- Context context = new ContextBase();
- plb.setContext(context);
- plb.setPattern("");
- plb.start();
- String s = plb.doLayout(getEventObject());
- assertEquals("", s);
- StatusChecker checker = new StatusChecker(context.getStatusManager());
- // StatusPrinter.print(context);
- checker.assertContainsMatch("Empty or null pattern.");
- }
+ @Test
+ public void testEmptyPattern() {
+ //System.out.println("testNullPattern");
+ PatternLayoutBase<E> plb = getPatternLayoutBase();
+ Context context = new ContextBase();
+ plb.setContext(context);
+ plb.setPattern("");
+ plb.start();
+ String s = plb.doLayout(getEventObject());
+ assertEquals("", s);
+ StatusChecker checker = new StatusChecker(context.getStatusManager());
+ //StatusPrinter.print(context);
+ checker.assertContainsMatch("Empty or null pattern.");
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/CompilerTest.java b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/CompilerTest.java
index 14ecadd..a532e73 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/CompilerTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/CompilerTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,225 +30,227 @@ import static org.junit.Assert.assertEquals;
public class CompilerTest {
- Map<String, String> converterMap = new HashMap<String, String>();
- Context context = new ContextBase();
-
- @Before
- public void setUp() {
- converterMap.put("OTT", Converter123.class.getName());
- converterMap.put("hello", ConverterHello.class.getName());
- converterMap.putAll(Parser.DEFAULT_COMPOSITE_CONVERTER_MAP);
- }
-
- String write(final Converter<Object> head, Object event) {
- StringBuilder buf = new StringBuilder();
- Converter<Object> c = head;
- while (c != null) {
- c.write(buf, event);
- c = c.getNext();
- }
- return buf.toString();
- }
-
- @Test
- public void testLiteral() throws Exception {
- Parser<Object> p = new Parser<Object>("hello");
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("hello", result);
- }
-
- @Test
- public void testBasic() throws Exception {
- {
- Parser<Object> p = new Parser<Object>("abc %hello");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("abc Hello", result);
- }
- {
- Parser<Object> p = new Parser<Object>("abc %hello %OTT");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("abc Hello 123", result);
- }
- }
-
- @Test
- public void testFormat() throws Exception {
- {
- Parser<Object> p = new Parser<Object>("abc %7hello");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("abc Hello", result);
- }
-
- {
- Parser<Object> p = new Parser<Object>("abc %-7hello");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("abc Hello ", result);
- }
-
- {
- Parser<Object> p = new Parser<Object>("abc %.3hello");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("abc llo", result);
- }
-
- {
- Parser<Object> p = new Parser<Object>("abc %.-3hello");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("abc Hel", result);
- }
-
- {
- Parser<Object> p = new Parser<Object>("abc %4.5OTT");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("abc 123", result);
- }
- {
- Parser<Object> p = new Parser<Object>("abc %-4.5OTT");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("abc 123 ", result);
- }
- {
- Parser<Object> p = new Parser<Object>("abc %3.4hello");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("abc ello", result);
- }
- {
- Parser<Object> p = new Parser<Object>("abc %-3.-4hello");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("abc Hell", result);
- }
- }
-
- @Test
- public void testComposite() throws Exception {
- // {
- // Parser<Object> p = new Parser<Object>("%(ABC)");
- // p.setContext(context);
- // Node t = p.parse();
- // Converter<Object> head = p.compile(t, converterMap);
- // String result = write(head, new Object());
- // assertEquals("ABC", result);
- // }
- {
- Context c = new ContextBase();
- Parser<Object> p = new Parser<Object>("%(ABC %hello)");
- p.setContext(c);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- StatusPrinter.print(c);
- assertEquals("ABC Hello", result);
- }
- {
- Parser<Object> p = new Parser<Object>("%(ABC %hello)");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("ABC Hello", result);
- }
- }
-
- @Test
- public void testCompositeFormatting() throws Exception {
- {
- Parser<Object> p = new Parser<Object>("xyz %4.10(ABC)");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("xyz ABC", result);
- }
-
- {
- Parser<Object> p = new Parser<Object>("xyz %-4.10(ABC)");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("xyz ABC ", result);
- }
-
- {
- Parser<Object> p = new Parser<Object>("xyz %.2(ABC %hello)");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("xyz lo", result);
- }
-
- {
- Parser<Object> p = new Parser<Object>("xyz %.-2(ABC)");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("xyz AB", result);
- }
-
- {
- Parser<Object> p = new Parser<Object>("xyz %30.30(ABC %20hello)");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("xyz ABC Hello", result);
- }
- }
-
- @Test
- public void testUnknownWord() throws Exception {
- Parser<Object> p = new Parser<Object>("%unknown");
- p.setContext(context);
- Node t = p.parse();
- p.compile(t, converterMap);
- StatusChecker checker = new StatusChecker(context.getStatusManager());
- checker.assertContainsMatch("\\[unknown] is not a valid conversion word");
- }
-
- @Test
- public void testWithNopEscape() throws Exception {
- {
- Parser<Object> p = new Parser<Object>("xyz %hello\\_world");
- p.setContext(context);
- Node t = p.parse();
- Converter<Object> head = p.compile(t, converterMap);
- String result = write(head, new Object());
- assertEquals("xyz Helloworld", result);
- }
+ Map<String, String> converterMap = new HashMap<String, String>();
+ Context context = new ContextBase();
+
+ @Before
+ public void setUp() {
+ converterMap.put("OTT", Converter123.class.getName());
+ converterMap.put("hello", ConverterHello.class.getName());
+ converterMap.putAll(Parser.DEFAULT_COMPOSITE_CONVERTER_MAP);
+ }
+
+
+ String write(final Converter<Object> head, Object event) {
+ StringBuilder buf = new StringBuilder();
+ Converter<Object> c = head;
+ while (c != null) {
+ c.write(buf, event);
+ c = c.getNext();
+ }
+ return buf.toString();
+ }
+
+ @Test
+ public void testLiteral() throws Exception {
+ Parser<Object> p = new Parser<Object>("hello");
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("hello", result);
+ }
+
+ @Test
+ public void testBasic() throws Exception {
+ {
+ Parser<Object> p = new Parser<Object>("abc %hello");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("abc Hello", result);
+ }
+ {
+ Parser<Object> p = new Parser<Object>("abc %hello %OTT");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("abc Hello 123", result);
+ }
+ }
+
+ @Test
+ public void testFormat() throws Exception {
+ {
+ Parser<Object> p = new Parser<Object>("abc %7hello");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("abc Hello", result);
+ }
+
+ {
+ Parser<Object> p = new Parser<Object>("abc %-7hello");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("abc Hello ", result);
+ }
+
+ {
+ Parser<Object> p = new Parser<Object>("abc %.3hello");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("abc llo", result);
+ }
+
+ {
+ Parser<Object> p = new Parser<Object>("abc %.-3hello");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("abc Hel", result);
+ }
+
+ {
+ Parser<Object> p = new Parser<Object>("abc %4.5OTT");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("abc 123", result);
+ }
+ {
+ Parser<Object> p = new Parser<Object>("abc %-4.5OTT");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("abc 123 ", result);
+ }
+ {
+ Parser<Object> p = new Parser<Object>("abc %3.4hello");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("abc ello", result);
+ }
+ {
+ Parser<Object> p = new Parser<Object>("abc %-3.-4hello");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("abc Hell", result);
+ }
+ }
+
+ @Test
+ public void testComposite() throws Exception {
+// {
+// Parser<Object> p = new Parser<Object>("%(ABC)");
+// p.setContext(context);
+// Node t = p.parse();
+// Converter<Object> head = p.compile(t, converterMap);
+// String result = write(head, new Object());
+// assertEquals("ABC", result);
+// }
+ {
+ Context c = new ContextBase();
+ Parser<Object> p = new Parser<Object>("%(ABC %hello)");
+ p.setContext(c);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ StatusPrinter.print(c);
+ assertEquals("ABC Hello", result);
+ }
+ {
+ Parser<Object> p = new Parser<Object>("%(ABC %hello)");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("ABC Hello", result);
+ }
+ }
+
+ @Test
+ public void testCompositeFormatting() throws Exception {
+ {
+ Parser<Object> p = new Parser<Object>("xyz %4.10(ABC)");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("xyz ABC", result);
+ }
+
+ {
+ Parser<Object> p = new Parser<Object>("xyz %-4.10(ABC)");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("xyz ABC ", result);
+ }
+
+ {
+ Parser<Object> p = new Parser<Object>("xyz %.2(ABC %hello)");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("xyz lo", result);
+ }
+
+ {
+ Parser<Object> p = new Parser<Object>("xyz %.-2(ABC)");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("xyz AB", result);
+ }
+
+ {
+ Parser<Object> p = new Parser<Object>("xyz %30.30(ABC %20hello)");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("xyz ABC Hello", result);
+ }
+ }
+
+ @Test
+ public void testUnknownWord() throws Exception {
+ Parser<Object> p = new Parser<Object>("%unknown");
+ p.setContext(context);
+ Node t = p.parse();
+ p.compile(t, converterMap);
+ StatusChecker checker = new StatusChecker(context.getStatusManager());
+ checker
+ .assertContainsMatch("\\[unknown] is not a valid conversion word");
+ }
+
+ @Test
+ public void testWithNopEscape() throws Exception {
+ {
+ Parser<Object> p = new Parser<Object>("xyz %hello\\_world");
+ p.setContext(context);
+ Node t = p.parse();
+ Converter<Object> head = p.compile(t, converterMap);
+ String result = write(head, new Object());
+ assertEquals("xyz Helloworld", result);
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/FormatInfoTest.java b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/FormatInfoTest.java
index 323a711..03ef88c 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/FormatInfoTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/FormatInfoTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,100 +20,101 @@ import org.junit.Test;
import ch.qos.logback.core.pattern.FormatInfo;
-public class FormatInfoTest {
- @Test
- public void testEndingInDot() {
- try {
- FormatInfo.valueOf("45.");
- fail("45. is not a valid format info string");
- } catch (IllegalArgumentException iae) {
- // OK
- }
+public class FormatInfoTest {
+
+ @Test
+ public void testEndingInDot() {
+ try {
+ FormatInfo.valueOf("45.");
+ fail("45. is not a valid format info string");
+ } catch (IllegalArgumentException iae) {
+ // OK
+ }
+ }
+
+ @Test
+ public void testBasic() {
+ {
+ FormatInfo fi = FormatInfo.valueOf("45");
+ FormatInfo witness = new FormatInfo();
+ witness.setMin(45);
+ assertEquals(witness, fi);
+ }
+
+ {
+ FormatInfo fi = FormatInfo.valueOf("4.5");
+ FormatInfo witness = new FormatInfo();
+ witness.setMin(4);
+ witness.setMax(5);
+ assertEquals(witness, fi);
+ }
+ }
+
+ @Test
+ public void testRightPad() {
+ {
+ FormatInfo fi = FormatInfo.valueOf("-40");
+ FormatInfo witness = new FormatInfo();
+ witness.setMin(40);
+ witness.setLeftPad(false);
+ assertEquals(witness, fi);
+ }
+
+ {
+ FormatInfo fi = FormatInfo.valueOf("-12.5");
+ FormatInfo witness = new FormatInfo();
+ witness.setMin(12);
+ witness.setMax(5);
+ witness.setLeftPad(false);
+ assertEquals(witness, fi);
+ }
+
+ {
+ FormatInfo fi = FormatInfo.valueOf("-14.-5");
+ FormatInfo witness = new FormatInfo();
+ witness.setMin(14);
+ witness.setMax(5);
+ witness.setLeftPad(false);
+ witness.setLeftTruncate(false);
+ assertEquals(witness, fi);
}
+ }
- @Test
- public void testBasic() {
- {
- FormatInfo fi = FormatInfo.valueOf("45");
- FormatInfo witness = new FormatInfo();
- witness.setMin(45);
- assertEquals(witness, fi);
- }
-
- {
- FormatInfo fi = FormatInfo.valueOf("4.5");
- FormatInfo witness = new FormatInfo();
- witness.setMin(4);
- witness.setMax(5);
- assertEquals(witness, fi);
- }
+ @Test
+ public void testMinOnly() {
+ {
+ FormatInfo fi = FormatInfo.valueOf("49");
+ FormatInfo witness = new FormatInfo();
+ witness.setMin(49);
+ assertEquals(witness, fi);
}
- @Test
- public void testRightPad() {
- {
- FormatInfo fi = FormatInfo.valueOf("-40");
- FormatInfo witness = new FormatInfo();
- witness.setMin(40);
- witness.setLeftPad(false);
- assertEquals(witness, fi);
- }
-
- {
- FormatInfo fi = FormatInfo.valueOf("-12.5");
- FormatInfo witness = new FormatInfo();
- witness.setMin(12);
- witness.setMax(5);
- witness.setLeftPad(false);
- assertEquals(witness, fi);
- }
-
- {
- FormatInfo fi = FormatInfo.valueOf("-14.-5");
- FormatInfo witness = new FormatInfo();
- witness.setMin(14);
- witness.setMax(5);
- witness.setLeftPad(false);
- witness.setLeftTruncate(false);
- assertEquals(witness, fi);
- }
+ {
+ FormatInfo fi = FormatInfo.valueOf("-587");
+ FormatInfo witness = new FormatInfo();
+ witness.setMin(587);
+ witness.setLeftPad(false);
+ assertEquals(witness, fi);
}
- @Test
- public void testMinOnly() {
- {
- FormatInfo fi = FormatInfo.valueOf("49");
- FormatInfo witness = new FormatInfo();
- witness.setMin(49);
- assertEquals(witness, fi);
- }
-
- {
- FormatInfo fi = FormatInfo.valueOf("-587");
- FormatInfo witness = new FormatInfo();
- witness.setMin(587);
- witness.setLeftPad(false);
- assertEquals(witness, fi);
- }
+ }
+ @Test
+ public void testMaxOnly() {
+ {
+ FormatInfo fi = FormatInfo.valueOf(".49");
+ FormatInfo witness = new FormatInfo();
+ witness.setMax(49);
+ assertEquals(witness, fi);
}
- @Test
- public void testMaxOnly() {
- {
- FormatInfo fi = FormatInfo.valueOf(".49");
- FormatInfo witness = new FormatInfo();
- witness.setMax(49);
- assertEquals(witness, fi);
- }
-
- {
- FormatInfo fi = FormatInfo.valueOf(".-5");
- FormatInfo witness = new FormatInfo();
- witness.setMax(5);
- witness.setLeftTruncate(false);
- assertEquals(witness, fi);
- }
+ {
+ FormatInfo fi = FormatInfo.valueOf(".-5");
+ FormatInfo witness = new FormatInfo();
+ witness.setMax(5);
+ witness.setLeftTruncate(false);
+ assertEquals(witness, fi);
}
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/OptionTokenizerTest.java b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/OptionTokenizerTest.java
index 749bb4e..3b1e21d 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/OptionTokenizerTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/OptionTokenizerTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,124 +17,124 @@ import org.junit.Test;
public class OptionTokenizerTest {
- @Test
- public void testEmpty() {
+ @Test
+ public void testEmpty() {
- }
+ }
- //
- // @Test
- // public void testEmpty() throws ScanException {
- // {
- // List ol = new OptionTokenizer("").tokenize();
- // List witness = new ArrayList();
- // assertEquals(witness, ol);
- // }
- //
- // {
- // List ol = new OptionTokenizer(" ").tokenize();
- // List witness = new ArrayList();
- // assertEquals(witness, ol);
- // }
- // }
- //
- // @Test
- // public void testSimple() throws ScanException {
- // {
- // List ol = new OptionTokenizer("abc").tokenize();
- // List<String> witness = new ArrayList<String>();
- // witness.add("abc");
- // assertEquals(witness, ol);
- // }
- // }
- //
- // @Test
- // public void testSingleQuote() throws ScanException {
- // {
- // List ol = new OptionTokenizer("' '").tokenize();
- // List<String> witness = new ArrayList<String>();
- // witness.add(" ");
- // assertEquals(witness, ol);
- // }
- //
- // {
- // List ol = new OptionTokenizer("' x\t'").tokenize();
- // List<String> witness = new ArrayList<String>();
- // witness.add(" x\t");
- // assertEquals(witness, ol);
- // }
- //
- // {
- // List ol = new OptionTokenizer("' x\\t'").tokenize();
- // List<String> witness = new ArrayList<String>();
- // witness.add(" x\\t");
- // assertEquals(witness, ol);
- // }
- //
- // {
- // List ol = new OptionTokenizer("' x\\''").tokenize();
- // List<String> witness = new ArrayList<String>();
- // witness.add(" x\\'");
- // assertEquals(witness, ol);
- // }
- // }
- //
- //
- //
- // @Test
- // public void testDoubleQuote() throws ScanException {
- // {
- // List ol = new OptionTokenizer("\" \"").tokenize();
- // List<String> witness = new ArrayList<String>();
- // witness.add(" ");
- // assertEquals(witness, ol);
- // }
- //
- // {
- // List ol = new OptionTokenizer("\" x\t\"").tokenize();
- // List<String> witness = new ArrayList<String>();
- // witness.add(" x\t");
- // assertEquals(witness, ol);
- // }
- //
- // {
- // List ol = new OptionTokenizer("\" x\\t\"").tokenize();
- // List<String> witness = new ArrayList<String>();
- // witness.add(" x\\t");
- // assertEquals(witness, ol);
- // }
- //
- // {
- // List ol = new OptionTokenizer("\" x\\\"\"").tokenize();
- // List<String> witness = new ArrayList<String>();
- // witness.add(" x\\\"");
- // assertEquals(witness, ol);
- // }
- // }
- //
- // @Test
- // public void testMultiple() throws ScanException {
- // {
- // List ol = new OptionTokenizer("a, b").tokenize();
- // List<String> witness = new ArrayList<String>();
- // witness.add("a");
- // witness.add("b");
- // assertEquals(witness, ol);
- // }
- // {
- // List ol = new OptionTokenizer("'a', b").tokenize();
- // List<String> witness = new ArrayList<String>();
- // witness.add("a");
- // witness.add("b");
- // assertEquals(witness, ol);
- // }
- // {
- // List ol = new OptionTokenizer("'', b").tokenize();
- // List<String> witness = new ArrayList<String>();
- // witness.add("");
- // witness.add("b");
- // assertEquals(witness, ol);
- // }
- // }
- //
+//
+// @Test
+// public void testEmpty() throws ScanException {
+// {
+// List ol = new OptionTokenizer("").tokenize();
+// List witness = new ArrayList();
+// assertEquals(witness, ol);
+// }
+//
+// {
+// List ol = new OptionTokenizer(" ").tokenize();
+// List witness = new ArrayList();
+// assertEquals(witness, ol);
+// }
+// }
+//
+// @Test
+// public void testSimple() throws ScanException {
+// {
+// List ol = new OptionTokenizer("abc").tokenize();
+// List<String> witness = new ArrayList<String>();
+// witness.add("abc");
+// assertEquals(witness, ol);
+// }
+// }
+//
+// @Test
+// public void testSingleQuote() throws ScanException {
+// {
+// List ol = new OptionTokenizer("' '").tokenize();
+// List<String> witness = new ArrayList<String>();
+// witness.add(" ");
+// assertEquals(witness, ol);
+// }
+//
+// {
+// List ol = new OptionTokenizer("' x\t'").tokenize();
+// List<String> witness = new ArrayList<String>();
+// witness.add(" x\t");
+// assertEquals(witness, ol);
+// }
+//
+// {
+// List ol = new OptionTokenizer("' x\\t'").tokenize();
+// List<String> witness = new ArrayList<String>();
+// witness.add(" x\\t");
+// assertEquals(witness, ol);
+// }
+//
+// {
+// List ol = new OptionTokenizer("' x\\''").tokenize();
+// List<String> witness = new ArrayList<String>();
+// witness.add(" x\\'");
+// assertEquals(witness, ol);
+// }
+// }
+//
+//
+//
+// @Test
+// public void testDoubleQuote() throws ScanException {
+// {
+// List ol = new OptionTokenizer("\" \"").tokenize();
+// List<String> witness = new ArrayList<String>();
+// witness.add(" ");
+// assertEquals(witness, ol);
+// }
+//
+// {
+// List ol = new OptionTokenizer("\" x\t\"").tokenize();
+// List<String> witness = new ArrayList<String>();
+// witness.add(" x\t");
+// assertEquals(witness, ol);
+// }
+//
+// {
+// List ol = new OptionTokenizer("\" x\\t\"").tokenize();
+// List<String> witness = new ArrayList<String>();
+// witness.add(" x\\t");
+// assertEquals(witness, ol);
+// }
+//
+// {
+// List ol = new OptionTokenizer("\" x\\\"\"").tokenize();
+// List<String> witness = new ArrayList<String>();
+// witness.add(" x\\\"");
+// assertEquals(witness, ol);
+// }
+// }
+//
+// @Test
+// public void testMultiple() throws ScanException {
+// {
+// List ol = new OptionTokenizer("a, b").tokenize();
+// List<String> witness = new ArrayList<String>();
+// witness.add("a");
+// witness.add("b");
+// assertEquals(witness, ol);
+// }
+// {
+// List ol = new OptionTokenizer("'a', b").tokenize();
+// List<String> witness = new ArrayList<String>();
+// witness.add("a");
+// witness.add("b");
+// assertEquals(witness, ol);
+// }
+// {
+// List ol = new OptionTokenizer("'', b").tokenize();
+// List<String> witness = new ArrayList<String>();
+// witness.add("");
+// witness.add("b");
+// assertEquals(witness, ol);
+// }
+// }
+//
}
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/PackageTest.java
index 54d7c56..1a3d4a5 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,11 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ TokenStreamTest.class, OptionTokenizerTest.class, ParserTest.class, FormatInfoTest.class, CompilerTest.class, SamplePatternLayoutTest.class })
+ at SuiteClasses({TokenStreamTest.class,
+ OptionTokenizerTest.class,
+ ParserTest.class,
+ FormatInfoTest.class,
+ CompilerTest.class,
+ SamplePatternLayoutTest.class})
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/ParserTest.java b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/ParserTest.java
index 4dfb1a5..2d69fb9 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/ParserTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/ParserTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,260 +30,262 @@ import ch.qos.logback.core.pattern.FormatInfo;
public class ParserTest {
- String BARE = Token.BARE_COMPOSITE_KEYWORD_TOKEN.getValue().toString();
- Context context = new ContextBase();
+ String BARE = Token.BARE_COMPOSITE_KEYWORD_TOKEN.getValue().toString();
+ Context context = new ContextBase();
- @Test
- public void testBasic() throws Exception {
- Parser p = new Parser("hello");
- Node t = p.parse();
- assertEquals(Node.LITERAL, t.getType());
- assertEquals("hello", t.getValue());
- }
- @Test
- public void testKeyword() throws Exception {
-
- {
- Parser p = new Parser("hello%xyz");
- Node t = p.parse();
- Node witness = new Node(Node.LITERAL, "hello");
- witness.next = new SimpleKeywordNode("xyz");
- assertEquals(witness, t);
- }
-
- {
- Parser p = new Parser("hello%xyz{x}");
- Node t = p.parse();
- Node witness = new Node(Node.LITERAL, "hello");
- SimpleKeywordNode n = new SimpleKeywordNode("xyz");
- List<String> optionList = new ArrayList<String>();
- optionList.add("x");
- n.setOptions(optionList);
- witness.next = n;
- assertEquals(witness, t);
- }
- }
+ @Test
+ public void testBasic() throws Exception {
+ Parser p = new Parser("hello");
+ Node t = p.parse();
+ assertEquals(Node.LITERAL, t.getType());
+ assertEquals("hello", t.getValue());
+ }
- @Test
- public void testComposite() throws Exception {
- {
- Parser p = new Parser("hello%(%child)");
- Node t = p.parse();
-
- Node witness = new Node(Node.LITERAL, "hello");
- CompositeNode composite = new CompositeNode(BARE);
- Node child = new SimpleKeywordNode("child");
- composite.setChildNode(child);
- witness.next = composite;
-
- // System.out.println("w:" + witness);
- // System.out.println(t);
-
- assertEquals(witness, t);
- }
-
- // System.out.println("testRecursive part 2");
- {
- Parser p = new Parser("hello%(%child )");
- Node t = p.parse();
-
- Node witness = new Node(Node.LITERAL, "hello");
- CompositeNode composite = new CompositeNode(BARE);
- Node child = new SimpleKeywordNode("child");
- composite.setChildNode(child);
- witness.next = composite;
- child.next = new Node(Node.LITERAL, " ");
- assertEquals(witness, t);
- }
-
- {
- Parser p = new Parser("hello%(%child %h)");
- Node t = p.parse();
- Node witness = new Node(Node.LITERAL, "hello");
- CompositeNode composite = new CompositeNode(BARE);
- Node child = new SimpleKeywordNode("child");
- composite.setChildNode(child);
- child.next = new Node(Node.LITERAL, " ");
- child.next.next = new SimpleKeywordNode("h");
- witness.next = composite;
- assertEquals(witness, t);
- }
-
- {
- Parser p = new Parser("hello%(%child %h) %m");
- Node t = p.parse();
- Node witness = new Node(Node.LITERAL, "hello");
- CompositeNode composite = new CompositeNode(BARE);
- Node child = new SimpleKeywordNode("child");
- composite.setChildNode(child);
- child.next = new Node(Node.LITERAL, " ");
- child.next.next = new SimpleKeywordNode("h");
- witness.next = composite;
- composite.next = new Node(Node.LITERAL, " ");
- composite.next.next = new SimpleKeywordNode("m");
- assertEquals(witness, t);
- }
-
- {
- Parser p = new Parser("hello%( %child \\(%h\\) ) %m");
- Node t = p.parse();
- Node witness = new Node(Node.LITERAL, "hello");
- CompositeNode composite = new CompositeNode(BARE);
- Node child = new Node(Node.LITERAL, " ");
- composite.setChildNode(child);
- Node c = child;
- c = c.next = new SimpleKeywordNode("child");
- c = c.next = new Node(Node.LITERAL, " (");
- c = c.next = new SimpleKeywordNode("h");
- c = c.next = new Node(Node.LITERAL, ") ");
- witness.next = composite;
- composite.next = new Node(Node.LITERAL, " ");
- composite.next.next = new SimpleKeywordNode("m");
- assertEquals(witness, t);
- }
+ @Test
+ public void testKeyword() throws Exception {
+ {
+ Parser p = new Parser("hello%xyz");
+ Node t = p.parse();
+ Node witness = new Node(Node.LITERAL, "hello");
+ witness.next = new SimpleKeywordNode("xyz");
+ assertEquals(witness, t);
}
- @Test
- public void testNested() throws Exception {
- {
- Parser p = new Parser("%top %(%child%(%h))");
- Node t = p.parse();
- Node witness = new SimpleKeywordNode("top");
- Node w = witness.next = new Node(Node.LITERAL, " ");
- CompositeNode composite = new CompositeNode(BARE);
- w = w.next = composite;
- Node child = new SimpleKeywordNode("child");
- composite.setChildNode(child);
- composite = new CompositeNode(BARE);
- child.next = composite;
- composite.setChildNode(new SimpleKeywordNode("h"));
-
- assertEquals(witness, t);
- }
+ {
+ Parser p = new Parser("hello%xyz{x}");
+ Node t = p.parse();
+ Node witness = new Node(Node.LITERAL, "hello");
+ SimpleKeywordNode n = new SimpleKeywordNode("xyz");
+ List<String> optionList = new ArrayList<String>();
+ optionList.add("x");
+ n.setOptions(optionList);
+ witness.next = n;
+ assertEquals(witness, t);
}
+ }
- @Test
- public void testFormattingInfo() throws Exception {
- {
- Parser p = new Parser("%45x");
- Node t = p.parse();
- FormattingNode witness = new SimpleKeywordNode("x");
- witness.setFormatInfo(new FormatInfo(45, Integer.MAX_VALUE));
- assertEquals(witness, t);
- }
- {
- Parser p = new Parser("%4.5x");
- Node t = p.parse();
- FormattingNode witness = new SimpleKeywordNode("x");
- witness.setFormatInfo(new FormatInfo(4, 5));
- assertEquals(witness, t);
- }
-
- {
- Parser p = new Parser("%-4.5x");
- Node t = p.parse();
- FormattingNode witness = new SimpleKeywordNode("x");
- witness.setFormatInfo(new FormatInfo(4, 5, false, true));
- assertEquals(witness, t);
- }
- {
- Parser p = new Parser("%-4.-5x");
- Node t = p.parse();
- FormattingNode witness = new SimpleKeywordNode("x");
- witness.setFormatInfo(new FormatInfo(4, 5, false, false));
- assertEquals(witness, t);
- }
-
- {
- Parser p = new Parser("%-4.5x %12y");
- Node t = p.parse();
- FormattingNode witness = new SimpleKeywordNode("x");
- witness.setFormatInfo(new FormatInfo(4, 5, false, true));
- Node n = witness.next = new Node(Node.LITERAL, " ");
- n = n.next = new SimpleKeywordNode("y");
- ((FormattingNode) n).setFormatInfo(new FormatInfo(12, Integer.MAX_VALUE));
- assertEquals(witness, t);
- }
- }
+ @Test
+ public void testComposite() throws Exception {
+ {
+ Parser p = new Parser("hello%(%child)");
+ Node t = p.parse();
- @Test
- public void testOptions0() throws Exception {
- Parser p = new Parser("%45x{'test '}");
- Node t = p.parse();
- SimpleKeywordNode witness = new SimpleKeywordNode("x");
- witness.setFormatInfo(new FormatInfo(45, Integer.MAX_VALUE));
- List<String> ol = new ArrayList<String>();
- ol.add("test ");
- witness.setOptions(ol);
- assertEquals(witness, t);
+ Node witness = new Node(Node.LITERAL, "hello");
+ CompositeNode composite = new CompositeNode(BARE);
+ Node child = new SimpleKeywordNode("child");
+ composite.setChildNode(child);
+ witness.next = composite;
+
+ // System.out.println("w:" + witness);
+ // System.out.println(t);
+
+ assertEquals(witness, t);
}
- @Test
- public void testOptions1() throws Exception {
- Parser p = new Parser("%45x{a, b}");
- Node t = p.parse();
- SimpleKeywordNode witness = new SimpleKeywordNode("x");
- witness.setFormatInfo(new FormatInfo(45, Integer.MAX_VALUE));
- List<String> ol = new ArrayList<String>();
- ol.add("a");
- ol.add("b");
- witness.setOptions(ol);
- assertEquals(witness, t);
+ // System.out.println("testRecursive part 2");
+ {
+ Parser p = new Parser("hello%(%child )");
+ Node t = p.parse();
+
+ Node witness = new Node(Node.LITERAL, "hello");
+ CompositeNode composite = new CompositeNode(BARE);
+ Node child = new SimpleKeywordNode("child");
+ composite.setChildNode(child);
+ witness.next = composite;
+ child.next = new Node(Node.LITERAL, " ");
+ assertEquals(witness, t);
}
- // see http://jira.qos.ch/browse/LBCORE-180
- @Test
- public void keywordGluedToLitteral() throws Exception {
- Parser p = new Parser("%x{}a");
- Node t = p.parse();
- SimpleKeywordNode witness = new SimpleKeywordNode("x");
- witness.setOptions(new ArrayList<String>());
- witness.next = new Node(Node.LITERAL, "a");
- assertEquals(witness, t);
+ {
+ Parser p = new Parser("hello%(%child %h)");
+ Node t = p.parse();
+ Node witness = new Node(Node.LITERAL, "hello");
+ CompositeNode composite = new CompositeNode(BARE);
+ Node child = new SimpleKeywordNode("child");
+ composite.setChildNode(child);
+ child.next = new Node(Node.LITERAL, " ");
+ child.next.next = new SimpleKeywordNode("h");
+ witness.next = composite;
+ assertEquals(witness, t);
}
- @Test
- public void testCompositeFormatting() throws Exception {
- Parser p = new Parser("hello%5(XYZ)");
- Node t = p.parse();
+ {
+ Parser p = new Parser("hello%(%child %h) %m");
+ Node t = p.parse();
+ Node witness = new Node(Node.LITERAL, "hello");
+ CompositeNode composite = new CompositeNode(BARE);
+ Node child = new SimpleKeywordNode("child");
+ composite.setChildNode(child);
+ child.next = new Node(Node.LITERAL, " ");
+ child.next.next = new SimpleKeywordNode("h");
+ witness.next = composite;
+ composite.next = new Node(Node.LITERAL, " ");
+ composite.next.next = new SimpleKeywordNode("m");
+ assertEquals(witness, t);
+ }
- Node witness = new Node(Node.LITERAL, "hello");
- CompositeNode composite = new CompositeNode(BARE);
- composite.setFormatInfo(new FormatInfo(5, Integer.MAX_VALUE));
- Node child = new Node(Node.LITERAL, "XYZ");
- composite.setChildNode(child);
- witness.next = composite;
+ {
+ Parser p = new Parser("hello%( %child \\(%h\\) ) %m");
+ Node t = p.parse();
+ Node witness = new Node(Node.LITERAL, "hello");
+ CompositeNode composite = new CompositeNode(BARE);
+ Node child = new Node(Node.LITERAL, " ");
+ composite.setChildNode(child);
+ Node c = child;
+ c = c.next = new SimpleKeywordNode("child");
+ c = c.next = new Node(Node.LITERAL, " (");
+ c = c.next = new SimpleKeywordNode("h");
+ c = c.next = new Node(Node.LITERAL, ") ");
+ witness.next = composite;
+ composite.next = new Node(Node.LITERAL, " ");
+ composite.next.next = new SimpleKeywordNode("m");
+ assertEquals(witness, t);
+ }
- assertEquals(witness, t);
+ }
+
+ @Test
+ public void testNested() throws Exception {
+ {
+ Parser p = new Parser("%top %(%child%(%h))");
+ Node t = p.parse();
+ Node witness = new SimpleKeywordNode("top");
+ Node w = witness.next = new Node(Node.LITERAL, " ");
+ CompositeNode composite = new CompositeNode(BARE);
+ w = w.next = composite;
+ Node child = new SimpleKeywordNode("child");
+ composite.setChildNode(child);
+ composite = new CompositeNode(BARE);
+ child.next = composite;
+ composite.setChildNode(new SimpleKeywordNode("h"));
+
+ assertEquals(witness, t);
+ }
+ }
+
+ @Test
+ public void testFormattingInfo() throws Exception {
+ {
+ Parser p = new Parser("%45x");
+ Node t = p.parse();
+ FormattingNode witness = new SimpleKeywordNode("x");
+ witness.setFormatInfo(new FormatInfo(45, Integer.MAX_VALUE));
+ assertEquals(witness, t);
+ }
+ {
+ Parser p = new Parser("%4.5x");
+ Node t = p.parse();
+ FormattingNode witness = new SimpleKeywordNode("x");
+ witness.setFormatInfo(new FormatInfo(4, 5));
+ assertEquals(witness, t);
}
- @Test
- public void empty() {
- try {
- Parser p = new Parser("");
- p.parse();
- fail("");
- } catch (ScanException e) {
+ {
+ Parser p = new Parser("%-4.5x");
+ Node t = p.parse();
+ FormattingNode witness = new SimpleKeywordNode("x");
+ witness.setFormatInfo(new FormatInfo(4, 5, false, true));
+ assertEquals(witness, t);
+ }
+ {
+ Parser p = new Parser("%-4.-5x");
+ Node t = p.parse();
+ FormattingNode witness = new SimpleKeywordNode("x");
+ witness.setFormatInfo(new FormatInfo(4, 5, false, false));
+ assertEquals(witness, t);
+ }
- }
+ {
+ Parser p = new Parser("%-4.5x %12y");
+ Node t = p.parse();
+ FormattingNode witness = new SimpleKeywordNode("x");
+ witness.setFormatInfo(new FormatInfo(4, 5, false, true));
+ Node n = witness.next = new Node(Node.LITERAL, " ");
+ n = n.next = new SimpleKeywordNode("y");
+ ((FormattingNode) n).setFormatInfo(new FormatInfo(12, Integer.MAX_VALUE));
+ assertEquals(witness, t);
}
+ }
+
+ @Test
+ public void testOptions0() throws Exception {
+ Parser p = new Parser("%45x{'test '}");
+ Node t = p.parse();
+ SimpleKeywordNode witness = new SimpleKeywordNode("x");
+ witness.setFormatInfo(new FormatInfo(45, Integer.MAX_VALUE));
+ List<String> ol = new ArrayList<String>();
+ ol.add("test ");
+ witness.setOptions(ol);
+ assertEquals(witness, t);
+ }
+
+ @Test
+ public void testOptions1() throws Exception {
+ Parser p = new Parser("%45x{a, b}");
+ Node t = p.parse();
+ SimpleKeywordNode witness = new SimpleKeywordNode("x");
+ witness.setFormatInfo(new FormatInfo(45, Integer.MAX_VALUE));
+ List<String> ol = new ArrayList<String>();
+ ol.add("a");
+ ol.add("b");
+ witness.setOptions(ol);
+ assertEquals(witness, t);
+ }
+
+ // see http://jira.qos.ch/browse/LBCORE-180
+ @Test
+ public void keywordGluedToLitteral() throws Exception {
+ Parser p = new Parser("%x{}a");
+ Node t = p.parse();
+ SimpleKeywordNode witness = new SimpleKeywordNode("x");
+ witness.setOptions(new ArrayList<String>());
+ witness.next = new Node(Node.LITERAL, "a");
+ assertEquals(witness, t);
+ }
+
+ @Test
+ public void testCompositeFormatting() throws Exception {
+ Parser p = new Parser("hello%5(XYZ)");
+ Node t = p.parse();
+
+ Node witness = new Node(Node.LITERAL, "hello");
+ CompositeNode composite = new CompositeNode(BARE);
+ composite.setFormatInfo(new FormatInfo(5, Integer.MAX_VALUE));
+ Node child = new Node(Node.LITERAL, "XYZ");
+ composite.setChildNode(child);
+ witness.next = composite;
+
+ assertEquals(witness, t);
+
+ }
+
+ @Test
+ public void empty() {
+ try {
+ Parser p = new Parser("");
+ p.parse();
+ fail("");
+ } catch (ScanException e) {
- @Test
- public void lbcore193() throws Exception {
- try {
- Parser p = new Parser("hello%(abc");
- p.setContext(context);
- Node t = p.parse();
- fail("where the is exception?");
- } catch (ScanException ise) {
- assertEquals("Expecting RIGHT_PARENTHESIS token but got null", ise.getMessage());
- }
- StatusChecker sc = new StatusChecker(context);
- sc.assertContainsMatch("Expecting RIGHT_PARENTHESIS");
- sc.assertContainsMatch("See also " + Parser.MISSING_RIGHT_PARENTHESIS);
}
+ }
+
+ @Test
+ public void lbcore193() throws Exception {
+ try {
+ Parser p = new Parser("hello%(abc");
+ p.setContext(context);
+ Node t = p.parse();
+ fail("where the is exception?");
+ } catch (ScanException ise) {
+ assertEquals("Expecting RIGHT_PARENTHESIS token but got null", ise.getMessage());
+ }
+ StatusChecker sc = new StatusChecker(context);
+ sc.assertContainsMatch("Expecting RIGHT_PARENTHESIS");
+ sc.assertContainsMatch("See also " + Parser.MISSING_RIGHT_PARENTHESIS);
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/SamplePatternLayout.java b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/SamplePatternLayout.java
index 062fb53..e981218 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/SamplePatternLayout.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/SamplePatternLayout.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,21 +20,23 @@ import ch.qos.logback.core.pattern.Converter123;
import ch.qos.logback.core.pattern.ConverterHello;
import ch.qos.logback.core.pattern.PatternLayoutBase;
-public class SamplePatternLayout<E> extends PatternLayoutBase<E> {
- Map<String, String> converterMap = new HashMap<String, String>();
- public SamplePatternLayout() {
- converterMap.put("OTT", Converter123.class.getName());
- converterMap.put("hello", ConverterHello.class.getName());
- }
+public class SamplePatternLayout<E> extends PatternLayoutBase<E> {
+
+ Map<String, String> converterMap = new HashMap<String, String>();
- public Map<String, String> getDefaultConverterMap() {
- return converterMap;
- }
+ public SamplePatternLayout() {
+ converterMap.put("OTT", Converter123.class.getName());
+ converterMap.put("hello", ConverterHello.class.getName());
+ }
+
+ public Map<String, String> getDefaultConverterMap() {
+ return converterMap;
+ }
- public String doLayout(E event) {
- return writeLoopOnConverters(event);
- }
+ public String doLayout(E event) {
+ return writeLoopOnConverters(event);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/SamplePatternLayoutTest.java b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/SamplePatternLayoutTest.java
index 05a931f..12df111 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/SamplePatternLayoutTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/SamplePatternLayoutTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,68 +21,70 @@ import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.pattern.PatternLayoutBase;
-public class SamplePatternLayoutTest extends AbstractPatternLayoutBaseTest<Object> {
-
- Context context = new ContextBase();
- public PatternLayoutBase<Object> getPatternLayoutBase() {
- return new SamplePatternLayout<Object>();
- }
+public class SamplePatternLayoutTest extends AbstractPatternLayoutBaseTest<Object> {
- public Object getEventObject() {
- return new Object();
- }
+ Context context = new ContextBase();
- @Test
- public void testOK() {
- PatternLayoutBase<Object> plb = getPatternLayoutBase();
- Context context = new ContextBase();
- plb.setContext(context);
- plb.setPattern("x%OTT");
- plb.start();
- String s = plb.doLayout(new Object());
- // System.out.println(s);
+ public PatternLayoutBase<Object> getPatternLayoutBase() {
+ return new SamplePatternLayout<Object>();
+ }
- // StatusManager sm = context.getStatusManager();
- // StatusPrinter.print(sm);
- assertEquals("x123", s);
- }
+ public Object getEventObject() {
+ return new Object();
+ }
+
+ @Test
+ public void testOK() {
+ PatternLayoutBase<Object> plb = getPatternLayoutBase();
+ Context context = new ContextBase();
+ plb.setContext(context);
+ plb.setPattern("x%OTT");
+ plb.start();
+ String s = plb.doLayout(new Object());
+ //System.out.println(s);
- @Test
- public void testEscapeClosingParentheses() {
- PatternLayoutBase<Object> plb = getPatternLayoutBase();
- Context context = new ContextBase();
- plb.setContext(context);
- plb.setPattern("x(%OTT\\)y");
- plb.start();
- String s = plb.doLayout(new Object());
- assertEquals("x(123)y", s);
- }
+ //StatusManager sm = context.getStatusManager();
+ //StatusPrinter.print(sm);
+ assertEquals("x123", s);
+ }
- @Test
- public void testEscapeBothParentheses() {
- PatternLayoutBase<Object> plb = getPatternLayoutBase();
- Context context = new ContextBase();
- plb.setContext(context);
- plb.setPattern("x\\(%OTT\\)y");
- plb.start();
- String s = plb.doLayout(new Object());
- assertEquals("x(123)y", s);
- }
+ @Test
+ public void testEscapeClosingParentheses() {
+ PatternLayoutBase<Object> plb = getPatternLayoutBase();
+ Context context = new ContextBase();
+ plb.setContext(context);
+ plb.setPattern("x(%OTT\\)y");
+ plb.start();
+ String s = plb.doLayout(new Object());
+ assertEquals("x(123)y", s);
+ }
+
+ @Test
+ public void testEscapeBothParentheses() {
+ PatternLayoutBase<Object> plb = getPatternLayoutBase();
+ Context context = new ContextBase();
+ plb.setContext(context);
+ plb.setPattern("x\\(%OTT\\)y");
+ plb.start();
+ String s = plb.doLayout(new Object());
+ assertEquals("x(123)y", s);
+ }
- @Test
- public void testPercentAsLiteral() {
- PatternLayoutBase<Object> plb = getPatternLayoutBase();
- Context context = new ContextBase();
- plb.setContext(context);
- plb.setPattern("hello \\% world");
- plb.start();
- String s = plb.doLayout(new Object());
- assertEquals("hello % world", s);
- }
+ @Test
+ public void testPercentAsLiteral() {
+ PatternLayoutBase<Object> plb = getPatternLayoutBase();
+ Context context = new ContextBase();
+ plb.setContext(context);
+ plb.setPattern("hello \\% world");
+ plb.start();
+ String s = plb.doLayout(new Object());
+ assertEquals("hello % world", s);
+ }
- @Override
- public Context getContext() {
- return context;
- }
+
+ @Override
+ public Context getContext() {
+ return context;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/TokenStreamTest.java b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/TokenStreamTest.java
index 3cb20ff..bd1d05b 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/TokenStreamTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/pattern/parser/TokenStreamTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,392 +26,396 @@ import ch.qos.logback.core.pattern.util.AlmostAsIsEscapeUtil;
public class TokenStreamTest {
- @Test
- public void testEmpty() throws ScanException {
- try {
- new TokenStream("").tokenize();
- fail("empty string not allowed");
- } catch (IllegalArgumentException e) {
- }
+ @Test
+ public void testEmpty() throws ScanException {
+ try {
+ new TokenStream("").tokenize();
+ fail("empty string not allowed");
+ } catch (IllegalArgumentException e) {
}
-
- @Test
- public void testSingleLiteral() throws ScanException {
- List tl = new TokenStream("hello").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(new Token(Token.LITERAL, "hello"));
- assertEquals(witness, tl);
+ }
+
+ @Test
+ public void testSingleLiteral() throws ScanException {
+ List tl = new TokenStream("hello").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(new Token(Token.LITERAL, "hello"));
+ assertEquals(witness, tl);
+ }
+
+ @Test
+ public void testLiteralWithPercent() throws ScanException {
+ {
+ List tl = new TokenStream("hello\\%world").tokenize();
+
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(new Token(Token.LITERAL, "hello%world"));
+ assertEquals(witness, tl);
}
-
- @Test
- public void testLiteralWithPercent() throws ScanException {
- {
- List tl = new TokenStream("hello\\%world").tokenize();
-
- List<Token> witness = new ArrayList<Token>();
- witness.add(new Token(Token.LITERAL, "hello%world"));
- assertEquals(witness, tl);
- }
- {
- List tl = new TokenStream("hello\\%").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(new Token(Token.LITERAL, "hello%"));
- assertEquals(witness, tl);
- }
-
- {
- List tl = new TokenStream("\\%").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(new Token(Token.LITERAL, "%"));
- assertEquals(witness, tl);
- }
+ {
+ List tl = new TokenStream("hello\\%").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(new Token(Token.LITERAL, "hello%"));
+ assertEquals(witness, tl);
}
- @Test
- public void testBasic() throws ScanException {
-
- // test "%c"
- {
- List tl = new TokenStream("%c").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "c"));
- assertEquals(witness, tl);
- }
-
- {
- // test "xyz%-34c"
- List tl = new TokenStream("%a%b").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "a"));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "b"));
- assertEquals(witness, tl);
- }
-
- {
- // test "xyz%-34c"
- List tl = new TokenStream("xyz%-34c").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(new Token(Token.LITERAL, "xyz"));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.FORMAT_MODIFIER, "-34"));
- witness.add(new Token(Token.SIMPLE_KEYWORD, "c"));
- assertEquals(witness, tl);
- }
+ {
+ List tl = new TokenStream("\\%").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(new Token(Token.LITERAL, "%"));
+ assertEquals(witness, tl);
}
-
- @Test
- public void testComplexNR() throws ScanException {
- List tl = new TokenStream("%d{1234} [%34.-67toto] %n").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "d"));
- List ol = new ArrayList<String>();
- ol.add("1234");
- witness.add(new Token(Token.OPTION, ol));
- witness.add(new Token(Token.LITERAL, " ["));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.FORMAT_MODIFIER, "34.-67"));
- witness.add(new Token(Token.SIMPLE_KEYWORD, "toto"));
- witness.add(new Token(Token.LITERAL, "] "));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "n"));
- assertEquals(witness, tl);
+ }
+
+ @Test
+ public void testBasic() throws ScanException {
+
+ // test "%c"
+ {
+ List tl = new TokenStream("%c").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "c"));
+ assertEquals(witness, tl);
}
- @Test
- public void testEmptyP() throws ScanException {
- List tl = new TokenStream("()").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(new Token(Token.LITERAL, "("));
- witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
- assertEquals(witness, tl);
+ {
+ // test "xyz%-34c"
+ List tl = new TokenStream("%a%b").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "a"));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "b"));
+ assertEquals(witness, tl);
}
- @Test
- public void testEmptyP2() throws ScanException {
- List tl = new TokenStream("%()").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
- witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
- assertEquals(witness, tl);
+ {
+ // test "xyz%-34c"
+ List tl = new TokenStream("xyz%-34c").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(new Token(Token.LITERAL, "xyz"));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.FORMAT_MODIFIER, "-34"));
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "c"));
+ assertEquals(witness, tl);
}
-
- @Test
- public void testEscape() throws ScanException {
- {
- List tl = new TokenStream("\\%").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(new Token(Token.LITERAL, "%"));
- assertEquals(witness, tl);
- }
-
- {
- List tl = new TokenStream("\\%\\(\\t\\)\\r\\n").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(new Token(Token.LITERAL, "%(\t)\r\n"));
- assertEquals(witness, tl);
- }
-
- {
- List tl = new TokenStream("\\\\%x").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(new Token(Token.LITERAL, "\\"));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
- assertEquals(witness, tl);
- }
-
- {
- List tl = new TokenStream("%x\\)").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
- witness.add(new Token(Token.LITERAL, ")"));
- assertEquals(witness, tl);
- }
-
- {
- List tl = new TokenStream("%x\\_a").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
- witness.add(new Token(Token.LITERAL, "a"));
- assertEquals(witness, tl);
- }
- {
- List tl = new TokenStream("%x\\_%b").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "b"));
- assertEquals(witness, tl);
- }
+ }
+
+ @Test
+ public void testComplexNR() throws ScanException {
+ List tl = new TokenStream("%d{1234} [%34.-67toto] %n").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "d"));
+ List ol = new ArrayList<String>();
+ ol.add("1234");
+ witness.add(new Token(Token.OPTION, ol));
+ witness.add(new Token(Token.LITERAL, " ["));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.FORMAT_MODIFIER, "34.-67"));
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "toto"));
+ witness.add(new Token(Token.LITERAL, "] "));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "n"));
+ assertEquals(witness, tl);
+ }
+
+ @Test
+ public void testEmptyP() throws ScanException {
+ List tl = new TokenStream("()").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(new Token(Token.LITERAL, "("));
+ witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
+ assertEquals(witness, tl);
+ }
+
+ @Test
+ public void testEmptyP2() throws ScanException {
+ List tl = new TokenStream("%()").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
+ witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
+ assertEquals(witness, tl);
+ }
+
+ @Test
+ public void testEscape() throws ScanException {
+ {
+ List tl = new TokenStream("\\%").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(new Token(Token.LITERAL, "%"));
+ assertEquals(witness, tl);
}
- @Test
- public void testOptions() throws ScanException {
- {
- List tl = new TokenStream("%x{t}").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
- List ol = new ArrayList<String>();
- ol.add("t");
- witness.add(new Token(Token.OPTION, ol));
- assertEquals(witness, tl);
- }
-
- {
- List tl = new TokenStream("%x{t,y}").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
- List ol = new ArrayList<String>();
- ol.add("t");
- ol.add("y");
- witness.add(new Token(Token.OPTION, ol));
- assertEquals(witness, tl);
- }
-
- {
- List tl = new TokenStream("%x{\"hello world.\", \"12y \"}").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
- List ol = new ArrayList<String>();
- ol.add("hello world.");
- ol.add("12y ");
- witness.add(new Token(Token.OPTION, ol));
- assertEquals(witness, tl);
- }
-
- {
- List tl = new TokenStream("%x{'opt}'}").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
- List ol = new ArrayList<String>();
- ol.add("opt}");
- witness.add(new Token(Token.OPTION, ol));
- assertEquals(witness, tl);
- }
+ {
+ List tl = new TokenStream("\\%\\(\\t\\)\\r\\n").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(new Token(Token.LITERAL, "%(\t)\r\n"));
+ assertEquals(witness, tl);
}
- @Test
- public void testSimpleP() throws ScanException {
- List tl = new TokenStream("%(hello %class{.4?})").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
- witness.add(new Token(Token.LITERAL, "hello "));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "class"));
- List ol = new ArrayList<String>();
- ol.add(".4?");
- witness.add(new Token(Token.OPTION, ol));
- witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
- assertEquals(witness, tl);
+ {
+ List tl = new TokenStream("\\\\%x").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(new Token(Token.LITERAL, "\\"));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
+ assertEquals(witness, tl);
}
- @Test
- public void testSimpleP2() throws ScanException {
- List tl = new TokenStream("X %a %-12.550(hello %class{.4?})").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(new Token(Token.LITERAL, "X "));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "a"));
- witness.add(new Token(Token.LITERAL, " "));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.FORMAT_MODIFIER, "-12.550"));
- witness.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
- witness.add(new Token(Token.LITERAL, "hello "));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "class"));
- List ol = new ArrayList<String>();
- ol.add(".4?");
- witness.add(new Token(Token.OPTION, ol));
- witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
- assertEquals(witness, tl);
+ {
+ List tl = new TokenStream("%x\\)").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
+ witness.add(new Token(Token.LITERAL, ")"));
+ assertEquals(witness, tl);
}
- @Test
- public void testMultipleRecursion() throws ScanException {
- List tl = new TokenStream("%-1(%d %45(%class %file))").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.FORMAT_MODIFIER, "-1"));
- witness.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "d"));
- witness.add(new Token(Token.LITERAL, " "));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.FORMAT_MODIFIER, "45"));
- witness.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "class"));
- witness.add(new Token(Token.LITERAL, " "));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "file"));
- witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
- witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
-
- assertEquals(witness, tl);
+ {
+ List tl = new TokenStream("%x\\_a").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
+ witness.add(new Token(Token.LITERAL, "a"));
+ assertEquals(witness, tl);
}
-
- @Test
- public void testNested() throws ScanException {
- List tl = new TokenStream("%(%a%(%b))").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "a"));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "b"));
- witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
- witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
-
- assertEquals(witness, tl);
-
+ {
+ List tl = new TokenStream("%x\\_%b").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "b"));
+ assertEquals(witness, tl);
}
-
- @Test
- public void testEscapedParanteheses() throws ScanException {
- {
- List tl = new TokenStream("\\(%h\\)").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(new Token(Token.LITERAL, "("));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "h"));
- witness.add(new Token(Token.LITERAL, ")"));
- assertEquals(witness, tl);
- }
- {
- List tl = new TokenStream("(%h\\)").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(new Token(Token.LITERAL, "("));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "h"));
- witness.add(new Token(Token.LITERAL, ")"));
- assertEquals(witness, tl);
- }
- {
- List tl = new TokenStream("%a(x\\)").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.COMPOSITE_KEYWORD, "a"));
- witness.add(new Token(Token.LITERAL, "x)"));
- assertEquals(witness, tl);
- }
- {
- List tl = new TokenStream("%a\\(x)").tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "a"));
- witness.add(new Token(Token.LITERAL, "(x"));
- witness.add(new Token(Token.RIGHT_PARENTHESIS));
-
- assertEquals(witness, tl);
- }
+ }
+
+ @Test
+ public void testOptions() throws ScanException {
+ {
+ List tl = new TokenStream("%x{t}").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
+ List ol = new ArrayList<String>();
+ ol.add("t");
+ witness.add(new Token(Token.OPTION, ol));
+ assertEquals(witness, tl);
}
- @Test
- public void testWindowsLikeBackSlashes() throws ScanException {
- List tl = new TokenStream("c:\\hello\\world.%i", new AlmostAsIsEscapeUtil()).tokenize();
-
- List<Token> witness = new ArrayList<Token>();
- witness.add(new Token(Token.LITERAL, "c:\\hello\\world."));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "i"));
- assertEquals(witness, tl);
+ {
+ List tl = new TokenStream("%x{t,y}").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
+ List ol = new ArrayList<String>();
+ ol.add("t");
+ ol.add("y");
+ witness.add(new Token(Token.OPTION, ol));
+ assertEquals(witness, tl);
}
- @Test
- public void compositedKeyword() throws ScanException {
- {
- List tl = new TokenStream("%d(A)", new AlmostAsIsEscapeUtil()).tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.COMPOSITE_KEYWORD, "d"));
- witness.add(new Token(Token.LITERAL, "A"));
- witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
- assertEquals(witness, tl);
- }
- {
- List tl = new TokenStream("a %subst(%b C)", new AlmostAsIsEscapeUtil()).tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(new Token(Token.LITERAL, "a "));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.COMPOSITE_KEYWORD, "subst"));
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.SIMPLE_KEYWORD, "b"));
- witness.add(new Token(Token.LITERAL, " C"));
- witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
- assertEquals(witness, tl);
- }
+ {
+ List tl = new TokenStream("%x{\"hello world.\", \"12y \"}").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
+ List ol = new ArrayList<String>();
+ ol.add("hello world.");
+ ol.add("12y ");
+ witness.add(new Token(Token.OPTION, ol));
+ assertEquals(witness, tl);
}
- @Test
- public void compositedKeywordFollowedByOptions() throws ScanException {
- {
- List tl = new TokenStream("%d(A){o}", new AlmostAsIsEscapeUtil()).tokenize();
- List<Token> witness = new ArrayList<Token>();
- witness.add(Token.PERCENT_TOKEN);
- witness.add(new Token(Token.COMPOSITE_KEYWORD, "d"));
- witness.add(new Token(Token.LITERAL, "A"));
- witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
- List ol = new ArrayList<String>();
- ol.add("o");
- witness.add(new Token(Token.OPTION, ol));
-
- assertEquals(witness, tl);
- }
+ {
+ List tl = new TokenStream("%x{'opt}'}").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "x"));
+ List ol = new ArrayList<String>();
+ ol.add("opt}");
+ witness.add(new Token(Token.OPTION, ol));
+ assertEquals(witness, tl);
+ }
+ }
+
+ @Test
+ public void testSimpleP() throws ScanException {
+ List tl = new TokenStream("%(hello %class{.4?})").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
+ witness.add(new Token(Token.LITERAL, "hello "));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "class"));
+ List ol = new ArrayList<String>();
+ ol.add(".4?");
+ witness.add(new Token(Token.OPTION, ol));
+ witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
+ assertEquals(witness, tl);
+ }
+
+ @Test
+ public void testSimpleP2() throws ScanException {
+ List tl = new TokenStream("X %a %-12.550(hello %class{.4?})").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(new Token(Token.LITERAL, "X "));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "a"));
+ witness.add(new Token(Token.LITERAL, " "));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.FORMAT_MODIFIER, "-12.550"));
+ witness.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
+ witness.add(new Token(Token.LITERAL, "hello "));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "class"));
+ List ol = new ArrayList<String>();
+ ol.add(".4?");
+ witness.add(new Token(Token.OPTION, ol));
+ witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
+ assertEquals(witness, tl);
+ }
+
+ @Test
+ public void testMultipleRecursion() throws ScanException {
+ List tl = new TokenStream("%-1(%d %45(%class %file))").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.FORMAT_MODIFIER, "-1"));
+ witness.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "d"));
+ witness.add(new Token(Token.LITERAL, " "));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.FORMAT_MODIFIER, "45"));
+ witness.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "class"));
+ witness.add(new Token(Token.LITERAL, " "));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "file"));
+ witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
+ witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
+
+ assertEquals(witness, tl);
+ }
+
+ @Test
+ public void testNested() throws ScanException {
+ List tl = new TokenStream("%(%a%(%b))").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "a"));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(Token.BARE_COMPOSITE_KEYWORD_TOKEN);
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "b"));
+ witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
+ witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
+
+ assertEquals(witness, tl);
+
+ }
+
+ @Test
+ public void testEscapedParanteheses() throws ScanException {
+ {
+ List tl = new TokenStream("\\(%h\\)").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(new Token(Token.LITERAL, "("));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "h"));
+ witness.add(new Token(Token.LITERAL, ")"));
+ assertEquals(witness, tl);
+ }
+ {
+ List tl = new TokenStream("(%h\\)").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(new Token(Token.LITERAL, "("));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "h"));
+ witness.add(new Token(Token.LITERAL, ")"));
+ assertEquals(witness, tl);
+ }
+ {
+ List tl = new TokenStream("%a(x\\)").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.COMPOSITE_KEYWORD, "a"));
+ witness.add(new Token(Token.LITERAL, "x)"));
+ assertEquals(witness, tl);
+ }
+ {
+ List tl = new TokenStream("%a\\(x)").tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "a"));
+ witness.add(new Token(Token.LITERAL, "(x"));
+ witness.add(new Token(Token.RIGHT_PARENTHESIS));
+
+ assertEquals(witness, tl);
+ }
+ }
+
+ @Test
+ public void testWindowsLikeBackSlashes() throws ScanException {
+ List tl = new TokenStream("c:\\hello\\world.%i",
+ new AlmostAsIsEscapeUtil()).tokenize();
+
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(new Token(Token.LITERAL, "c:\\hello\\world."));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "i"));
+ assertEquals(witness, tl);
+ }
+
+ @Test
+ public void compositedKeyword() throws ScanException {
+ {
+ List tl = new TokenStream("%d(A)",
+ new AlmostAsIsEscapeUtil()).tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.COMPOSITE_KEYWORD, "d"));
+ witness.add(new Token(Token.LITERAL, "A"));
+ witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
+ assertEquals(witness, tl);
+ }
+ {
+ List tl = new TokenStream("a %subst(%b C)",
+ new AlmostAsIsEscapeUtil()).tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(new Token(Token.LITERAL, "a "));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.COMPOSITE_KEYWORD, "subst"));
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.SIMPLE_KEYWORD, "b"));
+ witness.add(new Token(Token.LITERAL, " C"));
+ witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
+ assertEquals(witness, tl);
+ }
+ }
+
+ @Test
+ public void compositedKeywordFollowedByOptions() throws ScanException {
+ {
+ List tl = new TokenStream("%d(A){o}",
+ new AlmostAsIsEscapeUtil()).tokenize();
+ List<Token> witness = new ArrayList<Token>();
+ witness.add(Token.PERCENT_TOKEN);
+ witness.add(new Token(Token.COMPOSITE_KEYWORD, "d"));
+ witness.add(new Token(Token.LITERAL, "A"));
+ witness.add(Token.RIGHT_PARENTHESIS_TOKEN);
+ List ol = new ArrayList<String>();
+ ol.add("o");
+ witness.add(new Token(Token.OPTION, ol));
+
+ assertEquals(witness, tl);
}
+ }
}
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/read/CyclicBufferAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/read/CyclicBufferAppenderTest.java
index d79bd74..d0a6cf1 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/read/CyclicBufferAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/read/CyclicBufferAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,29 +20,30 @@ import static org.junit.Assert.assertEquals;
public class CyclicBufferAppenderTest {
- private CyclicBufferAppender<String> cyclicBufferAppender;
+ private CyclicBufferAppender<String> cyclicBufferAppender;
- @Before
- public void before() {
- cyclicBufferAppender = new CyclicBufferAppender<String>();
- cyclicBufferAppender.start();
- }
+ @Before
+ public void before() {
+ cyclicBufferAppender = new CyclicBufferAppender<String>();
+ cyclicBufferAppender.start();
+ }
- @Test
+ @Test
public void reset() {
- cyclicBufferAppender.append("foobar");
- assertEquals(1, cyclicBufferAppender.getLength());
- cyclicBufferAppender.reset();
- assertEquals(0, cyclicBufferAppender.getLength());
- }
-
- @Test
- public void genericGet() {
- cyclicBufferAppender.append("Some string");
- // get() now has type information, assigning to String should work without cast.
- String foo = cyclicBufferAppender.get(0);
- assertEquals("Some string", foo);
- }
+ cyclicBufferAppender.append("foobar");
+ assertEquals(1, cyclicBufferAppender.getLength());
+ cyclicBufferAppender.reset();
+ assertEquals(0, cyclicBufferAppender.getLength());
+ }
+
+ @Test
+ public void genericGet() {
+ cyclicBufferAppender.append("Some string");
+ // get() now has type information, assigning to String should work without cast.
+ String foo = cyclicBufferAppender.get(0);
+ assertEquals("Some string", foo);
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/recovery/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/recovery/PackageTest.java
index 8a190bd..c16e5a6 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/recovery/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/recovery/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ RecoveryCoordinatorTest.class, ResilientOutputStreamTest.class })
-public class PackageTest {
+ at SuiteClasses({RecoveryCoordinatorTest.class, ResilientOutputStreamTest.class})
+public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/recovery/RecoveryCoordinatorTest.java b/logback-core/src/test/java/ch/qos/logback/core/recovery/RecoveryCoordinatorTest.java
index d443a5c..05458f6 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/recovery/RecoveryCoordinatorTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/recovery/RecoveryCoordinatorTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,56 +19,61 @@ import org.junit.Test;
public class RecoveryCoordinatorTest {
- long now = System.currentTimeMillis();
- RecoveryCoordinator rc = new RecoveryCoordinator(now);
+ @Test
+ public void recoveryNotNeededAfterInit() {
+ RecoveryCoordinator rc = new RecoveryCoordinator();
+ assertTrue(rc.isTooSoon());
+ }
- @Test
- public void recoveryNotNeededAfterInit() {
- RecoveryCoordinator rc = new RecoveryCoordinator();
- assertTrue(rc.isTooSoon());
- }
+ @Test
+ public void recoveryNotNeededIfAsleepForLessThanBackOffTime() throws InterruptedException {
+ RecoveryCoordinator rc = new RecoveryCoordinator();
+ Thread.sleep(RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN / 2);
+ assertTrue(rc.isTooSoon());
+ }
- @Test
- public void recoveryNotNeededIfAsleepForLessThanBackOffTime() throws InterruptedException {
- rc.setCurrentTime(now + RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN / 2);
- assertTrue(rc.isTooSoon());
- }
-
- @Test
- public void recoveryNeededIfAsleepForMoreThanBackOffTime() throws InterruptedException {
- rc.setCurrentTime(now + RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN + 20);
- assertFalse(rc.isTooSoon());
- }
+ @Test
+ public void recoveryNeededIfAsleepForMoreThanBackOffTime() throws InterruptedException {
+ RecoveryCoordinator rc = new RecoveryCoordinator();
+ Thread.sleep(RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN + 20);
+ assertFalse(rc.isTooSoon());
+ }
- @Test
- public void recoveryNotNeededIfCurrentTimeSetToBackOffTime() throws InterruptedException {
- rc.setCurrentTime(now + RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN);
- assertTrue(rc.isTooSoon());
- }
+ @Test
+ public void recoveryNotNeededIfCurrentTimeSetToBackOffTime() throws InterruptedException {
+ RecoveryCoordinator rc = new RecoveryCoordinator();
+ long now = System.currentTimeMillis();
+ rc.setCurrentTime(now + RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN);
+ assertTrue(rc.isTooSoon());
+ }
- @Test
- public void recoveryNeededIfCurrentTimeSetToExceedBackOffTime() {
- rc.setCurrentTime(now + RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN + 1);
- assertFalse(rc.isTooSoon());
- }
+ @Test
+ public void recoveryNeededIfCurrentTimeSetToExceedBackOffTime() {
+ RecoveryCoordinator rc = new RecoveryCoordinator();
+ long now = System.currentTimeMillis();
+ rc.setCurrentTime(now + RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN + 1);
+ assertFalse(rc.isTooSoon());
+ }
- @Test
- public void recoveryConditionDetectedEvenAfterReallyLongTimesBetweenRecovery() {
- // Since backoff time quadruples whenever recovery is needed,
- // we double the offset on each for-loop iteration, causing
- // every other iteration to trigger recovery.
+ @Test
+ public void recoveryConditionDetectedEvenAfterReallyLongTimesBetweenRecovery() {
+ // Since backoff time quadruples whenever recovery is needed,
+ // we double the offset on each for-loop iteration, causing
+ // every other iteration to trigger recovery.
- long offset = RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN;
+ RecoveryCoordinator rc = new RecoveryCoordinator();
+ long now = System.currentTimeMillis();
+ long offset = RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN;
- for (int i = 0; i < 16; i++) {
- rc.setCurrentTime(now + offset);
+ for (int i = 0; i < 16; i++) {
+ rc.setCurrentTime(now + offset);
- if (i % 2 == 0) {
- assertTrue("recovery should've been needed at " + offset, rc.isTooSoon());
- } else {
- assertFalse("recovery should NOT have been needed at " + offset, rc.isTooSoon());
- }
- offset *= 2;
- }
+ if (i % 2 == 0) {
+ assertTrue("recovery should've been needed at " + offset, rc.isTooSoon());
+ } else {
+ assertFalse("recovery should NOT have been needed at " + offset, rc.isTooSoon());
+ }
+ offset *= 2;
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/recovery/ResilientOutputStreamTest.java b/logback-core/src/test/java/ch/qos/logback/core/recovery/ResilientOutputStreamTest.java
index d0b99ed..1c8f843 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/recovery/ResilientOutputStreamTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/recovery/ResilientOutputStreamTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,52 +13,53 @@
*/
package ch.qos.logback.core.recovery;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
-import java.io.File;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-
import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.util.CoreTestConstants;
+import ch.qos.logback.core.util.StatusPrinter;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class ResilientOutputStreamTest {
- int diff = RandomUtil.getPositiveInt();
- Context context = new ContextBase();
+ int diff = RandomUtil.getPositiveInt();
+ Context context = new ContextBase();
- @BeforeClass
- public static void setUp() {
- File file = new File(CoreTestConstants.OUTPUT_DIR_PREFIX);
- file.mkdirs();
- }
+ @BeforeClass
+ public static void setUp() {
+ File file = new File(CoreTestConstants.OUTPUT_DIR_PREFIX);
+ file.mkdirs();
+ }
- @Test
- public void verifyRecuperationAfterFailure() throws Exception {
- File file = new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "resilient" + diff + ".log");
- ResilientFileOutputStream rfos = new ResilientFileOutputStream(file, true);
- rfos.setContext(context);
+ @Test
+ public void verifyRecuperationAfterFailure() throws Exception {
+ File file = new File(CoreTestConstants.OUTPUT_DIR_PREFIX+"resilient"+diff+".log");
+ ResilientFileOutputStream rfos = new ResilientFileOutputStream(file, true);
+ rfos.setContext(context);
- ResilientFileOutputStream spy = spy(rfos);
+ ResilientFileOutputStream spy = spy(rfos);
- spy.write("a".getBytes());
- spy.flush();
+ spy.write("a".getBytes());
+ spy.flush();
- spy.getChannel().close();
- spy.write("b".getBytes());
- spy.flush();
- Thread.sleep(RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN + 10);
- spy.write("c".getBytes());
- spy.flush();
- verify(spy).openNewOutputStream();
+ spy.getChannel().close();
+ spy.write("b".getBytes());
+ spy.flush();
+ Thread.sleep(RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN+10);
+ spy.write("c".getBytes());
+ spy.flush();
+ verify(spy).openNewOutputStream();
- }
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/CollisionDetectionTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/CollisionDetectionTest.java
deleted file mode 100644
index 0b80d8d..0000000
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/CollisionDetectionTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package ch.qos.logback.core.rolling;
-
-import static ch.qos.logback.core.CoreConstants.FA_FILENAME_COLLISION_MAP;
-import static ch.qos.logback.core.util.CoreTestConstants.OUTPUT_DIR_PREFIX;
-
-import java.util.Map;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import ch.qos.logback.core.Context;
-import ch.qos.logback.core.ContextBase;
-import ch.qos.logback.core.FileAppender;
-import ch.qos.logback.core.encoder.NopEncoder;
-import ch.qos.logback.core.status.Status;
-import ch.qos.logback.core.status.StatusChecker;
-import ch.qos.logback.core.testUtil.RandomUtil;
-import ch.qos.logback.core.util.StatusPrinter;
-
-public class CollisionDetectionTest {
-
- Context context = new ContextBase();
- StatusChecker statusChecker = new StatusChecker(context);
- int diff = RandomUtil.getPositiveInt();
- protected String randomOutputDir = OUTPUT_DIR_PREFIX + diff + "/";
-
- @Before
- public void setUp() throws Exception {
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
-
- FileAppender<String> buildFileAppender(String name, String filenameSuffix) {
- FileAppender<String> fileAppender = new FileAppender<String>();
- fileAppender.setName(name);
- fileAppender.setContext(context);
- fileAppender.setFile(randomOutputDir+filenameSuffix);
- fileAppender.setEncoder(new NopEncoder<String>());
- return fileAppender;
- }
-
- RollingFileAppender<String> buildRollingFileAppender(String name, String filenameSuffix, String patternSuffix) {
- RollingFileAppender<String> rollingFileAppender = new RollingFileAppender<String>();
- rollingFileAppender.setName(name);
- rollingFileAppender.setContext(context);
- rollingFileAppender.setFile(randomOutputDir+filenameSuffix);
- rollingFileAppender.setEncoder(new NopEncoder<String>());
-
- TimeBasedRollingPolicy<String> tbrp = new TimeBasedRollingPolicy<String>();
- tbrp.setContext(context);
- tbrp.setFileNamePattern(randomOutputDir+patternSuffix);
- tbrp.setParent(rollingFileAppender);
- //tbrp.timeBasedFileNamingAndTriggeringPolicy = new DefaultTimeBasedFileNamingAndTriggeringPolicy<Object>();
- //tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(givenTime);
- rollingFileAppender.setRollingPolicy(tbrp);
- tbrp.start();
-
-
- return rollingFileAppender;
- }
-
-
- @Test
- public void collisionImpossibleForSingleAppender() {
- FileAppender<String> fileAppender = buildFileAppender("FA", "collisionImpossibleForSingleAppender");
- fileAppender.start();
- statusChecker.assertIsErrorFree();
-
- }
-
- @Test
- public void appenderStopShouldClearEntryInCollisionMap() {
- String key = "FA";
- FileAppender<String> fileAppender = buildFileAppender(key, "collisionImpossibleForSingleAppender");
- fileAppender.start();
- assertCollisionMapHasEntry(FA_FILENAME_COLLISION_MAP, key);
- fileAppender.stop();
- assertCollisionMapHasNoEntry(FA_FILENAME_COLLISION_MAP, key);
- statusChecker.assertIsErrorFree();
-
-
- }
-
- private void assertCollisionMapHasEntry(String mapName, String key) {
- @SuppressWarnings("unchecked")
- Map<String, ?> map = (Map<String, ?>) context.getObject(mapName);
- Assert.assertNotNull(map);
- Assert.assertNotNull(map.get(key));
- }
- private void assertCollisionMapHasNoEntry(String mapName, String key) {
- @SuppressWarnings("unchecked")
- Map<String, ?> map = (Map<String, ?>) context.getObject(mapName);
- Assert.assertNotNull(map);
- Assert.assertNull(map.get(key));
- }
-
- @Test
- public void collisionWithTwoFileAppenders() {
- String suffix = "collisionWithToFileAppenders";
-
- FileAppender<String> fileAppender1 = buildFileAppender("FA1", suffix);
- fileAppender1.start();
-
- FileAppender<String> fileAppender2 = buildFileAppender("FA2", suffix);
- fileAppender2.start();
- statusChecker.assertContainsMatch(Status.ERROR, "'File' option has the same value");
- //StatusPrinter.print(context);
- }
-
- @Test
- public void collisionWith_FA_RFA() {
- String suffix = "collisionWith_FA_RFA";
-
- FileAppender<String> fileAppender1 = buildFileAppender("FA", suffix);
- fileAppender1.start();
-
- RollingFileAppender<String> rollingfileAppender = buildRollingFileAppender("RFA", suffix, "bla-%d.log");
- rollingfileAppender.start();
- StatusPrinter.print(context);
- statusChecker.assertContainsMatch(Status.ERROR, "'File' option has the same value");
- }
-
- @Test
- public void collisionWith_2RFA() {
- String suffix = "collisionWith_2RFA";
-
- RollingFileAppender<String> rollingfileAppender1 = buildRollingFileAppender("RFA1", suffix, "bla-%d.log");
- rollingfileAppender1.start();
- RollingFileAppender<String> rollingfileAppender2 = buildRollingFileAppender("RFA1", suffix, "bla-%d.log");
- rollingfileAppender2.start();
-
- StatusPrinter.print(context);
- statusChecker.assertContainsMatch(Status.ERROR, "'FileNamePattern' option has the same value");
- }
-
-}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/ConfigParameters.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/ConfigParameters.java
deleted file mode 100644
index 71c73b2..0000000
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/ConfigParameters.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package ch.qos.logback.core.rolling;
-
-class ConfigParameters {
-
- long simulatedTime;
- int maxHistory;
- int simulatedNumberOfPeriods;
- int startInactivity = -1;
- int numInactivityPeriods;
- String fileNamePattern;
- long periodDurationInMillis = TimeBasedRollingWithArchiveRemoval_Test.MILLIS_IN_DAY;
- long sizeCap;
-
- ConfigParameters(long simulatedTime) {
- this.simulatedTime = simulatedTime;
- }
-
- ConfigParameters maxHistory(int maxHistory) {
- this.maxHistory = maxHistory;
- return this;
- }
-
- ConfigParameters simulatedNumberOfPeriods(int simulatedNumberOfPeriods) {
- this.simulatedNumberOfPeriods = simulatedNumberOfPeriods;
- return this;
- }
-
- ConfigParameters startInactivity(int startInactivity) {
- this.startInactivity = startInactivity;
- return this;
- }
-
- ConfigParameters numInactivityPeriods(int numInactivityPeriods) {
- this.numInactivityPeriods = numInactivityPeriods;
- return this;
- }
-
- ConfigParameters fileNamePattern(String fileNamePattern) {
- this.fileNamePattern = fileNamePattern;
- return this;
- }
-
- ConfigParameters periodDurationInMillis(long periodDurationInMillis) {
- this.periodDurationInMillis = periodDurationInMillis;
- return this;
- }
-
- ConfigParameters sizeCap(long sizeCap) {
- this.sizeCap = sizeCap;
- return this;
- }
-}
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/DefaultRolloverChecker.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/DefaultRolloverChecker.java
index 256be39..6603812 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/DefaultRolloverChecker.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/DefaultRolloverChecker.java
@@ -1,18 +1,19 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
- * or (per the licensee's choosing)
+ * or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
package ch.qos.logback.core.rolling;
+
import ch.qos.logback.core.util.Compare;
import ch.qos.logback.core.util.CoreTestConstants;
@@ -23,30 +24,32 @@ import static org.junit.Assert.assertTrue;
public class DefaultRolloverChecker implements RolloverChecker {
- final String testId;
- final boolean withCompression;
- final String compressionSuffix;
+ final String testId;
+ final boolean withCompression;
+ final String compressionSuffix;
- public DefaultRolloverChecker(String testId, boolean withCompression, String compressionSuffix) {
- this.testId = testId;
- this.withCompression = withCompression;
- this.compressionSuffix = compressionSuffix;
- }
+ public DefaultRolloverChecker(String testId, boolean withCompression, String compressionSuffix) {
+ this.testId = testId;
+ this.withCompression = withCompression;
+ this.compressionSuffix = compressionSuffix;
+ }
- public void check(List<String> expectedFilenameList) throws IOException {
+ public void check(List<String> expectedFilenameList) throws IOException {
- int i = 0;
- for (String fn : expectedFilenameList) {
- String suffix = withCompression ? addGZIfNotLast(expectedFilenameList, i, compressionSuffix) : "";
+ int i = 0;
+ for (String fn : expectedFilenameList) {
+ String suffix = withCompression ? addGZIfNotLast(expectedFilenameList, i, compressionSuffix) : "";
- String witnessFileName = CoreTestConstants.TEST_SRC_PREFIX + "witness/rolling/tbr-" + testId + "." + i + suffix;
- assertTrue(Compare.compare(fn, witnessFileName));
- i++;
- }
+ String witnessFileName = CoreTestConstants.TEST_SRC_PREFIX + "witness/rolling/tbr-" + testId + "." + i + suffix;
+ assertTrue(Compare.compare(fn, witnessFileName));
+ i++;
}
+ }
- String addGZIfNotLast(List<String> expectedFilenameList, int i, String suff) {
- int lastIndex = expectedFilenameList.size() - 1;
- return (i != lastIndex) ? suff : "";
- }
+ String addGZIfNotLast(List<String> expectedFilenameList, int i, String suff) {
+ int lastIndex = expectedFilenameList.size() - 1;
+ return (i != lastIndex) ? suff : "";
+ }
}
+
+
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/FileMatchFunction.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/FileMatchFunction.java
index e567dda..eb59cd5 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/FileMatchFunction.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/FileMatchFunction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,5 +24,5 @@ import java.io.File;
*/
public interface FileMatchFunction {
- boolean match(File f, String pattern);
+ boolean match(File f, String pattern);
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/FileOpener.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/FileOpener.java
index 9ca095d..4cd7344 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/FileOpener.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/FileOpener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,17 +16,18 @@ package ch.qos.logback.core.rolling;
import java.io.FileInputStream;
import java.io.InputStream;
+
/**
* Keep the file "output/test.log open for 10 seconds so that we can test
* RollingFileAppender's ability to roll file open by another process.
* @author Ceki Gülcü
*/
public class FileOpener {
- public static void main(String[] args) throws Exception {
- InputStream is = new FileInputStream("output/test.log");
- is.read();
- Thread.sleep(10000);
- is.close();
- System.out.println("Exiting FileOpener");
- }
+ public static void main(String[] args) throws Exception {
+ InputStream is = new FileInputStream("output/test.log");
+ is.read();
+ Thread.sleep(10000);
+ is.close();
+ System.out.println("Exiting FileOpener");
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/JVMExitBeforeCompressionISDoneTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/JVMExitBeforeCompressionISDoneTest.java
deleted file mode 100644
index dcdbfd5..0000000
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/JVMExitBeforeCompressionISDoneTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package ch.qos.logback.core.rolling;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.util.Date;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import ch.qos.logback.core.CoreConstants;
-import ch.qos.logback.core.encoder.EchoEncoder;
-import ch.qos.logback.core.hook.DelayingShutdownHook;
-import ch.qos.logback.core.status.OnConsoleStatusListener;
-import ch.qos.logback.core.testUtil.RandomUtil;
-import ch.qos.logback.core.util.StatusListenerConfigHelper;
-import ch.qos.logback.core.util.StatusPrinter;
- at Ignore
-public class JVMExitBeforeCompressionISDoneTest extends ScaffoldingForRollingTests {
-
- RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
- TimeBasedRollingPolicy<Object> tbrp = new TimeBasedRollingPolicy<Object>();
- DelayingShutdownHook delayingShutdownHook = new DelayingShutdownHook();
-
- static final long FRI_2016_05_13_T_170415_GMT = 1463159055630L;
-
- EchoEncoder<Object> encoder = new EchoEncoder<Object>();
-
- @Before
- @Override
- public void setUp() {
- super.setUp();
- StatusListenerConfigHelper.addOnConsoleListenerInstance(context, new OnConsoleStatusListener());
- delayingShutdownHook.setContext(context);
- initRFA(rfa);
- }
-
- void initRFA(RollingFileAppender<Object> rfa) {
- rfa.setContext(context);
- rfa.setEncoder(encoder);
- }
-
- void initTRBP(RollingFileAppender<Object> rfa, TimeBasedRollingPolicy<Object> tbrp, String filenamePattern, long givenTime) {
- tbrp.setContext(context);
- tbrp.setFileNamePattern(filenamePattern);
- tbrp.setParent(rfa);
- tbrp.timeBasedFileNamingAndTriggeringPolicy = new DefaultTimeBasedFileNamingAndTriggeringPolicy<Object>();
- tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(givenTime);
- rfa.setRollingPolicy(tbrp);
- tbrp.start();
- rfa.start();
- }
-
- @After
- public void tearDown() throws Exception {
- StatusPrinter.print(context);
- }
-
- @Ignore
- @Test
- public void test1() {
- Thread shutdownThread = new Thread(delayingShutdownHook);
- Runtime.getRuntime().addShutdownHook(shutdownThread);
-
- String patternPrefix = "test1";
- String compressionSuffix = ".zip";
-
- this.currentTime = FRI_2016_05_13_T_170415_GMT;
-
- Date d = new Date(FRI_2016_05_13_T_170415_GMT); //WED_2016_03_23_T_230705_CET);
- System.out.println(d);
- System.out.print(d.getTime());
-
- int ticksPerHour = 100;
- int hours = 7;
- int totalTicks = ticksPerHour*hours;
- long singleTickDuration = CoreConstants.MILLIS_IN_ONE_HOUR/ticksPerHour;
-
- String fileNamePatternStr = randomOutputDir + patternPrefix + "-%d{" + DATE_PATTERN_BY_DAY + ", GMT}" + compressionSuffix;
- initTRBP(rfa, tbrp, fileNamePatternStr, currentTime);
-
- incCurrentTime(singleTickDuration);
- tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
-
- for (int i = 0; i < totalTicks; i++) {
- StringBuilder sb = new StringBuilder(1000);
- sb.append("Hello");
- for(int j = 0; j < 100; j++) {
- sb.append(RandomUtil.getPositiveInt());
- }
- sb.append(i);
-
- rfa.doAppend(sb.toString());
- addExpectedFileNamedIfItsTime_ByDate(fileNamePatternStr);
- incCurrentTime(singleTickDuration);
- tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
- }
-
-
-
-
- String nameOfExpectedZipFile = randomOutputDir + patternPrefix+"-2016-05-13.zip";;
-
- // File expectedZipFile = new File(nameOfExpectedZipFile);
- // assertTrue("expecting file ["+nameOfExpectedZipFile+"] to exist", expectedZipFile.exists());
- // File[] files = getFilesInDirectory(randomOutputDir);
- // assertEquals(2, files.length);
- }
-
-}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/MultiThreadedRollingTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/MultiThreadedRollingTest.java
index f1a40db..2758a30 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/MultiThreadedRollingTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/MultiThreadedRollingTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,7 +25,6 @@ import java.io.IOException;
import java.io.OutputStream;
import ch.qos.logback.core.testUtil.EnvUtilForTests;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -39,248 +38,255 @@ import ch.qos.logback.core.encoder.Encoder;
import ch.qos.logback.core.status.StatusChecker;
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.util.CoreTestConstants;
-import ch.qos.logback.core.util.FileSize;
import ch.qos.logback.core.util.StatusPrinter;
public class MultiThreadedRollingTest {
- final static int NUM_THREADS = 10;
- final static int TOTAL_DURATION = 600;
- RunnableWithCounterAndDone[] runnableArray;
-
- Encoder<Object> encoder;
- Context context = new ContextBase();
-
- static String VERIFY_SH = "verify.sh";
+ final static int NUM_THREADS = 10;
+ final static int TOTAL_DURATION = 600;
+ RunnableWithCounterAndDone[] runnableArray;
- int diff = RandomUtil.getPositiveInt();
- String outputDirStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "multi-" + diff + "/";
+ Encoder<Object> encoder;
+ Context context = new ContextBase();
- RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
+ static String VERIFY_SH = "verify.sh";
- String pathToBash = EnvUtilForTests.getPathToBash();
- OutputStream scriptOS;
+ int diff = RandomUtil.getPositiveInt();
+ String outputDirStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "multi-" + diff
+ + "/";
- @Before
- public void setUp() throws Exception {
- encoder = new EchoEncoder<Object>();
- File outputDir = new File(outputDirStr);
- outputDir.mkdirs();
+ RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
- System.out.println("Output dir [" + outputDirStr + "]");
+ String pathToBash = EnvUtilForTests.getPathToBash();
+ OutputStream scriptOS;
- scriptOS = openScript();
+ @Before
+ public void setUp() throws Exception {
+ encoder = new EchoEncoder<Object>();
+ File outputDir = new File(outputDirStr);
+ outputDir.mkdirs();
- rfa.setName("rolling");
- rfa.setEncoder(encoder);
- rfa.setContext(context);
- rfa.setFile(outputDirStr + "output.log");
-
- }
+ System.out.println("Output dir [" + outputDirStr + "]");
- void close(OutputStream os) {
- if (os != null) {
- try {
- os.close();
- } catch (IOException e) {
- }
- }
- }
+ scriptOS = openScript();
- @After
- public void tearDown() throws Exception {
- rfa.stop();
- }
+ rfa.setName("rolling");
+ rfa.setEncoder(encoder);
+ rfa.setContext(context);
+ rfa.setFile(outputDirStr + "output.log");
- public void setUpTimeBasedTriggeringPolicy(RollingFileAppender<Object> rfa) {
- String datePattern = "yyyy-MM-dd'T'HH_mm_ss_SSS";
- TimeBasedRollingPolicy tbrp = new TimeBasedRollingPolicy();
- tbrp.setFileNamePattern(outputDirStr + "test-%d{" + datePattern + "}");
- tbrp.setContext(context);
- tbrp.setParent(rfa);
- tbrp.start();
+ }
- rfa.setRollingPolicy(tbrp);
- rfa.start();
+ void close(OutputStream os) {
+ if (os != null) {
+ try {
+ os.close();
+ } catch (IOException e) {
+ }
}
-
- public void setUpSizeBasedTriggeringPolicy(RollingFileAppender<Object> rfa) {
- SizeBasedTriggeringPolicy<Object> zbtp = new SizeBasedTriggeringPolicy<Object>();
- zbtp.setContext(context);
- zbtp.setMaxFileSize(FileSize.valueOf("100KB"));
-
- zbtp.start();
- rfa.setTriggeringPolicy(zbtp);
-
- FixedWindowRollingPolicy fwrp = new FixedWindowRollingPolicy();
- fwrp.setContext(context);
- fwrp.setFileNamePattern(outputDirStr + "test-%i.log");
- fwrp.setMaxIndex(20);
- fwrp.setMinIndex(0);
- fwrp.setParent(rfa);
- fwrp.start();
- rfa.setRollingPolicy(fwrp);
- rfa.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ rfa.stop();
+ }
+
+ public void setUpTimeBasedTriggeringPolicy(RollingFileAppender<Object> rfa) {
+ String datePattern = "yyyy-MM-dd'T'HH_mm_ss_SSS";
+ TimeBasedRollingPolicy tbrp = new TimeBasedRollingPolicy();
+ tbrp.setFileNamePattern(outputDirStr + "test-%d{" + datePattern + "}");
+ tbrp.setContext(context);
+ tbrp.setParent(rfa);
+ tbrp.start();
+
+ rfa.setRollingPolicy(tbrp);
+ rfa.start();
+ }
+
+ public void setUpSizeBasedTriggeringPolicy(RollingFileAppender<Object> rfa) {
+ SizeBasedTriggeringPolicy<Object> zbtp = new SizeBasedTriggeringPolicy<Object>();
+ zbtp.setContext(context);
+ zbtp.setMaxFileSize("100KB");
+
+ zbtp.start();
+ rfa.setTriggeringPolicy(zbtp);
+
+ FixedWindowRollingPolicy fwrp = new FixedWindowRollingPolicy();
+ fwrp.setContext(context);
+ fwrp.setFileNamePattern(outputDirStr + "test-%i.log");
+ fwrp.setMaxIndex(20);
+ fwrp.setMinIndex(0);
+ fwrp.setParent(rfa);
+ fwrp.start();
+ rfa.setRollingPolicy(fwrp);
+ rfa.start();
+ }
+
+ RunnableWithCounterAndDone[] buildRunnableArray(boolean withDelay) {
+ RunnableWithCounterAndDone[] runnableArray = new RunnableWithCounterAndDone[NUM_THREADS];
+ for (int i = 0; i < NUM_THREADS; i++) {
+ runnableArray[i] = new RFARunnable(i, rfa, withDelay);
}
-
- RunnableWithCounterAndDone[] buildRunnableArray(boolean withDelay) {
- RunnableWithCounterAndDone[] runnableArray = new RunnableWithCounterAndDone[NUM_THREADS];
- for (int i = 0; i < NUM_THREADS; i++) {
- runnableArray[i] = new RFARunnable(i, rfa, withDelay);
+ return runnableArray;
+ }
+
+ OutputStream openScript() throws IOException {
+ return new FileOutputStream(outputDirStr + VERIFY_SH);
+ }
+
+ @Test
+ public void multiThreadedTimedBased() throws InterruptedException,
+ IOException {
+ setUpTimeBasedTriggeringPolicy(rfa);
+ executeHarness(TOTAL_DURATION, false);
+ printScriptForTimeBased();
+ verify();
+ }
+
+ int testFileCount() {
+ File outputDir = new File(outputDirStr);
+ FilenameFilter filter = new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ if (name.matches("test-\\d{1,2}.log")) {
+ return true;
}
- return runnableArray;
+ return false;
+ }
+ };
+ File[] files = outputDir.listFiles(filter);
+ return files.length;
+ }
+
+ void verify() throws IOException, InterruptedException {
+ close(scriptOS);
+ // no point in this test if we don't have bash
+ if (pathToBash == null) {
+ return;
}
-
- OutputStream openScript() throws IOException {
- return new FileOutputStream(outputDirStr + VERIFY_SH);
+ ProcessBuilder pb = new ProcessBuilder();
+ pb.command(pathToBash, VERIFY_SH);
+ pb.directory(new File(outputDirStr));
+ Process process = pb.start();
+ process.waitFor();
+ int exitCode = process.exitValue();
+
+ assertEquals(SUCCESSFUL_EXIT_CODE, exitCode);
+ System.out
+ .println("External script based verification returned with exit code "
+ + exitCode);
+ }
+
+ @Test
+ public void multiThreadedSizeBased() throws InterruptedException, IOException {
+ setUpSizeBasedTriggeringPolicy(rfa);
+ // on a fast machine with a fast hard disk, if the tests runs for too
+ // long the MAX_WINDOW_SIZE is reached, resulting in data loss which
+ // we cannot test for.
+ executeHarness(TOTAL_DURATION, true);
+ int numFiles = testFileCount();
+ printScriptForSizeBased(numFiles);
+ verify();
+ }
+
+ private void printScriptHeader(String type) throws IOException {
+ out("# ====================================================");
+ out("# A script to check the exactness of the output ");
+ out("# produced by " + type + " test");
+ out("# ====================================================");
+ out("# ");
+ }
+
+ private void printCommonScriptCore() throws IOException {
+ out("");
+ out("for t in $(seq 0 1 " + (NUM_THREADS - 1) + ")");
+ out("do");
+ out(" echo \"Testing results of thread $t\"");
+ out(" grep \"$t \" aggregated | cut -d ' ' -f 2 > ${t}-sample");
+ out(" for j in $(seq 1 1 ${end[$t]}); do echo $j; done > ${t}-witness");
+ out(" diff -q -w ${t}-sample ${t}-witness;");
+ out(" res=$?");
+ out(" if [ $res != \"0\" ]; then");
+ out(" echo \"FAILED for $t\"");
+ out(" exit " + FAILURE_EXIT_CODE);
+ out(" fi");
+ out("done");
+ out("");
+ out("exit " + SUCCESSFUL_EXIT_CODE);
+ }
+
+ private void printScriptForTimeBased() throws IOException {
+ printScriptHeader("TimeBased");
+ for (int i = 0; i < NUM_THREADS; i++) {
+ out("end[" + i + "]=" + this.runnableArray[i].getCounter());
}
+ out("");
+ out("rm aggregated");
+ out("cat test* output.log >> aggregated");
+ printCommonScriptCore();
- @Test
- public void multiThreadedTimedBased() throws InterruptedException, IOException {
- setUpTimeBasedTriggeringPolicy(rfa);
- executeHarness(TOTAL_DURATION, false);
- printScriptForTimeBased();
- verify();
- }
+ }
- int testFileCount() {
- File outputDir = new File(outputDirStr);
- FilenameFilter filter = new FilenameFilter() {
- public boolean accept(File dir, String name) {
- if (name.matches("test-\\d{1,2}.log")) {
- return true;
- }
- return false;
- }
- };
- File[] files = outputDir.listFiles(filter);
- return files.length;
- }
+ private void printScriptForSizeBased(int numfiles) throws IOException {
+ printScriptHeader("SizeBased");
- void verify() throws IOException, InterruptedException {
- close(scriptOS);
- // no point in this test if we don't have bash
- if (pathToBash == null) {
- return;
- }
- ProcessBuilder pb = new ProcessBuilder();
- pb.command(pathToBash, VERIFY_SH);
- pb.directory(new File(outputDirStr));
- Process process = pb.start();
- process.waitFor();
- int exitCode = process.exitValue();
-
- assertEquals(SUCCESSFUL_EXIT_CODE, exitCode);
- System.out.println("External script based verification returned with exit code " + exitCode);
+ for (int i = 0; i < NUM_THREADS; i++) {
+ out("end[" + i + "]=" + this.runnableArray[i].getCounter());
}
-
- @Test
- public void multiThreadedSizeBased() throws InterruptedException, IOException {
- setUpSizeBasedTriggeringPolicy(rfa);
- // on a fast machine with a fast hard disk, if the tests runs for too
- // long the MAX_WINDOW_SIZE is reached, resulting in data loss which
- // we cannot test for.
- executeHarness(TOTAL_DURATION, true);
- int numFiles = testFileCount();
- printScriptForSizeBased(numFiles);
- verify();
+ out("");
+ out("rm aggregated");
+ out("for i in $(seq " + (numfiles - 1)
+ + " -1 0); do cat test-$i.log >> aggregated; done");
+ out("cat output.log >> aggregated");
+ out("");
+ printCommonScriptCore();
+ }
+
+ private void out(String msg) throws IOException {
+ scriptOS.write(msg.getBytes());
+ scriptOS.write("\n".getBytes());
+ }
+
+ private void executeHarness(int duration, boolean withDelay)
+ throws InterruptedException {
+ MultiThreadedHarness multiThreadedHarness = new MultiThreadedHarness(
+ duration);
+ this.runnableArray = buildRunnableArray(withDelay);
+ multiThreadedHarness.execute(runnableArray);
+
+ StatusChecker checker = new StatusChecker(context.getStatusManager());
+ if (!checker.isErrorFree(0)) {
+ StatusPrinter.print(context);
+ fail("errors reported");
}
-
- private void printScriptHeader(String type) throws IOException {
- out("# ====================================================");
- out("# A script to check the exactness of the output ");
- out("# produced by " + type + " test");
- out("# ====================================================");
- out("# ");
- }
-
- private void printCommonScriptCore() throws IOException {
- out("");
- out("for t in $(seq 0 1 " + (NUM_THREADS - 1) + ")");
- out("do");
- out(" echo \"Testing results of thread $t\"");
- out(" grep \"$t \" aggregated | cut -d ' ' -f 2 > ${t}-sample");
- out(" for j in $(seq 1 1 ${end[$t]}); do echo $j; done > ${t}-witness");
- out(" diff -q -w ${t}-sample ${t}-witness;");
- out(" res=$?");
- out(" if [ $res != \"0\" ]; then");
- out(" echo \"FAILED for $t\"");
- out(" exit " + FAILURE_EXIT_CODE);
- out(" fi");
- out("done");
- out("");
- out("exit " + SUCCESSFUL_EXIT_CODE);
+ }
+
+ long diff(long start) {
+ return System.currentTimeMillis() - start;
+ }
+
+ static class RFARunnable extends RunnableWithCounterAndDone {
+ RollingFileAppender<Object> rfa;
+ int id;
+ boolean withInducedDelay;
+
+ RFARunnable(int id, RollingFileAppender<Object> rfa,
+ boolean withInducedDelay) {
+ this.id = id;
+ this.rfa = rfa;
+ this.withInducedDelay = withInducedDelay;
}
- private void printScriptForTimeBased() throws IOException {
- printScriptHeader("TimeBased");
- for (int i = 0; i < NUM_THREADS; i++) {
- out("end[" + i + "]=" + this.runnableArray[i].getCounter());
- }
- out("");
- out("rm aggregated");
- out("cat test* output.log >> aggregated");
- printCommonScriptCore();
-
- }
-
- private void printScriptForSizeBased(int numfiles) throws IOException {
- printScriptHeader("SizeBased");
-
- for (int i = 0; i < NUM_THREADS; i++) {
- out("end[" + i + "]=" + this.runnableArray[i].getCounter());
- }
- out("");
- out("rm aggregated");
- out("for i in $(seq " + (numfiles - 1) + " -1 0); do cat test-$i.log >> aggregated; done");
- out("cat output.log >> aggregated");
- out("");
- printCommonScriptCore();
- }
-
- private void out(String msg) throws IOException {
- scriptOS.write(msg.getBytes());
- scriptOS.write("\n".getBytes());
- }
-
- private void executeHarness(int duration, boolean withDelay) throws InterruptedException {
- MultiThreadedHarness multiThreadedHarness = new MultiThreadedHarness(duration);
- this.runnableArray = buildRunnableArray(withDelay);
- multiThreadedHarness.execute(runnableArray);
-
- StatusChecker checker = new StatusChecker(context.getStatusManager());
- if (!checker.isErrorFree(0)) {
- StatusPrinter.print(context);
- fail("errors reported");
- }
- }
-
- long diff(long start) {
- return System.currentTimeMillis() - start;
- }
-
- static class RFARunnable extends RunnableWithCounterAndDone {
- RollingFileAppender<Object> rfa;
- int id;
- boolean withInducedDelay;
-
- RFARunnable(int id, RollingFileAppender<Object> rfa, boolean withInducedDelay) {
- this.id = id;
- this.rfa = rfa;
- this.withInducedDelay = withInducedDelay;
- }
-
- public void run() {
- while (!isDone()) {
- counter++;
- rfa.doAppend(id + " " + counter);
- if ((counter % 64 == 0) && withInducedDelay) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- }
- }
- }
+ public void run() {
+ while (!isDone()) {
+ counter++;
+ rfa.doAppend(id + " " + counter);
+ if ((counter % 64 == 0) && withInducedDelay) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ }
}
+ }
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/PackageTest.java
index 0d45660..cfd41cb 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,8 +17,11 @@ import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
- at Suite.SuiteClasses({ RenameUtilTest.class, SizeBasedRollingTest.class, TimeBasedRollingTest.class, TimeBasedRollingWithArchiveRemoval_Test.class,
- MultiThreadedRollingTest.class, SizeAndTimeBasedFNATP_Test.class, RollingFileAppenderTest.class,
- CollisionDetectionTest.class, ch.qos.logback.core.rolling.helper.PackageTest.class })
+ at Suite.SuiteClasses({RenameUtilTest.class, SizeBasedRollingTest.class,
+ TimeBasedRollingTest.class, TimeBasedRollingWithArchiveRemoval_Test.class,
+ MultiThreadedRollingTest.class,
+ SizeAndTimeBasedFNATP_Test.class,
+ RollingFileAppenderTest.class,
+ ch.qos.logback.core.rolling.helper.PackageTest.class})
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/RenameUtilTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/RenameUtilTest.java
index 47a3008..f8a38f0 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/RenameUtilTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/RenameUtilTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,110 +22,87 @@ import ch.qos.logback.core.status.StatusChecker;
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.util.CoreTestConstants;
import ch.qos.logback.core.util.StatusPrinter;
-
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
-import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class RenameUtilTest {
- Encoder<Object> encoder;
- Context context = new ContextBase();
- StatusChecker statusChecker = new StatusChecker(context);
-
- long currentTime = System.currentTimeMillis();
- int diff = RandomUtil.getPositiveInt();
- protected String randomOutputDirAsStr = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "/";
- protected File randomOutputDir = new File(randomOutputDirAsStr);
-
- @Before
- public void setUp() throws Exception {
- encoder = new EchoEncoder<Object>();
- // if this this the fist test run after 'build clean up' then the
- // OUTPUT_DIR_PREFIX might be not yet created
- randomOutputDir.mkdirs();
- }
-
- @Test
- public void renameToNonExistingDirectory() throws IOException, RolloverFailure {
- RenameUtil renameUtil = new RenameUtil();
- renameUtil.setContext(context);
-
- int diff2 = RandomUtil.getPositiveInt();
- File fromFile = File.createTempFile("from" + diff, "test", randomOutputDir);
-
- String randomTARGETDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff2;
-
- renameUtil.rename(fromFile.toString(), new File(randomTARGETDir + "/to.test").toString());
- StatusPrinter.printInCaseOfErrorsOrWarnings(context);
- assertTrue(statusChecker.isErrorFree(0));
- }
-
-
- @Test // LOGBACK-1054
- public void renameLockedAbstractFile_LOGBACK_1054 () throws IOException, RolloverFailure {
- RenameUtil renameUtil = new RenameUtil();
- renameUtil.setContext(context);
-
- String abstractFileName = "abstract_pathname-"+diff;
-
- String src = CoreTestConstants.OUTPUT_DIR_PREFIX+abstractFileName;
- String target = abstractFileName + ".target";
-
- makeFile(src);
-
- FileInputStream fisLock = new FileInputStream(src);
- renameUtil.rename(src, target);
- // release the lock
- fisLock.close();
-
- StatusPrinter.print(context);
- assertEquals(0, statusChecker.matchCount("Parent of target file ."+target+". is null"));
- }
-
- @Test
- @Ignore
- public void MANUAL_renamingOnDifferentVolumesOnLinux() throws IOException, RolloverFailure {
- RenameUtil renameUtil = new RenameUtil();
- renameUtil.setContext(context);
-
- String src = "/tmp/ramdisk/foo.txt";
- makeFile(src);
-
- renameUtil.rename(src, "/tmp/foo" + diff + ".txt");
- StatusPrinter.print(context);
- }
-
-
- @Test
- @Ignore
- public void MANUAL_renamingOnDifferentVolumesOnWindows() throws IOException, RolloverFailure {
- RenameUtil renameUtil = new RenameUtil();
- renameUtil.setContext(context);
-
- String src = "c:/tmp/foo.txt";
- makeFile(src);
-
- renameUtil.rename(src, "d:/tmp/foo" + diff + ".txt");
- StatusPrinter.print(context);
- assertTrue(statusChecker.isErrorFree(0));
- }
-
- private void makeFile(String src) throws FileNotFoundException, IOException {
-
- FileOutputStream fos = new FileOutputStream(src);
- fos.write(("hello" + diff).getBytes());
- fos.close();
- }
-
-
+ Encoder<Object> encoder;
+ Context context = new ContextBase();
+ StatusChecker statusChecker = new StatusChecker(context);
+
+ long currentTime = System.currentTimeMillis();
+ int diff = RandomUtil.getPositiveInt();
+ protected String randomOutputDirAsStr = CoreTestConstants.OUTPUT_DIR_PREFIX + diff
+ + "/";
+ protected File randomOutputDir = new File(randomOutputDirAsStr);
+
+ @Before
+ public void setUp() throws Exception {
+ encoder = new EchoEncoder<Object>();
+ // if this this the fist test run after 'build clean up' then the
+ // OUTPUT_DIR_PREFIX might be not yet created
+ randomOutputDir.mkdirs();
+ }
+
+ @Test
+ public void renameToNonExistingDirectory() throws IOException, RolloverFailure {
+ RenameUtil renameUtil = new RenameUtil();
+ renameUtil.setContext(context);
+
+ int diff2 = RandomUtil.getPositiveInt();
+ File fromFile = File.createTempFile("from" + diff, "test",
+ randomOutputDir);
+
+ String randomTARGETDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff2;
+
+ renameUtil.rename(fromFile.toString(), new File(randomTARGETDir + "/to.test").toString());
+ StatusPrinter.printInCaseOfErrorsOrWarnings(context);
+ assertTrue(statusChecker.isErrorFree(0));
+ }
+
+
+ @Test
+ @Ignore
+ public void MANUAL_renamingOnDifferentVolumesOnLinux() throws IOException, RolloverFailure {
+ RenameUtil renameUtil = new RenameUtil();
+ renameUtil.setContext(context);
+
+ String src = "/tmp/ramdisk/foo.txt";
+ FileOutputStream fis = new FileOutputStream(src);
+ fis.write(("hello" + diff).getBytes());
+
+ renameUtil.rename(src, "/tmp/foo" + diff + ".txt");
+ StatusPrinter.print(context);
+ }
+
+
+ @Test
+ @Ignore
+ public void MANUAL_renamingOnDifferentVolumesOnWindows() throws IOException, RolloverFailure {
+ RenameUtil renameUtil = new RenameUtil();
+ renameUtil.setContext(context);
+
+ String src = "c:/tmp/foo.txt";
+ FileOutputStream fis = new FileOutputStream(src);
+ fis.write(("hello" + diff).getBytes());
+ fis.close();
+
+ renameUtil.rename(src, "d:/tmp/foo" + diff + ".txt");
+ StatusPrinter.print(context);
+ assertTrue(statusChecker.isErrorFree(0));
+ }
+
+ @Test
+ public void renameByCopying() {
+
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java
index e571862..42ba7f7 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,15 +13,6 @@
*/
package ch.qos.logback.core.rolling;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
@@ -32,235 +23,188 @@ import ch.qos.logback.core.status.StatusChecker;
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.util.CoreTestConstants;
import ch.qos.logback.core.util.StatusPrinter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
public class RollingFileAppenderTest extends AbstractAppenderTest<Object> {
- RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
- Context context = new ContextBase();
-
- TimeBasedRollingPolicy<Object> tbrp = new TimeBasedRollingPolicy<Object>();
- int diff = RandomUtil.getPositiveInt();
- String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "/";
-
- @Before
- public void setUp() throws Exception {
- // noStartTest fails if the context is set in setUp
- // rfa.setContext(context);
-
- rfa.setEncoder(new DummyEncoder<Object>());
- rfa.setName("test");
- tbrp.setContext(context);
- tbrp.setParent(rfa);
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
- @Override
- protected Appender<Object> getAppender() {
- return rfa;
- }
-
- @Override
- protected Appender<Object> getConfiguredAppender() {
- rfa.setContext(context);
- tbrp.setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "toto-%d.log");
- tbrp.start();
- rfa.setRollingPolicy(tbrp);
-
- rfa.start();
- return rfa;
- }
-
- @Test
- public void testPrudentModeLogicalImplications() {
- rfa.setContext(context);
- // prudent mode will force "file" property to be null
- rfa.setFile("some non null value");
- rfa.setAppend(false);
- rfa.setPrudent(true);
-
- tbrp.setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "toto-%d.log");
- tbrp.start();
- rfa.setRollingPolicy(tbrp);
-
- rfa.start();
-
- assertTrue(rfa.isAppend());
- assertNull(rfa.rawFileProperty());
- assertTrue(rfa.isStarted());
- }
-
- @Test
- public void testPrudentModeLogicalImplicationsOnCompression() {
- rfa.setContext(context);
- rfa.setAppend(false);
- rfa.setPrudent(true);
-
- tbrp.setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "toto-%d.log.zip");
- tbrp.start();
- rfa.setRollingPolicy(tbrp);
-
- rfa.start();
-
- StatusChecker checker = new StatusChecker(context);
- assertFalse(rfa.isStarted());
- assertEquals(Status.ERROR, checker.getHighestLevel(0));
- }
-
- @Test
- public void testFilePropertyAfterRollingPolicy() {
- rfa.setContext(context);
- rfa.setRollingPolicy(tbrp);
- rfa.setFile("x");
- StatusPrinter.print(context);
- StatusChecker statusChecker = new StatusChecker(context.getStatusManager());
- statusChecker.assertContainsMatch(Status.ERROR, "File property must be set before any triggeringPolicy ");
- }
-
- @Test
- public void testFilePropertyAfterTriggeringPolicy() {
- rfa.setContext(context);
- rfa.setTriggeringPolicy(new SizeBasedTriggeringPolicy<Object>());
- rfa.setFile("x");
- StatusChecker statusChecker = new StatusChecker(context.getStatusManager());
- statusChecker.assertContainsMatch(Status.ERROR, "File property must be set before any triggeringPolicy ");
- }
-
- @Test
- public void testFileNameWithParenthesis() {
- // if ')' is not escaped, the test throws
- // java.lang.IllegalStateException: FileNamePattern [.../program(x86)/toto-%d.log] does not contain a valid
- // DateToken
- rfa.setContext(context);
- tbrp.setFileNamePattern(randomOutputDir + "program(x86)/toto-%d.log");
- tbrp.start();
- rfa.setRollingPolicy(tbrp);
- rfa.start();
- rfa.doAppend("hello");
- }
-
- @Test
- public void stopTimeBasedRollingPolicy() {
- rfa.setContext(context);
-
- tbrp.setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "toto-%d.log.zip");
- tbrp.start();
- rfa.setRollingPolicy(tbrp);
- rfa.start();
-
- StatusPrinter.print(context);
- assertTrue(tbrp.isStarted());
- assertTrue(rfa.isStarted());
- rfa.stop();
- assertFalse(rfa.isStarted());
- assertFalse(tbrp.isStarted());
-
- }
-
- @Test
- public void stopFixedWindowRollingPolicy() {
- rfa.setContext(context);
- rfa.setFile(CoreTestConstants.OUTPUT_DIR_PREFIX + "toto-.log");
-
- FixedWindowRollingPolicy fwRollingPolicy = new FixedWindowRollingPolicy();
- fwRollingPolicy.setContext(context);
- fwRollingPolicy.setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "toto-%i.log.zip");
- fwRollingPolicy.setParent(rfa);
- fwRollingPolicy.start();
- SizeBasedTriggeringPolicy<Object> sbTriggeringPolicy = new SizeBasedTriggeringPolicy<Object>();
- sbTriggeringPolicy.setContext(context);
- sbTriggeringPolicy.start();
-
- rfa.setRollingPolicy(fwRollingPolicy);
- rfa.setTriggeringPolicy(sbTriggeringPolicy);
-
- rfa.start();
-
- StatusPrinter.print(context);
- assertTrue(fwRollingPolicy.isStarted());
- assertTrue(sbTriggeringPolicy.isStarted());
- assertTrue(rfa.isStarted());
- rfa.stop();
- assertFalse(rfa.isStarted());
- assertFalse(fwRollingPolicy.isStarted());
- assertFalse(sbTriggeringPolicy.isStarted());
-
- }
-
- /**
- * Test for http://jira.qos.ch/browse/LOGBACK-796
- */
- @Test
- public void testFileShouldNotMatchFileNamePattern() {
- rfa.setContext(context);
- rfa.setFile(CoreTestConstants.OUTPUT_DIR_PREFIX + "x-2013-04.log");
- tbrp.setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "x-%d{yyyy-MM}.log");
- tbrp.start();
-
- rfa.setRollingPolicy(tbrp);
- rfa.start();
- StatusChecker statusChecker = new StatusChecker(context);
- final String msg = "File property collides with fileNamePattern. Aborting.";
- boolean containsMatch = statusChecker.containsMatch(Status.ERROR, msg);
- assertTrue("Missing error: " + msg, containsMatch);
- }
-
- @Test
- public void collidingTimeformat() {
- rfa.setContext(context);
- rfa.setAppend(false);
- rfa.setPrudent(true);
-
- tbrp.setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "toto-%d{dd}.log.zip");
- tbrp.start();
- rfa.setRollingPolicy(tbrp);
-
- rfa.start();
-
- StatusChecker checker = new StatusChecker(context);
- assertFalse(rfa.isStarted());
- assertEquals(Status.ERROR, checker.getHighestLevel(0));
- StatusPrinter.print(context);
- checker.assertContainsMatch("The date format in FileNamePattern will result");
- }
-
- @Test
- public void collidingFileNamePattern() {
- String filenamePattern = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "-collision-%d.log.zip";
-
- RollingFileAppender<Object> appender0 = new RollingFileAppender<Object>();
- appender0.setName("FA0");
- appender0.setContext(context);
- appender0.setEncoder(new DummyEncoder<Object>());
- TimeBasedRollingPolicy<Object> tbrp0 = new TimeBasedRollingPolicy<Object>();
- tbrp0.setContext(context);
- tbrp0.setFileNamePattern(filenamePattern);
- tbrp0.setParent(appender0);
- tbrp0.start();
- appender0.setRollingPolicy(tbrp0);
- appender0.start();
- assertTrue(appender0.isStarted());
-
- RollingFileAppender<Object> appender1 = new RollingFileAppender<Object>();
- appender1.setName("FA1");
- appender1.setFile("X");
- appender1.setContext(context);
- appender1.setEncoder(new DummyEncoder<Object>());
- TimeBasedRollingPolicy<Object> tbrp1 = new TimeBasedRollingPolicy<Object>();
- tbrp1.setContext(context);
- tbrp1.setFileNamePattern(filenamePattern);
- tbrp1.setParent(appender1);
- tbrp1.start();
- appender1.setRollingPolicy(tbrp1);
- appender1.start();
-
- // StatusPrinter.print(context);
-
- assertFalse(appender1.isStarted());
- StatusChecker checker = new StatusChecker(context);
- checker.assertContainsMatch(Status.ERROR, "'FileNamePattern' option has the same value");
- }
-
+ RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
+ Context context = new ContextBase();
+
+ TimeBasedRollingPolicy<Object> tbrp = new TimeBasedRollingPolicy<Object>();
+ int diff = RandomUtil.getPositiveInt();
+ String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "/";
+
+ @Before
+ public void setUp() throws Exception {
+ // noStartTest fails if the context is set in setUp
+ // rfa.setContext(context);
+
+ rfa.setEncoder(new DummyEncoder<Object>());
+ rfa.setName("test");
+ tbrp.setContext(context);
+ tbrp.setParent(rfa);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Override
+ protected Appender<Object> getAppender() {
+ return rfa;
+ }
+
+ @Override
+ protected Appender<Object> getConfiguredAppender() {
+ rfa.setContext(context);
+ tbrp
+ .setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "toto-%d.log");
+ tbrp.start();
+ rfa.setRollingPolicy(tbrp);
+
+ rfa.start();
+ return rfa;
+ }
+
+ @Test
+ public void testPrudentModeLogicalImplications() {
+ rfa.setContext(context);
+ // prudent mode will force "file" property to be null
+ rfa.setFile("some non null value");
+ rfa.setAppend(false);
+ rfa.setPrudent(true);
+
+ tbrp
+ .setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "toto-%d.log");
+ tbrp.start();
+ rfa.setRollingPolicy(tbrp);
+
+ rfa.start();
+
+ assertTrue(rfa.isAppend());
+ assertNull(rfa.rawFileProperty());
+ assertTrue(rfa.isStarted());
+ }
+
+ @Test
+ public void testPrudentModeLogicalImplicationsOnCompression() {
+ rfa.setContext(context);
+ rfa.setAppend(false);
+ rfa.setPrudent(true);
+
+ tbrp.setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "toto-%d.log.zip");
+ tbrp.start();
+ rfa.setRollingPolicy(tbrp);
+
+ rfa.start();
+
+ StatusChecker checker = new StatusChecker(context);
+ assertFalse(rfa.isStarted());
+ assertEquals(Status.ERROR, checker.getHighestLevel(0));
+ }
+
+ @Test
+ public void testFilePropertyAfterRollingPolicy() {
+ rfa.setContext(context);
+ rfa.setRollingPolicy(tbrp);
+ rfa.setFile("x");
+ StatusPrinter.print(context);
+ StatusChecker statusChecker = new StatusChecker(context.getStatusManager());
+ statusChecker.assertContainsMatch(Status.ERROR,
+ "File property must be set before any triggeringPolicy ");
+ }
+
+ @Test
+ public void testFilePropertyAfterTriggeringPolicy() {
+ rfa.setContext(context);
+ rfa.setTriggeringPolicy(new SizeBasedTriggeringPolicy<Object>());
+ rfa.setFile("x");
+ StatusChecker statusChecker = new StatusChecker(context.getStatusManager());
+ statusChecker.assertContainsMatch(Status.ERROR,
+ "File property must be set before any triggeringPolicy ");
+ }
+
+ @Test
+ public void testFileNameWithParenthesis() {
+ // if ')' is not escaped, the test throws
+ // java.lang.IllegalStateException: FileNamePattern [.../program(x86)/toto-%d.log] does not contain a valid DateToken
+ rfa.setContext(context);
+ tbrp
+ .setFileNamePattern(randomOutputDir + "program(x86)/toto-%d.log");
+ tbrp.start();
+ rfa.setRollingPolicy(tbrp);
+ rfa.start();
+ rfa.doAppend("hello");
+ }
+
+ @Test
+ public void stopTimeBasedRollingPolicy() {
+ rfa.setContext(context);
+
+ tbrp.setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "toto-%d.log.zip");
+ tbrp.start();
+ rfa.setRollingPolicy(tbrp);
+ rfa.start();
+
+ StatusPrinter.print(context);
+ assertTrue(tbrp.isStarted());
+ assertTrue(rfa.isStarted());
+ rfa.stop();
+ assertFalse(rfa.isStarted());
+ assertFalse(tbrp.isStarted());
+
+ }
+
+ @Test
+ public void stopFixedWindowRollingPolicy() {
+ rfa.setContext(context);
+ rfa.setFile(CoreTestConstants.OUTPUT_DIR_PREFIX + "toto-.log");
+
+ FixedWindowRollingPolicy fwRollingPolicy = new FixedWindowRollingPolicy();
+ fwRollingPolicy.setContext(context);
+ fwRollingPolicy.setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "toto-%i.log.zip");
+ fwRollingPolicy.setParent(rfa);
+ fwRollingPolicy.start();
+ SizeBasedTriggeringPolicy sbTriggeringPolicy = new SizeBasedTriggeringPolicy();
+ sbTriggeringPolicy.setContext(context);
+ sbTriggeringPolicy.start();
+
+ rfa.setRollingPolicy(fwRollingPolicy);
+ rfa.setTriggeringPolicy(sbTriggeringPolicy);
+
+ rfa.start();
+
+ StatusPrinter.print(context);
+ assertTrue(fwRollingPolicy.isStarted());
+ assertTrue(sbTriggeringPolicy.isStarted());
+ assertTrue(rfa.isStarted());
+ rfa.stop();
+ assertFalse(rfa.isStarted());
+ assertFalse(fwRollingPolicy.isStarted());
+ assertFalse(sbTriggeringPolicy.isStarted());
+
+ }
+
+ /**
+ * Test for http://jira.qos.ch/browse/LOGBACK-796
+ */
+ @Test
+ public void testFileShouldNotMatchFileNamePattern() {
+ rfa.setContext(context);
+ rfa.setFile(CoreTestConstants.OUTPUT_DIR_PREFIX + "x-2013-04.log");
+ tbrp.setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "x-%d{yyyy-MM}.log");
+ tbrp.start();
+
+ rfa.setRollingPolicy(tbrp);
+ rfa.start();
+ StatusChecker statusChecker = new StatusChecker(context);
+ final String msg = "File property collides with fileNamePattern. Aborting.";
+ boolean containsMatch = statusChecker.containsMatch(Status.ERROR, msg);
+ assertTrue("Missing error: " + msg, containsMatch);
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/RolloverChecker.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/RolloverChecker.java
index 938dcba..e972203 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/RolloverChecker.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/RolloverChecker.java
@@ -1,21 +1,23 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
- * or (per the licensee's choosing)
+ * or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
+
package ch.qos.logback.core.rolling;
import java.io.IOException;
import java.util.List;
+
public interface RolloverChecker {
- public void check(List<String> expectedFilenameList) throws IOException;
+ public void check(List<String> expectedFilenameList) throws IOException;
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/ScaffoldingForRollingTests.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/ScaffoldingForRollingTests.java
index 23d8a01..d20e566 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/ScaffoldingForRollingTests.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/ScaffoldingForRollingTests.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -46,239 +46,238 @@ import static org.junit.Assert.assertTrue;
*/
public class ScaffoldingForRollingTests {
- static public final String DATE_PATTERN_WITH_SECONDS = "yyyy-MM-dd_HH_mm_ss";
- static public final String DATE_PATTERN_BY_DAY = "yyyy-MM-dd";
- static public final SimpleDateFormat SDF = new SimpleDateFormat(DATE_PATTERN_WITH_SECONDS);
-
- int diff = RandomUtil.getPositiveInt();
- protected String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "/";
- EchoEncoder<Object> encoder = new EchoEncoder<Object>();
- Context context = new ContextBase();
- protected List<String> expectedFilenameList = new ArrayList<String>();
- protected long nextRolloverThreshold; // initialized in setUp()
- protected long currentTime; // initialized in setUp()
- protected List<Future<?>> futureList = new ArrayList<Future<?>>();
-
- Calendar calendar = Calendar.getInstance();
-
- public void setUp() {
- context.setName("test");
- calendar.set(Calendar.MILLISECOND, 333);
- currentTime = calendar.getTimeInMillis();
- recomputeRolloverThreshold(currentTime);
+ static public final String DATE_PATTERN_WITH_SECONDS = "yyyy-MM-dd_HH_mm_ss";
+ static public final SimpleDateFormat SDF = new SimpleDateFormat(
+ DATE_PATTERN_WITH_SECONDS);
+
+ int diff = RandomUtil.getPositiveInt();
+ protected String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff
+ + "/";
+ EchoEncoder<Object> encoder = new EchoEncoder<Object>();
+ Context context = new ContextBase();
+ protected List<String> expectedFilenameList = new ArrayList<String>();
+ protected long nextRolloverThreshold; // initialized in setUp()
+ protected long currentTime; // initialized in setUp()
+ protected List<Future<?>> futureList = new ArrayList<Future<?>>();
+
+ Calendar calendar = Calendar.getInstance();
+
+ public void setUp() {
+ context.setName("test");
+ calendar.set(Calendar.MILLISECOND, 333);
+ currentTime = calendar.getTimeInMillis();
+ recomputeRolloverThreshold(currentTime);
+ }
+
+ public static void existenceCheck(String filename) {
+ assertTrue("File " + filename + " does not exist", new File(filename)
+ .exists());
+ }
+
+ public static File[] getFilesInDirectory(String outputDirStr) {
+ File outputDir = new File(outputDirStr);
+ return outputDir.listFiles();
+ }
+
+ public static void fileContentCheck(File[] fileArray, int runLength,
+ String prefix) throws IOException {
+ List<String> stringList = new ArrayList<String>();
+ for (File file : fileArray) {
+ FileToBufferUtil.readIntoList(file, stringList);
}
- public static void existenceCheck(String filename) {
- assertTrue("File " + filename + " does not exist", new File(filename).exists());
- }
-
- public static File[] getFilesInDirectory(String outputDirStr) {
- File outputDir = new File(outputDirStr);
- return outputDir.listFiles();
- }
-
- public static void fileContentCheck(File[] fileArray, int runLength, String prefix) throws IOException {
- fileContentCheck(fileArray, runLength, prefix, 0);
- }
-
- public static void fileContentCheck(File[] fileArray, int runLength, String prefix, int runStart) throws IOException {
- List<String> stringList = new ArrayList<String>();
- for (File file : fileArray) {
- FileToBufferUtil.readIntoList(file, stringList);
- }
-
- List<String> witnessList = new ArrayList<String>();
-
- for (int i = runStart; i < runLength; i++) {
- witnessList.add(prefix + i);
- }
- assertEquals(witnessList, stringList);
- }
-
- public static void sortedContentCheck(String outputDirStr, int runLength, String prefix) throws IOException {
- sortedContentCheck(outputDirStr, runLength, prefix, 0);
- }
-
- public static void sortedContentCheck(String outputDirStr, int runLength, String prefix, int runStart) throws IOException {
- File[] fileArray = getFilesInDirectory(outputDirStr);
- FileFilterUtil.sortFileArrayByName(fileArray);
- fileContentCheck(fileArray, runLength, prefix, runStart);
- }
-
- public static void reverseSortedContentCheck(String outputDirStr, int runLength, String prefix) throws IOException {
- File[] fileArray = getFilesInDirectory(outputDirStr);
- FileFilterUtil.reverseSortFileArrayByName(fileArray);
- fileContentCheck(fileArray, runLength, prefix);
- }
-
- public static void existenceCheck(List<String> filenameList) {
- for (String filename : filenameList) {
- assertTrue("File " + filename + " does not exist", new File(filename).exists());
- }
- }
-
- public static int existenceCount(List<String> filenameList) {
- int existenceCounter = 0;
- for (String filename : filenameList) {
- if (new File(filename).exists()) {
- existenceCounter++;
- }
- }
- return existenceCounter;
- }
-
- String testId2FileName(String testId) {
- return randomOutputDir + testId + ".log";
- }
-
- // assuming rollover every second
- protected void recomputeRolloverThreshold(long ct) {
- long delta = ct % 1000;
- nextRolloverThreshold = (ct - delta) + 1000;
- }
-
- protected boolean passThresholdTime(long nextRolloverThreshold) {
- return currentTime >= nextRolloverThreshold;
- }
+ List<String> witnessList = new ArrayList<String>();
- protected void incCurrentTime(long increment) {
- currentTime += increment;
+ for (int i = 0; i < runLength; i++) {
+ witnessList.add(prefix + i);
}
-
- protected Date getDateOfCurrentPeriodsStart() {
- long delta = currentTime % 1000;
- return new Date(currentTime - delta);
+ assertEquals(witnessList, stringList);
+ }
+
+ public static void sortedContentCheck(String outputDirStr, int runLength,
+ String prefix) throws IOException {
+ File[] fileArray = getFilesInDirectory(outputDirStr);
+ FileFilterUtil.sortFileArrayByName(fileArray);
+ fileContentCheck(fileArray, runLength, prefix);
+ }
+
+ public static void reverseSortedContentCheck(String outputDirStr,
+ int runLength, String prefix) throws IOException {
+ File[] fileArray = getFilesInDirectory(outputDirStr);
+ FileFilterUtil.reverseSortFileArrayByName(fileArray);
+ fileContentCheck(fileArray, runLength, prefix);
+ }
+
+ public static void existenceCheck(List<String> filenameList) {
+ for (String filename : filenameList) {
+ assertTrue("File " + filename + " does not exist", new File(filename)
+ .exists());
}
-
- protected Date getDateOfPreviousPeriodsStart() {
- long delta = currentTime % 1000;
- return new Date(currentTime - delta - 1000);
+ }
+
+ public static int existenceCount(List<String> filenameList) {
+ int existenceCounter = 0;
+ for (String filename : filenameList) {
+ if (new File(filename).exists()) {
+ existenceCounter++;
+ }
}
-
- protected long getMillisOfCurrentPeriodsStart() {
- long delta = currentTime % 1000;
- return (currentTime - delta);
+ return existenceCounter;
+ }
+
+ String testId2FileName(String testId) {
+ return randomOutputDir + testId + ".log";
+ }
+
+ // assuming rollover every second
+
+ protected void recomputeRolloverThreshold(long ct) {
+ long delta = ct % 1000;
+ nextRolloverThreshold = (ct - delta) + 1000;
+ }
+
+ protected boolean passThresholdTime(long nextRolloverThreshold) {
+ return currentTime >= nextRolloverThreshold;
+ }
+
+ protected void incCurrentTime(long increment) {
+ currentTime += increment;
+ }
+
+ protected Date getDateOfCurrentPeriodsStart() {
+ long delta = currentTime % 1000;
+ return new Date(currentTime - delta);
+ }
+
+ protected Date getDateOfPreviousPeriodsStart() {
+ long delta = currentTime % 1000;
+ return new Date(currentTime - delta - 1000);
+ }
+
+ protected long getMillisOfCurrentPeriodsStart() {
+ long delta = currentTime % 1000;
+ return (currentTime - delta);
+ }
+
+
+ protected void addExpectedFileName_ByDate(String patternStr, long millis) {
+ FileNamePattern fileNamePattern = new FileNamePattern(patternStr, context);
+ String fn = fileNamePattern.convert(new Date(millis));
+ expectedFilenameList.add(fn);
+ }
+
+ void addExpectedFileNamedIfItsTime_ByDate(String fileNamePatternStr) {
+ if (passThresholdTime(nextRolloverThreshold)) {
+ addExpectedFileName_ByDate(fileNamePatternStr, getMillisOfCurrentPeriodsStart());
+ recomputeRolloverThreshold(currentTime);
}
+ }
- protected void addExpectedFileName_ByDate(String patternStr, long millis) {
- FileNamePattern fileNamePattern = new FileNamePattern(patternStr, context);
- String fn = fileNamePattern.convert(new Date(millis));
- expectedFilenameList.add(fn);
- }
+ protected void addExpectedFileName_ByDate(String outputDir, String testId, Date date,
+ boolean gzExtension) {
- void addExpectedFileNamedIfItsTime_ByDate(String fileNamePatternStr) {
- if (passThresholdTime(nextRolloverThreshold)) {
- addExpectedFileName_ByDate(fileNamePatternStr, getMillisOfCurrentPeriodsStart());
- recomputeRolloverThreshold(currentTime);
- }
+ String fn = outputDir + testId + "-" + SDF.format(date);
+ if (gzExtension) {
+ fn += ".gz";
}
+ expectedFilenameList.add(fn);
+ }
- protected void addExpectedFileName_ByDate(String outputDir, String testId, Date date, boolean gzExtension) {
-
- String fn = outputDir + testId + "-" + SDF.format(date);
- if (gzExtension) {
- fn += ".gz";
- }
- expectedFilenameList.add(fn);
- }
+ protected void addExpectedFileName_ByFileIndexCounter(String randomOutputDir, String testId, long millis,
+ int fileIndexCounter, String compressionSuffix) {
+ String fn = randomOutputDir + testId + "-" + SDF.format(millis) + "-" + fileIndexCounter + ".txt" + compressionSuffix;
+ expectedFilenameList.add(fn);
+ }
- protected void addExpectedFileName_ByFileIndexCounter(String randomOutputDir, String testId, long millis, int fileIndexCounter, String compressionSuffix) {
- String fn = randomOutputDir + testId + "-" + SDF.format(millis) + "-" + fileIndexCounter + ".txt" + compressionSuffix;
- expectedFilenameList.add(fn);
- }
- protected List<String> filterElementsInListBySuffix(String suffix) {
- List<String> zipFiles = new ArrayList<String>();
- for (String filename : expectedFilenameList) {
- if (filename.endsWith(suffix))
- zipFiles.add(filename);
- }
- return zipFiles;
+ protected List<String> filterElementsInListBySuffix(String suffix) {
+ List<String> zipFiles = new ArrayList<String>();
+ for (String filename : expectedFilenameList) {
+ if (filename.endsWith(suffix))
+ zipFiles.add(filename);
}
-
- protected void addExpectedFileNamedIfItsTime_ByDate(String outputDir, String testId, boolean gzExtension) {
- if (passThresholdTime(nextRolloverThreshold)) {
- addExpectedFileName_ByDate(outputDir, testId, getDateOfCurrentPeriodsStart(), gzExtension);
- recomputeRolloverThreshold(currentTime);
- }
+ return zipFiles;
+ }
+
+ protected void addExpectedFileNamedIfItsTime_ByDate(String outputDir, String testId,
+ boolean gzExtension) {
+ if (passThresholdTime(nextRolloverThreshold)) {
+ addExpectedFileName_ByDate(outputDir, testId, getDateOfCurrentPeriodsStart(),
+ gzExtension);
+ recomputeRolloverThreshold(currentTime);
}
-
- void massageExpectedFilesToCorresponToCurrentTarget(String fileName, boolean fileOptionIsSet) {
- int lastIndex = expectedFilenameList.size() - 1;
- String last = expectedFilenameList.remove(lastIndex);
-
- if (fileOptionIsSet) {
- expectedFilenameList.add(fileName);
- } else if (last.endsWith(".gz")) {
- int lastLen = last.length();
- String stem = last.substring(0, lastLen - 3);
- expectedFilenameList.add(stem);
- }
+ }
+
+ void massageExpectedFilesToCorresponToCurrentTarget(String fileName, boolean fileOptionIsSet) {
+ int lastIndex = expectedFilenameList.size() - 1;
+ String last = expectedFilenameList.remove(lastIndex);
+
+ if (fileOptionIsSet) {
+ expectedFilenameList.add(fileName);
+ } else if (last.endsWith(".gz")) {
+ int lastLen = last.length();
+ String stem = last.substring(0, lastLen - 3);
+ expectedFilenameList.add(stem);
}
+ }
- String addGZIfNotLast(int i) {
- int lastIndex = expectedFilenameList.size() - 1;
- if (i != lastIndex) {
- return ".gz";
- } else {
- return "";
- }
- }
- void zipEntryNameCheck(List<String> expectedFilenameList, String pattern) throws IOException {
- for (String filepath : expectedFilenameList) {
- checkZipEntryName(filepath, pattern);
- }
+ String addGZIfNotLast(int i) {
+ int lastIndex = expectedFilenameList.size() - 1;
+ if (i != lastIndex) {
+ return ".gz";
+ } else {
+ return "";
}
+ }
- void checkZipEntryMatchesZipFilename(List<String> expectedFilenameList) throws IOException {
- for (String filepath : expectedFilenameList) {
- String stripped = stripStemFromZipFilename(filepath);
- checkZipEntryName(filepath, stripped);
- }
+ void zipEntryNameCheck(List<String> expectedFilenameList, String pattern) throws IOException {
+ for (String filepath : expectedFilenameList) {
+ checkZipEntryName(filepath, pattern);
}
+ }
- String stripStemFromZipFilename(String filepath) {
- File filepathAsFile = new File(filepath);
- String stem = filepathAsFile.getName();
- int stemLen = stem.length();
- return stem.substring(0, stemLen - ".zip".length());
-
+ void checkZipEntryMatchesZipFilename(List<String> expectedFilenameList) throws IOException {
+ for (String filepath : expectedFilenameList) {
+ String stripped = stripStemFromZipFilename(filepath);
+ checkZipEntryName(filepath, stripped);
}
-
- void checkZipEntryName(String filepath, String pattern) throws IOException {
- System.out.println("Checking [" + filepath + "]");
- ZipFile zf = new ZipFile(filepath);
-
- try {
- Enumeration<? extends ZipEntry> entries = zf.entries();
- assert ((entries.hasMoreElements()));
- ZipEntry firstZipEntry = entries.nextElement();
- assert ((!entries.hasMoreElements()));
- System.out.println("Testing zip entry [" + firstZipEntry.getName() + "]");
- assertTrue(firstZipEntry.getName().matches(pattern));
- } finally {
- if (zf != null)
- zf.close();
- }
+ }
+
+ String stripStemFromZipFilename(String filepath) {
+ File filepathAsFile = new File(filepath);
+ String stem = filepathAsFile.getName();
+ int stemLen = stem.length();
+ return stem.substring(0, stemLen - ".zip".length());
+
+ }
+
+ void checkZipEntryName(String filepath, String pattern) throws IOException {
+ System.out.println("Checking [" + filepath + "]");
+ ZipFile zf = new ZipFile(filepath);
+ Enumeration<? extends ZipEntry> entries = zf.entries();
+ assert ((entries.hasMoreElements()));
+ ZipEntry firstZipEntry = entries.nextElement();
+ assert ((!entries.hasMoreElements()));
+ System.out.println("Testing zip entry [" + firstZipEntry.getName() + "]");
+ assertTrue(firstZipEntry.getName().matches(pattern));
+ }
+
+ protected void add(Future future) {
+ if (future == null) return;
+ if (!futureList.contains(future)) {
+ futureList.add(future);
}
-
- protected void add(Future<?> future) {
- if (future == null)
- return;
- if (!futureList.contains(future)) {
- futureList.add(future);
- }
+ }
+
+ protected void waitForJobsToComplete() {
+ for (Future future : futureList) {
+ try {
+ future.get(10, TimeUnit.SECONDS);
+ } catch (Exception e) {
+ new RuntimeException("unexpected exception while testing", e);
+ }
}
- protected void waitForJobsToComplete() {
- for (Future<?> future : futureList) {
- try {
- future.get(10, TimeUnit.SECONDS);
- } catch (Exception e) {
- new RuntimeException("unexpected exception while testing", e);
- }
- }
-
- }
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP_Test.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP_Test.java
index ccf773a..1d3ff1a 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP_Test.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP_Test.java
@@ -1,19 +1,24 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
- * or (per the licensee's choosing)
+ * or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
package ch.qos.logback.core.rolling;
-import static org.junit.Assert.assertFalse;
+import ch.qos.logback.core.encoder.EchoEncoder;
+import ch.qos.logback.core.status.InfoStatus;
+import ch.qos.logback.core.status.StatusManager;
+import ch.qos.logback.core.util.StatusPrinter;
+import org.junit.Before;
+import org.junit.Test;
import java.io.File;
import java.io.IOException;
@@ -21,237 +26,171 @@ import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;
-import org.junit.Before;
-import org.junit.Test;
-
-import ch.qos.logback.core.encoder.EchoEncoder;
-import ch.qos.logback.core.status.InfoStatus;
-import ch.qos.logback.core.status.StatusChecker;
-import ch.qos.logback.core.status.StatusManager;
-import ch.qos.logback.core.util.FileSize;
-
public class SizeAndTimeBasedFNATP_Test extends ScaffoldingForRollingTests {
- private SizeAndTimeBasedFNATP<Object> sizeAndTimeBasedFNATP = null;
- private RollingFileAppender<Object> rfa1 = new RollingFileAppender<Object>();
- private TimeBasedRollingPolicy<Object> tbrp1 = new TimeBasedRollingPolicy<Object>();
- private RollingFileAppender<Object> rfa2 = new RollingFileAppender<Object>();
- private TimeBasedRollingPolicy<Object> tbrp2 = new TimeBasedRollingPolicy<Object>();
-
- private EchoEncoder<Object> encoder = new EchoEncoder<Object>();
- int fileSize = 0;
- int fileIndexCounter = 0;
- int sizeThreshold = 0;
-
- @Before
- public void setUp() {
- super.setUp();
- }
-
- private void initRollingFileAppender(RollingFileAppender<Object> rfa, String filename) {
- rfa.setContext(context);
- rfa.setEncoder(encoder);
- if (filename != null) {
- rfa.setFile(filename);
- }
- }
-
- private void initPolicies(RollingFileAppender<Object> rfa, TimeBasedRollingPolicy<Object> tbrp, String filenamePattern, int sizeThreshold, long givenTime,
- long lastCheck) {
- sizeAndTimeBasedFNATP = new SizeAndTimeBasedFNATP<Object>();
- tbrp.setContext(context);
- sizeAndTimeBasedFNATP.setMaxFileSize(new FileSize(sizeThreshold));
- tbrp.setTimeBasedFileNamingAndTriggeringPolicy(sizeAndTimeBasedFNATP);
- tbrp.setFileNamePattern(filenamePattern);
- tbrp.setParent(rfa);
- tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(givenTime);
- rfa.setRollingPolicy(tbrp);
- tbrp.start();
- rfa.start();
- }
-
- private void addExpectedFileNamedIfItsTime(String randomOutputDir, String testId, String msg, String compressionSuffix) {
- fileSize = fileSize + msg.getBytes().length;
- if (passThresholdTime(nextRolloverThreshold)) {
- fileIndexCounter = 0;
- fileSize = 0;
- addExpectedFileName_ByFileIndexCounter(randomOutputDir, testId, getMillisOfCurrentPeriodsStart(), fileIndexCounter, compressionSuffix);
- recomputeRolloverThreshold(currentTime);
- return;
- }
-
- // windows can delay file size changes, so we only allow for fileIndexCounter 0
- if ((fileIndexCounter == 0) && fileSize > sizeThreshold) {
- addExpectedFileName_ByFileIndexCounter(randomOutputDir, testId, getMillisOfCurrentPeriodsStart(), fileIndexCounter, compressionSuffix);
- fileIndexCounter = fileIndexCounter + 1;
- fileSize = 0;
- }
+ private SizeAndTimeBasedFNATP sizeAndTimeBasedFNATP = null;
+ private RollingFileAppender<Object> rfa1 = new RollingFileAppender<Object>();
+ private TimeBasedRollingPolicy<Object> tbrp1 = new TimeBasedRollingPolicy<Object>();
+ private RollingFileAppender<Object> rfa2 = new RollingFileAppender<Object>();
+ private TimeBasedRollingPolicy<Object> tbrp2 = new TimeBasedRollingPolicy<Object>();
+
+ private EchoEncoder<Object> encoder = new EchoEncoder<Object>();
+ int fileSize = 0;
+ int fileIndexCounter = 0;
+ int sizeThreshold = 0;
+
+
+ @Before
+ public void setUp() {
+ super.setUp();
+ }
+
+ private void initRollingFileAppender(RollingFileAppender<Object> rfa, String filename) {
+ rfa.setContext(context);
+ rfa.setEncoder(encoder);
+ if (filename != null) {
+ rfa.setFile(filename);
}
-
- void generic(String testId, String stem, boolean withSecondPhase, String compressionSuffix) throws IOException, InterruptedException, ExecutionException {
- String file = (stem != null) ? randomOutputDir + stem : null;
- initRollingFileAppender(rfa1, file);
- sizeThreshold = 300;
-
- initPolicies(rfa1, tbrp1, randomOutputDir + testId + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}-%i.txt" + compressionSuffix, sizeThreshold, currentTime, 0);
- addExpectedFileName_ByFileIndexCounter(randomOutputDir, testId, getMillisOfCurrentPeriodsStart(), fileIndexCounter, compressionSuffix);
- incCurrentTime(100);
- tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
- int runLength = 100;
- String prefix = "Hello -----------------";
-
- for (int i = 0; i < runLength; i++) {
- String msg = prefix + i;
- rfa1.doAppend(msg);
- addExpectedFileNamedIfItsTime(randomOutputDir, testId, msg, compressionSuffix);
- incCurrentTime(20);
- tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
- add(tbrp1.compressionFuture);
- add(tbrp1.cleanUpFuture);
- }
-
- if (withSecondPhase) {
- secondPhase(testId, file, stem, compressionSuffix, runLength, prefix);
- runLength = runLength * 2;
- }
-
- if (stem != null)
- massageExpectedFilesToCorresponToCurrentTarget(file, true);
-
- Thread.yield();
- // wait for compression to finish
- waitForJobsToComplete();
-
- // StatusPrinter.print(context);
- existenceCheck(expectedFilenameList);
- sortedContentCheck(randomOutputDir, runLength, prefix);
+ }
+
+ private void initPolicies(RollingFileAppender<Object> rfa,
+ TimeBasedRollingPolicy<Object> tbrp,
+ String filenamePattern, int sizeThreshold,
+ long givenTime, long lastCheck) {
+ sizeAndTimeBasedFNATP = new SizeAndTimeBasedFNATP<Object>();
+ tbrp.setContext(context);
+ sizeAndTimeBasedFNATP.setMaxFileSize("" + sizeThreshold);
+ tbrp.setTimeBasedFileNamingAndTriggeringPolicy(sizeAndTimeBasedFNATP);
+ tbrp.setFileNamePattern(filenamePattern);
+ tbrp.setParent(rfa);
+ tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(givenTime);
+ rfa.setRollingPolicy(tbrp);
+ tbrp.start();
+ rfa.start();
+ }
+
+ private void addExpectedFileNamedIfItsTime(String randomOutputDir, String testId, String msg, String compressionSuffix) {
+ fileSize = fileSize + msg.getBytes().length;
+ if (passThresholdTime(nextRolloverThreshold)) {
+ fileIndexCounter = 0;
+ fileSize = 0;
+ addExpectedFileName_ByFileIndexCounter(randomOutputDir, testId, getMillisOfCurrentPeriodsStart(),
+ fileIndexCounter, compressionSuffix);
+ recomputeRolloverThreshold(currentTime);
+ return;
}
- void secondPhase(String testId, String file, String stem, String compressionSuffix, int runLength, String prefix) {
- rfa1.stop();
-
- if (stem != null) {
- File f = new File(file);
- f.setLastModified(currentTime);
- }
-
- StatusManager sm = context.getStatusManager();
- sm.add(new InfoStatus("Time when rfa1 is stopped: " + new Date(currentTime), this));
- sm.add(new InfoStatus("currentTime%1000=" + (currentTime % 1000), this));
-
- initRollingFileAppender(rfa2, file);
- initPolicies(rfa2, tbrp2, randomOutputDir + testId + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}-%i.txt" + compressionSuffix, sizeThreshold, currentTime, 0);
-
- for (int i = runLength; i < runLength * 2; i++) {
- incCurrentTime(100);
- tbrp2.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
- String msg = prefix + i;
- rfa2.doAppend(msg);
- addExpectedFileNamedIfItsTime(randomOutputDir, testId, msg, compressionSuffix);
- }
+ // windows can delay file size changes, so we only allow for
+ // fileIndexCounter 0
+ if ((fileIndexCounter < 1) && fileSize > sizeThreshold) {
+ addExpectedFileName_ByFileIndexCounter(randomOutputDir, testId, getMillisOfCurrentPeriodsStart(),
+ fileIndexCounter, compressionSuffix);
+ fileIndexCounter = fileIndexCounter + 1;
+ fileSize = 0;
}
-
- static final boolean FIRST_PHASE_ONLY = false;
- static final boolean WITH_SECOND_PHASE = true;
- static final String DEFAULT_COMPRESSION_SUFFIX = "";
-
- @Test
- public void noCompression_FileSet_NoRestart_1() throws InterruptedException, ExecutionException, IOException {
- generic("test1", "toto.log", FIRST_PHASE_ONLY, DEFAULT_COMPRESSION_SUFFIX);
- }
-
- @Test
- public void noCompression_FileBlank_NoRestart_2() throws Exception {
- generic("test2", null, FIRST_PHASE_ONLY, DEFAULT_COMPRESSION_SUFFIX);
- }
-
- @Test
- public void noCompression_FileBlank_WithStopStart_3() throws Exception {
- generic("test3", null, WITH_SECOND_PHASE, DEFAULT_COMPRESSION_SUFFIX);
+ }
+
+
+ void generic(String testId, String stem, boolean withSecondPhase, String compressionSuffix) throws IOException, InterruptedException, ExecutionException {
+ String file = (stem != null) ? randomOutputDir + stem : null;
+ initRollingFileAppender(rfa1, file);
+ sizeThreshold = 300;
+ initPolicies(rfa1, tbrp1, randomOutputDir + testId + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}-%i.txt" + compressionSuffix, sizeThreshold, currentTime, 0);
+ addExpectedFileName_ByFileIndexCounter(randomOutputDir, testId, getMillisOfCurrentPeriodsStart(), fileIndexCounter, compressionSuffix);
+ incCurrentTime(100);
+ tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
+ int runLength = 100;
+ String prefix = "Hello -----------------";
+
+ for (int i = 0; i < runLength; i++) {
+ String msg = prefix + i;
+ rfa1.doAppend(msg);
+ addExpectedFileNamedIfItsTime(randomOutputDir, testId, msg, compressionSuffix);
+ incCurrentTime(20);
+ tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
+ add(tbrp1.future);
}
- @Test
- public void noCompression_FileSet_WithStopStart_4() throws Exception {
- generic("test4", "test4.log", WITH_SECOND_PHASE, DEFAULT_COMPRESSION_SUFFIX);
+ if (withSecondPhase) {
+ secondPhase(testId, file, stem, compressionSuffix, runLength, prefix);
+ runLength = runLength * 2;
}
- @Test
- public void withGZCompression_FileSet_NoRestart_5() throws Exception {
- generic("test5", "toto.log", FIRST_PHASE_ONLY, ".gz");
- }
+ if (stem != null)
+ massageExpectedFilesToCorresponToCurrentTarget(file, true);
- @Test
- public void withGZCompression_FileBlank_NoRestart_6() throws Exception {
- generic("test6", null, FIRST_PHASE_ONLY, ".gz");
- }
+ Thread.yield();
+ // wait for compression to finish
+ waitForJobsToComplete();
- @Test
- public void withZipCompression_FileSet_NoRestart_7() throws Exception {
- generic("test7", "toto.log", FIRST_PHASE_ONLY, ".zip");
- List<String> zipFiles = filterElementsInListBySuffix(".zip");
- checkZipEntryMatchesZipFilename(zipFiles);
- }
+ StatusPrinter.print(context);
+ existenceCheck(expectedFilenameList);
+ sortedContentCheck(randomOutputDir, runLength, prefix);
+ }
- @Test
- public void checkMissingIntToken() {
- String stem = "toto.log";
- String testId = "checkMissingIntToken";
- String compressionSuffix = "gz";
- String file = (stem != null) ? randomOutputDir + stem : null;
- initRollingFileAppender(rfa1, file);
- sizeThreshold = 300;
- initPolicies(rfa1, tbrp1, randomOutputDir + testId + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}.txt" + compressionSuffix, sizeThreshold, currentTime, 0);
+ void secondPhase(String testId, String file, String stem, String compressionSuffix, int runLength, String prefix) {
+ rfa1.stop();
- // StatusPrinter.print(context);
- assertFalse(rfa1.isStarted());
- StatusChecker checker = new StatusChecker(context);
- checker.assertContainsMatch("Missing integer token");
+ if (stem != null) {
+ File f = new File(file);
+ f.setLastModified(currentTime);
}
- @Test
- public void checkDateCollision() {
- String stem = "toto.log";
- String testId = "checkDateCollision";
- String compressionSuffix = "gz";
+ StatusManager sm = context.getStatusManager();
+ sm.add(new InfoStatus("Time when rfa1 is stopped: " + new Date(currentTime), this));
+ sm.add(new InfoStatus("currentTime%1000=" + (currentTime % 1000), this));
- String file = (stem != null) ? randomOutputDir + stem : null;
- initRollingFileAppender(rfa1, file);
- sizeThreshold = 300;
- initPolicies(rfa1, tbrp1, randomOutputDir + testId + "-%d{EE}.txt" + compressionSuffix, sizeThreshold, currentTime, 0);
+ initRollingFileAppender(rfa2, file);
+ initPolicies(rfa2, tbrp2, randomOutputDir + testId + "-%d{"
+ + DATE_PATTERN_WITH_SECONDS + "}-%i.txt" + compressionSuffix, sizeThreshold, currentTime, 0);
- // StatusPrinter.print(context);
- assertFalse(rfa1.isStarted());
- StatusChecker checker = new StatusChecker(context);
- checker.assertContainsMatch("The date format in FileNamePattern");
+ for (int i = runLength; i < runLength * 2; i++) {
+ incCurrentTime(100);
+ tbrp2.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
+ String msg = prefix + i;
+ rfa2.doAppend(msg);
+ addExpectedFileNamedIfItsTime(randomOutputDir, testId, msg, compressionSuffix);
}
-
- // @Test
- // public void testHistoryAsFileCount() throws IOException {
- // String testId = "testHistoryAsFileCount";
- // int maxHistory = 10;
- // initRollingFileAppender(rfa1, randomOutputDir + "~" + testId);
- // sizeThreshold = 50;
- // System.out.println("testHistoryAsFileCount started on "+new Date(currentTime));
- // initPolicies(rfa1, tbrp1, randomOutputDir + testId + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}-%i.txt",
- // sizeThreshold, currentTime, 0, maxHistory, true);
- //
- // incCurrentTime(100);
- // tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
- // int runLength = 1000;
- //
- // for (int i = 0; i < runLength; i++) {
- // String msg = "" + i;
- // rfa1.doAppend(msg);
- // incCurrentTime(20);
- // tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
- // add(tbrp1.future);
- // }
- //
- // Thread.yield();
- // // wait for compression to finish
- // waitForJobsToComplete();
- //
- // assertEquals(maxHistory + 1, getFilesInDirectory(randomOutputDir).length);
- // sortedContentCheck(randomOutputDir, 1000, "", 863);
- // }
+ }
+
+ static final boolean FIRST_PHASE_ONLY = false;
+ static final boolean WITH_SECOND_PHASE = true;
+ static String DEFAULT_COMPRESSION_SUFFIX = "";
+
+ @Test
+ public void noCompression_FileSet_NoRestart_1() throws InterruptedException, ExecutionException, IOException {
+ generic("test1", "toto.log", FIRST_PHASE_ONLY, DEFAULT_COMPRESSION_SUFFIX);
+ }
+
+ @Test
+ public void noCompression_FileBlank_NoRestart_2() throws Exception {
+ generic("test2", null, FIRST_PHASE_ONLY, DEFAULT_COMPRESSION_SUFFIX);
+ }
+
+ @Test
+ public void noCompression_FileBlank_WithStopStart_3() throws Exception {
+ generic("test3", null, WITH_SECOND_PHASE, DEFAULT_COMPRESSION_SUFFIX);
+ }
+
+ @Test
+ public void noCompression_FileSet_WithStopStart_4() throws Exception {
+ generic("test4", "test4.log", WITH_SECOND_PHASE, DEFAULT_COMPRESSION_SUFFIX);
+ }
+
+ @Test
+ public void withGZCompression_FileSet_NoRestart_5() throws Exception {
+ generic("test5", "toto.log", FIRST_PHASE_ONLY, ".gz");
+ }
+
+ @Test
+ public void withGZCompression_FileBlank_NoRestart_6() throws Exception {
+ generic("test6", null, FIRST_PHASE_ONLY, ".gz");
+ }
+
+ @Test
+ public void withZipCompression_FileSet_NoRestart_7() throws Exception {
+ generic("test7", "toto.log", FIRST_PHASE_ONLY, ".zip");
+ List<String> zipFiles = filterElementsInListBySuffix(".zip");
+ checkZipEntryMatchesZipFilename(zipFiles);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeBasedRollingTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeBasedRollingTest.java
index 1964123..0368eef 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeBasedRollingTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeBasedRollingTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,106 +13,106 @@
*/
package ch.qos.logback.core.rolling;
-import java.io.IOException;
-import java.util.List;
-
+import ch.qos.logback.core.encoder.EchoEncoder;
+import ch.qos.logback.core.util.CoreTestConstants;
import org.junit.Before;
import org.junit.Test;
-import ch.qos.logback.core.encoder.EchoEncoder;
-import ch.qos.logback.core.util.CoreTestConstants;
-import ch.qos.logback.core.util.FileSize;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
public class SizeBasedRollingTest extends ScaffoldingForRollingTests {
- RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
- FixedWindowRollingPolicy fwrp = new FixedWindowRollingPolicy();
- SizeBasedTriggeringPolicy<Object> sizeBasedTriggeringPolicy = new SizeBasedTriggeringPolicy<Object>();
- EchoEncoder<Object> encoder = new EchoEncoder<Object>();
-
- @Before
- public void setUp() {
- super.setUp();
- fwrp.setContext(context);
- fwrp.setParent(rfa);
- rfa.setContext(context);
- sizeBasedTriggeringPolicy.setContext(context);
- }
-
- private void initRFA(String filename) {
- rfa.setEncoder(encoder);
- if (filename != null) {
- rfa.setFile(filename);
- }
+ RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
+ FixedWindowRollingPolicy fwrp = new FixedWindowRollingPolicy();
+ SizeBasedTriggeringPolicy<Object> sizeBasedTriggeringPolicy = new SizeBasedTriggeringPolicy<Object>();
+ EchoEncoder<Object> encoder = new EchoEncoder<Object>();
+
+
+ @Before
+ public void setUp() {
+ super.setUp();
+ fwrp.setContext(context);
+ fwrp.setParent(rfa);
+ rfa.setContext(context);
+ sizeBasedTriggeringPolicy.setContext(context);
+ }
+
+ private void initRFA(String filename) {
+ rfa.setEncoder(encoder);
+ if (filename != null) {
+ rfa.setFile(filename);
}
-
- /**
- * Test whether FixedWindowRollingPolicy throws an exception when the
- * ActiveFileName is not set.
- */
- @Test(expected = IllegalStateException.class)
- public void activeFileNameNotSet() {
- sizeBasedTriggeringPolicy.setMaxFileSize(new FileSize(100));
- sizeBasedTriggeringPolicy.start();
-
- fwrp.setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "sizeBased-test1.%i");
- fwrp.start();
- // The absence of activeFileName option should cause an exception.
- }
-
- void generic(String testName, String fileName, String filenamePattern, List<String> expectedFilenameList) throws InterruptedException, IOException {
- rfa.setName("ROLLING");
- initRFA(randomOutputDir + fileName);
-
- sizeBasedTriggeringPolicy.setMaxFileSize(new FileSize(100));
- fwrp.setMinIndex(0);
- fwrp.setFileNamePattern(randomOutputDir + filenamePattern);
-
- rfa.triggeringPolicy = sizeBasedTriggeringPolicy;
- rfa.rollingPolicy = fwrp;
-
- fwrp.start();
- sizeBasedTriggeringPolicy.start();
- rfa.start();
-
- int runLength = 40;
- String prefix = "hello";
- for (int i = 0; i < runLength; i++) {
- Thread.sleep(10);
- rfa.doAppend(prefix + i);
- }
- rfa.stop();
-
- existenceCheck(expectedFilenameList);
- reverseSortedContentCheck(randomOutputDir, runLength, prefix);
- }
-
- @Test
- public void smoke() throws IOException, InterruptedException {
- expectedFilenameList.add(randomOutputDir + "a-sizeBased-smoke.log");
- expectedFilenameList.add(randomOutputDir + "sizeBased-smoke.0");
- expectedFilenameList.add(randomOutputDir + "sizeBased-smoke.1");
- generic("zipped", "a-sizeBased-smoke.log", "sizeBased-smoke.%i", expectedFilenameList);
-
- }
-
- @Test
- public void gz() throws IOException, InterruptedException {
- expectedFilenameList.add(randomOutputDir + "a-sbr-gzed.log");
- expectedFilenameList.add(randomOutputDir + "sbr-gzed.0.gz");
- expectedFilenameList.add(randomOutputDir + "sbr-gzed.1.gz");
- generic("gzed", "a-sbr-gzed.log", "sbr-gzed.%i.gz", expectedFilenameList);
- }
-
- // see also LBCORE-199
- @Test
- public void zipped() throws IOException, InterruptedException {
- expectedFilenameList.add(randomOutputDir + "a-sbr-zipped.log");
- expectedFilenameList.add(randomOutputDir + "sbr-zipped.0.zip");
- expectedFilenameList.add(randomOutputDir + "sbr-zipped.1.zip");
- generic("zipped", "a-sbr-zipped.log", "sbr-zipped.%i.zip", expectedFilenameList);
-
- List<String> zipFiles = filterElementsInListBySuffix(".zip");
- zipEntryNameCheck(zipFiles, "sbr-zipped.20\\d{2}-\\d{2}-\\d{2}_\\d{4}");
+ }
+
+ /**
+ * Test whether FixedWindowRollingPolicy throws an exception when the
+ * ActiveFileName is not set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void activeFileNameNotSet() {
+ sizeBasedTriggeringPolicy.setMaxFileSize("100");
+ sizeBasedTriggeringPolicy.start();
+
+ fwrp.setFileNamePattern(CoreTestConstants.OUTPUT_DIR_PREFIX + "sizeBased-test1.%i");
+ fwrp.start();
+ // The absence of activeFileName option should cause an exception.
+ }
+
+
+ void generic(String testName, String fileName, String filenamePattern, List<String> expectedFilenameList) throws InterruptedException, IOException {
+ rfa.setName("ROLLING");
+ initRFA(randomOutputDir + fileName);
+
+ sizeBasedTriggeringPolicy.setMaxFileSize("100");
+ fwrp.setMinIndex(0);
+ fwrp.setFileNamePattern(randomOutputDir + filenamePattern);
+
+ rfa.triggeringPolicy = sizeBasedTriggeringPolicy;
+ rfa.rollingPolicy = fwrp;
+
+ fwrp.start();
+ sizeBasedTriggeringPolicy.start();
+ rfa.start();
+
+ int runLength = 40;
+ String prefix = "hello";
+ for (int i = 0; i < runLength; i++){
+ Thread.sleep(10);
+ rfa.doAppend(prefix + i);
}
+ rfa.stop();
+
+ existenceCheck(expectedFilenameList);
+ reverseSortedContentCheck(randomOutputDir, runLength, prefix);
+ }
+
+ @Test
+ public void smoke() throws IOException, InterruptedException {
+ expectedFilenameList.add(randomOutputDir + "a-sizeBased-smoke.log");
+ expectedFilenameList.add(randomOutputDir + "sizeBased-smoke.0");
+ expectedFilenameList.add(randomOutputDir + "sizeBased-smoke.1");
+ generic("zipped", "a-sizeBased-smoke.log", "sizeBased-smoke.%i", expectedFilenameList);
+
+ }
+ @Test
+ public void gz() throws IOException, InterruptedException {
+ expectedFilenameList.add(randomOutputDir + "a-sbr-gzed.log");
+ expectedFilenameList.add(randomOutputDir + "sbr-gzed.0.gz");
+ expectedFilenameList.add(randomOutputDir + "sbr-gzed.1.gz");
+ generic("gzed", "a-sbr-gzed.log", "sbr-gzed.%i.gz", expectedFilenameList);
+ }
+
+ // see also LBCORE-199
+ @Test
+ public void zipped() throws IOException, InterruptedException {
+ expectedFilenameList.add(randomOutputDir + "a-sbr-zipped.log");
+ expectedFilenameList.add(randomOutputDir + "sbr-zipped.0.zip");
+ expectedFilenameList.add(randomOutputDir + "sbr-zipped.1.zip");
+ generic("zipped", "a-sbr-zipped.log", "sbr-zipped.%i.zip", expectedFilenameList);
+
+ List<String> zipFiles = filterElementsInListBySuffix(".zip");
+ zipEntryNameCheck(zipFiles, "sbr-zipped.20\\d{2}-\\d{2}-\\d{2}_\\d{4}");
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicyTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicyTest.java
new file mode 100644
index 0000000..08ca2ce
--- /dev/null
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicyTest.java
@@ -0,0 +1,58 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.core.rolling;
+
+import junit.framework.TestCase;
+import ch.qos.logback.core.Context;
+import ch.qos.logback.core.ContextBase;
+
+public class SizeBasedTriggeringPolicyTest extends TestCase {
+
+ public void testStringToLong() {
+ Context context = new ContextBase();
+ SizeBasedTriggeringPolicy policy = new SizeBasedTriggeringPolicy();
+ policy.setContext(context);
+
+ Long result;
+
+ {
+ result = policy.toFileSize("123");
+ assertEquals(new Long("123"), result);
+ }
+ {
+ result = policy.toFileSize("123KB");
+ // = 123 * 1024
+ assertEquals(new Long("125952"), result);
+ }
+ {
+ result = policy.toFileSize("123MB");
+ // = 123 * 1024 * 1024
+ assertEquals(new Long("128974848"), result);
+ }
+ {
+ result = policy.toFileSize("123GB");
+ // = 123 * 1024 * 1024 * 1024
+ assertEquals(new Long("132070244352"), result);
+ }
+
+ {
+ result = policy.toFileSize("123xxxx");
+ // = 123 * 1024 * 1024 * 1024
+ assertEquals(new Long(SizeBasedTriggeringPolicy.DEFAULT_MAX_FILE_SIZE),
+ result);
+ assertEquals(2, context.getStatusManager().getCount());
+ }
+
+ }
+}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicyBaseTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicyBaseTest.java
index 0ee8349..d405f5e 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicyBaseTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedFileNamingAndTriggeringPolicyBaseTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,104 +13,72 @@
*/
package ch.qos.logback.core.rolling;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
+import ch.qos.logback.core.Context;
+import ch.qos.logback.core.ContextBase;
import org.junit.Before;
import org.junit.Test;
-import ch.qos.logback.core.Context;
-import ch.qos.logback.core.ContextBase;
-import ch.qos.logback.core.status.Status;
-import ch.qos.logback.core.status.StatusChecker;
+import java.util.logging.Logger;
+
+import static org.junit.Assert.assertEquals;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class TimeBasedFileNamingAndTriggeringPolicyBaseTest {
- static long MILLIS_IN_MINUTE = 60 * 1000;
- static long MILLIS_IN_HOUR = 60 * MILLIS_IN_MINUTE;
-
- Context context = new ContextBase();
- RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
- TimeBasedRollingPolicy<Object> tbrp = new TimeBasedRollingPolicy<Object>();
- DefaultTimeBasedFileNamingAndTriggeringPolicy<Object> timeBasedFNATP = new DefaultTimeBasedFileNamingAndTriggeringPolicy<Object>();
-
- @Before
- public void setUp() {
- rfa.setContext(context);
- tbrp.setContext(context);
- timeBasedFNATP.setContext(context);
-
- rfa.setRollingPolicy(tbrp);
- tbrp.setParent(rfa);
- tbrp.setTimeBasedFileNamingAndTriggeringPolicy(timeBasedFNATP);
- timeBasedFNATP.setTimeBasedRollingPolicy(tbrp);
- }
-
- @Test
- public void singleDate() {
- // Tuesday December 20th 17:59:01 CET 2011
- long startTime = 1324400341553L;
- tbrp.setFileNamePattern("foo-%d{yyyy-MM'T'mm}.log");
- tbrp.start();
-
- timeBasedFNATP.setCurrentTime(startTime);
- timeBasedFNATP.start();
-
- timeBasedFNATP.setCurrentTime(startTime + MILLIS_IN_MINUTE);
- timeBasedFNATP.isTriggeringEvent(null, null);
- String elapsedPeriodsFileName = timeBasedFNATP.getElapsedPeriodsFileName();
- assertEquals("foo-2011-12T59.log", elapsedPeriodsFileName);
- }
-
- // see "log rollover should be configurable using %d multiple times in file name pattern"
- // http://jira.qos.ch/browse/LBCORE-242
-
- @Test
- public void multiDate() {
- // Tuesday December 20th 17:59:01 CET 2011
- long startTime = 1324400341553L;
- tbrp.setFileNamePattern("foo-%d{yyyy-MM, AUX}/%d{mm}.log");
- tbrp.start();
-
- timeBasedFNATP.setCurrentTime(startTime);
- timeBasedFNATP.start();
-
- timeBasedFNATP.setCurrentTime(startTime + MILLIS_IN_MINUTE);
- boolean triggerred = timeBasedFNATP.isTriggeringEvent(null, null);
- assertTrue(triggerred);
- String elapsedPeriodsFileName = timeBasedFNATP.getElapsedPeriodsFileName();
- assertEquals("foo-2011-12/59.log", elapsedPeriodsFileName);
- }
-
- @Test
- public void withTimeZone() {
- // Tuesday December 20th 17:59:01 CET 2011
- long startTime = 1324400341553L;
- tbrp.setFileNamePattern("foo-%d{yyyy-MM-dd, GMT+5}.log");
- tbrp.start();
-
- timeBasedFNATP.setCurrentTime(startTime);
- timeBasedFNATP.start();
-
- timeBasedFNATP.setCurrentTime(startTime + MILLIS_IN_MINUTE + 2 * MILLIS_IN_HOUR);
- boolean triggerred = timeBasedFNATP.isTriggeringEvent(null, null);
- assertTrue(triggerred);
- String elapsedPeriodsFileName = timeBasedFNATP.getElapsedPeriodsFileName();
- assertEquals("foo-2011-12-20.log", elapsedPeriodsFileName);
- }
-
- @Test
- public void extraIntegerTokenInFileNamePatternShouldBeDetected() {
- String pattern = "test-%d{yyyy-MM-dd'T'HH}-%i.log.zip";
- tbrp.setFileNamePattern(pattern);
- tbrp.start();
-
- assertFalse(tbrp.isStarted());
- StatusChecker statusChecker = new StatusChecker(context);
- statusChecker.assertContainsMatch(Status.ERROR, "Filename pattern .{37} contains an integer token converter");
- }
+ static long MILLIS_IN_MINUTE = 60*1000;
+
+ Context context = new ContextBase();
+ RollingFileAppender rfa = new RollingFileAppender();
+ TimeBasedRollingPolicy tbrp = new TimeBasedRollingPolicy();
+ DefaultTimeBasedFileNamingAndTriggeringPolicy timeBasedFNATP = new DefaultTimeBasedFileNamingAndTriggeringPolicy();
+
+ @Before
+ public void setUp() {
+ rfa.setContext(context);
+ tbrp.setContext(context);
+ timeBasedFNATP.setContext(context);
+
+ rfa.setRollingPolicy(tbrp);
+ tbrp.setParent(rfa);
+ tbrp.setTimeBasedFileNamingAndTriggeringPolicy(timeBasedFNATP);
+ timeBasedFNATP.setTimeBasedRollingPolicy(tbrp);
+ }
+
+ @Test
+ public void singleDate() {
+ // Tuesday December 20th 17:59:01 CET 2011
+ long startTime = 1324400341553L;
+ tbrp.setFileNamePattern("foo-%d{yyyy-MM'T'mm}.log");
+ tbrp.start();
+
+ timeBasedFNATP.setCurrentTime(startTime);
+ timeBasedFNATP.start();
+
+ timeBasedFNATP.setCurrentTime(startTime+MILLIS_IN_MINUTE);
+ timeBasedFNATP.isTriggeringEvent(null, null);
+ String elapsedPeriodsFileName = timeBasedFNATP.getElapsedPeriodsFileName();
+ assertEquals("foo-2011-12T59.log", elapsedPeriodsFileName);
+ }
+
+ // see "log rollover should be configurable using %d multiple times in file name pattern"
+ // http://jira.qos.ch/browse/LBCORE-242
+
+ @Test
+ public void multiDate() {
+ // Tuesday December 20th 17:59:01 CET 2011
+ long startTime = 1324400341553L;
+ tbrp.setFileNamePattern("foo-%d{yyyy-MM, AUX}/%d{mm}.log");
+ tbrp.start();
+
+ timeBasedFNATP.setCurrentTime(startTime);
+ timeBasedFNATP.start();
+
+ timeBasedFNATP.setCurrentTime(startTime+MILLIS_IN_MINUTE);
+ timeBasedFNATP.isTriggeringEvent(null, null);
+ String elapsedPeriodsFileName = timeBasedFNATP.getElapsedPeriodsFileName();
+ assertEquals("foo-2011-12/59.log", elapsedPeriodsFileName);
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java
index 26e3618..eec46c8 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,17 +13,17 @@
*/
package ch.qos.logback.core.rolling;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
+import ch.qos.logback.core.encoder.EchoEncoder;
+import ch.qos.logback.core.testUtil.EnvUtilForTests;
+import ch.qos.logback.core.util.StatusPrinter;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import ch.qos.logback.core.encoder.EchoEncoder;
-import ch.qos.logback.core.testUtil.EnvUtilForTests;
-import ch.qos.logback.core.util.StatusPrinter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
/**
* A rather exhaustive set of tests. Tests include leaving the file option
@@ -48,186 +48,238 @@ import ch.qos.logback.core.util.StatusPrinter;
*/
public class TimeBasedRollingTest extends ScaffoldingForRollingTests {
- static final int NO_RESTART = 0;
- static final int WITH_RESTART = 1;
- static final int WITH_RESTART_AND_LONG_WAIT = 2000;
+ static final int NO_RESTART = 0;
+ static final int WITH_RESTART = 1;
+ static final int WITH_RESTART_AND_LONG_WAIT = 2000;
- static final boolean FILE_OPTION_SET = true;
- static final boolean FILE_OPTION_BLANK = false;
+ static final boolean FILE_OPTION_SET = true;
+ static final boolean FILE_OPTION_BLANK = false;
- RollingFileAppender<Object> rfa1 = new RollingFileAppender<Object>();
- TimeBasedRollingPolicy<Object> tbrp1 = new TimeBasedRollingPolicy<Object>();
- RollingFileAppender<Object> rfa2 = new RollingFileAppender<Object>();
- TimeBasedRollingPolicy<Object> tbrp2 = new TimeBasedRollingPolicy<Object>();
+ RollingFileAppender<Object> rfa1 = new RollingFileAppender<Object>();
+ TimeBasedRollingPolicy<Object> tbrp1 = new TimeBasedRollingPolicy<Object>();
- EchoEncoder<Object> encoder = new EchoEncoder<Object>();
+ RollingFileAppender<Object> rfa2 = new RollingFileAppender<Object>();
+ TimeBasedRollingPolicy<Object> tbrp2 = new TimeBasedRollingPolicy<Object>();
- RolloverChecker rolloverChecker;
+ EchoEncoder<Object> encoder = new EchoEncoder<Object>();
- @Before
- @Override
- public void setUp() {
- super.setUp();
- }
+ RolloverChecker rolloverChecker;
- @After
- public void tearDown() {
- }
+ @Before
+ @Override
+ public void setUp() {
+ super.setUp();
+ }
- void initRFA(RollingFileAppender<Object> rfa, String filename) {
- rfa.setContext(context);
- rfa.setEncoder(encoder);
- if (filename != null) {
- rfa.setFile(filename);
- }
- }
+ @After
+ public void tearDown() {
+ }
- void initTRBP(RollingFileAppender<Object> rfa, TimeBasedRollingPolicy<Object> tbrp, String filenamePattern, long givenTime) {
- tbrp.setContext(context);
- tbrp.setFileNamePattern(filenamePattern);
- tbrp.setParent(rfa);
- tbrp.timeBasedFileNamingAndTriggeringPolicy = new DefaultTimeBasedFileNamingAndTriggeringPolicy<Object>();
- tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(givenTime);
- rfa.setRollingPolicy(tbrp);
- tbrp.start();
- rfa.start();
+ void initRFA(RollingFileAppender<Object> rfa, String filename) {
+ rfa.setContext(context);
+ rfa.setEncoder(encoder);
+ if (filename != null) {
+ rfa.setFile(filename);
}
-
- void genericTest(String testId, String patternPrefix, String compressionSuffix, boolean fileOptionIsSet, int waitDuration) throws IOException {
- String fileName = fileOptionIsSet ? testId2FileName(testId) : null;
- initRFA(rfa1, fileName);
-
- String fileNamePatternStr = randomOutputDir + patternPrefix + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}" + compressionSuffix;
-
- initTRBP(rfa1, tbrp1, fileNamePatternStr, currentTime);
-
- // compute the current filename
- addExpectedFileName_ByDate(fileNamePatternStr, getMillisOfCurrentPeriodsStart());
-
- incCurrentTime(1100);
- tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
-
- for (int i = 0; i < 3; i++) {
- rfa1.doAppend("Hello---" + i);
- addExpectedFileNamedIfItsTime_ByDate(fileNamePatternStr);
- incCurrentTime(500);
- tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
- add(tbrp1.compressionFuture);
- add(tbrp1.cleanUpFuture);
- }
- rfa1.stop();
- waitForJobsToComplete();
-
- if (waitDuration != NO_RESTART) {
- doRestart(testId, patternPrefix, fileOptionIsSet, waitDuration);
- }
- waitForJobsToComplete();
-
- massageExpectedFilesToCorresponToCurrentTarget(fileName, fileOptionIsSet);
- StatusPrinter.print(context);
- rolloverChecker.check(expectedFilenameList);
+ }
+
+ void initTRBP(RollingFileAppender<Object> rfa,
+ TimeBasedRollingPolicy<Object> tbrp, String filenamePattern,
+ long givenTime) {
+ tbrp.setContext(context);
+ tbrp.setFileNamePattern(filenamePattern);
+ tbrp.setParent(rfa);
+ tbrp.timeBasedFileNamingAndTriggeringPolicy = new DefaultTimeBasedFileNamingAndTriggeringPolicy<Object>();
+ tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(givenTime);
+ rfa.setRollingPolicy(tbrp);
+ tbrp.start();
+ rfa.start();
+ }
+
+
+ void genericTest(String testId, String patternPrefix, String compressionSuffix, boolean fileOptionIsSet, int waitDuration) throws IOException {
+ String fileName = fileOptionIsSet ? testId2FileName(testId) : null;
+ initRFA(rfa1, fileName);
+
+ String fileNamePatternStr = randomOutputDir + patternPrefix + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}" + compressionSuffix;
+
+ initTRBP(rfa1, tbrp1, fileNamePatternStr, currentTime);
+
+ // compute the current filename
+ addExpectedFileName_ByDate(fileNamePatternStr, getMillisOfCurrentPeriodsStart());
+
+ incCurrentTime(1100);
+ tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
+
+ for (int i = 0; i < 3; i++) {
+ rfa1.doAppend("Hello---" + i);
+ addExpectedFileNamedIfItsTime_ByDate(fileNamePatternStr);
+ incCurrentTime(500);
+ tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
+ add(tbrp1.future);
}
+ rfa1.stop();
+ waitForJobsToComplete();
- void defaultTest(String testId, String patternPrefix, String compressionSuffix, boolean fileOptionIsSet, int waitDuration) throws IOException {
- boolean withCompression = compressionSuffix.length() > 0;
- rolloverChecker = new DefaultRolloverChecker(testId, withCompression, compressionSuffix);
- genericTest(testId, patternPrefix, compressionSuffix, fileOptionIsSet, waitDuration);
+ if (waitDuration != NO_RESTART) {
+ doRestart(testId, patternPrefix, fileOptionIsSet, waitDuration);
}
-
- void doRestart(String testId, String patternPart, boolean fileOptionIsSet, int waitDuration) {
- // change the timestamp of the currently actively file
- File activeFile = new File(rfa1.getFile());
- activeFile.setLastModified(currentTime);
-
- incCurrentTime(waitDuration);
-
- String filePatternStr = randomOutputDir + patternPart + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}";
-
- String fileName = fileOptionIsSet ? testId2FileName(testId) : null;
- initRFA(rfa2, fileName);
- initTRBP(rfa2, tbrp2, filePatternStr, currentTime);
- for (int i = 0; i < 3; i++) {
- rfa2.doAppend("World---" + i);
- addExpectedFileNamedIfItsTime_ByDate(filePatternStr);
- incCurrentTime(100);
- tbrp2.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
- add(tbrp2.compressionFuture);
- add(tbrp1.cleanUpFuture);
- }
- rfa2.stop();
+ waitForJobsToComplete();
+
+ massageExpectedFilesToCorresponToCurrentTarget(fileName, fileOptionIsSet);
+ StatusPrinter.print(context);
+ rolloverChecker.check(expectedFilenameList);
+ }
+
+ void defaultTest(String testId, String patternPrefix, String compressionSuffix, boolean fileOptionIsSet, int waitDuration) throws IOException {
+ boolean withCompression = compressionSuffix.length() > 0;
+ rolloverChecker = new DefaultRolloverChecker(testId, withCompression, compressionSuffix);
+ genericTest(testId, patternPrefix, compressionSuffix, fileOptionIsSet, waitDuration);
+ }
+
+ void doRestart(String testId, String patternPart, boolean fileOptionIsSet, int waitDuration) {
+ // change the timestamp of the currently actively file
+ File activeFile = new File(rfa1.getFile());
+ activeFile.setLastModified(currentTime);
+
+ incCurrentTime(waitDuration);
+
+ String filePatternStr = randomOutputDir + patternPart + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}";
+
+ String fileName = fileOptionIsSet ? testId2FileName(testId) : null;
+ initRFA(rfa2, fileName);
+ initTRBP(rfa2, tbrp2, filePatternStr, currentTime);
+ for (int i = 0; i < 3; i++) {
+ rfa2.doAppend("World---" + i);
+ addExpectedFileNamedIfItsTime_ByDate(filePatternStr);
+ incCurrentTime(100);
+ tbrp2.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
+ add(tbrp2.future);
}
-
- @Test
- public void noCompression_FileBlank_NoRestart_1() throws IOException {
- defaultTest("test1", "test1", "", FILE_OPTION_BLANK, NO_RESTART);
- }
-
- @Test
- public void withCompression_FileBlank_NoRestart_2() throws IOException {
- defaultTest("test2", "test2", ".gz", FILE_OPTION_BLANK, NO_RESTART);
- }
-
- @Test
- public void noCompression_FileBlank_StopRestart_3() throws IOException {
- defaultTest("test3", "test3", "", FILE_OPTION_BLANK, WITH_RESTART);
- }
-
- @Test
- public void noCompression_FileSet_StopRestart_4() throws IOException {
- defaultTest("test4", "test4", "", FILE_OPTION_SET, WITH_RESTART);
- }
-
- @Test
- public void noCompression_FileSet_StopRestart_WithLongWait_4B() throws IOException {
- defaultTest("test4B", "test4B", "", FILE_OPTION_SET, WITH_RESTART_AND_LONG_WAIT);
- }
-
- @Test
- public void noCompression_FileSet_NoRestart_5() throws IOException {
- defaultTest("test5", "test5", "", FILE_OPTION_SET, NO_RESTART);
- }
-
- @Test
- public void withCompression_FileSet_NoRestart_6() throws IOException {
- defaultTest("test6", "test6", ".gz", FILE_OPTION_SET, NO_RESTART);
- }
-
- // LOGBACK-168
- @Test
- public void withMissingTargetDirWithCompression() throws IOException {
- defaultTest("test7", "%d{yyyy-MM-dd, aux}/test7", ".gz", FILE_OPTION_SET, NO_RESTART);
- }
-
- @Test
- public void withMissingTargetDirWithZipCompression() throws IOException {
- defaultTest("test8", "%d{yyyy-MM-dd, aux}/test8", ".zip", FILE_OPTION_SET, NO_RESTART);
- }
-
- @Test
- public void failed_rename() throws IOException {
- if (!EnvUtilForTests.isWindows())
- return;
-
- FileOutputStream fos = null;
- try {
- String fileName = testId2FileName("failed_rename");
- File file = new File(fileName);
- file.getParentFile().mkdirs();
-
- fos = new FileOutputStream(fileName);
-
- String testId = "failed_rename";
- rolloverChecker = new ZRolloverChecker(testId);
- genericTest(testId, "failed_rename", "", FILE_OPTION_SET, NO_RESTART);
-
- } finally {
- StatusPrinter.print(context);
- if (fos != null)
- fos.close();
- }
+ rfa2.stop();
+ }
+
+
+ @Test
+ public void noCompression_FileBlank_NoRestart_1() throws IOException {
+ defaultTest("test1", "test1", "", FILE_OPTION_BLANK, NO_RESTART);
+ }
+
+ @Test
+ public void withCompression_FileBlank_NoRestart_2() throws IOException {
+ defaultTest("test2", "test2", ".gz", FILE_OPTION_BLANK, NO_RESTART);
+ }
+
+ @Test
+ public void noCompression_FileBlank_StopRestart_3() throws IOException {
+ defaultTest("test3", "test3", "", FILE_OPTION_BLANK, WITH_RESTART);
+ }
+
+ @Test
+ public void noCompression_FileSet_StopRestart_4() throws IOException {
+ defaultTest("test4", "test4", "", FILE_OPTION_SET, WITH_RESTART);
+ }
+
+ @Test
+ public void noCompression_FileSet_StopRestart_WithLongWait_4B() throws IOException {
+ defaultTest("test4B", "test4B", "", FILE_OPTION_SET, WITH_RESTART_AND_LONG_WAIT);
+ }
+
+ @Test
+ public void noCompression_FileSet_NoRestart_5() throws IOException {
+ defaultTest("test5", "test6", "", FILE_OPTION_SET, NO_RESTART);
+ }
+
+ @Test
+ public void withCompression_FileSet_NoRestart_6() throws IOException {
+ defaultTest("test6", "test6", ".gz", FILE_OPTION_SET, NO_RESTART);
+ }
+
+ // LOGBACK-168
+ @Test
+ public void withMissingTargetDirWithCompression() throws IOException {
+ defaultTest("test7", "%d{yyyy-MM-dd, aux}/", ".gz", FILE_OPTION_SET, NO_RESTART);
+ }
+
+ @Test
+ public void withMissingTargetDirWithZipCompression() throws IOException {
+ defaultTest("test8", "%d{yyyy-MM-dd, aux}/", ".zip", FILE_OPTION_SET, NO_RESTART);
+ }
+
+ @Test
+ public void failed_rename() throws IOException {
+ if (!EnvUtilForTests.isWindows())
+ return;
+
+ FileOutputStream fos = null;
+ try {
+ String fileName = testId2FileName("failed_rename");
+ File file = new File(fileName);
+ file.getParentFile().mkdirs();
+
+ fos = new FileOutputStream(fileName);
+
+ String testId = "failed_rename";
+ rolloverChecker = new ZRolloverChecker(testId);
+ genericTest(testId, "failed_rename", "", FILE_OPTION_SET, NO_RESTART);
+
+
+ } finally {
+ StatusPrinter.print(context);
+ if (fos != null) fos.close();
}
-
-
-
+ }
+
+//
+// @Test
+// public void withMissingTargetDir() throws Exception {
+// String testId = "missingTargetDir";
+//
+// initRFA(rfa1, testId2FileName(testId));
+// int secondDiff = RandomUtil.getPositiveInt();
+// String randomTargetDir = CoreTestConstants.OUTPUT_DIR_PREFIX + secondDiff + '/';
+//
+// System.out.println("randomOutputDir" + randomOutputDir);
+// System.out.println("randomTargetDir" + randomTargetDir);
+//
+// initTRBP(rfa1, tbrp1, randomTargetDir + testId + "-%d{"
+// + DATE_PATTERN_WITH_SECONDS + "}", currentTime);
+//
+// addExpectedFileName_ByDate(randomTargetDir, testId, getDateOfCurrentPeriodsStart(), false);
+//
+// incCurrentTime(1100);
+// tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
+//
+// for (int i = 0; i < 3; i++) {
+// rfa1.doAppend("Hello---" + i);
+// addExpectedFileNamedIfItsTime_ByDate(randomTargetDir, testId, false);
+// incCurrentTime(500);
+// tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
+// }
+// massageExpectedFilesToCorresponToCurrentTarget("missingTargetDir.log");
+// int i = 0;
+// for (String fn : expectedFilenameList) {
+// System.out.println("expectedFile=" + fn);
+// assertTrue(Compare.compare(fn, CoreTestConstants.TEST_SRC_PREFIX
+// + "witness/rolling/tbr-test5." + i++));
+// }
+//
+// }
+//
+// =========================================================================
+// utility methods
+// =========================================================================
+//
+// void massageExpectedFilesToCorresponToCurrentTarget(String file) {
+// // we added one too many files by date
+// expectedFilenameList.remove(expectedFilenameList.size() - 1);
+// // since file is set, we have to add it
+// addExpectedFileName_ByFile(file);
+// }
+//
+// void addExpectedFileName_ByFile(String filenameSuffix) {
+// String fn = randomOutputDir + filenameSuffix;
+// expectedFilenameList.add(fn);
+// }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithArchiveRemoval_Test.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithArchiveRemoval_Test.java
index 0140014..9f457f0 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithArchiveRemoval_Test.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithArchiveRemoval_Test.java
@@ -1,585 +1,401 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
- * or (per the licensee's choosing)
+ * or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
package ch.qos.logback.core.rolling;
-import static ch.qos.logback.core.CoreConstants.DAILY_DATE_PATTERN;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import ch.qos.logback.core.Context;
+import ch.qos.logback.core.ContextBase;
+import ch.qos.logback.core.encoder.EchoEncoder;
+import ch.qos.logback.core.rolling.helper.RollingCalendar;
+import ch.qos.logback.core.testUtil.RandomUtil;
+import ch.qos.logback.core.util.CoreTestConstants;
+import ch.qos.logback.core.util.StatusPrinter;
+import org.junit.Before;
+import org.junit.Test;
import java.io.File;
import java.io.FileFilter;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.joda.time.DateTimeZone;
-import org.joda.time.Days;
-import org.joda.time.LocalDate;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import ch.qos.logback.core.CoreConstants;
-import ch.qos.logback.core.pattern.SpacePadder;
-import ch.qos.logback.core.rolling.helper.RollingCalendar;
-import ch.qos.logback.core.status.StatusChecker;
-import ch.qos.logback.core.util.FileSize;
-import ch.qos.logback.core.util.FixedRateInvocationGate;
-import ch.qos.logback.core.util.StatusPrinter;
+import static ch.qos.logback.core.CoreConstants.DAILY_DATE_PATTERN;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
public class TimeBasedRollingWithArchiveRemoval_Test extends ScaffoldingForRollingTests {
- String MONTHLY_DATE_PATTERN = "yyyy-MM";
- String MONTHLY_CRONOLOG_DATE_PATTERN = "yyyy/MM";
- final String DAILY_CRONOLOG_DATE_PATTERN = "yyyy/MM/dd";
-
- RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
- TimeBasedRollingPolicy<Object> tbrp = new TimeBasedRollingPolicy<Object>();
-
- // by default tbfnatp is an instance of DefaultTimeBasedFileNamingAndTriggeringPolicy
- TimeBasedFileNamingAndTriggeringPolicy<Object> tbfnatp = new DefaultTimeBasedFileNamingAndTriggeringPolicy<Object>();
-
- StatusChecker checker = new StatusChecker(context);
-
- static long MILLIS_IN_MINUTE = 60 * 1000;
- static long MILLIS_IN_HOUR = 60 * MILLIS_IN_MINUTE;
- static long MILLIS_IN_DAY = 24 * MILLIS_IN_HOUR;
- static long MILLIS_IN_MONTH = (long) ((365.242199 / 12) * MILLIS_IN_DAY);
- static int MONTHS_IN_YEAR = 12;
-
- // Wed Mar 23 23:07:05 CET 2016
- static final long WED_2016_03_23_T_230705_CET = 1458770825333L;
- static final long THU_2016_03_17_T_230330_CET = 1458252210975L;
-
- int slashCount = 0;
- int ticksPerPeriod = 216;
-
- ConfigParameters cp; // initialized in setup
- FixedRateInvocationGate fixedRateInvocationGate = new FixedRateInvocationGate(ticksPerPeriod / 2);
-
- @Before
- public void setUp() {
- super.setUp();
- this.cp = new ConfigParameters(currentTime);
- }
-
- private int computeSlashCount(String datePattern) {
- if (datePattern == null)
- return 0;
- else {
- int count = 0;
- for (int i = 0; i < datePattern.length(); i++) {
- char c = datePattern.charAt(i);
- if (c == '/')
- count++;
- }
- return count;
- }
- }
-
- // test that the number of files at the end of the test is same as the expected number taking into account end dates
- // near the beginning of a new year. This test has been run in a loop with start date varying over a two years
- // with success.
- @Test
- public void monthlyRolloverOverManyPeriods() {
- this.slashCount = computeSlashCount(MONTHLY_CRONOLOG_DATE_PATTERN);
- int maxHistory = 2;
- int simulatedNumberOfPeriods = 30;
- String fileNamePattern = randomOutputDir + "/%d{" + MONTHLY_CRONOLOG_DATE_PATTERN + "}/clean.txt.zip";
-
- cp.maxHistory(maxHistory).fileNamePattern(fileNamePattern).simulatedNumberOfPeriods(simulatedNumberOfPeriods).periodDurationInMillis(MILLIS_IN_MONTH);
-
- long startTime = currentTime;
- long endTime = logOverMultiplePeriods(cp);
- System.out.println("randomOutputDir:" + randomOutputDir);
- System.out.println("start:" + startTime + ", end=" + endTime);
- int differenceInMonths = RollingCalendar.diffInMonths(startTime, endTime);
- System.out.println("differenceInMonths:" + differenceInMonths);
- Calendar startTimeAsCalendar = Calendar.getInstance();
- startTimeAsCalendar.setTimeInMillis(startTime);
- int indexOfStartPeriod = startTimeAsCalendar.get(Calendar.MONTH);
- boolean withExtraFolder = extraFolder(differenceInMonths, MONTHS_IN_YEAR, indexOfStartPeriod, maxHistory);
-
- checkFileCount(expectedCountWithFolders(maxHistory, withExtraFolder));
- }
-
- long generateDailyRollover(ConfigParameters cp) {
- this.slashCount = computeSlashCount(DAILY_DATE_PATTERN);
- cp.fileNamePattern(randomOutputDir + "clean-%d{" + DAILY_DATE_PATTERN + "}.txt");
- return logOverMultiplePeriods(cp);
- }
-
- long generateDailyRolloverAndCheckFileCount(ConfigParameters cp) {
- long millisAtEnd = generateDailyRollover(cp);
- int periodBarriersCrossed = computeCrossedDayBarriers(currentTime, millisAtEnd);
- System.out.println("**** " + periodBarriersCrossed);
- checkFileCount(expectedCountWithoutFoldersWithInactivity(cp.maxHistory, periodBarriersCrossed, cp.startInactivity + cp.numInactivityPeriods));
- return millisAtEnd;
- }
-
- @Test
- public void checkCrossedPeriodsWithDSTBarrier() {
- long SAT_2016_03_26_T_230705_CET = WED_2016_03_23_T_230705_CET + 3 * CoreConstants.MILLIS_IN_ONE_DAY;
- System.out.println("SAT_2016_03_26_T_230705_CET " + new Date(SAT_2016_03_26_T_230705_CET));
- long MON_2016_03_28_T_000705_CET = SAT_2016_03_26_T_230705_CET + CoreConstants.MILLIS_IN_ONE_DAY;
- System.out.println("MON_2016_03_28_T_000705_CET " + new Date(MON_2016_03_28_T_000705_CET));
-
- int result = computeCrossedDayBarriers(SAT_2016_03_26_T_230705_CET, MON_2016_03_28_T_000705_CET, "CET");
- assertEquals(2, result);
- }
-
- private int computeCrossedDayBarriers(long currentTime, long millisAtEnd) {
- return computeCrossedDayBarriers(currentTime, millisAtEnd, null);
- }
-
- private int computeCrossedDayBarriers(long currentTime, long millisAtEnd, String timeZoneID) {
- DateTimeZone dateTimeZone = DateTimeZone.getDefault();
- if (timeZoneID != null) {
- dateTimeZone = DateTimeZone.forID(timeZoneID);
- }
- LocalDate startInstant = new LocalDate(currentTime, dateTimeZone);
- LocalDate endInstant = new LocalDate(millisAtEnd, dateTimeZone);
- Days days = Days.daysBetween(startInstant, endInstant);
- return days.getDays();
- }
-
- @Test
- public void checkCleanupForBasicDailyRollover() {
- cp.maxHistory(20).simulatedNumberOfPeriods(20 * 3).startInactivity(0).numInactivityPeriods(0);
- generateDailyRolloverAndCheckFileCount(cp);
- }
-
- @Test
- public void checkCleanupForBasicDailyRolloverWithSizeCap() {
- long bytesOutputPerPeriod = 15984;
- int sizeInUnitsOfBytesPerPeriod = 2;
-
- cp.maxHistory(5).simulatedNumberOfPeriods(10).sizeCap(sizeInUnitsOfBytesPerPeriod * bytesOutputPerPeriod + 1000);
- generateDailyRollover(cp);
- StatusPrinter.print(context);
- checkFileCount(sizeInUnitsOfBytesPerPeriod + 1);
- }
-
- @Test
- public void checkThatSmallTotalSizeCapLeavesAtLeastOneArhcive() {
- long WED_2016_03_23_T_131345_CET = WED_2016_03_23_T_230705_CET - 10 * CoreConstants.MILLIS_IN_ONE_HOUR;
-
- // long bytesOutputPerPeriod = 15984;
-
- cp = new ConfigParameters(WED_2016_03_23_T_131345_CET);
- final int verySmallCapSize = 1;
- cp.maxHistory(5).simulatedNumberOfPeriods(3).sizeCap(verySmallCapSize);
- generateDailyRollover(cp);
- StatusPrinter.print(context);
- checkFileCountAtMost(1);
-
- }
-
- @Test
- public void checkCleanupForBasicDailyRolloverWithMaxSize() {
- cp.maxHistory(6).simulatedNumberOfPeriods(30).startInactivity(10).numInactivityPeriods(1);
- generateDailyRolloverAndCheckFileCount(cp);
- }
-
- // Since the duration of a month (in seconds) varies from month to month, tests with inactivity period must
- // be conducted with daily rollover not monthly
- @Test
- public void checkCleanupForDailyRollover_15Periods() {
- cp.maxHistory(5).simulatedNumberOfPeriods(15).startInactivity(6).numInactivityPeriods(3);
- generateDailyRolloverAndCheckFileCount(cp);
- }
-
- @Test
- public void checkCleanupForDailyRolloverWithInactivity_30Periods() {
- // / -------
- cp.maxHistory(2).simulatedNumberOfPeriods(30).startInactivity(3).numInactivityPeriods(1);
- generateDailyRolloverAndCheckFileCount(cp);
- }
-
- @Test
- public void checkCleanupForDailyRolloverWithInactivity_10Periods() {
- this.currentTime = THU_2016_03_17_T_230330_CET;
- cp.maxHistory(6).simulatedNumberOfPeriods(10).startInactivity(2).numInactivityPeriods(2);
- generateDailyRolloverAndCheckFileCount(cp);
- }
-
- @Test
- public void checkCleanupForDailyRolloverWithSecondPhase() {
- slashCount = computeSlashCount(DAILY_DATE_PATTERN);
- int maxHistory = 5;
- String fileNamePattern = randomOutputDir + "clean-%d{" + DAILY_DATE_PATTERN + "}.txt";
-
- ConfigParameters cp0 = new ConfigParameters(currentTime).maxHistory(maxHistory).fileNamePattern(fileNamePattern)
- .simulatedNumberOfPeriods(maxHistory * 2);
- long endTime = logOverMultiplePeriods(cp0);
-
- ConfigParameters cp1 = new ConfigParameters(endTime + MILLIS_IN_DAY * 10).maxHistory(maxHistory).fileNamePattern(fileNamePattern)
- .simulatedNumberOfPeriods(maxHistory);
- logOverMultiplePeriods(cp1);
- checkFileCount(expectedCountWithoutFolders(maxHistory));
- }
-
- @Test
- public void dailyRolloverWithCronologPattern() {
- this.slashCount = computeSlashCount(DAILY_CRONOLOG_DATE_PATTERN);
- String fileNamePattern = randomOutputDir + "/%d{" + DAILY_CRONOLOG_DATE_PATTERN + "}/clean.txt.zip";
- cp.maxHistory(8).fileNamePattern(fileNamePattern).simulatedNumberOfPeriods(8 * 3);
- logOverMultiplePeriods(cp);
- int expectedDirMin = 9 + slashCount;
- int expectDirMax = expectedDirMin + 1 + 1;
- expectedFileAndDirCount(9, expectedDirMin, expectDirMax);
- }
-
- @Test
- public void dailySizeBasedRolloverWithoutCap() {
- SizeAndTimeBasedFNATP<Object> sizeAndTimeBasedFNATP = new SizeAndTimeBasedFNATP<Object>();
- sizeAndTimeBasedFNATP.invocationGate = fixedRateInvocationGate;
-
- sizeAndTimeBasedFNATP.setMaxFileSize(new FileSize(10000));
- tbfnatp = sizeAndTimeBasedFNATP;
- this.slashCount = computeSlashCount(DAILY_DATE_PATTERN);
- String fileNamePattern = randomOutputDir + "/%d{" + DAILY_DATE_PATTERN + "}-clean.%i.zip";
- cp.maxHistory(5).fileNamePattern(fileNamePattern).simulatedNumberOfPeriods(5 * 4);
- logOverMultiplePeriods(cp);
- checkPatternCompliance(5 + 1 + slashCount, "\\d{4}-\\d{2}-\\d{2}-clean(\\.\\d)(.zip)?");
- }
-
- @Test
- public void dailySizeBasedRolloverWithSizeCap() {
- SizeAndTimeBasedFNATP<Object> sizeAndTimeBasedFNATP = new SizeAndTimeBasedFNATP<Object>();
- sizeAndTimeBasedFNATP.invocationGate = new FixedRateInvocationGate(ticksPerPeriod / 8);
- long bytesPerPeriod = 17000;
- long fileSize = (bytesPerPeriod) / 5;
- int expectedFileCount = 10;
- long sizeCap = expectedFileCount * fileSize;
- sizeAndTimeBasedFNATP.setMaxFileSize(new FileSize(fileSize));
- tbfnatp = sizeAndTimeBasedFNATP;
- this.slashCount = computeSlashCount(DAILY_DATE_PATTERN);
-
- // 2016-03-05 00:14:39 CET
- long simulatedTime = 1457133279186L;
- ConfigParameters params = new ConfigParameters(simulatedTime);
- String fileNamePattern = randomOutputDir + "/%d{" + DAILY_DATE_PATTERN + "}-clean.%i";
- params.maxHistory(60).fileNamePattern(fileNamePattern).simulatedNumberOfPeriods(10).sizeCap(sizeCap);
- logOverMultiplePeriods(params);
-
- List<File> foundFiles = findFilesByPattern("\\d{4}-\\d{2}-\\d{2}-clean(\\.\\d)");
- Collections.sort(foundFiles, new Comparator<File>() {
- public int compare(File f0, File f1) {
- String s0 = f0.getName().toString();
- String s1 = f1.getName().toString();
- return s0.compareTo(s1);
- }
- });
- System.out.print(foundFiles);
- StatusPrinter.print(context);
- checkFileCount(expectedFileCount - 1);
- }
-
- @Test
- public void dailyChronologSizeBasedRollover() {
- SizeAndTimeBasedFNATP<Object> sizeAndTimeBasedFNATP = new SizeAndTimeBasedFNATP<Object>();
- sizeAndTimeBasedFNATP.setMaxFileSize(new FileSize(10000));
- sizeAndTimeBasedFNATP.invocationGate = fixedRateInvocationGate;
- tbfnatp = sizeAndTimeBasedFNATP;
- slashCount = 1;
- String fileNamePattern = randomOutputDir + "/%d{" + DAILY_DATE_PATTERN + "}/clean.%i.zip";
- cp.maxHistory(5).fileNamePattern(fileNamePattern).simulatedNumberOfPeriods(5 * 3);
- logOverMultiplePeriods(cp);
- checkDirPatternCompliance(6);
- }
-
- @Test
- public void dailyChronologSizeBasedRolloverWithSecondPhase() {
- SizeAndTimeBasedFNATP<Object> sizeAndTimeBasedFNATP = new SizeAndTimeBasedFNATP<Object>();
- sizeAndTimeBasedFNATP.setMaxFileSize(new FileSize(10000));
- sizeAndTimeBasedFNATP.invocationGate = fixedRateInvocationGate;
- tbfnatp = sizeAndTimeBasedFNATP;
- this.slashCount = 1;
- String fileNamePattern = randomOutputDir + "/%d{" + DAILY_DATE_PATTERN + "}/clean.%i";
- int maxHistory = 5;
- cp.maxHistory(maxHistory).fileNamePattern(fileNamePattern).simulatedNumberOfPeriods(3);
- long endTime = logOverMultiplePeriods(cp);
-
- int simulatedNumberOfPeriods = maxHistory * 4;
- ConfigParameters cp1 = new ConfigParameters(endTime + MILLIS_IN_DAY * 7).maxHistory(maxHistory).fileNamePattern(fileNamePattern)
- .simulatedNumberOfPeriods(simulatedNumberOfPeriods);
- logOverMultiplePeriods(cp1);
- checkDirPatternCompliance(maxHistory + 1);
- }
-
- void logTwiceAndStop(long currentTime, String fileNamePattern, int maxHistory) {
- ConfigParameters params = new ConfigParameters(currentTime).fileNamePattern(fileNamePattern).maxHistory(maxHistory);
- buildRollingFileAppender(params, DO_CLEAN_HISTORY_ON_START);
- rfa.doAppend("Hello ----------------------------------------------------------" + new Date(currentTime));
- currentTime += MILLIS_IN_DAY / 2;
- add(tbrp.compressionFuture);
- add(tbrp.cleanUpFuture);
- waitForJobsToComplete();
- tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
- rfa.doAppend("Hello ----------------------------------------------------------" + new Date(currentTime));
- rfa.stop();
- }
-
- @Test
- public void cleanHistoryOnStart() {
- long simulatedTime = WED_2016_03_23_T_230705_CET;
- System.out.println(new Date(simulatedTime));
-
- String fileNamePattern = randomOutputDir + "clean-%d{" + DAILY_DATE_PATTERN + "}.txt";
- int maxHistory = 3;
- for (int i = 0; i <= 5; i++) {
- logTwiceAndStop(simulatedTime, fileNamePattern, maxHistory);
- simulatedTime += MILLIS_IN_DAY;
- }
- StatusPrinter.print(context);
- checkFileCount(expectedCountWithoutFolders(maxHistory));
- }
-
- @Test
- public void cleanHistoryOnStartWithDayPattern() {
- long simulatedTime = WED_2016_03_23_T_230705_CET;
- String fileNamePattern = randomOutputDir + "clean-%d{yyyy-MM-dd}.txt";
- int maxHistory = 3;
- for (int i = 0; i <= 5; i++) {
- logTwiceAndStop(simulatedTime, fileNamePattern, maxHistory);
- simulatedTime += MILLIS_IN_DAY;
- }
- StatusPrinter.print(context);
- checkFileCount(expectedCountWithoutFolders(maxHistory));
- }
-
- @Ignore
- @Test
- // this test assumes a high degree of collisions in the archived files. Every 24 hours, the archive
- // belonging to the previous day will be overwritten. Given that logback goes 14 days (336 hours) in history
- // to clean files on start up, it is bound to delete more recent files. It is not logback's responsibility
- // to cater for such degenerate cases.
- public void cleanHistoryOnStartWithHourPattern() {
- long now = this.currentTime;
- String fileNamePattern = randomOutputDir + "clean-%d{HH}.txt";
- int maxHistory = 3;
- for (int i = 0; i <= 5; i++) {
- logTwiceAndStop(now, fileNamePattern, maxHistory);
- now = now + MILLIS_IN_HOUR;
- }
- StatusPrinter.print(context);
- checkFileCount(expectedCountWithoutFolders(maxHistory));
- }
-
- int expectedCountWithoutFolders(int maxHistory) {
- return maxHistory + 1;
- }
-
- int expectedCountWithFolders(int maxHistory, boolean withExtraFolder) {
- int numLogFiles = (maxHistory + 1);
- int numLogFilesAndFolders = numLogFiles * 2;
- int result = numLogFilesAndFolders + slashCount;
- if (withExtraFolder)
- result += 1;
- return result;
- }
-
- void buildRollingFileAppender(ConfigParameters cp, boolean cleanHistoryOnStart) {
- rfa.setContext(context);
- rfa.setEncoder(encoder);
- tbrp.setContext(context);
- tbrp.setFileNamePattern(cp.fileNamePattern);
- tbrp.setMaxHistory(cp.maxHistory);
- tbrp.setTotalSizeCap(new FileSize(cp.sizeCap));
- tbrp.setParent(rfa);
- tbrp.setCleanHistoryOnStart(cleanHistoryOnStart);
- tbrp.timeBasedFileNamingAndTriggeringPolicy = tbfnatp;
- tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(cp.simulatedTime);
- tbrp.start();
- rfa.setRollingPolicy(tbrp);
- rfa.start();
- }
-
- boolean DO_CLEAN_HISTORY_ON_START = true;
- boolean DO_NOT_CLEAN_HISTORY_ON_START = false;
-
- long logOverMultiplePeriods(ConfigParameters cp) {
-
- buildRollingFileAppender(cp, DO_NOT_CLEAN_HISTORY_ON_START);
-
- int runLength = cp.simulatedNumberOfPeriods * ticksPerPeriod;
- int startInactivityIndex = cp.startInactivity * ticksPerPeriod;
- int endInactivityIndex = startInactivityIndex + cp.numInactivityPeriods * ticksPerPeriod;
- long tickDuration = cp.periodDurationInMillis / ticksPerPeriod;
-
- System.out.println("cp.periodDurationInMillis=" + cp.periodDurationInMillis + ", tickDuration=:" + tickDuration + ", runLength=" + runLength);
- for (int i = 0; i <= runLength; i++) {
- if (i < startInactivityIndex || i > endInactivityIndex) {
- StringBuilder sb = new StringBuilder("Hello");
- String iAsString = Integer.toString(i);
- SpacePadder.spacePad(sb, 66 + (6 - iAsString.length()));
- rfa.doAppend(sb.toString());
- } else {
- @SuppressWarnings("unused")
- Date d = new Date(tbrp.timeBasedFileNamingAndTriggeringPolicy.getCurrentTime());
- System.out.print("");
- }
-
- tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(addTime(tbrp.timeBasedFileNamingAndTriggeringPolicy.getCurrentTime(), tickDuration));
- add(tbrp.compressionFuture);
- add(tbrp.cleanUpFuture);
- waitForJobsToComplete();
- }
- rfa.stop();
-
- System.out.println(new Date(tbrp.timeBasedFileNamingAndTriggeringPolicy.getCurrentTime()));
- return tbrp.timeBasedFileNamingAndTriggeringPolicy.getCurrentTime();
- }
-
- void fillWithChar(StringBuffer sb, char c, int count) {
- for (int i = 0; i < count; i++) {
- sb.append(c);
- }
- }
-
- boolean extraFolder(int numPeriods, int periodsPerEra, int beginPeriod, int maxHistory) {
- int valueOfLastMonth = ((beginPeriod) + numPeriods) % periodsPerEra;
- return (valueOfLastMonth < maxHistory);
- }
-
- long addTime(long time, long timeToWait) {
- return time + timeToWait;
- }
-
- void expectedFileAndDirCount(int expectedFileAndDirCount, int expectedDirCountMin, int expectedDirCountMax) {
- File dir = new File(randomOutputDir);
- List<File> fileList = new ArrayList<File>();
- findFilesInFolderRecursivelyByPatterMatch(dir, fileList, "clean");
- List<File> dirList = new ArrayList<File>();
- findAllFoldersInFolderRecursively(dir, dirList);
- String msg = "expectedDirCountMin=" + expectedDirCountMin + ", expectedDirCountMax=" + expectedDirCountMax + " actual value=" + dirList.size();
- assertTrue(msg, expectedDirCountMin <= dirList.size() && dirList.size() <= expectedDirCountMax);
- }
-
- void checkFileCount(int expectedCount) {
- File dir = new File(randomOutputDir);
- List<File> fileList = new ArrayList<File>();
- findAllDirsOrStringContainsFilesRecursively(dir, fileList, "clean");
- assertEquals(expectedCount, fileList.size());
- }
-
- void checkFileCountAtMost(int expectedCount) {
- File dir = new File(randomOutputDir);
- List<File> fileList = new ArrayList<File>();
- findAllDirsOrStringContainsFilesRecursively(dir, fileList, "clean");
- int fileListSize = fileList.size();
-
- assertTrue("file list size "+ fileListSize+", expectedCount="+expectedCount, fileListSize <= expectedCount);
- }
-
- int expectedCountWithoutFoldersWithInactivity(int maxHistory, int totalPeriods, int endOfInactivity) {
- int availableHistory = (totalPeriods + 1) - endOfInactivity;
- int actualHistory = Math.min(availableHistory, maxHistory + 1);
- return actualHistory;
- }
-
- void genericFindMatching(final FileMatchFunction matchFunc, File dir, List<File> fileList, final String pattern, boolean includeDirs) {
- if (dir.isDirectory()) {
- File[] matchArray = dir.listFiles(new FileFilter() {
- public boolean accept(File f) {
- return f.isDirectory() || matchFunc.match(f, pattern);
- }
- });
- for (File f : matchArray) {
- if (f.isDirectory()) {
- if (includeDirs)
- fileList.add(f);
- genericFindMatching(matchFunc, f, fileList, pattern, includeDirs);
- } else
- fileList.add(f);
- }
- }
- }
-
- private void findAllFoldersInFolderRecursively(File dir, List<File> fileList) {
- FileMatchFunction alwaysFalse = new FileMatchFunction() {
- public boolean match(File f, String pattern) {
- return false;
- }
- };
- genericFindMatching(alwaysFalse, dir, fileList, null, true);
- }
-
- private void findAllDirsOrStringContainsFilesRecursively(File dir, List<File> fileList, String pattern) {
- FileMatchFunction matchFunction = new FileMatchFunction() {
- public boolean match(File f, String pattern) {
- return f.getName().contains(pattern);
- }
- };
- genericFindMatching(matchFunction, dir, fileList, pattern, true);
- }
-
- void findFilesInFolderRecursivelyByPatterMatch(File dir, List<File> fileList, String pattern) {
- FileMatchFunction matchByPattern = new FileMatchFunction() {
- public boolean match(File f, String pattern) {
- return f.getName().matches(pattern);
- }
- };
- genericFindMatching(matchByPattern, dir, fileList, pattern, false);
- }
-
- Set<String> groupByClass(List<File> fileList, String regex) {
- Pattern p = Pattern.compile(regex);
- Set<String> set = new HashSet<String>();
- for (File f : fileList) {
- String n = f.getName();
- Matcher m = p.matcher(n);
- m.matches();
- int begin = m.start(1);
- String reduced = n.substring(0, begin);
- set.add(reduced);
- }
- return set;
- }
-
- void checkPatternCompliance(int expectedClassCount, String regex) {
- Set<String> set = findFilesByPatternClass(regex);
- assertEquals(expectedClassCount, set.size());
- }
-
- private List<File> findFilesByPattern(String regex) {
- File dir = new File(randomOutputDir);
- List<File> fileList = new ArrayList<File>();
- findFilesInFolderRecursivelyByPatterMatch(dir, fileList, regex);
- return fileList;
- }
-
- private Set<String> findFilesByPatternClass(String regex) {
- List<File> fileList = findFilesByPattern(regex);
- Set<String> set = groupByClass(fileList, regex);
- return set;
- }
-
- void checkDirPatternCompliance(int expectedClassCount) {
- File dir = new File(randomOutputDir);
- List<File> fileList = new ArrayList<File>();
- findAllFoldersInFolderRecursively(dir, fileList);
- for (File f : fileList) {
- assertTrue(f.list().length >= 1);
+ String MONTHLY_DATE_PATTERN = "yyyy-MM";
+ String MONTHLY_CRONOLOG_DATE_PATTERN = "yyyy/MM";
+ final String DAILY_CRONOLOG_DATE_PATTERN = "yyyy/MM/dd";
+
+
+ RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
+ TimeBasedRollingPolicy<Object> tbrp = new TimeBasedRollingPolicy<Object>();
+
+ // by default tbfnatp is an instance of DefaultTimeBasedFileNamingAndTriggeringPolicy
+ TimeBasedFileNamingAndTriggeringPolicy<Object> tbfnatp = new DefaultTimeBasedFileNamingAndTriggeringPolicy<Object>();
+
+ long MILLIS_IN_MINUTE = 60 * 1000;
+ long MILLIS_IN_HOUR = 60 * MILLIS_IN_MINUTE;
+ long MILLIS_IN_DAY = 24 * MILLIS_IN_HOUR;
+ long MILLIS_IN_MONTH = (long) ((365.242199 / 12) * MILLIS_IN_DAY);
+ int MONTHS_IN_YEAR = 12;
+
+ int slashCount = 0;
+
+ @Before
+ public void setUp() {
+ super.setUp();
+ }
+
+
+ private int computeSlashCount(String datePattern) {
+ if (datePattern == null)
+ return 0;
+ else {
+ int count = 0;
+ for (int i = 0; i < datePattern.length(); i++) {
+ char c = datePattern.charAt(i);
+ if (c == '/')
+ count++;
+ }
+ return count;
+ }
+ }
+
+
+ // test that the number of files at the end of the test is same as the expected number taking into account end dates
+ // near the beginning of a new year. This test has been run in a loop with start date varying over a two years
+ // with success.
+ @Test
+ public void monthlyRolloverOverManyPeriods() {
+
+ slashCount = computeSlashCount(MONTHLY_CRONOLOG_DATE_PATTERN);
+ int numPeriods = 40;
+ int maxHistory = 2;
+ String fileNamePattern = randomOutputDir + "/%d{" + MONTHLY_CRONOLOG_DATE_PATTERN + "}/clean.txt.zip";
+
+ long startTime = currentTime;
+ long endTime = logOverMultiplePeriodsContinuously(currentTime, fileNamePattern, MILLIS_IN_MONTH, maxHistory,
+ numPeriods);
+ System.out.println("randomOutputDir:" + randomOutputDir);
+ System.out.println("start:" + startTime + ", end=" + endTime);
+ int differenceInMonths = RollingCalendar.diffInMonths(startTime, endTime);
+ System.out.println("differenceInMonths:" + differenceInMonths);
+ Calendar startTimeAsCalendar = Calendar.getInstance();
+ startTimeAsCalendar.setTimeInMillis(startTime);
+ int indexOfStartPeriod = startTimeAsCalendar.get(Calendar.MONTH);
+ boolean withExtraFolder = extraFolder(differenceInMonths, MONTHS_IN_YEAR, indexOfStartPeriod, maxHistory);
+
+ check(expectedCountWithFolders(maxHistory, withExtraFolder));
+ }
+
+ void generateDailyRollover(long now, int maxHistory, int simulatedNumberOfPeriods, int startInactivity,
+ int numInactivityPeriods) {
+ slashCount = computeSlashCount(DAILY_DATE_PATTERN);
+ logOverMultiplePeriods(now, randomOutputDir + "clean-%d{" + DAILY_DATE_PATTERN + "}.txt", MILLIS_IN_DAY, maxHistory, simulatedNumberOfPeriods, startInactivity, numInactivityPeriods);
+ check(expectedCountWithoutFoldersWithInactivity(maxHistory, simulatedNumberOfPeriods, startInactivity + numInactivityPeriods));
+ }
+
+ @Test
+ public void basicDailyRollover() {
+ int maxHistory = 20;
+ int simulatedNumberOfPeriods = 20 * 3;
+ int startInactivity = 0;
+ int numInactivityPeriods = 0;
+ generateDailyRollover(currentTime, maxHistory, simulatedNumberOfPeriods, startInactivity, numInactivityPeriods);
+ }
+
+ // Since the duration of a month (in seconds) varies from month to month, tests with inactivity period must
+ // be conducted with daily rollover not monthly
+ @Test
+ public void dailyRollover15() {
+ int maxHistory = 5;
+ int simulatedNumberOfPeriods = 15;
+ int startInactivity = 6;
+ int numInactivityPeriods = 3;
+ generateDailyRollover(currentTime, maxHistory, simulatedNumberOfPeriods, startInactivity, numInactivityPeriods);
+ }
+
+ @Test
+ public void dailyRolloverWithInactivity70() {
+ int maxHistory = 6;
+ int simulatedNumberOfPeriods = 70;
+ int startInactivity = 30;
+ int numInactivityPeriods = 1;
+ generateDailyRollover(currentTime, maxHistory, simulatedNumberOfPeriods, startInactivity, numInactivityPeriods);
+ }
+
+ @Test
+ public void dailyRolloverWithInactivity10() {
+ int maxHistory = 6;
+ int simulatedNumberOfPeriods = 10;
+ int startInactivity = 3;
+ int numInactivityPeriods = 4;
+ generateDailyRollover(currentTime, maxHistory, simulatedNumberOfPeriods, startInactivity, numInactivityPeriods);
+ }
+
+ @Test
+ public void dailyRolloverWithSecondPhase() {
+ slashCount = computeSlashCount(DAILY_DATE_PATTERN);
+ int maxHistory = 5;
+ long endTime = logOverMultiplePeriodsContinuously(currentTime, randomOutputDir + "clean-%d{" + DAILY_DATE_PATTERN + "}.txt",
+ MILLIS_IN_DAY, maxHistory, maxHistory * 2);
+ logOverMultiplePeriodsContinuously(endTime + MILLIS_IN_DAY * 10, randomOutputDir + "clean-%d{" + DAILY_DATE_PATTERN + "}.txt",
+ MILLIS_IN_DAY, maxHistory, maxHistory);
+ check(expectedCountWithoutFolders(maxHistory));
+ }
+
+ @Test
+ public void dailyCronologRollover() {
+ slashCount = computeSlashCount(DAILY_CRONOLOG_DATE_PATTERN);
+ logOverMultiplePeriodsContinuously(currentTime, randomOutputDir + "/%d{" + DAILY_CRONOLOG_DATE_PATTERN + "}/clean.txt.zip",
+ MILLIS_IN_DAY, 8, 8 * 3);
+ int expectedDirMin = 9 + slashCount;
+ int expectDirMax = expectedDirMin + 1 + 1;
+ expectedFileAndDirCount(9, expectedDirMin, expectDirMax);
+ }
+
+ @Test
+ public void dailySizeBasedRollover() {
+ SizeAndTimeBasedFNATP<Object> sizeAndTimeBasedFNATP = new SizeAndTimeBasedFNATP<Object>();
+ sizeAndTimeBasedFNATP.setMaxFileSize("10000");
+ tbfnatp = sizeAndTimeBasedFNATP;
+ slashCount = computeSlashCount(DAILY_DATE_PATTERN);
+ logOverMultiplePeriodsContinuously(currentTime, randomOutputDir + "/%d{" + DAILY_DATE_PATTERN + "}-clean.%i.zip", MILLIS_IN_DAY,
+ 5, 5 * 4);
+ checkPatternCompliance(5 + 1 + slashCount, "\\d{4}-\\d{2}-\\d{2}-clean(\\.\\d)(.zip)?");
+ }
+
+ @Test
+ public void dailyChronologSizeBasedRollover() {
+ SizeAndTimeBasedFNATP<Object> sizeAndTimeBasedFNATP = new SizeAndTimeBasedFNATP<Object>();
+ sizeAndTimeBasedFNATP.setMaxFileSize("10000");
+ tbfnatp = sizeAndTimeBasedFNATP;
+ slashCount = 1;
+ logOverMultiplePeriodsContinuously(currentTime, randomOutputDir + "/%d{" + DAILY_DATE_PATTERN + "}/clean.%i.zip", MILLIS_IN_DAY,
+ 5, 5 * 4);
+ checkDirPatternCompliance(6);
+ }
+
+ @Test
+ public void dailyChronologSizeBasedRolloverWithSecondPhase() {
+ SizeAndTimeBasedFNATP<Object> sizeAndTimeBasedFNATP = new SizeAndTimeBasedFNATP<Object>();
+ sizeAndTimeBasedFNATP.setMaxFileSize("10000");
+ tbfnatp = sizeAndTimeBasedFNATP;
+ slashCount = 1;
+ int maxHistory = 5;
+ int simulatedNumberOfPeriods = maxHistory * 4;
+ long endTime = logOverMultiplePeriodsContinuously(currentTime, randomOutputDir + "/%d{" + DAILY_DATE_PATTERN + "}/clean.%i", MILLIS_IN_DAY,
+ maxHistory, 3);
+ logOverMultiplePeriodsContinuously(endTime + MILLIS_IN_DAY * 7, randomOutputDir + "/%d{" + DAILY_DATE_PATTERN + "}/clean.%i",
+ MILLIS_IN_DAY, maxHistory, simulatedNumberOfPeriods);
+ checkDirPatternCompliance(maxHistory + 1);
+ }
+
+
+ void logOncePeriod(long currentTime, String fileNamePattern, int maxHistory) {
+ buildRollingFileAppender(currentTime, fileNamePattern, maxHistory, DO_CLEAN_HISTORY_ON_START);
+ rfa.doAppend("Hello ----------------------------------------------------------" + new Date(currentTime));
+ rfa.stop();
+ }
+
+ @Test
+ public void cleanHistoryOnStart() {
+ long now = this.currentTime;
+ String fileNamePattern = randomOutputDir + "clean-%d{" + DAILY_DATE_PATTERN + "}.txt";
+ int maxHistory = 3;
+ for (int i = 0; i <= 5; i++) {
+ logOncePeriod(now, fileNamePattern, maxHistory);
+ now = now + MILLIS_IN_DAY;
+ }
+ StatusPrinter.print(context);
+ check(expectedCountWithoutFolders(maxHistory));
+ }
+
+
+ int expectedCountWithoutFolders(int maxHistory) {
+ return maxHistory + 1;
+ }
+
+
+ int expectedCountWithFolders(int maxHistory, boolean withExtraFolder) {
+ int numLogFiles = (maxHistory + 1);
+ int numLogFilesAndFolders = numLogFiles * 2;
+ int result = numLogFilesAndFolders + slashCount;
+ if (withExtraFolder) result += 1;
+ return result;
+ }
+
+
+ void buildRollingFileAppender(long currentTime, String fileNamePattern, int maxHistory,
+ boolean cleanHistoryOnStart) {
+ rfa.setContext(context);
+ rfa.setEncoder(encoder);
+ tbrp.setContext(context);
+ tbrp.setFileNamePattern(fileNamePattern);
+ tbrp.setMaxHistory(maxHistory);
+ tbrp.setParent(rfa);
+ tbrp.setCleanHistoryOnStart(cleanHistoryOnStart);
+ tbrp.timeBasedFileNamingAndTriggeringPolicy = tbfnatp;
+ tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
+ tbrp.start();
+ rfa.setRollingPolicy(tbrp);
+ rfa.start();
+ }
+
+ boolean DO_CLEAN_HISTORY_ON_START = true;
+ boolean DO_NOT_CLEAN_HISTORY_ON_START = false;
+
+
+ long logOverMultiplePeriodsContinuously(long simulatedTime, String fileNamePattern, long periodDurationInMillis, int maxHistory,
+ int simulatedNumberOfPeriods) {
+ return logOverMultiplePeriods(simulatedTime, fileNamePattern, periodDurationInMillis, maxHistory,
+ simulatedNumberOfPeriods, 0, 0);
+ }
+
+ long logOverMultiplePeriods(long simulatedTime, String fileNamePattern, long periodDurationInMillis, int maxHistory,
+ int simulatedNumberOfPeriods, int startInactivity,
+ int numInactivityPeriods) {
+ buildRollingFileAppender(simulatedTime, fileNamePattern, maxHistory, DO_NOT_CLEAN_HISTORY_ON_START);
+ int ticksPerPeriod = 512;
+ int runLength = simulatedNumberOfPeriods * ticksPerPeriod;
+ int startInactivityIndex = 1 + startInactivity * ticksPerPeriod;
+ int endInactivityIndex = startInactivityIndex + numInactivityPeriods * ticksPerPeriod;
+ long tickDuration = periodDurationInMillis / ticksPerPeriod;
+
+ for (int i = 0; i <= runLength; i++) {
+ if (i < startInactivityIndex || i > endInactivityIndex) {
+ rfa.doAppend("Hello ----------------------------------------------------------" + i);
+ }
+ tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(addTime(tbrp.timeBasedFileNamingAndTriggeringPolicy.getCurrentTime(),
+ tickDuration));
+ add(tbrp.future);
+ waitForJobsToComplete();
+ }
+ rfa.stop();
+ return tbrp.timeBasedFileNamingAndTriggeringPolicy.getCurrentTime();
+ }
+
+ boolean extraFolder(int numPeriods, int periodsPerEra, int beginPeriod, int maxHistory) {
+ int valueOfLastMonth = ((beginPeriod) + numPeriods) % periodsPerEra;
+ return (valueOfLastMonth < maxHistory);
+ }
+
+ long addTime(long time, long timeToWait) {
+ return time + timeToWait;
+ }
+
+
+ void expectedFileAndDirCount(int expectedFileAndDirCount, int expectedDirCountMin, int expectedDirCountMax) {
+ File dir = new File(randomOutputDir);
+ List<File> fileList = new ArrayList<File>();
+ findFilesInFolderRecursivelyByPatterMatch(dir, fileList, "clean");
+ List<File> dirList = new ArrayList<File>();
+ findAllFoldersInFolderRecursively(dir, dirList);
+ String msg = "expectedDirCountMin=" + expectedDirCountMin + ", expectedDirCountMax=" + expectedDirCountMax + " actual value=" + dirList.size();
+ assertTrue(msg, expectedDirCountMin <= dirList.size() && dirList.size() <= expectedDirCountMax);
+ }
+
+
+ void check(int expectedCount) {
+ File dir = new File(randomOutputDir);
+ List<File> fileList = new ArrayList<File>();
+ findAllDirsOrStringContainsFilesRecursively(dir, fileList, "clean");
+ assertEquals(expectedCount, fileList.size());
+ }
+
+ int expectedCountWithoutFoldersWithInactivity(int maxHistory, int totalPeriods, int endOfInactivity) {
+ int availableHistory = (totalPeriods + 1) - endOfInactivity;
+ int actualHistory = Math.min(availableHistory, maxHistory + 1);
+ return actualHistory;
+ }
+
+ void genericFindMatching(final FileMatchFunction matchFunc, File dir, List<File> fileList, final String pattern, boolean includeDirs) {
+ if (dir.isDirectory()) {
+ File[] matchArray = dir.listFiles(new FileFilter() {
+ public boolean accept(File f) {
+ return f.isDirectory() || matchFunc.match(f, pattern);
}
- assertEquals(expectedClassCount, fileList.size());
- }
+ });
+ for (File f : matchArray) {
+ if (f.isDirectory()) {
+ if (includeDirs) fileList.add(f);
+ genericFindMatching(matchFunc, f, fileList, pattern, includeDirs);
+ } else
+ fileList.add(f);
+ }
+ }
+ }
+
+ private void findAllFoldersInFolderRecursively(File dir, List<File> fileList) {
+ FileMatchFunction alwaysFalse = new FileMatchFunction() {
+ public boolean match(File f, String pattern) {
+ return false;
+ }
+ };
+ genericFindMatching(alwaysFalse, dir, fileList, null, true);
+ }
+
+ private void findAllDirsOrStringContainsFilesRecursively(File dir, List<File> fileList, String pattern) {
+ FileMatchFunction matchFunction = new FileMatchFunction() {
+ public boolean match(File f, String pattern) {
+ return f.getName().contains(pattern);
+ }
+ };
+ genericFindMatching(matchFunction, dir, fileList, pattern, true);
+ }
+
+ void findFilesInFolderRecursivelyByPatterMatch(File dir, List<File> fileList, String pattern) {
+ FileMatchFunction matchByPattern = new FileMatchFunction() {
+ public boolean match(File f, String pattern) {
+ return f.getName().matches(pattern);
+ }
+ };
+ genericFindMatching(matchByPattern, dir, fileList, pattern, false);
+ }
+
+ Set<String> groupByClass(List<File> fileList, String regex) {
+ Pattern p = Pattern.compile(regex);
+ Set<String> set = new HashSet<String>();
+ for (File f : fileList) {
+ String n = f.getName();
+ Matcher m = p.matcher(n);
+ m.matches();
+ int begin = m.start(1);
+ String reduced = n.substring(0, begin);
+ set.add(reduced);
+ }
+ return set;
+ }
+
+
+ void checkPatternCompliance(int expectedClassCount, String regex) {
+ File dir = new File(randomOutputDir);
+ List<File> fileList = new ArrayList<File>();
+ findFilesInFolderRecursivelyByPatterMatch(dir, fileList, regex);
+ Set<String> set = groupByClass(fileList, regex);
+ assertEquals(expectedClassCount, set.size());
+ }
+
+ void checkDirPatternCompliance(int expectedClassCount) {
+ File dir = new File(randomOutputDir);
+ List<File> fileList = new ArrayList<File>();
+ findAllFoldersInFolderRecursively(dir, fileList);
+ for (File f : fileList) {
+ assertTrue(f.list().length >= 1);
+ }
+ assertEquals(expectedClassCount, fileList.size());
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/ZRolloverChecker.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/ZRolloverChecker.java
index 096f398..6fc143e 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/ZRolloverChecker.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/ZRolloverChecker.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.rolling;
+
import ch.qos.logback.core.util.Compare;
import ch.qos.logback.core.util.CoreTestConstants;
@@ -23,16 +24,16 @@ import static org.junit.Assert.assertTrue;
public class ZRolloverChecker implements RolloverChecker {
- String testId;
+ String testId;
- public ZRolloverChecker(String testId) {
- this.testId = testId;
- }
+ public ZRolloverChecker(String testId) {
+ this.testId = testId;
+ }
- public void check(List<String> expectedFilenameList) throws IOException {
- int lastIndex = expectedFilenameList.size() - 1;
- String lastFile = expectedFilenameList.get(lastIndex);
- String witnessFileName = CoreTestConstants.TEST_SRC_PREFIX + "witness/rolling/tbr-" + testId;
- assertTrue(Compare.compare(lastFile, witnessFileName));
- }
+ public void check(List<String> expectedFilenameList) throws IOException {
+ int lastIndex = expectedFilenameList.size() - 1;
+ String lastFile = expectedFilenameList.get(lastIndex);
+ String witnessFileName = CoreTestConstants.TEST_SRC_PREFIX + "witness/rolling/tbr-" + testId;
+ assertTrue(Compare.compare(lastFile, witnessFileName));
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/CompressTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/CompressTest.java
index 578cd5e..c33a893 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/CompressTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/CompressTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -36,86 +36,105 @@ import ch.qos.logback.core.util.CoreTestConstants;
*/
public class CompressTest {
- Context context = new ContextBase();
-
- @Before
- public void setUp() throws IOException {
- // Copy source files
- // Delete output files
- {
- File source = new File(CoreTestConstants.TEST_SRC_PREFIX + "input/compress1.copy");
- File dest = new File(CoreTestConstants.TEST_SRC_PREFIX + "input/compress1.txt");
-
- copy(source, dest);
- File target = new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "compress1.txt.gz");
- target.mkdirs();
- target.delete();
- }
- {
- File source = new File(CoreTestConstants.TEST_SRC_PREFIX + "input/compress2.copy");
- File dest = new File(CoreTestConstants.TEST_SRC_PREFIX + "input/compress2.txt");
- copy(source, dest);
- File target = new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "compress2.txt.gz");
- target.mkdirs();
- target.delete();
- }
- {
- File source = new File(CoreTestConstants.TEST_SRC_PREFIX + "input/compress3.copy");
- File dest = new File(CoreTestConstants.TEST_SRC_PREFIX + "input/compress3.txt");
- copy(source, dest);
- File target = new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "compress3.txt.zip");
- target.mkdirs();
- target.delete();
- }
+ Context context = new ContextBase();
+
+ @Before
+ public void setUp() throws IOException {
+ // Copy source files
+ // Delete output files
+ {
+ File source = new File(CoreTestConstants.TEST_SRC_PREFIX
+ + "input/compress1.copy");
+ File dest = new File(CoreTestConstants.TEST_SRC_PREFIX
+ + "input/compress1.txt");
+
+ copy(source, dest);
+ File target = new File(CoreTestConstants.OUTPUT_DIR_PREFIX
+ + "compress1.txt.gz");
+ target.mkdirs();
+ target.delete();
}
-
- @Test
- public void test1() throws Exception {
- Compressor compressor = new Compressor(CompressionMode.GZ);
- compressor.setContext(context);
- compressor.compress(CoreTestConstants.TEST_SRC_PREFIX + "input/compress1.txt", CoreTestConstants.OUTPUT_DIR_PREFIX + "compress1.txt.gz", null);
-
- StatusChecker checker = new StatusChecker(context);
- assertTrue(checker.isErrorFree(0));
- assertTrue(Compare.gzCompare(CoreTestConstants.OUTPUT_DIR_PREFIX + "compress1.txt.gz", CoreTestConstants.TEST_SRC_PREFIX + "witness/compress1.txt.gz"));
- }
-
- @Test
- public void test2() throws Exception {
- Compressor compressor = new Compressor(CompressionMode.GZ);
- compressor.setContext(context);
- compressor.compress(CoreTestConstants.TEST_SRC_PREFIX + "input/compress2.txt", CoreTestConstants.OUTPUT_DIR_PREFIX + "compress2.txt", null);
-
- StatusChecker checker = new StatusChecker(context);
- assertTrue(checker.isErrorFree(0));
-
- assertTrue(Compare.gzCompare(CoreTestConstants.OUTPUT_DIR_PREFIX + "compress2.txt.gz", CoreTestConstants.TEST_SRC_PREFIX + "witness/compress2.txt.gz"));
+ {
+ File source = new File(CoreTestConstants.TEST_SRC_PREFIX
+ + "input/compress2.copy");
+ File dest = new File(CoreTestConstants.TEST_SRC_PREFIX
+ + "input/compress2.txt");
+ copy(source, dest);
+ File target = new File(CoreTestConstants.OUTPUT_DIR_PREFIX
+ + "compress2.txt.gz");
+ target.mkdirs();
+ target.delete();
}
-
- @Test
- public void test3() throws Exception {
- Compressor compressor = new Compressor(CompressionMode.ZIP);
- compressor.setContext(context);
- compressor.compress(CoreTestConstants.TEST_SRC_PREFIX + "input/compress3.txt", CoreTestConstants.OUTPUT_DIR_PREFIX + "compress3.txt", "compress3.txt");
- StatusChecker checker = new StatusChecker(context);
- assertTrue(checker.isErrorFree(0));
-
- // we don't know how to compare .zip files
- // assertTrue(Compare.compare(CoreTestConstants.OUTPUT_DIR_PREFIX
- // + "compress3.txt.zip", CoreTestConstants.TEST_SRC_PREFIX
- // + "witness/compress3.txt.zip"));
+ {
+ File source = new File(CoreTestConstants.TEST_SRC_PREFIX
+ + "input/compress3.copy");
+ File dest = new File(CoreTestConstants.TEST_SRC_PREFIX
+ + "input/compress3.txt");
+ copy(source, dest);
+ File target = new File(CoreTestConstants.OUTPUT_DIR_PREFIX
+ + "compress3.txt.zip");
+ target.mkdirs();
+ target.delete();
}
-
- private void copy(File src, File dst) throws IOException {
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dst);
- byte[] buf = new byte[1024];
- int len;
- while ((len = in.read(buf)) > 0) {
- out.write(buf, 0, len);
- }
- in.close();
- out.close();
+ }
+
+ @Test
+ public void test1() throws Exception {
+ Compressor compressor = new Compressor(CompressionMode.GZ);
+ compressor.setContext(context);
+ compressor.compress(CoreTestConstants.TEST_SRC_PREFIX
+ + "input/compress1.txt", CoreTestConstants.OUTPUT_DIR_PREFIX
+ + "compress1.txt.gz", null);
+
+ StatusChecker checker = new StatusChecker(context);
+ assertTrue(checker.isErrorFree(0));
+ assertTrue(Compare.gzCompare(CoreTestConstants.OUTPUT_DIR_PREFIX
+ + "compress1.txt.gz", CoreTestConstants.TEST_SRC_PREFIX
+ + "witness/compress1.txt.gz"));
+ }
+
+ @Test
+ public void test2() throws Exception {
+ Compressor compressor = new Compressor(CompressionMode.GZ);
+ compressor.setContext(context);
+ compressor.compress(CoreTestConstants.TEST_SRC_PREFIX
+ + "input/compress2.txt", CoreTestConstants.OUTPUT_DIR_PREFIX
+ + "compress2.txt", null);
+
+ StatusChecker checker = new StatusChecker(context);
+ assertTrue(checker.isErrorFree(0));
+
+ assertTrue(Compare.gzCompare(CoreTestConstants.OUTPUT_DIR_PREFIX
+ + "compress2.txt.gz", CoreTestConstants.TEST_SRC_PREFIX
+ + "witness/compress2.txt.gz"));
+ }
+
+ @Test
+ public void test3() throws Exception {
+ Compressor compressor = new Compressor(CompressionMode.ZIP);
+ compressor.setContext(context);
+ compressor.compress(CoreTestConstants.TEST_SRC_PREFIX
+ + "input/compress3.txt", CoreTestConstants.OUTPUT_DIR_PREFIX
+ + "compress3.txt", "compress3.txt");
+ StatusChecker checker = new StatusChecker(context);
+ assertTrue(checker.isErrorFree(0));
+
+ // we don't know how to compare .zip files
+ // assertTrue(Compare.compare(CoreTestConstants.OUTPUT_DIR_PREFIX
+ // + "compress3.txt.zip", CoreTestConstants.TEST_SRC_PREFIX
+ // + "witness/compress3.txt.zip"));
+ }
+
+ private void copy(File src, File dst) throws IOException {
+ InputStream in = new FileInputStream(src);
+ OutputStream out = new FileOutputStream(dst);
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = in.read(buf)) > 0) {
+ out.write(buf, 0, len);
}
+ in.close();
+ out.close();
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java
index 35fa934..4d61083 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -14,11 +14,8 @@
package ch.qos.logback.core.rolling.helper;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
import java.util.Calendar;
-import java.util.TimeZone;
import org.junit.Test;
@@ -31,162 +28,123 @@ import ch.qos.logback.core.ContextBase;
*/
public class FileNamePatternTest {
- Context context = new ContextBase();
+ Context context = new ContextBase();
- @Test
- public void testSmoke() {
- FileNamePattern pp = new FileNamePattern("t", context);
- assertEquals("t", pp.convertInt(3));
+ @Test
+ public void testSmoke() {
+ FileNamePattern pp = new FileNamePattern("t", context);
+ assertEquals("t", pp.convertInt(3));
- pp = new FileNamePattern("foo", context);
- assertEquals("foo", pp.convertInt(3));
+ pp = new FileNamePattern("foo", context);
+ assertEquals("foo", pp.convertInt(3));
- pp = new FileNamePattern("%i foo", context);
+ pp = new FileNamePattern("%i foo", context);
- assertEquals("3 foo", pp.convertInt(3));
+ assertEquals("3 foo", pp.convertInt(3));
- pp = new FileNamePattern("foo%i.xixo", context);
- assertEquals("foo3.xixo", pp.convertInt(3));
+ pp = new FileNamePattern("foo%i.xixo", context);
+ assertEquals("foo3.xixo", pp.convertInt(3));
- pp = new FileNamePattern("foo%i.log", context);
- assertEquals("foo3.log", pp.convertInt(3));
+ pp = new FileNamePattern("foo%i.log", context);
+ assertEquals("foo3.log", pp.convertInt(3));
- pp = new FileNamePattern("foo.%i.log", context);
- assertEquals("foo.3.log", pp.convertInt(3));
+ pp = new FileNamePattern("foo.%i.log", context);
+ assertEquals("foo.3.log", pp.convertInt(3));
- // pp = new FileNamePattern("%i.foo\\%", context);
- // assertEquals("3.foo%", pp.convertInt(3));
+ //pp = new FileNamePattern("%i.foo\\%", context);
+ //assertEquals("3.foo%", pp.convertInt(3));
- // pp = new FileNamePattern("\\%foo", context);
- // assertEquals("%foo", pp.convertInt(3));
- }
+ //pp = new FileNamePattern("\\%foo", context);
+ //assertEquals("%foo", pp.convertInt(3));
+ }
- @Test
- // test ways for dealing with flowing i converter, as in "foo%ix"
- public void flowingI() {
- {
- FileNamePattern pp = new FileNamePattern("foo%i{}bar%i", context);
- assertEquals("foo3bar3", pp.convertInt(3));
- }
- {
- FileNamePattern pp = new FileNamePattern("foo%i{}bar%i", context);
- assertEquals("foo3bar3", pp.convertInt(3));
- }
+ @Test
+ // test ways for dealing with flowing i converter, as in "foo%ix"
+ public void flowingI() {
+ {
+ FileNamePattern pp = new FileNamePattern("foo%i{}bar%i", context);
+ assertEquals("foo3bar3", pp.convertInt(3));
}
+ {
+ FileNamePattern pp = new FileNamePattern("foo%i{}bar%i", context);
+ assertEquals("foo3bar3", pp.convertInt(3));
+ }
+ }
- @Test
- public void date() {
- Calendar cal = Calendar.getInstance();
- cal.set(2003, 4, 20, 17, 55);
-
- FileNamePattern pp = new FileNamePattern("foo%d{yyyy.MM.dd}", context);
+ @Test
+ public void date() {
+ Calendar cal = Calendar.getInstance();
+ cal.set(2003, 4, 20, 17, 55);
- assertEquals("foo2003.05.20", pp.convert(cal.getTime()));
+ FileNamePattern pp = new FileNamePattern("foo%d{yyyy.MM.dd}", context);
- pp = new FileNamePattern("foo%d{yyyy.MM.dd HH:mm}", context);
- assertEquals("foo2003.05.20 17:55", pp.convert(cal.getTime()));
+ assertEquals("foo2003.05.20", pp.convert(cal.getTime()));
- pp = new FileNamePattern("%d{yyyy.MM.dd HH:mm} foo", context);
- assertEquals("2003.05.20 17:55 foo", pp.convert(cal.getTime()));
+ pp = new FileNamePattern("foo%d{yyyy.MM.dd HH:mm}", context);
+ assertEquals("foo2003.05.20 17:55", pp.convert(cal.getTime()));
- }
+ pp = new FileNamePattern("%d{yyyy.MM.dd HH:mm} foo", context);
+ assertEquals("2003.05.20 17:55 foo", pp.convert(cal.getTime()));
- @Test
- public void dateWithTimeZone() {
- TimeZone utc = TimeZone.getTimeZone("UTC");
- Calendar cal = Calendar.getInstance(utc);
- cal.set(2003, 4, 20, 10, 55);
+ }
- FileNamePattern fnp = new FileNamePattern("foo%d{yyyy-MM-dd'T'HH:mm, Australia/Perth}", context);
- // Perth is 8 hours ahead of UTC
- assertEquals("foo2003-05-20T18:55", fnp.convert(cal.getTime()));
- }
-
- @Test
- public void auxAndTimeZoneShouldNotConflict() {
- TimeZone utc = TimeZone.getTimeZone("UTC");
- Calendar cal = Calendar.getInstance(utc);
- cal.set(2003, 4, 20, 10, 55);
-
- {
- FileNamePattern fnp = new FileNamePattern("foo%d{yyyy-MM-dd'T'HH:mm, aux, Australia/Perth}", context);
- // Perth is 8 hours ahead of UTC
- assertEquals("foo2003-05-20T18:55", fnp.convert(cal.getTime()));
- assertNull(fnp.getPrimaryDateTokenConverter());
- }
-
- {
- FileNamePattern fnp = new FileNamePattern("folder/%d{yyyy/MM, aux, Australia/Perth}/test.%d{yyyy-MM-dd'T'HHmm, Australia/Perth}.log", context);
- assertEquals("folder/2003/05/test.2003-05-20T1855.log", fnp.convert(cal.getTime()));
- assertNotNull(fnp.getPrimaryDateTokenConverter());
- }
- }
+ @Test
+ public void withBackslash() {
+ FileNamePattern pp = new FileNamePattern("c:\\foo\\bar.%i", context);
+ assertEquals("c:/foo/bar.3", pp.convertInt(3));
+ }
- @Test
- public void withBackslash() {
- FileNamePattern pp = new FileNamePattern("c:\\foo\\bar.%i", context);
- assertEquals("c:/foo/bar.3", pp.convertInt(3));
- }
+ @Test
+ public void objectListConverter() {
+ Calendar cal = Calendar.getInstance();
+ cal.set(2003, 4, 20, 17, 55);
+ FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd}-%i.txt",
+ context);
+ assertEquals("foo-2003.05.20-79.txt", fnp.convertMultipleArguments(cal
+ .getTime(), 79));
+ }
- @Test
- public void objectListConverter() {
- Calendar cal = Calendar.getInstance();
- cal.set(2003, 4, 20, 17, 55);
- FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd}-%i.txt", context);
- assertEquals("foo-2003.05.20-79.txt", fnp.convertMultipleArguments(cal.getTime(), 79));
- }
+ @Test
+ public void asRegexByDate() {
- @Test
- public void asRegexByDate() {
-
- Calendar cal = Calendar.getInstance();
- cal.set(2003, 4, 20, 17, 55);
-
- {
- FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd}-%i.txt", context);
- String regex = fnp.toRegexForFixedDate(cal.getTime());
- assertEquals("foo-2003.05.20-(\\d{1,3}).txt", regex);
- }
- {
- FileNamePattern fnp = new FileNamePattern("\\toto\\foo-%d{yyyy\\MM\\dd}-%i.txt", context);
- String regex = fnp.toRegexForFixedDate(cal.getTime());
- assertEquals("/toto/foo-2003/05/20-(\\d{1,3}).txt", regex);
- }
- }
+ Calendar cal = Calendar.getInstance();
+ cal.set(2003, 4, 20, 17, 55);
- @Test
- public void asRegex() {
- {
- FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd}-%i.txt", context);
- String regex = fnp.toRegex();
- assertEquals("foo-\\d{4}\\.\\d{2}\\.\\d{2}-\\d{1,2}.txt", regex);
- }
- {
- FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd'T'}-%i.txt", context);
- String regex = fnp.toRegex();
- assertEquals("foo-\\d{4}\\.\\d{2}\\.\\d{2}T-\\d{1,2}.txt", regex);
- }
+ {
+ FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd}-%i.txt",
+ context);
+ String regex = fnp.toRegexForFixedDate(cal.getTime());
+ assertEquals("foo-2003.05.20-(\\d{1,3}).txt", regex);
}
-
- @Test
- public void convertMultipleDates() {
- Calendar cal = Calendar.getInstance();
- cal.set(2003, 4, 20, 17, 55);
- FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM, aux}/%d{yyyy.MM.dd}.txt", context);
- assertEquals("foo-2003.05/2003.05.20.txt", fnp.convert(cal.getTime()));
+ {
+ FileNamePattern fnp = new FileNamePattern("\\toto\\foo-%d{yyyy\\MM\\dd}-%i.txt",
+ context);
+ String regex = fnp.toRegexForFixedDate(cal.getTime());
+ assertEquals("/toto/foo-2003/05/20-(\\d{1,3}).txt", regex);
}
-
- @Test
- public void nullTimeZoneByDefault() {
- FileNamePattern fnp = new FileNamePattern("%d{hh}", context);
- assertNull(fnp.getPrimaryDateTokenConverter().getTimeZone());
+ }
+
+ @Test
+ public void asRegex() {
+ {
+ FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd}-%i.txt",
+ context);
+ String regex = fnp.toRegex();
+ assertEquals("foo-\\d{4}\\.\\d{2}\\.\\d{2}-\\d{1,2}.txt", regex);
}
-
- @Test
- public void settingTimeZoneOptionHasAnEffect() {
- TimeZone tz = TimeZone.getTimeZone("Australia/Perth");
-
- FileNamePattern fnp = new FileNamePattern("%d{hh, " + tz.getID() + "}", context);
- assertEquals(tz, fnp.getPrimaryDateTokenConverter().getTimeZone());
+ {
+ FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd'T'}-%i.txt",
+ context);
+ String regex = fnp.toRegex();
+ assertEquals("foo-\\d{4}\\.\\d{2}\\.\\d{2}T-\\d{1,2}.txt", regex);
}
+ }
+
+ @Test
+ public void convertMultipleDates() {
+ Calendar cal = Calendar.getInstance();
+ cal.set(2003, 4, 20, 17, 55);
+ FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM, aux}/%d{yyyy.MM.dd}.txt", context);
+ assertEquals("foo-2003.05/2003.05.20.txt", fnp.convert(cal.getTime()));
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileStoreUtilTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileStoreUtilTest.java
index d0f1459..0eb8b3c 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileStoreUtilTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileStoreUtilTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,31 +29,33 @@ import static org.junit.Assert.assertTrue;
public class FileStoreUtilTest {
- int diff = RandomUtil.getPositiveInt();
- String pathPrefix = CoreTestConstants.OUTPUT_DIR_PREFIX + "fs" + diff + "/";
-
- @Test
- public void filesOnSameFolderShouldBeOnTheSameFileStore() throws RolloverFailure, IOException {
- if (!EnvUtil.isJDK7OrHigher())
- return;
-
- File parent = new File(pathPrefix);
- File file = new File(pathPrefix + "filesOnSameFolderShouldBeOnTheSameFileStore");
- FileUtil.createMissingParentDirectories(file);
- file.createNewFile();
- assertTrue(FileStoreUtil.areOnSameFileStore(parent, file));
- }
-
- // test should be run manually
- @Ignore
- @Test
- public void manual_filesOnDifferentVolumesShouldBeDetectedAsSuch() throws RolloverFailure {
- if (!EnvUtil.isJDK7OrHigher())
- return;
-
- // author's computer has two volumes
- File c = new File("c:/tmp/");
- File d = new File("d:/");
- assertFalse(FileStoreUtil.areOnSameFileStore(c, d));
- }
+
+ int diff = RandomUtil.getPositiveInt();
+ String pathPrefix = CoreTestConstants.OUTPUT_DIR_PREFIX+"fs"+diff+"/";
+
+ @Test
+ public void filesOnSameFolderShouldBeOnTheSameFileStore() throws RolloverFailure, IOException {
+ if(!EnvUtil.isJDK7OrHigher())
+ return;
+
+ File parent = new File(pathPrefix);
+ File file = new File(pathPrefix+"filesOnSameFolderShouldBeOnTheSameFileStore");
+ FileUtil.createMissingParentDirectories(file);
+ file.createNewFile();
+ assertTrue(FileStoreUtil.areOnSameFileStore(parent, file));
+ }
+
+
+ // test should be run manually
+ @Ignore
+ @Test
+ public void manual_filesOnDifferentVolumesShouldBeDetectedAsSuch() throws RolloverFailure {
+ if(!EnvUtil.isJDK7OrHigher())
+ return;
+
+ // author's computer has two volumes
+ File c = new File("c:/tmp/");
+ File d = new File("d:/");
+ assertFalse(FileStoreUtil.areOnSameFileStore(c, d));
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/PackageTest.java
index 4aa0b9a..2bbc41d 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,7 +20,8 @@ import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
- at Suite.SuiteClasses({ CompressTest.class, FileNamePatternTest.class, RollingCalendarTest.class, DatePatternToRegexTest.class })
+ at Suite.SuiteClasses( { CompressTest.class, FileNamePatternTest.class,
+ RollingCalendarTest.class, DatePatternToRegexTest.class })
public class PackageTest extends TestCase {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/RollingCalendarTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/RollingCalendarTest.java
index c57a2fa..432b311 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/RollingCalendarTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/RollingCalendarTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,184 +13,83 @@
*/
package ch.qos.logback.core.rolling.helper;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
import java.util.Date;
-import java.util.Locale;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import ch.qos.logback.core.CoreConstants;
-import ch.qos.logback.core.util.EnvUtil;
-
-public class RollingCalendarTest {
-
- @Before
- public void setUp() {
-
- // Most surprisingly, in certain environments (e.g. Windows 7), setting the default locale
- // allows certain tests to pass which otherwise fail.
- //
- // These tests are:
- //
- // checkCollisionFreeness("yyyy-WW", false);
- // checkCollisionFreeness("yyyy-ww", true);
- // checkCollisionFreeness("ww", false);
- // {
- // RollingCalendar rc = new RollingCalendar("yyyy-ww");
- // assertEquals(PeriodicityType.TOP_OF_WEEK, rc.getPeriodicityType());
- // }
- //
-
- Locale oldLocale = Locale.getDefault();
- Locale.setDefault(oldLocale);
- }
-
- @After
- public void tearDown() {
- }
-
- @Test
- public void testPeriodicity() {
- {
- RollingCalendar rc = new RollingCalendar("yyyy-MM-dd_HH_mm_ss");
- assertEquals(PeriodicityType.TOP_OF_SECOND, rc.getPeriodicityType());
- }
- {
- RollingCalendar rc = new RollingCalendar("yyyy-MM-dd_HH_mm");
- assertEquals(PeriodicityType.TOP_OF_MINUTE, rc.getPeriodicityType());
- }
+import junit.framework.TestCase;
- {
- RollingCalendar rc = new RollingCalendar("yyyy-MM-dd_HH");
- assertEquals(PeriodicityType.TOP_OF_HOUR, rc.getPeriodicityType());
- }
+public class RollingCalendarTest extends TestCase {
- {
- RollingCalendar rc = new RollingCalendar("yyyy-MM-dd_hh");
- assertEquals(PeriodicityType.TOP_OF_HOUR, rc.getPeriodicityType());
- }
+ public RollingCalendarTest(String arg0) {
+ super(arg0);
+ }
- {
- RollingCalendar rc = new RollingCalendar("yyyy-MM-dd");
- assertEquals(PeriodicityType.TOP_OF_DAY, rc.getPeriodicityType());
- }
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
- {
- RollingCalendar rc = new RollingCalendar("yyyy-MM");
- assertEquals(PeriodicityType.TOP_OF_MONTH, rc.getPeriodicityType());
- }
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
- {
- RollingCalendar rc = new RollingCalendar("yyyy-ww");
- assertEquals(PeriodicityType.TOP_OF_WEEK, rc.getPeriodicityType());
- }
-
- {
- RollingCalendar rc = new RollingCalendar("yyyy-WW");
- assertEquals(PeriodicityType.TOP_OF_WEEK, rc.getPeriodicityType());
- }
+ public void testPeriodicity() {
+ {
+ RollingCalendar rc = new RollingCalendar();
+ assertEquals(PeriodicityType.TOP_OF_SECOND, rc
+ .computePeriodicityType("yyyy-MM-dd_HH_mm_ss"));
}
- @Test
- public void testVaryingNumberOfHourlyPeriods() {
- RollingCalendar rc = new RollingCalendar("yyyy-MM-dd_HH");
-
- long MILLIS_IN_HOUR = 3600 * 1000;
-
- for (int p = 100; p > -100; p--) {
- long now = 1223325293589L; // Mon Oct 06 22:34:53 CEST 2008
- Date result = rc.getEndOfNextNthPeriod(new Date(now), p);
- long expected = now - (now % (MILLIS_IN_HOUR)) + p * MILLIS_IN_HOUR;
- assertEquals(expected, result.getTime());
- }
+ {
+ RollingCalendar rc = new RollingCalendar();
+ assertEquals(PeriodicityType.TOP_OF_MINUTE, rc
+ .computePeriodicityType("yyyy-MM-dd_HH_mm"));
}
- @Test
- public void testVaryingNumberOfDailyPeriods() {
- RollingCalendar rc = new RollingCalendar("yyyy-MM-dd");
- final long MILLIS_IN_DAY = 24 * 3600 * 1000;
-
- for (int p = 20; p > -100; p--) {
- long now = 1223325293589L; // Mon Oct 06 22:34:53 CEST 2008
- Date nowDate = new Date(now);
- Date result = rc.getEndOfNextNthPeriod(nowDate, p);
- long offset = rc.getTimeZone().getRawOffset() + rc.getTimeZone().getDSTSavings();
-
- long origin = now - ((now + offset) % (MILLIS_IN_DAY));
- long expected = origin + p * MILLIS_IN_DAY;
- assertEquals("p=" + p, expected, result.getTime());
- }
+ {
+ RollingCalendar rc = new RollingCalendar();
+ assertEquals(PeriodicityType.TOP_OF_HOUR, rc
+ .computePeriodicityType("yyyy-MM-dd_HH"));
}
- // Wed Mar 23 23:07:05 CET 2016
- final long WED_2016_03_23_T_230705_CET = 1458770825333L;
-
- @Test
- public void testBarrierCrossingComputation() {
- checkPeriodBarriersCrossed("yyyy-MM-dd'T'HHmmss", WED_2016_03_23_T_230705_CET, WED_2016_03_23_T_230705_CET + 3*CoreConstants.MILLIS_IN_ONE_SECOND, 3);
- checkPeriodBarriersCrossed("yyyy-MM-dd'T'HHmm", WED_2016_03_23_T_230705_CET, WED_2016_03_23_T_230705_CET + 3*CoreConstants.MILLIS_IN_ONE_MINUTE, 3);
- checkPeriodBarriersCrossed("yyyy-MM-dd'T'HH", WED_2016_03_23_T_230705_CET, WED_2016_03_23_T_230705_CET + 3*CoreConstants.MILLIS_IN_ONE_HOUR, 3);
- checkPeriodBarriersCrossed("yyyy-MM-dd", WED_2016_03_23_T_230705_CET, WED_2016_03_23_T_230705_CET + 3*CoreConstants.MILLIS_IN_ONE_DAY, 3);
+ {
+ RollingCalendar rc = new RollingCalendar();
+ assertEquals(PeriodicityType.TOP_OF_DAY, rc
+ .computePeriodicityType("yyyy-MM-dd"));
}
- private void checkPeriodBarriersCrossed(String pattern, long start, long end, int count) {
- RollingCalendar rc = new RollingCalendar(pattern);
- assertEquals(count, rc.periodBarriersCrossed(start, end));
+ {
+ RollingCalendar rc = new RollingCalendar();
+ assertEquals(PeriodicityType.TOP_OF_MONTH, rc
+ .computePeriodicityType("yyyy-MM"));
}
-
- @Test
- public void testCollisionFreenes() {
- // hourly
- checkCollisionFreeness("yyyy-MM-dd hh", false);
- checkCollisionFreeness("yyyy-MM-dd hh a", true);
-
- checkCollisionFreeness("yyyy-MM-dd HH", true);
- checkCollisionFreeness("yyyy-MM-dd kk", true);
-
- checkCollisionFreeness("yyyy-MM-dd KK", false);
- checkCollisionFreeness("yyyy-MM-dd KK a", true);
-
- // daily
- checkCollisionFreeness("yyyy-MM-dd", true);
- checkCollisionFreeness("yyyy-dd", false);
- checkCollisionFreeness("dd", false);
- checkCollisionFreeness("MM-dd", false);
-
- checkCollisionFreeness("yyyy-DDD", true);
- checkCollisionFreeness("DDD", false);
-
- // 'u' is new to JDK 7
- if (EnvUtil.isJDK7OrHigher()) {
- checkCollisionFreeness("yyyy-MM-dd-uu", true);
- checkCollisionFreeness("yyyy-MM-uu", false);
- }
-
- // weekly
- checkCollisionFreeness("yyyy-MM-WW", true);
- dumpCurrentLocale(Locale.getDefault());
- checkCollisionFreeness("yyyy-WW", false);
- checkCollisionFreeness("yyyy-ww", true);
- checkCollisionFreeness("ww", false);
+ }
+
+ public void testVaryingNumberOfHourlyPeriods() {
+ RollingCalendar rc = new RollingCalendar();
+ rc.init("yyyy-MM-dd_HH");
+ long MILLIS_IN_HOUR = 3600*1000;
+
+ for (int p = 100; p > -100; p--) {
+ long now = 1223325293589L; // Mon Oct 06 22:34:53 CEST 2008
+ Date result = rc.getRelativeDate(new Date(now), p);
+ long expected = now - (now % (MILLIS_IN_HOUR)) + p * MILLIS_IN_HOUR;
+ assertEquals(expected, result.getTime());
}
-
- private void dumpCurrentLocale(Locale locale) {
- System.out.println("***Current default locale is "+locale);
-
+ }
+
+ public void testVaryingNumberOfDailyPeriods() {
+ RollingCalendar rc = new RollingCalendar();
+ rc.init("yyyy-MM-dd");
+ final long MILLIS_IN_DAY = 24*3600*1000;
+
+ for (int p = 20; p > -100; p--) {
+ long now = 1223325293589L; // Mon Oct 06 22:34:53 CEST 2008
+ Date nowDate = new Date(now);
+ Date result = rc.getRelativeDate(nowDate, p);
+ long offset = rc.getTimeZone().getRawOffset()+rc.getTimeZone().getDSTSavings();
+
+ long origin = now - (now % (MILLIS_IN_DAY)) - offset;
+ long expected = origin + p * MILLIS_IN_DAY;
+ assertEquals("p="+p, expected, result.getTime());
}
-
- private void checkCollisionFreeness(String pattern, boolean expected) {
- RollingCalendar rc = new RollingCalendar(pattern);
- if (expected) {
- assertTrue(rc.isCollisionFree());
- } else {
- assertFalse(rc.isCollisionFree());
- }
- }
-
-}
\ No newline at end of file
+ }
+}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/sift/AppenderTrackerTest.java b/logback-core/src/test/java/ch/qos/logback/core/sift/AppenderTrackerTest.java
index e3da953..dd47d90 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/sift/AppenderTrackerTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/sift/AppenderTrackerTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -32,121 +32,122 @@ import static org.junit.Assert.*;
*/
public class AppenderTrackerTest {
- Context context = new ContextBase();
- ListAppenderFactory listAppenderFactory = new ListAppenderFactory();
- int diff = RandomUtil.getPositiveInt();
- AppenderTracker<Object> appenderTracker = new AppenderTracker<Object>(context, listAppenderFactory);
- String key = "k-" + diff;
- long now = 3000;
-
- @Before
- public void setUp() {
+ Context context = new ContextBase();
+ ListAppenderFactory listAppenderFactory = new ListAppenderFactory();
+ int diff = RandomUtil.getPositiveInt();
+ AppenderTracker<Object> appenderTracker = new AppenderTracker<Object>(context, listAppenderFactory);
+ String key = "k-" + diff;
+ long now = 3000;
+
+ @Before
+ public void setUp() {
+ }
+
+ @Test
+ public void removeStaleComponentsShouldNotBomb() {
+ appenderTracker.removeStaleComponents(now);
+ assertEquals(0, appenderTracker.getComponentCount());
+ }
+
+ @Test
+ public void findingTheInexistentShouldNotBomb() {
+ assertNull(appenderTracker.find(key));
+ now += AppenderTracker.DEFAULT_TIMEOUT + 1;
+ appenderTracker.removeStaleComponents(now);
+ assertNull(appenderTracker.find(key));
+ }
+
+ @Test
+ public void smoke() {
+ Appender<Object> a = appenderTracker.getOrCreate(key, now);
+ assertTrue(a.isStarted());
+ now += AppenderTracker.DEFAULT_TIMEOUT + 1;
+ appenderTracker.removeStaleComponents(now);
+ assertFalse(a.isStarted());
+ assertNull(appenderTracker.find(key));
+ }
+
+ @Test
+ public void endOfLivedAppendersShouldBeRemovedAfterLingeringTimeout() {
+ Appender a = appenderTracker.getOrCreate(key, now);
+ appenderTracker.endOfLife(key);
+ now += AppenderTracker.LINGERING_TIMEOUT + 1;
+ appenderTracker.removeStaleComponents(now);
+ assertFalse(a.isStarted());
+ a = appenderTracker.find(key);
+ assertNull(a);
+ }
+
+ @Test
+ public void endOfLivedAppenderShouldBeAvailableDuringLingeringPeriod() {
+ Appender a = appenderTracker.getOrCreate(key, now);
+ appenderTracker.endOfLife(key);
+ // clean
+ appenderTracker.removeStaleComponents(now);
+ Appender lingering = appenderTracker.getOrCreate(key, now);
+ assertTrue(lingering.isStarted());
+ assertTrue(a == lingering);
+ now += AppenderTracker.LINGERING_TIMEOUT + 1;
+ appenderTracker.removeStaleComponents(now);
+ assertFalse(a.isStarted());
+ a = appenderTracker.find(key);
+ assertNull(a);
+ }
+
+
+ @Test
+ public void trackerShouldHonorMaxComponentsParameter() {
+ List<Appender<Object>> appenderList = new ArrayList<Appender<Object>>();
+ int max = 10;
+ appenderTracker.setMaxComponents(max);
+ for (int i = 0; i < (max + 1); i++) {
+ Appender a = appenderTracker.getOrCreate(key + "-" + i, now++);
+ appenderList.add(a);
}
-
- @Test
- public void removeStaleComponentsShouldNotBomb() {
- appenderTracker.removeStaleComponents(now);
- assertEquals(0, appenderTracker.getComponentCount());
+ // cleaning only happens in removeStaleComponents
+ appenderTracker.removeStaleComponents(now++);
+ assertEquals(max, appenderTracker.allKeys().size());
+ assertNull(appenderTracker.find(key + "-" + 0));
+ assertFalse(appenderList.get(0).isStarted());
+ }
+
+ @Test
+ public void trackerShouldHonorTimeoutParameter() {
+ List<Appender<Object>> appenderList = new ArrayList<Appender<Object>>();
+ int timeout = 2;
+ appenderTracker.setTimeout(timeout);
+ for (int i = 0; i <= timeout; i++) {
+ Appender a = appenderTracker.getOrCreate(key + "-" + i, now++);
+ appenderList.add(a);
}
- @Test
- public void findingTheInexistentShouldNotBomb() {
- assertNull(appenderTracker.find(key));
- now += AppenderTracker.DEFAULT_TIMEOUT + 1;
- appenderTracker.removeStaleComponents(now);
- assertNull(appenderTracker.find(key));
- }
+ long numComponentsCreated = timeout + 1;
+ assertEquals(numComponentsCreated, appenderTracker.allKeys().size());
- @Test
- public void smoke() {
- Appender<Object> a = appenderTracker.getOrCreate(key, now);
- assertTrue(a.isStarted());
- now += AppenderTracker.DEFAULT_TIMEOUT + 1;
- appenderTracker.removeStaleComponents(now);
- assertFalse(a.isStarted());
- assertNull(appenderTracker.find(key));
- }
+ // cleaning only happens in removeStaleComponents. The first appender should timeout
+ appenderTracker.removeStaleComponents(now++);
- @Test
- public void endOfLivedAppendersShouldBeRemovedAfterLingeringTimeout() {
- Appender a = appenderTracker.getOrCreate(key, now);
- appenderTracker.endOfLife(key);
- now += AppenderTracker.LINGERING_TIMEOUT + 1;
- appenderTracker.removeStaleComponents(now);
- assertFalse(a.isStarted());
- a = appenderTracker.find(key);
- assertNull(a);
- }
-
- @Test
- public void endOfLivedAppenderShouldBeAvailableDuringLingeringPeriod() {
- Appender a = appenderTracker.getOrCreate(key, now);
- appenderTracker.endOfLife(key);
- // clean
- appenderTracker.removeStaleComponents(now);
- Appender lingering = appenderTracker.getOrCreate(key, now);
- assertTrue(lingering.isStarted());
- assertTrue(a == lingering);
- now += AppenderTracker.LINGERING_TIMEOUT + 1;
- appenderTracker.removeStaleComponents(now);
- assertFalse(a.isStarted());
- a = appenderTracker.find(key);
- assertNull(a);
- }
-
- @Test
- public void trackerShouldHonorMaxComponentsParameter() {
- List<Appender<Object>> appenderList = new ArrayList<Appender<Object>>();
- int max = 10;
- appenderTracker.setMaxComponents(max);
- for (int i = 0; i < (max + 1); i++) {
- Appender a = appenderTracker.getOrCreate(key + "-" + i, now++);
- appenderList.add(a);
- }
- // cleaning only happens in removeStaleComponents
- appenderTracker.removeStaleComponents(now++);
- assertEquals(max, appenderTracker.allKeys().size());
- assertNull(appenderTracker.find(key + "-" + 0));
- assertFalse(appenderList.get(0).isStarted());
- }
+ // the first appender should have been removed
+ assertEquals(numComponentsCreated - 1, appenderTracker.allKeys().size());
+ assertNull(appenderTracker.find(key + "-" + 0));
+ assertFalse(appenderList.get(0).isStarted());
- @Test
- public void trackerShouldHonorTimeoutParameter() {
- List<Appender<Object>> appenderList = new ArrayList<Appender<Object>>();
- int timeout = 2;
- appenderTracker.setTimeout(timeout);
- for (int i = 0; i <= timeout; i++) {
- Appender a = appenderTracker.getOrCreate(key + "-" + i, now++);
- appenderList.add(a);
- }
-
- long numComponentsCreated = timeout + 1;
- assertEquals(numComponentsCreated, appenderTracker.allKeys().size());
-
- // cleaning only happens in removeStaleComponents. The first appender should timeout
- appenderTracker.removeStaleComponents(now++);
-
- // the first appender should have been removed
- assertEquals(numComponentsCreated - 1, appenderTracker.allKeys().size());
- assertNull(appenderTracker.find(key + "-" + 0));
- assertFalse(appenderList.get(0).isStarted());
-
- // the other appenders should be in the tracker
- for (int i = 1; i <= timeout; i++) {
- assertNotNull(appenderTracker.find(key + "-" + i));
- assertTrue(appenderList.get(i).isStarted());
- }
+ // the other appenders should be in the tracker
+ for (int i = 1; i <= timeout; i++) {
+ assertNotNull(appenderTracker.find(key + "-" + i));
+ assertTrue(appenderList.get(i).isStarted());
}
+ }
- // ======================================================================
- static class ListAppenderFactory implements AppenderFactory<Object> {
+ // ======================================================================
+ static class ListAppenderFactory implements AppenderFactory<Object> {
- public Appender<Object> buildAppender(Context context, String discriminatingValue) throws JoranException {
- ListAppender<Object> la = new ListAppender<Object>();
- la.setContext(context);
- la.setName(discriminatingValue);
- la.start();
- return la;
- }
+ public Appender<Object> buildAppender(Context context, String discriminatingValue) throws JoranException {
+ ListAppender<Object> la = new ListAppender<Object>();
+ la.setContext(context);
+ la.setName(discriminatingValue);
+ la.start();
+ return la;
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/sift/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/sift/PackageTest.java
index d1fa08f..87b9aaf 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/sift/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/sift/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ AppenderTrackerTest.class })
-public class PackageTest {
+ at SuiteClasses({AppenderTrackerTest.class})
+public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/spi/AppenderAttachableImplLockTest.java b/logback-core/src/test/java/ch/qos/logback/core/spi/AppenderAttachableImplLockTest.java
index 43cd729..11d0e74 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/spi/AppenderAttachableImplLockTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/spi/AppenderAttachableImplLockTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -47,52 +47,52 @@ import static org.mockito.Mockito.when;
*/
public class AppenderAttachableImplLockTest {
- private AppenderAttachableImpl<Integer> aai = new AppenderAttachableImpl<Integer>();
+ private AppenderAttachableImpl<Integer> aai = new AppenderAttachableImpl<Integer>();
- @SuppressWarnings("unchecked")
- @Test(timeout = 5000)
- public void getAppenderBoom() {
- Appender<Integer> mockAppender1 = mock(Appender.class);
+ @SuppressWarnings("unchecked")
+ @Test(timeout = 5000)
+ public void getAppenderBoom() {
+ Appender<Integer> mockAppender1 = mock(Appender.class);
- when(mockAppender1.getName()).thenThrow(new OutOfMemoryError("oops"));
- aai.addAppender(mockAppender1);
- try {
- // appender.getName called as a result of next statement
- aai.getAppender("foo");
- } catch (OutOfMemoryError e) {
- // this leaves the read lock locked.
- }
-
- Appender<Integer> mockAppender2 = mock(Appender.class);
- // the next call used to freeze with the earlier ReadWriteLock lock
- // implementation
- aai.addAppender(mockAppender2);
+ when(mockAppender1.getName()).thenThrow(new OutOfMemoryError("oops"));
+ aai.addAppender(mockAppender1);
+ try {
+ // appender.getName called as a result of next statement
+ aai.getAppender("foo");
+ } catch (OutOfMemoryError e) {
+ // this leaves the read lock locked.
}
- @SuppressWarnings("unchecked")
- @Test(timeout = 5000)
- public void detachAppenderBoom() throws InterruptedException {
- Appender<Integer> mockAppender = mock(Appender.class);
- when(mockAppender.getName()).thenThrow(new OutOfMemoryError("oops"));
- mockAppender.doAppend(17);
+ Appender<Integer> mockAppender2=mock(Appender.class);
+ // the next call used to freeze with the earlier ReadWriteLock lock
+ // implementation
+ aai.addAppender(mockAppender2);
+ }
- aai.addAppender(mockAppender);
- Thread t = new Thread(new Runnable() {
+ @SuppressWarnings("unchecked")
+ @Test(timeout = 5000)
+ public void detachAppenderBoom() throws InterruptedException {
+ Appender<Integer> mockAppender = mock(Appender.class);
+ when(mockAppender.getName()).thenThrow(new OutOfMemoryError("oops"));
+ mockAppender.doAppend(17);
- public void run() {
- try {
- // appender.getName called as a result of next statement
- aai.detachAppender("foo");
- } catch (OutOfMemoryError e) {
- // this leaves the write lock locked.
- }
- }
- });
- t.start();
- t.join();
+ aai.addAppender(mockAppender);
+ Thread t = new Thread(new Runnable() {
- // the next call used to freeze with the earlier ReadWriteLock lock
- // implementation
- aai.appendLoopOnAppenders(17);
- }
+ public void run() {
+ try {
+ // appender.getName called as a result of next statement
+ aai.detachAppender("foo");
+ } catch (OutOfMemoryError e) {
+ // this leaves the write lock locked.
+ }
+ }
+ });
+ t.start();
+ t.join();
+
+ // the next call used to freeze with the earlier ReadWriteLock lock
+ // implementation
+ aai.appendLoopOnAppenders(17);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/spi/AppenderAttachableImplTest.java b/logback-core/src/test/java/ch/qos/logback/core/spi/AppenderAttachableImplTest.java
index bb93180..44e26f9 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/spi/AppenderAttachableImplTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/spi/AppenderAttachableImplTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package ch.qos.logback.core.spi;
+
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -34,134 +35,136 @@ import ch.qos.logback.core.helpers.NOPAppender;
*/
public class AppenderAttachableImplTest {
- private AppenderAttachableImpl<TestEvent> aai;
-
- @Before
- public void setUp() throws Exception {
- aai = new AppenderAttachableImpl<TestEvent>();
- }
-
- @After
- public void tearDown() throws Exception {
- aai = null;
- }
-
- @Test
- public void testAddAppender() throws Exception {
- TestEvent event = new TestEvent();
- NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
- ta.start();
- aai.addAppender(ta);
- ta = new NOPAppender<TestEvent>();
- ta.setName("test");
- ta.start();
- aai.addAppender(ta);
- int size = aai.appendLoopOnAppenders(event);
- assertTrue("Incorrect number of appenders", size == 2);
- }
-
- @Test
- public void testIteratorForAppenders() throws Exception {
- NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
- ta.start();
- aai.addAppender(ta);
- NOPAppender<TestEvent> tab = new NOPAppender<TestEvent>();
- tab.setName("test");
- tab.start();
- aai.addAppender(tab);
- Iterator<Appender<TestEvent>> iter = aai.iteratorForAppenders();
- int size = 0;
- while (iter.hasNext()) {
- ++size;
- Appender<TestEvent> app = iter.next();
- assertTrue("Bad Appender", app == ta || app == tab);
- }
- assertTrue("Incorrect number of appenders", size == 2);
- }
-
- @Test
- public void getGetAppender() throws Exception {
- NOPAppender<TestEvent> test = new NOPAppender<TestEvent>();
- test.setName("test");
- test.start();
- aai.addAppender(test);
-
- NOPAppender<TestEvent> testOther = new NOPAppender<TestEvent>();
- testOther.setName("testOther");
- testOther.start();
- aai.addAppender(testOther);
-
- Appender<TestEvent> a = aai.getAppender("testOther");
- assertNotNull("Could not find appender", a);
- assertTrue("Wrong appender", a == testOther);
-
- a = aai.getAppender("test");
- assertNotNull("Could not find appender", a);
- assertTrue("Wrong appender", a == test);
- a = aai.getAppender("NotThere");
- assertNull("Appender was returned", a);
- }
-
- @Test
- public void testIsAttached() throws Exception {
- NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
- ta.start();
- aai.addAppender(ta);
- NOPAppender<TestEvent> tab = new NOPAppender<TestEvent>();
- tab.setName("test");
- tab.start();
- aai.addAppender(tab);
- assertTrue("Appender is not attached", aai.isAttached(ta));
- assertTrue("Appender is not attached", aai.isAttached(tab));
- }
-
- @Test
- public void testDetachAndStopAllAppenders() throws Exception {
- NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
- ta.start();
- aai.addAppender(ta);
- NOPAppender<TestEvent> tab = new NOPAppender<TestEvent>();
- tab.setName("test");
- tab.start();
- aai.addAppender(tab);
- assertTrue("Appender was not started", tab.isStarted());
- aai.detachAndStopAllAppenders();
- assertNull("Appender was not removed", aai.getAppender("test"));
- assertFalse("Appender was not stopped", tab.isStarted());
- }
-
- @Test
- public void testDetachAppender() throws Exception {
- NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
- ta.start();
- aai.addAppender(ta);
- NOPAppender<TestEvent> tab = new NOPAppender<TestEvent>();
- tab.setName("test");
- tab.start();
- aai.addAppender(tab);
- assertTrue("Appender not detached", aai.detachAppender(tab));
- assertNull("Appender was not removed", aai.getAppender("test"));
- assertFalse("Appender detach error", aai.detachAppender(tab));
- }
-
- @Test
- public void testDetachAppenderByName() throws Exception {
- NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
- ta.setName("test1");
- ta.start();
- aai.addAppender(ta);
- NOPAppender<TestEvent> tab = new NOPAppender<TestEvent>();
- tab.setName("test");
- tab.start();
- aai.addAppender(tab);
-
- assertTrue(aai.detachAppender("test"));
- assertTrue(aai.detachAppender("test1"));
- assertFalse(aai.detachAppender("test1"));
- }
-
- private static class TestEvent {
-
+
+ private AppenderAttachableImpl<TestEvent> aai;
+
+ @Before
+ public void setUp() throws Exception {
+ aai = new AppenderAttachableImpl<TestEvent>();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ aai = null;
+ }
+
+ @Test
+ public void testAddAppender() throws Exception {
+ TestEvent event = new TestEvent();
+ NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
+ ta.start();
+ aai.addAppender(ta);
+ ta = new NOPAppender<TestEvent>();
+ ta.setName("test");
+ ta.start();
+ aai.addAppender(ta);
+ int size = aai.appendLoopOnAppenders(event);
+ assertTrue("Incorrect number of appenders", size == 2);
+ }
+
+ @Test
+ public void testIteratorForAppenders() throws Exception {
+ NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
+ ta.start();
+ aai.addAppender(ta);
+ NOPAppender<TestEvent> tab = new NOPAppender<TestEvent>();
+ tab.setName("test");
+ tab.start();
+ aai.addAppender(tab);
+ Iterator<Appender<TestEvent>> iter = aai.iteratorForAppenders();
+ int size = 0;
+ while (iter.hasNext()) {
+ ++size;
+ Appender<TestEvent> app = iter.next();
+ assertTrue("Bad Appender", app == ta || app == tab);
}
+ assertTrue("Incorrect number of appenders", size == 2);
+ }
+
+ @Test
+ public void getGetAppender() throws Exception {
+ NOPAppender<TestEvent> test = new NOPAppender<TestEvent>();
+ test.setName("test");
+ test.start();
+ aai.addAppender(test);
+
+ NOPAppender<TestEvent> testOther = new NOPAppender<TestEvent>();
+ testOther.setName("testOther");
+ testOther.start();
+ aai.addAppender(testOther);
+
+ Appender<TestEvent> a = aai.getAppender("testOther");
+ assertNotNull("Could not find appender", a);
+ assertTrue("Wrong appender", a == testOther);
+
+ a = aai.getAppender("test");
+ assertNotNull("Could not find appender", a);
+ assertTrue("Wrong appender", a == test);
+ a = aai.getAppender("NotThere");
+ assertNull("Appender was returned", a);
+ }
+
+ @Test
+ public void testIsAttached() throws Exception {
+ NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
+ ta.start();
+ aai.addAppender(ta);
+ NOPAppender<TestEvent> tab = new NOPAppender<TestEvent>();
+ tab.setName("test");
+ tab.start();
+ aai.addAppender(tab);
+ assertTrue("Appender is not attached", aai.isAttached(ta));
+ assertTrue("Appender is not attached", aai.isAttached(tab));
+ }
+
+ @Test
+ public void testDetachAndStopAllAppenders() throws Exception {
+ NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
+ ta.start();
+ aai.addAppender(ta);
+ NOPAppender<TestEvent> tab = new NOPAppender<TestEvent>();
+ tab.setName("test");
+ tab.start();
+ aai.addAppender(tab);
+ assertTrue("Appender was not started", tab.isStarted());
+ aai.detachAndStopAllAppenders();
+ assertNull("Appender was not removed", aai.getAppender("test"));
+ assertFalse("Appender was not stopped", tab.isStarted());
+ }
+
+ @Test
+ public void testDetachAppender() throws Exception {
+ NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
+ ta.start();
+ aai.addAppender(ta);
+ NOPAppender<TestEvent> tab = new NOPAppender<TestEvent>();
+ tab.setName("test");
+ tab.start();
+ aai.addAppender(tab);
+ assertTrue("Appender not detached", aai.detachAppender(tab));
+ assertNull("Appender was not removed", aai.getAppender("test"));
+ assertFalse("Appender detach error", aai.detachAppender(tab));
+ }
+
+ @Test
+ public void testDetachAppenderByName() throws Exception {
+ NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
+ ta.setName("test1");
+ ta.start();
+ aai.addAppender(ta);
+ NOPAppender<TestEvent> tab = new NOPAppender<TestEvent>();
+ tab.setName("test");
+ tab.start();
+ aai.addAppender(tab);
+
+ assertTrue(aai.detachAppender("test"));
+ assertTrue(aai.detachAppender("test1"));
+ assertFalse( aai.detachAppender("test1"));
+ }
+
+ private static class TestEvent {
+
+ }
}
+
diff --git a/logback-core/src/test/java/ch/qos/logback/core/spi/CyclicBufferTrackerSimulator.java b/logback-core/src/test/java/ch/qos/logback/core/spi/CyclicBufferTrackerSimulator.java
index b9e3089..7f1cac7 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/spi/CyclicBufferTrackerSimulator.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/spi/CyclicBufferTrackerSimulator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,111 +18,117 @@ import ch.qos.logback.core.helpers.CyclicBuffer;
import java.util.*;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class CyclicBufferTrackerSimulator {
- static class Parameters {
- public int keySpaceLen;
- public int maxTimestampInc;
- public int simulationLength;
+ static class Parameters {
+ public int keySpaceLen;
+ public int maxTimestampInc;
+ public int simulationLength;
+ }
+
+ CyclicBufferTracker<Object> realCBTracker = new CyclicBufferTracker<Object>();
+ CyclicBufferTrackerT<Object> t_CBTracker = new CyclicBufferTrackerT<Object>();
+
+ List<SimulationEvent> scenario = new ArrayList<SimulationEvent>();
+ List<String> keySpace = new ArrayList<String>();
+ Random randomKeyGen = new Random(100);
+ Random simulatorRandom = new Random(11234);
+ Parameters params;
+
+ int getToEndOfLifeRatio = 10;
+
+ CyclicBufferTrackerSimulator(Parameters params) {
+ this.params = params;
+ Map<String, String> checkMap = new HashMap<String, String>();
+ for (int i = 0; i < params.keySpaceLen; i++) {
+ String k = getRandomKeyStr();
+ if (checkMap.containsKey(k)) {
+ System.out.println("random key collision occurred");
+ k += "" + i;
+ }
+ keySpace.add(k);
+ checkMap.put(k, k);
}
- CyclicBufferTracker<Object> realCBTracker = new CyclicBufferTracker<Object>();
- CyclicBufferTrackerT<Object> t_CBTracker = new CyclicBufferTrackerT<Object>();
-
- List<SimulationEvent> scenario = new ArrayList<SimulationEvent>();
- List<String> keySpace = new ArrayList<String>();
- Random randomKeyGen = new Random(100);
- Random simulatorRandom = new Random(11234);
- Parameters params;
-
- int getToEndOfLifeRatio = 10;
-
- CyclicBufferTrackerSimulator(Parameters params) {
- this.params = params;
- Map<String, String> checkMap = new HashMap<String, String>();
- for (int i = 0; i < params.keySpaceLen; i++) {
- String k = getRandomKeyStr();
- if (checkMap.containsKey(k)) {
- System.out.println("random key collision occurred");
- k += "" + i;
- }
- keySpace.add(k);
- checkMap.put(k, k);
- }
-
- }
-
- private String getRandomKeyStr() {
- int ri = randomKeyGen.nextInt();
- return String.format("%X", ri);
+ }
+
+ private String getRandomKeyStr() {
+ int ri = randomKeyGen.nextInt();
+ return String.format("%X", ri);
+ }
+
+ void buildScenario() {
+ long timestamp = 30000;
+ int keySpaceLen = keySpace.size();
+ for (int i = 0; i < params.simulationLength; i++) {
+ int keyIndex = simulatorRandom.nextInt(keySpaceLen);
+ timestamp += simulatorRandom.nextInt(params.maxTimestampInc);
+ String key = keySpace.get(keyIndex);
+ scenario.add(new SimulationEvent(EventType.INSERT, key, timestamp));
+ if (simulatorRandom.nextInt(getToEndOfLifeRatio) == 0) {
+ scenario.add(new SimulationEvent(EventType.END_OF_LIFE, key, timestamp));
+ }
+ scenario.add(new SimulationEvent(EventType.REMOVE_STALE, key, timestamp));
}
+ }
- void buildScenario() {
- long timestamp = 30000;
- int keySpaceLen = keySpace.size();
- for (int i = 0; i < params.simulationLength; i++) {
- int keyIndex = simulatorRandom.nextInt(keySpaceLen);
- timestamp += simulatorRandom.nextInt(params.maxTimestampInc);
- String key = keySpace.get(keyIndex);
- scenario.add(new SimulationEvent(EventType.INSERT, key, timestamp));
- if (simulatorRandom.nextInt(getToEndOfLifeRatio) == 0) {
- scenario.add(new SimulationEvent(EventType.END_OF_LIFE, key, timestamp));
- }
- scenario.add(new SimulationEvent(EventType.REMOVE_STALE, key, timestamp));
- }
+ public void dump() {
+ for (SimulationEvent simeEvent : scenario) {
+ System.out.println(simeEvent);
}
-
- public void dump() {
- for (SimulationEvent simeEvent : scenario) {
- System.out.println(simeEvent);
- }
+ }
+
+
+ void play(SimulationEvent simulationEvent,
+ ComponentTracker<CyclicBuffer<Object>> tracker) {
+ String key = simulationEvent.key;
+ long timestamp = simulationEvent.timestamp;
+ EventType eventType = simulationEvent.eventType;
+ switch (eventType) {
+ case INSERT:
+ tracker.getOrCreate(key, timestamp);
+ break;
+ case END_OF_LIFE:
+ tracker.endOfLife(key);
+ break;
+ case REMOVE_STALE:
+ tracker.removeStaleComponents(timestamp);
+ break;
}
+ }
- void play(SimulationEvent simulationEvent, ComponentTracker<CyclicBuffer<Object>> tracker) {
- String key = simulationEvent.key;
- long timestamp = simulationEvent.timestamp;
- EventType eventType = simulationEvent.eventType;
- switch (eventType) {
- case INSERT:
- tracker.getOrCreate(key, timestamp);
- break;
- case END_OF_LIFE:
- tracker.endOfLife(key);
- break;
- case REMOVE_STALE:
- tracker.removeStaleComponents(timestamp);
- break;
- }
+ public void simulate() {
+ for (SimulationEvent simeEvent : scenario) {
+ play(simeEvent, realCBTracker);
+ play(simeEvent, t_CBTracker);
}
-
- public void simulate() {
- for (SimulationEvent simeEvent : scenario) {
- play(simeEvent, realCBTracker);
- play(simeEvent, t_CBTracker);
- }
- }
-
- // =========================================================================
- enum EventType {
- INSERT, END_OF_LIFE, REMOVE_STALE;
+ }
+
+ // =========================================================================
+ enum EventType {
+ INSERT, END_OF_LIFE, REMOVE_STALE;
+ }
+
+ class SimulationEvent {
+ final public String key;
+ final public long timestamp;
+ final EventType eventType;
+
+ public SimulationEvent(EventType eventType, String key, long timestamp) {
+ this.eventType = eventType;
+ this.key = key;
+ this.timestamp = timestamp;
}
- class SimulationEvent {
- final public String key;
- final public long timestamp;
- final EventType eventType;
-
- public SimulationEvent(EventType eventType, String key, long timestamp) {
- this.eventType = eventType;
- this.key = key;
- this.timestamp = timestamp;
- }
-
- @Override
- public String toString() {
- return "SimulationEvent{" + "eventType=" + eventType + ", key='" + key + '\'' + ", timestamp=" + timestamp + '}';
- }
+ @Override
+ public String toString() {
+ return "SimulationEvent{" +
+ "eventType=" + eventType +
+ ", key='" + key + '\'' +
+ ", timestamp=" + timestamp +
+ '}';
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/spi/CyclicBufferTrackerT.java b/logback-core/src/test/java/ch/qos/logback/core/spi/CyclicBufferTrackerT.java
index 812d849..3ef6fd2 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/spi/CyclicBufferTrackerT.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/spi/CyclicBufferTrackerT.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,227 +21,226 @@ import java.util.*;
/**
* Another tracker implementtion for testing purposes only.
*
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class CyclicBufferTrackerT<E> implements ComponentTracker<CyclicBuffer<E>> {
- int bufferSize = CyclicBufferTracker.DEFAULT_BUFFER_SIZE;
- int maxComponents = CyclicBufferTracker.DEFAULT_NUMBER_OF_BUFFERS;
-
- List<TEntry<E>> liveList = new LinkedList<TEntry<E>>();
- List<TEntry<E>> lingererList = new LinkedList<TEntry<E>>();
-
- long lastCheck = 0;
-
- private TEntry<E> getEntry(List<TEntry<E>> list, String k) {
- for (int i = 0; i < list.size(); i++) {
- TEntry<E> te = list.get(i);
- if (te.key.equals(k)) {
- return te;
- }
- }
- return null;
- }
-
- private TEntry getFromEitherList(String key) {
- TEntry entry = getEntry(liveList, key);
- if (entry != null)
- return entry;
- else {
- return getEntry(lingererList, key);
- }
- }
-
- private List<String> keysAsOrderedList(List<TEntry<E>> list) {
- Collections.sort(list);
- List<String> result = new LinkedList<String>();
- for (int i = 0; i < list.size(); i++) {
- TEntry<E> te = list.get(i);
- result.add(te.key);
- }
- return result;
- }
-
- List<String> liveKeysAsOrderedList() {
- return keysAsOrderedList(liveList);
- }
-
- List<String> lingererKeysAsOrderedList() {
- return keysAsOrderedList(lingererList);
- }
-
- public Set<String> allKeys() {
- HashSet<String> allKeys = new HashSet<String>();
- for (TEntry e : liveList)
- allKeys.add(e.key);
- for (TEntry e : lingererList)
- allKeys.add(e.key);
- return allKeys;
- }
-
- public Collection<CyclicBuffer<E>> allComponents() {
- List<CyclicBuffer<E>> allComponents = new ArrayList<CyclicBuffer<E>>();
- for (TEntry e : liveList)
- allComponents.add(e.value);
- for (TEntry e : lingererList)
- allComponents.add(e.value);
-
- return allComponents;
- }
-
- public CyclicBuffer<E> find(String key) {
- TEntry<E> te = getFromEitherList(key);
- if (te == null)
- return null;
- else
- return te.value;
- }
-
- public CyclicBuffer<E> getOrCreate(String key, long timestamp) {
- TEntry<E> te = getFromEitherList(key);
- if (te == null) {
- CyclicBuffer<E> cb = new CyclicBuffer<E>(bufferSize);
- te = new TEntry<E>(key, cb, timestamp);
- liveList.add(te);
- if (liveList.size() > maxComponents) {
- Collections.sort(liveList);
- liveList.remove(0);
- }
- } else {
- te.timestamp = timestamp;
- Collections.sort(liveList);
- }
- return te.value;
- }
-
- public void endOfLife(String k) {
- TEntry<E> te = null;
- boolean found = false;
- for (int i = 0; i < liveList.size(); i++) {
- te = liveList.get(i);
- if (te.key.equals(k)) {
- liveList.remove(i);
- found = true;
- break;
- }
- }
- if (found) {
- lingererList.add(te);
- }
- }
-
- private boolean isEntryStale(TEntry<E> entry, long now) {
- return ((entry.timestamp + DEFAULT_TIMEOUT) < now);
- }
-
- private boolean isEntryDoneLingering(TEntry<E> tEntry, long now) {
- return ((tEntry.timestamp + AbstractComponentTracker.LINGERING_TIMEOUT) < now);
- }
-
- public void removeStaleComponents(long now) {
- if (isTooSoonForRemovalIteration(now))
- return;
- // both list should be sorted before removal attempts
+ int bufferSize = CyclicBufferTracker.DEFAULT_BUFFER_SIZE;
+ int maxComponents = CyclicBufferTracker.DEFAULT_NUMBER_OF_BUFFERS;
+
+ List<TEntry<E>> liveList = new LinkedList<TEntry<E>>();
+ List<TEntry<E>> lingererList = new LinkedList<TEntry<E>>();
+
+ long lastCheck = 0;
+
+
+ private TEntry<E> getEntry(List<TEntry<E>> list,String k) {
+ for (int i = 0; i < list.size(); i++) {
+ TEntry<E> te = list.get(i);
+ if (te.key.equals(k)) {
+ return te;
+ }
+ }
+ return null;
+ }
+
+ private TEntry getFromEitherList(String key) {
+ TEntry entry = getEntry(liveList, key);
+ if(entry != null)
+ return entry;
+ else {
+ return getEntry(lingererList, key);
+ }
+ }
+
+ private List<String> keysAsOrderedList(List<TEntry<E>> list) {
+ Collections.sort(list);
+ List<String> result = new LinkedList<String>();
+ for (int i = 0; i < list.size(); i++) {
+ TEntry<E> te = list.get(i);
+ result.add(te.key);
+ }
+ return result;
+ }
+
+ List<String> liveKeysAsOrderedList() {
+ return keysAsOrderedList(liveList);
+ }
+ List<String> lingererKeysAsOrderedList() {
+ return keysAsOrderedList(lingererList);
+ }
+
+
+ public Set<String> allKeys() {
+ HashSet<String> allKeys = new HashSet<String>();
+ for (TEntry e : liveList)
+ allKeys.add(e.key);
+ for (TEntry e : lingererList)
+ allKeys.add(e.key);
+ return allKeys;
+ }
+
+
+ public Collection<CyclicBuffer<E>> allComponents() {
+ List<CyclicBuffer<E>> allComponents = new ArrayList<CyclicBuffer<E>>();
+ for (TEntry e : liveList)
+ allComponents.add(e.value);
+ for (TEntry e : lingererList)
+ allComponents.add(e.value);
+
+ return allComponents;
+ }
+
+ public CyclicBuffer<E> find(String key) {
+ TEntry<E> te = getFromEitherList(key);
+ if(te == null) return null;
+ else return te.value;
+ }
+
+ public CyclicBuffer<E> getOrCreate(String key, long timestamp) {
+ TEntry<E> te = getFromEitherList(key);
+ if (te == null) {
+ CyclicBuffer<E> cb = new CyclicBuffer<E>(bufferSize);
+ te = new TEntry<E>(key, cb, timestamp);
+ liveList.add(te);
+ if (liveList.size() > maxComponents) {
Collections.sort(liveList);
- Collections.sort(lingererList);
- removeComponentsInExcessFromMainList();
- removeStaleComponentsFromMainList(now);
- removeStaleComponentsFromLingerersList(now);
- }
-
- private void removeComponentsInExcessFromMainList() {
- while (liveList.size() > maxComponents) {
- liveList.remove(0);
- }
+ liveList.remove(0);
+ }
+ } else {
+ te.timestamp = timestamp;
+ Collections.sort(liveList);
+ }
+ return te.value;
+ }
+
+ public void endOfLife(String k) {
+ TEntry<E> te = null;
+ boolean found = false;
+ for (int i = 0; i < liveList.size(); i++) {
+ te = liveList.get(i);
+ if (te.key.equals(k)) {
+ liveList.remove(i);
+ found = true;
+ break;
+ }
+ }
+ if(found) {
+ lingererList.add(te);
+ }
+ }
+
+ private boolean isEntryStale(TEntry<E> entry, long now) {
+ return ((entry.timestamp + DEFAULT_TIMEOUT) < now);
+ }
+ private boolean isEntryDoneLingering(TEntry<E> tEntry, long now) {
+ return ((tEntry.timestamp + AbstractComponentTracker.LINGERING_TIMEOUT) < now);
+ }
+
+ public void removeStaleComponents(long now) {
+ if (isTooSoonForRemovalIteration(now)) return;
+ // both list should be sorted before removal attempts
+ Collections.sort(liveList);
+ Collections.sort(lingererList);
+ removeComponentsInExcessFromMainList();
+ removeStaleComponentsFromMainList(now);
+ removeStaleComponentsFromLingerersList(now);
+ }
+
+ private void removeComponentsInExcessFromMainList() {
+ while (liveList.size() > maxComponents) {
+ liveList.remove(0);
+ }
+ }
+
+ private void removeStaleComponentsFromMainList(long now) {
+ while (liveList.size() != 0 && isEntryStale(liveList.get(0), now)) {
+ liveList.remove(0);
+ }
+ }
+
+ private void removeStaleComponentsFromLingerersList(long now) {
+ while (lingererList.size() != 0 && isEntryDoneLingering(lingererList.get(0), now)) {
+ lingererList.remove(0);
+ }
+ }
+
+ private boolean isTooSoonForRemovalIteration(long now) {
+ if (lastCheck + CoreConstants.MILLIS_IN_ONE_SECOND > now) {
+ return true;
+ }
+ lastCheck = now;
+ return false;
+ }
+
+ public int getComponentCount() {
+ return liveList.size() + lingererList.size();
+ }
+
+
+ // ==================================================================
+
+ private class TEntry<X> implements Comparable<TEntry<?>> {
+
+ String key;
+ CyclicBuffer<E> value;
+ long timestamp;
+
+ TEntry(String k, CyclicBuffer<E> v, long timestamp) {
+ this.key = k;
+ this.value = v;
+ this.timestamp = timestamp;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((key == null) ? 0 : key.hashCode());
+ return result;
+ }
+
+ public int compareTo(TEntry<?> o) {
+ if (!(o instanceof TEntry)) {
+ throw new IllegalArgumentException("arguments must be of type " + TEntry.class);
+ }
+
+ TEntry<?> other = (TEntry<?>) o;
+ if (timestamp > other.timestamp) {
+ return 1;
+ }
+ if (timestamp == other.timestamp) {
+ return 0;
+ }
+ return -1;
}
-
- private void removeStaleComponentsFromMainList(long now) {
- while (liveList.size() != 0 && isEntryStale(liveList.get(0), now)) {
- liveList.remove(0);
- }
- }
-
- private void removeStaleComponentsFromLingerersList(long now) {
- while (lingererList.size() != 0 && isEntryDoneLingering(lingererList.get(0), now)) {
- lingererList.remove(0);
- }
- }
-
- private boolean isTooSoonForRemovalIteration(long now) {
- if (lastCheck + CoreConstants.MILLIS_IN_ONE_SECOND > now) {
- return true;
- }
- lastCheck = now;
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
return false;
+ if (getClass() != obj.getClass())
+ return false;
+ @SuppressWarnings("unchecked")
+ final TEntry<?> other = (TEntry<?>) obj;
+ if (key == null) {
+ if (other.key != null)
+ return false;
+ } else if (!key.equals(other.key))
+ return false;
+ if (value == null) {
+ if (other.value != null)
+ return false;
+ } else if (!value.equals(other.value))
+ return false;
+ return true;
}
- public int getComponentCount() {
- return liveList.size() + lingererList.size();
- }
-
- // ==================================================================
-
- private class TEntry<X> implements Comparable<TEntry<?>> {
-
- String key;
- CyclicBuffer<E> value;
- long timestamp;
-
- TEntry(String k, CyclicBuffer<E> v, long timestamp) {
- this.key = k;
- this.value = v;
- this.timestamp = timestamp;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((key == null) ? 0 : key.hashCode());
- return result;
- }
-
- public int compareTo(TEntry<?> o) {
- if (!(o instanceof TEntry)) {
- throw new IllegalArgumentException("arguments must be of type " + TEntry.class);
- }
-
- TEntry<?> other = (TEntry<?>) o;
- if (timestamp > other.timestamp) {
- return 1;
- }
- if (timestamp == other.timestamp) {
- return 0;
- }
- return -1;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- @SuppressWarnings("unchecked")
- final TEntry<?> other = (TEntry<?>) obj;
- if (key == null) {
- if (other.key != null)
- return false;
- } else if (!key.equals(other.key))
- return false;
- if (value == null) {
- if (other.value != null)
- return false;
- } else if (!value.equals(other.value))
- return false;
- return true;
- }
-
- @Override
- public String toString() {
- return "(" + key + ", " + value + ")";
- }
+ @Override
+ public String toString() {
+ return "(" + key + ", " + value + ")";
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/spi/CyclicBufferTrackerTest.java b/logback-core/src/test/java/ch/qos/logback/core/spi/CyclicBufferTrackerTest.java
index eb743b6..f9c1606 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/spi/CyclicBufferTrackerTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/spi/CyclicBufferTrackerTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,56 +20,60 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class CyclicBufferTrackerTest {
- CyclicBufferTracker<Object> tracker = new CyclicBufferTracker<Object>();
- String key = "a";
- @Test
- public void empty0() {
- long now = 3000;
- tracker.removeStaleComponents(now);
- assertEquals(0, tracker.liveKeysAsOrderedList().size());
- assertEquals(0, tracker.getComponentCount());
- }
+ CyclicBufferTracker<Object> tracker = new CyclicBufferTracker<Object>();
+ String key = "a";
- @Test
- public void empty1() {
- long now = 3000;
- assertNotNull(tracker.getOrCreate(key, now++));
- now += ComponentTracker.DEFAULT_TIMEOUT + 1000;
- tracker.removeStaleComponents(now);
- assertEquals(0, tracker.liveKeysAsOrderedList().size());
- assertEquals(0, tracker.getComponentCount());
+ @Test
+ public void empty0() {
+ long now = 3000;
+ tracker.removeStaleComponents(now);
+ assertEquals(0, tracker.liveKeysAsOrderedList().size());
+ assertEquals(0, tracker.getComponentCount());
+ }
+
+ @Test
+ public void empty1() {
+ long now = 3000;
+ assertNotNull(tracker.getOrCreate(key, now++));
+ now += ComponentTracker.DEFAULT_TIMEOUT + 1000;
+ tracker.removeStaleComponents(now);
+ assertEquals(0, tracker.liveKeysAsOrderedList().size());
+ assertEquals(0, tracker.getComponentCount());
+
+ assertNotNull(tracker.getOrCreate(key, now++));
+ }
+
+ @Test
+ public void smoke() {
+ long now = 3000;
+ CyclicBuffer<Object> cb = tracker.getOrCreate(key, now);
+ assertEquals(cb, tracker.getOrCreate(key, now++));
+ now += CyclicBufferTracker.DEFAULT_TIMEOUT + 1000;
+ tracker.removeStaleComponents(now);
+ assertEquals(0, tracker.liveKeysAsOrderedList().size());
+ assertEquals(0, tracker.getComponentCount());
+ }
+
+ @Test
+ public void destroy() {
+ long now = 3000;
+ CyclicBuffer<Object> cb = tracker.getOrCreate(key, now);
+ cb.add(new Object());
+ assertEquals(1, cb.length());
+ tracker.endOfLife(key);
+ now += CyclicBufferTracker.LINGERING_TIMEOUT + 10;
+ tracker.removeStaleComponents(now);
+ assertEquals(0, tracker.liveKeysAsOrderedList().size());
+ assertEquals(0, tracker.getComponentCount());
+ assertEquals(0, cb.length());
+ }
- assertNotNull(tracker.getOrCreate(key, now++));
- }
- @Test
- public void smoke() {
- long now = 3000;
- CyclicBuffer<Object> cb = tracker.getOrCreate(key, now);
- assertEquals(cb, tracker.getOrCreate(key, now++));
- now += CyclicBufferTracker.DEFAULT_TIMEOUT + 1000;
- tracker.removeStaleComponents(now);
- assertEquals(0, tracker.liveKeysAsOrderedList().size());
- assertEquals(0, tracker.getComponentCount());
- }
- @Test
- public void destroy() {
- long now = 3000;
- CyclicBuffer<Object> cb = tracker.getOrCreate(key, now);
- cb.add(new Object());
- assertEquals(1, cb.length());
- tracker.endOfLife(key);
- now += CyclicBufferTracker.LINGERING_TIMEOUT + 10;
- tracker.removeStaleComponents(now);
- assertEquals(0, tracker.liveKeysAsOrderedList().size());
- assertEquals(0, tracker.getComponentCount());
- assertEquals(0, cb.length());
- }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/spi/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/spi/PackageTest.java
index d8d7ab3..dd98a07 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/spi/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/spi/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,8 +16,10 @@ package ch.qos.logback.core.spi;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
+
@RunWith(Suite.class)
- at Suite.SuiteClasses({ AppenderAttachableImplTest.class, AppenderAttachableImplLockTest.class, CyclicBufferTrackerTest.class,
- ScenarioBasedCyclicBufferTrackerTest.class })
+ at Suite.SuiteClasses({AppenderAttachableImplTest.class, AppenderAttachableImplLockTest.class,
+ CyclicBufferTrackerTest.class, ScenarioBasedCyclicBufferTrackerTest.class})
+
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/spi/ScenarioBasedCyclicBufferTrackerTest.java b/logback-core/src/test/java/ch/qos/logback/core/spi/ScenarioBasedCyclicBufferTrackerTest.java
index dd528a0..a5da74e 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/spi/ScenarioBasedCyclicBufferTrackerTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/spi/ScenarioBasedCyclicBufferTrackerTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,54 +21,53 @@ import static junit.framework.Assert.assertEquals;
/**
* A
*
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class ScenarioBasedCyclicBufferTrackerTest {
- CyclicBufferTrackerSimulator simulator;
- CyclicBufferTrackerSimulator.Parameters parameters = new CyclicBufferTrackerSimulator.Parameters();
+ CyclicBufferTrackerSimulator simulator;
+ CyclicBufferTrackerSimulator.Parameters parameters = new CyclicBufferTrackerSimulator.Parameters();
- void verify() {
- CyclicBufferTracker<Object> at = simulator.realCBTracker;
- CyclicBufferTrackerT<Object> t_at = simulator.t_CBTracker;
- assertEquals(t_at.liveKeysAsOrderedList(), at.liveKeysAsOrderedList());
- assertEquals(t_at.lingererKeysAsOrderedList(), at.lingererKeysAsOrderedList());
- }
+ void verify() {
+ CyclicBufferTracker<Object> at = simulator.realCBTracker;
+ CyclicBufferTrackerT<Object> t_at = simulator.t_CBTracker;
+ assertEquals(t_at.liveKeysAsOrderedList(), at.liveKeysAsOrderedList());
+ assertEquals(t_at.lingererKeysAsOrderedList(), at.lingererKeysAsOrderedList());
+ }
- @Before
- public void setUp() {
- parameters.keySpaceLen = 128;
- parameters.maxTimestampInc = ComponentTracker.DEFAULT_TIMEOUT / 2;
- }
+ @Before public void setUp() {
+ parameters.keySpaceLen = 128;
+ parameters.maxTimestampInc = ComponentTracker.DEFAULT_TIMEOUT / 2;
+ }
- @Test
- public void shortTest() {
- parameters.keySpaceLen = 64;
- parameters.maxTimestampInc = 500;
- parameters.simulationLength = 70;
+ @Test
+ public void shortTest() {
+ parameters.keySpaceLen = 64;
+ parameters.maxTimestampInc = 500;
+ parameters.simulationLength = 70;
- simulator = new CyclicBufferTrackerSimulator(parameters);
- simulator.buildScenario();
- simulator.simulate();
- verify();
- }
+ simulator = new CyclicBufferTrackerSimulator(parameters);
+ simulator.buildScenario();
+ simulator.simulate();
+ verify();
+ }
- @Test
- public void mediumTest() {
- parameters.simulationLength = 20000;
+ @Test
+ public void mediumTest() {
+ parameters.simulationLength = 20000;
- simulator = new CyclicBufferTrackerSimulator(parameters);
- simulator.buildScenario();
- simulator.simulate();
- verify();
- }
+ simulator = new CyclicBufferTrackerSimulator(parameters);
+ simulator.buildScenario();
+ simulator.simulate();
+ verify();
+ }
- @Test
- public void longTest() {
- parameters.simulationLength = 100 * 1000;
- simulator = new CyclicBufferTrackerSimulator(parameters);
- simulator.buildScenario();
- simulator.simulate();
- verify();
- }
+ @Test
+ public void longTest() {
+ parameters.simulationLength = 100*1000;
+ simulator = new CyclicBufferTrackerSimulator(parameters);
+ simulator.buildScenario();
+ simulator.simulate();
+ verify();
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/status/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/status/PackageTest.java
index 8b73bfb..137ba69 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/status/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/status/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,7 +16,9 @@ package ch.qos.logback.core.status;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
+
@RunWith(Suite.class)
- at Suite.SuiteClasses({ StatusBaseTest.class, StatusUtilTest.class })
+ at Suite.SuiteClasses({StatusBaseTest.class, StatusUtilTest.class})
+
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/status/StatusBaseTest.java b/logback-core/src/test/java/ch/qos/logback/core/status/StatusBaseTest.java
index bca8e5a..131d8db 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/status/StatusBaseTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/status/StatusBaseTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,70 +19,75 @@ import junit.framework.TestCase;
public class StatusBaseTest extends TestCase {
- public void testAddStatus() {
- {
- InfoStatus status = new InfoStatus("testing", this);
- status.add(new ErrorStatus("error", this));
- Iterator it = status.iterator();
- assertTrue("No status was added", it.hasNext());
- assertTrue("hasChilden method reported wrong result", status.hasChildren());
- }
- {
- InfoStatus status = new InfoStatus("testing", this);
- try {
- status.add(null);
- fail("method should have thrown an Exception");
- } catch (NullPointerException ex) {
- }
- }
+ public void testAddStatus() {
+ {
+ InfoStatus status = new InfoStatus("testing", this);
+ status.add(new ErrorStatus("error", this));
+ Iterator it = status.iterator();
+ assertTrue("No status was added", it.hasNext());
+ assertTrue("hasChilden method reported wrong result", status
+ .hasChildren());
}
+ {
+ InfoStatus status = new InfoStatus("testing", this);
+ try {
+ status.add(null);
+ fail("method should have thrown an Exception");
+ } catch (NullPointerException ex) {
+ }
+ }
+ }
- public void testRemoveStatus() {
- {
- InfoStatus status = new InfoStatus("testing", this);
- ErrorStatus error = new ErrorStatus("error", this);
- status.add(error);
- boolean result = status.remove(error);
- Iterator it = status.iterator();
- assertTrue("Remove failed", result);
- assertFalse("No status was removed", it.hasNext());
- assertFalse("hasChilden method reported wrong result", status.hasChildren());
- }
- {
- InfoStatus status = new InfoStatus("testing", this);
- ErrorStatus error = new ErrorStatus("error", this);
- status.add(error);
- boolean result = status.remove(null);
- assertFalse("Remove result was not false", result);
- }
+ public void testRemoveStatus() {
+ {
+ InfoStatus status = new InfoStatus("testing", this);
+ ErrorStatus error = new ErrorStatus("error", this);
+ status.add(error);
+ boolean result = status.remove(error);
+ Iterator it = status.iterator();
+ assertTrue("Remove failed", result);
+ assertFalse("No status was removed", it.hasNext());
+ assertFalse("hasChilden method reported wrong result", status
+ .hasChildren());
+ }
+ {
+ InfoStatus status = new InfoStatus("testing", this);
+ ErrorStatus error = new ErrorStatus("error", this);
+ status.add(error);
+ boolean result = status.remove(null);
+ assertFalse("Remove result was not false", result);
}
+ }
- public void testEffectiveLevel() {
- {
- // effective level = 0 level deep
- ErrorStatus status = new ErrorStatus("error", this);
- WarnStatus warn = new WarnStatus("warning", this);
- status.add(warn);
- assertEquals("effective level misevaluated", status.getEffectiveLevel(), Status.ERROR);
- }
+ public void testEffectiveLevel() {
+ {
+ // effective level = 0 level deep
+ ErrorStatus status = new ErrorStatus("error", this);
+ WarnStatus warn = new WarnStatus("warning", this);
+ status.add(warn);
+ assertEquals("effective level misevaluated", status.getEffectiveLevel(),
+ Status.ERROR);
+ }
- {
- // effective level = 1 level deep
- InfoStatus status = new InfoStatus("info", this);
- WarnStatus warn = new WarnStatus("warning", this);
- status.add(warn);
- assertEquals("effective level misevaluated", status.getEffectiveLevel(), Status.WARN);
- }
+ {
+ // effective level = 1 level deep
+ InfoStatus status = new InfoStatus("info", this);
+ WarnStatus warn = new WarnStatus("warning", this);
+ status.add(warn);
+ assertEquals("effective level misevaluated", status.getEffectiveLevel(),
+ Status.WARN);
+ }
- {
- // effective level = 2 levels deep
- InfoStatus status = new InfoStatus("info", this);
- WarnStatus warn = new WarnStatus("warning", this);
- ErrorStatus error = new ErrorStatus("error", this);
- status.add(warn);
- warn.add(error);
- assertEquals("effective level misevaluated", status.getEffectiveLevel(), Status.ERROR);
- }
+ {
+ // effective level = 2 levels deep
+ InfoStatus status = new InfoStatus("info", this);
+ WarnStatus warn = new WarnStatus("warning", this);
+ ErrorStatus error = new ErrorStatus("error", this);
+ status.add(warn);
+ warn.add(error);
+ assertEquals("effective level misevaluated", status.getEffectiveLevel(),
+ Status.ERROR);
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/status/StatusChecker.java b/logback-core/src/test/java/ch/qos/logback/core/status/StatusChecker.java
index 687e40d..e26a33c 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/status/StatusChecker.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/status/StatusChecker.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -11,47 +11,41 @@
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
+
package ch.qos.logback.core.status;
import ch.qos.logback.core.Context;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
/**
* Extend StatusUtil with assertions.
*/
public class StatusChecker extends StatusUtil {
- public StatusChecker(StatusManager sm) {
- super(sm);
- }
-
- public StatusChecker(Context context) {
- super(context);
- }
-
- public void assertContainsMatch(int level, String regex) {
- assertTrue(containsMatch(level, regex));
- }
-
- public void assertNoMatch(String regex) {
- assertFalse(containsMatch(regex));
- }
-
- public void assertContainsMatch(String regex) {
- assertTrue(containsMatch(regex));
- }
-
- public void asssertContainsException(Class<?> scanExceptionClass) {
- assertTrue(containsException(scanExceptionClass));
- }
-
- public void assertIsErrorFree() {
- assertTrue(isErrorFree(0));
- }
-
- public void assertIsWarningOrErrorFree() {
- assertTrue(isWarningOrErrorFree(0));
- }
+ public StatusChecker(StatusManager sm) {
+ super(sm);
+ }
+
+ public StatusChecker(Context context) {
+ super(context);
+ }
+
+ public void assertContainsMatch(int level, String regex) {
+ assertTrue(containsMatch(level, regex));
+ }
+
+ public void assertContainsMatch(String regex) {
+ assertTrue(containsMatch(regex));
+ }
+
+ public void asssertContainsException(Class<?> scanExceptionClass) {
+ assertTrue(containsException(scanExceptionClass));
+ }
+
+ public void assertIsErrorFree() {
+ assertTrue(isErrorFree(0));
+ }
+
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/status/StatusUtilTest.java b/logback-core/src/test/java/ch/qos/logback/core/status/StatusUtilTest.java
index ac7d640..a246e7b 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/status/StatusUtilTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/status/StatusUtilTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,31 +22,32 @@ import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class StatusUtilTest {
- Context context = new ContextBase();
- StatusUtil statusUtil = new StatusUtil(context);
-
- @Test
- public void emptyStatusListShouldResultInNotFound() {
- assertEquals(-1, statusUtil.timeOfLastReset());
- }
-
- @Test
- public void withoutResetsStatusUtilShouldReturnNotFound() {
- context.getStatusManager().add(new InfoStatus("test", this));
- assertEquals(-1, statusUtil.timeOfLastReset());
- }
-
- @Test
- public void statusListShouldReturnLastResetTime() {
- context.getStatusManager().add(new InfoStatus("test", this));
- long resetTime = System.currentTimeMillis();
- context.getStatusManager().add(new InfoStatus(CoreConstants.RESET_MSG_PREFIX, this));
- context.getStatusManager().add(new InfoStatus("bla", this));
- assertTrue(resetTime <= statusUtil.timeOfLastReset());
- }
+ Context context = new ContextBase();
+ StatusUtil statusUtil = new StatusUtil(context);
+
+ @Test
+ public void emptyStatusListShouldResultInNotFound() {
+ assertEquals(-1, statusUtil.timeOfLastReset());
+ }
+
+ @Test
+ public void withoutResetsStatusUtilShouldReturnNotFound() {
+ context.getStatusManager().add(new InfoStatus("test", this));
+ assertEquals(-1, statusUtil.timeOfLastReset());
+ }
+
+ @Test
+ public void statusListShouldReturnLastResetTime() {
+ context.getStatusManager().add(new InfoStatus("test", this));
+ long resetTime = System.currentTimeMillis();
+ context.getStatusManager().add(new InfoStatus(CoreConstants.RESET_MSG_PREFIX, this));
+ context.getStatusManager().add(new InfoStatus("bla", this));
+ assertTrue(resetTime <= statusUtil.timeOfLastReset());
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/status/TrivialStatusListener.java b/logback-core/src/test/java/ch/qos/logback/core/status/TrivialStatusListener.java
index 8917911..5a960ad 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/status/TrivialStatusListener.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/status/TrivialStatusListener.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,24 +22,24 @@ import ch.qos.logback.core.status.StatusListener;
public class TrivialStatusListener implements StatusListener, LifeCycle {
- public List<Status> list = new ArrayList<Status>();
- boolean start = false;
+ public List<Status> list = new ArrayList<Status>();
+ boolean start = false;
- public void addStatusEvent(Status status) {
- if (!isStarted())
- return;
- list.add(status);
- }
+ public void addStatusEvent(Status status) {
+ if(!isStarted())
+ return;
+ list.add(status);
+ }
- public void start() {
- start = true;
- }
+ public void start() {
+ start = true;
+ }
- public void stop() {
- start = false;
- }
+ public void stop() {
+ start = false;
+ }
- public boolean isStarted() {
- return start;
- }
+ public boolean isStarted() {
+ return start;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/subst/NodeToStringTransformerTest.java b/logback-core/src/test/java/ch/qos/logback/core/subst/NodeToStringTransformerTest.java
index f005ce9..821dea6 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/subst/NodeToStringTransformerTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/subst/NodeToStringTransformerTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,112 +21,116 @@ import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class NodeToStringTransformerTest {
- ContextBase propertyContainer0 = new ContextBase();
-
- @Before
- public void setUp() {
- propertyContainer0.putProperty("k0", "v0");
- propertyContainer0.putProperty("zero", "0");
- propertyContainer0.putProperty("v0.jdbc.url", "http://..");
- propertyContainer0.putProperty("host", "local");
-
- }
-
- private Node makeNode(String input) throws ScanException {
- Tokenizer tokenizer = new Tokenizer(input);
- Parser parser = new Parser(tokenizer.tokenize());
- return parser.parse();
- }
-
- @Test
- public void literal() throws ScanException {
- String input = "abv";
- Node node = makeNode(input);
- NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
- assertEquals(input, nodeToStringTransformer.transform());
- }
-
- void checkInputEqualsOutput(String input) throws ScanException {
- Node node = makeNode(input);
- NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
- assertEquals(input, nodeToStringTransformer.transform());
- }
-
- @Test
- public void literalWithNestedAccolades() throws ScanException {
- checkInputEqualsOutput("%logger{35}");
- checkInputEqualsOutput("%a{35} %b{35} c");
- checkInputEqualsOutput("%replace(%msg){'\\d{14,16}', 'XXXX'}");
- checkInputEqualsOutput("TEST %d{HHmmssSSS} [%thread] %-5level %logger{36} - %msg%n");
- }
-
- @Test
- public void variable() throws ScanException {
- String input = "${k0}";
- Node node = makeNode(input);
- NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
- assertEquals("v0", nodeToStringTransformer.transform());
- }
-
- @Test
- public void literalVariableLiteral() throws ScanException {
- String input = "a${k0}c";
- Node node = makeNode(input);
- NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
- assertEquals("av0c", nodeToStringTransformer.transform());
- }
-
- @Test
- public void nestedVariable() throws ScanException {
- String input = "a${k${zero}}b";
- Node node = makeNode(input);
- NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
- assertEquals("av0b", nodeToStringTransformer.transform());
- }
-
- @Test
- public void LOGBACK729() throws ScanException {
- String input = "${${k0}.jdbc.url}";
- Node node = makeNode(input);
- NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
- assertEquals("http://..", nodeToStringTransformer.transform());
- }
-
- @Test
- public void LOGBACK744_withColon() throws ScanException {
- String input = "%d{HH:mm:ss.SSS} host:${host} %logger{36} - %msg%n";
- Node node = makeNode(input);
- NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
- System.out.println(nodeToStringTransformer.transform());
- assertEquals("%d{HH:mm:ss.SSS} host:local %logger{36} - %msg%n", nodeToStringTransformer.transform());
- }
-
- @Test
- public void loneColonShouldReadLikeAnyOtherCharacter() throws ScanException {
- String input = "java:comp/env/jdbc/datasource";
- Node node = makeNode(input);
- NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
- assertEquals(input, nodeToStringTransformer.transform());
- }
-
- @Test
- public void withDefaultValue() throws ScanException {
- String input = "${k67:-b}c";
- Node node = makeNode(input);
- NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
- assertEquals("bc", nodeToStringTransformer.transform());
- }
-
- @Test
- public void defaultValueNestedAsVar() throws ScanException {
- String input = "a${k67:-x${k0}}c";
- Node node = makeNode(input);
- NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
- assertEquals("axv0c", nodeToStringTransformer.transform());
- }
+ ContextBase propertyContainer0 = new ContextBase();
+
+
+ @Before
+ public void setUp() {
+ propertyContainer0.putProperty("k0", "v0");
+ propertyContainer0.putProperty("zero", "0");
+ propertyContainer0.putProperty("v0.jdbc.url", "http://..");
+ propertyContainer0.putProperty("host", "local");
+
+ }
+
+ private Node makeNode(String input) throws ScanException {
+ Tokenizer tokenizer = new Tokenizer(input);
+ Parser parser = new Parser(tokenizer.tokenize());
+ return parser.parse();
+ }
+
+ @Test
+ public void literal() throws ScanException {
+ String input = "abv";
+ Node node = makeNode(input);
+ NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
+ assertEquals(input, nodeToStringTransformer.transform());
+ }
+
+
+ void checkInputEqualsOutput(String input) throws ScanException {
+ Node node = makeNode(input);
+ NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
+ assertEquals(input, nodeToStringTransformer.transform());
+ }
+
+ @Test
+ public void literalWithNestedAccolades() throws ScanException {
+ checkInputEqualsOutput("%logger{35}");
+ checkInputEqualsOutput("%a{35} %b{35} c");
+ checkInputEqualsOutput("%replace(%msg){'\\d{14,16}', 'XXXX'}");
+ checkInputEqualsOutput("TEST %d{HHmmssSSS} [%thread] %-5level %logger{36} - %msg%n");
+ }
+
+
+ @Test
+ public void variable() throws ScanException {
+ String input = "${k0}";
+ Node node = makeNode(input);
+ NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
+ assertEquals("v0", nodeToStringTransformer.transform());
+ }
+
+ @Test
+ public void literalVariableLiteral() throws ScanException {
+ String input = "a${k0}c";
+ Node node = makeNode(input);
+ NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
+ assertEquals("av0c", nodeToStringTransformer.transform());
+ }
+
+ @Test
+ public void nestedVariable() throws ScanException {
+ String input = "a${k${zero}}b";
+ Node node = makeNode(input);
+ NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
+ assertEquals("av0b", nodeToStringTransformer.transform());
+ }
+
+ @Test
+ public void LOGBACK729() throws ScanException {
+ String input = "${${k0}.jdbc.url}";
+ Node node = makeNode(input);
+ NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
+ assertEquals("http://..", nodeToStringTransformer.transform());
+ }
+
+ @Test
+ public void LOGBACK744_withColon() throws ScanException {
+ String input = "%d{HH:mm:ss.SSS} host:${host} %logger{36} - %msg%n";
+ Node node = makeNode(input);
+ NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
+ System.out.println(nodeToStringTransformer.transform());
+ assertEquals("%d{HH:mm:ss.SSS} host:local %logger{36} - %msg%n", nodeToStringTransformer.transform());
+ }
+
+ @Test
+ public void loneColonShouldReadLikeAnyOtherCharacter() throws ScanException {
+ String input = "java:comp/env/jdbc/datasource";
+ Node node = makeNode(input);
+ NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
+ assertEquals(input, nodeToStringTransformer.transform());
+ }
+
+ @Test
+ public void withDefaultValue() throws ScanException {
+ String input = "${k67:-b}c";
+ Node node = makeNode(input);
+ NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
+ assertEquals("bc", nodeToStringTransformer.transform());
+ }
+
+ @Test
+ public void defaultValueNestedAsVar() throws ScanException {
+ String input = "a${k67:-x${k0}}c";
+ Node node = makeNode(input);
+ NodeToStringTransformer nodeToStringTransformer = new NodeToStringTransformer(node, propertyContainer0);
+ assertEquals("axv0c", nodeToStringTransformer.transform());
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/subst/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/subst/PackageTest.java
index d71c86b..af66f3a 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/subst/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/subst/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,7 +16,9 @@ package ch.qos.logback.core.subst;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
+
@RunWith(Suite.class)
- at Suite.SuiteClasses({ TokenizerTest.class, ParserTest.class, NodeToStringTransformerTest.class })
+ at Suite.SuiteClasses({TokenizerTest.class, ParserTest.class, NodeToStringTransformerTest.class})
+
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/subst/ParserTest.java b/logback-core/src/test/java/ch/qos/logback/core/subst/ParserTest.java
index 57af400..d8a404b 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/subst/ParserTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/subst/ParserTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,166 +30,170 @@ import ch.qos.logback.core.spi.ScanException;
*/
public class ParserTest {
- @Test
- public void literal() throws ScanException {
- Tokenizer tokenizer = new Tokenizer("abc");
- Parser parser = new Parser(tokenizer.tokenize());
- Node node = parser.parse();
- Node witness = new Node(Node.Type.LITERAL, "abc");
- assertEquals(witness, node);
- }
-
- @Test
- public void literalWithAccolade0() throws ScanException {
- Tokenizer tokenizer = new Tokenizer("{}");
- Parser parser = new Parser(tokenizer.tokenize());
- Node node = parser.parse();
- Node witness = new Node(Node.Type.LITERAL, "{");
- witness.next = new Node(Node.Type.LITERAL, "}");
- assertEquals(witness, node);
- }
-
- @Test
- public void literalWithAccolade1() throws ScanException {
- Tokenizer tokenizer = new Tokenizer("%x{a}");
- Parser parser = new Parser(tokenizer.tokenize());
- Node node = parser.parse();
- Node witness = new Node(Node.Type.LITERAL, "%x");
- Node t = witness.next = new Node(Node.Type.LITERAL, "{");
- t.next = new Node(Node.Type.LITERAL, "a");
- t = t.next;
- t.next = new Node(Node.Type.LITERAL, "}");
- assertEquals(witness, node);
- }
-
- @Test
- public void literalWithTwoAccolades() throws ScanException {
- Tokenizer tokenizer = new Tokenizer("%x{y} %a{b} c");
-
- Parser parser = new Parser(tokenizer.tokenize());
- Node node = parser.parse();
- Node witness = new Node(Node.Type.LITERAL, "%x");
-
- Node t = witness.next = new Node(Node.Type.LITERAL, "{");
- t.next = new Node(Node.Type.LITERAL, "y");
- t = t.next;
-
- t.next = new Node(Node.Type.LITERAL, "}");
- t = t.next;
-
- t.next = new Node(Node.Type.LITERAL, " %a");
- t = t.next;
-
- t.next = new Node(Node.Type.LITERAL, "{");
- t = t.next;
-
- t.next = new Node(Node.Type.LITERAL, "b");
- t = t.next;
-
- t.next = new Node(Node.Type.LITERAL, "}");
- t = t.next;
-
- t.next = new Node(Node.Type.LITERAL, " c");
-
- node.dump();
- System.out.println("");
- assertEquals(witness, node);
- }
-
- @Test
- public void variable() throws ScanException {
- Tokenizer tokenizer = new Tokenizer("${abc}");
- Parser parser = new Parser(tokenizer.tokenize());
- Node node = parser.parse();
- Node witness = new Node(Node.Type.VARIABLE, new Node(Node.Type.LITERAL, "abc"));
- assertEquals(witness, node);
- }
-
- @Test
- public void literalVariableLiteral() throws ScanException {
- Tokenizer tokenizer = new Tokenizer("a${b}c");
- Parser parser = new Parser(tokenizer.tokenize());
- Node node = parser.parse();
- Node witness = new Node(Node.Type.LITERAL, "a");
- witness.next = new Node(Node.Type.VARIABLE, new Node(Node.Type.LITERAL, "b"));
- witness.next.next = new Node(Node.Type.LITERAL, "c");
- assertEquals(witness, node);
- }
-
- // /LOGBACK-744
- @Test
- public void withColon() throws ScanException {
- Tokenizer tokenizer = new Tokenizer("a:${b}");
- Parser parser = new Parser(tokenizer.tokenize());
- Node node = parser.parse();
- Node witness = new Node(Node.Type.LITERAL, "a");
- Node t = witness.next = new Node(Node.Type.LITERAL, ":");
- t.next = new Node(Node.Type.VARIABLE, new Node(Node.Type.LITERAL, "b"));
- assertEquals(witness, node);
- }
- @Test
- public void nested() throws ScanException {
- Tokenizer tokenizer = new Tokenizer("a${b${c}}d");
- Parser parser = new Parser(tokenizer.tokenize());
- Node node = parser.parse();
- Node witness = new Node(Node.Type.LITERAL, "a");
- Node bLiteralNode = new Node(Node.Type.LITERAL, "b");
- Node cLiteralNode = new Node(Node.Type.LITERAL, "c");
- Node bVariableNode = new Node(Node.Type.VARIABLE, bLiteralNode);
- Node cVariableNode = new Node(Node.Type.VARIABLE, cLiteralNode);
- bLiteralNode.next = cVariableNode;
-
- witness.next = bVariableNode;
- witness.next.next = new Node(Node.Type.LITERAL, "d");
- assertEquals(witness, node);
+ @Test
+ public void literal() throws ScanException {
+ Tokenizer tokenizer = new Tokenizer("abc");
+ Parser parser = new Parser(tokenizer.tokenize());
+ Node node = parser.parse();
+ Node witness = new Node(Node.Type.LITERAL, "abc");
+ assertEquals(witness, node);
+ }
+
+ @Test
+ public void literalWithAccolade0() throws ScanException {
+ Tokenizer tokenizer = new Tokenizer("{}");
+ Parser parser = new Parser(tokenizer.tokenize());
+ Node node = parser.parse();
+ Node witness = new Node(Node.Type.LITERAL, "{");
+ witness.next = new Node(Node.Type.LITERAL, "}");
+ assertEquals(witness, node);
+ }
+
+ @Test
+ public void literalWithAccolade1() throws ScanException {
+ Tokenizer tokenizer = new Tokenizer("%x{a}");
+ Parser parser = new Parser(tokenizer.tokenize());
+ Node node = parser.parse();
+ Node witness = new Node(Node.Type.LITERAL, "%x");
+ Node t = witness.next = new Node(Node.Type.LITERAL, "{");
+ t.next = new Node(Node.Type.LITERAL, "a");
+ t = t.next;
+ t.next = new Node(Node.Type.LITERAL, "}");
+ assertEquals(witness, node);
+ }
+
+ @Test
+ public void literalWithTwoAccolades() throws ScanException {
+ Tokenizer tokenizer = new Tokenizer("%x{y} %a{b} c");
+
+ Parser parser = new Parser(tokenizer.tokenize());
+ Node node = parser.parse();
+ Node witness = new Node(Node.Type.LITERAL, "%x");
+
+ Node t = witness.next = new Node(Node.Type.LITERAL, "{");
+ t.next = new Node(Node.Type.LITERAL, "y");
+ t = t.next;
+
+ t.next = new Node(Node.Type.LITERAL, "}");
+ t = t.next;
+
+ t.next = new Node(Node.Type.LITERAL, " %a");
+ t = t.next;
+
+ t.next = new Node(Node.Type.LITERAL, "{");
+ t = t.next;
+
+ t.next = new Node(Node.Type.LITERAL, "b");
+ t = t.next;
+
+ t.next = new Node(Node.Type.LITERAL, "}");
+ t = t.next;
+
+ t.next = new Node(Node.Type.LITERAL, " c");
+
+ node.dump();
+ System.out.println("");
+ assertEquals(witness, node);
+ }
+
+ @Test
+ public void variable() throws ScanException {
+ Tokenizer tokenizer = new Tokenizer("${abc}");
+ Parser parser = new Parser(tokenizer.tokenize());
+ Node node = parser.parse();
+ Node witness = new Node(Node.Type.VARIABLE, new Node(Node.Type.LITERAL, "abc"));
+ assertEquals(witness, node);
+ }
+
+ @Test
+ public void literalVariableLiteral() throws ScanException {
+ Tokenizer tokenizer = new Tokenizer("a${b}c");
+ Parser parser = new Parser(tokenizer.tokenize());
+ Node node = parser.parse();
+ Node witness = new Node(Node.Type.LITERAL, "a");
+ witness.next = new Node(Node.Type.VARIABLE, new Node(Node.Type.LITERAL, "b"));
+ witness.next.next = new Node(Node.Type.LITERAL, "c");
+ assertEquals(witness, node);
+ }
+
+
+ // /LOGBACK-744
+ @Test
+ public void withColon() throws ScanException {
+ Tokenizer tokenizer = new Tokenizer("a:${b}");
+ Parser parser = new Parser(tokenizer.tokenize());
+ Node node = parser.parse();
+ Node witness = new Node(Node.Type.LITERAL, "a");
+ Node t = witness.next = new Node(Node.Type.LITERAL, ":");
+ t.next = new Node(Node.Type.VARIABLE, new Node(Node.Type.LITERAL, "b"));
+ assertEquals(witness, node);
+ }
+
+ @Test
+ public void nested() throws ScanException {
+ Tokenizer tokenizer = new Tokenizer("a${b${c}}d");
+ Parser parser = new Parser(tokenizer.tokenize());
+ Node node = parser.parse();
+ Node witness = new Node(Node.Type.LITERAL, "a");
+ Node bLiteralNode = new Node(Node.Type.LITERAL, "b");
+ Node cLiteralNode = new Node(Node.Type.LITERAL, "c");
+ Node bVariableNode = new Node(Node.Type.VARIABLE, bLiteralNode);
+ Node cVariableNode = new Node(Node.Type.VARIABLE, cLiteralNode);
+ bLiteralNode.next = cVariableNode;
+
+ witness.next = bVariableNode;
+ witness.next.next = new Node(Node.Type.LITERAL, "d");
+ assertEquals(witness, node);
+ }
+
+ @Test
+ public void withDefault() throws ScanException {
+ Tokenizer tokenizer = new Tokenizer("${b:-c}");
+ Parser parser = new Parser(tokenizer.tokenize());
+ Node node = parser.parse();
+ Node witness = new Node(Node.Type.VARIABLE, new Node(Node.Type.LITERAL, "b"));
+ witness.defaultPart = new Node(Node.Type.LITERAL, "c");
+ assertEquals(witness, node);
+ }
+
+ @Test
+ public void defaultSeparatorOutsideOfAVariable() throws ScanException {
+ Tokenizer tokenizer = new Tokenizer("{a:-b}");
+ Parser parser = new Parser(tokenizer.tokenize());
+ Node node = parser.parse();
+
+ dump(node);
+ Node witness = new Node(Node.Type.LITERAL, "{");
+ Node t = witness.next = new Node(Node.Type.LITERAL, "a");
+
+
+ t.next = new Node(Node.Type.LITERAL, ":-");
+ t = t.next;
+
+ t.next = new Node(Node.Type.LITERAL, "b");
+ t = t.next;
+
+ t.next = new Node(Node.Type.LITERAL, "}");
+
+ assertEquals(witness, node);
+ }
+
+ @Test
+ public void emptyTokenListDoesNotThrowNullPointerException() throws ScanException {
+ // An empty token list would be returned from Tokenizer.tokenize()
+ // if it were constructed with an empty string. The parser should
+ // be able to handle this.
+ Parser parser = new Parser(new ArrayList<Token>());
+ parser.parse();
+ }
+
+ private void dump(Node node) {
+ while (node != null) {
+ System.out.println(node.toString());
+ node = node.next;
}
+ }
- @Test
- public void withDefault() throws ScanException {
- Tokenizer tokenizer = new Tokenizer("${b:-c}");
- Parser parser = new Parser(tokenizer.tokenize());
- Node node = parser.parse();
- Node witness = new Node(Node.Type.VARIABLE, new Node(Node.Type.LITERAL, "b"));
- witness.defaultPart = new Node(Node.Type.LITERAL, "c");
- assertEquals(witness, node);
- }
-
- @Test
- public void defaultSeparatorOutsideOfAVariable() throws ScanException {
- Tokenizer tokenizer = new Tokenizer("{a:-b}");
- Parser parser = new Parser(tokenizer.tokenize());
- Node node = parser.parse();
-
- dump(node);
- Node witness = new Node(Node.Type.LITERAL, "{");
- Node t = witness.next = new Node(Node.Type.LITERAL, "a");
-
- t.next = new Node(Node.Type.LITERAL, ":-");
- t = t.next;
-
- t.next = new Node(Node.Type.LITERAL, "b");
- t = t.next;
-
- t.next = new Node(Node.Type.LITERAL, "}");
-
- assertEquals(witness, node);
- }
-
- @Test
- public void emptyTokenListDoesNotThrowNullPointerException() throws ScanException {
- // An empty token list would be returned from Tokenizer.tokenize()
- // if it were constructed with an empty string. The parser should
- // be able to handle this.
- Parser parser = new Parser(new ArrayList<Token>());
- parser.parse();
- }
-
- private void dump(Node node) {
- while (node != null) {
- System.out.println(node.toString());
- node = node.next;
- }
- }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/subst/TokenizerTest.java b/logback-core/src/test/java/ch/qos/logback/core/subst/TokenizerTest.java
index 245cba5..e7e382f 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/subst/TokenizerTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/subst/TokenizerTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,152 +23,126 @@ import static org.junit.Assert.assertEquals;
public class TokenizerTest {
- List<Token> witnessList = new ArrayList<Token>();
-
- @Test
- public void literalOnly() throws ScanException {
- String input = "abc";
- Tokenizer tokenizer = new Tokenizer(input);
- List<Token> tokenList = tokenizer.tokenize();
- witnessList.add(new Token(Token.Type.LITERAL, input));
- assertEquals(witnessList, tokenList);
- }
-
- @Test
- public void literalWithAccolades() throws ScanException {
- String input0 = "%logger";
- String input1 = "24";
- String input2 = " - %m";
- String input = input0 + "{" + input1 + "}" + input2;
- Tokenizer tokenizer = new Tokenizer(input);
- List<Token> tokenList = tokenizer.tokenize();
- witnessList.add(new Token(Token.Type.LITERAL, input0));
- witnessList.add(Token.CURLY_LEFT_TOKEN);
- witnessList.add(new Token(Token.Type.LITERAL, input1));
-
- witnessList.add(Token.CURLY_RIGHT_TOKEN);
- witnessList.add(new Token(Token.Type.LITERAL, input2));
- assertEquals(witnessList, tokenList);
- }
-
- @Test
- public void simleVariable() throws ScanException {
- String input = "${abc}";
- Tokenizer tokenizer = new Tokenizer(input);
- List<Token> tokenList = tokenizer.tokenize();
- witnessList.add(Token.START_TOKEN);
- witnessList.add(new Token(Token.Type.LITERAL, "abc"));
- witnessList.add(Token.CURLY_RIGHT_TOKEN);
- assertEquals(witnessList, tokenList);
- }
-
- @Test
- public void mix() throws ScanException {
- String input = "a${b}c";
- Tokenizer tokenizer = new Tokenizer(input);
- List<Token> tokenList = tokenizer.tokenize();
- witnessList.add(new Token(Token.Type.LITERAL, "a"));
- witnessList.add(Token.START_TOKEN);
- witnessList.add(new Token(Token.Type.LITERAL, "b"));
- witnessList.add(Token.CURLY_RIGHT_TOKEN);
- witnessList.add(new Token(Token.Type.LITERAL, "c"));
- assertEquals(witnessList, tokenList);
- }
-
- @Test
- public void nested() throws ScanException {
- String input = "a${b${c}}";
- Tokenizer tokenizer = new Tokenizer(input);
- List<Token> tokenList = tokenizer.tokenize();
- witnessList.add(new Token(Token.Type.LITERAL, "a"));
- witnessList.add(Token.START_TOKEN);
- witnessList.add(new Token(Token.Type.LITERAL, "b"));
- witnessList.add(Token.START_TOKEN);
- witnessList.add(new Token(Token.Type.LITERAL, "c"));
- witnessList.add(Token.CURLY_RIGHT_TOKEN);
- witnessList.add(Token.CURLY_RIGHT_TOKEN);
- assertEquals(witnessList, tokenList);
- }
-
- @Test
- public void basicDefaultSeparator() throws ScanException {
- String input = "${a:-b}";
- Tokenizer tokenizer = new Tokenizer(input);
- List<Token> tokenList = tokenizer.tokenize();
- witnessList.add(Token.START_TOKEN);
- witnessList.add(new Token(Token.Type.LITERAL, "a"));
- witnessList.add(Token.DEFAULT_SEP_TOKEN);
- witnessList.add(new Token(Token.Type.LITERAL, "b"));
- witnessList.add(Token.CURLY_RIGHT_TOKEN);
- assertEquals(witnessList, tokenList);
- }
-
- @Test
- public void colon() throws ScanException {
- String input = "a:b";
- Tokenizer tokenizer = new Tokenizer(input);
- List<Token> tokenList = tokenizer.tokenize();
- witnessList.add(new Token(Token.Type.LITERAL, "a"));
- witnessList.add(new Token(Token.Type.LITERAL, ":b"));
- assertEquals(witnessList, tokenList);
- }
-
- // /LOGBACK-744
- @Test
- public void colonFollowedByDollar() throws ScanException {
- String input = "a:${b}";
- Tokenizer tokenizer = new Tokenizer(input);
- List<Token> tokenList = tokenizer.tokenize();
- witnessList.add(new Token(Token.Type.LITERAL, "a"));
- witnessList.add(new Token(Token.Type.LITERAL, ":"));
- witnessList.add(Token.START_TOKEN);
- witnessList.add(new Token(Token.Type.LITERAL, "b"));
- witnessList.add(Token.CURLY_RIGHT_TOKEN);
- assertEquals(witnessList, tokenList);
-
- }
-
- @Test
- public void defaultSeparatorOutsideVariable() throws ScanException {
-
- String input = "{a:-b}";
- Tokenizer tokenizer = new Tokenizer(input);
- List<Token> tokenList = tokenizer.tokenize();
- witnessList.add(Token.CURLY_LEFT_TOKEN);
- witnessList.add(new Token(Token.Type.LITERAL, "a"));
- witnessList.add(Token.DEFAULT_SEP_TOKEN);
- witnessList.add(new Token(Token.Type.LITERAL, "b"));
- witnessList.add(Token.CURLY_RIGHT_TOKEN);
- assertEquals(witnessList, tokenList);
- }
-
- @Test
- public void literalContainingColon() throws ScanException {
- String input = "a:b";
- Tokenizer tokenizer = new Tokenizer(input);
- List<Token> tokenList = tokenizer.tokenize();
- witnessList.add(new Token(Token.Type.LITERAL, "a"));
- witnessList.add(new Token(Token.Type.LITERAL, ":b"));
- assertEquals(witnessList, tokenList);
- }
-
- @Test
- public void literalEndingWithColon_LOGBACK_1140() throws ScanException {
- String input = "a:";
- Tokenizer tokenizer = new Tokenizer(input);
- List<Token> tokenList = tokenizer.tokenize();
- witnessList.add(new Token(Token.Type.LITERAL, "a"));
- witnessList.add(new Token(Token.Type.LITERAL, ":"));
- assertEquals(witnessList, tokenList);
- }
-
- @Test
- public void literalEndingWithDollar_LOGBACK_1149() throws ScanException {
- String input = "a$";
- Tokenizer tokenizer = new Tokenizer(input);
- List<Token> tokenList = tokenizer.tokenize();
- witnessList.add(new Token(Token.Type.LITERAL, "a"));
- witnessList.add(new Token(Token.Type.LITERAL, "$"));
- assertEquals(witnessList, tokenList);
- }
-}
+ List<Token> witnessList = new ArrayList<Token>();
+
+ @Test
+ public void literalOnly() throws ScanException {
+ String input = "abc";
+ Tokenizer tokenizer = new Tokenizer(input);
+ List<Token> tokenList = tokenizer.tokenize();
+ witnessList.add(new Token(Token.Type.LITERAL, input));
+ assertEquals(witnessList, tokenList);
+ }
+
+ @Test
+ public void literalWithAccolades() throws ScanException {
+ String input0 = "%logger";
+ String input1 = "24";
+ String input2 = " - %m";
+ String input = input0+"{"+input1+"}"+input2;
+ Tokenizer tokenizer = new Tokenizer(input);
+ List<Token> tokenList = tokenizer.tokenize();
+ witnessList.add(new Token(Token.Type.LITERAL, input0));
+ witnessList.add(Token.CURLY_LEFT_TOKEN);
+ witnessList.add(new Token(Token.Type.LITERAL, input1));
+
+ witnessList.add(Token.CURLY_RIGHT_TOKEN);
+ witnessList.add(new Token(Token.Type.LITERAL, input2));
+ assertEquals(witnessList, tokenList);
+ }
+
+
+ @Test
+ public void simleVariable() throws ScanException {
+ String input = "${abc}";
+ Tokenizer tokenizer = new Tokenizer(input);
+ List<Token> tokenList = tokenizer.tokenize();
+ witnessList.add(Token.START_TOKEN);
+ witnessList.add(new Token(Token.Type.LITERAL, "abc"));
+ witnessList.add(Token.CURLY_RIGHT_TOKEN);
+ assertEquals(witnessList, tokenList);
+ }
+
+ @Test
+ public void mix() throws ScanException {
+ String input = "a${b}c";
+ Tokenizer tokenizer = new Tokenizer(input);
+ List<Token> tokenList = tokenizer.tokenize();
+ witnessList.add(new Token(Token.Type.LITERAL, "a"));
+ witnessList.add(Token.START_TOKEN);
+ witnessList.add(new Token(Token.Type.LITERAL, "b"));
+ witnessList.add(Token.CURLY_RIGHT_TOKEN);
+ witnessList.add(new Token(Token.Type.LITERAL, "c"));
+ assertEquals(witnessList, tokenList);
+ }
+
+ @Test
+ public void nested() throws ScanException {
+ String input = "a${b${c}}";
+ Tokenizer tokenizer = new Tokenizer(input);
+ List<Token> tokenList = tokenizer.tokenize();
+ witnessList.add(new Token(Token.Type.LITERAL, "a"));
+ witnessList.add(Token.START_TOKEN);
+ witnessList.add(new Token(Token.Type.LITERAL, "b"));
+ witnessList.add(Token.START_TOKEN);
+ witnessList.add(new Token(Token.Type.LITERAL, "c"));
+ witnessList.add(Token.CURLY_RIGHT_TOKEN);
+ witnessList.add(Token.CURLY_RIGHT_TOKEN);
+ assertEquals(witnessList, tokenList);
+ }
+
+
+ @Test
+ public void basicDefaultSeparator() throws ScanException {
+ String input = "${a:-b}";
+ Tokenizer tokenizer = new Tokenizer(input);
+ List<Token> tokenList = tokenizer.tokenize();
+ witnessList.add(Token.START_TOKEN);
+ witnessList.add(new Token(Token.Type.LITERAL, "a"));
+ witnessList.add(Token.DEFAULT_SEP_TOKEN);
+ witnessList.add(new Token(Token.Type.LITERAL, "b"));
+ witnessList.add(Token.CURLY_RIGHT_TOKEN);
+ assertEquals(witnessList, tokenList);
+ }
+
+ @Test
+ public void colon() throws ScanException {
+ String input = "a:b";
+ Tokenizer tokenizer = new Tokenizer(input);
+ List<Token> tokenList = tokenizer.tokenize();
+ witnessList.add(new Token(Token.Type.LITERAL, "a"));
+ witnessList.add(new Token(Token.Type.LITERAL, ":b"));
+ assertEquals(witnessList, tokenList);
+ }
+
+
+ // /LOGBACK-744
+ @Test
+ public void colonFollowedByDollar() throws ScanException {
+ String input = "a:${b}";
+ Tokenizer tokenizer = new Tokenizer(input);
+ List<Token> tokenList = tokenizer.tokenize();
+ witnessList.add(new Token(Token.Type.LITERAL, "a"));
+ witnessList.add(new Token(Token.Type.LITERAL, ":"));
+ witnessList.add(Token.START_TOKEN);
+ witnessList.add(new Token(Token.Type.LITERAL, "b"));
+ witnessList.add(Token.CURLY_RIGHT_TOKEN);
+ assertEquals(witnessList, tokenList);
+ }
+
+ @Test
+ public void defaultSeparatorOutsideVariable() throws ScanException {
+
+ String input = "{a:-b}";
+ Tokenizer tokenizer = new Tokenizer(input);
+ List<Token> tokenList = tokenizer.tokenize();
+ witnessList.add(Token.CURLY_LEFT_TOKEN);
+ witnessList.add(new Token(Token.Type.LITERAL, "a"));
+ witnessList.add(Token.DEFAULT_SEP_TOKEN);
+ witnessList.add(new Token(Token.Type.LITERAL, "b"));
+ witnessList.add(Token.CURLY_RIGHT_TOKEN);
+ assertEquals(witnessList, tokenList);
+ }
+
+
+ }
diff --git a/logback-core/src/test/java/ch/qos/logback/core/testUtil/DelayingListAppender.java b/logback-core/src/test/java/ch/qos/logback/core/testUtil/DelayingListAppender.java
index 8309a3a..02ff18f 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/testUtil/DelayingListAppender.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/testUtil/DelayingListAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,21 +17,19 @@ import ch.qos.logback.core.read.ListAppender;
public class DelayingListAppender<E> extends ListAppender<E> {
- public int delay = 1;
- public boolean interrupted = false;
+ public int delay = 5;
+ public boolean interrupted = false;
- public void setDelay(int ms) {
- delay = ms;
- }
-
- @Override
- public void append(E e) {
- try {
- Thread.sleep(delay);
- } catch (InterruptedException ie) {
- interrupted = true;
- }
- super.append(e);
+ @Override
+ public void append(E e) {
+ try {
+ Thread.yield();
+ Thread.sleep(delay);
+ Thread.yield();
+ } catch (InterruptedException ie) {
+ interrupted = true;
}
+ super.append(e);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/testUtil/EnvUtilForTests.java b/logback-core/src/test/java/ch/qos/logback/core/testUtil/EnvUtilForTests.java
index fd84675..14b317d 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/testUtil/EnvUtilForTests.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/testUtil/EnvUtilForTests.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,52 +22,55 @@ import ch.qos.logback.core.util.CoreTestConstants;
public class EnvUtilForTests {
- static public boolean isWindows() {
- return System.getProperty("os.name").indexOf("Windows") != -1;
- }
+ static public boolean isWindows() {
+ return System.getProperty("os.name").indexOf("Windows") != -1;
+ }
- static public boolean isMac() {
- return System.getProperty("os.name").indexOf("Mac") != -1;
- }
+ static public boolean isMac() {
+ return System.getProperty("os.name").indexOf("Mac") != -1;
+ }
- static public boolean isLinux() {
- return System.getProperty("os.name").indexOf("Linux") != -1;
- }
+ static public boolean isLinux() {
+ return System.getProperty("os.name").indexOf("Linux") != -1;
+ }
- static public boolean isRunningOnSlowJenkins() {
- return System.getProperty(CoreTestConstants.SLOW_JENKINS) != null;
- }
- static public String getLocalHostName() {
- InetAddress localhostIA;
- try {
- localhostIA = InetAddress.getLocalHost();
- return localhostIA.getHostName();
- } catch (UnknownHostException e) {
- return null;
- }
+ static public boolean isRunningOnSlowJenkins() {
+ return System.getProperty(CoreTestConstants.SLOW_JENKINS) != null;
+ }
+
+
+ static public String getLocalHostName() {
+ InetAddress localhostIA;
+ try {
+ localhostIA = InetAddress.getLocalHost();
+ return localhostIA.getHostName();
+ } catch (UnknownHostException e) {
+ return null;
}
+ }
- static public boolean isLocalHostNameInList(String[] hostList) {
- String localHostName = getLocalHostName();
- if (localHostName == null) {
- return false;
- }
- for (String host : hostList) {
- if (host.equalsIgnoreCase(localHostName)) {
- return true;
- }
- }
- return false;
+ static public boolean isLocalHostNameInList(String[] hostList) {
+ String localHostName = getLocalHostName();
+ if (localHostName == null) {
+ return false;
+ }
+ for (String host : hostList) {
+ if (host.equalsIgnoreCase(localHostName)) {
+ return true;
+ }
}
+ return false;
+ }
- public static String getPathToBash() {
- if (EnvUtilForTests.isLinux()) {
- return CoreTestConstants.BASH_PATH_ON_LINUX;
- }
- if (EnvUtilForTests.isLocalHostNameInList(new String[] { "hetz", "het" })) {
- return CoreTestConstants.BASH_PATH_ON_CYGWIN;
- }
- return null;
+
+ public static String getPathToBash() {
+ if (EnvUtilForTests.isLinux()) {
+ return CoreTestConstants.BASH_PATH_ON_LINUX;
+ }
+ if (EnvUtilForTests.isLocalHostNameInList(new String[]{"hetz", "het"})) {
+ return CoreTestConstants.BASH_PATH_ON_CYGWIN;
}
+ return null;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/testUtil/FileTestUtil.java b/logback-core/src/test/java/ch/qos/logback/core/testUtil/FileTestUtil.java
index 242d47b..aec6472 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/testUtil/FileTestUtil.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/testUtil/FileTestUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,18 +20,18 @@ import java.io.File;
import static junit.framework.Assert.assertTrue;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class FileTestUtil {
- public static void makeTestOutputDir() {
- File target = new File(CoreTestConstants.TARGET_DIR);
- if (target.exists() && target.isDirectory()) {
- File testoutput = new File(CoreTestConstants.OUTPUT_DIR_PREFIX);
- if (!testoutput.exists())
- assertTrue(testoutput.mkdir());
- } else {
- throw new IllegalStateException(CoreTestConstants.TARGET_DIR + " does not exist");
- }
+ public static void makeTestOutputDir() {
+ File target = new File(CoreTestConstants.TARGET_DIR);
+ if(target.exists() && target.isDirectory()) {
+ File testoutput = new File(CoreTestConstants.OUTPUT_DIR_PREFIX);
+ if(!testoutput.exists())
+ assertTrue(testoutput.mkdir());
+ } else {
+ throw new IllegalStateException(CoreTestConstants.TARGET_DIR + " does not exist");
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/testUtil/FileToBufferUtil.java b/logback-core/src/test/java/ch/qos/logback/core/testUtil/FileToBufferUtil.java
index e938da5..a09e6c5 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/testUtil/FileToBufferUtil.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/testUtil/FileToBufferUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,48 +27,49 @@ import java.util.zip.ZipFile;
public class FileToBufferUtil {
- static public void readIntoList(File file, List<String> stringList) throws IOException {
+ static public void readIntoList(File file, List<String> stringList)
+ throws IOException {
- if (file.getName().endsWith(".gz")) {
- gzFileReadIntoList(file, stringList);
- } else if (file.getName().endsWith(".zip")) {
- zipFileReadIntoList(file, stringList);
- } else {
- regularReadIntoList(file, stringList);
- }
+ if (file.getName().endsWith(".gz")) {
+ gzFileReadIntoList(file, stringList);
+ } else if (file.getName().endsWith(".zip")) {
+ zipFileReadIntoList(file, stringList);
+ } else {
+ regularReadIntoList(file, stringList);
}
+ }
- private static void zipFileReadIntoList(File file, List<String> stringList) throws IOException {
- System.out.println("Reading zip file [" + file + "]");
- ZipFile zipFile = new ZipFile(file);
- Enumeration entries = zipFile.entries();
- ZipEntry entry = (ZipEntry) entries.nextElement();
- readInputStream(zipFile.getInputStream(entry), stringList);
- }
+ private static void zipFileReadIntoList(File file, List<String> stringList) throws IOException {
+ System.out.println("Reading zip file ["+file+"]");
+ ZipFile zipFile = new ZipFile(file);
+ Enumeration entries = zipFile.entries();
+ ZipEntry entry = (ZipEntry) entries.nextElement();
+ readInputStream(zipFile.getInputStream(entry), stringList);
+ }
- static void readInputStream(InputStream is, List<String> stringList) throws IOException {
- BufferedReader in = new BufferedReader(new InputStreamReader(is));
- String line;
- while ((line = in.readLine()) != null) {
- stringList.add(line);
- }
- in.close();
+ static void readInputStream(InputStream is, List<String> stringList) throws IOException {
+ BufferedReader in = new BufferedReader(new InputStreamReader(is));
+ String line;
+ while ((line = in.readLine()) != null) {
+ stringList.add(line);
}
+ in.close();
+ }
- static public void regularReadIntoList(File file, List<String> stringList) throws IOException {
- FileInputStream fis = new FileInputStream(file);
- BufferedReader in = new BufferedReader(new InputStreamReader(fis));
- String line;
- while ((line = in.readLine()) != null) {
- stringList.add(line);
- }
- in.close();
+ static public void regularReadIntoList(File file, List<String> stringList) throws IOException {
+ FileInputStream fis = new FileInputStream(file);
+ BufferedReader in = new BufferedReader(new InputStreamReader(fis));
+ String line;
+ while ((line = in.readLine()) != null) {
+ stringList.add(line);
}
+ in.close();
+ }
- static public void gzFileReadIntoList(File file, List<String> stringList) throws IOException {
- FileInputStream fis = new FileInputStream(file);
- GZIPInputStream gzis = new GZIPInputStream(fis);
- readInputStream(gzis, stringList);
- }
+ static public void gzFileReadIntoList(File file, List<String> stringList) throws IOException {
+ FileInputStream fis = new FileInputStream(file);
+ GZIPInputStream gzis = new GZIPInputStream(fis);
+ readInputStream(gzis, stringList);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/testUtil/NPEAppender.java b/logback-core/src/test/java/ch/qos/logback/core/testUtil/NPEAppender.java
index da964eb..0017cca 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/testUtil/NPEAppender.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/testUtil/NPEAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,8 +16,8 @@ package ch.qos.logback.core.testUtil;
import ch.qos.logback.core.AppenderBase;
public class NPEAppender<E> extends AppenderBase<E> {
- @Override
- protected void append(E eventObject) {
- throw new NullPointerException();
- }
+ @Override
+ protected void append(E eventObject) {
+ throw new NullPointerException();
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/testUtil/RandomUtil.java b/logback-core/src/test/java/ch/qos/logback/core/testUtil/RandomUtil.java
index 502474b..5554c96 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/testUtil/RandomUtil.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/testUtil/RandomUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,19 +17,19 @@ import java.util.Random;
public class RandomUtil {
- private static Random random = new Random();
+ private static Random random = new Random();
- public static int getRandomServerPort() {
- int r = random.nextInt(20000);
- // the first 1024 ports are usually reserved for the OS
- return r + 1024;
- }
+ public static int getRandomServerPort() {
+ int r = random.nextInt(20000);
+ // the first 1024 ports are usually reserved for the OS
+ return r + 1024;
+ }
- public static int getPositiveInt() {
- int r = random.nextInt();
- if (r < 0) {
- r = -r;
- }
- return r;
+ public static int getPositiveInt() {
+ int r = random.nextInt();
+ if (r < 0) {
+ r = -r;
}
+ return r;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/testUtil/StringListAppender.java b/logback-core/src/test/java/ch/qos/logback/core/testUtil/StringListAppender.java
index a4c808b..58cf487 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/testUtil/StringListAppender.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/testUtil/StringListAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,33 +21,33 @@ import ch.qos.logback.core.Layout;
public class StringListAppender<E> extends AppenderBase<E> {
- Layout<E> layout;
- public List<String> strList = new ArrayList<String>();
+ Layout<E> layout;
+ public List<String> strList = new ArrayList<String>();
- public void start() {
- strList.clear();
+ public void start() {
+ strList.clear();
- if (layout == null || !layout.isStarted()) {
- return;
- }
- super.start();
- }
-
- public void stop() {
- super.stop();
- }
-
- @Override
- protected void append(E eventObject) {
- String res = layout.doLayout(eventObject);
- strList.add(res);
- }
-
- public Layout<E> getLayout() {
- return layout;
- }
-
- public void setLayout(Layout<E> layout) {
- this.layout = layout;
+ if (layout == null || !layout.isStarted()) {
+ return;
}
+ super.start();
+ }
+
+ public void stop() {
+ super.stop();
+ }
+
+ @Override
+ protected void append(E eventObject) {
+ String res = layout.doLayout(eventObject);
+ strList.add(res);
+ }
+
+ public Layout<E> getLayout() {
+ return layout;
+ }
+
+ public void setLayout(Layout<E> layout) {
+ this.layout = layout;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/CachingFotmatterTest.java b/logback-core/src/test/java/ch/qos/logback/core/util/CachingFotmatterTest.java
deleted file mode 100644
index b3256c9..0000000
--- a/logback-core/src/test/java/ch/qos/logback/core/util/CachingFotmatterTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package ch.qos.logback.core.util;
-
-import static org.junit.Assert.assertEquals;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.TimeZone;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class CachingFotmatterTest {
-
- final static String DATE_PATTERN = "yyyy-MM-dd'T'HH:mm";
-
- SimpleDateFormat sdf = new SimpleDateFormat(DATE_PATTERN);
- TimeZone perthTZ = TimeZone.getTimeZone("Australia/Perth");
- TimeZone utcTZ = TimeZone.getTimeZone("UTC");
-
- @Before
- public void setUp() {
- sdf.setTimeZone(utcTZ);
- }
-
- @Test
- public void timeZoneIsTakenIntoAccount() throws ParseException {
-
- CachingDateFormatter cdf = new CachingDateFormatter(DATE_PATTERN);
- TimeZone perthTZ = TimeZone.getTimeZone("Australia/Perth");
- cdf.setTimeZone(perthTZ);
-
- Date march26_2015_0949_UTC = sdf.parse("2015-03-26T09:49");
- System.out.print(march26_2015_0949_UTC);
-
- String result = cdf.format(march26_2015_0949_UTC.getTime());
- // AWST (Perth) is 8 hours ahead of UTC
- assertEquals("2015-03-26T17:49", result);
- }
-}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/CharSequenceToRegexMapperTest.java b/logback-core/src/test/java/ch/qos/logback/core/util/CharSequenceToRegexMapperTest.java
deleted file mode 100644
index 44fd66f..0000000
--- a/logback-core/src/test/java/ch/qos/logback/core/util/CharSequenceToRegexMapperTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
- *
- * This program and the accompanying materials are dual-licensed under
- * either the terms of the Eclipse Public License v1.0 as published by
- * the Eclipse Foundation
- *
- * or (per the licensee's choosing)
- *
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- */
-package ch.qos.logback.core.util;
-
-import org.junit.After;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import java.text.DateFormatSymbols;
-import java.util.Locale;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertEquals;
-
-public class CharSequenceToRegexMapperTest {
- static Locale KO_LOCALE = new Locale("ko", "KR");
- Locale oldLocale = Locale.getDefault();
-
- @After
- public void tearDown() {
- Locale.setDefault(oldLocale);
- }
-
- @Test
- public void findMinMaxLengthsInSymbolsWithTrivialInputs() {
- String[] symbols = new String[] { "a", "bb" };
- int[] results = CharSequenceToRegexMapper.findMinMaxLengthsInSymbols(symbols);
- assertEquals(1, results[0]);
- assertEquals(2, results[1]);
- }
-
- @Test
- public void emptyStringValuesShouldBeIgnoredByFindMinMaxLengthsInSymbols() {
- String[] symbols = new String[] { "aaa", "" };
- int[] results = CharSequenceToRegexMapper.findMinMaxLengthsInSymbols(symbols);
- assertEquals(3, results[0]);
- assertEquals(3, results[1]);
- }
-
- @Test
- @Ignore
- public void noneOfTheSymbolsAreOfZeroLengthForKorean() {
- Locale.setDefault(KO_LOCALE);
- noneOfTheSymbolsAreOfZeroLength();
- }
-
- @Test
- @Ignore
- public void noneOfTheSymbolsAreOfZeroLengthForSwiss() {
- Locale.setDefault(new Locale("fr", "CH"));
- noneOfTheSymbolsAreOfZeroLength();
- }
-
- private void noneOfTheSymbolsAreOfZeroLength() {
- DateFormatSymbols dateFormatSymbols = DateFormatSymbols.getInstance();
- // checkEmptyString(dateFormatSymbols.getShortMonths(), "ShortMonths");
- // checkEmptyString(dateFormatSymbols.getMonths(), "Months");
- checkEmptyString(dateFormatSymbols.getShortWeekdays(), "ShortWeekdays");
- checkEmptyString(dateFormatSymbols.getWeekdays(), "Weekdays");
- checkEmptyString(dateFormatSymbols.getAmPmStrings(), "AmPmStrings");
-
- }
-
- private void checkEmptyString(String[] symbolArray, String category) {
- for (String s : symbolArray) {
- System.out.println(category + " [" + s + "]");
- assertTrue(category + " contains empty strings", s.length() > 0);
- }
- }
-
-}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/Compare.java b/logback-core/src/test/java/ch/qos/logback/core/util/Compare.java
index 0ed5d8a..5b643b6 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/Compare.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/Compare.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,171 +19,161 @@ import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
-import java.io.Reader;
+import java.util.Enumeration;
import java.util.zip.GZIPInputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
public class Compare {
- static final int B1_NULL = -1;
- static final int B2_NULL = -2;
-
- public static boolean compare(String file1, String file2) throws FileNotFoundException, IOException {
- if (file1.endsWith(".gz")) {
- return gzFileCompare(file1, file2);
- } else if (file1.endsWith(".zip")) {
- return zipFileCompare(file1, file2);
- } else {
- return regularFileCompare(file1, file2);
- }
+ static final int B1_NULL = -1;
+ static final int B2_NULL = -2;
+
+ public static boolean compare(String file1, String file2) throws FileNotFoundException, IOException {
+ if (file1.endsWith(".gz")) {
+ return gzFileCompare(file1, file2);
+ } else if(file1.endsWith(".zip")) {
+ return zipFileCompare(file1, file2);
+ } else {
+ return regularFileCompare(file1, file2);
}
-
- static BufferedReader gzFileToBufferedReader(String file) throws IOException {
- FileInputStream fis = new FileInputStream(file);
- GZIPInputStream gzis = new GZIPInputStream(fis);
- return new BufferedReader(new InputStreamReader(gzis));
+ }
+
+ static BufferedReader gzFileToBufferedReader(String file) throws IOException {
+ FileInputStream fis = new FileInputStream(file);
+ GZIPInputStream gzis = new GZIPInputStream(fis);
+ return new BufferedReader(new InputStreamReader(gzis));
+ }
+
+ static BufferedReader zipFileToBufferedReader(String file) throws IOException {
+ FileInputStream fis = new FileInputStream(file);
+ ZipInputStream zis = new ZipInputStream(fis);
+ zis.getNextEntry();
+ return new BufferedReader(new InputStreamReader(zis));
+ }
+ public static boolean gzFileCompare(String file1, String file2) throws IOException {
+ BufferedReader in1 = gzFileToBufferedReader(file1);
+ BufferedReader in2 = gzFileToBufferedReader(file2);
+ return bufferCompare(in1, in2, file1, file2);
+ }
+
+ public static boolean zipFileCompare(String file1, String file2) throws IOException {
+ BufferedReader in1 = zipFileToBufferedReader(file1);
+ BufferedReader in2 = zipFileToBufferedReader(file2);
+ return bufferCompare(in1, in2, file1, file2);
+ }
+ public static boolean regularFileCompare(String file1, String file2)
+ throws FileNotFoundException, IOException {
+ BufferedReader in1 = new BufferedReader(new FileReader(file1));
+ BufferedReader in2 = new BufferedReader(new FileReader(file2));
+ return bufferCompare(in1, in2, file1, file2);
+ }
+
+ public static boolean bufferCompare(BufferedReader in1, BufferedReader in2,
+ String file1, String file2) throws FileNotFoundException, IOException {
+
+ String s1;
+ int lineCounter = 0;
+
+ while ((s1 = in1.readLine()) != null) {
+ lineCounter++;
+
+ String s2 = in2.readLine();
+
+ if (!s1.equals(s2)) {
+ System.out.println("Files [" + file1 + "] and [" + file2
+ + "] differ on line " + lineCounter);
+ System.out.println("One reads: [" + s1 + "].");
+ System.out.println("Other reads:[" + s2 + "].");
+ outputFile(file1);
+ outputFile(file2);
+
+ return false;
+ }
}
- static BufferedReader zipFileToBufferedReader(String file) throws IOException {
- FileInputStream fis = new FileInputStream(file);
- ZipInputStream zis = new ZipInputStream(fis);
- zis.getNextEntry();
- return new BufferedReader(new InputStreamReader(zis));
- }
+ // the second file is longer
+ if (in2.read() != -1) {
+ System.out.println("File [" + file2 + "] longer than file [" + file1
+ + "].");
+ outputFile(file1);
+ outputFile(file2);
- public static boolean gzFileCompare(String file1, String file2) throws IOException {
- BufferedReader in1 = gzFileToBufferedReader(file1);
- BufferedReader in2 = gzFileToBufferedReader(file2);
- return bufferCompare(in1, in2, file1, file2);
+ return false;
}
- public static boolean zipFileCompare(String file1, String file2) throws IOException {
- BufferedReader in1 = zipFileToBufferedReader(file1);
- BufferedReader in2 = zipFileToBufferedReader(file2);
- return bufferCompare(in1, in2, file1, file2);
+ return true;
+ }
+
+ /**
+ *
+ * Prints file on the console.
+ *
+ */
+ private static void outputFile(String file) throws FileNotFoundException,
+ IOException {
+ BufferedReader in1 = new BufferedReader(new FileReader(file));
+
+ String s1;
+ int lineCounter = 0;
+ System.out.println("--------------------------------");
+ System.out.println("Contents of " + file + ":");
+
+ while ((s1 = in1.readLine()) != null) {
+ lineCounter++;
+ System.out.print(lineCounter);
+
+ if (lineCounter < 10) {
+ System.out.print(" : ");
+ } else if (lineCounter < 100) {
+ System.out.print(" : ");
+ } else if (lineCounter < 1000) {
+ System.out.print(" : ");
+ } else {
+ System.out.print(": ");
+ }
+
+ System.out.println(s1);
}
+ }
- public static boolean regularFileCompare(String file1, String file2) throws FileNotFoundException, IOException {
- BufferedReader in1 = new BufferedReader(new FileReader(file1));
- BufferedReader in2 = new BufferedReader(new FileReader(file2));
- return bufferCompare(in1, in2, file1, file2);
- }
-
- public static boolean bufferCompare(BufferedReader in1, BufferedReader in2, String file1, String file2) throws FileNotFoundException, IOException {
-
- String s1;
- int lineCounter = 0;
+ public static boolean gzCompare(String file1, String file2)
+ throws FileNotFoundException, IOException {
+ BufferedReader in1 = new BufferedReader(new InputStreamReader(
+ new GZIPInputStream(new FileInputStream(file1))));
+ BufferedReader in2 = new BufferedReader(new InputStreamReader(
+ new GZIPInputStream(new FileInputStream(file2))));
- while ((s1 = in1.readLine()) != null) {
- lineCounter++;
+ String s1;
+ int lineCounter = 0;
- String s2 = in2.readLine();
+ while ((s1 = in1.readLine()) != null) {
+ lineCounter++;
- if (!s1.equals(s2)) {
- System.out.println("Files [" + file1 + "] and [" + file2 + "] differ on line " + lineCounter);
- System.out.println("One reads: [" + s1 + "].");
- System.out.println("Other reads:[" + s2 + "].");
- outputFile(file1);
- outputFile(file2);
+ String s2 = in2.readLine();
- return false;
- }
- }
+ if (!s1.equals(s2)) {
+ System.out.println("Files [" + file1 + "] and [" + file2
+ + "] differ on line " + lineCounter);
+ System.out.println("One reads: [" + s1 + "].");
+ System.out.println("Other reads:[" + s2 + "].");
+ outputFile(file1);
+ outputFile(file2);
- // the second file is longer
- if (in2.read() != -1) {
- System.out.println("File [" + file2 + "] longer than file [" + file1 + "].");
- outputFile(file1);
- outputFile(file2);
-
- return false;
- }
-
- return true;
+ return false;
+ }
}
- /**
- *
- * Prints file on the console.
- *
- */
- private static void outputFile(String file) throws FileNotFoundException, IOException {
- BufferedReader in1 = null;
-
- try {
- in1 = new BufferedReader(new FileReader(file));
- String s1;
- int lineCounter = 0;
- System.out.println("--------------------------------");
- System.out.println("Contents of " + file + ":");
-
- while ((s1 = in1.readLine()) != null) {
- lineCounter++;
- System.out.print(lineCounter);
-
- if (lineCounter < 10) {
- System.out.print(" : ");
- } else if (lineCounter < 100) {
- System.out.print(" : ");
- } else if (lineCounter < 1000) {
- System.out.print(" : ");
- } else {
- System.out.print(": ");
- }
-
- System.out.println(s1);
- }
- } finally {
- close(in1);
- }
- }
+ // the second file is longer
+ if (in2.read() != -1) {
+ System.out.println("File [" + file2 + "] longer than file [" + file1
+ + "].");
+ outputFile(file1);
+ outputFile(file2);
- public static boolean gzCompare(String file1, String file2) throws FileNotFoundException, IOException {
- BufferedReader in1 = null;
- BufferedReader in2 = null;
- try {
- in1 = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(file1))));
- in2 = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(file2))));
-
- String s1;
- int lineCounter = 0;
-
- while ((s1 = in1.readLine()) != null) {
- lineCounter++;
-
- String s2 = in2.readLine();
-
- if (!s1.equals(s2)) {
- System.out.println("Files [" + file1 + "] and [" + file2 + "] differ on line " + lineCounter);
- System.out.println("One reads: [" + s1 + "].");
- System.out.println("Other reads:[" + s2 + "].");
- outputFile(file1);
- outputFile(file2);
-
- return false;
- }
- }
-
- // the second file is longer
- if (in2.read() != -1) {
- System.out.println("File [" + file2 + "] longer than file [" + file1 + "].");
- outputFile(file1);
- outputFile(file2);
-
- return false;
- }
-
- return true;
- } finally {
- close(in1);
- close(in2);
- }
+ return false;
}
- static void close(Reader r) {
- if (r != null)
- try {
- r.close();
- } catch (IOException e) {
- }
- }
+ return true;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/ContentTypeUtilTest.java b/logback-core/src/test/java/ch/qos/logback/core/util/ContentTypeUtilTest.java
index e685e96..5303108 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/ContentTypeUtilTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/ContentTypeUtilTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,26 +17,28 @@ import static org.junit.Assert.*;
import org.junit.Test;
-public class ContentTypeUtilTest {
-
- @Test
- public void smoke() {
- String contextType = "text/html";
- assertTrue(ContentTypeUtil.isTextual(contextType));
- assertEquals("html", ContentTypeUtil.getSubType(contextType));
- }
- @Test
- public void nullContext() {
- String contextType = null;
- assertFalse(ContentTypeUtil.isTextual(contextType));
- assertNull(ContentTypeUtil.getSubType(contextType));
- }
+public class ContentTypeUtilTest {
- @Test
- public void emptySubtype() {
- String contextType = "text/";
- assertTrue(ContentTypeUtil.isTextual(contextType));
- assertNull(ContentTypeUtil.getSubType(contextType));
- }
+
+ @Test
+ public void smoke() {
+ String contextType = "text/html";
+ assertTrue(ContentTypeUtil.isTextual(contextType));
+ assertEquals("html", ContentTypeUtil.getSubType(contextType));
+ }
+
+ @Test
+ public void nullContext() {
+ String contextType = null;
+ assertFalse(ContentTypeUtil.isTextual(contextType));
+ assertNull(ContentTypeUtil.getSubType(contextType));
+ }
+
+ @Test
+ public void emptySubtype() {
+ String contextType = "text/";
+ assertTrue(ContentTypeUtil.isTextual(contextType));
+ assertNull(ContentTypeUtil.getSubType(contextType));
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/CoreTestConstants.java b/logback-core/src/test/java/ch/qos/logback/core/util/CoreTestConstants.java
index 1906df6..250d084 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/CoreTestConstants.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/CoreTestConstants.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,18 +15,20 @@ package ch.qos.logback.core.util;
public class CoreTestConstants {
- public static final String TEST_SRC_PREFIX = "src/test/";
- public static final String TEST_INPUT_PREFIX = TEST_SRC_PREFIX + "input/";
- public static final String JORAN_INPUT_PREFIX = TEST_INPUT_PREFIX + "joran/";
+ public static final String TEST_SRC_PREFIX = "src/test/";
+ public static final String TEST_INPUT_PREFIX = TEST_SRC_PREFIX + "input/";
+ public static final String JORAN_INPUT_PREFIX = TEST_INPUT_PREFIX
+ + "joran/";
- public static final String TARGET_DIR = "target/";
- public static final String OUTPUT_DIR_PREFIX = TARGET_DIR + "test-output/";
+ public static final String TARGET_DIR = "target/";
+ public static final String OUTPUT_DIR_PREFIX = TARGET_DIR + "test-output/";
- public static final int SUCCESSFUL_EXIT_CODE = 8;
- public static final int FAILURE_EXIT_CODE = 1;
+ public static final int SUCCESSFUL_EXIT_CODE = 8;
+ public static final int FAILURE_EXIT_CODE = 1;
- public static final String BASH_PATH_ON_CYGWIN = "c:/cygwin/bin/bash";
- public static final String BASH_PATH_ON_LINUX = "bash";
+ public static final String BASH_PATH_ON_CYGWIN = "c:/cygwin/bin/bash";
+ public static final String BASH_PATH_ON_LINUX = "bash";
- public static final String SLOW_JENKINS = "slowJenkins";
+
+ public static final String SLOW_JENKINS = "slowJenkins";
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/DatePatternToRegexTest.java b/logback-core/src/test/java/ch/qos/logback/core/util/DatePatternToRegexTest.java
index 6f3e97e..545f23e 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/DatePatternToRegexTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/DatePatternToRegexTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,7 +19,6 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
-import java.util.Locale;
import ch.qos.logback.core.rolling.helper.DateTokenConverter;
import org.junit.BeforeClass;
@@ -28,126 +27,91 @@ import org.junit.Test;
import ch.qos.logback.core.CoreConstants;
public class DatePatternToRegexTest {
- static Calendar CAL_2009_08_3_NIGHT = Calendar.getInstance();
- static Calendar CAL_2009_08_3_MORNING = Calendar.getInstance();
- static Locale CZ_LOCALE = new Locale("cs", "CZ");
- static Locale KO_LOCALE = new Locale("ko", "KR");
-
- @BeforeClass
- public static void setUpCalendars() {
- CAL_2009_08_3_NIGHT.set(2009, 8, 3, 21, 57, 16);
- CAL_2009_08_3_NIGHT.set(Calendar.MILLISECOND, 333);
-
- CAL_2009_08_3_MORNING.set(2009, 8, 3, 10, 24, 37);
- CAL_2009_08_3_MORNING.set(Calendar.MILLISECOND, 333);
- }
-
- @Test
- public void ISO8601() {
- doTest(CoreConstants.ISO8601_PATTERN, CAL_2009_08_3_NIGHT);
- }
-
- @Test
- public void withQuotes() {
- doTest("yyyy-MM-dd'T'HH:mm:ss,SSS", CAL_2009_08_3_NIGHT);
-
- }
-
- @Test
- public void month() {
- doTest("yyyy-MMM-dd", CAL_2009_08_3_NIGHT);
- doTest("yyyy-MMM-dd", CAL_2009_08_3_NIGHT, CZ_LOCALE);
- doTest("yyyy-MMM-dd", CAL_2009_08_3_NIGHT, KO_LOCALE);
-
- doTest("yyyy-MMMM-dd", CAL_2009_08_3_NIGHT);
- doTest("yyyy-MMMM-dd", CAL_2009_08_3_NIGHT, CZ_LOCALE);
- doTest("yyyy-MMMM-dd", CAL_2009_08_3_NIGHT, KO_LOCALE);
-
- }
-
- public void monthWithLocal() {
-
- }
-
- @Test
- public void dot() {
- doTest("yyyy.MMM.dd", CAL_2009_08_3_NIGHT);
- ;
- }
-
- @Test
- public void timeZone() {
- doTest("yyyy-MMM-dd HH:mm:ss z", CAL_2009_08_3_NIGHT);
- doTest("yyyy-MMM-dd HH:mm:ss Z", CAL_2009_08_3_NIGHT);
- }
-
- @Test
- public void dayInWeek() {
- doTest("EE", CAL_2009_08_3_NIGHT);
- doTest("EE", CAL_2009_08_3_NIGHT, CZ_LOCALE);
- doTest("EE", CAL_2009_08_3_NIGHT, KO_LOCALE);
-
- doTest("EEEE", CAL_2009_08_3_NIGHT);
- doTest("EEEE", CAL_2009_08_3_NIGHT, CZ_LOCALE);
- doTest("EEEE", CAL_2009_08_3_NIGHT, KO_LOCALE);
- }
-
- @Test
- public void amPm() {
- doTest("yyyy-MM-dd a", CAL_2009_08_3_NIGHT);
- doTest("yyyy-MM-dd a", CAL_2009_08_3_NIGHT, CZ_LOCALE);
- doTest("yyyy-MM-dd a", CAL_2009_08_3_NIGHT, KO_LOCALE);
-
- doTest("yyyy-MM-dd a", CAL_2009_08_3_MORNING);
- doTest("yyyy-MM-dd a", CAL_2009_08_3_MORNING, CZ_LOCALE);
- doTest("yyyy-MM-dd a", CAL_2009_08_3_MORNING, KO_LOCALE);
-
- }
-
- void doTest(String datePattern, Calendar calendar) {
- doTest(datePattern, calendar, null);
- }
-
- void doTest(String datePattern, Calendar calendar, Locale locale) {
- Locale oldDefaultLocale = Locale.getDefault();
- if (locale != null) {
- Locale.setDefault(locale);
- }
-
- try {
- SimpleDateFormat sdf = new SimpleDateFormat(datePattern);
- DateTokenConverter<?> dtc = makeDTC(datePattern);
- verify(sdf, calendar, dtc);
- } finally {
- if (locale != null)
- Locale.setDefault(oldDefaultLocale);
-
- }
- }
-
- Locale locale;
-
- // void doTest(String datePattern, Calendar calendar) {
- // doTest(datePattern, calendar, false);
- // }
-
- void verify(SimpleDateFormat sdf, Calendar calendar, DateTokenConverter<?> dtc) {
- String expected = sdf.format(calendar.getTime());
- // if (slashified) {
- // expected = expected.replace('\\', '/');
- // }
- String regex = dtc.toRegex();
- // System.out.println("expected="+expected);
- // System.out.println(regex);
- assertTrue("[" + expected + "] does not match regex [" + regex + "]", expected.matches(regex));
- }
-
- private DateTokenConverter<?> makeDTC(String datePattern) {
- DateTokenConverter<?> dtc = new DateTokenConverter<Object>();
- List<String> optionList = new ArrayList<String>();
- optionList.add(datePattern);
- dtc.setOptionList(optionList);
- dtc.start();
- return dtc;
+ static Calendar CAL_2009_08_3_NIGHT = Calendar.getInstance();
+ static Calendar CAL_2009_08_3_MORNING = Calendar.getInstance();
+
+ @BeforeClass
+ public static void setUpCalendars() {
+ CAL_2009_08_3_NIGHT.set(2009, 8, 3, 21, 57, 16);
+ CAL_2009_08_3_NIGHT.set(Calendar.MILLISECOND, 333);
+
+ CAL_2009_08_3_MORNING.set(2009, 8, 3, 10, 24, 37);
+ CAL_2009_08_3_MORNING.set(Calendar.MILLISECOND, 333);
+ }
+
+ @Test
+ public void ISO8601() {
+ doTest(CoreConstants.ISO8601_PATTERN, CAL_2009_08_3_NIGHT);
+ ;
+ }
+
+ @Test
+ public void withQuotes() {
+ doTest("yyyy-MM-dd'T'HH:mm:ss,SSS", CAL_2009_08_3_NIGHT);
+ ;
+ }
+
+ @Test
+ public void month() {
+ doTest("yyyy-MMM-dd", CAL_2009_08_3_NIGHT);
+ doTest("yyyy-MMMM-dd", CAL_2009_08_3_NIGHT);
+ }
+
+ @Test
+ public void dot() {
+ doTest("yyyy.MMM.dd", CAL_2009_08_3_NIGHT);
+ ;
+ }
+
+ @Test
+ public void timeZone() {
+ doTest("yyyy-MMM-dd HH:mm:ss z", CAL_2009_08_3_NIGHT);
+ doTest("yyyy-MMM-dd HH:mm:ss Z", CAL_2009_08_3_NIGHT);
+ }
+
+ @Test
+ public void dayInWeek() {
+ doTest("yyyy-MMM-E", CAL_2009_08_3_NIGHT);
+ doTest("yyyy-MMM-EE", CAL_2009_08_3_NIGHT);
+ doTest("yyyy-MMM-EEE", CAL_2009_08_3_NIGHT);
+ }
+
+ @Test
+ public void amPm() {
+ doTest("yyyy-MM-dd a", CAL_2009_08_3_NIGHT);
+ doTest("yyyy-MM-dd a", CAL_2009_08_3_MORNING);
+ }
+
+
+ void doTest(String datePattern, Calendar calendar, boolean slashified) {
+ SimpleDateFormat sdf = new SimpleDateFormat(datePattern);
+ DateTokenConverter dtc = makeDTC(datePattern);
+ verify(sdf, calendar, dtc, slashified);
+ }
+
+ void doTest(String datePattern, Calendar calendar) {
+ doTest(datePattern, calendar, false);
+ }
+
+
+ void verify(SimpleDateFormat sdf, Calendar calendar, DateTokenConverter dtc, boolean slashified) {
+ String expected = sdf.format(calendar.getTime());
+ if (slashified) {
+ expected = expected.replace('\\', '/');
}
+ String regex = dtc.toRegex();
+ //System.out.println("expected="+expected);
+ //System.out.println(regex);
+ assertTrue("[" + expected + "] does not match regex [" + regex + "]",
+ expected.matches(regex));
+ }
+
+ private DateTokenConverter makeDTC(String datePattern) {
+ DateTokenConverter dtc = new DateTokenConverter();
+ List<String> optionList = new ArrayList<String>();
+ optionList.add(datePattern);
+ dtc.setOptionList(optionList);
+ dtc.start();
+ return dtc;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/DefaultInvocationGateTest.java b/logback-core/src/test/java/ch/qos/logback/core/util/DefaultInvocationGateTest.java
deleted file mode 100644
index b34ee87..0000000
--- a/logback-core/src/test/java/ch/qos/logback/core/util/DefaultInvocationGateTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package ch.qos.logback.core.util;
-
-import static ch.qos.logback.core.util.DefaultInvocationGate.DEFAULT_MASK;
-import static ch.qos.logback.core.util.DefaultInvocationGate.MASK_DECREASE_RIGHT_SHIFT_COUNT;
-import static org.junit.Assert.*;
-
-import org.junit.Test;
-
-public class DefaultInvocationGateTest {
-
- @Test
- public void smoke() {
- long currentTime = 0;
- long minDelayThreshold = 4;
- long maxDelayThreshold = 8;
-
- DefaultInvocationGate gate = new DefaultInvocationGate(minDelayThreshold, maxDelayThreshold, currentTime);
- assertTrue(gate.isTooSoon(0));
- }
-
- @Test
- public void closelyRepeatedCallsShouldCauseMaskToIncrease() {
- long currentTime = 0;
- long minDelayThreshold = 4;
- long maxDelayThreshold = 8;
-
- DefaultInvocationGate gate = new DefaultInvocationGate(minDelayThreshold, maxDelayThreshold, currentTime);
- for (int i = 0; i < DEFAULT_MASK; i++) {
- assertTrue(gate.isTooSoon(0));
- }
- assertFalse(gate.isTooSoon(0));
- assertTrue(gate.getMask() > DEFAULT_MASK);
- }
-
- @Test
- public void stableAtSteadyRate() {
- long currentTime = 0;
- long minDelayThreshold = DEFAULT_MASK;
- long maxDelayThreshold = DEFAULT_MASK * 2;
-
- DefaultInvocationGate gate = new DefaultInvocationGate(minDelayThreshold, maxDelayThreshold, currentTime);
-
- for (int t = 0; t < 4 * minDelayThreshold; t++) {
- gate.isTooSoon(currentTime++);
- assertEquals(DEFAULT_MASK, gate.getMask());
- }
- }
-
- @Test
- public void intermittentCallsShouldCauseMaskToDecrease() {
- long currentTime = 0;
- long minDelayThreshold = 4;
- long maxDelayThreshold = 8;
-
- DefaultInvocationGate gate = new DefaultInvocationGate(minDelayThreshold, maxDelayThreshold, currentTime);
- int currentMask = DEFAULT_MASK;
-
- currentTime += maxDelayThreshold + 1;
- assertFalse(gate.isTooSoon(currentTime));
- assertTrue(gate.getMask() < currentMask);
- }
-
- @Test
- public void maskCanDropToZeroForInfrequentInvocations() {
- long currentTime = 0;
- long minDelayThreshold = 4;
- long maxDelayThreshold = 8;
-
- DefaultInvocationGate gate = new DefaultInvocationGate(minDelayThreshold, maxDelayThreshold, currentTime);
- int currentMask = DEFAULT_MASK;
-
- do {
- currentTime += maxDelayThreshold + 1;
- assertFalse(gate.isTooSoon(currentTime));
- assertTrue(gate.getMask() < currentMask);
- currentMask = currentMask >> MASK_DECREASE_RIGHT_SHIFT_COUNT;
- } while (currentMask > 0);
-
- assertEquals(0, gate.getMask());
- assertFalse(gate.isTooSoon(currentTime));
- }
-}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/DurationTest.java b/logback-core/src/test/java/ch/qos/logback/core/util/DurationTest.java
index 5626188..fd547c0 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/DurationTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/DurationTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,86 +17,88 @@ import static org.junit.Assert.assertEquals;
import org.junit.Test;
-public class DurationTest {
- static long HOURS_CO = 60 * 60;
- static long DAYS_CO = 24 * 60 * 60;
+public class DurationTest {
- @Test
- public void test() {
- {
- Duration d = Duration.valueOf("12");
- assertEquals(12, d.getMilliseconds());
- }
+ static long HOURS_CO = 60*60;
+ static long DAYS_CO = 24*60*60;
+
- {
- Duration d = Duration.valueOf("159 milli");
- assertEquals(159, d.getMilliseconds());
- }
-
- {
- Duration d = Duration.valueOf("15 millis");
- assertEquals(15, d.getMilliseconds());
- }
-
- {
- Duration d = Duration.valueOf("8 milliseconds");
- assertEquals(8, d.getMilliseconds());
- }
-
- {
- Duration d = Duration.valueOf("10.7 millisecond");
- assertEquals(10, d.getMilliseconds());
- }
-
- {
- Duration d = Duration.valueOf("10 SECOnds");
- assertEquals(10 * 1000, d.getMilliseconds());
- }
-
- {
- Duration d = Duration.valueOf("12seconde");
- assertEquals(12 * 1000, d.getMilliseconds());
- }
-
- {
- Duration d = Duration.valueOf("14 SECONDES");
- assertEquals(14 * 1000, d.getMilliseconds());
- }
-
- {
- Duration d = Duration.valueOf("12second");
- assertEquals(12 * 1000, d.getMilliseconds());
- }
-
- {
- Duration d = Duration.valueOf("10.7 seconds");
- assertEquals(10700, d.getMilliseconds());
- }
-
- {
- Duration d = Duration.valueOf("1 minute");
- assertEquals(1000 * 60, d.getMilliseconds());
- }
+ @Test
+ public void test() {
+ {
+ Duration d = Duration.valueOf("12");
+ assertEquals(12, d.getMilliseconds());
+ }
- {
- Duration d = Duration.valueOf("2.2 minutes");
- assertEquals(2200 * 60, d.getMilliseconds());
- }
+ {
+ Duration d = Duration.valueOf("159 milli");
+ assertEquals(159, d.getMilliseconds());
+ }
+
+ {
+ Duration d = Duration.valueOf("15 millis");
+ assertEquals(15, d.getMilliseconds());
+ }
+
+ {
+ Duration d = Duration.valueOf("8 milliseconds");
+ assertEquals(8, d.getMilliseconds());
+ }
+
+ {
+ Duration d = Duration.valueOf("10.7 millisecond");
+ assertEquals(10, d.getMilliseconds());
+ }
+
+ {
+ Duration d = Duration.valueOf("10 SECOnds");
+ assertEquals(10 * 1000, d.getMilliseconds());
+ }
- {
- Duration d = Duration.valueOf("1 hour");
- assertEquals(1000 * HOURS_CO, d.getMilliseconds());
- }
+ {
+ Duration d = Duration.valueOf("12seconde");
+ assertEquals(12 * 1000, d.getMilliseconds());
+ }
- {
- Duration d = Duration.valueOf("4.2 hours");
- assertEquals(4200 * HOURS_CO, d.getMilliseconds());
- }
+ {
+ Duration d = Duration.valueOf("14 SECONDES");
+ assertEquals(14 * 1000, d.getMilliseconds());
+ }
+
+ {
+ Duration d = Duration.valueOf("12second");
+ assertEquals(12 * 1000, d.getMilliseconds());
+ }
+
+ {
+ Duration d = Duration.valueOf("10.7 seconds");
+ assertEquals(10700, d.getMilliseconds());
+ }
+
+ {
+ Duration d = Duration.valueOf("1 minute");
+ assertEquals(1000*60, d.getMilliseconds());
+ }
+
+ {
+ Duration d = Duration.valueOf("2.2 minutes");
+ assertEquals(2200*60, d.getMilliseconds());
+ }
+
+ {
+ Duration d = Duration.valueOf("1 hour");
+ assertEquals(1000*HOURS_CO, d.getMilliseconds());
+ }
+
+ {
+ Duration d = Duration.valueOf("4.2 hours");
+ assertEquals(4200*HOURS_CO, d.getMilliseconds());
+ }
- {
- Duration d = Duration.valueOf("5 days");
- assertEquals(5000 * DAYS_CO, d.getMilliseconds());
- }
+ {
+ Duration d = Duration.valueOf("5 days");
+ assertEquals(5000*DAYS_CO, d.getMilliseconds());
}
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/FileSizeTest.java b/logback-core/src/test/java/ch/qos/logback/core/util/FileSizeTest.java
index bbe0022..0f56078 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/FileSizeTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/FileSizeTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,56 +17,40 @@ import static org.junit.Assert.assertEquals;
import org.junit.Test;
-public class FileSizeTest {
- static long KB_CO = 1024;
- static long MB_CO = 1024 * 1024;
- static long GB_CO = 1024 * MB_CO;
+public class FileSizeTest{
- @Test
- public void testValueOf() {
- {
- FileSize fs = FileSize.valueOf("8");
- assertEquals(8, fs.getSize());
- }
+ static long KB_CO = 1024;
+ static long MB_CO = 1024*1024;
+ static long GB_CO = 1024*MB_CO;
+
- {
- FileSize fs = FileSize.valueOf("8 kbs");
- assertEquals(8 * KB_CO, fs.getSize());
- }
-
- {
- FileSize fs = FileSize.valueOf("8 kb");
- assertEquals(8 * KB_CO, fs.getSize());
- }
-
- {
- FileSize fs = FileSize.valueOf("12 mb");
- assertEquals(12 * MB_CO, fs.getSize());
- }
-
- {
- FileSize fs = FileSize.valueOf("5 GBs");
- assertEquals(5 * GB_CO, fs.getSize());
- }
+ @Test
+ public void test() {
+ {
+ FileSize fs = FileSize.valueOf("8");
+ assertEquals(8, fs.getSize());
}
+ {
+ FileSize fs = FileSize.valueOf("8 kbs");
+ assertEquals(8*KB_CO, fs.getSize());
+ }
+
+ {
+ FileSize fs = FileSize.valueOf("8 kb");
+ assertEquals(8*KB_CO, fs.getSize());
+ }
- @Test
- public void testToString() {
- {
- FileSize fs = new FileSize(8);
- assertEquals("8 Bytes", fs.toString());
- }
-
- {
- FileSize fs = new FileSize(8*1024+3);
- assertEquals("8 KB", fs.toString());
- }
-
- {
- FileSize fs = new FileSize(8*1024*1024+3*1024);
- assertEquals("8 MB", fs.toString());
- }
+ {
+ FileSize fs = FileSize.valueOf("12 mb");
+ assertEquals(12*MB_CO, fs.getSize());
+ }
+
+ {
+ FileSize fs = FileSize.valueOf("5 GBs");
+ assertEquals(5*GB_CO, fs.getSize());
}
+
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/FileUtilTest.java b/logback-core/src/test/java/ch/qos/logback/core/util/FileUtilTest.java
index 1408a46..b3ec832 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/FileUtilTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/FileUtilTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,10 +13,12 @@
*/
package ch.qos.logback.core.util;
+
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -30,77 +32,63 @@ import org.junit.Test;
public class FileUtilTest {
- Context context = new ContextBase();
- FileUtil fileUtil = new FileUtil(context);
- List<File> cleanupList = new ArrayList<File>();
- // test-output folder is not always clean
- int diff = new Random().nextInt(10000);
-
- @Before
- public void setUp() throws Exception {
-
- }
-
- @After
- public void tearDown() throws Exception {
- for (File f : cleanupList) {
- f.delete();
- }
+ Context context = new ContextBase();
+ FileUtil fileUtil = new FileUtil(context);
+ List<File> cleanupList = new ArrayList<File>();
+ // test-output folder is not always clean
+ int diff = new Random().nextInt(10000);
+
+ @Before
+ public void setUp() throws Exception {
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ for(File f: cleanupList) {
+ f.delete();
}
+ }
+
+ @Test
+ public void checkParentCreationInquiryAndSubsequentCreation() {
+ File file = new File(CoreTestConstants.OUTPUT_DIR_PREFIX+"/fu"+diff+"/testing.txt");
+ // these will be deleted later
+ cleanupList.add(file);
+ cleanupList.add(file.getParentFile());
+
+ assertTrue(FileUtil.isParentDirectoryCreationRequired(file));
+ assertTrue(FileUtil.createMissingParentDirectories(file));
+ assertFalse(FileUtil.isParentDirectoryCreationRequired(file));
+ }
+
+ @Test
+ public void checkDeeperParentCreationInquiryAndSubsequentCreation() {
+
+ File file = new File(CoreTestConstants.OUTPUT_DIR_PREFIX+"/fu"+diff+"/bla/testing.txt");
+ // these will be deleted later
+ cleanupList.add(file);
+ cleanupList.add(file.getParentFile());
+ cleanupList.add(file.getParentFile().getParentFile());
+
+ assertTrue(FileUtil.isParentDirectoryCreationRequired(file));
+ assertTrue(FileUtil.createMissingParentDirectories(file));
+ assertFalse(FileUtil.isParentDirectoryCreationRequired(file));
+ }
+
+ @Test
+ public void basicCopyingWorks() throws IOException {
+ String dir = CoreTestConstants.OUTPUT_DIR_PREFIX+"/fu"+diff;
+
+ File dirFile = new File(dir);
+ dirFile.mkdir();
+
+ String src = CoreTestConstants.TEST_INPUT_PREFIX + "compress1.copy";
+ String target = CoreTestConstants.OUTPUT_DIR_PREFIX+"/fu"+diff+"/copyingWorks.txt";
+
+ fileUtil.copy(src, target);
+ Compare.compare(src, target);
+ }
- @Test
- public void checkParentCreationInquiryAndSubsequentCreation() {
- File file = new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "/fu" + diff + "/testing.txt");
- // these will be deleted later
- cleanupList.add(file);
- cleanupList.add(file.getParentFile());
- assertFalse(file.getParentFile().exists());
- assertTrue(FileUtil.createMissingParentDirectories(file));
- assertTrue(file.getParentFile().exists());
- }
-
- @Test
- public void checkDeeperParentCreationInquiryAndSubsequentCreation() {
-
- File file = new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "/fu" + diff + "/bla/testing.txt");
- // these will be deleted later
- cleanupList.add(file);
- cleanupList.add(file.getParentFile());
- cleanupList.add(file.getParentFile().getParentFile());
-
- assertFalse(file.getParentFile().exists());
- assertTrue(FileUtil.createMissingParentDirectories(file));
- assertTrue(file.getParentFile().exists());
- }
-
- @Test
- public void basicCopyingWorks() throws IOException {
- String dir = CoreTestConstants.OUTPUT_DIR_PREFIX + "/fu" + diff;
-
- File dirFile = new File(dir);
- dirFile.mkdir();
-
- String src = CoreTestConstants.TEST_INPUT_PREFIX + "compress1.copy";
- String target = CoreTestConstants.OUTPUT_DIR_PREFIX + "/fu" + diff + "/copyingWorks.txt";
-
- fileUtil.copy(src, target);
- Compare.compare(src, target);
- }
-
- @Test
- public void createParentDirIgnoresExistingDir() {
- String target = CoreTestConstants.OUTPUT_DIR_PREFIX + "/fu" + diff + "/testing.txt";
- File file = new File(target);
- cleanupList.add(file);
- file.mkdirs();
- assertTrue(file.getParentFile().exists());
- assertTrue(FileUtil.createMissingParentDirectories(file));
- }
-
- @Test
- public void createParentDirAcceptsNoParentSpecified() {
- File file = new File("testing.txt");
- assertTrue(FileUtil.createMissingParentDirectories(file));
- }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/FixedRateInvocationGate.java b/logback-core/src/test/java/ch/qos/logback/core/util/FixedRateInvocationGate.java
deleted file mode 100644
index 40c20f6..0000000
--- a/logback-core/src/test/java/ch/qos/logback/core/util/FixedRateInvocationGate.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package ch.qos.logback.core.util;
-
-public class FixedRateInvocationGate implements InvocationGate {
-
- int rate;
- int invocationCount = 0;
-
- public FixedRateInvocationGate(int rate) {
- this.rate = rate;
- }
-
- @Override
- public boolean isTooSoon(long currentTime) {
- if (invocationCount++ % rate != 0)
- return true;
- return false;
- }
-
-}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/LocationUtilTest.java b/logback-core/src/test/java/ch/qos/logback/core/util/LocationUtilTest.java
index a4f5a00..991d69a 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/LocationUtilTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/LocationUtilTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -35,62 +35,66 @@ import ch.qos.logback.core.util.LocationUtil;
*/
public class LocationUtilTest {
- private static final String TEST_CLASSPATH_RESOURCE = "util/testResource.txt";
- private static final String TEST_PATTERN = "TEST RESOURCE";
+ private static final String TEST_CLASSPATH_RESOURCE = "util/testResource.txt";
+ private static final String TEST_PATTERN = "TEST RESOURCE";
+
+ @Test
+ public void testImplicitClasspathUrl() throws Exception {
+ URL url = LocationUtil.urlForResource(TEST_CLASSPATH_RESOURCE);
+ validateResource(url);
+ }
+
+ @Test
+ public void testExplicitClasspathUrl() throws Exception {
+ URL url = LocationUtil.urlForResource(
+ LocationUtil.CLASSPATH_SCHEME + TEST_CLASSPATH_RESOURCE);
+ validateResource(url);
+ }
+
+ @Test
+ public void testExplicitClasspathUrlWithLeadingSlash() throws Exception {
+ URL url = LocationUtil.urlForResource(
+ LocationUtil.CLASSPATH_SCHEME + "/" + TEST_CLASSPATH_RESOURCE);
+ validateResource(url);
+ }
- @Test
- public void testImplicitClasspathUrl() throws Exception {
- URL url = LocationUtil.urlForResource(TEST_CLASSPATH_RESOURCE);
- validateResource(url);
- }
-
- @Test
- public void testExplicitClasspathUrl() throws Exception {
- URL url = LocationUtil.urlForResource(LocationUtil.CLASSPATH_SCHEME + TEST_CLASSPATH_RESOURCE);
- validateResource(url);
- }
-
- @Test
- public void testExplicitClasspathUrlWithLeadingSlash() throws Exception {
- URL url = LocationUtil.urlForResource(LocationUtil.CLASSPATH_SCHEME + "/" + TEST_CLASSPATH_RESOURCE);
- validateResource(url);
- }
+ @Test(expected = MalformedURLException.class)
+ public void testExplicitClasspathUrlEmptyPath() throws Exception {
+ LocationUtil.urlForResource(LocationUtil.CLASSPATH_SCHEME);
+ }
- @Test(expected = MalformedURLException.class)
- public void testExplicitClasspathUrlEmptyPath() throws Exception {
- LocationUtil.urlForResource(LocationUtil.CLASSPATH_SCHEME);
- }
+ @Test(expected = MalformedURLException.class)
+ public void testExplicitClasspathUrlWithRootPath() throws Exception {
+ LocationUtil.urlForResource(LocationUtil.CLASSPATH_SCHEME + "/");
+ }
- @Test(expected = MalformedURLException.class)
- public void testExplicitClasspathUrlWithRootPath() throws Exception {
- LocationUtil.urlForResource(LocationUtil.CLASSPATH_SCHEME + "/");
+ @Test
+ public void testFileUrl() throws Exception {
+ File file = File.createTempFile("testResource", ".txt");
+ file.deleteOnExit();
+ PrintWriter writer = new PrintWriter(file);
+ writer.println(TEST_PATTERN);
+ writer.close();
+ URL url = file.toURI().toURL();
+ validateResource(url);
+ }
+
+ private void validateResource(URL url) throws IOException {
+ InputStream inputStream = url.openStream();
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+ String line = reader.readLine();
+ assertEquals(TEST_PATTERN, line);
}
-
- @Test
- public void testFileUrl() throws Exception {
- File file = File.createTempFile("testResource", ".txt");
- file.deleteOnExit();
- PrintWriter writer = new PrintWriter(file);
- writer.println(TEST_PATTERN);
- writer.close();
- URL url = file.toURI().toURL();
- validateResource(url);
+ finally {
+ try {
+ inputStream.close();
+ }
+ catch (IOException ex) {
+ // ignore close exception
+ ex.printStackTrace(System.err);
+ }
}
-
- private void validateResource(URL url) throws IOException {
- InputStream inputStream = url.openStream();
- try {
- BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
- String line = reader.readLine();
- assertEquals(TEST_PATTERN, line);
- } finally {
- try {
- inputStream.close();
- } catch (IOException ex) {
- // ignore close exception
- ex.printStackTrace(System.err);
- }
- }
- }
-
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/OptionHelperTest.java b/logback-core/src/test/java/ch/qos/logback/core/util/OptionHelperTest.java
index 0b89773..6585e63 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/OptionHelperTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/OptionHelperTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,6 +19,7 @@ import static org.junit.Assert.fail;
import java.util.HashMap;
import java.util.Map;
+import ch.qos.logback.core.joran.spi.InterpretationContext;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -28,235 +29,231 @@ import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.joran.spi.JoranException;
-public class OptionHelperTest {
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- String text = "Testing ${v1} variable substitution ${v2}";
- String expected = "Testing if variable substitution works";
- Context context = new ContextBase();
- Map<String, String> secondaryMap;
-
- @Before
- public void setUp() throws Exception {
- secondaryMap = new HashMap<String, String>();
- }
-
- @Test
- public void testLiteral() {
- String noSubst = "hello world";
- String result = OptionHelper.substVars(noSubst, context);
- assertEquals(noSubst, result);
- }
-
- @Test
- public void testUndefinedValues() {
- String withUndefinedValues = "${axyz}";
-
- String result = OptionHelper.substVars(withUndefinedValues, context);
- assertEquals("axyz" + OptionHelper._IS_UNDEFINED, result);
- }
-
- @Test
- public void testSubstVarsVariableNotClosed() {
- String noSubst = "testing if ${v1 works";
-
- try {
- @SuppressWarnings("unused")
- String result = OptionHelper.substVars(noSubst, context);
- fail();
- } catch (IllegalArgumentException e) {
- // ok
- }
- }
-
- @Test
- public void testSubstVarsContextOnly() {
- context.putProperty("v1", "if");
- context.putProperty("v2", "works");
-
- String result = OptionHelper.substVars(text, context);
- assertEquals(expected, result);
- }
-
- @Test
- public void testSubstVarsSystemProperties() {
- System.setProperty("v1", "if");
- System.setProperty("v2", "works");
-
- String result = OptionHelper.substVars(text, context);
- assertEquals(expected, result);
-
- System.clearProperty("v1");
- System.clearProperty("v2");
- }
-
- @Test
- public void testSubstVarsWithDefault() {
- context.putProperty("v1", "if");
- String textWithDefault = "Testing ${v1} variable substitution ${v2:-toto}";
- String resultWithDefault = "Testing if variable substitution toto";
-
- String result = OptionHelper.substVars(textWithDefault, context);
- assertEquals(resultWithDefault, result);
- }
-
- @Test
- public void testSubstVarsRecursive() {
- context.putProperty("v1", "if");
- context.putProperty("v2", "${v3}");
- context.putProperty("v3", "works");
-
- String result = OptionHelper.substVars(text, context);
- assertEquals(expected, result);
- }
-
- @Test
- public void testSubstVarsTwoLevelsDeep() {
- context.putProperty("v1", "if");
- context.putProperty("v2", "${v3}");
- context.putProperty("v3", "${v4}");
- context.putProperty("v4", "works");
-
- String result = OptionHelper.substVars(text, context);
- assertEquals(expected, result);
- }
-
- @Test
- public void testSubstVarsTwoLevelsWithDefault() {
- // Example input taken from LOGBCK-943 bug report
- context.putProperty("APP_NAME", "LOGBACK");
- context.putProperty("ARCHIVE_SUFFIX", "archive.log");
- context.putProperty("LOG_HOME", "${logfilepath.default:-logs}");
- context.putProperty("ARCHIVE_PATH", "${LOG_HOME}/archive/${APP_NAME}");
-
- String result = OptionHelper.substVars("${ARCHIVE_PATH}_trace_${ARCHIVE_SUFFIX}", context);
- assertEquals("logs/archive/LOGBACK_trace_archive.log", result);
- }
-
- @Test(timeout = 1000)
- public void stubstVarsShouldNotGoIntoInfiniteLoop() {
- context.putProperty("v1", "if");
- context.putProperty("v2", "${v3}");
- context.putProperty("v3", "${v4}");
- context.putProperty("v4", "${v2}c");
-
- expectedException.expect(Exception.class);
- OptionHelper.substVars(text, context);
- }
-
- @Test
- public void nonCircularGraphShouldWork() {
- context.putProperty("A", "${B} and ${C}");
- context.putProperty("B", "${B1}");
- context.putProperty("B1", "B1-value");
- context.putProperty("C", "${C1} and ${B}");
- context.putProperty("C1", "C1-value");
-
- String result = OptionHelper.substVars("${A}", context);
- assertEquals("B1-value and C1-value and B1-value", result);
- }
-
- @Test(timeout = 1000)
- public void detectCircularReferences0() {
- context.putProperty("A", "${A}");
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Circular variable reference detected while parsing input [${A} --> ${A}]");
- OptionHelper.substVars("${A}", context);
- }
-
- @Test(timeout = 1000)
- public void detectCircularReferences1() {
- context.putProperty("A", "${A}a");
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Circular variable reference detected while parsing input [${A} --> ${A}]");
- OptionHelper.substVars("${A}", context);
- }
-
- @Test(timeout = 1000)
- public void detectCircularReferences2() {
- context.putProperty("A", "${B}");
- context.putProperty("B", "${C}");
- context.putProperty("C", "${A}");
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Circular variable reference detected while parsing input [${A} --> ${B} --> ${C} --> ${A}]");
- OptionHelper.substVars("${A}", context);
- }
-
- @Test
- public void detectCircularReferencesInDefault() {
- context.putProperty("A", "${B:-${A}}");
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Circular variable reference detected while parsing input [${A} --> ${B} --> ${A}]");
- OptionHelper.substVars("${A}", context);
- }
-
- @Test(timeout = 1000)
- public void detectCircularReferences3() {
- context.putProperty("A", "${B}");
- context.putProperty("B", "${C}");
- context.putProperty("C", "${A}");
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Circular variable reference detected while parsing input [${B} --> ${C} --> ${A} --> ${B}]");
- OptionHelper.substVars("${B} ", context);
- }
-
- @Test(timeout = 1000)
- public void detectCircularReferences4() {
- context.putProperty("A", "${B}");
- context.putProperty("B", "${C}");
- context.putProperty("C", "${A}");
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Circular variable reference detected while parsing input [${C} --> ${A} --> ${B} --> ${C}]");
- OptionHelper.substVars("${C} and ${A}", context);
- }
-
- @Test
- public void detectCircularReferences5() {
- context.putProperty("A", "${B} and ${C}");
- context.putProperty("B", "${B1}");
- context.putProperty("B1", "B1-value");
- context.putProperty("C", "${C1}");
- context.putProperty("C1", "here's the loop: ${A}");
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Circular variable reference detected while parsing input [${A} --> ${C} --> ${C1} --> ${A}]");
- String result = OptionHelper.substVars("${A}", context);
- System.err.println(result);
- }
-
- @Test
- public void defaultValueReferencingAVariable() {
- context.putProperty("v1", "k1");
- String result = OptionHelper.substVars("${undef:-${v1}}", context);
- assertEquals("k1", result);
- }
-
- @Test
- public void jackrabbit_standalone() {
- String r = OptionHelper.substVars("${jackrabbit.log:-${repo:-jackrabbit}/log/jackrabbit.log}", context);
- assertEquals("jackrabbit/log/jackrabbit.log", r);
- }
-
- @Test
- public void doesNotThrowNullPointerExceptionForEmptyVariable() throws JoranException {
- context.putProperty("var", "");
- OptionHelper.substVars("${var}", context);
- }
-
- @Test
- public void trailingColon_LOGBACK_1140() {
- String prefix = "c:";
- String suffix = "/tmp";
- context.putProperty("var", prefix);
- String r = OptionHelper.substVars("${var}"+suffix, context);
- assertEquals(prefix+suffix, r);
+public class OptionHelperTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ String text = "Testing ${v1} variable substitution ${v2}";
+ String expected = "Testing if variable substitution works";
+ Context context = new ContextBase();
+ Map<String, String> secondaryMap;
+
+
+
+ @Before
+ public void setUp() throws Exception {
+ secondaryMap = new HashMap<String, String>();
+ }
+
+ @Test
+ public void testLiteral() {
+ String noSubst = "hello world";
+ String result = OptionHelper.substVars(noSubst, context);
+ assertEquals(noSubst, result);
+ }
+
+ @Test
+ public void testUndefinedValues() {
+ String withUndefinedValues = "${axyz}";
+
+ String result = OptionHelper.substVars(withUndefinedValues, context);
+ assertEquals("axyz"+OptionHelper._IS_UNDEFINED, result);
+ }
+
+ @Test
+ public void testSubstVarsVariableNotClosed() {
+ String noSubst = "testing if ${v1 works";
+
+ try {
+ @SuppressWarnings("unused")
+ String result = OptionHelper.substVars(noSubst, context);
+ fail();
+ } catch (IllegalArgumentException e) {
+ //ok
}
+ }
+ @Test
+ public void testSubstVarsContextOnly() {
+ context.putProperty("v1", "if");
+ context.putProperty("v2", "works");
+
+ String result = OptionHelper.substVars(text, context);
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void testSubstVarsSystemProperties() {
+ System.setProperty("v1", "if");
+ System.setProperty("v2", "works");
+ String result = OptionHelper.substVars(text, context);
+ assertEquals(expected, result);
+
+ System.clearProperty("v1");
+ System.clearProperty("v2");
+ }
+
+ @Test
+ public void testSubstVarsWithDefault() {
+ context.putProperty("v1", "if");
+ String textWithDefault = "Testing ${v1} variable substitution ${v2:-toto}";
+ String resultWithDefault = "Testing if variable substitution toto";
+
+ String result = OptionHelper.substVars(textWithDefault, context);
+ assertEquals(resultWithDefault, result);
+ }
+
+ @Test
+ public void testSubstVarsRecursive() {
+ context.putProperty("v1", "if");
+ context.putProperty("v2", "${v3}");
+ context.putProperty("v3", "works");
+
+ String result = OptionHelper.substVars(text, context);
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void testSubstVarsTwoLevelsDeep() {
+ context.putProperty("v1", "if");
+ context.putProperty("v2", "${v3}");
+ context.putProperty("v3", "${v4}");
+ context.putProperty("v4", "works");
+
+ String result = OptionHelper.substVars(text, context);
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void testSubstVarsTwoLevelsWithDefault() {
+ // Example input taken from LOGBCK-943 bug report
+ context.putProperty("APP_NAME", "LOGBACK");
+ context.putProperty("ARCHIVE_SUFFIX", "archive.log");
+ context.putProperty("LOG_HOME", "${logfilepath.default:-logs}");
+ context.putProperty("ARCHIVE_PATH", "${LOG_HOME}/archive/${APP_NAME}");
+
+ String result = OptionHelper.substVars("${ARCHIVE_PATH}_trace_${ARCHIVE_SUFFIX}", context);
+ assertEquals("logs/archive/LOGBACK_trace_archive.log", result);
+ }
+
+
+ @Test(timeout = 1000)
+ public void stubstVarsShouldNotGoIntoInfiniteLoop() {
+ context.putProperty("v1", "if");
+ context.putProperty("v2", "${v3}");
+ context.putProperty("v3", "${v4}");
+ context.putProperty("v4", "${v2}c");
+
+ expectedException.expect(Exception.class);
+ OptionHelper.substVars(text, context);
+ }
+
+ @Test
+ public void nonCircularGraphShouldWork() {
+ context.putProperty("A", "${B} and ${C}");
+ context.putProperty("B", "${B1}");
+ context.putProperty("B1", "B1-value");
+ context.putProperty("C", "${C1} and ${B}");
+ context.putProperty("C1", "C1-value");
+
+ String result = OptionHelper.substVars("${A}", context);
+ assertEquals("B1-value and C1-value and B1-value", result);
+ }
+
+ @Test(timeout = 1000)
+ public void detectCircularReferences0() {
+ context.putProperty("A", "${A}");
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Circular variable reference detected while parsing input [${A} --> ${A}]");
+ OptionHelper.substVars("${A}", context);
+ }
+
+ @Test(timeout = 1000)
+ public void detectCircularReferences1() {
+ context.putProperty("A", "${A}a");
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Circular variable reference detected while parsing input [${A} --> ${A}]");
+ OptionHelper.substVars("${A}", context);
+ }
+
+ @Test(timeout = 1000)
+ public void detectCircularReferences2() {
+ context.putProperty("A", "${B}");
+ context.putProperty("B", "${C}");
+ context.putProperty("C", "${A}");
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Circular variable reference detected while parsing input [${A} --> ${B} --> ${C} --> ${A}]");
+ OptionHelper.substVars("${A}", context);
+ }
+
+
+ @Test
+ public void detectCircularReferencesInDefault() {
+ context.putProperty("A", "${B:-${A}}");
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Circular variable reference detected while parsing input [${A} --> ${B} --> ${A}]");
+ OptionHelper.substVars("${A}", context);
+ }
+
+ @Test(timeout = 1000)
+ public void detectCircularReferences3() {
+ context.putProperty("A", "${B}");
+ context.putProperty("B", "${C}");
+ context.putProperty("C", "${A}");
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Circular variable reference detected while parsing input [${B} --> ${C} --> ${A} --> ${B}]");
+ OptionHelper.substVars("${B} ", context);
+ }
+
+ @Test(timeout = 1000)
+ public void detectCircularReferences4() {
+ context.putProperty("A", "${B}");
+ context.putProperty("B", "${C}");
+ context.putProperty("C", "${A}");
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Circular variable reference detected while parsing input [${C} --> ${A} --> ${B} --> ${C}]");
+ OptionHelper.substVars("${C} and ${A}", context);
+ }
+
+ @Test
+ public void detectCircularReferences5() {
+ context.putProperty("A", "${B} and ${C}");
+ context.putProperty("B", "${B1}");
+ context.putProperty("B1", "B1-value");
+ context.putProperty("C", "${C1}");
+ context.putProperty("C1", "here's the loop: ${A}");
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Circular variable reference detected while parsing input [${A} --> ${C} --> ${C1} --> ${A}]");
+ String result = OptionHelper.substVars("${A}", context);
+ System.err.println(result);
+ }
+
+ @Test
+ public void defaultValueReferencingAVariable() {
+ context.putProperty("v1", "k1");
+ String result = OptionHelper.substVars("${undef:-${v1}}", context);
+ assertEquals("k1", result);
+ }
+
+ @Test
+ public void jackrabbit_standalone() {
+ String r = OptionHelper.substVars("${jackrabbit.log:-${repo:-jackrabbit}/log/jackrabbit.log}", context);
+ assertEquals("jackrabbit/log/jackrabbit.log", r);
+ }
+
+ @Test
+ public void doesNotThrowNullPointerExceptionForEmptyVariable() throws JoranException {
+ context.putProperty("var", "");
+ OptionHelper.substVars("${var}", context);
+
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/util/PackageTest.java
index d504aaa..926e28f 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/PackageTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,7 +18,13 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
- at SuiteClasses({ DurationTest.class, FileSizeTest.class, FileUtilTest.class, OptionHelperTest.class, StatusPrinterTest.class, TimeUtilTest.class,
- ContentTypeUtilTest.class, CharSequenceToRegexMapperTest.class })
+ at SuiteClasses({
+ DurationTest.class,
+ FileSizeTest.class,
+ FileUtilTest.class,
+ OptionHelperTest.class,
+ StatusPrinterTest.class,
+ TimeUtilTest.class,
+ ContentTypeUtilTest.class})
public class PackageTest {
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/ResilienceUtil.java b/logback-core/src/test/java/ch/qos/logback/core/util/ResilienceUtil.java
index e577511..585040f 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/ResilienceUtil.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/ResilienceUtil.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,35 +23,36 @@ import java.util.regex.Pattern;
public class ResilienceUtil {
- static public void verify(String logfile, String regexp, long totalSteps, double successRatioLowerBound) throws NumberFormatException, IOException {
- FileReader fr = new FileReader(logfile);
- BufferedReader br = new BufferedReader(fr);
- Pattern p = Pattern.compile(regexp);
- String line;
-
- int totalLines = 0;
- int oldNum = -1;
- int gaps = 0;
- while ((line = br.readLine()) != null) {
- Matcher m = p.matcher(line);
- if (m.matches()) {
- totalLines++;
- String g = m.group(1);
- int num = Integer.parseInt(g);
- if (oldNum != -1 && num != oldNum + 1) {
- gaps++;
- }
- oldNum = num;
- }
+
+ static public void verify(String logfile, String regexp, long totalSteps, double successRatioLowerBound) throws NumberFormatException, IOException {
+ FileReader fr = new FileReader(logfile);
+ BufferedReader br = new BufferedReader(fr);
+ Pattern p = Pattern.compile(regexp);
+ String line;
+
+ int totalLines = 0;
+ int oldNum = -1;
+ int gaps = 0;
+ while ((line = br.readLine()) != null) {
+ Matcher m = p.matcher(line);
+ if (m.matches()) {
+ totalLines++;
+ String g = m.group(1);
+ int num = Integer.parseInt(g);
+ if(oldNum != -1 && num != oldNum+1) {
+ gaps++;
}
- fr.close();
- br.close();
-
- int lowerLimit = (int) (totalSteps * successRatioLowerBound);
- assertTrue("totalLines=" + totalLines + " less than " + lowerLimit, totalLines > lowerLimit);
-
- // we want at least one gap indicating recuperation
- assertTrue("gaps=" + gaps + " less than 1", gaps >= 1);
-
+ oldNum = num;
+ }
}
+ fr.close();
+ br.close();
+
+ int lowerLimit = (int) (totalSteps*successRatioLowerBound);
+ assertTrue("totalLines="+totalLines+" less than "+lowerLimit, totalLines > lowerLimit);
+
+ // we want at least one gap indicating recuperation
+ assertTrue("gaps="+gaps+" less than 1", gaps >= 1);
+
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/StatusListenerConfigHelperTest.java b/logback-core/src/test/java/ch/qos/logback/core/util/StatusListenerConfigHelperTest.java
deleted file mode 100644
index 70c9b8d..0000000
--- a/logback-core/src/test/java/ch/qos/logback/core/util/StatusListenerConfigHelperTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package ch.qos.logback.core.util;
-
-import static org.junit.Assert.*;
-
-import java.util.List;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import ch.qos.logback.core.Context;
-import ch.qos.logback.core.ContextBase;
-import ch.qos.logback.core.status.OnConsoleStatusListener;
-import ch.qos.logback.core.status.StatusListener;
-import ch.qos.logback.core.status.StatusManager;
-
-public class StatusListenerConfigHelperTest {
-
- Context context = new ContextBase();
- StatusManager sm = context.getStatusManager();
-
- @Before
- public void setUp() throws Exception {
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
- @Test
- public void addOnConsoleListenerInstanceShouldNotStartSecondListener() {
- OnConsoleStatusListener ocl0 = new OnConsoleStatusListener();
- OnConsoleStatusListener ocl1 = new OnConsoleStatusListener();
-
- StatusListenerConfigHelper.addOnConsoleListenerInstance(context, ocl0);
- {
- List<StatusListener> listeners = sm.getCopyOfStatusListenerList();
- assertEquals(1, listeners.size());
- assertTrue(ocl0.isStarted());
- }
-
- // second listener should not have been started
- StatusListenerConfigHelper.addOnConsoleListenerInstance(context, ocl1);
- {
- List<StatusListener> listeners = sm.getCopyOfStatusListenerList();
- assertEquals(1, listeners.size());
- assertFalse(ocl1.isStarted());
- }
- }
-
-}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/StatusPrinterTest.java b/logback-core/src/test/java/ch/qos/logback/core/util/StatusPrinterTest.java
index 5d6f3ce..13f30ad 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/StatusPrinterTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/StatusPrinterTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -31,89 +31,90 @@ import ch.qos.logback.core.status.WarnStatus;
public class StatusPrinterTest {
- ByteArrayOutputStream outputStream;
- PrintStream ps;
-
- @Before
- public void setUp() throws Exception {
- outputStream = new ByteArrayOutputStream();
- ps = new PrintStream(outputStream);
- StatusPrinter.setPrintStream(ps);
- }
-
- @After
- public void tearDown() throws Exception {
- StatusPrinter.setPrintStream(System.out);
- ps = null;
- outputStream = null;
- }
-
- @Test
- public void testBasic() {
- Context context = new ContextBase();
- context.getStatusManager().add(new InfoStatus("test", this));
- StatusPrinter.print(context);
- String result = outputStream.toString();
- assertTrue(result.contains("|-INFO in " + this.getClass().getName()));
- }
-
- @Test
- public void testNested() {
- Status s0 = new ErrorStatus("test0", this);
- Status s1 = new InfoStatus("test1", this);
- Status s11 = new InfoStatus("test11", this);
- Status s12 = new InfoStatus("test12", this);
- s1.add(s11);
- s1.add(s12);
-
- Status s2 = new InfoStatus("test2", this);
- Status s21 = new InfoStatus("test21", this);
- Status s211 = new WarnStatus("test211", this);
-
- Status s22 = new InfoStatus("test22", this);
- s2.add(s21);
- s2.add(s22);
- s21.add(s211);
-
- Context context = new ContextBase();
- context.getStatusManager().add(s0);
- context.getStatusManager().add(s1);
- context.getStatusManager().add(s2);
-
- StatusPrinter.print(context);
- String result = outputStream.toString();
- assertTrue(result.contains("+ INFO in " + this.getClass().getName()));
- assertTrue(result.contains("+ WARN in " + this.getClass().getName()));
- assertTrue(result.contains(" |-WARN in " + this.getClass().getName()));
- }
-
- @Test
- public void testWithException() {
- Status s0 = new ErrorStatus("test0", this);
- Status s1 = new InfoStatus("test1", this, new Exception("testEx"));
- Status s11 = new InfoStatus("test11", this);
- Status s12 = new InfoStatus("test12", this);
- s1.add(s11);
- s1.add(s12);
-
- Status s2 = new InfoStatus("test2", this);
- Status s21 = new InfoStatus("test21", this);
- Status s211 = new WarnStatus("test211", this);
-
- Status s22 = new InfoStatus("test22", this);
- s2.add(s21);
- s2.add(s22);
- s21.add(s211);
-
- Context context = new ContextBase();
- context.getStatusManager().add(s0);
- context.getStatusManager().add(s1);
- context.getStatusManager().add(s2);
- StatusPrinter.print(context);
- String result = outputStream.toString();
- assertTrue(result.contains("|-ERROR in " + this.getClass().getName()));
- assertTrue(result.contains("+ INFO in " + this.getClass().getName()));
- assertTrue(result.contains("ch.qos.logback.core.util.StatusPrinterTest.testWithException"));
- }
-
+ ByteArrayOutputStream outputStream;
+ PrintStream ps;
+
+ @Before
+ public void setUp() throws Exception {
+ outputStream = new ByteArrayOutputStream();
+ ps = new PrintStream(outputStream);
+ StatusPrinter.setPrintStream(ps);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ StatusPrinter.setPrintStream(System.out);
+ ps = null;
+ outputStream = null;
+ }
+
+ @Test
+ public void testBasic() {
+ Context context = new ContextBase();
+ context.getStatusManager().add(new InfoStatus("test", this));
+ StatusPrinter.print(context);
+ String result = outputStream.toString();
+ assertTrue(result.contains("|-INFO in "+this.getClass().getName()));
+ }
+
+ @Test
+ public void testNested() {
+ Status s0 = new ErrorStatus("test0", this);
+ Status s1 = new InfoStatus("test1", this);
+ Status s11 = new InfoStatus("test11", this);
+ Status s12 = new InfoStatus("test12", this);
+ s1.add(s11);
+ s1.add(s12);
+
+ Status s2 = new InfoStatus("test2", this);
+ Status s21 = new InfoStatus("test21", this);
+ Status s211 = new WarnStatus("test211", this);
+
+ Status s22 = new InfoStatus("test22", this);
+ s2.add(s21);
+ s2.add(s22);
+ s21.add(s211);
+
+
+ Context context = new ContextBase();
+ context.getStatusManager().add(s0);
+ context.getStatusManager().add(s1);
+ context.getStatusManager().add(s2);
+
+ StatusPrinter.print(context);
+ String result = outputStream.toString();
+ assertTrue(result.contains("+ INFO in "+this.getClass().getName()));
+ assertTrue(result.contains("+ WARN in "+this.getClass().getName()));
+ assertTrue(result.contains(" |-WARN in "+this.getClass().getName()));
+ }
+
+ @Test
+ public void testWithException() {
+ Status s0 = new ErrorStatus("test0", this);
+ Status s1 = new InfoStatus("test1", this, new Exception("testEx"));
+ Status s11 = new InfoStatus("test11", this);
+ Status s12 = new InfoStatus("test12", this);
+ s1.add(s11);
+ s1.add(s12);
+
+ Status s2 = new InfoStatus("test2", this);
+ Status s21 = new InfoStatus("test21", this);
+ Status s211 = new WarnStatus("test211", this);
+
+ Status s22 = new InfoStatus("test22", this);
+ s2.add(s21);
+ s2.add(s22);
+ s21.add(s211);
+
+ Context context = new ContextBase();
+ context.getStatusManager().add(s0);
+ context.getStatusManager().add(s1);
+ context.getStatusManager().add(s2);
+ StatusPrinter.print(context);
+ String result = outputStream.toString();
+ assertTrue(result.contains("|-ERROR in "+this.getClass().getName()));
+ assertTrue(result.contains("+ INFO in "+this.getClass().getName()));
+ assertTrue(result.contains("ch.qos.logback.core.util.StatusPrinterTest.testWithException"));
+ }
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/StringCollectionUtilTest.java b/logback-core/src/test/java/ch/qos/logback/core/util/StringCollectionUtilTest.java
index 44c1a5d..a99ba75 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/StringCollectionUtilTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/StringCollectionUtilTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,6 +22,7 @@ import java.util.List;
import org.junit.Test;
+
/**
* Unit tests for {@link StringCollectionUtil}.
*
@@ -29,53 +30,53 @@ import org.junit.Test;
*/
public class StringCollectionUtilTest {
- @Test
- public void testRetainMatchingWithNoPatterns() throws Exception {
- Collection<String> values = stringToList("A");
- StringCollectionUtil.retainMatching(values);
- assertTrue(values.contains("A"));
- }
+ @Test
+ public void testRetainMatchingWithNoPatterns() throws Exception {
+ Collection<String> values = stringToList("A");
+ StringCollectionUtil.retainMatching(values);
+ assertTrue(values.contains("A"));
+ }
- @Test
- public void testRetainMatchingWithMatchingPattern() throws Exception {
- Collection<String> values = stringToList("A");
- StringCollectionUtil.retainMatching(values, "A");
- assertTrue(values.contains("A"));
- }
+ @Test
+ public void testRetainMatchingWithMatchingPattern() throws Exception {
+ Collection<String> values = stringToList("A");
+ StringCollectionUtil.retainMatching(values, "A");
+ assertTrue(values.contains("A"));
+ }
- @Test
- public void testRetainMatchingWithNoMatchingPattern() throws Exception {
- Collection<String> values = stringToList("A");
- StringCollectionUtil.retainMatching(values, "B");
- assertTrue(values.isEmpty());
- }
+ @Test
+ public void testRetainMatchingWithNoMatchingPattern() throws Exception {
+ Collection<String> values = stringToList("A");
+ StringCollectionUtil.retainMatching(values, "B");
+ assertTrue(values.isEmpty());
+ }
- @Test
- public void testRemoveMatchingWithNoPatterns() throws Exception {
- Collection<String> values = stringToList("A");
- StringCollectionUtil.removeMatching(values);
- assertTrue(values.contains("A"));
- }
+ @Test
+ public void testRemoveMatchingWithNoPatterns() throws Exception {
+ Collection<String> values = stringToList("A");
+ StringCollectionUtil.removeMatching(values);
+ assertTrue(values.contains("A"));
+ }
- @Test
- public void testRemoveMatchingWithMatchingPattern() throws Exception {
- Collection<String> values = stringToList("A");
- StringCollectionUtil.removeMatching(values, "A");
- assertTrue(values.isEmpty());
- }
+ @Test
+ public void testRemoveMatchingWithMatchingPattern() throws Exception {
+ Collection<String> values = stringToList("A");
+ StringCollectionUtil.removeMatching(values, "A");
+ assertTrue(values.isEmpty());
+ }
- @Test
- public void testRemoveMatchingWithNoMatchingPattern() throws Exception {
- Collection<String> values = stringToList("A");
- StringCollectionUtil.removeMatching(values, "B");
- assertTrue(values.contains("A"));
- }
+ @Test
+ public void testRemoveMatchingWithNoMatchingPattern() throws Exception {
+ Collection<String> values = stringToList("A");
+ StringCollectionUtil.removeMatching(values, "B");
+ assertTrue(values.contains("A"));
+ }
- @SuppressWarnings("unchecked")
- private List<String> stringToList(String... values) {
- List<String> result = new ArrayList<String>(values.length);
- result.addAll(Arrays.asList(values));
- return result;
- }
+ @SuppressWarnings("unchecked")
+ private List<String> stringToList(String... values) {
+ List<String> result = new ArrayList<String>(values.length);
+ result.addAll(Arrays.asList(values));
+ return result;
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/TeeOutputStream.java b/logback-core/src/test/java/ch/qos/logback/core/util/TeeOutputStream.java
index a331931..0184262 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/TeeOutputStream.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/TeeOutputStream.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,26 +27,26 @@ import java.io.PrintStream;
*/
public class TeeOutputStream extends OutputStream {
- final PrintStream targetPS;
- public final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final PrintStream targetPS;
+ public final ByteArrayOutputStream baos = new ByteArrayOutputStream();
- public TeeOutputStream(PrintStream targetPS) {
- // allow for null arguments
- this.targetPS = targetPS;
- }
+ public TeeOutputStream(PrintStream targetPS) {
+ // allow for null arguments
+ this.targetPS = targetPS;
+ }
- public void write(int b) throws IOException {
- baos.write(b);
- if (targetPS != null) {
- targetPS.write(b);
- }
+ public void write(int b) throws IOException {
+ baos.write(b);
+ if(targetPS != null) {
+ targetPS.write(b);
}
+ }
- public String toString() {
- return baos.toString();
- }
+ public String toString() {
+ return baos.toString();
+ }
- public byte[] toByteArray() {
- return baos.toByteArray();
- }
+ public byte[] toByteArray() {
+ return baos.toByteArray();
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/TimeUtilTest.java b/logback-core/src/test/java/ch/qos/logback/core/util/TimeUtilTest.java
index 648f6c4..8eb1fc0 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/TimeUtilTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/TimeUtilTest.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,101 +21,103 @@ import java.util.TimeZone;
import org.junit.Test;
-public class TimeUtilTest {
-
- @Test
- public void testSecond() {
- // Mon Nov 20 18:05:17,522 CET 2006
- long now = 1164042317522L;
- // Mon Nov 20 18:05:18,000 CET 2006
- long expected = 1164042318000L;
- long computed = TimeUtil.computeStartOfNextSecond(now);
- assertEquals(expected - now, 478);
- assertEquals(expected, computed);
- }
-
- @Test
- public void testMinute() {
- // Mon Nov 20 18:05:17,522 CET 2006
- long now = 1164042317522L;
- // Mon Nov 20 18:06:00 CET 2006
- long expected = 1164042360000L;
-
- long computed = TimeUtil.computeStartOfNextMinute(now);
- assertEquals(expected - now, 1000 * 42 + 478);
- assertEquals(expected, computed);
- }
-
- @Test
- public void testHour() {
- // Mon Nov 20 18:05:17,522 GMT 2006
- long now = 1164045917522L;
- now = correctBasedOnTimeZone(now);
- // Mon Nov 20 19:00:00 GMT 2006
- long expected = 1164049200000L;
- expected = correctBasedOnTimeZone(expected);
-
- long computed = TimeUtil.computeStartOfNextHour(now);
- assertEquals(expected - now, 1000 * (42 + 60 * 54) + 478);
- assertEquals(expected, computed);
- }
-
- @Test
- public void testDay() {
- // Mon Nov 20 18:05:17 GMT 2006
- long now = 1164045917522L;
- now = correctBasedOnTimeZone(now);
- // Tue Nov 21 00:00:00 GMT 2006
- long expected = 1164067200000L;
- expected = correctBasedOnTimeZone(expected);
- long computed = TimeUtil.computeStartOfNextDay(now);
-
- assertEquals(expected - now, 1000 * (3600 * 5 + 60 * 54 + 42) + 478);
- assertEquals(expected, computed);
+public class TimeUtilTest {
+
+ @Test
+ public void testSecond() {
+ // Mon Nov 20 18:05:17,522 CET 2006
+ long now = 1164042317522L;
+ // Mon Nov 20 18:05:18,000 CET 2006
+ long expected = 1164042318000L;
+ long computed = TimeUtil.computeStartOfNextSecond(now);
+ assertEquals(expected - now, 478);
+ assertEquals(expected, computed);
+ }
+
+ @Test
+ public void testMinute() {
+ // Mon Nov 20 18:05:17,522 CET 2006
+ long now = 1164042317522L;
+ // Mon Nov 20 18:06:00 CET 2006
+ long expected = 1164042360000L;
+
+ long computed = TimeUtil.computeStartOfNextMinute(now);
+ assertEquals(expected - now, 1000 * 42 + 478);
+ assertEquals(expected, computed);
+ }
+
+ @Test
+ public void testHour() {
+ // Mon Nov 20 18:05:17,522 GMT 2006
+ long now = 1164045917522L;
+ now = correctBasedOnTimeZone(now);
+ // Mon Nov 20 19:00:00 GMT 2006
+ long expected = 1164049200000L;
+ expected = correctBasedOnTimeZone(expected);
+
+ long computed = TimeUtil.computeStartOfNextHour(now);
+ assertEquals(expected - now, 1000 * (42 + 60 * 54) + 478);
+ assertEquals(expected, computed);
+ }
+
+ @Test
+ public void testDay() {
+ // Mon Nov 20 18:05:17 GMT 2006
+ long now = 1164045917522L;
+ now = correctBasedOnTimeZone(now);
+ // Tue Nov 21 00:00:00 GMT 2006
+ long expected = 1164067200000L;
+ expected = correctBasedOnTimeZone(expected);
+ long computed = TimeUtil.computeStartOfNextDay(now);
+
+ assertEquals(expected - now, 1000 * (3600 * 5 + 60 * 54 + 42) + 478);
+ assertEquals(expected, computed);
+ }
+
+ @Test
+ public void testWeek() {
+ // Mon Nov 20 18:05:17 GMT 2006
+ long now = 1164045917522L;
+ now = correctBasedOnTimeZone(now);
+ // Sun Nov 26 00:00:00 GMT 2006
+ long expected = 1164499200000L;
+ expected = correctBasedOnTimeZone(expected);
+
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(new Date(now));
+
+ int dayOffset = cal.getFirstDayOfWeek() - Calendar.SUNDAY;
+ if (dayOffset != 0) {
+ expected += 24L * 3600 * 1000 * (cal.getFirstDayOfWeek() - Calendar.SUNDAY);
}
- @Test
- public void testWeek() {
- // Mon Nov 20 18:05:17 GMT 2006
- long now = 1164045917522L;
- now = correctBasedOnTimeZone(now);
- // Sun Nov 26 00:00:00 GMT 2006
- long expected = 1164499200000L;
- expected = correctBasedOnTimeZone(expected);
-
- Calendar cal = Calendar.getInstance();
- cal.setTime(new Date(now));
-
- int dayOffset = cal.getFirstDayOfWeek() - Calendar.SUNDAY;
- if (dayOffset != 0) {
- expected += 24L * 3600 * 1000 * (cal.getFirstDayOfWeek() - Calendar.SUNDAY);
- }
-
- long computed = TimeUtil.computeStartOfNextWeek(now);
- // System.out.println("now "+new Date(now));
- // System.out.println("computed "+new Date(computed));
- // System.out.println("expected "+new Date(expected));
- assertEquals(expected - now, 1000 * (3600 * (5 + 24 * (5 + dayOffset)) + 60 * 54 + 42) + 478);
- assertEquals(expected, computed);
- }
-
- @Test
- public void testMonth() {
- // Mon Nov 20 18:05:17 GMT 2006
- long now = 1164045917522L;
- now = correctBasedOnTimeZone(now);
- // Fri Dec 01 00:00:00 GMT 2006
- long expected = 1164931200000L;
- expected = correctBasedOnTimeZone(expected);
-
- long computed = TimeUtil.computeStartOfNextMonth(now);
- assertEquals(expected - now, 1000 * (3600 * (5 + 24 * 10) + 60 * 54 + 42) + 478);
- assertEquals(expected, computed);
- }
-
- private long correctBasedOnTimeZone(long gmtLong) {
- int offset = TimeZone.getDefault().getRawOffset();
- return gmtLong - offset;
- }
+ long computed = TimeUtil.computeStartOfNextWeek(now);
+ // System.out.println("now "+new Date(now));
+ // System.out.println("computed "+new Date(computed));
+ // System.out.println("expected "+new Date(expected));
+ assertEquals(expected - now,
+ 1000 * (3600 * (5 + 24 * (5 + dayOffset)) + 60 * 54 + 42) + 478);
+ assertEquals(expected, computed);
+ }
+
+ @Test
+ public void testMonth() {
+ // Mon Nov 20 18:05:17 GMT 2006
+ long now = 1164045917522L;
+ now = correctBasedOnTimeZone(now);
+ // Fri Dec 01 00:00:00 GMT 2006
+ long expected = 1164931200000L;
+ expected = correctBasedOnTimeZone(expected);
+
+ long computed = TimeUtil.computeStartOfNextMonth(now);
+ assertEquals(expected - now,
+ 1000 * (3600 * (5 + 24 * 10) + 60 * 54 + 42) + 478);
+ assertEquals(expected, computed);
+ }
+
+ private long correctBasedOnTimeZone(long gmtLong) {
+ int offset = TimeZone.getDefault().getRawOffset();
+ return gmtLong - offset;
+ }
}
diff --git a/logback-examples/pom.xml b/logback-examples/pom.xml
index 27c55c3..adeaf40 100644
--- a/logback-examples/pom.xml
+++ b/logback-examples/pom.xml
@@ -1,54 +1,78 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-parent</artifactId>
- <version>1.1.9</version>
+ <version>1.1.2</version>
</parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>ch.qos.logback</groupId>
<artifactId>logback-examples</artifactId>
<packaging>jar</packaging>
<name>Logback Examples Module</name>
<description>logback-examples module</description>
+ <url>http://logback.qos.ch</url>
+
+ <licenses>
+ <license>
+ <name>Eclipse Public License - v 1.0</name>
+ <url>http://www.eclipse.org/legal/epl-v10.html</url>
+ </license>
+
+ <license>
+ <name>GNU Lesser General Public License</name>
+ <url>http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</url>
+ </license>
+ </licenses>
+
<dependencies>
+
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
+
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
+
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
</dependency>
+
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-ext</artifactId>
<version>${slf4j.version}</version>
</dependency>
+
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
- <version>1.2.17</version>
+ <version>1.2.14</version>
</dependency>
+
+
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
+
<dependency>
<groupId>org.fusesource.jansi</groupId>
<artifactId>jansi</artifactId>
<optional>true</optional>
</dependency>
+
</dependencies>
<build>
@@ -61,43 +85,36 @@
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
- <id>copy</id>
<phase>package</phase>
- <goals>
- <goal>copy</goal>
- </goals>
<configuration>
- <artifactItems>
- <artifactItem>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>${slf4j.version}</version>
- <overWrite>false</overWrite>
- <outputDirectory>${project.basedir}/lib</outputDirectory>
- </artifactItem>
- </artifactItems>
+ <tasks>
+ <mkdir dir="lib/"/>
+ <property name="slf4jJAR"
+ value="${settings.localRepository}/org/slf4j/slf4j-api/${slf4j.version}/slf4j-api-${slf4j.version}.jar"/>
+ <echo>Copying ${slf4jJAR} to lib/</echo>
+ <delete>
+ <fileset dir="lib/" includes="slf4j-*SNAPSHOT.jar"/>
+ </delete>
+ <copy file="${slf4jJAR}" todir="lib/"/>
+ </tasks>
</configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
</execution>
</executions>
</plugin>
-
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>cobertura-maven-plugin</artifactId>
- <version>${cobertura.maven.plugin.version}</version>
- <configuration>
- <instrumentation>
- <excludes>
- <exclude>chapters/**/*.class</exclude>
- </excludes>
- </instrumentation>
- </configuration>
- </plugin>
-
-
- </plugins>
+ </plugins>
</build>
</project>
\ No newline at end of file
diff --git a/logback-examples/setClasspath.cmd b/logback-examples/setClasspath.cmd
index 8d5429d..45bd250 100644
--- a/logback-examples/setClasspath.cmd
+++ b/logback-examples/setClasspath.cmd
@@ -5,9 +5,9 @@ REM This script will add logback jars to your classpath.
set LB_HOME=c:/SET/THIS/PARAMETER/TO/THE/FOLDER/WHERE/YOU/INSTALLED/LOGBACK
REM echo %LB_HOME%
-set CLASSPATH=%CLASSPATH%;%LB_HOME%/logback-classic-1.1.9.jar
-set CLASSPATH=%CLASSPATH%;%LB_HOME%/logback-core-1.1.9.jar
-set CLASSPATH=%CLASSPATH%;%LB_HOME%/logback-examples/logback-examples-1.1.9.jar
-set CLASSPATH=%CLASSPATH%;%LB_HOME%/logback-examples/lib/slf4j-api-1.7.22.jar
+set CLASSPATH=%CLASSPATH%;%LB_HOME%/logback-classic-${project.version}.jar
+set CLASSPATH=%CLASSPATH%;%LB_HOME%/logback-core-${project.version}.jar
+set CLASSPATH=%CLASSPATH%;%LB_HOME%/logback-examples/logback-examples-${project.version}.jar
+set CLASSPATH=%CLASSPATH%;%LB_HOME%/logback-examples/lib/slf4j-api-${slf4j.version}.jar
REM echo %CLASSPATH%
diff --git a/logback-examples/setClasspath.sh b/logback-examples/setClasspath.sh
index b4cf8b9..5180c1c 100644
--- a/logback-examples/setClasspath.sh
+++ b/logback-examples/setClasspath.sh
@@ -6,10 +6,10 @@
LB_HOME=/SET/THIS/PARAMETER/TO/THE/DIRECTORY/WHERE/YOU/INSTALLED/LOGBACK
-CLASSPATH="${CLASSPATH}:${LB_HOME}/logback-classic-1.1.9.jar"
-CLASSPATH="${CLASSPATH}:${LB_HOME}/logback-core-1.1.9.jar"
-CLASSPATH="${CLASSPATH}:${LB_HOME}/logback-examples/logback-examples-1.1.9.jar"
-CLASSPATH="${CLASSPATH}:${LB_HOME}/logback-examples/lib/slf4j-api-1.7.22.jar"
+CLASSPATH="${CLASSPATH}:${LB_HOME}/logback-classic-1.1.2.jar"
+CLASSPATH="${CLASSPATH}:${LB_HOME}/logback-core-1.1.2.jar"
+CLASSPATH="${CLASSPATH}:${LB_HOME}/logback-examples/logback-examples-1.1.2.jar"
+CLASSPATH="${CLASSPATH}:${LB_HOME}/logback-examples/lib/slf4j-api-1.7.6.jar"
export CLASSPATH
diff --git a/logback-examples/src/main/java/chapters/appenders/ConfigurationTester.java b/logback-examples/src/main/java/chapters/appenders/ConfigurationTester.java
index 9a8b222..10d9c67 100644
--- a/logback-examples/src/main/java/chapters/appenders/ConfigurationTester.java
+++ b/logback-examples/src/main/java/chapters/appenders/ConfigurationTester.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,40 +20,41 @@ import org.slf4j.MDC;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.util.StatusPrinter;
import chapters.appenders.sub.sample.Bar;
/**
*
- * This java "application" configures logback using a configuration file
- * supplied on the class path and logs a few times.
+ * This class can be used to check the result of a configuration file.
*
* @author Sébastien Pennec
*/
public class ConfigurationTester {
- public static void main(String[] args) throws InterruptedException {
- Logger logger = (Logger) LoggerFactory.getLogger(ConfigurationTester.class);
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ public static void main(String[] args) throws InterruptedException {
+ Logger logger = (Logger) LoggerFactory.getLogger(ConfigurationTester.class);
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- lc.reset();
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- je.printStackTrace();
- }
- // Next call forces status messages to be printed on the console
- // StatusPrinter.print(lc);
+ try {
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ lc.reset();
+ configurator.doConfigure(args[0]);
+ } catch (JoranException je) {
+ je.printStackTrace();
+ }
+ // After we've called Joran, let's print information about the
+ // internal status of logback
+ StatusPrinter.print(lc);
- logger.debug("**Hello {}", new Bar());
- MDC.put("testKey", "testValueFromMDC");
- MDC.put("testKey2", "value2");
- for (int i = 0; i < 64; i++) {
- logger.debug("logging statement {}", i);
- Thread.sleep(100);
- }
- Bar bar = new Bar();
- bar.createLoggingRequest();
+ logger.debug("**Hello {}", new Bar());
+ MDC.put("testKey", "testValueFromMDC");
+ MDC.put("testKey2", "value2");
+ for (int i = 0; i < 10; i++) {
+ logger.debug("logging statement " + i);
+ Thread.sleep(100);
}
+ Bar bar = new Bar();
+ bar.createLoggingRequest();
+ }
}
diff --git a/logback-examples/src/main/java/chapters/appenders/CountingConsoleAppender.java b/logback-examples/src/main/java/chapters/appenders/CountingConsoleAppender.java
index 731bf7a..abe40c7 100644
--- a/logback-examples/src/main/java/chapters/appenders/CountingConsoleAppender.java
+++ b/logback-examples/src/main/java/chapters/appenders/CountingConsoleAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,54 +19,55 @@ import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
-public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
- static int DEFAULT_LIMIT = 10;
- int counter = 0;
- int limit = DEFAULT_LIMIT;
- PatternLayoutEncoder encoder;
+public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
+ static int DEFAULT_LIMIT = 10;
+ int counter = 0;
+ int limit = DEFAULT_LIMIT;
+
+ PatternLayoutEncoder encoder;
+
+ public void setLimit(int limit) {
+ this.limit = limit;
+ }
- public void setLimit(int limit) {
- this.limit = limit;
+ public int getLimit() {
+ return limit;
+ }
+
+ @Override
+ public void start() {
+ if (this.encoder == null) {
+ addError("No encoder set for the appender named ["+ name +"].");
+ return;
}
-
- public int getLimit() {
- return limit;
+
+ try {
+ encoder.init(System.out);
+ } catch (IOException e) {
}
+ super.start();
+ }
- @Override
- public void start() {
- if (this.encoder == null) {
- addError("No encoder set for the appender named [" + name + "].");
- return;
- }
-
- try {
- encoder.init(System.out);
- } catch (IOException e) {
- }
- super.start();
+ public void append(ILoggingEvent event) {
+ if (counter >= limit) {
+ return;
}
-
- public void append(ILoggingEvent event) {
- if (counter >= limit) {
- return;
- }
- // output the events as formatted by the wrapped layout
- try {
- this.encoder.doEncode(event);
- } catch (IOException e) {
- }
-
- // prepare for next event
- counter++;
+ // output the events as formatted by the wrapped layout
+ try {
+ this.encoder.doEncode(event);
+ } catch (IOException e) {
}
- public PatternLayoutEncoder getEncoder() {
- return encoder;
- }
+ // prepare for next event
+ counter++;
+ }
- public void setEncoder(PatternLayoutEncoder encoder) {
- this.encoder = encoder;
- }
+ public PatternLayoutEncoder getEncoder() {
+ return encoder;
+ }
+
+ public void setEncoder(PatternLayoutEncoder encoder) {
+ this.encoder = encoder;
+ }
}
diff --git a/logback-examples/src/main/java/chapters/appenders/IO.java b/logback-examples/src/main/java/chapters/appenders/IO.java
index c705285..2213fbb 100644
--- a/logback-examples/src/main/java/chapters/appenders/IO.java
+++ b/logback-examples/src/main/java/chapters/appenders/IO.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,152 +22,160 @@ import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.encoder.EchoEncoder;
public class IO extends Thread {
- static String msgLong = "ABCDEGHIJKLMNOPQRSTUVWXYZabcdeghijklmnopqrstuvwxyz1234567890";
- static String msgShort = "Hello";
- static boolean scarceCPU;
- static int numThreads;
- static long l;
- static boolean longMessage;
- long len;
- boolean buffered;
- boolean immediateFlush;
- Logger logger;
- LoggerContext context;
- double throughput;
-
- public IO(boolean _buffered, boolean _immediateFlush, long _len) {
- this.len = _len;
- this.buffered = _buffered;
- this.immediateFlush = _immediateFlush;
- context = new LoggerContext();
- logger = context.getLogger("logger-" + getName());
-
- // A FileAppender is created according to the buffering and
- // immediate flush setting of this IO instance.
- FileAppender<ILoggingEvent> fa = new FileAppender<ILoggingEvent>();
-
- if (longMessage) {
- PatternLayoutEncoder pa = new PatternLayoutEncoder();
- pa.setPattern("%r %5p %c [%t] - %m%n");
- pa.setContext(context);
- pa.start();
- fa.setEncoder(pa);
- } else {
- fa.setEncoder(new EchoEncoder<ILoggingEvent>());
- }
-
- fa.setFile(getName() + ".log");
- fa.setAppend(false);
- fa.setContext(context);
- fa.start();
-
+ static String msgLong = "ABCDEGHIJKLMNOPQRSTUVWXYZabcdeghijklmnopqrstuvwxyz1234567890";
+ static String msgShort = "Hello";
+ static boolean scarceCPU;
+ static int numThreads;
+ static long l;
+ static boolean longMessage;
+ long len;
+ boolean buffered;
+ boolean immediateFlush;
+ Logger logger;
+ LoggerContext context;
+ double throughput;
+
+ public IO(boolean _buffered, boolean _immediateFlush, long _len) {
+ this.len = _len;
+ this.buffered = _buffered;
+ this.immediateFlush = _immediateFlush;
+ context = new LoggerContext();
+ logger = context.getLogger("logger-" + getName());
+
+ // A FileAppender is created according to the buffering and
+ // immediate flush setting of this IO instance.
+ FileAppender<ILoggingEvent> fa = new FileAppender<ILoggingEvent>();
+
+ if (longMessage) {
+ PatternLayoutEncoder pa = new PatternLayoutEncoder();
+ pa.setPattern("%r %5p %c [%t] - %m%n");
+ pa.setContext(context);
+ pa.start();
+ fa.setEncoder(pa);
+ } else {
+ fa.setEncoder(new EchoEncoder<ILoggingEvent>());
}
- public static void main(String[] argv) throws Exception {
- if (argv.length != 4) {
- usage("Wrong number of arguments.");
- }
-
- l = Integer.parseInt(argv[0]);
- numThreads = Integer.parseInt(argv[1]);
- scarceCPU = "true".equalsIgnoreCase(argv[2]);
- longMessage = "long".equalsIgnoreCase(argv[3]);
+ fa.setFile(getName() + ".log");
+ fa.setAppend(false);
+ fa.setContext(context);
+ fa.start();
+
+ }
- // ----------------------------------------------------
- // first test with unbuffered IO and immediate flushing
- perfCase(false, true, l);
+ public static void main(String[] argv) throws Exception {
+ if (argv.length != 4) {
+ usage("Wrong number of arguments.");
+ }
- // ----------------------------------------------------
- // Second test with unbuffered IO and no immediate flushing
- perfCase(false, false, l);
+ l = Integer.parseInt(argv[0]);
+ numThreads = Integer.parseInt(argv[1]);
+ scarceCPU = "true".equalsIgnoreCase(argv[2]);
+ longMessage = "long".equalsIgnoreCase(argv[3]);
+
+ // ----------------------------------------------------
+ // first test with unbuffered IO and immediate flushing
+ perfCase(false, true, l);
+
+ // ----------------------------------------------------
+ // Second test with unbuffered IO and no immediate flushing
+ perfCase(false, false, l);
+
+ // ----------------------------------------------------
+ // Third test with buffered IO and no immediate flushing
+ perfCase(true, false, l);
+
+ // There is no fourth test as buffered IO and immediate flushing
+ // do not make sense.
+ }
+
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + IO.class.getName() +
+ " runLength numThreads scarceCPU (short|long)\n" +
+ " runLength (integer) the number of logs to generate perthread\n" +
+ " numThreads (integer) the number of threads.\n" +
+ " scarceCPU (boolean) if true an additional CPU intensive thread is created\n" +
+ " (short|long) length of log messages.");
+ System.exit(1);
+ }
+
+ static void perfCase(boolean buffered, boolean immediateFlush, long len)
+ throws Exception {
+ IO[] threads = new IO[numThreads];
+ Counter counterThread = null;
+
+ if (scarceCPU) {
+ counterThread = new Counter();
+ counterThread.start();
+ }
- // ----------------------------------------------------
- // Third test with buffered IO and no immediate flushing
- perfCase(true, false, l);
+ // First create the threads
+ for (int i = 0; i < numThreads; i++) {
+ threads[i] = new IO(buffered, immediateFlush, len);
+ }
- // There is no fourth test as buffered IO and immediate flushing
- // do not make sense.
+ // then start them
+ for (int i = 0; i < numThreads; i++) {
+ threads[i].start();
}
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + IO.class.getName() + " runLength numThreads scarceCPU (short|long)\n"
- + " runLength (integer) the number of logs to generate perthread\n" + " numThreads (integer) the number of threads.\n"
- + " scarceCPU (boolean) if true an additional CPU intensive thread is created\n" + " (short|long) length of log messages.");
- System.exit(1);
+ // wait for them to processPriorToRemoval, compute the average throughput
+ double sum = 0;
+
+ for (int i = 0; i < numThreads; i++) {
+ threads[i].join();
+ sum += threads[i].throughput;
}
- static void perfCase(boolean buffered, boolean immediateFlush, long len) throws Exception {
- IO[] threads = new IO[numThreads];
- Counter counterThread = null;
-
- if (scarceCPU) {
- counterThread = new Counter();
- counterThread.start();
- }
-
- // First create the threads
- for (int i = 0; i < numThreads; i++) {
- threads[i] = new IO(buffered, immediateFlush, len);
- }
-
- // then start them
- for (int i = 0; i < numThreads; i++) {
- threads[i].start();
- }
-
- // wait for them to processPriorToRemoval, compute the average throughput
- double sum = 0;
-
- for (int i = 0; i < numThreads; i++) {
- threads[i].join();
- sum += threads[i].throughput;
- }
-
- if (scarceCPU) {
- // setting the interrupted field will cause counterThread to processPriorToRemoval
- counterThread.interrupted = true;
- counterThread.join();
- }
-
- System.out.println("On average throughput of " + (sum / numThreads) * 1000 + " logs per microsecond.");
- System.out.println("------------------------------------------------");
+ if (scarceCPU) {
+ // setting the interrupted field will cause counterThread to processPriorToRemoval
+ counterThread.interrupted = true;
+ counterThread.join();
}
- public void run() {
- String msg = msgShort;
+ System.out.println("On average throughput of " + (sum / numThreads)*1000 +
+ " logs per microsecond.");
+ System.out.println("------------------------------------------------");
+ }
- if (longMessage) {
- msg = msgLong;
- }
+ public void run() {
+ String msg = msgShort;
- long before = System.nanoTime();
+ if (longMessage) {
+ msg = msgLong;
+ }
- for (int i = 0; i < len; i++) {
- logger.debug(msg);
- }
+ long before = System.nanoTime();
- throughput = (len * 1.0) / (System.nanoTime() - before);
- System.out.println(getName() + ", buffered: " + buffered + ", immediateFlush: " + immediateFlush + ", throughput: " + throughput
- + " logs per nanosecond.");
+ for (int i = 0; i < len; i++) {
+ logger.debug(msg);
}
+
+ throughput = (len * 1.0) / (System.nanoTime() - before);
+ System.out.println(getName() + ", buffered: " + buffered +
+ ", immediateFlush: " + immediateFlush + ", throughput: " + throughput +
+ " logs per nanosecond.");
+ }
}
-class Counter extends Thread {
- public boolean interrupted = false;
- public double counter = 0;
- public void run() {
- long before = System.nanoTime();
+class Counter extends Thread {
+ public boolean interrupted = false;
+ public double counter = 0;
- while (!interrupted) {
- if (counter % 1000 == 0) {
- Thread.yield();
- }
- counter += 1.0;
- }
+ public void run() {
+ long before = System.nanoTime();
- double tput = (counter * 1.0) / (System.nanoTime() - before);
- System.out.println("Counter thread " + getName() + " incremented counter by " + tput + " per nanosecond.");
+ while (!interrupted) {
+ if(counter % 1000 == 0) {
+ Thread.yield();
+ }
+ counter += 1.0;
}
+
+ double tput = (counter * 1.0) / (System.nanoTime() - before);
+ System.out.println("Counter thread " + getName() +
+ " incremented counter by " + tput + " per nanosecond.");
+ }
}
diff --git a/logback-examples/src/main/java/chapters/appenders/IOPerformance.java b/logback-examples/src/main/java/chapters/appenders/IOPerformance.java
index 0b9d152..ec355cc 100644
--- a/logback-examples/src/main/java/chapters/appenders/IOPerformance.java
+++ b/logback-examples/src/main/java/chapters/appenders/IOPerformance.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,136 +25,141 @@ import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.util.StatusPrinter;
public class IOPerformance extends Thread {
- static String MSG = "ABCDEGHIJKLMNOPQRSTUVWXYZabcdeghijklmnopqrstuvwxyz1234567890";
- static String LOG_FILE;
- public static String PARALLEL_FILE;
-
- static int NUM_THREADS = 1;
- static long l;
- long len;
- boolean immediateFlush;
- Logger logger;
- LoggerContext context;
- double throughput;
-
- public IOPerformance(boolean _immediateFlush, long _len) {
- this.len = _len;
- this.immediateFlush = _immediateFlush;
- context = new LoggerContext();
- logger = context.getLogger("logger-" + getName());
-
- // A FileAppender is created according to the buffering and
- // immediate flush setting of this IO instance.
- FileAppender<ILoggingEvent> fa = new FileAppender<ILoggingEvent>();
- fa.setName("FILE");
- PatternLayoutEncoder pa = new PatternLayoutEncoder();
- pa.setPattern("%r %5p %c [%t] - %m%n");
- pa.setContext(context);
- pa.start();
- fa.setEncoder(pa);
-
- fa.setFile(LOG_FILE);
- fa.setAppend(true);
- fa.setContext(context);
- fa.start();
-
- ((ch.qos.logback.classic.Logger) logger).addAppender(fa);
-
- StatusPrinter.print(context);
+ static String MSG = "ABCDEGHIJKLMNOPQRSTUVWXYZabcdeghijklmnopqrstuvwxyz1234567890";
+ static String LOG_FILE;
+ public static String PARALLEL_FILE;
+
+ static int NUM_THREADS = 1;
+ static long l;
+ long len;
+ boolean immediateFlush;
+ Logger logger;
+ LoggerContext context;
+ double throughput;
+
+ public IOPerformance(boolean _immediateFlush, long _len) {
+ this.len = _len;
+ this.immediateFlush = _immediateFlush;
+ context = new LoggerContext();
+ logger = context.getLogger("logger-" + getName());
+
+ // A FileAppender is created according to the buffering and
+ // immediate flush setting of this IO instance.
+ FileAppender<ILoggingEvent> fa = new FileAppender<ILoggingEvent>();
+ fa.setName("FILE");
+ PatternLayoutEncoder pa = new PatternLayoutEncoder();
+ pa.setPattern("%r %5p %c [%t] - %m%n");
+ pa.setContext(context);
+ pa.start();
+ fa.setEncoder(pa);
+
+ fa.setFile(LOG_FILE);
+ fa.setAppend(true);
+ fa.setContext(context);
+ fa.start();
+
+ ((ch.qos.logback.classic.Logger) logger).addAppender(fa);
+
+ StatusPrinter.print(context);
+ }
+
+ public static void main(String[] argv) throws Exception {
+ if (argv.length != 3) {
+ usage("Wrong number of arguments.");
}
- public static void main(String[] argv) throws Exception {
- if (argv.length != 3) {
- usage("Wrong number of arguments.");
- }
-
- l = Integer.parseInt(argv[0]);
- LOG_FILE = argv[1];
- PARALLEL_FILE = argv[2];
-
- // ----------------------------------------------------
- // first test with immediate flushing
- perfCase(true, l);
-
- // ----------------------------------------------------
- // Second test with no immediate flushing
- perfCase(false, l);
-
- // There is no fourth test as buffered IO and immediate flushing
- // do not make sense.
+ l = Integer.parseInt(argv[0]);
+ LOG_FILE = argv[1];
+ PARALLEL_FILE = argv[2];
+
+ // ----------------------------------------------------
+ // first test with immediate flushing
+ perfCase(true, l);
+
+ // ----------------------------------------------------
+ // Second test with no immediate flushing
+ perfCase(false, l);
+
+ // There is no fourth test as buffered IO and immediate flushing
+ // do not make sense.
+ }
+
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + IOPerformance.class.getName()
+ + " runLength logFile otherFile\n"
+ + " runLength (integer) the number of logs to generate perthread\n"
+ + " logFile path to a logFile\n"
+ + " otherFile path to a second file\n");
+ System.exit(1);
+ }
+
+ static void perfCase(boolean immediateFlush, long len) throws Exception {
+ IOPerformance[] threads = new IOPerformance[NUM_THREADS];
+ OtherIO otherIOThread = new OtherIO();
+ otherIOThread.start();
+
+ // First create the threads
+ for (int i = 0; i < NUM_THREADS; i++) {
+ threads[i] = new IOPerformance(immediateFlush, len);
}
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + IOPerformance.class.getName() + " runLength logFile otherFile\n"
- + " runLength (integer) the number of logs to generate perthread\n" + " logFile path to a logFile\n"
- + " otherFile path to a second file\n");
- System.exit(1);
+ // then start them
+ for (int i = 0; i < NUM_THREADS; i++) {
+ threads[i].start();
}
- static void perfCase(boolean immediateFlush, long len) throws Exception {
- IOPerformance[] threads = new IOPerformance[NUM_THREADS];
- OtherIO otherIOThread = new OtherIO();
- otherIOThread.start();
+ // wait for them to processPriorToRemoval, compute the average throughput
+ double sum = 0;
- // First create the threads
- for (int i = 0; i < NUM_THREADS; i++) {
- threads[i] = new IOPerformance(immediateFlush, len);
- }
+ for (int i = 0; i < NUM_THREADS; i++) {
+ threads[i].join();
+ sum += threads[i].throughput;
+ }
- // then start them
- for (int i = 0; i < NUM_THREADS; i++) {
- threads[i].start();
- }
+ // setting the interrupted field will cause counterThread to processPriorToRemoval
+ otherIOThread.interrupted = true;
+ otherIOThread.join();
- // wait for them to processPriorToRemoval, compute the average throughput
- double sum = 0;
+ System.out.println("On total throughput of " + (sum)
+ + " logs per microsecond.");
+ System.out.println("------------------------------------------------");
+ }
- for (int i = 0; i < NUM_THREADS; i++) {
- threads[i].join();
- sum += threads[i].throughput;
- }
+ public void run() {
- // setting the interrupted field will cause counterThread to processPriorToRemoval
- otherIOThread.interrupted = true;
- otherIOThread.join();
+ long before = System.nanoTime();
- System.out.println("On total throughput of " + (sum) + " logs per microsecond.");
- System.out.println("------------------------------------------------");
+ for (int i = 0; i < len; i++) {
+ logger.debug(MSG);
}
- public void run() {
-
- long before = System.nanoTime();
-
- for (int i = 0; i < len; i++) {
- logger.debug(MSG);
- }
-
- throughput = (len * 1.0) / ((System.nanoTime() - before) / 1000);
- System.out.println(getName() + ", immediateFlush: " + immediateFlush + ", throughput: " + throughput + " logs per microsecond.");
- }
+ throughput = (len * 1.0) / ((System.nanoTime() - before) / 1000);
+ System.out.println(getName() + ", immediateFlush: " + immediateFlush
+ + ", throughput: " + throughput + " logs per microsecond.");
+ }
}
class OtherIO extends Thread {
- public boolean interrupted = false;
- public int counter = 0;
-
- public void run() {
- long before = System.nanoTime();
- try {
- FileWriter fw = new FileWriter(IOPerformance.PARALLEL_FILE, true);
-
- while (!interrupted) {
- counter++;
- fw.write("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- fw.flush();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- double tput = (counter * 1.0) / (System.nanoTime() - before);
- System.out.println("Counter thread " + getName() + " incremented counter by " + tput + " per nanosecond.");
+ public boolean interrupted = false;
+ public int counter = 0;
+
+ public void run() {
+ long before = System.nanoTime();
+ try {
+ FileWriter fw = new FileWriter(IOPerformance.PARALLEL_FILE, true);
+
+ while (!interrupted) {
+ counter++;
+ fw.write("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+ fw.flush();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
}
+
+ double tput = (counter * 1.0) / (System.nanoTime() - before);
+ System.out.println("Counter thread " + getName()
+ + " incremented counter by " + tput + " per nanosecond.");
+ }
}
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/access/logback-DB.xml b/logback-examples/src/main/java/chapters/appenders/conf/access/logback-DB.xml
new file mode 100644
index 0000000..64e3dfd
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/access/logback-DB.xml
@@ -0,0 +1,14 @@
+<configuration>
+
+ <appender name="DB" class="ch.qos.logback.access.db.DBAppender">
+ <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
+ <driverClass>com.mysql.jdbc.Driver</driverClass>
+ <url>jdbc:mysql://localhost:3306/logbackdb</url>
+ <user>logback</user>
+ <password>logback</password>
+ </connectionSource>
+ <insertHeaders>true</insertHeaders>
+ </appender>
+
+ <appender-ref ref="DB" />
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/access/logback-SMTP.xml b/logback-examples/src/main/java/chapters/appenders/conf/access/logback-SMTP.xml
new file mode 100644
index 0000000..dffcc3d
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/access/logback-SMTP.xml
@@ -0,0 +1,21 @@
+<configuration>
+
+ <appender name="SMTP"
+ class="ch.qos.logback.access.net.SMTPAppender">
+ <layout class="ch.qos.logback.access.html.HTMLLayout">
+ <Pattern>%h%l%u%t%r%s%b</Pattern>
+ </layout>
+
+ <b>
+ <Evaluator class="ch.qos.logback.access.net.URLEvaluator">
+ <URL>url1.jsp</URL>
+ <URL>directory/url2.html</URL>
+ </Evaluator>
+ </b>
+ <From>sender_email at host.com</From>
+ <SMTPHost>mail.domain.com</SMTPHost>
+ <To>recipient_email at host.com</To>
+ </appender>
+
+ <appender-ref ref="SMTP" />
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml
new file mode 100644
index 0000000..7527c1f
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml
@@ -0,0 +1,15 @@
+<configuration>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <!-- encoders are assigned the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
+ <encoder>
+ <pattern>%-4relative [%thread] %-5level - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
+
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-HtmlToConsole.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-HtmlToConsole.xml
new file mode 100644
index 0000000..b43efc2
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-HtmlToConsole.xml
@@ -0,0 +1,18 @@
+<configuration>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+ <layout class="ch.qos.logback.classic.html.HTMLLayout">
+ <cssBuilder class="ch.qos.logback.classic.html.UrlCssBuilder">
+ <url>path_to_StyleFile.css</url>
+ </cssBuilder>
+ <pattern>%-4relative [%thread] %-5level - %msg%n</pattern>
+ </layout>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
+
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-JMSQueue.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-JMSQueue.xml
new file mode 100644
index 0000000..63f9a74
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-JMSQueue.xml
@@ -0,0 +1,17 @@
+<configuration>
+
+ <appender name="Queue" class="ch.qos.logback.classic.net.JMSQueueAppender">
+ <InitialContextFactoryName>
+ org.apache.activemq.jndi.ActiveMQInitialContextFactory
+ </InitialContextFactoryName>
+ <ProviderURL>tcp://localhost:61616</ProviderURL>
+ <QueueConnectionFactoryBindingName>
+ ConnectionFactory
+ </QueueConnectionFactoryBindingName>
+ <QueueBindingName>MyQueue</QueueBindingName>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="Queue" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-JMSTopic.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-JMSTopic.xml
new file mode 100644
index 0000000..30ea733
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-JMSTopic.xml
@@ -0,0 +1,17 @@
+<configuration>
+
+ <appender name="Topic" class="ch.qos.logback.classic.net.JMSTopicAppender">
+ <InitialContextFactoryName>
+ org.apache.activemq.jndi.ActiveMQInitialContextFactory
+ </InitialContextFactoryName>
+ <ProviderURL>tcp://localhost:61616</ProviderURL>
+ <TopicConnectionFactoryBindingName>
+ ConnectionFactory
+ </TopicConnectionFactoryBindingName>
+ <TopicBindingName>MyTopic</TopicBindingName>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="Topic" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-MDC.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-MDC.xml
new file mode 100644
index 0000000..d0dc587
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-MDC.xml
@@ -0,0 +1,13 @@
+<configuration>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%-4relative [%thread] %-5level %X{testKey} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
+
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml
new file mode 100644
index 0000000..26718be
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml
@@ -0,0 +1,19 @@
+<configuration>
+ <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+
+ <!-- Support multiple-JVMs writing to the same log file -->
+ <prudent>true</prudent>
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
+ <maxHistory>30</maxHistory>
+ </rollingPolicy>
+
+ <encoder>
+ <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-RollingFixedWindow.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-RollingFixedWindow.xml
new file mode 100644
index 0000000..c1aedab
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-RollingFixedWindow.xml
@@ -0,0 +1,22 @@
+<configuration>
+ <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+
+ <file>testFile.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>testFile.%i.log.zip</fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>3</maxIndex>
+ </rollingPolicy>
+
+ <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-RollingSizeBased.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-RollingSizeBased.xml
new file mode 100644
index 0000000..b59056f
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-RollingSizeBased.xml
@@ -0,0 +1,23 @@
+<configuration>
+
+ <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>test.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>test.%i.log.zip</fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>3</maxIndex>
+ </rollingPolicy>
+
+ <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
+
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-RollingTimeBased.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-RollingTimeBased.xml
new file mode 100644
index 0000000..c4840ec
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-RollingTimeBased.xml
@@ -0,0 +1,21 @@
+<configuration>
+
+ <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>logFile.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <!-- daily rollover -->
+ <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
+
+ <!-- keep 30 days worth of history -->
+ <maxHistory>30</maxHistory>
+ </rollingPolicy>
+
+ <encoder>
+ <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-SMTP.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-SMTP.xml
new file mode 100644
index 0000000..8cc2752
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-SMTP.xml
@@ -0,0 +1,19 @@
+<configuration>
+
+ <appender name="SMTP" class="ch.qos.logback.classic.net.SMTPAppender">
+ <encoder>
+ <pattern>%-4relative [%thread] %-5level %class - %msg%n</pattern>
+ </encoder>
+ <from>sender_email at host.ch</from>
+ <SMTPHost>mail.host.ch</SMTPHost>
+
+ <subject>Last Event: %-10logger %nopex</subject>
+
+ <to>recipient_email at host.ch</to>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="SMTP" />
+ </root>
+</configuration>
+
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-SMTPWithHtml.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-SMTPWithHtml.xml
new file mode 100644
index 0000000..1bc6732
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-SMTPWithHtml.xml
@@ -0,0 +1,20 @@
+<configuration>
+
+ <appender name="SMTP" class="ch.qos.logback.classic.net.SMTPAppender">
+ <layout class="ch.qos.logback.classic.html.HTMLLayout">
+ <pattern>%relative%thread%mdc%level%class%msg</pattern>
+ <throwableRenderer class="ch.qos.logback.classic.html.DefaultThrowableRenderer" />
+ </layout>
+ <from>sender_email at host.ch</from>
+ <SMTPHost>mail.host.ch</SMTPHost>
+
+ <subject>Last Event: %-10logger %nopex</subject>
+
+ <to>recipient_email at host.ch</to>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="SMTP" />
+ </root>
+</configuration>
+
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-async.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-async.xml
new file mode 100644
index 0000000..c90e783
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-async.xml
@@ -0,0 +1,16 @@
+<configuration>
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>myapp.log</file>
+ <encoder>
+ <pattern>%logger{35} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
+ <appender-ref ref="FILE" />
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="ASYNC" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml
new file mode 100644
index 0000000..5f4ac3d
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml
@@ -0,0 +1,17 @@
+<configuration>
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>testFile.log</file>
+ <append>true</append>
+
+ <!-- encoders are assigned the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
+ <encoder>
+ <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-sizeAndTime.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-sizeAndTime.xml
new file mode 100644
index 0000000..18f7d31
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-sizeAndTime.xml
@@ -0,0 +1,25 @@
+<configuration>
+
+ <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+
+ <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>mylog.txt</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <!-- rollover daily -->
+ <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
+ <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+ <!-- or whenever the file size reaches 100MB -->
+ <maxFileSize>100MB</maxFileSize>
+ </timeBasedFileNamingAndTriggeringPolicy>
+ </rollingPolicy>
+ <encoder>
+ <pattern>%msg%n</pattern>
+ </encoder>
+ </appender>
+
+
+ <root level="debug">
+ <appender-ref ref="ROLLING" />
+ </root>
+
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-syslog.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-syslog.xml
new file mode 100644
index 0000000..d67292b
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-syslog.xml
@@ -0,0 +1,13 @@
+<configuration>
+
+ <appender name="SYSLOG" class="ch.qos.logback.classic.net.SyslogAppender">
+ <syslogHost>${syslogHost}</syslogHost>
+ <facility>${facility}</facility>
+ <suffixPattern>%-4relative [%thread] %-5level - %msg</suffixPattern>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="SYSLOG" />
+ </root>
+</configuration>
+
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp-contextBirth.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp-contextBirth.xml
new file mode 100644
index 0000000..08cdcbe
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp-contextBirth.xml
@@ -0,0 +1,22 @@
+<configuration>
+
+ <!-- Insert the logger context bith date formatted as
+ "yyyyMMdd'T'HHmmss" under the key "bySecond" into the logger
+ context. This value will be available to all subsequent
+ configuration elements. -->
+ <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"
+ timeReference="contextBirth"/>
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <!-- use the previously created timestamp to create a uniquely
+ named log file -->
+ <file>log-${bySecond}.txt</file>
+ <encoder>
+ <pattern>%logger{35} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml b/logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml
new file mode 100644
index 0000000..95b6f27
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml
@@ -0,0 +1,20 @@
+<configuration>
+
+ <!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
+ the key "bySecond" into the logger context. This value will be
+ available to all subsequent configuration elements. -->
+ <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <!-- use the previously created timestamp to create a uniquely
+ named log file -->
+ <file>log-${bySecond}.txt</file>
+ <encoder>
+ <pattern>%logger{35} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/appenders/countingConsole.xml b/logback-examples/src/main/java/chapters/appenders/countingConsole.xml
new file mode 100644
index 0000000..0d294ea
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/countingConsole.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+
+ <appender name="CUSTOM" class="chapters.appenders.CountingConsoleAppender">
+ <layout>
+ <Pattern>%date [%thread] %-5level %logger - %msg%n</Pattern>
+ </layout>
+ <limit>5</limit>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="CUSTOM" />
+ </root>
+</configuration>
+
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/db/append-and-share-with-jndi.xml b/logback-examples/src/main/java/chapters/appenders/db/append-and-share-with-jndi.xml
new file mode 100644
index 0000000..0a190f5
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/db/append-and-share-with-jndi.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- WARNING -->
+<!-- WARNING BindDataSourceToJNDIAction is both untested and undocumented. -->
+<!-- WARNING Just ignore this configuration file. -->
+<!-- WARNING -->
+
+<configuration>
+ <!-- We create a joran rule that will instance and bind the appropriate
+ data source instance to JNDI. -->
+ <newRule pattern="configuration/bindDataSourceToJNDI"
+ actionClass="ch.qos.logback.core.db.BindDataSourceToJNDIAction"/>
+
+ <bindDataSourceToJNDI/>
+
+ <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
+ <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
+
+ <dataSource class="${dataSourceClass}">
+ <!-- Joran cannot handle element names which are variables themselves. In order to let -->
+ <!-- the property name vary, we use the <param> element.-->
+ <param name="${url-key:-url}" value="${url}"/>
+ <serverName>${serverName}</serverName>
+ <databaseName>${databaseName}</databaseName>
+ </dataSource>
+
+ <user>${user}</user>
+ <password>${password}</password>>
+ </connectionSource>
+ </appender>
+
+ <root>
+ <level value="debug"/>
+ <appender-ref ref="DB"/>
+ </root>
+
+</configuration>
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml b/logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml
new file mode 100644
index 0000000..0bc0999
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml
@@ -0,0 +1,17 @@
+<configuration>
+
+ <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
+ <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
+ <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
+ <driverClass>com.mysql.jdbc.Driver</driverClass>
+ <jdbcUrl>jdbc:mysql://localhost:3306/logbackdb</jdbcUrl>
+ <user>logback</user>
+ <password>logback</password>
+ </dataSource>
+ </connectionSource>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="DB"/>
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource.xml b/logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource.xml
new file mode 100644
index 0000000..ac42867
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
+ <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
+ <dataSource class="com.mysql.jdbc.jdbc2.optional.MysqlDataSource">
+ <serverName>${serverName}</serverName>
+ <port>${port$</port>
+ <databaseName>${dbName}</databaseName>
+ <user>${user}</user>
+ <password>${pass}</password>
+ </dataSource>
+ </connectionSource>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="DB" />
+ </root>
+
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-driverManager.xml b/logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-driverManager.xml
new file mode 100644
index 0000000..5e21c36
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-driverManager.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
+ <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
+ <driverClass>com.mysql.jdbc.Driver</driverClass>
+ <url>jdbc:mysql://host_name:3306/datebase_name</url>
+ <user>username</user>
+ <password>password</password>
+ </connectionSource>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="DB" />
+ </root>
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/appenders/db/append-via-jndi.xml b/logback-examples/src/main/java/chapters/appenders/db/append-via-jndi.xml
new file mode 100644
index 0000000..687d58c
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/db/append-via-jndi.xml
@@ -0,0 +1,11 @@
+<configuration debug="true">
+ <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
+ <connectionSource class="ch.qos.logback.core.db.JNDIConnectionSource">
+ <!-- please note the "java:comp/env/" prefix -->
+ <jndiLocation>java:comp/env/jdbc/logging</jndiLocation>
+ </connectionSource>
+ </appender>
+ <root level="DEBUG">
+ <appender-ref ref="DB"/>
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/appenders/db/append-with-c3p0.xml b/logback-examples/src/main/java/chapters/appenders/db/append-with-c3p0.xml
new file mode 100644
index 0000000..513701c
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/db/append-with-c3p0.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
+ <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
+ <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
+ <driverClass>${driverClass}</driverClass>
+ <jdbcUrl>${url}</jdbcUrl>
+ <serverName>${serverName}</serverName>
+ <databaseName>${databaseName}</databaseName>
+ <user>${user}</user>
+ <password>${password}</password>
+ </dataSource>
+
+ </connectionSource>
+ </appender>
+
+ <root>
+ <level value ="debug"/>
+ <appender-ref ref="DB" />
+ </root>
+</configuration>
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/db/append-with-datasource.xml b/logback-examples/src/main/java/chapters/appenders/db/append-with-datasource.xml
new file mode 100644
index 0000000..dc1aeff
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/db/append-with-datasource.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
+ <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
+
+ <dataSource class="${dataSourceClass}">
+ <!-- Joran cannot substitute variables
+ that are not attribute values. Therefore, we cannot
+ declare the next parameter like the others.
+ -->
+ <param name="${url-key:-url}" value="${url}"/>
+ <serverName>${serverName}</serverName>
+ <databaseName>${databaseName}</databaseName>
+ </dataSource>
+
+ <user>${user}</user>
+ <password>${password}</password>
+ </connectionSource>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="DB" />
+ </root>
+</configuration>
+
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/db/append-with-drivermanager.xml b/logback-examples/src/main/java/chapters/appenders/db/append-with-drivermanager.xml
new file mode 100644
index 0000000..f5e568e
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/db/append-with-drivermanager.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
+ <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
+ <driverClass>${driverClass}</driverClass>
+ <url>${url}</url>
+ <user>${user}</user>
+ <password>${password}</password>
+ </connectionSource>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="DB"/>
+ </root>
+</configuration>
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/db/append-with-pooled-datasource.xml b/logback-examples/src/main/java/chapters/appenders/db/append-with-pooled-datasource.xml
new file mode 100644
index 0000000..0a9237b
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/db/append-with-pooled-datasource.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
+ <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
+
+ <dataSource class="${pooledDataSourceClass}">
+ <!-- Joran cannot handle element names which are variables themselves. In order to let -->
+ <!-- the property name vary, we use the <param> element.-->
+ <param name="${url-key:-url}" value="${url}"/>
+ <serverName>${serverName}</serverName>
+ <databaseName>${databaseName}</databaseName>
+ <user>${user}</user>
+ <password>${password}</password>
+
+ <initialConnections>10</initialConnections>
+ <maxConnections>10</maxConnections>
+ </dataSource>
+
+ </connectionSource>
+ </appender>
+
+ <root>
+ <level value ="debug"/>
+ <appender-ref ref="DB" />
+ </root>
+</configuration>
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/mail/CounterBasedEvaluator.java b/logback-examples/src/main/java/chapters/appenders/mail/CounterBasedEvaluator.java
index e063828..9a6a227 100644
--- a/logback-examples/src/main/java/chapters/appenders/mail/CounterBasedEvaluator.java
+++ b/logback-examples/src/main/java/chapters/appenders/mail/CounterBasedEvaluator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,40 +23,41 @@ import ch.qos.logback.core.spi.ContextAwareBase;
*/
public class CounterBasedEvaluator extends ContextAwareBase implements EventEvaluator {
- static int LIMIT = 1024;
- int counter = 0;
- String name;
- boolean started;
+ static int LIMIT = 1024;
+ int counter = 0;
+ String name;
+ boolean started;
- public boolean evaluate(Object event) throws NullPointerException, EvaluationException {
- counter++;
+ public boolean evaluate(Object event) throws NullPointerException,
+ EvaluationException {
+ counter++;
- if (counter == LIMIT) {
- counter = 0;
+ if (counter == LIMIT) {
+ counter = 0;
- return true;
- } else {
- return false;
- }
+ return true;
+ } else {
+ return false;
}
+ }
- public String getName() {
- return name;
- }
+ public String getName() {
+ return name;
+ }
- public void setName(String name) {
- this.name = name;
- }
+ public void setName(String name) {
+ this.name = name;
+ }
- public boolean isStarted() {
- return started;
- }
+ public boolean isStarted() {
+ return started;
+ }
- public void start() {
- started = true;
- }
+ public void start() {
+ started = true;
+ }
- public void stop() {
- started = false;
- }
+ public void stop() {
+ started = false;
+ }
}
diff --git a/logback-examples/src/main/java/chapters/appenders/mail/EMail.java b/logback-examples/src/main/java/chapters/appenders/mail/EMail.java
index 3d36645..ad6d6a7 100644
--- a/logback-examples/src/main/java/chapters/appenders/mail/EMail.java
+++ b/logback-examples/src/main/java/chapters/appenders/mail/EMail.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,41 +25,43 @@ import ch.qos.logback.core.util.StatusPrinter;
* user.
* */
public class EMail {
- static public void main(String[] args) throws Exception {
- if (args.length != 2) {
- usage("Wrong number of arguments.");
- }
-
- int runLength = Integer.parseInt(args[0]);
- String configFile = args[1];
+ static public void main(String[] args) throws Exception {
+ if (args.length != 2) {
+ usage("Wrong number of arguments.");
+ }
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator configurator = new JoranConfigurator();
- lc.reset();
- configurator.setContext(lc);
- configurator.doConfigure(configFile);
+ int runLength = Integer.parseInt(args[0]);
+ String configFile = args[1];
- Logger logger = LoggerFactory.getLogger(EMail.class);
- for (int i = 1; i <= runLength; i++) {
- if ((i % 10) < 9) {
- logger.debug("This is a debug message. Message number: " + i);
- } else {
- logger.warn("This is a warning message. Message number: " + i);
- }
- }
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ JoranConfigurator configurator = new JoranConfigurator();
+ lc.reset();
+ configurator.setContext(lc);
+ configurator.doConfigure(configFile);
+
+ Logger logger = LoggerFactory.getLogger(EMail.class);
- logger.error("At last an error.", new Exception("Just testing"));
-
- lc.stop();
-
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
+ for (int i = 1; i <= runLength; i++) {
+ if ((i % 10) < 9) {
+ logger.debug("This is a debug message. Message number: " + i);
+ } else {
+ logger.warn("This is a warning message. Message number: " + i);
+ }
}
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + EMail.class.getName() + " runLength configFile\n" + " runLength (integer) the number of logs to generate\n"
- + " configFile a logback configuration file in XML format." + " XML files must have a '.xml' extension.");
- System.exit(1);
- }
+ logger.error("At last an error.", new Exception("Just testing"));
+
+ StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
+ }
+
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + EMail.class.getName() +
+ " runLength configFile\n" +
+ " runLength (integer) the number of logs to generate\n" +
+ " configFile a logback configuration file in XML format." +
+ " XML files must have a '.xml' extension.");
+ System.exit(1);
+ }
}
diff --git a/logback-examples/src/main/java/chapters/appenders/mail/Marked_EMail.java b/logback-examples/src/main/java/chapters/appenders/mail/Marked_EMail.java
index 1e4a155..466eef0 100644
--- a/logback-examples/src/main/java/chapters/appenders/mail/Marked_EMail.java
+++ b/logback-examples/src/main/java/chapters/appenders/mail/Marked_EMail.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,40 +27,44 @@ import ch.qos.logback.core.util.StatusPrinter;
* However, only one message bears the "NOTIFY_ADMIN" marker.
* */
public class Marked_EMail {
- static public void main(String[] args) throws Exception {
- if (args.length != 1) {
- usage("Wrong number of arguments.");
- }
+ static public void main(String[] args) throws Exception {
+ if (args.length != 1) {
+ usage("Wrong number of arguments.");
+ }
- String configFile = args[0];
+ String configFile = args[0];
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator configurator = new JoranConfigurator();
- lc.reset();
- configurator.setContext(lc);
- configurator.doConfigure(configFile);
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ JoranConfigurator configurator = new JoranConfigurator();
+ lc.reset();
+ configurator.setContext(lc);
+ configurator.doConfigure(configFile);
+ StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
- Logger logger = LoggerFactory.getLogger(Marked_EMail.class);
+ Logger logger = LoggerFactory.getLogger(Marked_EMail.class);
- int runLength = 100;
- for (int i = 1; i <= runLength; i++) {
- if ((i % 10) < 9) {
- logger.debug("This is a debug message. Message number: " + i);
- } else {
- logger.error("This is an error message. Message number: " + i);
- }
- }
+ int runLength = 100;
+ for (int i = 1; i <= runLength; i++) {
+ if ((i % 10) < 9) {
+ logger.debug("This is a debug message. Message number: " + i);
+ } else {
+ logger.error("This is an error message. Message number: " + i);
+ }
+ }
- Marker notifyAdmin = MarkerFactory.getMarker("NOTIFY_ADMIN");
- logger.error(notifyAdmin, "This is a serious an error requiring the admin's attention", new Exception("Just testing"));
+ Marker notifyAdmin = MarkerFactory.getMarker("NOTIFY_ADMIN");
+ logger.error(notifyAdmin,
+ "This is a serious an error requiring the admin's attention",
+ new Exception("Just testing"));
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
- }
+ StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
+ }
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + Marked_EMail.class.getName() + " configFile\n" + " configFile a logback configuration file in XML format.");
- System.exit(1);
- }
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + Marked_EMail.class.getName()
+ + " configFile\n"
+ + " configFile a logback configuration file in XML format.");
+ System.exit(1);
+ }
}
diff --git a/logback-examples/src/main/java/chapters/appenders/mail/customBufferSize.xml b/logback-examples/src/main/java/chapters/appenders/mail/customBufferSize.xml
new file mode 100644
index 0000000..143c6ee
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/mail/customBufferSize.xml
@@ -0,0 +1,20 @@
+<configuration>
+ <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
+
+ <Subject>TESTING: %logger{20} - %m</Subject>
+
+ <SMTPHost>${smtpHost}</SMTPHost>
+ <To>${to}</To>
+ <From>${from}</From>
+ <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
+
+
+ <CyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker">
+ <BufferSize>1</BufferSize>
+ </CyclicBufferTracker>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="EMAIL" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/appenders/mail/gmailSSL.xml b/logback-examples/src/main/java/chapters/appenders/mail/gmailSSL.xml
new file mode 100644
index 0000000..61f68db
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/mail/gmailSSL.xml
@@ -0,0 +1,22 @@
+<configuration>
+
+ <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
+ <SMTPHost>smtp.gmail.com</SMTPHost>
+ <SMTPPort>465</SMTPPort>
+ <SSL>true</SSL>
+ <Username>YOUR_USERNAME at gmail.com</Username>
+ <Password>YOUR_GMAIL_PASSWORD</Password>
+
+ <To>EMAIL-DESTINATION</To>
+ <To>ANOTHER_EMAIL_DESTINATION</To> <!-- additional destinations are possible -->
+ <From>YOUR_USERNAME at gmail.com</From>
+ <Subject>TESTING: %logger{20} - %m</Subject>
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%date %-5level %logger - %message%n</Pattern>
+ </layout>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="EMAIL" />
+ </root>
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/appenders/mail/gmailSTARTTLS.xml b/logback-examples/src/main/java/chapters/appenders/mail/gmailSTARTTLS.xml
new file mode 100644
index 0000000..e7520a1
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/mail/gmailSTARTTLS.xml
@@ -0,0 +1,21 @@
+<configuration>
+ <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
+ <SMTPHost>smtp.gmail.com</SMTPHost>
+ <SMTPPort>587</SMTPPort>
+ <STARTTLS>true</STARTTLS>
+ <Username>YOUR_USERNAME at gmail.com</Username>
+ <Password>YOUR_GMAIL_PASSWORD</Password>
+
+ <To>EMAIL-DESTINATION</To>
+ <To>ANOTHER_EMAIL_DESTINATION</To> <!-- additional destinations are possible -->
+ <From>YOUR_USERNAME at gmail.com</From>
+ <Subject>TESTING: %logger{20} - %m</Subject>
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%date %-5level %logger - %message%n</Pattern>
+ </layout>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="EMAIL" />
+ </root>
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/appenders/mail/mail1.xml b/logback-examples/src/main/java/chapters/appenders/mail/mail1.xml
new file mode 100644
index 0000000..6de9862
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/mail/mail1.xml
@@ -0,0 +1,17 @@
+<configuration>
+
+ <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
+ <smtpHost>ADDRESS-OF-YOUR-SMTP-HOST</smtpHost>
+ <to>EMAIL-DESTINATION</to>
+ <to>ANOTHER_EMAIL_DESTINATION</to> <!-- additional destinations are possible -->
+ <from>SENDER-EMAIL</from>
+ <subject>%logger{20} - %m</subject>
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <pattern>%date %-5level %logger - %message%n</pattern>
+ </layout>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="EMAIL" />
+ </root>
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/appenders/mail/mail2.xml b/logback-examples/src/main/java/chapters/appenders/mail/mail2.xml
new file mode 100644
index 0000000..d19deab
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/mail/mail2.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
+ <SMTPHost>${smtpHost}</SMTPHost>
+ <To>${to}</To>
+ <From>${from}</From>
+ <Subject>%logger{20} - %m</Subject>
+ <Layout class="ch.qos.logback.classic.html.HTMLLayout"/>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="EMAIL" />
+ </root>
+</configuration>
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/mail/mail3.xml b/logback-examples/src/main/java/chapters/appenders/mail/mail3.xml
new file mode 100644
index 0000000..6e0e5bb
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/mail/mail3.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ============================================================= -->
+<!-- Sample SMTPAppender configuration using the HTMLLayout and a -->
+<!-- custom triggering policy. -->
+<!-- ============================================================= -->
+
+<configuration>
+ <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
+ <Evaluator class="chapters.appenders.mail.CounterBasedEvaluator" />
+ <SMTPHost>${smtpHost}</SMTPHost>
+ <To>${to}</To>
+ <From>${from}</From>
+ <subject>%logger{20} - %m</subject>
+ <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
+ </appender>
+
+ <root>
+ <level value ="debug"/>
+ <appender-ref ref="EMAIL" />
+ </root>
+</configuration>
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/mail/mailWithMDCBasedDiscriminator.xml b/logback-examples/src/main/java/chapters/appenders/mail/mailWithMDCBasedDiscriminator.xml
new file mode 100644
index 0000000..eeb849a
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/mail/mailWithMDCBasedDiscriminator.xml
@@ -0,0 +1,27 @@
+
+<configuration>
+ <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
+
+ <SMTPHost>ADDRESS-OF-YOUR-SMTP-HOST</SMTPHost>
+ <to>EMAIL-DESTINATION</to>
+ <from>SENDER-EMAIL</from>
+
+
+ <discriminator class="ch.qos.logback.classic.sift.MDCBasedDiscriminator">
+ <key>req.remoteHost</key>
+ <defaultValue>default</defaultValue>
+ </discriminator>
+
+ <subject>${HOSTNAME} -- %X{req.remoteHost} %msg"</subject>
+ <layout class="ch.qos.logback.classic.html.HTMLLayout">
+ <pattern>%date%level%thread%X{req.remoteHost}%X{req.requestURL}%X{req.queryString}%logger%msg</pattern>
+ </layout>
+ </appender>
+
+ <root>
+ <level level="DEBUG"/>
+ <appender-ref ref="EMAIL" />
+ </root>
+</configuration>
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker.xml b/logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker.xml
new file mode 100644
index 0000000..2cbb698
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+ <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+
+ <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
+ <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
+ <marker>NOTIFY_ADMIN</marker>
+ <!-- you specify add as many markers as you want -->
+ <marker>ANOTHER_MARKER</marker>
+ </evaluator>
+ <SMTPHost>${smtpHost}</SMTPHost>
+ <To>${to}</To>
+ <From>${from}</From>
+ <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
+ </appender>
+
+ <root>
+ <level value ="debug"/>
+ <appender-ref ref="EMAIL" />
+ </root>
+</configuration>
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker_GEventEvaluator.xml b/logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker_GEventEvaluator.xml
new file mode 100644
index 0000000..b1522f2
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker_GEventEvaluator.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+ <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+
+ <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
+ <evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator">
+ <expression>
+ e.marker?.contains("NOTIFY_ADMIN") || e.marker?.contains("TRANSACTION_FAILURE")
+ </expression>
+ </evaluator>
+ <SMTPHost>${smtpHost}</SMTPHost>
+ <To>${to}</To>
+ <From>${from}</From>
+ <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
+ </appender>
+
+ <root>
+ <level value ="debug"/>
+ <appender-ref ref="EMAIL" />
+ </root>
+</configuration>
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker_Janino.xml b/logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker_Janino.xml
new file mode 100644
index 0000000..1ec9fd8
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker_Janino.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+ <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+
+ <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
+ <evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
+ <expression>
+ (marker != null) &&
+ (marker.contains("NOTIFY_ADMIN") || marker.contains("TRANSACTION_FAILURE"))
+ </expression>
+ </evaluator>
+ <SMTPHost>${smtpHost}</SMTPHost>
+ <To>${to}</To>
+ <From>${from}</From>
+ <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
+ </appender>
+
+ <root>
+ <level value ="debug"/>
+ <appender-ref ref="EMAIL" />
+ </root>
+</configuration>
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/sift/SiftExample.java b/logback-examples/src/main/java/chapters/appenders/sift/SiftExample.java
index 917025c..d4503e8 100644
--- a/logback-examples/src/main/java/chapters/appenders/sift/SiftExample.java
+++ b/logback-examples/src/main/java/chapters/appenders/sift/SiftExample.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,31 +23,33 @@ import ch.qos.logback.core.joran.spi.JoranException;
public class SiftExample {
- public static void main(String[] args) throws JoranException {
- if (args.length != 1) {
- usage("Wrong number of arguments.");
- }
-
- String configFile = args[0];
-
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator configurator = new JoranConfigurator();
- lc.reset();
- configurator.setContext(lc);
- configurator.doConfigure(configFile);
-
- Logger logger = LoggerFactory.getLogger(SiftExample.class);
- logger.debug("Application started");
-
- MDC.put("userid", "Alice");
- logger.debug("Alice says hello");
-
- // StatusPrinter.print(lc);
+ public static void main(String[] args) throws JoranException {
+ if (args.length != 1) {
+ usage("Wrong number of arguments.");
}
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + SiftExample.class.getName() + " configFile\n" + " configFile a logback configuration file");
- System.exit(1);
- }
+ String configFile = args[0];
+
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ JoranConfigurator configurator = new JoranConfigurator();
+ lc.reset();
+ configurator.setContext(lc);
+ configurator.doConfigure(configFile);
+
+
+ Logger logger = LoggerFactory.getLogger(SiftExample.class);
+ logger.debug("Application started");
+
+ MDC.put("userid", "Alice");
+ logger.debug("Alice says hello");
+
+ //StatusPrinter.print(lc);
+ }
+
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + SiftExample.class.getName()
+ + " configFile\n" + " configFile a logback configuration file");
+ System.exit(1);
+ }
}
diff --git a/logback-examples/src/main/java/chapters/appenders/sift/access-siftingFile.xml b/logback-examples/src/main/java/chapters/appenders/sift/access-siftingFile.xml
new file mode 100644
index 0000000..f579e3f
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/sift/access-siftingFile.xml
@@ -0,0 +1,22 @@
+<configuration>
+
+ <appender name="SIFTING"
+ class="ch.qos.logback.access.sift.SiftingAppender">
+ <Discriminator>
+ <Key>id</Key>
+ <FieldName>SESSION_ATTRIBUTE</FieldName>
+ <AdditionalKey>username</AdditionalKey>
+ <DefaultValue>NA</DefaultValue>
+ </Discriminator>
+ <sift>
+ <appender name="${id}" class="ch.qos.logback.core.FileAppender">
+ <File>byUser/${id}.log</File>
+ <layout class="ch.qos.logback.access.PatternLayout">
+ <Pattern>%h %l %u %t \"%r\" %s %b</Pattern>
+ </layout>
+ </appender>
+ </sift>
+ </appender>
+
+ <appender-ref ref="SIFTING" />
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/appenders/sift/byUserid.xml b/logback-examples/src/main/java/chapters/appenders/sift/byUserid.xml
new file mode 100644
index 0000000..997692c
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/sift/byUserid.xml
@@ -0,0 +1,21 @@
+<configuration>
+ <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
+ <discriminator>
+ <Key>userid</Key>
+ <DefaultValue>unknown</DefaultValue>
+ </discriminator>
+ <sift>
+ <appender name="FILE-${userid}" class="ch.qos.logback.core.FileAppender">
+ <File>${userid}.log</File>s
+ <Append>false</Append>
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%d [%thread] %level %mdc %logger{35} - %msg%n</Pattern>
+ </layout>
+ </appender>
+ </sift>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="SIFT" />
+ </root>
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/appenders/socket/ConsolePluginClient.java b/logback-examples/src/main/java/chapters/appenders/socket/ConsolePluginClient.java
index 3ca29ec..edf7d31 100644
--- a/logback-examples/src/main/java/chapters/appenders/socket/ConsolePluginClient.java
+++ b/logback-examples/src/main/java/chapters/appenders/socket/ConsolePluginClient.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,93 +30,94 @@ import static org.slf4j.Logger.ROOT_LOGGER_NAME;
*/
public class ConsolePluginClient {
- static String LONG_TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum lectus augue, pulvinar quis cursus nec, imperdiet nec ante. Cras sit amet arcu et enim adipiscing pellentesque. Suspendisse mi felis, dictum a lobortis nec, placerat in diam. Proin lobortis tortor at nunc facilisis aliquet. Praesent eget dignissim orci. Ut iaculis bibendum.";
-
- static String LOGGER_NAME = "com.acme.myapp.foo";
- static String UGLY_BETTY_LOGGER_NAME = "com.acme.myapp.UglyBetty";
- static long SLEEP = 1;
- static long RUN_LENGTH = 200 * 1000;
-
- static public void main(String[] args) throws Exception {
- // Create a SocketAppender connected to hostname:port with a
- // reconnection delay of 10000 seconds.
- String hostname = "localhost";
- int port = 4321;
- SocketAppender socketAppender = new SocketAppender();
- socketAppender.setRemoteHost(hostname);
- socketAppender.setPort(port);
- socketAppender.setIncludeCallerData(true);
+ static String LONG_TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum lectus augue, pulvinar quis cursus nec, imperdiet nec ante. Cras sit amet arcu et enim adipiscing pellentesque. Suspendisse mi felis, dictum a lobortis nec, placerat in diam. Proin lobortis tortor at nunc facilisis aliquet. Praesent eget dignissim orci. Ut iaculis bibendum.";
+
+ static String LOGGER_NAME = "com.acme.myapp.foo";
+ static String UGLY_BETTY_LOGGER_NAME = "com.acme.myapp.UglyBetty";
+ static long SLEEP = 1;
+ static long RUN_LENGTH = 200 * 1000;
+
+ static public void main(String[] args) throws Exception {
+ // Create a SocketAppender connected to hostname:port with a
+ // reconnection delay of 10000 seconds.
+ String hostname = "localhost";
+ int port = 4321;
+ SocketAppender socketAppender = new SocketAppender();
+ socketAppender.setRemoteHost(hostname);
+ socketAppender.setPort(port);
+ socketAppender.setIncludeCallerData(true);
socketAppender.setReconnectionDelay(new Duration(10000));
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
-
- socketAppender.setContext(lc);
-
- lc.reset();
-
- lc.getStatusManager().add(new OnConsoleStatusListener());
- // SocketAppender options become active only after the execution
- // of the next statement.
- socketAppender.start();
-
- Logger rootLogger = (Logger) LoggerFactory.getLogger(ROOT_LOGGER_NAME);
- rootLogger.addAppender(socketAppender);
-
- org.slf4j.Logger logger = LoggerFactory.getLogger(LOGGER_NAME);
-
- UglyBetty ub = new UglyBetty("ugly-betty-thread-234");
- ub.start();
- for (int i = 0; i < RUN_LENGTH; i++) {
- if (i % 3 == 0) {
- logger.warn(i + " is divisible by 3");
- } else {
- toto(logger, i);
- }
- Thread.sleep(SLEEP);
- }
- ub.join();
-
- StatusPrinter.print(lc);
- }
-
- /**
- * @param logger
- * @param i
- */
- /**
- * @param logger
- * @param i
- */
- static void toto(org.slf4j.Logger logger, int i) {
- logger.debug("this is message number " + i);
- }
-
- static class UglyBetty extends Thread {
- org.slf4j.Logger logger = LoggerFactory.getLogger(UGLY_BETTY_LOGGER_NAME);
-
- public UglyBetty(String name) {
- super(name);
- }
-
- public void run() {
- for (int i = 0; i < RUN_LENGTH; i++) {
- if (i % 23 == 0) {
- logger.warn(LONG_TEXT);
- } else if (i % 47 == 0) {
- logger.error("this is an exception", new Exception("test"));
- } else {
- count(logger, i);
- }
- try {
- Thread.sleep(SLEEP);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
-
- void count(org.slf4j.Logger logger, int i) {
- logger.debug("Betty counts to " + i);
- }
- }
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+
+ socketAppender.setContext(lc);
+
+ lc.reset();
+
+ lc.getStatusManager().add(new OnConsoleStatusListener());
+ // SocketAppender options become active only after the execution
+ // of the next statement.
+ socketAppender.start();
+
+ Logger rootLogger = (Logger) LoggerFactory.getLogger(ROOT_LOGGER_NAME);
+ rootLogger.addAppender(socketAppender);
+
+ org.slf4j.Logger logger = LoggerFactory.getLogger(LOGGER_NAME);
+
+ UglyBetty ub = new UglyBetty("ugly-betty-thread-234");
+ ub.start();
+ for (int i = 0; i < RUN_LENGTH; i++) {
+ if (i % 3 == 0) {
+ logger.warn(i + " is divisible by 3");
+ } else {
+ toto(logger, i);
+ }
+ Thread.sleep(SLEEP);
+ }
+ ub.join();
+
+ StatusPrinter.print(lc);
+ }
+
+ /**
+ * @param logger
+ * @param i
+ */
+ /**
+ * @param logger
+ * @param i
+ */
+ static void toto(org.slf4j.Logger logger, int i) {
+ logger.debug("this is message number " + i);
+ }
+
+ static class UglyBetty extends Thread {
+ org.slf4j.Logger logger = LoggerFactory
+ .getLogger(UGLY_BETTY_LOGGER_NAME);
+
+ public UglyBetty(String name) {
+ super(name);
+ }
+
+ public void run() {
+ for (int i = 0; i < RUN_LENGTH; i++) {
+ if (i % 23 == 0) {
+ logger.warn(LONG_TEXT);
+ } else if (i % 47 == 0) {
+ logger.error("this is an exception", new Exception("test"));
+ } else {
+ count(logger, i);
+ }
+ try {
+ Thread.sleep(SLEEP);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ void count(org.slf4j.Logger logger, int i) {
+ logger.debug("Betty counts to " + i);
+ }
+ }
}
diff --git a/logback-examples/src/main/java/chapters/appenders/socket/SocketClient1.java b/logback-examples/src/main/java/chapters/appenders/socket/SocketClient1.java
index f1e1e4f..be02e10 100644
--- a/logback-examples/src/main/java/chapters/appenders/socket/SocketClient1.java
+++ b/logback-examples/src/main/java/chapters/appenders/socket/SocketClient1.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,6 +13,7 @@
*/
package chapters.appenders.socket;
+
import java.io.BufferedReader;
import java.io.InputStreamReader;
@@ -23,55 +24,58 @@ import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.net.SocketAppender;
+
/**
* This application uses a SocketAppender that log messages to a
* server on a host and port specified by the user. It waits for the
* user to type a message which will be sent to the server.
* */
public class SocketClient1 {
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + SocketClient1.class.getName() + " hostname port\n" + " hostname the name of the remote log server\n"
- + " port (integer) the port number of the server\n");
- System.exit(1);
- }
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + SocketClient1.class.getName() +
+ " hostname port\n" + " hostname the name of the remote log server\n" +
+ " port (integer) the port number of the server\n");
+ System.exit(1);
+ }
- static public void main(String[] args) throws Exception {
- if (args.length != 2) {
- usage("Wrong number of arguments.");
- }
+ static public void main(String[] args) throws Exception {
+ if (args.length != 2) {
+ usage("Wrong number of arguments.");
+ }
- String hostName = args[0];
- int port = Integer.parseInt(args[1]);
+ String hostName = args[0];
+ int port = Integer.parseInt(args[1]);
- // Create a SocketAppender connected to hostname:port with a
- // reconnection delay of 10000 seconds.
- SocketAppender socketAppender = new SocketAppender();
- socketAppender.setRemoteHost(hostName);
- socketAppender.setPort(port);
- socketAppender.setReconnectionDelay(new Duration(10000));
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- socketAppender.setContext(lc);
+ // Create a SocketAppender connected to hostname:port with a
+ // reconnection delay of 10000 seconds.
+ SocketAppender socketAppender = new SocketAppender();
+ socketAppender.setRemoteHost(hostName);
+ socketAppender.setPort(port);
+ socketAppender.setReconnectionDelay(new Duration(10000));
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ socketAppender.setContext(lc);
- // SocketAppender options become active only after the execution
- // of the next statement.
- socketAppender.start();
+ // SocketAppender options become active only after the execution
+ // of the next statement.
+ socketAppender.start();
- Logger logger = (Logger) LoggerFactory.getLogger(SocketClient1.class);
- logger.addAppender(socketAppender);
+ Logger logger = (Logger) LoggerFactory.getLogger(SocketClient1.class);
+ logger.addAppender(socketAppender);
- BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+ BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
- while (true) {
- System.out.println("Type a message to send to log server at " + hostName + ":" + port + ". Type 'q' to quit.");
+ while (true) {
+ System.out.println("Type a message to send to log server at " + hostName +
+ ":" + port + ". Type 'q' to quit.");
- String s = reader.readLine();
+ String s = reader.readLine();
- if (s.equals("q")) {
- break;
- } else {
- logger.debug(s);
- }
- }
+ if (s.equals("q")) {
+ break;
+ } else {
+ logger.debug(s);
+ }
}
+ }
}
diff --git a/logback-examples/src/main/java/chapters/appenders/socket/SocketClient2.java b/logback-examples/src/main/java/chapters/appenders/socket/SocketClient2.java
index b33ec3d..a0b1782 100644
--- a/logback-examples/src/main/java/chapters/appenders/socket/SocketClient2.java
+++ b/logback-examples/src/main/java/chapters/appenders/socket/SocketClient2.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,48 +22,52 @@ import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
+
/**
* This application uses a SocketAppender that log messages to a
* server on a host and port specified by the user. It waits for the
* user to type a message which will be sent to the server.
* */
public class SocketClient2 {
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + SocketClient2.class.getName() + " configFile\n" + " configFile a logback configuration file"
- + " in XML format.");
- System.exit(1);
- }
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + SocketClient2.class.getName() +
+ " configFile\n" +
+ " configFile a logback configuration file" +
+ " in XML format.");
+ System.exit(1);
+ }
- static public void main(String[] args) throws Exception {
- if (args.length != 1) {
- usage("Wrong number of arguments.");
- }
+ static public void main(String[] args) throws Exception {
+ if (args.length != 1) {
+ usage("Wrong number of arguments.");
+ }
- String configFile = args[0];
+ String configFile = args[0];
- if (configFile.endsWith(".xml")) {
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator configurator = new JoranConfigurator();
- lc.stop();
- configurator.setContext(lc);
- configurator.doConfigure(configFile);
- }
+ if (configFile.endsWith(".xml")) {
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ JoranConfigurator configurator = new JoranConfigurator();
+ lc.stop();
+ configurator.setContext(lc);
+ configurator.doConfigure(configFile);
+ }
- Logger logger = LoggerFactory.getLogger(SocketClient2.class);
+ Logger logger = LoggerFactory.getLogger(SocketClient2.class);
- BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+ BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
- while (true) {
- System.out.println("Type a message to send to log server. Type 'q' to quit.");
+ while (true) {
+ System.out.println(
+ "Type a message to send to log server. Type 'q' to quit.");
- String s = reader.readLine();
+ String s = reader.readLine();
- if (s.equals("q")) {
- break;
- } else {
- logger.debug(s);
- }
- }
+ if (s.equals("q")) {
+ break;
+ } else {
+ logger.debug(s);
+ }
}
+ }
}
diff --git a/logback-examples/src/main/java/chapters/appenders/socket/client1.xml b/logback-examples/src/main/java/chapters/appenders/socket/client1.xml
new file mode 100644
index 0000000..4c7fefb
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/socket/client1.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- Sample SocketAppender configuration. -->
+<!-- ==================================================================== -->
+
+<configuration>
+
+ <appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
+ <RemoteHost>${host}</RemoteHost>
+ <Port>${port}</Port>
+ <ReconnectionDelay>10000</ReconnectionDelay>
+ <IncludeCallerData>${includeCallerData}</IncludeCallerData>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="SOCKET" />
+ </root>
+
+</configuration>
+
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/socket/client2.xml b/logback-examples/src/main/java/chapters/appenders/socket/client2.xml
new file mode 100644
index 0000000..4882f0d
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/socket/client2.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- Sample SocketReceiver configuration. -->
+<!-- ==================================================================== -->
+
+<configuration debug="true">
+
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%date %-5level [%thread] %logger - %message%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="CONSOLE" />
+ </root>
+
+ <receiver class="ch.qos.logback.classic.net.SocketReceiver">
+ <host>${host}</host>
+ <port>${port}</port>
+ <reconnectionDelay>10000</reconnectionDelay>
+ </receiver>
+
+</configuration>
+
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/socket/server1.xml b/logback-examples/src/main/java/chapters/appenders/socket/server1.xml
new file mode 100644
index 0000000..2cf0587
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/socket/server1.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- This config file is intended to be used by a SocketServer that logs -->
+<!-- events received from various clients on the console and to a file -->
+<!-- that is rolled over when appropriate. The interesting point to note -->
+<!-- is that it is a configuration file like any other. -->
+<!-- ==================================================================== -->
+
+<configuration>
+
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%date %-5level [%thread] %logger - %message%n</Pattern>
+ </layout>
+
+ </appender>
+
+ <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <File>rolling.log</File>
+
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <FileNamePattern>rolling.%i.log</FileNamePattern>
+ <MinIndex>1</MinIndex>
+ <MaxIndex>3</MaxIndex>
+ </rollingPolicy>
+
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <MaxFileSize>8KB</MaxFileSize>
+ </triggeringPolicy>
+
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%relative %-5level %logger - %message%n</Pattern>
+ </layout>
+ </appender>
+
+ <root>
+ <level value ="debug"/>
+ <appender-ref ref="CONSOLE" />
+ <appender-ref ref="ROLLING" />
+ </root>
+</configuration>
+
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/socket/server2.xml b/logback-examples/src/main/java/chapters/appenders/socket/server2.xml
new file mode 100644
index 0000000..7c458d8
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/socket/server2.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- This config file is intended to be used by a SocketServer that logs -->
+<!-- events received from various clients on the console. The interesting -->
+<!-- point to note is that it is a configuration file like any other. -->
+<!-- ==================================================================== -->
+
+<configuration>
+
+ <!-- Notice the %file and %line patterns in the Pattern. -->
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%date %-5level [%thread] [%file:%line] %logger - %message%n</Pattern>
+ </layout>
+ </appender>
+
+ <root>
+ <level value ="debug"/>
+ <appender-ref ref="CONSOLE" />
+ </root>
+</configuration>
+
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/socket/ssl/client.xml b/logback-examples/src/main/java/chapters/appenders/socket/ssl/client.xml
new file mode 100644
index 0000000..f038fe5
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/socket/ssl/client.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- Sample SSLSocketAppender configuration. -->
+<!-- ==================================================================== -->
+
+<configuration debug="true">
+
+ <appender name="SOCKET" class="ch.qos.logback.classic.net.SSLSocketAppender">
+ <remoteHost>${host}</remoteHost>
+ <port>${port}</port>
+ <reconnectionDelay>10000</reconnectionDelay>
+ <ssl>
+ <trustStore>
+ <location>${truststore}</location>
+ <password>${password}</password>
+ </trustStore>
+ </ssl>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="SOCKET" />
+ </root>
+
+</configuration>
+
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/socket/ssl/keystore.jks b/logback-examples/src/main/java/chapters/appenders/socket/ssl/keystore.jks
new file mode 100644
index 0000000..274e4d1
Binary files /dev/null and b/logback-examples/src/main/java/chapters/appenders/socket/ssl/keystore.jks differ
diff --git a/logback-examples/src/main/java/chapters/appenders/socket/ssl/server.xml b/logback-examples/src/main/java/chapters/appenders/socket/ssl/server.xml
new file mode 100644
index 0000000..9348677
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/appenders/socket/ssl/server.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- Sample SimpleSSLSocketServer configuration. -->
+<!-- ==================================================================== -->
+
+<configuration debug="true">
+
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="CONSOLE" />
+ </root>
+
+</configuration>
+
+
+
diff --git a/logback-examples/src/main/java/chapters/appenders/socket/ssl/truststore.jks b/logback-examples/src/main/java/chapters/appenders/socket/ssl/truststore.jks
new file mode 100644
index 0000000..93498fb
Binary files /dev/null and b/logback-examples/src/main/java/chapters/appenders/socket/ssl/truststore.jks differ
diff --git a/logback-examples/src/main/java/chapters/appenders/sub/sample/Bar.java b/logback-examples/src/main/java/chapters/appenders/sub/sample/Bar.java
index 2abde9e..d34ddb1 100644
--- a/logback-examples/src/main/java/chapters/appenders/sub/sample/Bar.java
+++ b/logback-examples/src/main/java/chapters/appenders/sub/sample/Bar.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,18 +17,18 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Bar {
- Logger logger = LoggerFactory.getLogger(Bar.class);
-
- public String toString() {
- return "test 123";
- }
-
- public void createLoggingRequest() {
- subMethodToCreateRequest();
- }
-
- // this is done to create a stacktrace of more than one line
- private void subMethodToCreateRequest() {
- logger.error("error-level request", new Exception("test exception"));
- }
+ Logger logger = LoggerFactory.getLogger(Bar.class);
+
+ public String toString() {
+ return "test 123";
+ }
+
+ public void createLoggingRequest() {
+ subMethodToCreateRequest();
+ }
+
+ //this is done to create a stacktrace of more than one line
+ private void subMethodToCreateRequest() {
+ logger.error("error-level request", new Exception("test exception"));
+ }
}
diff --git a/logback-examples/src/main/java/chapters/architecture/Bar.java b/logback-examples/src/main/java/chapters/architecture/Bar.java
index 16acc66..3fa0fbc 100644
--- a/logback-examples/src/main/java/chapters/architecture/Bar.java
+++ b/logback-examples/src/main/java/chapters/architecture/Bar.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,9 +17,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class Bar {
- Logger logger = LoggerFactory.getLogger(Bar.class);
+ Logger logger = LoggerFactory.getLogger(Bar.class);
- public void doIt() {
- logger.debug("doing my job");
- }
+ public void doIt() {
+ logger.debug("doing my job");
+ }
}
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/architecture/MyAppWithConfigFile.java b/logback-examples/src/main/java/chapters/architecture/MyAppWithConfigFile.java
index 42c377d..828104c 100644
--- a/logback-examples/src/main/java/chapters/architecture/MyAppWithConfigFile.java
+++ b/logback-examples/src/main/java/chapters/architecture/MyAppWithConfigFile.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,22 +24,22 @@ import ch.qos.logback.core.util.StatusPrinter;
public class MyAppWithConfigFile {
- public static void main(String[] args) {
- Logger logger = LoggerFactory.getLogger(MyAppWithConfigFile.class);
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
-
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- lc.reset();
- configurator.setContext(lc);
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- StatusPrinter.print(lc.getStatusManager());
- }
- logger.info("Entering application.");
- Bar bar = new Bar();
- bar.doIt();
- logger.info("Exiting application.");
+ public static void main(String[] args) {
+ Logger logger = LoggerFactory.getLogger(MyAppWithConfigFile.class);
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ try {
+ JoranConfigurator configurator = new JoranConfigurator();
+ lc.reset();
+ configurator.setContext(lc);
+ configurator.doConfigure(args[0]);
+ } catch (JoranException je) {
+ StatusPrinter.print(lc.getStatusManager());
}
+ logger.info("Entering application.");
+ Bar bar = new Bar();
+ bar.doIt();
+ logger.info("Exiting application.");
+
+ }
}
diff --git a/logback-examples/src/main/java/chapters/architecture/SelectionRule.java b/logback-examples/src/main/java/chapters/architecture/SelectionRule.java
index daea3ce..f656c04 100644
--- a/logback-examples/src/main/java/chapters/architecture/SelectionRule.java
+++ b/logback-examples/src/main/java/chapters/architecture/SelectionRule.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,34 +18,34 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*/
public class SelectionRule {
- public static void main(String[] args) {
- // get a logger instance named "com.foo". Let us further assume that the
- // logger is of type ch.qos.logback.classic.Logger so that we can
- // set its level
- ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.foo");
- // set its Level to INFO. The setLevel() method requires a logback logger
- logger.setLevel(Level.INFO);
+ public static void main(String[] args) {
+ // get a logger instance named "com.foo". Let us further assume that the
+ // logger is of type ch.qos.logback.classic.Logger so that we can
+ // set its level
+ ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.foo");
+ //set its Level to INFO. The setLevel() method requires a logback logger
+ logger.setLevel(Level.INFO);
- Logger barlogger = LoggerFactory.getLogger("com.foo.Bar");
+ Logger barlogger = LoggerFactory.getLogger("com.foo.Bar");
- // This request is enabled, because WARN >= INFO
- logger.warn("Low fuel level.");
+ // This request is enabled, because WARN >= INFO
+ logger.warn("Low fuel level.");
- // This request is disabled, because DEBUG < INFO.
- logger.debug("Starting search for nearest gas station.");
+ // This request is disabled, because DEBUG < INFO.
+ logger.debug("Starting search for nearest gas station.");
- // The logger instance barlogger, named "com.foo.Bar",
- // will inherit its level from the logger named
- // "com.foo" Thus, the following request is enabled
- // because INFO >= INFO.
- barlogger.info("Located nearest gas station.");
+ // The logger instance barlogger, named "com.foo.Bar",
+ // will inherit its level from the logger named
+ // "com.foo" Thus, the following request is enabled
+ // because INFO >= INFO.
+ barlogger.info("Located nearest gas station.");
- // This request is disabled, because DEBUG < INFO.
- barlogger.debug("Exiting gas station search");
+ // This request is disabled, because DEBUG < INFO.
+ barlogger.debug("Exiting gas station search");
- }
+ }
}
diff --git a/logback-examples/src/main/java/chapters/architecture/sample-config-1.xml b/logback-examples/src/main/java/chapters/architecture/sample-config-1.xml
new file mode 100644
index 0000000..d65744d
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/architecture/sample-config-1.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <appender name="STDOUT"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </layout>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/architecture/sample-config-2.xml b/logback-examples/src/main/java/chapters/architecture/sample-config-2.xml
new file mode 100644
index 0000000..f22a27e
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/architecture/sample-config-2.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <appender name="STDOUT"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <pattern>%-4relative [%thread] %-5level %class - %msg%n</pattern>
+ </layout>
+ </appender>
+
+ <appender name="FILE"
+ class="ch.qos.logback.core.FileAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <pattern>%-4relative [%thread] %-5level %class - %msg%n</pattern>
+ </layout>
+ <File>sample-log.txt</File>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/architecture/sample-config-3.xml b/logback-examples/src/main/java/chapters/architecture/sample-config-3.xml
new file mode 100644
index 0000000..d057e9f
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/architecture/sample-config-3.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <appender name="STDOUT"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <pattern>%-4relative [%thread] %-5level %class - %msg%n</pattern>
+ </layout>
+ </appender>
+
+ <appender name="FILE"
+ class="ch.qos.logback.core.FileAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <pattern>%-4relative [%thread] %-5level %class - %msg%n</pattern>
+ </layout>
+ <File>sample-log.txt</File>
+ </appender>
+
+ <logger name="chapters.architecture" level="info" />
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/configuration/AddStatusListenerApp.java b/logback-examples/src/main/java/chapters/configuration/AddStatusListenerApp.java
index b514cfc..4c70f6d 100644
--- a/logback-examples/src/main/java/chapters/configuration/AddStatusListenerApp.java
+++ b/logback-examples/src/main/java/chapters/configuration/AddStatusListenerApp.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,18 +23,19 @@ import ch.qos.logback.core.status.StatusManager;
public class AddStatusListenerApp {
- public static void main(String[] args) throws JoranException {
+ public static void main(String[] args) throws JoranException {
+
+
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ StatusManager statusManager = lc.getStatusManager();
+ OnConsoleStatusListener onConsoleListener = new OnConsoleStatusListener();
+ statusManager.add(onConsoleListener);
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- StatusManager statusManager = lc.getStatusManager();
- OnConsoleStatusListener onConsoleListener = new OnConsoleStatusListener();
- statusManager.add(onConsoleListener);
+ Logger logger = LoggerFactory.getLogger("myApp");
+ logger.info("Entering application.");
- Logger logger = LoggerFactory.getLogger("myApp");
- logger.info("Entering application.");
-
- Foo foo = new Foo();
- foo.doIt();
- logger.info("Exiting application.");
- }
+ Foo foo = new Foo();
+ foo.doIt();
+ logger.info("Exiting application.");
+ }
}
diff --git a/logback-examples/src/main/java/chapters/configuration/Foo.java b/logback-examples/src/main/java/chapters/configuration/Foo.java
index fd727cf..174fc5f 100644
--- a/logback-examples/src/main/java/chapters/configuration/Foo.java
+++ b/logback-examples/src/main/java/chapters/configuration/Foo.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,10 +16,11 @@ package chapters.configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
public class Foo {
- static final Logger logger = LoggerFactory.getLogger(Foo.class);
+ static final Logger logger = LoggerFactory.getLogger(Foo.class);
- public void doIt() {
- logger.debug("Did it again!");
- }
+ public void doIt() {
+ logger.debug("Did it again!");
+ }
}
diff --git a/logback-examples/src/main/java/chapters/configuration/MyApp1.java b/logback-examples/src/main/java/chapters/configuration/MyApp1.java
index 76bd512..498bdac 100644
--- a/logback-examples/src/main/java/chapters/configuration/MyApp1.java
+++ b/logback-examples/src/main/java/chapters/configuration/MyApp1.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,14 +16,15 @@ package chapters.configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
public class MyApp1 {
- final static Logger logger = LoggerFactory.getLogger(MyApp1.class);
+ final static Logger logger = LoggerFactory.getLogger(MyApp1.class);
- public static void main(String[] args) {
- logger.info("Entering application.");
+ public static void main(String[] args) {
+ logger.info("Entering application.");
- Foo foo = new Foo();
- foo.doIt();
- logger.info("Exiting application.");
- }
+ Foo foo = new Foo();
+ foo.doIt();
+ logger.info("Exiting application.");
+ }
}
diff --git a/logback-examples/src/main/java/chapters/configuration/MyApp2.java b/logback-examples/src/main/java/chapters/configuration/MyApp2.java
index d4ab3a5..3af3687 100644
--- a/logback-examples/src/main/java/chapters/configuration/MyApp2.java
+++ b/logback-examples/src/main/java/chapters/configuration/MyApp2.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,17 +20,17 @@ import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.util.StatusPrinter;
public class MyApp2 {
- final static Logger logger = LoggerFactory.getLogger(MyApp2.class);
+ final static Logger logger = LoggerFactory.getLogger(MyApp2.class);
- public static void main(String[] args) {
- // assume SLF4J is bound to logback in the current environment
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- // print logback's internal status
- StatusPrinter.print(lc);
-
- logger.info("Entering application.");
- Foo foo = new Foo();
- foo.doIt();
- logger.info("Exiting application.");
- }
+ public static void main(String[] args) {
+ // assume SLF4J is bound to logback in the current environment
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ // print logback's internal status
+ StatusPrinter.print(lc);
+
+ logger.info("Entering application.");
+ Foo foo = new Foo();
+ foo.doIt();
+ logger.info("Exiting application.");
+ }
}
diff --git a/logback-examples/src/main/java/chapters/configuration/MyApp3.java b/logback-examples/src/main/java/chapters/configuration/MyApp3.java
index 3000e8a..802bb0f 100644
--- a/logback-examples/src/main/java/chapters/configuration/MyApp3.java
+++ b/logback-examples/src/main/java/chapters/configuration/MyApp3.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,28 +26,28 @@ import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.util.StatusPrinter;
public class MyApp3 {
- final static Logger logger = LoggerFactory.getLogger(MyApp3.class);
+ final static Logger logger = LoggerFactory.getLogger(MyApp3.class);
- public static void main(String[] args) {
- // assume SLF4J is bound to logback in the current environment
- LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+ public static void main(String[] args) {
+ // assume SLF4J is bound to logback in the current environment
+ LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(context);
- // Call context.reset() to clear any previous configuration, e.g. default
- // configuration. For multi-step configuration, omit calling context.reset().
- context.reset();
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- // StatusPrinter will handle this
- }
- StatusPrinter.printInCaseOfErrorsOrWarnings(context);
+ try {
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(context);
+ // Call context.reset() to clear any previous configuration, e.g. default
+ // configuration. For multi-step configuration, omit calling context.reset().
+ context.reset();
+ configurator.doConfigure(args[0]);
+ } catch (JoranException je) {
+ // StatusPrinter will handle this
+ }
+ StatusPrinter.printInCaseOfErrorsOrWarnings(context);
- logger.info("Entering application.");
+ logger.info("Entering application.");
- Foo foo = new Foo();
- foo.doIt();
- logger.info("Exiting application.");
- }
+ Foo foo = new Foo();
+ foo.doIt();
+ logger.info("Exiting application.");
+ }
}
diff --git a/logback-examples/src/main/java/chapters/configuration/additivityFlag.xml b/logback-examples/src/main/java/chapters/configuration/additivityFlag.xml
new file mode 100644
index 0000000..38b7422
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/additivityFlag.xml
@@ -0,0 +1,26 @@
+<configuration>
+
+ <appender name="FILE"
+ class="ch.qos.logback.core.FileAppender">
+ <file>foo.log</file>
+ <encoder>
+ <Pattern>
+ %date %level [%thread] %logger{10} [%file : %line] %msg%n
+ </Pattern>
+ </encoder>
+ </appender>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <Pattern>%msg%n</Pattern>
+ </encoder>
+ </appender>
+
+ <logger name="chapters.configuration.Foo" additivity="false">
+ <appender-ref ref="FILE" />
+ </logger>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/containingConfig.xml b/logback-examples/src/main/java/chapters/configuration/containingConfig.xml
new file mode 100644
index 0000000..99470ad
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/containingConfig.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <include file="src/main/java/chapters/configuration/includedConfig.xml" />
+
+ <root level="DEBUG">
+ <appender-ref ref="includedConsole" />
+ </root>
+
+
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/configuration/contextName.xml b/logback-examples/src/main/java/chapters/configuration/contextName.xml
new file mode 100644
index 0000000..09e7df9
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/contextName.xml
@@ -0,0 +1,15 @@
+<configuration>
+
+ <contextName>myAppName</contextName>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/contextScopedVariable.xml b/logback-examples/src/main/java/chapters/configuration/contextScopedVariable.xml
new file mode 100644
index 0000000..cc5d22b
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/contextScopedVariable.xml
@@ -0,0 +1,15 @@
+<configuration>
+
+ <property scope="context" name="nodeId" value="firstNode"/>
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>/opt/${noteId}/myApp.log</file>
+ <encoder>
+ <pattern>%msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="FILE"/>
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/duplicate.xml b/logback-examples/src/main/java/chapters/configuration/duplicate.xml
new file mode 100644
index 0000000..eddf9db
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/duplicate.xml
@@ -0,0 +1,19 @@
+<configuration>
+
+ <appender name="STDOUT"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+ </pattern>
+ </encoder>
+ </appender>
+
+ <logger name="chapters.configuration">
+ <appender-ref ref="STDOUT" />
+ </logger>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/includedConfig.xml b/logback-examples/src/main/java/chapters/configuration/includedConfig.xml
new file mode 100644
index 0000000..83c2d85
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/includedConfig.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<included>
+
+ <appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
+ <!-- encoders are assigned by default the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
+ <encoder>
+ <param name="Pattern" value="%d - %m%n" />
+ </encoder>
+ </appender>
+
+</included>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/insertFromJNDI.xml b/logback-examples/src/main/java/chapters/configuration/insertFromJNDI.xml
new file mode 100644
index 0000000..4b58ba9
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/insertFromJNDI.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<configuration>
+ <insertFromJNDI env-entry-name="java:comp/env/appName" as="appName" />
+ <contextName>${appName}</contextName>
+
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <!-- encoders are assigned by default the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
+ <encoder>
+ <pattern>%d %contextName %level %msg %logger{50}%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="CONSOLE" />
+ </root>
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/configuration/multiple.xml b/logback-examples/src/main/java/chapters/configuration/multiple.xml
new file mode 100644
index 0000000..9206177
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/multiple.xml
@@ -0,0 +1,21 @@
+<configuration>
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>myApp.log</file>
+ <!-- encoders are assigned by default the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
+ <encoder>
+ <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="FILE" />
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml b/logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml
new file mode 100644
index 0000000..f7c166f
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration debug="false">
+
+ <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <!-- encoders are assigned by default the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
+ <encoder>
+ <pattern>
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+ </pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/restricted.xml b/logback-examples/src/main/java/chapters/configuration/restricted.xml
new file mode 100644
index 0000000..d87cac7
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/restricted.xml
@@ -0,0 +1,25 @@
+<configuration>
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>myApp.log</file>
+ <!-- encoders are assigned by default the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
+ <encoder>
+ <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <logger name="chapters.configuration">
+ <appender-ref ref="FILE" />
+ </logger>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/sample0.xml b/logback-examples/src/main/java/chapters/configuration/sample0.xml
new file mode 100644
index 0000000..2a7f627
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/sample0.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<configuration>
+
+ <appender name="STDOUT"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <!-- encoders are assigned by default the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
+
diff --git a/logback-examples/src/main/java/chapters/configuration/sample1.xml b/logback-examples/src/main/java/chapters/configuration/sample1.xml
new file mode 100644
index 0000000..cbf6197
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/sample1.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<configuration debug="true">
+
+ <appender name="STDOUT"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <!-- encoders are assigned by default the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
+
diff --git a/logback-examples/src/main/java/chapters/configuration/sample2.xml b/logback-examples/src/main/java/chapters/configuration/sample2.xml
new file mode 100644
index 0000000..41cfd02
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/sample2.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<configuration>
+
+ <appender name="STDOUT"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <!-- encoders are assigned by default the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
+ <encoder>
+ <pattern>
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+ </pattern>
+ </encoder>
+ </appender>
+
+ <logger name="chapters.configuration" level="INFO" />
+
+ <!-- Strictly speaking, the level attribute is not necessary since -->
+ <!-- the level of the root level is set to DEBUG by default. -->
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/sample3.xml b/logback-examples/src/main/java/chapters/configuration/sample3.xml
new file mode 100644
index 0000000..3b2b9f7
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/sample3.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<configuration>
+
+ <appender name="STDOUT"
+ class="ch.qos.logback.core.ConsoleAppender">
+
+ <!-- encoders are assigned by default the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
+ <encoder>
+ <pattern>
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+ </pattern>
+ </encoder>
+ </appender>
+
+ <logger name="chapters.configuration" level="INFO" />
+
+ <logger name="chapters.configuration.Foo" level="DEBUG" />
+
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/sample4.xml b/logback-examples/src/main/java/chapters/configuration/sample4.xml
new file mode 100644
index 0000000..f9ee7f3
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/sample4.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<configuration>
+
+ <appender name="STDOUT"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <!-- encoders are assigned by default the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
+ <encoder>
+ <pattern>
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+ </pattern>
+ </encoder>
+ </appender>
+
+ <logger name="chapters.configuration" level="INFO" />
+
+ <root level="OFF">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/scan1.xml b/logback-examples/src/main/java/chapters/configuration/scan1.xml
new file mode 100644
index 0000000..fa48249
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/scan1.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration scan="true">
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <!-- encoders are assigned by default the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
+ <encoder>
+ <pattern>%d [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/scan2.xml b/logback-examples/src/main/java/chapters/configuration/scan2.xml
new file mode 100644
index 0000000..70aec8e
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/scan2.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration scan="true" scanPeriod="30 seconds">
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/variableSubstitution1.xml b/logback-examples/src/main/java/chapters/configuration/variableSubstitution1.xml
new file mode 100644
index 0000000..8e79db1
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/variableSubstitution1.xml
@@ -0,0 +1,15 @@
+<configuration>
+
+ <property name="USER_HOME" value="/home/sebastien" />
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>${USER_HOME}/myApp.log</file>
+ <encoder>
+ <pattern>%msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/variableSubstitution2.xml b/logback-examples/src/main/java/chapters/configuration/variableSubstitution2.xml
new file mode 100644
index 0000000..c6bd1fe
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/variableSubstitution2.xml
@@ -0,0 +1,13 @@
+<configuration>
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>${USER_HOME}/myApp.log</file>
+ <encoder>
+ <pattern>%msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/variableSubstitution3.xml b/logback-examples/src/main/java/chapters/configuration/variableSubstitution3.xml
new file mode 100644
index 0000000..3121987
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/variableSubstitution3.xml
@@ -0,0 +1,15 @@
+<configuration>
+
+ <property file="src/main/java/chapters/configuration/variables1.properties" />
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>${USER_HOME}/myApp.log</file>
+ <encoder>
+ <pattern>%msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/variableSubstitution4.xml b/logback-examples/src/main/java/chapters/configuration/variableSubstitution4.xml
new file mode 100644
index 0000000..e6b0f89
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/variableSubstitution4.xml
@@ -0,0 +1,15 @@
+<configuration>
+
+ <property file="src/main/java/chapters/configuration/variables2.properties" />
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>${destination}/myApp.log</file>
+ <encoder>
+ <pattern>%msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/variables1.properties b/logback-examples/src/main/java/chapters/configuration/variables1.properties
new file mode 100644
index 0000000..7e0238f
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/variables1.properties
@@ -0,0 +1 @@
+USER_HOME=/home/sebastien
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/configuration/variables2.properties b/logback-examples/src/main/java/chapters/configuration/variables2.properties
new file mode 100644
index 0000000..d021f64
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/configuration/variables2.properties
@@ -0,0 +1,3 @@
+USER_HOME=/home/sebastien
+fileName=myApp.log
+destination=${USER_HOME}/${fileName}
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/filters/FilterEvents.java b/logback-examples/src/main/java/chapters/filters/FilterEvents.java
index 547bd84..0b9ab54 100644
--- a/logback-examples/src/main/java/chapters/filters/FilterEvents.java
+++ b/logback-examples/src/main/java/chapters/filters/FilterEvents.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,35 +25,35 @@ import ch.qos.logback.core.joran.spi.JoranException;
public class FilterEvents {
- public static void main(String[] args) throws InterruptedException {
- if (args.length == 0) {
- System.out.println("A configuration file must be passed as a parameter.");
- return;
- }
-
- Logger logger = (Logger) LoggerFactory.getLogger(FilterEvents.class);
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
-
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- lc.reset();
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- je.printStackTrace();
- }
+ public static void main(String[] args) throws InterruptedException {
+ if (args.length == 0) {
+ System.out.println("A configuration file must be passed as a parameter.");
+ return;
+ }
+
+ Logger logger = (Logger) LoggerFactory.getLogger(FilterEvents.class);
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- for (int i = 0; i < 10; i++) {
- if (i == 3) {
- MDC.put("username", "sebastien");
- logger.debug("logging statement {}", i);
- MDC.remove("username");
- } else if (i == 6) {
- Marker billing = MarkerFactory.getMarker("billing");
- logger.error(billing, "billing statement {}", i);
- } else {
- logger.info("logging statement {}", i);
- }
- }
+ try {
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ lc.reset();
+ configurator.doConfigure(args[0]);
+ } catch (JoranException je) {
+ je.printStackTrace();
+ }
+
+ for (int i = 0; i < 10; i++) {
+ if (i == 3) {
+ MDC.put("username", "sebastien");
+ logger.debug("logging statement {}", i);
+ MDC.remove("username");
+ } else if (i == 6) {
+ Marker billing = MarkerFactory.getMarker("billing");
+ logger.error(billing, "billing statement {}", i);
+ } else {
+ logger.info("logging statement {}", i);
+ }
}
+ }
}
diff --git a/logback-examples/src/main/java/chapters/filters/GoMDC.java b/logback-examples/src/main/java/chapters/filters/GoMDC.java
index 493b51c..cb7a3da 100644
--- a/logback-examples/src/main/java/chapters/filters/GoMDC.java
+++ b/logback-examples/src/main/java/chapters/filters/GoMDC.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,24 +24,25 @@ import ch.qos.logback.core.util.StatusPrinter;
public class GoMDC {
- public static void main(String[] args) {
- Logger logger = LoggerFactory.getLogger(GoMDC.class);
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
-
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- lc.reset();
- configurator.doConfigure("mdcFilter.xml");
-
- } catch (JoranException je) {
- StatusPrinter.print(lc);
- }
-
- logger.debug("I know me " + 0);
- MDC.put("key", "val");
- logger.debug("I know me " + 1);
-
- StatusPrinter.print(lc);
+ public static void main(String[] args) {
+ Logger logger = LoggerFactory
+ .getLogger(GoMDC.class);
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+
+ try {
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ lc.reset();
+ configurator.doConfigure("mdcFilter.xml");
+
+ } catch (JoranException je) {
+ StatusPrinter.print(lc);
}
+
+ logger.debug("I know me " + 0);
+ MDC.put("key", "val");
+ logger.debug("I know me " + 1);
+
+ StatusPrinter.print(lc);
+ }
}
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/filters/SampleFilter.java b/logback-examples/src/main/java/chapters/filters/SampleFilter.java
index 76ef8f4..8983d28 100644
--- a/logback-examples/src/main/java/chapters/filters/SampleFilter.java
+++ b/logback-examples/src/main/java/chapters/filters/SampleFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,12 +19,12 @@ import ch.qos.logback.core.spi.FilterReply;
public class SampleFilter extends Filter<ILoggingEvent> {
- @Override
- public FilterReply decide(ILoggingEvent event) {
- if (event.getMessage() != null && event.getMessage().contains("sample")) {
- return FilterReply.ACCEPT;
- } else {
- return FilterReply.NEUTRAL;
- }
+ @Override
+ public FilterReply decide(ILoggingEvent event) {
+ if (event.getMessage() != null && event.getMessage().contains("sample")) {
+ return FilterReply.ACCEPT;
+ } else {
+ return FilterReply.NEUTRAL;
}
+ }
}
diff --git a/logback-examples/src/main/java/chapters/filters/SampleTurboFilter.java b/logback-examples/src/main/java/chapters/filters/SampleTurboFilter.java
index 34206c9..39fb641 100644
--- a/logback-examples/src/main/java/chapters/filters/SampleTurboFilter.java
+++ b/logback-examples/src/main/java/chapters/filters/SampleTurboFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,36 +23,37 @@ import ch.qos.logback.core.spi.FilterReply;
public class SampleTurboFilter extends TurboFilter {
- String marker;
- Marker markerToAccept;
+ String marker;
+ Marker markerToAccept;
- @Override
- public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
-
- if (!isStarted()) {
- return FilterReply.NEUTRAL;
- }
-
- if ((markerToAccept.equals(marker))) {
- return FilterReply.ACCEPT;
- } else {
- return FilterReply.NEUTRAL;
- }
+ @Override
+ public FilterReply decide(Marker marker, Logger logger, Level level,
+ String format, Object[] params, Throwable t) {
+
+ if (!isStarted()) {
+ return FilterReply.NEUTRAL;
}
- public String getMarker() {
- return marker;
+ if ((markerToAccept.equals(marker))) {
+ return FilterReply.ACCEPT;
+ } else {
+ return FilterReply.NEUTRAL;
}
+ }
- public void setMarker(String markerStr) {
- this.marker = markerStr;
- }
+ public String getMarker() {
+ return marker;
+ }
+
+ public void setMarker(String markerStr) {
+ this.marker = markerStr;
+ }
- @Override
- public void start() {
- if (marker != null && marker.trim().length() > 0) {
- markerToAccept = MarkerFactory.getMarker(marker);
- super.start();
- }
+ @Override
+ public void start() {
+ if (marker != null && marker.trim().length() > 0) {
+ markerToAccept = MarkerFactory.getMarker(marker);
+ super.start();
}
+ }
}
diff --git a/logback-examples/src/main/java/chapters/filters/accessEventEvaluator.xml b/logback-examples/src/main/java/chapters/filters/accessEventEvaluator.xml
new file mode 100644
index 0000000..e618ac9
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/filters/accessEventEvaluator.xml
@@ -0,0 +1,17 @@
+<configuration>
+ <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
+ <evaluator>
+ <expression>event.getStatusCode() == 404</expression>
+ </evaluator>
+ <onMismatch>DENY</onMismatch>
+ <onMatch>ACCEPT</onMatch>
+ </filter>
+
+ <encoder><pattern>%h %l %u %t %r %s %b</pattern></encoder>
+ </appender>
+
+ <appender-ref ref="STDOUT" />
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/filters/accessEventEvaluator2.xml b/logback-examples/src/main/java/chapters/filters/accessEventEvaluator2.xml
new file mode 100644
index 0000000..f80344e
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/filters/accessEventEvaluator2.xml
@@ -0,0 +1,21 @@
+<configuration>
+ <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
+ <evaluator name="Eval404">
+ <expression>
+ (event.getStatusCode() == 404)
+ && <!-- ampersand characters need to be escaped -->
+ !(event.getRequestURI().contains(".css"))
+ </expression>
+ </evaluator>
+ <onMismatch>DENY</onMismatch>
+ <onMatch>ACCEPT</onMatch>
+ </filter>
+
+ <encoder><pattern>%h %l %u %t %r %s %b</pattern></encoder>
+ </appender>
+
+ <appender-ref ref="STDOUT" />
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/filters/basicConfiguration.xml b/logback-examples/src/main/java/chapters/filters/basicConfiguration.xml
new file mode 100644
index 0000000..83fd046
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/filters/basicConfiguration.xml
@@ -0,0 +1,12 @@
+<configuration>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <pattern>%-4relative [%thread] %-5level %logger - %msg%n</pattern>
+ </layout>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/filters/basicEventEvaluator.xml b/logback-examples/src/main/java/chapters/filters/basicEventEvaluator.xml
new file mode 100644
index 0000000..f6a1e3e
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/filters/basicEventEvaluator.xml
@@ -0,0 +1,19 @@
+<configuration debug="true">
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
+ <evaluator>
+ <expression>message.contains("billing")</expression>
+ </evaluator>
+ <OnMismatch>NEUTRAL</OnMismatch>
+ <OnMatch>DENY</OnMatch>
+ </filter>
+ <layout>
+ <pattern>%-4relative [%thread] %-5level %logger - %msg%n</pattern>
+ </layout>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/filters/duplicateMessage.xml b/logback-examples/src/main/java/chapters/filters/duplicateMessage.xml
new file mode 100644
index 0000000..9637829
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/filters/duplicateMessage.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <turboFilter class="ch.qos.logback.classic.turbo.DuplicateMessageFilter" />
+
+ <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%date [%thread] %-5level %logger - %msg%n</Pattern>
+ </layout>
+ </appender>
+
+ <root level="info">
+ <appender-ref ref="console" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/filters/evaluatorWithMatcher.xml b/logback-examples/src/main/java/chapters/filters/evaluatorWithMatcher.xml
new file mode 100644
index 0000000..f2aab92
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/filters/evaluatorWithMatcher.xml
@@ -0,0 +1,25 @@
+<configuration debug="true">
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
+ <evaluator>
+
+ <matcher>
+ <Name>odd</Name>
+ <regex>statement [13579]</regex>
+ </matcher>
+
+ <expression>odd.matches(formattedMessage)</expression>
+ </evaluator>
+ <OnMismatch>NEUTRAL</OnMismatch>
+ <OnMatch>DENY</OnMatch>
+ </filter>
+ <layout>
+ <pattern>%-4relative [%thread] %-5level %logger - %msg%n</pattern>
+ </layout>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/filters/levelFilterConfig.xml b/logback-examples/src/main/java/chapters/filters/levelFilterConfig.xml
new file mode 100644
index 0000000..d8e777a
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/filters/levelFilterConfig.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<configuration>
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <filter class="ch.qos.logback.classic.filter.LevelFilter">
+ <level>INFO</level>
+ <onMatch>ACCEPT</onMatch>
+ <onMismatch>DENY</onMismatch>
+ </filter>
+ <encoder>
+ <pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>
+ </encoder>
+ </appender>
+ <root level="DEBUG">
+ <appender-ref ref="CONSOLE" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/filters/mdcfilter.xml b/logback-examples/src/main/java/chapters/filters/mdcfilter.xml
new file mode 100644
index 0000000..9963e61
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/filters/mdcfilter.xml
@@ -0,0 +1,23 @@
+<configuration>
+
+ <appender name="STDOUT"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%-4relative [%thread] %-5level %X{testKey} - %msg%n"</Pattern>
+ </layout>
+
+ <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
+ <Name>myFilter</Name>
+ <OnMatch>DENY</OnMatch>
+ <Evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
+ <Name>mdcEvaluator</Name>
+ <Expression>mdc!=null && "val".equals(mdc.get("key"))</Expression>
+ </Evaluator>
+ </filter>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
+
diff --git a/logback-examples/src/main/java/chapters/filters/sampleFilterConfig.xml b/logback-examples/src/main/java/chapters/filters/sampleFilterConfig.xml
new file mode 100644
index 0000000..9e711e9
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/filters/sampleFilterConfig.xml
@@ -0,0 +1,16 @@
+<configuration>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <filter class="chapters.filters.SampleFilter" />
+
+ <encoder>
+ <pattern>
+ %-4relative [%thread] %-5level %logger - %msg%n
+ </pattern>
+ </encoder>
+ </appender>
+
+ <root>
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml b/logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml
new file mode 100644
index 0000000..428f28d
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml
@@ -0,0 +1,16 @@
+<configuration>
+
+ <turboFilter class="chapters.filters.SampleTurboFilter">
+ <Marker>sample</Marker>
+ </turboFilter>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <pattern>%-4relative [%thread] %-5level %logger - %msg%n</pattern>
+ </layout>
+ </appender>
+
+ <root>
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/filters/thresholdFilterConfig.xml b/logback-examples/src/main/java/chapters/filters/thresholdFilterConfig.xml
new file mode 100644
index 0000000..60697ec
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/filters/thresholdFilterConfig.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<configuration>
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+
+ <!-- deny all events with a level below INFO, that is TRACE and DEBUG -->
+ <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+ <level>INFO</level>
+ </filter>
+ <encoder>
+ <pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+
+ <root level="DEBUG">
+ <appender-ref ref="CONSOLE" />
+ </root>
+
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/filters/turboFilters.xml b/logback-examples/src/main/java/chapters/filters/turboFilters.xml
new file mode 100644
index 0000000..6e1b26b
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/filters/turboFilters.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <turboFilter class="ch.qos.logback.classic.turbo.MDCFilter">
+ <MDCKey>username</MDCKey>
+ <Value>sebastien</Value>
+ <OnMatch>ACCEPT</OnMatch>
+ </turboFilter>
+
+ <turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
+ <Marker>billing</Marker>
+ <OnMatch>DENY</OnMatch>
+ </turboFilter>
+
+ <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%date [%thread] %-5level %logger - %msg%n</Pattern>
+ </layout>
+ </appender>
+
+ <root level="info">
+ <appender-ref ref="console" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/introduction/HelloWorld1.java b/logback-examples/src/main/java/chapters/introduction/HelloWorld1.java
index 9f6b9d0..bc2f2b4 100644
--- a/logback-examples/src/main/java/chapters/introduction/HelloWorld1.java
+++ b/logback-examples/src/main/java/chapters/introduction/HelloWorld1.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,9 +18,9 @@ import org.slf4j.LoggerFactory;
public class HelloWorld1 {
- public static void main(String[] args) {
+ public static void main(String[] args) {
- Logger logger = LoggerFactory.getLogger("chapters.introduction.HelloWorld1");
- logger.debug("Hello world.");
- }
+ Logger logger = LoggerFactory.getLogger("chapters.introduction.HelloWorld1");
+ logger.debug("Hello world.");
+ }
}
diff --git a/logback-examples/src/main/java/chapters/introduction/HelloWorld2.java b/logback-examples/src/main/java/chapters/introduction/HelloWorld2.java
index 97a8c92..cb3d533 100644
--- a/logback-examples/src/main/java/chapters/introduction/HelloWorld2.java
+++ b/logback-examples/src/main/java/chapters/introduction/HelloWorld2.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,12 +20,12 @@ import ch.qos.logback.core.util.StatusPrinter;
public class HelloWorld2 {
- public static void main(String[] args) {
- Logger logger = LoggerFactory.getLogger("chapters.introduction.HelloWorld2");
- logger.debug("Hello world.");
+ public static void main(String[] args) {
+ Logger logger = LoggerFactory.getLogger("chapters.introduction.HelloWorld2");
+ logger.debug("Hello world.");
- // print internal state
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- StatusPrinter.print(lc);
- }
+ // print internal state
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ StatusPrinter.print(lc);
+ }
}
diff --git a/logback-examples/src/main/java/chapters/layouts/CallerEvaluatorExample.java b/logback-examples/src/main/java/chapters/layouts/CallerEvaluatorExample.java
index b235b2e..98f87e5 100644
--- a/logback-examples/src/main/java/chapters/layouts/CallerEvaluatorExample.java
+++ b/logback-examples/src/main/java/chapters/layouts/CallerEvaluatorExample.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,26 +23,26 @@ import ch.qos.logback.core.util.StatusPrinter;
public class CallerEvaluatorExample {
- public static void main(String[] args) {
- Logger logger = LoggerFactory.getLogger(CallerEvaluatorExample.class);
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ public static void main(String[] args) {
+ Logger logger = LoggerFactory.getLogger(CallerEvaluatorExample.class);
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- lc.reset();
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- // StatusPrinter will handle this
- }
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
+ try {
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ lc.reset();
+ configurator.doConfigure(args[0]);
+ } catch (JoranException je) {
+ // StatusPrinter will handle this
+ }
+ StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
- for (int i = 0; i < 5; i++) {
- if (i == 3) {
- logger.debug("who calls thee?");
- } else {
- logger.debug("I know me " + i);
- }
- }
+ for (int i = 0; i < 5; i++) {
+ if (i == 3) {
+ logger.debug("who calls thee?");
+ } else {
+ logger.debug("I know me " + i);
+ }
}
+ }
}
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/layouts/ExceptionEvaluatorExample.java b/logback-examples/src/main/java/chapters/layouts/ExceptionEvaluatorExample.java
index 169236d..f46ce69 100644
--- a/logback-examples/src/main/java/chapters/layouts/ExceptionEvaluatorExample.java
+++ b/logback-examples/src/main/java/chapters/layouts/ExceptionEvaluatorExample.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,26 +23,27 @@ import ch.qos.logback.core.util.StatusPrinter;
public class ExceptionEvaluatorExample {
- public static void main(String[] args) {
- Logger logger = LoggerFactory.getLogger(ExceptionEvaluatorExample.class);
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ public static void main(String[] args) {
+ Logger logger = LoggerFactory.getLogger(ExceptionEvaluatorExample.class);
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- lc.reset();
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- // StatusPrinter will handle this
- }
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
-
- for (int i = 0; i < 3; i++) {
- if (i == 1) {
- logger.debug("logging statement " + i, new TestException("do not display this"));
- } else {
- logger.debug("logging statement " + i, new Exception("display"));
- }
- }
+ try {
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ lc.reset();
+ configurator.doConfigure(args[0]);
+ } catch (JoranException je) {
+ // StatusPrinter will handle this
+ }
+ StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
+
+ for (int i = 0; i < 3; i++) {
+ if (i == 1) {
+ logger.debug("logging statement " + i, new TestException(
+ "do not display this"));
+ } else {
+ logger.debug("logging statement " + i, new Exception("display"));
+ }
}
+ }
}
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/layouts/MySampleConverter.java b/logback-examples/src/main/java/chapters/layouts/MySampleConverter.java
index 3e1bdf8..f3bbbb0 100644
--- a/logback-examples/src/main/java/chapters/layouts/MySampleConverter.java
+++ b/logback-examples/src/main/java/chapters/layouts/MySampleConverter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,11 +19,11 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
public class MySampleConverter extends ClassicConverter {
- long start = System.nanoTime();
+ long start = System.nanoTime();
- @Override
- public String convert(ILoggingEvent event) {
- long nowInNanos = System.nanoTime();
- return Long.toString(nowInNanos - start);
- }
+ @Override
+ public String convert(ILoggingEvent event) {
+ long nowInNanos = System.nanoTime();
+ return Long.toString(nowInNanos-start);
+ }
}
diff --git a/logback-examples/src/main/java/chapters/layouts/MySampleLayout.java b/logback-examples/src/main/java/chapters/layouts/MySampleLayout.java
index 38e1048..1117508 100644
--- a/logback-examples/src/main/java/chapters/layouts/MySampleLayout.java
+++ b/logback-examples/src/main/java/chapters/layouts/MySampleLayout.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -17,20 +17,20 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.LayoutBase;
-public class MySampleLayout extends LayoutBase<ILoggingEvent> {
+public class MySampleLayout extends LayoutBase<ILoggingEvent> {
- public String doLayout(ILoggingEvent event) {
- StringBuilder sbuf = new StringBuilder(128);
- sbuf.append(event.getTimeStamp() - event.getLoggerContextVO().getBirthTime());
- sbuf.append(" ");
- sbuf.append(event.getLevel());
- sbuf.append(" [");
- sbuf.append(event.getThreadName());
- sbuf.append("] ");
- sbuf.append(event.getLoggerName());
- sbuf.append(" - ");
- sbuf.append(event.getFormattedMessage());
- sbuf.append(CoreConstants.LINE_SEPARATOR);
- return sbuf.toString();
- }
+ public String doLayout(ILoggingEvent event) {
+ StringBuilder sbuf = new StringBuilder(128);
+ sbuf.append(event.getTimeStamp() - event.getLoggerContextVO().getBirthTime());
+ sbuf.append(" ");
+ sbuf.append(event.getLevel());
+ sbuf.append(" [");
+ sbuf.append(event.getThreadName());
+ sbuf.append("] ");
+ sbuf.append(event.getLoggerName());
+ sbuf.append(" - ");
+ sbuf.append(event.getFormattedMessage());
+ sbuf.append(CoreConstants.LINE_SEPARATOR);
+ return sbuf.toString();
+ }
}
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/layouts/MySampleLayout2.java b/logback-examples/src/main/java/chapters/layouts/MySampleLayout2.java
index ed1bfc9..05248c9 100644
--- a/logback-examples/src/main/java/chapters/layouts/MySampleLayout2.java
+++ b/logback-examples/src/main/java/chapters/layouts/MySampleLayout2.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -19,36 +19,36 @@ import ch.qos.logback.core.LayoutBase;
public class MySampleLayout2 extends LayoutBase<ILoggingEvent> {
- String prefix = null;
- boolean printThreadName = true;
+ String prefix = null;
+ boolean printThreadName = true;
- public void setPrefix(String prefix) {
- this.prefix = prefix;
- }
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
- public void setPrintThreadName(boolean printThreadName) {
- this.printThreadName = printThreadName;
- }
+ public void setPrintThreadName(boolean printThreadName) {
+ this.printThreadName = printThreadName;
+ }
- public String doLayout(ILoggingEvent event) {
- StringBuilder sbuf = new StringBuilder(128);
- if (prefix != null) {
- sbuf.append(prefix + ": ");
- }
- sbuf.append(event.getTimeStamp() - event.getLoggerContextVO().getBirthTime());
- sbuf.append(" ");
- sbuf.append(event.getLevel());
- if (printThreadName) {
- sbuf.append(" [");
- sbuf.append(event.getThreadName());
- sbuf.append("] ");
- } else {
- sbuf.append(" ");
- }
- sbuf.append(event.getLoggerName());
- sbuf.append(" - ");
- sbuf.append(event.getFormattedMessage());
- sbuf.append(CoreConstants.LINE_SEPARATOR);
- return sbuf.toString();
+ public String doLayout(ILoggingEvent event) {
+ StringBuilder sbuf = new StringBuilder(128);
+ if (prefix != null) {
+ sbuf.append(prefix + ": ");
+ }
+ sbuf.append(event.getTimeStamp() - event.getLoggerContextVO().getBirthTime());
+ sbuf.append(" ");
+ sbuf.append(event.getLevel());
+ if (printThreadName) {
+ sbuf.append(" [");
+ sbuf.append(event.getThreadName());
+ sbuf.append("] ");
+ } else {
+ sbuf.append(" ");
}
+ sbuf.append(event.getLoggerName());
+ sbuf.append(" - ");
+ sbuf.append(event.getFormattedMessage());
+ sbuf.append(CoreConstants.LINE_SEPARATOR);
+ return sbuf.toString();
+ }
}
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/layouts/PatternSample.java b/logback-examples/src/main/java/chapters/layouts/PatternSample.java
index f9818bd..4b8127a 100644
--- a/logback-examples/src/main/java/chapters/layouts/PatternSample.java
+++ b/logback-examples/src/main/java/chapters/layouts/PatternSample.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,24 +23,24 @@ import ch.qos.logback.core.ConsoleAppender;
public class PatternSample {
- static public void main(String[] args) throws Exception {
- Logger rootLogger = (Logger) LoggerFactory.getLogger("root");
- LoggerContext loggerContext = rootLogger.getLoggerContext();
- loggerContext.reset();
-
- PatternLayoutEncoder encoder = new PatternLayoutEncoder();
- encoder.setContext(loggerContext);
- encoder.setPattern("%-5level [%thread]: %message%n");
- encoder.start();
-
- ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<ILoggingEvent>();
- appender.setContext(loggerContext);
- appender.setEncoder(encoder);
- appender.start();
-
- rootLogger.addAppender(appender);
-
- rootLogger.debug("Message 1");
- rootLogger.warn("Message 2");
- }
+ static public void main(String[] args) throws Exception {
+ Logger rootLogger = (Logger) LoggerFactory.getLogger("root");
+ LoggerContext loggerContext = rootLogger.getLoggerContext();
+ loggerContext.reset();
+
+ PatternLayoutEncoder encoder = new PatternLayoutEncoder();
+ encoder.setContext(loggerContext);
+ encoder.setPattern("%-5level [%thread]: %message%n");
+ encoder.start();
+
+ ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<ILoggingEvent>();
+ appender.setContext(loggerContext);
+ appender.setEncoder(encoder);
+ appender.start();
+
+ rootLogger.addAppender(appender);
+
+ rootLogger.debug("Message 1");
+ rootLogger.warn("Message 2");
+ }
}
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/layouts/SampleLogging.java b/logback-examples/src/main/java/chapters/layouts/SampleLogging.java
index e348ce6..87f44e1 100644
--- a/logback-examples/src/main/java/chapters/layouts/SampleLogging.java
+++ b/logback-examples/src/main/java/chapters/layouts/SampleLogging.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -23,23 +23,23 @@ import ch.qos.logback.core.util.StatusPrinter;
public class SampleLogging {
- public static void main(String[] args) {
+ public static void main(String[] args) {
- Logger logger = LoggerFactory.getLogger(SampleLogging.class);
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ Logger logger = LoggerFactory.getLogger(SampleLogging.class);
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- lc.reset();
- configurator.setContext(lc);
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- // StatusPrinter will handle this
- }
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
-
- logger.debug("Everything's going well");
- logger.error("maybe not quite...");
+ try {
+ JoranConfigurator configurator = new JoranConfigurator();
+ lc.reset();
+ configurator.setContext(lc);
+ configurator.doConfigure(args[0]);
+ } catch (JoranException je) {
+ // StatusPrinter will handle this
}
+ StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
+
+ logger.debug("Everything's going well");
+ logger.error("maybe not quite...");
+ }
}
diff --git a/logback-examples/src/main/java/chapters/layouts/TestException.java b/logback-examples/src/main/java/chapters/layouts/TestException.java
index 103fbbc..f8abf1c 100644
--- a/logback-examples/src/main/java/chapters/layouts/TestException.java
+++ b/logback-examples/src/main/java/chapters/layouts/TestException.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -15,9 +15,9 @@ package chapters.layouts;
public class TestException extends Exception {
- private static final long serialVersionUID = 8326547927308399902L;
+ private static final long serialVersionUID = 8326547927308399902L;
- public TestException(String message) {
- super(message);
- }
+ public TestException(String message) {
+ super(message);
+ }
}
diff --git a/logback-examples/src/main/java/chapters/layouts/TrivialMain.java b/logback-examples/src/main/java/chapters/layouts/TrivialMain.java
index e21b808..e8d1a80 100644
--- a/logback-examples/src/main/java/chapters/layouts/TrivialMain.java
+++ b/logback-examples/src/main/java/chapters/layouts/TrivialMain.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -22,29 +22,29 @@ import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.util.StatusPrinter;
public class TrivialMain {
- public static void main(String[] args) throws InterruptedException {
- Logger logger = LoggerFactory.getLogger(TrivialMain.class);
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
-
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- lc.reset();
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- // StatusPrinter will handle this
- }
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
+ public static void main(String[] args) throws InterruptedException {
+ Logger logger = LoggerFactory.getLogger(TrivialMain.class);
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+
+ try {
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ lc.reset();
+ configurator.doConfigure(args[0]);
+ } catch (JoranException je) {
+ // StatusPrinter will handle this
+ }
+ StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
- for (int i = 0; i < 6; i++) {
- if (i % 5 == 0) {
- logger.warn("a warning message " + i);
- } else if (i % 3 == 0) {
- logger.info("hello world number" + i);
- } else {
- logger.debug("hello world number" + i);
- }
- }
- logger.error("Finish off with fireworks", new Exception("Just testing"));
+ for (int i = 0; i < 6; i++) {
+ if (i % 5 == 0) {
+ logger.warn("a warning message " + i);
+ } else if(i % 3 == 0) {
+ logger.info("hello world number" + i);
+ } else {
+ logger.debug("hello world number" + i);
+ }
}
+ logger.error("Finish off with fireworks", new Exception("Just testing"));
+ }
}
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/layouts/callerEvaluatorConfig.xml b/logback-examples/src/main/java/chapters/layouts/callerEvaluatorConfig.xml
new file mode 100644
index 0000000..613a848
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/layouts/callerEvaluatorConfig.xml
@@ -0,0 +1,18 @@
+<configuration>
+
+ <evaluator name="DISPLAY_CALLER_EVAL">
+ <expression>
+ logger.contains("chapters.layouts") && message.contains("who calls thee")
+ </expression>
+ </evaluator>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%-4relative [%thread] %-5level - %msg%n%caller{2, DISPLAY_CALLER_EVAL}</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/layouts/exceptionEvaluatorConfig.xml b/logback-examples/src/main/java/chapters/layouts/exceptionEvaluatorConfig.xml
new file mode 100644
index 0000000..9b57b91
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/layouts/exceptionEvaluatorConfig.xml
@@ -0,0 +1,16 @@
+<configuration>
+
+ <evaluator name="DISPLAY_EX_EVAL">
+ <expression>throwable != null && throwable instanceof chapters.layouts.TestException</expression>
+ </evaluator>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%msg%n%xEx{full, DISPLAY_EX_EVAL}</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/layouts/highlighted.xml b/logback-examples/src/main/java/chapters/layouts/highlighted.xml
new file mode 100644
index 0000000..a1a9859
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/layouts/highlighted.xml
@@ -0,0 +1,16 @@
+<configuration debug="true">
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <!-- On Windows machines setting withJansi to true enables ANSI
+ color code interpretation by the Jansi library. This requires
+ org.fusesource.jansi:jansi:1.9 on the class path. Note that
+ Unix-based operating systems such as Linux and Mac OS X
+ support ANSI color codes by default. codes.-->
+ <withJansi>true</withJansi>
+ <encoder>
+ <pattern>%date [%thread] %highlight(%-5level) %cyan(%-15logger{15}) %X - %msg %n</pattern>
+ </encoder>
+ </appender>
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/layouts/htmlLayoutConfig1.xml b/logback-examples/src/main/java/chapters/layouts/htmlLayoutConfig1.xml
new file mode 100644
index 0000000..2dca391
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/layouts/htmlLayoutConfig1.xml
@@ -0,0 +1,14 @@
+<configuration>
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+ <layout class="ch.qos.logback.classic.html.HTMLLayout">
+ <pattern>%relative%thread%mdc%level%logger%msg</pattern>
+ </layout>
+ </encoder>
+ <file>test.html</file>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/layouts/log4jXMLLayout.xml b/logback-examples/src/main/java/chapters/layouts/log4jXMLLayout.xml
new file mode 100644
index 0000000..ea517a8
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/layouts/log4jXMLLayout.xml
@@ -0,0 +1,14 @@
+<configuration>
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>test.xml</file>
+ <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+ <layout class="ch.qos.logback.classic.log4j.XMLLayout">
+ <locationInfo>true</locationInfo>
+ </layout>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="FILE" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/layouts/mySampleConverterConfig.xml b/logback-examples/src/main/java/chapters/layouts/mySampleConverterConfig.xml
new file mode 100644
index 0000000..b6ee515
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/layouts/mySampleConverterConfig.xml
@@ -0,0 +1,15 @@
+<configuration>
+
+ <conversionRule conversionWord="nano"
+ converterClass="chapters.layouts.MySampleConverter" />
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%-6nano [%thread] %level - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig.xml b/logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig.xml
new file mode 100644
index 0000000..269270c
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig.xml
@@ -0,0 +1,12 @@
+<configuration debug="true">
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+ <layout class="chapters.layouts.MySampleLayout" />
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig2.xml b/logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig2.xml
new file mode 100644
index 0000000..a6b24db
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig2.xml
@@ -0,0 +1,16 @@
+<configuration>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+
+ <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+ <layout class="chapters.layouts.MySampleLayout2">
+ <prefix>MyPrefix</prefix>
+ <printThreadName>false</printThreadName>
+ </layout>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/mdc/NumberCruncher.java b/logback-examples/src/main/java/chapters/mdc/NumberCruncher.java
index acd7a10..8f18b5b 100644
--- a/logback-examples/src/main/java/chapters/mdc/NumberCruncher.java
+++ b/logback-examples/src/main/java/chapters/mdc/NumberCruncher.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,13 +16,14 @@ package chapters.mdc;
import java.rmi.Remote;
import java.rmi.RemoteException;
+
/**
* NumberCruncher factors positive integers.
*/
public interface NumberCruncher extends Remote {
- /**
- * Factor a positive integer <code>number</code> and return its
- * <em>distinct</em> factor's as an integer array.
- * */
- int[] factor(int number) throws RemoteException;
+ /**
+ * Factor a positive integer <code>number</code> and return its
+ * <em>distinct</em> factor's as an integer array.
+ * */
+ int[] factor(int number) throws RemoteException;
}
diff --git a/logback-examples/src/main/java/chapters/mdc/NumberCruncherClient.java b/logback-examples/src/main/java/chapters/mdc/NumberCruncherClient.java
index efccad9..d929858 100644
--- a/logback-examples/src/main/java/chapters/mdc/NumberCruncherClient.java
+++ b/logback-examples/src/main/java/chapters/mdc/NumberCruncherClient.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,6 +18,7 @@ import java.io.InputStreamReader;
import java.rmi.Naming;
import java.rmi.RemoteException;
+
/**
* NumberCruncherClient is a simple client for factoring integers. A
* remote NumberCruncher is contacted and asked to factor an
@@ -25,60 +26,61 @@ import java.rmi.RemoteException;
* are displayed on the screen.
* */
public class NumberCruncherClient {
- public static void main(String[] args) {
- if (args.length == 1) {
- try {
- String url = "rmi://" + args[0] + "/Factor";
- NumberCruncher nc = (NumberCruncher) Naming.lookup(url);
- loop(nc);
- } catch (Exception e) {
- e.printStackTrace();
- }
- } else {
- usage("Wrong number of arguments.");
- }
+ public static void main(String[] args) {
+ if (args.length == 1) {
+ try {
+ String url = "rmi://" + args[0] + "/Factor";
+ NumberCruncher nc = (NumberCruncher) Naming.lookup(url);
+ loop(nc);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } else {
+ usage("Wrong number of arguments.");
}
+ }
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java chapters.mdc.NumberCruncherClient HOST\n" + " where HOST is the machine where the NumberCruncherServer is running.");
- System.exit(1);
- }
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java chapters.mdc.NumberCruncherClient HOST\n" +
+ " where HOST is the machine where the NumberCruncherServer is running.");
+ System.exit(1);
+ }
- static void loop(NumberCruncher nc) {
- BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
- int i = 0;
+ static void loop(NumberCruncher nc) {
+ BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+ int i = 0;
- while (true) {
- System.out.print("Enter a number to factor, '-1' to quit: ");
+ while (true) {
+ System.out.print("Enter a number to factor, '-1' to quit: ");
- try {
- i = Integer.parseInt(in.readLine());
- } catch (Exception e) {
- e.printStackTrace();
- }
+ try {
+ i = Integer.parseInt(in.readLine());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
- if (i == -1) {
- System.out.print("Exiting loop.");
+ if (i == -1) {
+ System.out.print("Exiting loop.");
- return;
- } else {
- try {
- System.out.println("Will attempt to factor " + i);
+ return;
+ } else {
+ try {
+ System.out.println("Will attempt to factor " + i);
- int[] factors = nc.factor(i);
- System.out.print("The factors of " + i + " are");
+ int[] factors = nc.factor(i);
+ System.out.print("The factors of " + i + " are");
- for (int k = 0; k < factors.length; k++) {
- System.out.print(" " + factors[k]);
- }
+ for (int k = 0; k < factors.length; k++) {
+ System.out.print(" " + factors[k]);
+ }
- System.out.println(".");
- } catch (RemoteException e) {
- System.err.println("Could not factor " + i);
- e.printStackTrace();
- }
- }
+ System.out.println(".");
+ } catch (RemoteException e) {
+ System.err.println("Could not factor " + i);
+ e.printStackTrace();
}
+ }
}
+ }
}
diff --git a/logback-examples/src/main/java/chapters/mdc/NumberCruncherServer.java b/logback-examples/src/main/java/chapters/mdc/NumberCruncherServer.java
index 45dcfb6..e763116 100644
--- a/logback-examples/src/main/java/chapters/mdc/NumberCruncherServer.java
+++ b/logback-examples/src/main/java/chapters/mdc/NumberCruncherServer.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,132 +27,136 @@ import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
+
/**
* A simple NumberCruncher implementation that logs its progress when
* factoring numbers. The purpose of the whole exercise is to show the
* use of mapped diagnostic contexts in order to distinguish the log
* output from different client requests.
* */
-public class NumberCruncherServer extends UnicastRemoteObject implements NumberCruncher {
+public class NumberCruncherServer extends UnicastRemoteObject
+ implements NumberCruncher {
+
+ private static final long serialVersionUID = 1L;
+
+ static Logger logger = LoggerFactory.getLogger(NumberCruncherServer.class);
+
+ public NumberCruncherServer() throws RemoteException {
+ }
+
+ public int[] factor(int number) throws RemoteException {
+ // The client's host is an important source of information.
+ try {
+ MDC.put("client", NumberCruncherServer.getClientHost());
+ } catch (java.rmi.server.ServerNotActiveException e) {
+ logger.warn("Caught unexpected ServerNotActiveException.", e);
+ }
+
+ // The information contained within the request is another source
+ // of distinctive information. It might reveal the users name,
+ // date of request, request ID etc. In servlet type environments,
+ // useful information is contained in the HttpRequest or in the
+ // HttpSession.
+ MDC.put("number", String.valueOf(number));
+
+ logger.info("Beginning to factor.");
+
+ if (number <= 0) {
+ throw new IllegalArgumentException(number +
+ " is not a positive integer.");
+ } else if (number == 1) {
+ return new int[] { 1 };
+ }
+
+ Vector<Integer> factors = new Vector<Integer>();
+ int n = number;
+
+ for (int i = 2; (i <= n) && ((i * i) <= number); i++) {
+ // It is bad practice to place log requests within tight loops.
+ // It is done here to show interleaved log output from
+ // different requests.
+ logger.debug("Trying " + i + " as a factor.");
- private static final long serialVersionUID = 1L;
+ if ((n % i) == 0) {
+ logger.info("Found factor " + i);
+ factors.addElement(i);
- static Logger logger = LoggerFactory.getLogger(NumberCruncherServer.class);
+ do {
+ n /= i;
+ } while ((n % i) == 0);
+ }
- public NumberCruncherServer() throws RemoteException {
+ // Placing artificial delays in tight loops will also lead to
+ // sub-optimal resuts. :-)
+ delay(100);
}
- public int[] factor(int number) throws RemoteException {
- // The client's host is an important source of information.
- try {
- MDC.put("client", NumberCruncherServer.getClientHost());
- } catch (java.rmi.server.ServerNotActiveException e) {
- logger.warn("Caught unexpected ServerNotActiveException.", e);
- }
-
- // The information contained within the request is another source
- // of distinctive information. It might reveal the users name,
- // date of request, request ID etc. In servlet type environments,
- // useful information is contained in the HttpRequest or in the
- // HttpSession.
- MDC.put("number", String.valueOf(number));
-
- logger.info("Beginning to factor.");
-
- if (number <= 0) {
- throw new IllegalArgumentException(number + " is not a positive integer.");
- } else if (number == 1) {
- return new int[] { 1 };
- }
-
- Vector<Integer> factors = new Vector<Integer>();
- int n = number;
-
- for (int i = 2; (i <= n) && ((i * i) <= number); i++) {
- // It is bad practice to place log requests within tight loops.
- // It is done here to show interleaved log output from
- // different requests.
- logger.debug("Trying " + i + " as a factor.");
-
- if ((n % i) == 0) {
- logger.info("Found factor " + i);
- factors.addElement(i);
-
- do {
- n /= i;
- } while ((n % i) == 0);
- }
-
- // Placing artificial delays in tight loops will also lead to
- // sub-optimal resuts. :-)
- delay(100);
- }
-
- if (n != 1) {
- logger.info("Found factor " + n);
- factors.addElement(n);
- }
-
- int len = factors.size();
-
- int[] result = new int[len];
-
- for (int i = 0; i < len; i++) {
- result[i] = ((Integer) factors.elementAt(i)).intValue();
- }
-
- // clean up
- MDC.remove("client");
- MDC.remove("number");
-
- return result;
+ if (n != 1) {
+ logger.info("Found factor " + n);
+ factors.addElement(n);
}
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java chapters.mdc.NumberCruncherServer configFile\n" + " where configFile is a logback configuration file.");
- System.exit(1);
+ int len = factors.size();
+
+ int[] result = new int[len];
+
+ for (int i = 0; i < len; i++) {
+ result[i] = ((Integer) factors.elementAt(i)).intValue();
+ }
+
+ // clean up
+ MDC.remove("client");
+ MDC.remove("number");
+
+ return result;
+ }
+
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java chapters.mdc.NumberCruncherServer configFile\n" +
+ " where configFile is a logback configuration file.");
+ System.exit(1);
+ }
+
+ public static void delay(int millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ public static void main(String[] args) {
+ if (args.length != 1) {
+ usage("Wrong number of arguments.");
}
- public static void delay(int millis) {
- try {
- Thread.sleep(millis);
- } catch (InterruptedException e) {
- }
+ String configFile = args[0];
+
+ if (configFile.endsWith(".xml")) {
+ try {
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ lc.reset();
+ configurator.doConfigure(args[0]);
+ } catch (JoranException je) {
+ je.printStackTrace();
+ }
}
- public static void main(String[] args) {
- if (args.length != 1) {
- usage("Wrong number of arguments.");
- }
-
- String configFile = args[0];
-
- if (configFile.endsWith(".xml")) {
- try {
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- lc.reset();
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- je.printStackTrace();
- }
- }
-
- NumberCruncherServer ncs;
-
- try {
- ncs = new NumberCruncherServer();
- logger.info("Creating registry.");
-
- Registry registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
- registry.rebind("Factor", ncs);
- logger.info("NumberCruncherServer bound and ready.");
- } catch (Exception e) {
- logger.error("Could not bind NumberCruncherServer.", e);
-
- return;
- }
+ NumberCruncherServer ncs;
+
+ try {
+ ncs = new NumberCruncherServer();
+ logger.info("Creating registry.");
+
+ Registry registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
+ registry.rebind("Factor", ncs);
+ logger.info("NumberCruncherServer bound and ready.");
+ } catch (Exception e) {
+ logger.error("Could not bind NumberCruncherServer.", e);
+
+ return;
}
+ }
}
diff --git a/logback-examples/src/main/java/chapters/mdc/SimpleMDC.java b/logback-examples/src/main/java/chapters/mdc/SimpleMDC.java
index 0b36088..574ac6e 100644
--- a/logback-examples/src/main/java/chapters/mdc/SimpleMDC.java
+++ b/logback-examples/src/main/java/chapters/mdc/SimpleMDC.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,64 +29,66 @@ import ch.qos.logback.core.util.Loader;
import ch.qos.logback.core.util.StatusPrinter;
public class SimpleMDC {
- static public void main(String[] args) throws Exception {
- // You can put values in the MDC at any time. Before anything else
- // we put the first name
- MDC.put("first", "Dorothy");
+ static public void main(String[] args) throws Exception {
+ // You can put values in the MDC at any time. Before anything else
+ // we put the first name
+ MDC.put("first", "Dorothy");
- // configure via the configuration file "chapters/mdc/simpleMDC.xml"
- // which ships with the examples
- configureViaXML_File();
+ // configure via the configuration file "chapters/mdc/simpleMDC.xml"
+ // which ships with the examples
+ configureViaXML_File();
+
+ // For educational purposes, the same configuration can
+ // be accomplished programmatically.
+ //
+ // programmaticConfiguration();
+
+ Logger logger = LoggerFactory.getLogger(SimpleMDC.class);
+ // We now put the last name
+ MDC.put("last", "Parker");
- // For educational purposes, the same configuration can
- // be accomplished programmatically.
- //
- // programmaticConfiguration();
+ // The most beautiful two words in the English language according
+ // to Dorothy Parker:
+ logger.info("Check enclosed.");
+ logger.debug("The most beautiful two words in English.");
- Logger logger = LoggerFactory.getLogger(SimpleMDC.class);
- // We now put the last name
- MDC.put("last", "Parker");
+ MDC.put("first", "Richard");
+ MDC.put("last", "Nixon");
+ logger.info("I am not a crook.");
+ logger.info("Attributed to the former US president. 17 Nov 1973.");
+ }
- // The most beautiful two words in the English language according
- // to Dorothy Parker:
- logger.info("Check enclosed.");
- logger.debug("The most beautiful two words in English.");
+ static void programmaticConfiguration() {
+ // Configure logback
+ LoggerContext loggerContext = (LoggerContext) LoggerFactory
+ .getILoggerFactory();
+ loggerContext.reset();
+ PatternLayoutEncoder layout = new PatternLayoutEncoder();
+ layout.setContext(loggerContext);
+ layout.setPattern("%X{first} %X{last} - %m%n");
+ layout.start();
+ ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<ILoggingEvent>();
+ appender.setContext(loggerContext);
+ appender.setEncoder(layout);
+ appender.start();
+ // cast root logger to c.q.logback.classic.Logger so that we can attach
+ // an appender to it
+ ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory
+ .getLogger("root");
+ root.addAppender(appender);
+ }
- MDC.put("first", "Richard");
- MDC.put("last", "Nixon");
- logger.info("I am not a crook.");
- logger.info("Attributed to the former US president. 17 Nov 1973.");
- }
-
- static void programmaticConfiguration() {
- // Configure logback
- LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
- loggerContext.reset();
- PatternLayoutEncoder layout = new PatternLayoutEncoder();
- layout.setContext(loggerContext);
- layout.setPattern("%X{first} %X{last} - %m%n");
- layout.start();
- ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<ILoggingEvent>();
- appender.setContext(loggerContext);
- appender.setEncoder(layout);
- appender.start();
- // cast root logger to c.q.logback.classic.Logger so that we can attach
- // an appender to it
- ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("root");
- root.addAppender(appender);
- }
-
- static void configureViaXML_File() {
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- lc.reset();
- URL url = Loader.getResourceBySelfClassLoader("chapters/mdc/simpleMDC.xml");
- configurator.doConfigure(url);
- } catch (JoranException je) {
- StatusPrinter.print(lc);
- }
+ static void configureViaXML_File() {
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ try {
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ lc.reset();
+ URL url = Loader.getResourceBySelfClassLoader("chapters/mdc/simpleMDC.xml");
+ configurator.doConfigure(url);
+ } catch (JoranException je) {
+ StatusPrinter.print(lc);
}
+ }
}
diff --git a/logback-examples/src/main/java/chapters/mdc/UserServletFilter.java b/logback-examples/src/main/java/chapters/mdc/UserServletFilter.java
index 73aea3f..2bb242e 100644
--- a/logback-examples/src/main/java/chapters/mdc/UserServletFilter.java
+++ b/logback-examples/src/main/java/chapters/mdc/UserServletFilter.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -37,48 +37,49 @@ import org.slf4j.MDC;
*/
public class UserServletFilter implements Filter {
- private final String USER_KEY = "username";
+ private final String USER_KEY = "username";
+
+ public void destroy() {
+ }
- public void destroy() {
- }
-
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
-
- boolean successfulRegistration = false;
- HttpServletRequest req = (HttpServletRequest) request;
- Principal principal = req.getUserPrincipal();
- // Please note that we also could have used a cookie to
- // retrieve the user name
+ public void doFilter(ServletRequest request, ServletResponse response,
+ FilterChain chain) throws IOException, ServletException {
- if (principal != null) {
- String username = principal.getName();
- successfulRegistration = registerUsername(username);
- }
-
- try {
- chain.doFilter(request, response);
- } finally {
- if (successfulRegistration) {
- MDC.remove(USER_KEY);
- }
- }
+ boolean successfulRegistration = false;
+ HttpServletRequest req = (HttpServletRequest) request;
+ Principal principal = req.getUserPrincipal();
+ // Please note that we also could have used a cookie to
+ // retrieve the user name
+
+ if (principal != null) {
+ String username = principal.getName();
+ successfulRegistration = registerUsername(username);
}
-
- public void init(FilterConfig arg0) throws ServletException {
+
+ try {
+ chain.doFilter(request, response);
+ } finally {
+ if (successfulRegistration) {
+ MDC.remove(USER_KEY);
+ }
}
+ }
- /**
- * Register the user in the MDC under USER_KEY.
- *
- * @param username
- * @return true id the user can be successfully registered
- */
- private boolean registerUsername(String username) {
- if (username != null && username.trim().length() > 0) {
- MDC.put(USER_KEY, username);
- return true;
- }
- return false;
+ public void init(FilterConfig arg0) throws ServletException {
+ }
+
+ /**
+ * Register the user in the MDC under USER_KEY.
+ *
+ * @param username
+ * @return true id the user can be successfully registered
+ */
+ private boolean registerUsername(String username) {
+ if (username != null && username.trim().length() > 0) {
+ MDC.put(USER_KEY, username);
+ return true;
}
+ return false;
+ }
}
diff --git a/logback-examples/src/main/java/chapters/mdc/mdc1.xml b/logback-examples/src/main/java/chapters/mdc/mdc1.xml
new file mode 100644
index 0000000..5a97bf9
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/mdc/mdc1.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <appender name="CONSOLE"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%-4r [%thread] %-5level C:%X{client} N:%X{number} - %msg%n</Pattern>
+ </layout>
+ </appender>
+
+ <root>
+ <level value ="debug"/>
+ <appender-ref ref="CONSOLE"/>
+ </root>
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/mdc/simpleMDC.xml b/logback-examples/src/main/java/chapters/mdc/simpleMDC.xml
new file mode 100644
index 0000000..6a4e605
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/mdc/simpleMDC.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <appender name="CONSOLE"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%X{first} %X{last} - %m%n</Pattern>
+ </layout>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="CONSOLE" />
+ </root>
+</configuration>
diff --git a/logback-examples/src/main/java/chapters/migrationFromLog4j/Log4jMain.java b/logback-examples/src/main/java/chapters/migrationFromLog4j/Log4jMain.java
index ad82702..9919c48 100644
--- a/logback-examples/src/main/java/chapters/migrationFromLog4j/Log4jMain.java
+++ b/logback-examples/src/main/java/chapters/migrationFromLog4j/Log4jMain.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,11 +24,11 @@ import org.apache.log4j.PropertyConfigurator;
*/
public class Log4jMain {
- static Logger logger = Logger.getLogger(Log4jMain.class);
+ static Logger logger = Logger.getLogger(Log4jMain.class);
- public static void main(String[] args) {
- PropertyConfigurator.configure("src/main/java/chapters/migrationFromLog4j/log4jTrivial.properties");
- logger.debug("Hello world");
- }
+ public static void main(String[] args) {
+ PropertyConfigurator.configure("src/main/java/chapters/migrationFromLog4j/log4jTrivial.properties");
+ logger.debug("Hello world");
+ }
}
diff --git a/logback-examples/src/main/java/chapters/migrationFromLog4j/LogbackMain.java b/logback-examples/src/main/java/chapters/migrationFromLog4j/LogbackMain.java
index ee9b44d..55ced34 100644
--- a/logback-examples/src/main/java/chapters/migrationFromLog4j/LogbackMain.java
+++ b/logback-examples/src/main/java/chapters/migrationFromLog4j/LogbackMain.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,18 +30,19 @@ import ch.qos.logback.core.util.StatusPrinter;
*/
public class LogbackMain {
- static Logger logger = LoggerFactory.getLogger(LogbackMain.class);
+ static Logger logger = LoggerFactory.getLogger(LogbackMain.class);
- public static void main(String[] args) throws JoranException {
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ public static void main(String[] args) throws JoranException {
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- lc.reset();
- configurator.doConfigure("src/main/java/chapters/migrationFromLog4j/logback-trivial.xml");
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
-
- logger.debug("Hello world");
- }
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ lc.reset();
+ configurator.doConfigure("src/main/java/chapters/migrationFromLog4j/logback-trivial.xml");
+ StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
+
+
+ logger.debug("Hello world");
+ }
}
diff --git a/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLog4jAppender.java b/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLog4jAppender.java
index 36a2d75..ddf294d 100644
--- a/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLog4jAppender.java
+++ b/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLog4jAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,17 +18,17 @@ import org.apache.log4j.spi.LoggingEvent;
public class TrivialLog4jAppender extends AppenderSkeleton {
- protected void append(LoggingEvent loggingevent) {
- String s = this.layout.format(loggingevent);
- System.out.println(s);
- }
+ protected void append(LoggingEvent loggingevent) {
+ String s = this.layout.format(loggingevent);
+ System.out.println(s);
+ }
- public void close() {
- // nothing to do
- }
+ public void close() {
+ // nothing to do
+ }
- public boolean requiresLayout() {
- return true;
- }
+ public boolean requiresLayout() {
+ return true;
+ }
}
diff --git a/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLog4jLayout.java b/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLog4jLayout.java
index 9228c72..52024f0 100644
--- a/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLog4jLayout.java
+++ b/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLog4jLayout.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,6 +16,7 @@ package chapters.migrationFromLog4j;
import org.apache.log4j.Layout;
import org.apache.log4j.spi.LoggingEvent;
+
/**
*
* A very simple log4j layout which formats a logging event
@@ -26,17 +27,17 @@ import org.apache.log4j.spi.LoggingEvent;
*/
public class TrivialLog4jLayout extends Layout {
- public void activateOptions() {
- // there are no options to activate
- }
+ public void activateOptions() {
+ // there are no options to activate
+ }
- public String format(LoggingEvent loggingEvent) {
- return loggingEvent.getRenderedMessage();
- }
+ public String format(LoggingEvent loggingEvent) {
+ return loggingEvent.getRenderedMessage();
+ }
- @Override
- public boolean ignoresThrowable() {
- return true;
- }
+ @Override
+ public boolean ignoresThrowable() {
+ return true;
+ }
}
diff --git a/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLogbackAppender.java b/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLogbackAppender.java
index 3cd01a7..af37abf 100644
--- a/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLogbackAppender.java
+++ b/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLogbackAppender.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,40 +21,40 @@ import ch.qos.logback.core.AppenderBase;
public class TrivialLogbackAppender extends AppenderBase<ILoggingEvent> {
- PatternLayoutEncoder encoder;
-
- public PatternLayoutEncoder getEncoder() {
- return encoder;
+ PatternLayoutEncoder encoder;
+
+ public PatternLayoutEncoder getEncoder() {
+ return encoder;
+ }
+
+ public void setEncoder(PatternLayoutEncoder encoder) {
+ this.encoder = encoder;
+ }
+
+ @Override
+ public void start() {
+ if (this.encoder == null) {
+ addError("No encoder set for the appender named [" + name + "].");
+ return;
}
-
- public void setEncoder(PatternLayoutEncoder encoder) {
- this.encoder = encoder;
+ try {
+ encoder.init(System.out);
+ } catch (IOException e) {
}
-
- @Override
- public void start() {
- if (this.encoder == null) {
- addError("No encoder set for the appender named [" + name + "].");
- return;
- }
- try {
- encoder.init(System.out);
- } catch (IOException e) {
- }
- super.start();
- }
-
- @Override
- protected void append(ILoggingEvent loggingevent) {
- // note that AppenderBase.doAppend will invoke this method only if
- // this appender was successfully started.
- try {
- this.encoder.doEncode(loggingevent);
- } catch (IOException e) {
- // we can't do much with the exception except halting
- super.stop();
- addError("Failed to write to the console");
- }
+ super.start();
+ }
+
+ @Override
+ protected void append(ILoggingEvent loggingevent) {
+ // note that AppenderBase.doAppend will invoke this method only if
+ // this appender was successfully started.
+ try {
+ this.encoder.doEncode(loggingevent);
+ } catch (IOException e) {
+ // we can't do much with the exception except halting
+ super.stop();
+ addError("Failed to write to the console");
}
+ }
}
diff --git a/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLogbackLayout.java b/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLogbackLayout.java
index 2f36073..9a000b9 100644
--- a/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLogbackLayout.java
+++ b/logback-examples/src/main/java/chapters/migrationFromLog4j/TrivialLogbackLayout.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -16,6 +16,7 @@ package chapters.migrationFromLog4j;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.LayoutBase;
+
/**
*
* A very simple logback-classic layout which formats a logging event
@@ -26,7 +27,7 @@ import ch.qos.logback.core.LayoutBase;
*/
public class TrivialLogbackLayout extends LayoutBase<ILoggingEvent> {
- public String doLayout(ILoggingEvent loggingEvent) {
- return loggingEvent.getMessage();
- }
+ public String doLayout(ILoggingEvent loggingEvent) {
+ return loggingEvent.getMessage();
+ }
}
diff --git a/logback-examples/src/main/java/chapters/migrationFromLog4j/log4jTrivial.properties b/logback-examples/src/main/java/chapters/migrationFromLog4j/log4jTrivial.properties
new file mode 100644
index 0000000..f1e7aea
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/migrationFromLog4j/log4jTrivial.properties
@@ -0,0 +1,3 @@
+log4j.rootLogger=DEBUG, TRIVIAL
+log4j.appender.TRIVIAL=chapters.migrationFromLog4j.TrivialLog4jAppender
+log4j.appender.TRIVIAL.layout=chapters.migrationFromLog4j.TrivialLog4jLayout
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/migrationFromLog4j/logback-trivial.xml b/logback-examples/src/main/java/chapters/migrationFromLog4j/logback-trivial.xml
new file mode 100644
index 0000000..01a3e9f
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/migrationFromLog4j/logback-trivial.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<configuration>
+ <appender name="TRIVIAL" class="chapters.migrationFromLog4j.TrivialLogbackAppender">
+ <layout class="chapters.migrationFromLog4j.TrivialLogbackLayout"/>
+ </appender>
+ <root level="DEBUG">
+ <appender-ref ref="TRIVIAL"/>
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/onJoran/SimpleConfigurator.java b/logback-examples/src/main/java/chapters/onJoran/SimpleConfigurator.java
index 397932c..bf1b4db 100644
--- a/logback-examples/src/main/java/chapters/onJoran/SimpleConfigurator.java
+++ b/logback-examples/src/main/java/chapters/onJoran/SimpleConfigurator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,38 +27,38 @@ import ch.qos.logback.core.joran.spi.RuleStore;
/**
* A minimal configurator extending GenericConfigurator.
*
- * @author Ceki Gülcü
+ * @author Ceki Gücü
*
*/
public class SimpleConfigurator extends GenericConfigurator {
- final Map<ElementSelector, Action> ruleMap;
- final List<ImplicitAction> iaList;
+ final Map<ElementSelector, Action> ruleMap;
+ final List<ImplicitAction> iaList;
- public SimpleConfigurator(Map<ElementSelector, Action> ruleMap) {
- this(ruleMap, null);
- }
+ public SimpleConfigurator(Map<ElementSelector, Action> ruleMap) {
+ this(ruleMap, null);
+ }
- public SimpleConfigurator(Map<ElementSelector, Action> ruleMap, List<ImplicitAction> iaList) {
- this.ruleMap = ruleMap;
- this.iaList = iaList;
- }
+ public SimpleConfigurator(Map<ElementSelector, Action> ruleMap, List<ImplicitAction> iaList) {
+ this.ruleMap = ruleMap;
+ this.iaList = iaList;
+ }
- @Override
- protected void addInstanceRules(RuleStore rs) {
- for (ElementSelector elementSelector : ruleMap.keySet()) {
- Action action = ruleMap.get(elementSelector);
- rs.addRule(elementSelector, action);
- }
+ @Override
+ protected void addInstanceRules(RuleStore rs) {
+ for (ElementSelector elementSelector : ruleMap.keySet()) {
+ Action action = ruleMap.get(elementSelector);
+ rs.addRule(elementSelector, action);
}
+ }
- @Override
- protected void addImplicitRules(Interpreter interpreter) {
- if (iaList == null) {
- return;
- }
- for (ImplicitAction ia : iaList) {
- interpreter.addImplicitAction(ia);
- }
+ @Override
+ protected void addImplicitRules(Interpreter interpreter) {
+ if(iaList == null) {
+ return;
+ }
+ for (ImplicitAction ia : iaList) {
+ interpreter.addImplicitAction(ia);
}
+ }
}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/AddAction.java b/logback-examples/src/main/java/chapters/onJoran/calculator/AddAction.java
index 8bc79b4..d098ecd 100644
--- a/logback-examples/src/main/java/chapters/onJoran/calculator/AddAction.java
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/AddAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -20,6 +20,7 @@ import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.InterpretationContext;
+
/**
* This action adds the two integers at the top of the stack (they are removed)
* and pushes the result to the top the stack.
@@ -27,40 +28,42 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
* @author Ceki Gülcü
*/
public class AddAction extends Action {
+
+ public void begin(InterpretationContext ic, String name, Attributes attributes) {
+ int first = fetchInteger(ic);
+ int second = fetchInteger(ic);
+ // Push the result of the addition for the following actions.
+ ic.pushObject(first + second);
+ }
- public void begin(InterpretationContext ic, String name, Attributes attributes) {
- int first = fetchInteger(ic);
- int second = fetchInteger(ic);
- // Push the result of the addition for the following actions.
- ic.pushObject(first + second);
- }
-
- /**
- * Pop the Integer object at the top of the stack.
- * This code also illustrates usage of Joran's error handling paradigm.
- */
- int fetchInteger(InterpretationContext ic) {
- int result = 0;
+ /**
+ * Pop the Integer object at the top of the stack.
+ * This code also illustrates usage of Joran's error handling paradigm.
+ */
+ int fetchInteger(InterpretationContext ic) {
+ int result = 0;
- try {
- // Pop the object at the top of the interpretation context's stack.
- Object o1 = ic.popObject();
+ try {
+ // Pop the object at the top of the interpretation context's stack.
+ Object o1 = ic.popObject();
- if (o1 instanceof Integer) {
- result = ((Integer) o1).intValue();
- } else {
- String errMsg = "Object [" + o1 + "] currently at the top of the stack is not an integer.";
- ic.addError(errMsg);
- throw new IllegalArgumentException(errMsg);
- }
- } catch (EmptyStackException ese) {
- ic.addError(("Expecting an integer on the execution stack."));
- throw ese;
- }
- return result;
+ if (o1 instanceof Integer) {
+ result = ((Integer) o1).intValue();
+ } else {
+ String errMsg =
+ "Object [" + o1
+ + "] currently at the top of the stack is not an integer.";
+ ic.addError(errMsg);
+ throw new IllegalArgumentException(errMsg);
+ }
+ } catch (EmptyStackException ese) {
+ ic.addError(("Expecting an integer on the execution stack."));
+ throw ese;
}
+ return result;
+ }
- public void end(InterpretationContext ic, String name) {
- // Nothing to do here.
- }
+ public void end(InterpretationContext ic, String name) {
+ // Nothing to do here.
+ }
}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/Calculator1.java b/logback-examples/src/main/java/chapters/onJoran/calculator/Calculator1.java
index 30ccaab..f632552 100644
--- a/logback-examples/src/main/java/chapters/onJoran/calculator/Calculator1.java
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/Calculator1.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -27,29 +27,29 @@ import chapters.onJoran.SimpleConfigurator;
* This examples illustrates collaboration between multiple actions through the
* common execution context stack.
*
- * @author Ceki Gülcü
+ * @author Ceki Güulcü
*/
public class Calculator1 {
- public static void main(String[] args) throws Exception {
- Context context = new ContextBase();
+ public static void main(String[] args) throws Exception {
+ Context context = new ContextBase();
- Map<ElementSelector, Action> ruleMap = new HashMap<ElementSelector, Action>();
+ Map<ElementSelector, Action> ruleMap = new HashMap<ElementSelector, Action>();
- // Associate "/computation" pattern with ComputationAction1
- ruleMap.put(new ElementSelector("/computation"), new ComputationAction1());
+ // Associate "/computation" pattern with ComputationAction1
+ ruleMap.put(new ElementSelector("/computation"), new ComputationAction1());
- // Other associations
- ruleMap.put(new ElementSelector("/computation/literal"), new LiteralAction());
- ruleMap.put(new ElementSelector("/computation/add"), new AddAction());
- ruleMap.put(new ElementSelector("/computation/multiply"), new MultiplyAction());
+ // Other associations
+ ruleMap.put(new ElementSelector("/computation/literal"), new LiteralAction());
+ ruleMap.put(new ElementSelector("/computation/add"), new AddAction());
+ ruleMap.put(new ElementSelector("/computation/multiply"), new MultiplyAction());
- SimpleConfigurator simpleConfigurator = new SimpleConfigurator(ruleMap);
- // link the configurator with its context
- simpleConfigurator.setContext(context);
+ SimpleConfigurator simpleConfigurator = new SimpleConfigurator(ruleMap);
+ // link the configurator with its context
+ simpleConfigurator.setContext(context);
- simpleConfigurator.doConfigure(args[0]);
- // Print any errors that might have occured.
- StatusPrinter.print(context);
- }
+ simpleConfigurator.doConfigure(args[0]);
+ // Print any errors that might have occured.
+ StatusPrinter.print(context);
+ }
}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/Calculator2.java b/logback-examples/src/main/java/chapters/onJoran/calculator/Calculator2.java
index 3319805..b1ef676 100644
--- a/logback-examples/src/main/java/chapters/onJoran/calculator/Calculator2.java
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/Calculator2.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -24,6 +24,7 @@ import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.util.StatusPrinter;
import chapters.onJoran.SimpleConfigurator;
+
/**
* This examples illustrates collaboration between multiple actions through the
* common execution context stack.
@@ -33,30 +34,31 @@ import chapters.onJoran.SimpleConfigurator;
*
* You can test this application with the sample XML file <em>calculator3.xml</em>.
*
- * @author Ceki Gülcü
+ * @author Ceki Güulcü
*/
public class Calculator2 {
- public static void main(String[] args) throws Exception {
- Map<ElementSelector, Action> ruleMap = new HashMap<ElementSelector, Action>();
-
- // Note the wild card character '*', in the paterns, signifying any level
- // of nesting.
- ruleMap.put(new ElementSelector("*/computation"), new ComputationAction2());
-
- ruleMap.put(new ElementSelector("*/computation/literal"), new LiteralAction());
- ruleMap.put(new ElementSelector("*/computation/add"), new AddAction());
- ruleMap.put(new ElementSelector("*/computation/multiply"), new MultiplyAction());
+ public static void main(String[] args) throws Exception {
+ Map<ElementSelector, Action> ruleMap = new HashMap<ElementSelector, Action>();
+
+
+ // Note the wild card character '*', in the paterns, signifying any level
+ // of nesting.
+ ruleMap.put(new ElementSelector("*/computation"), new ComputationAction2());
- Context context = new ContextBase();
- SimpleConfigurator simpleConfigurator = new SimpleConfigurator(ruleMap);
- // link the configurator with its context
- simpleConfigurator.setContext(context);
+ ruleMap.put(new ElementSelector("*/computation/literal"), new LiteralAction());
+ ruleMap.put(new ElementSelector("*/computation/add"), new AddAction());
+ ruleMap.put(new ElementSelector("*/computation/multiply"), new MultiplyAction());
+
+ Context context = new ContextBase();
+ SimpleConfigurator simpleConfigurator = new SimpleConfigurator(ruleMap);
+ // link the configurator with its context
+ simpleConfigurator.setContext(context);
- try {
- simpleConfigurator.doConfigure(args[0]);
- } catch (JoranException e) {
- // Print any errors that might have occured.
- StatusPrinter.print(context);
- }
+ try {
+ simpleConfigurator.doConfigure(args[0]);
+ } catch (JoranException e) {
+ // Print any errors that might have occured.
+ StatusPrinter.print(context);
}
+ }
}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/ComputationAction1.java b/logback-examples/src/main/java/chapters/onJoran/calculator/ComputationAction1.java
index b738611..ed040fc 100644
--- a/logback-examples/src/main/java/chapters/onJoran/calculator/ComputationAction1.java
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/ComputationAction1.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -13,12 +13,15 @@
*/
package chapters.onJoran.calculator;
+
+
import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.util.OptionHelper;
+
/**
* ComputationAction1 will print the result of the compuration made by
* children elements but only if the compuration itself is named, that is if the
@@ -28,30 +31,31 @@ import ch.qos.logback.core.util.OptionHelper;
* @author Ceki Gülcü
*/
public class ComputationAction1 extends Action {
- public static final String NAME_ATR = "name";
+ public static final String NAME_ATR = "name";
- String nameStr;
+ String nameStr;
- /**
- * Store the value of the name attribute for future use.
- */
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- nameStr = attributes.getValue(NAME_ATR);
- }
+ /**
+ * Store the value of the name attribute for future use.
+ */
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ nameStr = attributes.getValue(NAME_ATR);
+ }
- /**
- * Children elements have been processed. The sesults should be an integer
- * placed at the top of the execution stack.
- *
- * This value will be printed on the console but only if the action is
- * named. Anonymous computation will not print their result.
- */
- public void end(InterpretationContext ec, String name) {
- if (OptionHelper.isEmpty(nameStr)) {
- // nothing to do
- } else {
- Integer i = (Integer) ec.peekObject();
- System.out.println("The computation named [" + nameStr + "] resulted in the value " + i);
- }
+ /**
+ * Children elements have been processed. The sesults should be an integer
+ * placed at the top of the execution stack.
+ *
+ * This value will be printed on the console but only if the action is
+ * named. Anonymous computation will not print their result.
+ */
+ public void end(InterpretationContext ec, String name) {
+ if (OptionHelper.isEmpty(nameStr)) {
+ // nothing to do
+ } else {
+ Integer i = (Integer) ec.peekObject();
+ System.out.println(
+ "The computation named [" + nameStr + "] resulted in the value " + i);
}
+ }
}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/ComputationAction2.java b/logback-examples/src/main/java/chapters/onJoran/calculator/ComputationAction2.java
index ec91327..150b10a 100644
--- a/logback-examples/src/main/java/chapters/onJoran/calculator/ComputationAction2.java
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/ComputationAction2.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -21,6 +21,7 @@ import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.util.OptionHelper;
+
/**
* ComputationAction2 will print the result of the compuration made by
* children elements but only if the computation itself is named, that is if the
@@ -58,26 +59,28 @@ import ch.qos.logback.core.util.OptionHelper;
* @author Ceki Gülcü
*/
public class ComputationAction2 extends Action {
- public static final String NAME_ATR = "name";
-
- Stack<String> nameStrStack = new Stack<String>();
-
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- String nameStr = attributes.getValue(NAME_ATR);
- // save nameStr value in a special stack. Note that the value is saved
- // even if it is empty or null.
- nameStrStack.push(nameStr);
- }
+ public static final String NAME_ATR = "name";
- public void end(InterpretationContext ec, String name) {
- // pop nameStr value from the special stack
- String nameStr = (String) nameStrStack.pop();
+ Stack<String> nameStrStack = new Stack<String>();
+
+
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ String nameStr = attributes.getValue(NAME_ATR);
+ // save nameStr value in a special stack. Note that the value is saved
+ // even if it is empty or null.
+ nameStrStack.push(nameStr);
+ }
- if (OptionHelper.isEmpty(nameStr)) {
- // nothing to do
- } else {
- Integer i = (Integer) ec.peekObject();
- System.out.println("The computation named [" + nameStr + "] resulted in the value " + i);
- }
+ public void end(InterpretationContext ec, String name) {
+ // pop nameStr value from the special stack
+ String nameStr = (String) nameStrStack.pop();
+
+ if (OptionHelper.isEmpty(nameStr)) {
+ // nothing to do
+ } else {
+ Integer i = (Integer) ec.peekObject();
+ System.out.println(
+ "The computation named [" + nameStr + "] resulted in the value " + i);
}
+ }
}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/LiteralAction.java b/logback-examples/src/main/java/chapters/onJoran/calculator/LiteralAction.java
index 1b29088..f33627f 100644
--- a/logback-examples/src/main/java/chapters/onJoran/calculator/LiteralAction.java
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/LiteralAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,29 +29,30 @@ import ch.qos.logback.core.util.OptionHelper;
* @author Ceki Gülcü
*/
public class LiteralAction extends Action {
- public static final String VALUE_ATR = "value";
+ public static final String VALUE_ATR = "value";
- public void begin(InterpretationContext ic, String name, Attributes attributes) {
- String valueStr = attributes.getValue(VALUE_ATR);
+ public void begin(InterpretationContext ic, String name, Attributes attributes) {
+ String valueStr = attributes.getValue(VALUE_ATR);
- if (OptionHelper.isEmpty(valueStr)) {
- ic.addError("The literal action requires a value attribute");
- return;
- }
-
- try {
- Integer i = Integer.valueOf(valueStr);
- ic.pushObject(i);
- } catch (NumberFormatException nfe) {
- ic.addError("The value [" + valueStr + "] could not be converted to an Integer", nfe);
- throw nfe;
- }
+ if (OptionHelper.isEmpty(valueStr)) {
+ ic.addError("The literal action requires a value attribute");
+ return;
}
- public void end(InterpretationContext ic, String name) {
- // Nothing to do here.
- // In general, the end() method of actions associated with elements
- // having no children do not need to perform any processing in their
- // end() method.
+ try {
+ Integer i = Integer.valueOf(valueStr);
+ ic.pushObject(i);
+ } catch (NumberFormatException nfe) {
+ ic.addError("The value [" + valueStr
+ + "] could not be converted to an Integer", nfe);
+ throw nfe;
}
+ }
+
+ public void end(InterpretationContext ic, String name) {
+ // Nothing to do here.
+ // In general, the end() method of actions associated with elements
+ // having no children do not need to perform any processing in their
+ // end() method.
+ }
}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/MultiplyAction.java b/logback-examples/src/main/java/chapters/onJoran/calculator/MultiplyAction.java
index f9137ee..4ed7624 100644
--- a/logback-examples/src/main/java/chapters/onJoran/calculator/MultiplyAction.java
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/MultiplyAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,37 +29,38 @@ import java.util.EmptyStackException;
*/
public class MultiplyAction extends Action {
- public void begin(InterpretationContext ic, String name, Attributes attributes) {
- int first = fetchInteger(ic);
- int second = fetchInteger(ic);
- ic.pushObject(first * second);
- }
+ public void begin(InterpretationContext ic, String name, Attributes attributes) {
+ int first = fetchInteger(ic);
+ int second = fetchInteger(ic);
+ ic.pushObject(first * second);
+ }
- /**
- * Pop the Integer object at the top of the stack. This code illustrates usage
- * of Joran's error handling paradigm.
- */
- int fetchInteger(InterpretationContext ic) {
- int result = 0;
+ /**
+ * Pop the Integer object at the top of the stack. This code illustrates usage
+ * of Joran's error handling paradigm.
+ */
+ int fetchInteger(InterpretationContext ic) {
+ int result = 0;
- try {
- Object o1 = ic.popObject();
+ try {
+ Object o1 = ic.popObject();
- if (o1 instanceof Integer) {
- result = ((Integer) o1).intValue();
- } else {
- String errMsg = "Object [" + o1 + "] currently at the top of the stack is not an integer.";
- ic.addError(errMsg);
- throw new IllegalArgumentException(errMsg);
- }
- } catch (EmptyStackException ese) {
- ic.addError("Expecting an integer on the execution stack.");
- throw ese;
- }
- return result;
+ if (o1 instanceof Integer) {
+ result = ((Integer) o1).intValue();
+ } else {
+ String errMsg = "Object [" + o1
+ + "] currently at the top of the stack is not an integer.";
+ ic.addError(errMsg);
+ throw new IllegalArgumentException(errMsg);
+ }
+ } catch (EmptyStackException ese) {
+ ic.addError("Expecting an integer on the execution stack.");
+ throw ese;
}
+ return result;
+ }
- public void end(InterpretationContext ic, String name) {
- // Nothing to do here.
- }
+ public void end(InterpretationContext ic, String name) {
+ // Nothing to do here.
+ }
}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/calculator1.xml b/logback-examples/src/main/java/chapters/onJoran/calculator/calculator1.xml
new file mode 100644
index 0000000..d06aa7f
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/calculator1.xml
@@ -0,0 +1,3 @@
+<computation name="total">
+ <literal value="3"/>
+</computation>
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/calculator2.xml b/logback-examples/src/main/java/chapters/onJoran/calculator/calculator2.xml
new file mode 100644
index 0000000..92e67b0
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/calculator2.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE computation>
+
+<computation name="toto">
+ <literal value="7"/>
+ <literal value="3"/>
+ <add/>
+ <literal value="3"/>
+ <multiply/>
+</computation>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/calculator3.xml b/logback-examples/src/main/java/chapters/onJoran/calculator/calculator3.xml
new file mode 100644
index 0000000..5532b5e
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/calculator3.xml
@@ -0,0 +1,15 @@
+<!-- This file is intended to be executed by Caculator2.
+ It is not suited for Calculator1 due to nested computation
+ elements.
+ -->
+
+<computation name="toto">
+ <computation>
+ <literal value="7"/>
+ <literal value="3"/>
+ <add/>
+ </computation>
+
+ <literal value="3"/>
+ <multiply/>
+</computation>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/onJoran/helloWorld/HelloWorld.java b/logback-examples/src/main/java/chapters/onJoran/helloWorld/HelloWorld.java
index 554c80b..93fdb12 100644
--- a/logback-examples/src/main/java/chapters/onJoran/helloWorld/HelloWorld.java
+++ b/logback-examples/src/main/java/chapters/onJoran/helloWorld/HelloWorld.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -30,19 +30,19 @@ import chapters.onJoran.SimpleConfigurator;
* @author Ceki Gulcu
*/
public class HelloWorld {
- public static void main(String[] args) throws Exception {
- Map<ElementSelector, Action> ruleMap = new HashMap<ElementSelector, Action>();
+ public static void main(String[] args) throws Exception {
+ Map<ElementSelector, Action> ruleMap = new HashMap<ElementSelector, Action>();
- // Associate "hello-world" pattern with HelloWorldAction
- ruleMap.put(new ElementSelector("hello-world"), new HelloWorldAction());
+ // Associate "hello-world" pattern with HelloWorldAction
+ ruleMap.put(new ElementSelector("hello-world"), new HelloWorldAction());
- // Joran needs to work within a context.
- Context context = new ContextBase();
- SimpleConfigurator simpleConfigurator = new SimpleConfigurator(ruleMap);
- // link the configurator with its context
- simpleConfigurator.setContext(context);
+ // Joran needs to work within a context.
+ Context context = new ContextBase();
+ SimpleConfigurator simpleConfigurator = new SimpleConfigurator(ruleMap);
+ // link the configurator with its context
+ simpleConfigurator.setContext(context);
- simpleConfigurator.doConfigure(args[0]);
- StatusPrinter.print(context);
- }
+ simpleConfigurator.doConfigure(args[0]);
+ StatusPrinter.print(context);
+ }
}
diff --git a/logback-examples/src/main/java/chapters/onJoran/helloWorld/HelloWorldAction.java b/logback-examples/src/main/java/chapters/onJoran/helloWorld/HelloWorldAction.java
index 051dcf1..9ed9936 100644
--- a/logback-examples/src/main/java/chapters/onJoran/helloWorld/HelloWorldAction.java
+++ b/logback-examples/src/main/java/chapters/onJoran/helloWorld/HelloWorldAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -26,10 +26,10 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
* @author Ceki Gülcü
*/
public class HelloWorldAction extends Action {
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- System.out.println("Hello World");
- }
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ System.out.println("Hello World");
+ }
- public void end(InterpretationContext ec, String name) {
- }
+ public void end(InterpretationContext ec, String name) {
+ }
}
diff --git a/logback-examples/src/main/java/chapters/onJoran/helloWorld/hello.xml b/logback-examples/src/main/java/chapters/onJoran/helloWorld/hello.xml
new file mode 100644
index 0000000..5089742
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/helloWorld/hello.xml
@@ -0,0 +1,2 @@
+<hello-world>
+</hello-world>
diff --git a/logback-examples/src/main/java/chapters/onJoran/implicit/NOPAction.java b/logback-examples/src/main/java/chapters/onJoran/implicit/NOPAction.java
index da30f76..f531398 100644
--- a/logback-examples/src/main/java/chapters/onJoran/implicit/NOPAction.java
+++ b/logback-examples/src/main/java/chapters/onJoran/implicit/NOPAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -18,16 +18,17 @@ import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.InterpretationContext;
+
/**
* No operation (NOP) action that does strictly nothing.
*
* @author Ceki Gülcü
*/
public class NOPAction extends Action {
+
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ }
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- }
-
- public void end(InterpretationContext ec, String name) {
- }
+ public void end(InterpretationContext ec, String name) {
+ }
}
diff --git a/logback-examples/src/main/java/chapters/onJoran/implicit/PrintMe.java b/logback-examples/src/main/java/chapters/onJoran/implicit/PrintMe.java
index 1956bbf..09b887f 100644
--- a/logback-examples/src/main/java/chapters/onJoran/implicit/PrintMe.java
+++ b/logback-examples/src/main/java/chapters/onJoran/implicit/PrintMe.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -33,28 +33,29 @@ import chapters.onJoran.SimpleConfigurator;
* pattern. Moreover, they are added directly to a Joran Interpreter instead of
* a rule store.
*
- * @author Ceki Gülcü
+ * @author Ceki Güulcü
*/
public class PrintMe {
- public static void main(String[] args) throws Exception {
- Context context = new ContextBase();
+ public static void main(String[] args) throws Exception {
+ Context context = new ContextBase();
- Map<ElementSelector, Action> ruleMap = new HashMap<ElementSelector, Action>();
+ Map<ElementSelector, Action> ruleMap = new HashMap<ElementSelector, Action>();
- // we start with the rule for the top-most (root) element
- ruleMap.put(new ElementSelector("*/foo"), new NOPAction());
+ // we start with the rule for the top-most (root) element
+ ruleMap.put(new ElementSelector("*/foo"), new NOPAction());
- // Add an implicit action.
- List<ImplicitAction> iaList = new ArrayList<ImplicitAction>();
- iaList.add(new PrintMeImplicitAction());
- SimpleConfigurator simpleConfigurator = new SimpleConfigurator(ruleMap, iaList);
+ // Add an implicit action.
+ List<ImplicitAction> iaList = new ArrayList<ImplicitAction>();
+ iaList.add(new PrintMeImplicitAction());
+ SimpleConfigurator simpleConfigurator = new SimpleConfigurator(ruleMap,
+ iaList);
- // link the configurator with its context
- simpleConfigurator.setContext(context);
+ // link the configurator with its context
+ simpleConfigurator.setContext(context);
- simpleConfigurator.doConfigure(args[0]);
- StatusPrinter.printInCaseOfErrorsOrWarnings(context);
-
- }
+ simpleConfigurator.doConfigure(args[0]);
+ StatusPrinter.printInCaseOfErrorsOrWarnings(context);
+
+ }
}
diff --git a/logback-examples/src/main/java/chapters/onJoran/implicit/PrintMeImplicitAction.java b/logback-examples/src/main/java/chapters/onJoran/implicit/PrintMeImplicitAction.java
index 22ef410..6d096c0 100644
--- a/logback-examples/src/main/java/chapters/onJoran/implicit/PrintMeImplicitAction.java
+++ b/logback-examples/src/main/java/chapters/onJoran/implicit/PrintMeImplicitAction.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -28,16 +28,17 @@ import ch.qos.logback.core.joran.spi.InterpretationContext;
*/
public class PrintMeImplicitAction extends ImplicitAction {
- public boolean isApplicable(ElementPath elementPath, Attributes attributes, InterpretationContext ec) {
- String printmeStr = attributes.getValue("printme");
+ public boolean isApplicable(ElementPath elementPath, Attributes attributes,
+ InterpretationContext ec) {
+ String printmeStr = attributes.getValue("printme");
- return Boolean.valueOf(printmeStr).booleanValue();
- }
+ return Boolean.valueOf(printmeStr).booleanValue();
+ }
- public void begin(InterpretationContext ec, String name, Attributes attributes) {
- System.out.println("Element [" + name + "] asked to be printed.");
- }
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ System.out.println("Element [" + name + "] asked to be printed.");
+ }
- public void end(InterpretationContext ec, String name) {
- }
+ public void end(InterpretationContext ec, String name) {
+ }
}
diff --git a/logback-examples/src/main/java/chapters/onJoran/implicit/implicit1.xml b/logback-examples/src/main/java/chapters/onJoran/implicit/implicit1.xml
new file mode 100644
index 0000000..5d20377
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/implicit/implicit1.xml
@@ -0,0 +1,21 @@
+<foo>
+
+ <!-- These elements will print due to the implicit rule -->
+ <xyz printme="true">
+ <abc printme="true"/>
+ </xyz>
+
+ <!-- This element has no associated rule and no implicit rule
+ applies for it because the printme attribute is not set. -->
+ <xyz/>
+
+
+
+ <!-- This element will not be printed even if its printme
+ attribute is set because implicit rules are invoked only
+ if no explicit rule matches the element. The */foo rule
+ matches the following element.
+ -->
+ <foo printme="true"/>
+
+</foo>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/onJoran/newRule/NewRuleCalculator.java b/logback-examples/src/main/java/chapters/onJoran/newRule/NewRuleCalculator.java
index 6902c9e..e69d372 100644
--- a/logback-examples/src/main/java/chapters/onJoran/newRule/NewRuleCalculator.java
+++ b/logback-examples/src/main/java/chapters/onJoran/newRule/NewRuleCalculator.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -32,32 +32,32 @@ import chapters.onJoran.calculator.ComputationAction1;
* <p>This example relies heavily on the code from the joran.calculator
* package.
*
- * @author Ceki Gülcü
+ * @author Ceki Güulcü
*/
public class NewRuleCalculator {
- public static void main(String[] args) throws Exception {
+ public static void main(String[] args) throws Exception {
- Context context = new ContextBase();
+ Context context = new ContextBase();
- Map<ElementSelector, Action> ruleMap = new HashMap<ElementSelector, Action>();
+ Map<ElementSelector, Action> ruleMap = new HashMap<ElementSelector, Action>();
- // we start with the rule for the top-most (root) element
- ruleMap.put(new ElementSelector("*/computation"), new ComputationAction1());
+ // we start with the rule for the top-most (root) element
+ ruleMap.put(new ElementSelector("*/computation"), new ComputationAction1());
- // Associate "/new-rule" pattern with NewRuleAction from the
- // org.apache.joran.action package.
- //
- // We will let the XML file to teach the Joran interpreter about new rules
- ruleMap.put(new ElementSelector("/computation/newRule"), new NewRuleAction());
+ // Associate "/new-rule" pattern with NewRuleAction from the
+ // org.apache.joran.action package.
+ //
+ // We will let the XML file to teach the Joran interpreter about new rules
+ ruleMap.put(new ElementSelector("/computation/newRule"), new NewRuleAction());
- SimpleConfigurator simpleConfigurator = new SimpleConfigurator(ruleMap);
- // link the configurator with its context
- simpleConfigurator.setContext(context);
+ SimpleConfigurator simpleConfigurator = new SimpleConfigurator(ruleMap);
+ // link the configurator with its context
+ simpleConfigurator.setContext(context);
- simpleConfigurator.doConfigure(args[0]);
+ simpleConfigurator.doConfigure(args[0]);
- // Print any errors that might have occured.
- StatusPrinter.printInCaseOfErrorsOrWarnings(context);
- }
+ // Print any errors that might have occured.
+ StatusPrinter.printInCaseOfErrorsOrWarnings(context);
+ }
}
diff --git a/logback-examples/src/main/java/chapters/onJoran/newRule/newRule.xml b/logback-examples/src/main/java/chapters/onJoran/newRule/newRule.xml
new file mode 100644
index 0000000..167c264
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/newRule/newRule.xml
@@ -0,0 +1,23 @@
+<!--
+ This file is intended to be executed by NewRuleCalculator.
+ Note that the rules for adding and multiplying are learned on
+ the fly, while parsingthis file.
+-->
+
+<computation name="toto">
+ <new-rule pattern="*/computation/literal"
+ actionClass="chapters.onJoran.calculator.LiteralAction"/>
+ <new-rule pattern="*/computation/add"
+ actionClass="chapters.onJoran.calculator.AddAction"/>
+ <new-rule pattern="*/computation/multiply"
+ actionClass="chapters.onJoran.calculator.MultiplyAction"/>
+
+ <computation>
+ <literal value="7"/>
+ <literal value="3"/>
+ <add/>
+ </computation>
+
+ <literal value="3"/>
+ <multiply/>
+</computation>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/receivers/socket/AppenderExample.java b/logback-examples/src/main/java/chapters/receivers/socket/AppenderExample.java
index 6e5d701..2ebb6ac 100644
--- a/logback-examples/src/main/java/chapters/receivers/socket/AppenderExample.java
+++ b/logback-examples/src/main/java/chapters/receivers/socket/AppenderExample.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -29,45 +29,48 @@ import ch.qos.logback.classic.joran.JoranConfigurator;
*/
public class AppenderExample {
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + AppenderExample.class.getName() + " configFile\n" + " configFile a logback configuration file"
- + " in XML format.");
- System.exit(1);
- }
-
- static public void main(String[] args) throws Exception {
- if (args.length != 1) {
- usage("Wrong number of arguments.");
- }
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + AppenderExample.class.getName() +
+ " configFile\n" +
+ " configFile a logback configuration file" +
+ " in XML format.");
+ System.exit(1);
+ }
- String configFile = args[0];
+ static public void main(String[] args) throws Exception {
+ if (args.length != 1) {
+ usage("Wrong number of arguments.");
+ }
- if (configFile.endsWith(".xml")) {
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- lc.reset();
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- configurator.doConfigure(configFile);
- }
+ String configFile = args[0];
- Logger logger = LoggerFactory.getLogger(AppenderExample.class);
+ if (configFile.endsWith(".xml")) {
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ lc.reset();
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ configurator.doConfigure(configFile);
+ }
- BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+ Logger logger = LoggerFactory.getLogger(AppenderExample.class);
- while (true) {
- System.out.println("Type a message to send to remote clients. Type 'q' to quit.");
+ BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
- String s = reader.readLine();
+ while (true) {
+ System.out.println(
+ "Type a message to send to remote clients. Type 'q' to quit.");
- if (s.equals("q")) {
- break;
- } else {
- logger.debug(s);
- }
- }
+ String s = reader.readLine();
- ((LoggerContext) LoggerFactory.getILoggerFactory()).stop();
+ if (s.equals("q")) {
+ break;
+ } else {
+ logger.debug(s);
+ }
}
+
+ ((LoggerContext) LoggerFactory.getILoggerFactory()).stop();
+ }
}
diff --git a/logback-examples/src/main/java/chapters/receivers/socket/ReceiverExample.java b/logback-examples/src/main/java/chapters/receivers/socket/ReceiverExample.java
index 016ef1f..84c1dad 100644
--- a/logback-examples/src/main/java/chapters/receivers/socket/ReceiverExample.java
+++ b/logback-examples/src/main/java/chapters/receivers/socket/ReceiverExample.java
@@ -1,6 +1,6 @@
/**
* Logback: the reliable, generic, fast and flexible logging framework.
- * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+ * Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
@@ -25,29 +25,31 @@ import ch.qos.logback.classic.joran.JoranConfigurator;
*/
public class ReceiverExample {
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java " + ReceiverExample.class.getName() + " configFile\n" + " configFile a logback configuration file"
- + " in XML format.");
- System.exit(1);
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + ReceiverExample.class.getName() +
+ " configFile\n" +
+ " configFile a logback configuration file" +
+ " in XML format.");
+ System.exit(1);
+ }
+
+ static public void main(String[] args) throws Exception {
+ if (args.length != 1) {
+ usage("Wrong number of arguments.");
}
- static public void main(String[] args) throws Exception {
- if (args.length != 1) {
- usage("Wrong number of arguments.");
- }
+ String configFile = args[0];
- String configFile = args[0];
-
- if (configFile.endsWith(".xml")) {
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- lc.reset();
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- configurator.doConfigure(configFile);
- }
-
- Thread.sleep(Long.MAX_VALUE);
+ if (configFile.endsWith(".xml")) {
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ lc.reset();
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ configurator.doConfigure(configFile);
}
+ Thread.sleep(Long.MAX_VALUE);
+ }
+
}
diff --git a/logback-examples/src/main/java/chapters/receivers/socket/appender1.xml b/logback-examples/src/main/java/chapters/receivers/socket/appender1.xml
new file mode 100644
index 0000000..7ac3121
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/receivers/socket/appender1.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- Sample SocketAppender configuration. -->
+<!-- ==================================================================== -->
+
+<configuration debug="true">
+
+ <appender name="SERVER" class="ch.qos.logback.classic.net.SocketAppender">
+ <remoteHost>${host}</remoteHost>
+ <port>${port}</port>
+ <reconnectionDelay>10000</reconnectionDelay>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="SERVER" />
+ </root>
+
+</configuration>
+
+
+
diff --git a/logback-examples/src/main/java/chapters/receivers/socket/appender2.xml b/logback-examples/src/main/java/chapters/receivers/socket/appender2.xml
new file mode 100644
index 0000000..5cf9bb1
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/receivers/socket/appender2.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- Sample SSLSocketAppender configuration. -->
+<!-- ==================================================================== -->
+
+<configuration debug="true">
+
+ <appender name="SERVER" class="ch.qos.logback.classic.net.SSLSocketAppender">
+ <remoteHost>${host}</remoteHost>
+ <port>${port}</port>
+ <reconnectionDelay>10000</reconnectionDelay>
+ <ssl>
+ <trustStore>
+ <location>${truststore}</location>
+ <password>${password}</password>
+ </trustStore>
+ </ssl>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="SERVER" />
+ </root>
+
+</configuration>
+
+
+
diff --git a/logback-examples/src/main/java/chapters/receivers/socket/appender3.xml b/logback-examples/src/main/java/chapters/receivers/socket/appender3.xml
new file mode 100644
index 0000000..8fcdb69
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/receivers/socket/appender3.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- Sample ServerSocketAppender configuration. -->
+<!-- ==================================================================== -->
+
+<configuration debug="true">
+
+ <appender name="SERVER"
+ class="ch.qos.logback.classic.net.server.ServerSocketAppender">
+ <port>${port}</port>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="SERVER" />
+ </root>
+
+</configuration>
+
+
+
diff --git a/logback-examples/src/main/java/chapters/receivers/socket/appender4.xml b/logback-examples/src/main/java/chapters/receivers/socket/appender4.xml
new file mode 100644
index 0000000..5c7318f
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/receivers/socket/appender4.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- Sample SSLServerSocketAppender configuration. -->
+<!-- ==================================================================== -->
+
+<configuration debug="true">
+
+ <appender name="SERVER"
+ class="ch.qos.logback.classic.net.server.SSLServerSocketAppender">
+ <port>${port}</port>
+ <ssl>
+ <keyStore>
+ <location>${keystore}</location>
+ <password>${password}</password>
+ </keyStore>
+ </ssl>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="SERVER" />
+ </root>
+
+</configuration>
+
+
+
diff --git a/logback-examples/src/main/java/chapters/receivers/socket/receiver1.xml b/logback-examples/src/main/java/chapters/receivers/socket/receiver1.xml
new file mode 100644
index 0000000..aff9f96
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/receivers/socket/receiver1.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- Sample ServerSocketReceiver configuration. -->
+<!-- ==================================================================== -->
+
+<configuration debug="true">
+
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="CONSOLE" />
+ </root>
+
+ <receiver class="ch.qos.logback.classic.net.server.ServerSocketReceiver">
+ <port>${port}</port>
+ </receiver>
+
+</configuration>
+
+
+
diff --git a/logback-examples/src/main/java/chapters/receivers/socket/receiver2.xml b/logback-examples/src/main/java/chapters/receivers/socket/receiver2.xml
new file mode 100644
index 0000000..9891d50
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/receivers/socket/receiver2.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- Sample SSLServerSocketReceiver configuration. -->
+<!-- ==================================================================== -->
+
+<configuration debug="true">
+
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="CONSOLE" />
+ </root>
+
+ <receiver class="ch.qos.logback.classic.net.server.SSLServerSocketReceiver">
+ <port>${port}</port>
+ <ssl>
+ <keyStore>
+ <location>${keystore}</location>
+ <password>${password}</password>
+ </keyStore>
+ </ssl>
+ </receiver>
+
+</configuration>
+
+
+
diff --git a/logback-examples/src/main/java/chapters/receivers/socket/receiver3.xml b/logback-examples/src/main/java/chapters/receivers/socket/receiver3.xml
new file mode 100644
index 0000000..00db540
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/receivers/socket/receiver3.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- Sample SocketReceiver configuration. -->
+<!-- ==================================================================== -->
+
+<configuration debug="true">
+
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="CONSOLE" />
+ </root>
+
+ <receiver class="ch.qos.logback.classic.net.SocketReceiver">
+ <remoteHost>${host}</remoteHost>
+ <port>${port}</port>
+ <reconnectionDelay>10000</reconnectionDelay>
+ </receiver>
+
+</configuration>
+
+
+
diff --git a/logback-examples/src/main/java/chapters/receivers/socket/receiver4.xml b/logback-examples/src/main/java/chapters/receivers/socket/receiver4.xml
new file mode 100644
index 0000000..b2955a8
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/receivers/socket/receiver4.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!-- ==================================================================== -->
+<!-- Sample SSLSocketReceiver configuration. -->
+<!-- ==================================================================== -->
+
+<configuration debug="true">
+
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="CONSOLE" />
+ </root>
+
+ <receiver class="ch.qos.logback.classic.net.SSLSocketReceiver">
+ <remoteHost>${host}</remoteHost>
+ <port>${port}</port>
+ <reconnectionDelay>10000</reconnectionDelay>
+ <ssl>
+ <trustStore>
+ <location>${truststore}</location>
+ <password>${password}</password>
+ </trustStore>
+ </ssl>
+ </receiver>
+
+</configuration>
+
+
+
diff --git a/logback-site/pom.xml b/logback-site/pom.xml
index d029e2a..85d5181 100644
--- a/logback-site/pom.xml
+++ b/logback-site/pom.xml
@@ -1,22 +1,41 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-parent</artifactId>
- <version>1.1.9</version>
+ <version>1.1.2</version>
</parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>ch.qos.logback</groupId>
<artifactId>logback-site</artifactId>
<packaging>jar</packaging>
<name>Logback Site</name>
<description>logback-site module</description>
+ <url>http://logback.qos.ch</url>
+
+ <organization>
+ <name>QOS.ch</name>
+ <url>http://www.qos.ch</url>
+ </organization>
<inceptionYear>1999</inceptionYear>
+ <licenses>
+ <license>
+ <name>Eclipse Public License - v 1.0</name>
+ <url>http://www.eclipse.org/legal/epl-v10.html</url>
+ </license>
+
+ <license>
+ <name>GNU Lesser General Public License</name>
+ <url>http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</url>
+ </license>
+ </licenses>
+
<build>
<resources>
<resource>
@@ -38,6 +57,7 @@
</configuration>
</plugin>
</plugins>
+
</build>
</project>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/access.html b/logback-site/src/site/pages/access.html
index cf841a8..57afaf8 100644
--- a/logback-site/src/site/pages/access.html
+++ b/logback-site/src/site/pages/access.html
@@ -17,34 +17,30 @@
<div id="left">
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="templates/right.js" type="text/javascript"></script>
- </div>
-
<div id="content">
-
+
<h2>HTTP-access logs with logback-access, Jetty and Tomcat</h2>
<div class="author">
- Authors: Ceki Gülcü, Sébastien Pennec
- </div>
+ Authors: Ceki Gülcü, Sébastien Pennec
+ </div>
<script src="../templates/creative.js" type="text/javascript"></script>
- <h1>Introduction</h1>
+ <h1>Introduction</h1>
<p>The logback-access module, part of the standard logback
distribution, integrates with Servlet containers such as Jetty or
Tomcat to provide rich and powerful HTTP-access log functionality.
</p>
-
- <p>Logback was designed as a modular framework from the
- start. Making logback-core reusable under different circumstances
- without much recoding was one of our main goals. In accordance
- with this strategy, logback-access builds on top of logback-core
- and can thus provide much of the functionality of logback-classic
- but in the scope of HTTP-access logging. </p>
+
+ <p>Logback was designed as a modular framework from the
+ start. Making logback-core reusable under different circumstances
+ without much recoding was one of our main goals. In accordance
+ with this strategy, logback-access builds on top of logback-core
+ and can thus provide much of the functionality of logback-classic
+ but in the scope of HTTP-access logging. </p>
<p>It should be noted that while logback-access requires
logback-core, it is independent of logback-classic as well as
@@ -54,18 +50,18 @@
level of a web-application.
</p>
- <h1><a name="tomcat" href="#tomcat">Logback-access under Tomcat</a></h1>
-
+ <h1><a name="tomcat" href="#tomcat">Logback-access under Tomcat</a></h1>
+
- <p>To use logback-access with Tomcat, after downloading the
- logback distribution, place the files
- <em>logback-core-${project.version}.jar</em> and
- <em>logback-access-${project.version}.jar</em> under
- $TOMCAT_HOME/lib/ directory, where $TOMCAT_HOME is the folder
- where you have installed Tomcat.
+ <p>To use logback-access with Tomcat, after downloading the
+ logback distribution, place the files
+ <em>logback-core-${project.version}.jar</em> and
+ <em>logback-access-${project.version}.jar</em> under
+ $TOMCAT_HOME/lib/ directory, where $TOMCAT_HOME is the folder
+ where you have installed Tomcat.
</p>
<p class="highlight">Deploying recent versions of logback-access
@@ -73,52 +69,44 @@
server to crash.</p>
<p><span class="label notice">Tomcat 7.x</span> This version of
- logback-access has been tested with Tomcat version 7.0.62. It will
+ logback-access has been tested with Tomcat version 7.0.21. It will
not work with Tomcat 6.x.
- </p>
+ </p>
<p><span class="label notice">Tomcat 6.x</span> Logback-access
version 0.9.30 will deploy on Tomcat 6.x.</p>
- <h2>LogbackValve</h2>
-
- <p>The <a
- href="xref/ch/qos/logback/access/tomcat/LogbackValve.html">
- <code>ch.qos.logback.access.tomcat.LogbackValve</code></a> class
- extends Tomcat's <code><a
- href="http://tomcat.apache.org/tomcat-5.5-doc/catalina/docs/api/org/apache/catalina/valves/ValveBase.html">
- ValveBase</a></code> class. Valves are usually associated together
- to form a processing pipeline.
- </p>
-
- <p>To configure Tomcat in order to use <code>LogbackValve</code>,
- add the following lines to the tomcat server configuration file,
- namely <em>$TOMCAT_HOME/conf/server.xml</em>:
- </p>
- <pre class="source"><Valve className="ch.qos.logback.access.tomcat.LogbackValve"/></pre>
-
- <p>This line is usually nested within an <code><Engine></code>
- or <code><Host></code> element.
- </p>
-
- <p>By default, <code>LogbackValve</code> looks for a configuration
- file called <em>logback-access.xml</em>, in the same folder where
- <em>server.xml</em> is located, that is in
- <em>$TOMCAT_HOME/conf/</em>. This configuration file contains
- directives for configuring logback-access components. It is used
- to specify appenders where the logging requests will be
- sent. Please refer to the <a href="#configuration">logback-access
- configuration section</a> further below.
- </p>
-
- <p>If the <code>LogbackValve</code> is not able to read a configuration file
- from the filesystem, it will attempt to load it as a resource (i.e.
- getClassLoader().getResourceAsStream()). This might be helpful in scenarios
- where your application is embedding Tomcat (e.g. using Spring Boot.) As
- mentioned above, if no filename is set, it defaults to looking for a
- resource named logback-access.xml.
- </p>
-
+ <h2>LogbackValve</h2>
+
+ <p>The <a
+ href="xref/ch/qos/logback/access/tomcat/LogbackValve.html">
+ <code>ch.qos.logback.access.tomcat.LogbackValve</code></a> class
+ extends Tomcat's <code><a
+ href="http://tomcat.apache.org/tomcat-5.5-doc/catalina/docs/api/org/apache/catalina/valves/ValveBase.html">
+ ValveBase</a></code> class. Valves are usually associated together
+ to form a processing pipeline.
+ </p>
+
+ <p>To configure Tomcat in order to use <code>LogbackValve</code>,
+ add the following lines to the tomcat server configuration file,
+ namely <em>$TOMCAT_HOME/conf/server.xml</em>:
+ </p>
+ <pre class="source"><Valve className="ch.qos.logback.access.tomcat.LogbackValve"/></pre>
+
+ <p>This line is usually nested within an <code><Engine></code>
+ or <code><Host></code> element.
+ </p>
+
+ <p>By default, <code>LogbackValve</code> looks for a configuration
+ file called <em>logback-access.xml</em>, in the same folder where
+ <em>server.xml</em> is located, that is in
+ <em>$TOMCAT_HOME/conf/</em>. This configuration file contains
+ directives for configuring logback-access components. It is used
+ to specify appenders where the logging requests will be
+ sent. Please refer to the <a href="#configuration">logback-access
+ configuration section</a> further below.
+ </p>
+
<p>In order to help with troubleshooting, by default, the
<code>LogbackValve</code> will print its internal status at its
initialization. Typical output would look as:
@@ -127,6 +115,7 @@
<p class="source">21:56:09,921 |-INFO in c.q.lb.access.j.a.ConfigurationAction - Ignoring debug attribute.
21:56:09,921 |-INFO in c.q.lb.core.j.a.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
21:56:09,921 |-INFO in c.q.lb.core.j.a.AppenderAction - Naming appender as [STDOUT]
+21:56:10,000 |-INFO in c.q.lb.core.j.a.NestedComponentIA - Pushing component [layout] on top of the object stack.
21:56:10,015 |-INFO in c.q.lb.core.j.a.AppenderAction - Popping appender named [STDOUT] from the object stack
21:56:10,015 |-INFO in c.q.lb.core.j.a.AppenderRefAction - Attaching appender named [STDOUT] to ch.qos.logback.access.tomcat.LogbackValve[Catalina]
21:56:10,015 |-INFO in c.q.lb.access.j.a.ConfigurationAction - End of configuration.</p>
@@ -172,42 +161,42 @@
</p>
- <h1><a name="jetty" href="#jetty">Logback-access under
- Jetty</a></h1>
-
- <p>After downloading the logback distribution, place the files
- <em>logback-core-VERSION.jar</em> and
- <em>logback-access-VERSION.jar</em> under $JETTY_HOME/lib
- directory, where $JETTY_HOME is the folder where you have
- installed Jetty. Versions of logback-access 0.9.31 and later
- target Jetty versions 7.x and 8.x. Logback-access versions 0.9.30
- and earlier target Jetty version 6.x.
- </p>
-
- <h3>Logback's implementation of
- <code>org.eclipse.jetty.server.RequestLog</code> interface</h3>
-
- <p>The <a
- href="xref/ch/qos/logback/access/jetty/RequestLogImpl.html">
- <code>ch.qos.logback.access.jetty.RequestLogImpl</code></a> class
- implements Jetty's <code><a
- href="http://download.eclipse.org/jetty/stable-7/apidocs/org/eclipse/jetty/server/RequestLog.html">RequestLog</a></code>
- interface. Jetty delegates the management of access logging
- functionality to implementations of this interface.
- </p>
-
- <p>In logback, a logging destination is called an "appender" which
- can be directly attached to a
- <code>ch.qos.logback.access.jetty.RequestLogImpl</code> instance.
- </p>
-
-
- <p>In order to configure Jetty to use logback-access's
- <code>RequestLogImpl</code>, please add the following lines to
- Jetty's main configuration file, namely
- <em>$JETTY_HOME/etc/jetty.xml</em>:
- </p>
- <pre class="prettyprint source"><Ref id="RequestLogHandler">
+ <h1><a name="jetty" href="#jetty">Logback-access under
+ Jetty</a></h1>
+
+ <p>After downloading the logback distribution, place the files
+ <em>logback-core-VERSION.jar</em> and
+ <em>logback-access-VERSION.jar</em> under $JETTY_HOME/lib
+ directory, where $JETTY_HOME is the folder where you have
+ installed Jetty. Versions of logback-access 0.9.31 and later
+ target Jetty versions 7.x and 8.x. Logback-access versions 0.9.30
+ and earlier target Jetty version 6.x.
+ </p>
+
+ <h3>Logback's implementation of
+ <code>org.eclipse.jetty.server.RequestLog</code> interface</h3>
+
+ <p>The <a
+ href="xref/ch/qos/logback/access/jetty/RequestLogImpl.html">
+ <code>ch.qos.logback.access.jetty.RequestLogImpl</code></a> class
+ implements Jetty's <code><a
+ href="http://download.eclipse.org/jetty/stable-7/apidocs/org/eclipse/jetty/server/RequestLog.html">RequestLog</a></code>
+ interface. Jetty delegates the management of access logging
+ functionality to implementations of this interface.
+ </p>
+
+ <p>In logback, a logging destination is called an "appender" which
+ can be directly attached to a
+ <code>ch.qos.logback.access.jetty.RequestLogImpl</code> instance.
+ </p>
+
+
+ <p>In order to configure Jetty to use logback-access's
+ <code>RequestLogImpl</code>, please add the following lines to
+ Jetty's main configuration file, namely
+ <em>$JETTY_HOME/etc/jetty.xml</em>:
+ </p>
+ <pre class="prettyprint source"><Ref id="RequestLogHandler">
<Set name="requestLog">
<New id="requestLogImpl" class="ch.qos.logback.access.jetty.RequestLogImpl">
</New>
@@ -250,13 +239,13 @@
directives for configuring logback components such as appenders
and layouts.
</p>
-
- <p>As long the path is specified, you can place the logback
- configuration file in any location. Here is another example of a
- Jetty configuration file, including the path to the logback-access
- configuration file here named <em>myaccess.xml</em>.
- </p>
-
+
+ <p>As long the path is specified, you can place the logback
+ configuration file in any location. Here is another example of a
+ Jetty configuration file, including the path to the logback-access
+ configuration file here named <em>myaccess.xml</em>.
+ </p>
+
<pre class="prettyprint source"><Ref id="RequestLogHandler">
<Set name="requestLog">
<New id="requestLogImpl" class="ch.qos.logback.access.jetty.RequestLogImpl">
@@ -281,21 +270,21 @@
<h1><a name="configuration" href="#configuration">Logback-access
configuration</a></h1>
-
-
+
+
<p>Although similar, the format of <em>logback-access.xml</em>
configuration file is slightly different than the configuration file
format logback-classic. Appenders and Layouts are declared the
exact same way. However, in the access module there is no notion of
loggers and consequently logger elements are disallowed.
- </p>
+ </p>
<h3>Example 1: basic logback-access configuration</h3>
- <p>
- Here is a small but fully functional <em>logback-access.xml</em>
- configuration file:
- </p>
+ <p>
+ Here is a small but fully functional <em>logback-access.xml</em>
+ configuration file:
+ </p>
<pre class="prettyprint source"><configuration>
<!-- always a good activate OnConsoleStatusListener -->
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
@@ -308,16 +297,16 @@
<appender-ref ref="STDOUT" />
</configuration></pre>
- <p>
- It declares a <code>ConsoleAppender</code> which prints its output
- on the console. The <code>ConsoleAppender</code> contains an
- <code>Encoder</code> object responsible for formatting output. The
- log format is specified by the "%h %l %u %user %date "%r" %s %b"
- pattern which incidentally corresponds to the Common Log Format
- (CLF). This format is recognized by log analyzers such as <a
- href="http://www.analog.cx/">Analog</a> or <a
- href="http://awstats.sourceforge.net/">AWStats</a>.
- </p>
+ <p>
+ It declares a <code>ConsoleAppender</code> which prints its output
+ on the console. The <code>ConsoleAppender</code> contains an
+ <code>Encoder</code> object responsible for formatting output. The
+ log format is specified by the "%h %l %u %user %date "%r" %s %b"
+ pattern which incidentally corresponds to the Common Log Format
+ (CLF). This format is recognized by log analyzers such as <a
+ href="http://www.analog.cx/">Analog</a> or <a
+ href="http://awstats.sourceforge.net/">AWStats</a>.
+ </p>
<p>The words "common" or "clf" are interpreted as shorthands for
the said pattern. Thus, the following are all equivalent:
@@ -346,11 +335,11 @@
<h3>Example 2: RollingFileAppender</h3>
- <p>The configuration file below configures a daily rolling
- <code>RollingFileAppender</code>. Note that due to the
- <em>.zip</em> suffix included in the value for <span
- class="option">fileNamePattern</span> option, the log files are not
- only rolled daily, but they are also automatically compressed.</p>
+ <p>The configuration file below configures a daily rolling
+ <code>RollingFileAppender</code>. Note that due to the
+ <em>.zip</em> suffix included in the value for <span
+ class="option">fileNamePattern</span> option, the log files are not
+ only rolled daily, but they are also automatically compressed.</p>
<pre class="prettyprint source"><configuration>
@@ -370,62 +359,62 @@
<appender-ref ref="FILE" />
</configuration></pre>
-
+
<p>These two examples should give you an idea of the possibilities
offered by logback-access. In principle, most if not all of the
features available in logback-classic are also available in
logback-access.
- </p>
+ </p>
<h3>PatternLayout</h3>
- <p>Logback-access ships with an http-specific implementation of <a
- href="xref/ch/qos/logback/access/PatternLayout.html">
- <code>PatternLayout</code></a>. For detailed instructions on how
- to use the <code>PatternLayout</code>, please refer to the <a
- href="manual/layouts.html#AccessPatternLayout">corresponding
- chapter</a> of the logback manual.
- </p>
-
- <h2>JMX Components</h2>
-
- <p>Logback-access integrates with JMX servers to publish
- information about its components.
- </p>
-
- <p>Both <code>RequestLogImpl</code> and <code>LogbackValve</code>
- expose data and can be updated via JMX. A special filter, covered
- further down this document, publishes statistical data on access
- logs.
- </p>
-
-
- <h3>Configuring Tomcat for JMX</h3>
-
- <p>In order to configure Tomcat for JMX, please add the following
- lines to the <em>$TOMCAT_HOME/bin/catalina.sh</em> shell script
- (or its MS Windows equivalent):
- </p>
-
+ <p>Logback-access ships with an http-specific implementation of <a
+ href="xref/ch/qos/logback/access/PatternLayout.html">
+ <code>PatternLayout</code></a>. For detailed instructions on how
+ to use the <code>PatternLayout</code>, please refer to the <a
+ href="manual/layouts.html#AccessPatternLayout">corresponding
+ chapter</a> of the logback manual.
+ </p>
+
+ <h2>JMX Components</h2>
+
+ <p>Logback-access integrates with JMX servers to publish
+ information about its components.
+ </p>
+
+ <p>Both <code>RequestLogImpl</code> and <code>LogbackValve</code>
+ expose data and can be updated via JMX. A special filter, covered
+ further down this document, publishes statistical data on access
+ logs.
+ </p>
+
+
+ <h3>Configuring Tomcat for JMX</h3>
+
+ <p>In order to configure Tomcat for JMX, please add the following
+ lines to the <em>$TOMCAT_HOME/bin/catalina.sh</em> shell script
+ (or its MS Windows equivalent):
+ </p>
+
<div class="source"><pre>CATALINA_OPTS="-Dcom.sun.management.jmxremote"
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.ssl=false"
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.authenticate=false"</pre></div>
- <p>After you launch Tomcat, you can access the MBeans exposed by
- Tomcat via the JConsole application, which can be started with the
- following command:
- </p>
+ <p>After you launch Tomcat, you can access the MBeans exposed by
+ Tomcat via the JConsole application, which can be started with the
+ following command:
+ </p>
<pre class="source">jconsole</pre>
- <p>If you prefer MX4J to access your components via a web-based
- interface, here is a short summary of the steps to follow. After
- <a href="http://mx4j.sourceforge.net/">downloading MX4J</a>, place
- the <em>mx4j-impl.jar</em> file in the <em>$TOMCAT_HOME/bin/</em>
- directory, and the <em>mx4j-tools.jar</em> file in the
- <em>$TOMCAT_HOME/common/lib/</em> directory. Once that is done,
- add the following lines to the
- <em>$TOMCAT_HOME/bin/catalina.sh</em> shell script:
- </p>
+ <p>If you prefer MX4J to access your components via a web-based
+ interface, here is a short summary of the steps to follow. After
+ <a href="http://mx4j.sourceforge.net/">downloading MX4J</a>, place
+ the <em>mx4j-impl.jar</em> file in the <em>$TOMCAT_HOME/bin/</em>
+ directory, and the <em>mx4j-tools.jar</em> file in the
+ <em>$TOMCAT_HOME/common/lib/</em> directory. Once that is done,
+ add the following lines to the
+ <em>$TOMCAT_HOME/bin/catalina.sh</em> shell script:
+ </p>
<div class="source"><pre><!-- at the beginning of the file -->
CATALINA_OPTS="-Dcom.sun.management.jmxremote"
@@ -434,9 +423,9 @@ CATALINA_OPTS="$CATALINA_OPTS -Djavax.management.builder.initial=mx4j.server.MX4
<!-- in the "Add on extra jar files to CLASSPATH" section -->
CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/mx4j-impl.jar</pre></div>
- <p>Finally, declare a new <code>Connector</code> in the
- <em>$TOMCAT_HOME/conf/server.xml</em> file: </p>
-
+ <p>Finally, declare a new <code>Connector</code> in the
+ <em>$TOMCAT_HOME/conf/server.xml</em> file: </p>
+
<pre class="prettyprint source"><Connector port="8050"
handler.list="mx"
mx.enabled="true"
@@ -444,19 +433,19 @@ CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/mx4j-impl.jar</pre></div>
mx.httpPort="8082"
protocol="AJP/1.3" /></pre>
- <p> Once Tomcat is started, you should be able to reach your JMX
- components by pointing your browser at the following URL:
- </p>
+ <p> Once Tomcat is started, you should be able to reach your JMX
+ components by pointing your browser at the following URL:
+ </p>
<pre class="source">http://localhost:8082/</pre>
- <h3>Configuring Jetty</h3>
-
- <p>
- Configuring Jetty to publish JMX components requires a few modifications to the
- <em>$JETTY_HOME/etc/jetty.xml</em> configuration file. Here are the elements that need to be
- added:
- </p>
+ <h3>Configuring Jetty</h3>
+
+ <p>
+ Configuring Jetty to publish JMX components requires a few modifications to the
+ <em>$JETTY_HOME/etc/jetty.xml</em> configuration file. Here are the elements that need to be
+ added:
+ </p>
<pre class="prettyprint source"><Call id="MBeanServer" class="java.lang.management.ManagementFactory" name="getPlatformMBeanServer"/>
<!-- initialize the Jetty MBean container -->
@@ -472,15 +461,15 @@ CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/mx4j-impl.jar</pre></div>
</Call>
</Get></pre>
- <p>Once Jetty is started with this configuration, all available
- components can be reviewed at:
- </p>
+ <p>Once Jetty is started with this configuration, all available
+ components can be reviewed at:
+ </p>
<pre class="prettyprint source">http://localhost:8082/</pre>
- <p>Logback-access' <code>RequestLogImpl</code> should be
- available, including its <code>start()</code> and
- <code>stop()</code> methods.
- </p>
+ <p>Logback-access' <code>RequestLogImpl</code> should be
+ available, including its <code>start()</code> and
+ <code>stop()</code> methods.
+ </p>
<h2><a name="teeFilter"
@@ -533,7 +522,7 @@ CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/mx4j-impl.jar</pre></div>
<pattern>%fullRequest%n%n%fullResponse</pattern>
</encoder>
</appender>
-
+
<appender-ref ref="STDOUT" />
</configuration></pre>
diff --git a/logback-site/src/site/pages/beagle/index.html b/logback-site/src/site/pages/beagle/index.html
index 4323e7c..e88e254 100644
--- a/logback-site/src/site/pages/beagle/index.html
+++ b/logback-site/src/site/pages/beagle/index.html
@@ -23,9 +23,6 @@
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="../templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="../templates/right.js" type="text/javascript"></script>
- </div>
<div id="content">
diff --git a/logback-site/src/site/pages/bugreport.html b/logback-site/src/site/pages/bugreport.html
index 75f032e..253034b 100644
--- a/logback-site/src/site/pages/bugreport.html
+++ b/logback-site/src/site/pages/bugreport.html
@@ -15,10 +15,6 @@
<div id="left">
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script type="text/javascript" src="templates/right.js" ></script>
- </div>
-x
<div id="content">
diff --git a/logback-site/src/site/pages/cla.txt b/logback-site/src/site/pages/cla.txt
index ed13608..cce3714 100644
--- a/logback-site/src/site/pages/cla.txt
+++ b/logback-site/src/site/pages/cla.txt
@@ -1,23 +1,21 @@
- QOS.CH Sarl
+ QOS.ch
Individual Contributor License Agreement ("Agreement")
This agreement is an adaptation of the Apache Software Foundation ICL
-agreement where references to ASF have been replaced by QOS.CH. We
-thank the ASF for allowing QOS.CH Sarl to make use of their ICL
-agreement.
-
-Thank you for your interest in QOS.CH Sarl, hereafter referred to as
-just QOS.CH. In order to clarify the intellectual property license
-granted with Contributions from any person or entity, QOS.CH must have
-a Contributor License Agreement ("CLA") on file that has been signed
-by each Contributor, indicating agreement to the license terms
-below. This license is for your protection as a Contributor as well as
-the protection of QOS.CH and its users; it does not change your rights
-to use your own Contributions for any other purpose. If you have not
-already done so, please complete and send an original signed Agreement
-to QOS.CH, rue de la Ria 8B, 1462 Yvonand, Switzerland. Please read
-this document carefully before signing and keep a copy for your
-records.
+agreement where references to ASF have been replaced by QOS.ch. We
+thank the ASF for allowing QOS.ch to make use of their ICL agreement.
+
+Thank you for your interest in QOS.ch. In order to clarify the
+intellectual property license granted with Contributions from any
+person or entity, QOS.ch must have a Contributor License Agreement
+("CLA") on file that has been signed by each Contributor, indicating
+agreement to the license terms below. This license is for your
+protection as a Contributor as well as the protection of QOS.ch and
+its users; it does not change your rights to use your own
+Contributions for any other purpose. If you have not already done so,
+please complete and send an original signed Agreement to QOS.ch, rue
+Enning 4, 1003 Lausanne, Switzerland. Please read this document
+carefully before signing and keep a copy for your records.
Full name: ____________________________ E-Mail: ___________________
@@ -29,17 +27,17 @@ records.
You accept and agree to the following terms and conditions for Your
-present and future Contributions submitted QOS.CH. In return, QOS.CH
+present and future Contributions submitted QOS.ch. In return, QOS.ch
shall not use Your Contributions in a way that is contrary to the
-public benefit. Except for the license granted herein to QOS.CH and
-recipients of software distributed by QOS.CH, You reserve all right,
+public benefit. Except for the license granted herein to QOS.ch and
+recipients of software distributed by QOS.ch, You reserve all right,
title, and interest in and to Your Contributions.
1. Definitions.
"You" (or "Your") shall mean the copyright owner or legal entity
authorized by the copyright owner that is making this Agreement
- with QOS.CH. For legal entities, the entity making a Contribution
+ with QOS.ch. For legal entities, the entity making a Contribution
and all other entities that control, are controlled by, or are
under common control with that entity are considered to be a single
Contributor. For the purposes of this definition, "control" means
@@ -50,28 +48,28 @@ title, and interest in and to Your Contributions.
"Contribution" shall mean any original work of authorship,
including any modifications or additions to an existing work, that
- is intentionally submitted by You to QOS.CH for inclusion in, or
- documentation of, any of the products owned or managed by QOS.CH
+ is intentionally submitted by You to QOS.ch for inclusion in, or
+ documentation of, any of the products owned or managed by QOS.ch
(the "Work"). For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
- to QOS.CH or its representatives, including but not limited to
+ to QOS.ch or its representatives, including but not limited to
communication on electronic mailing lists, source code control
systems, and issue tracking systems that are managed by, or on
- behalf of, QOS.CH for the purpose of discussing and improving the
+ behalf of, QOS.ch for the purpose of discussing and improving the
Work, but excluding communication that is conspicuously marked or
otherwise designated in writing by You as "Not a Contribution."
2. Grant of Copyright License. Subject to the terms and conditions of
- this Agreement, You hereby grant to QOS.CH and to recipients of
- software distributed by QOS.CH a perpetual, worldwide,
+ this Agreement, You hereby grant to QOS.ch and to recipients of
+ software distributed by QOS.ch a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable copyright
license to reproduce, prepare derivative works of, publicly
display, publicly perform, sublicense, and distribute Your
Contributions and such derivative works.
3. Grant of Patent License. Subject to the terms and conditions of
- this Agreement, You hereby grant to QOS.CH and to recipients of
- software distributed by QOS.CH a perpetual, worldwide,
+ this Agreement, You hereby grant to QOS.ch and to recipients of
+ software distributed by QOS.ch a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable (except as
stated in this section) patent license to make, have made, use,
offer to sell, sell, import, and otherwise transfer the Work, where
@@ -91,7 +89,7 @@ title, and interest in and to Your Contributions.
that you create that includes your Contributions, you represent
that you have received permission to make Contributions on behalf
of that employer, that your employer has waived such rights for
- your Contributions to QOS.CH.
+ your Contributions to QOS.ch.
5. You represent that each of Your Contributions is Your original
creation (see section 7 for submissions on behalf of others). You
@@ -111,14 +109,14 @@ title, and interest in and to Your Contributions.
INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
7. Should You wish to submit work that is not Your original creation,
- You may submit it to QOS.CH separately from any Contribution,
+ You may submit it to QOS.ch separately from any Contribution,
identifying the complete details of its source and of any license
or other restriction (including, but not limited to, related
patents, trademarks, and license agreements) of which you are
personally aware, and conspicuously marking the work as "Submitted
on behalf of a third-party: [named here]".
-8. You agree to notify QOS.CH of any facts or circumstances of which
+8. You agree to notify QOS.ch of any facts or circumstances of which
you become aware that would make these representations inaccurate
in any respect.
diff --git a/logback-site/src/site/pages/codes.html b/logback-site/src/site/pages/codes.html
index eee7f2a..36d0468 100644
--- a/logback-site/src/site/pages/codes.html
+++ b/logback-site/src/site/pages/codes.html
@@ -31,10 +31,6 @@
<div id="left">
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script type="text/javascript" src="templates/right.js" ></script>
- </div>
-
<div id="content">
<h2><a name="top">Logback error messages and their meanings</a></h2>
@@ -287,21 +283,7 @@
<code>RollingPolicy</code> at the same time.
</p>
- <!-- ============================================================= -->
-
- <h3 class="doAnchor" name="#sat_missing_integer_token">Missing
- integer token, that is %i, in FileNamePattern [...].
-
- </h3>
- <p>The %i conversion token is mandatory for <a
- href="manual/appenders.html#SizeAndTimeBasedFNATP">size and time
- based archiving</a>. In case the %i token is missing,
- <code>SizeAndTimeBasedFNATP</code> attached to
- <code>RollingFileAppender</code> will detect the omission and will
- not start.
- </p>
-
<!-- ============================================================= -->
@@ -398,52 +380,7 @@
<code>RollingFileAppender</code> will emit an error message and
refuse to start.</p>
- <!-- ============================================================= -->
-
- <h3 class="doAnchor" name="rfa_collision_in_dateFormat">The date
- format in <span class="option">fileNamePattern</span> will result in
- collisions in the names of archived log files.
- </h3>
-
- <p>This error message is output when the date time pattern in the %d
- token within the <span class="option">fileNamePattern</span> is not
- collision free. For example, the following
- code>fileNamePattern</code> will result in the same log archive
- every day of the week after the first week of the month.
- </p>
-
- <pre class="source">myapp-%d{yyyy-MM-<span class="bold red">uu</span>}.log.zip</pre>
-
- <p>As such collisions will result in log data loss,
- <code>RollingFileAppender</code> will check for a variety of such
- possible collisions and will not start if any collisions are
- detected.</p>
-
- <!-- ============================================================= -->
-
- <h3 class="doAnchor" name="earlier_fa_collision"><span
- class="option">File</span>/<span
- class="option">FileNamePattern</span> option has the same value "..." as
- that given for appender [...] defined earlier.
- </h3>
-
-
- <p>If a <code>FileAppender</code>/<code>RollingFileAppender</code>
- defined earlier has the same <span class="option">File</span> option
- as the current appender, then those two appenders are in collision
- as <code>FileAppender</code> instances cannot share the same output
- target. To prevent loss of data, the current appender will not
- start. Make sure that each appender has a unique <span
- class="option">File</span> option.
- </p>
-
- <p>By analogy the same restriction applies to the <span
- class="option">FileNamePattern</span> option of
- RollingFileAppender. Make sure that each RollingFileAppender has a
- unique <span class="option">FileNamePattern</span> option</p>
-
- <!-- =============================================================
- -->
+ <!-- ============================================================= -->
<h3 class="doAnchor" name="renamingError">Failed to rename file [x]
as [y].</h3>
@@ -473,22 +410,18 @@
permission which is different than the permission to "write" to the
file.</p>
- <p class="highlight">File rename operations during rollover can be
- avoided altogether by omitting the <span class="option">file</span>
- property in RollingFileAppender.</p>
<p>In practice, it can be hard to set the right permissions or to
- ensure that there are no file handle references to log files.</p>
-
- <p>Under many circumstances, it can be more robust to avoid file
- renaming during rollover altogether. This is as easy as omitting the
- <span class="option">file</span> property in
- <code>RollingFileAppender</code>, as shown in the next configuration
- snippet.
+ ensure that there are no file handle references to log files. Under
+ such circumstances, it can be easier to avoid file renaming
+ altogether. File renaming can be avoided by omitting the <span
+ class="option">file</span> property in
+ <code>TimeBasedRollingPolicy</code>, as shown in the next
+ configuration snippet.
</p>
<pre class="prettyprint source"><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <b><!-- <span class="option">file</span> property left unset/blank --></b>
+ <!-- <span class="option">file</span> property left unset/blank -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>mylog.%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
@@ -507,8 +440,8 @@
<p>On the Unix platform, the basic/quick rename method supplied by
the JDK does not work if the source and target files are located on
different file systems. In order to deal with this contingency,
- logback will resort to renaming by copying if all of the following
- three conditions are met:</p>
+ logback will resort to renaming by copying if all following three
+ conditions are met:</p>
<ol>
<li>quick renaming fails, </li>
@@ -522,10 +455,6 @@
<p>The code for determining the file system of a file requires Java
7. No rename by copying will be performed on Java 6 or earlier.</p>
- <p>As explained in the Windows section above, renaming can be
- avoided altogether by omitting the <span class="option">file</span>
- property.
- </p>
<!-- ============================================================= -->
<h3 class="doAnchor" name="fwrp_parentFileName_not_set">The <span
@@ -714,7 +643,47 @@ return false;</pre>
</configuration>
</pre>
-
+ <!-- =========================================================== -->
+
+ <h3 class="doAnchor" name="remote_no_host">No remote host or address
+ is set for <code>SocketRemote</code>
+
+ </h3>
+
+ <p>A remote host or address is mandatory for SocketRemote. </p>
+ <p>You can specify the remote host in the configuration file
+ as follows.
+ </p>
+
+ <pre class="prettyprint source"><remote class="ch.qos.logback.classic.net.SocketRemote">
+ ...
+ <host>127.0.0.1</host>
+ ...
+</remote></pre>
+
+
+
+
+ <!-- ============================================================= -->
+
+ <h3 class="doAnchor" name="socket_no_port">No remote port is set for
+ <code>SocketRemote</code>
+ </h3>
+
+ <p>A remote port is mandatory for SocketRemote.</p>
+
+ <p>You can specify the remote port in the configuration file
+ like this:
+ </p>
+
+ <pre class="prettyprint source"><remote class="ch.qos.logback.classic.net.SocketRemote">
+ ...
+ <port>4560</port>
+ ...
+</remote></pre>
+
+
+
<script src="templates/footer.js" type="text/javascript"></script>
</div>
</body>
diff --git a/logback-site/src/site/pages/css/screen.css b/logback-site/src/site/pages/css/screen.css
index f4c2b61..3b996d5 100644
--- a/logback-site/src/site/pages/css/screen.css
+++ b/logback-site/src/site/pages/css/screen.css
@@ -37,6 +37,22 @@ p.menu {
font-size: smaller;
}
+
+#leftOld {
+ position: absolute;
+ font-size: 80%;
+ left: 0px;
+ width: 15em;
+ color: #564b47;
+ margin: 4px 0px 0px 4px;
+ padding: 0px;
+ border: 1px solid #cccccc;
+ background-color: #fff8e8;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+
#left {
position: absolute;
left: 0px;
@@ -59,6 +75,7 @@ p.menu {
#left a, #right a {
display: block;
+ width: 95.5%;
margin: 0px;
padding: 2px;
border: solid 1px #fff8e8;
@@ -83,18 +100,6 @@ p.menu_header {
-moz-border-radius: 3px;
border-radius: 3px;
}
-.pub {
- text-align: center;
-}
-
-#left .pub a:hover {
- background-color: transparent;
- border: solid 0px #FFFFFF;
-}
-
-#left img {
- border: none;
-}
#left div.jobadd {
font-size: 140%;
@@ -135,6 +140,13 @@ p.menu_header {
font-size: 80%;
}
+#left img {
+ display: block;
+ margin: 20px 0 20px 17px;
+ border: none;
+ width: 90px;
+ height: 30px;
+}
#headerLine {
background-color:#FFD0A0;
diff --git a/logback-site/src/site/pages/demo.html b/logback-site/src/site/pages/demo.html
index 2617059..8f88992 100644
--- a/logback-site/src/site/pages/demo.html
+++ b/logback-site/src/site/pages/demo.html
@@ -16,10 +16,6 @@
<div id="left">
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="templates/right.js" type="text/javascript"></script>
- </div>
-
<div id="content">
diff --git a/logback-site/src/site/pages/dependencies.html b/logback-site/src/site/pages/dependencies.html
index 1552b8d..8080b87 100644
--- a/logback-site/src/site/pages/dependencies.html
+++ b/logback-site/src/site/pages/dependencies.html
@@ -17,16 +17,14 @@
<div id="left">
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script type="text/javascript" src="templates/right.js" ></script>
- </div>
-
<div id="content">
<h1>Dependencies per module</h1>
- <p>As of version 1.1.3, logback requires JDK 1.6.</p>
+ <p>As of version 1.0.12, logback requires JDK 1.6 to build,
+ however, it is inteded to run under JDK 1.5 (with the exception of
+ SSL related functionality).</p>
<p>Each logback module has a different set of dependencies. These
are listed below in a separate table per module.</p>
@@ -41,6 +39,11 @@
<tr>
<td>Overall</td>
+ <td><ul><li>JDK 1.5</li></ul></td>
+ </tr>
+
+ <tr>
+ <td>ch.qos.logback.core.net.ssl.*</td>
<td><ul><li>JDK 1.6</li></ul></td>
</tr>
@@ -83,7 +86,7 @@
<td>Overall</td>
<td>
<ul>
- <li>JDK 1.6
+ <li>JDK 1.5
</li>
</ul>
</td>
@@ -105,7 +108,7 @@
<td>
<ul>
<li><a href="http://www.slf4j.org">slf4j-api</a> version
- <span class="big red">1.7.15 or later</span>
+ ${slf4j.version}
</li>
</ul>
</td>
diff --git a/logback-site/src/site/pages/documentation.html b/logback-site/src/site/pages/documentation.html
index 21a191d..fbc7857 100644
--- a/logback-site/src/site/pages/documentation.html
+++ b/logback-site/src/site/pages/documentation.html
@@ -17,9 +17,6 @@
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script type="text/javascript" src="templates/right.js" ></script>
- </div>
<div id="content">
@@ -29,9 +26,7 @@
available.</p>
<ul>
- <li><a href="manual/index.html"><b>The logback manual</b></a><ul>
- <li><a href="manual/index_ja.html">和訳 (Japanese translation)</a></li>
- </ul></li>
+ <li><a href="manual/index.html"><b>The logback manual</b></a></li>
<li><a href="reasonsToSwitch.html">Reasons to switch to logback
from log4j</a></li>
diff --git a/logback-site/src/site/pages/download.html b/logback-site/src/site/pages/download.html
index 0286b04..fad3d4f 100644
--- a/logback-site/src/site/pages/download.html
+++ b/logback-site/src/site/pages/download.html
@@ -10,17 +10,18 @@
<link rel="stylesheet" type="text/css" href="css/_print.css" media="print" />
<link rel="stylesheet" type="text/css" href="css/popup.css" media="screen" />
</head>
- <body>
- <script type="text/javascript">prefix='';</script>
- <script type="text/javascript" src="templates/header.js" ></script>
- <script type="text/javascript" src="js/jquery-min.js"></script>
+ <body onload="centerPopup(); loadPopup();">
+ <script type="text/javascript">prefix='';</script>
+
+ <script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js" ></script>
+ <script type="text/javascript" src="js/jquery.cookies.2.2.0.js"></script>
+ <script type="text/javascript" src="js/popup.js" ></script>
+
+ <script src="templates/header.js" type="text/javascript"></script>
<div id="left">
<noscript>Please turn on Javascript to view this menu</noscript>
- <script type="text/javascript" src="templates/left.js" ></script>
- </div>
- <div id="right">
- <script type="text/javascript" src="templates/right.js" ></script>
+ <script src="templates/left.js" type="text/javascript"></script>
</div>
<div id="popupContents">
@@ -90,10 +91,9 @@
</dt>
<dd>
- Lilith is a Logging- and AccessEvent viewer for logback.
+ <p>Lilith is a Logging- and AccessEvent viewer for logback.</p>
</dd>
- <br/>
<!-- ============================================================ -->
<dt>
<a
@@ -102,13 +102,11 @@
</dt>
<dd>
- Consists of several akka-based logback utilities, including
+ <p>Consists of several akka-based logback utilities, including
ActorAppender, HoptoadActorAppender and Logstash redis
appender.
-
+ </p>
</dd>
-
- <br/>
<!-- ============================================================ -->
<dt>
@@ -118,10 +116,11 @@
</dt>
<dd>
- Logback-Android brings the power of Logback to Android.
+ <p>Logback-Android brings the power of Logback to Android.
+ </p>
</dd>
- <br/>
+
<!-- ============================================================ -->
<dt>
<a
@@ -130,42 +129,24 @@
</dt>
<dd>
- Logback Appender writing to Amazon SimpleDB. See also <a
+ <p>Logback Appender writing to Amazon SimpleDB. See also <a
href="http://www.peecho.com/blog/logging-the-cloud-with-simpledb.html">Logging
- the cloud with SimpleDB</a>.
+ the cloud with SimpleDB</a>.</p>
</dd>
- <br/>
<!-- ============================================================ -->
<dt>
- <a
- href="https://github.com/carlspring/logback-configuration/">logback-configuration</a>
- by Martin Todorov
- </dt>
-
- <dd>
- A service layer (using Spring) and a REST interface which
- provides methods to: add or update loggers, resolve a log
- file, resolve the logback configuration file, and upload a
- logback configuration file and reload it.
-
- </dd>
-
- <br/>
- <!-- ============================================================ -->
- <!--
- <dt>
<a href="http://perf4j.codehaus.org/">Perf4J</a> by Alex
Devine, Doran Chakraborty et al.
</dt>
<dd>
- Perf4J is a set of utilities for calculating and displaying
- performance statistics for Java code.
+ <p>Perf4J is a set of utilities for calculating and displaying
+ performance statistics for Java code.</p>
</dd>
- -->
-
+
+
<!-- ============================================================ -->
<dt>
<a
@@ -177,18 +158,7 @@
href="http://graylog2.org/">Graylog2</a> server via GELF
messages.
</dd>
- <br/>
- <!-- ============================================================ -->
- <dt>
- <a
- href="https://github.com/sbabcoc/logback-testng">Logback-testng</a>
- by Scott Babcock
- </dt>
-
- <dd>Logback appender for TestNG Reporter. </dd>
-
- <!-- ============================================================ -->
-
+
</dl>
<p/>
diff --git a/logback-site/src/site/pages/faq.html b/logback-site/src/site/pages/faq.html
index 9a7f452..e4cfe1f 100644
--- a/logback-site/src/site/pages/faq.html
+++ b/logback-site/src/site/pages/faq.html
@@ -17,10 +17,6 @@
<div id="left">
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="templates/right.js" type="text/javascript"></script>
- </div>
-
<div id="content">
<h2>
diff --git a/logback-site/src/site/pages/index.html b/logback-site/src/site/pages/index.html
index 68fc4b7..5655b81 100644
--- a/logback-site/src/site/pages/index.html
+++ b/logback-site/src/site/pages/index.html
@@ -17,10 +17,6 @@
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="templates/right.js" type="text/javascript"></script>
- </div>
-
<div id="content">
<h2>Logback Project</h2>
@@ -83,7 +79,6 @@
<li><a href="http://syncope.apache.org/">Apache Syncope</a></li>
<li><a href="http://myfaces.apache.org/tobago/">Apache Tobago</a></li>
<li><a href="http://www.jfrog.org/products.php">Artifactory</a></li>
- <li><a href="https://github.com/nhl/bootique">Bootique</a></li>
<li><a href="http://cia.sourceforge.net/">Citizen Intelligence Agency</a></li>
<li><a href="http://www.dcache.org/">dCache</a></li>
</ul>
@@ -114,7 +109,6 @@
<td valign="top">
<ul>
<li><a href="http://www.playframework.org/">Play Framework</a></li>
- <li><a href="https://github.com/psi-probe/psi-probe/">PSI probe</a></li>
<li><a href="http://www.red5.org">Red5</a></li>
<li><a href="http://scalate.fusesource.org/">Scalate</a></li>
<li><a href="http://www.scalatra.org/2.0/book/">Scalatra</a></li>
diff --git a/logback-site/src/site/pages/js/dsl.js b/logback-site/src/site/pages/js/dsl.js
index 92faee2..d564dc4 100644
--- a/logback-site/src/site/pages/js/dsl.js
+++ b/logback-site/src/site/pages/js/dsl.js
@@ -15,7 +15,7 @@ function asGroovy(id) {
inner = inner.replace(/</gi, '<');
inner = inner.replace(/>/gi, '>');
- inner = inner.replace(/<span class="[^"]*"?>/gi, '');
+ inner = inner.replace(/<span class="?\w{3,5}"?>/gi, '');
inner = inner.replace(/<\/span>/gi, '');
inner = inner.replace(/<br>/gi, '');
inner = inner.replace(/ /gi, '');
diff --git a/logback-site/src/site/pages/js/jquery.cookies.2.2.0.js b/logback-site/src/site/pages/js/jquery.cookies.2.2.0.js
new file mode 100644
index 0000000..6b7183a
--- /dev/null
+++ b/logback-site/src/site/pages/js/jquery.cookies.2.2.0.js
@@ -0,0 +1,450 @@
+/**
+ * Copyright (c) 2005 - 2010, James Auldridge
+ * All rights reserved.
+ *
+ * Licensed under the BSD, MIT, and GPL (your choice!) Licenses:
+ * http://code.google.com/p/cookies/wiki/License
+ *
+ */
+var jaaulde = window.jaaulde || {};
+jaaulde.utils = jaaulde.utils || {};
+jaaulde.utils.cookies = ( function()
+{
+ var resolveOptions, assembleOptionsString, parseCookies, constructor, defaultOptions = {
+ expiresAt: null,
+ path: '/',
+ domain: null,
+ secure: false
+ };
+ /**
+ * resolveOptions - receive an options object and ensure all options are present and valid, replacing with defaults where necessary
+ *
+ * @access private
+ * @static
+ * @parameter Object options - optional options to start with
+ * @return Object complete and valid options object
+ */
+ resolveOptions = function( options )
+ {
+ var returnValue, expireDate;
+
+ if( typeof options !== 'object' || options === null )
+ {
+ returnValue = defaultOptions;
+ }
+ else
+ {
+ returnValue = {
+ expiresAt: defaultOptions.expiresAt,
+ path: defaultOptions.path,
+ domain: defaultOptions.domain,
+ secure: defaultOptions.secure
+ };
+
+ if( typeof options.expiresAt === 'object' && options.expiresAt instanceof Date )
+ {
+ returnValue.expiresAt = options.expiresAt;
+ }
+ else if( typeof options.hoursToLive === 'number' && options.hoursToLive !== 0 )
+ {
+ expireDate = new Date();
+ expireDate.setTime( expireDate.getTime() + ( options.hoursToLive * 60 * 60 * 1000 ) );
+ returnValue.expiresAt = expireDate;
+ }
+
+ if( typeof options.path === 'string' && options.path !== '' )
+ {
+ returnValue.path = options.path;
+ }
+
+ if( typeof options.domain === 'string' && options.domain !== '' )
+ {
+ returnValue.domain = options.domain;
+ }
+
+ if( options.secure === true )
+ {
+ returnValue.secure = options.secure;
+ }
+ }
+
+ return returnValue;
+ };
+ /**
+ * assembleOptionsString - analyze options and assemble appropriate string for setting a cookie with those options
+ *
+ * @access private
+ * @static
+ * @parameter options OBJECT - optional options to start with
+ * @return STRING - complete and valid cookie setting options
+ */
+ assembleOptionsString = function( options )
+ {
+ options = resolveOptions( options );
+
+ return (
+ ( typeof options.expiresAt === 'object' && options.expiresAt instanceof Date ? '; expires=' + options.expiresAt.toGMTString() : '' ) +
+ '; path=' + options.path +
+ ( typeof options.domain === 'string' ? '; domain=' + options.domain : '' ) +
+ ( options.secure === true ? '; secure' : '' )
+ );
+ };
+ /**
+ * parseCookies - retrieve document.cookie string and break it into a hash with values decoded and unserialized
+ *
+ * @access private
+ * @static
+ * @return OBJECT - hash of cookies from document.cookie
+ */
+ parseCookies = function()
+ {
+ var cookies = {}, i, pair, name, value, separated = document.cookie.split( ';' ), unparsedValue;
+ for( i = 0; i < separated.length; i = i + 1 )
+ {
+ pair = separated[i].split( '=' );
+ name = pair[0].replace( /^\s*/, '' ).replace( /\s*$/, '' );
+
+ try
+ {
+ value = decodeURIComponent( pair[1] );
+ }
+ catch( e1 )
+ {
+ value = pair[1];
+ }
+
+ if( typeof JSON === 'object' && JSON !== null && typeof JSON.parse === 'function' )
+ {
+ try
+ {
+ unparsedValue = value;
+ value = JSON.parse( value );
+ }
+ catch( e2 )
+ {
+ value = unparsedValue;
+ }
+ }
+
+ cookies[name] = value;
+ }
+ return cookies;
+ };
+
+ constructor = function(){};
+
+ /**
+ * get - get one, several, or all cookies
+ *
+ * @access public
+ * @paramater Mixed cookieName - String:name of single cookie; Array:list of multiple cookie names; Void (no param):if you want all cookies
+ * @return Mixed - Value of cookie as set; Null:if only one cookie is requested and is not found; Object:hash of multiple or all cookies (if multiple or all requested);
+ */
+ constructor.prototype.get = function( cookieName )
+ {
+ var returnValue, item, cookies = parseCookies();
+
+ if( typeof cookieName === 'string' )
+ {
+ returnValue = ( typeof cookies[cookieName] !== 'undefined' ) ? cookies[cookieName] : null;
+ }
+ else if( typeof cookieName === 'object' && cookieName !== null )
+ {
+ returnValue = {};
+ for( item in cookieName )
+ {
+ if( typeof cookies[cookieName[item]] !== 'undefined' )
+ {
+ returnValue[cookieName[item]] = cookies[cookieName[item]];
+ }
+ else
+ {
+ returnValue[cookieName[item]] = null;
+ }
+ }
+ }
+ else
+ {
+ returnValue = cookies;
+ }
+
+ return returnValue;
+ };
+ /**
+ * filter - get array of cookies whose names match the provided RegExp
+ *
+ * @access public
+ * @paramater Object RegExp - The regular expression to match against cookie names
+ * @return Mixed - Object:hash of cookies whose names match the RegExp
+ */
+ constructor.prototype.filter = function( cookieNameRegExp )
+ {
+ var cookieName, returnValue = {}, cookies = parseCookies();
+
+ if( typeof cookieNameRegExp === 'string' )
+ {
+ cookieNameRegExp = new RegExp( cookieNameRegExp );
+ }
+
+ for( cookieName in cookies )
+ {
+ if( cookieName.match( cookieNameRegExp ) )
+ {
+ returnValue[cookieName] = cookies[cookieName];
+ }
+ }
+
+ return returnValue;
+ };
+ /**
+ * set - set or delete a cookie with desired options
+ *
+ * @access public
+ * @paramater String cookieName - name of cookie to set
+ * @paramater Mixed value - Any JS value. If not a string, will be JSON encoded; NULL to delete
+ * @paramater Object options - optional list of cookie options to specify
+ * @return void
+ */
+ constructor.prototype.set = function( cookieName, value, options )
+ {
+ if( typeof options !== 'object' || options === null )
+ {
+ options = {};
+ }
+
+ if( typeof value === 'undefined' || value === null )
+ {
+ value = '';
+ options.hoursToLive = -8760;
+ }
+
+ else if( typeof value !== 'string' )
+ {
+ if( typeof JSON === 'object' && JSON !== null && typeof JSON.stringify === 'function' )
+ {
+ value = JSON.stringify( value );
+ }
+ else
+ {
+ throw new Error( 'cookies.set() received non-string value and could not serialize.' );
+ }
+ }
+
+
+ var optionsString = assembleOptionsString( options );
+
+ document.cookie = cookieName + '=' + encodeURIComponent( value ) + optionsString;
+ };
+ /**
+ * del - delete a cookie (domain and path options must match those with which the cookie was set; this is really an alias for set() with parameters simplified for this use)
+ *
+ * @access public
+ * @paramater MIxed cookieName - String name of cookie to delete, or Bool true to delete all
+ * @paramater Object options - optional list of cookie options to specify ( path, domain )
+ * @return void
+ */
+ constructor.prototype.del = function( cookieName, options )
+ {
+ var allCookies = {}, name;
+
+ if( typeof options !== 'object' || options === null )
+ {
+ options = {};
+ }
+
+ if( typeof cookieName === 'boolean' && cookieName === true )
+ {
+ allCookies = this.get();
+ }
+ else if( typeof cookieName === 'string' )
+ {
+ allCookies[cookieName] = true;
+ }
+
+ for( name in allCookies )
+ {
+ if( typeof name === 'string' && name !== '' )
+ {
+ this.set( name, null, options );
+ }
+ }
+ };
+ /**
+ * test - test whether the browser is accepting cookies
+ *
+ * @access public
+ * @return Boolean
+ */
+ constructor.prototype.test = function()
+ {
+ var returnValue = false, testName = 'cT', testValue = 'data';
+
+ this.set( testName, testValue );
+
+ if( this.get( testName ) === testValue )
+ {
+ this.del( testName );
+ returnValue = true;
+ }
+
+ return returnValue;
+ };
+ /**
+ * setOptions - set default options for calls to cookie methods
+ *
+ * @access public
+ * @param Object options - list of cookie options to specify
+ * @return void
+ */
+ constructor.prototype.setOptions = function( options )
+ {
+ if( typeof options !== 'object' )
+ {
+ options = null;
+ }
+
+ defaultOptions = resolveOptions( options );
+ };
+
+ return new constructor();
+} )();
+
+( function()
+{
+ if( window.jQuery )
+ {
+ ( function( $ )
+ {
+ $.cookies = jaaulde.utils.cookies;
+
+ var extensions = {
+ /**
+ * $( 'selector' ).cookify - set the value of an input field, or the innerHTML of an element, to a cookie by the name or id of the field or element
+ * (field or element MUST have name or id attribute)
+ *
+ * @access public
+ * @param options OBJECT - list of cookie options to specify
+ * @return jQuery
+ */
+ cookify: function( options )
+ {
+ return this.each( function()
+ {
+ var i, nameAttrs = ['name', 'id'], name, $this = $( this ), value;
+
+ for( i in nameAttrs )
+ {
+ if( ! isNaN( i ) )
+ {
+ name = $this.attr( nameAttrs[ i ] );
+ if( typeof name === 'string' && name !== '' )
+ {
+ if( $this.is( ':checkbox, :radio' ) )
+ {
+ if( $this.attr( 'checked' ) )
+ {
+ value = $this.val();
+ }
+ }
+ else if( $this.is( ':input' ) )
+ {
+ value = $this.val();
+ }
+ else
+ {
+ value = $this.html();
+ }
+
+ if( typeof value !== 'string' || value === '' )
+ {
+ value = null;
+ }
+
+ $.cookies.set( name, value, options );
+
+ break;
+ }
+ }
+ }
+ } );
+ },
+ /**
+ * $( 'selector' ).cookieFill - set the value of an input field or the innerHTML of an element from a cookie by the name or id of the field or element
+ *
+ * @access public
+ * @return jQuery
+ */
+ cookieFill: function()
+ {
+ return this.each( function()
+ {
+ var n, getN, nameAttrs = ['name', 'id'], name, $this = $( this ), value;
+
+ getN = function()
+ {
+ n = nameAttrs.pop();
+ return !! n;
+ };
+
+ while( getN() )
+ {
+ name = $this.attr( n );
+ if( typeof name === 'string' && name !== '' )
+ {
+ value = $.cookies.get( name );
+ if( value !== null )
+ {
+ if( $this.is( ':checkbox, :radio' ) )
+ {
+ if( $this.val() === value )
+ {
+ $this.attr( 'checked', 'checked' );
+ }
+ else
+ {
+ $this.removeAttr( 'checked' );
+ }
+ }
+ else if( $this.is( ':input' ) )
+ {
+ $this.val( value );
+ }
+ else
+ {
+ $this.html( value );
+ }
+ }
+
+ break;
+ }
+ }
+ } );
+ },
+ /**
+ * $( 'selector' ).cookieBind - call cookie fill on matching elements, and bind their change events to cookify()
+ *
+ * @access public
+ * @param options OBJECT - list of cookie options to specify
+ * @return jQuery
+ */
+ cookieBind: function( options )
+ {
+ return this.each( function()
+ {
+ var $this = $( this );
+ $this.cookieFill().change( function()
+ {
+ $this.cookify( options );
+ } );
+ } );
+ }
+ };
+
+ $.each( extensions, function( i )
+ {
+ $.fn[i] = this;
+ } );
+
+ } )( window.jQuery );
+ }
+} )();
\ No newline at end of file
diff --git a/logback-site/src/site/pages/js/popup.js b/logback-site/src/site/pages/js/popup.js
new file mode 100644
index 0000000..4c70b2f
--- /dev/null
+++ b/logback-site/src/site/pages/js/popup.js
@@ -0,0 +1,102 @@
+/***************************/
+//@Author: Adrian "yEnS" Mato Gondelle
+//@website: www.yensdesign.com
+//@email: yensamg at gmail.com
+//@license: Feel free to use it, but keep this credits please!
+/***************************/
+
+//SETTING UP OUR POPUP
+//0 means disabled; 1 means enabled;
+var popupStatus = 0;
+
+//loading popup with jQuery magic!
+function loadPopup() {
+ var surveyCookie = $.cookies.get("SURVEY");
+ if(surveyCookie) {
+ popupStatus = 0;
+ return;
+ }
+ //loads popup only if it is disabled
+ if(popupStatus==0){
+ $("#backgroundPopup").css({
+ "opacity": "0.7"
+ });
+ $("#backgroundPopup").fadeIn("slow");
+ $("#popupContents").fadeIn("slow");
+ popupStatus = 1;
+ }
+}
+
+function getDateInSixMonths() {
+ var date = new Date();
+ date.setDate(date.getDate()+180);
+ return date;
+}
+
+//disabling popup with jQuery magic!
+function disablePopup(){
+ //disables popup only if it is enabled
+ if(popupStatus==1){
+ $("#backgroundPopup").fadeOut("slow");
+ $("#popupContents").fadeOut("slow");
+ popupStatus = 0;
+ $.cookies.set("SURVEY", "NO", {expiresAt: getDateInSixMonths()});
+ }
+}
+
+//centering popup
+function centerPopup(){
+ //request data for centering
+ var windowWidth = document.documentElement.clientWidth;
+ var windowHeight = document.documentElement.clientHeight;
+ var popupHeight = $("#popupContents").height();
+ var popupWidth = $("#popupContents").width();
+ //centering
+ $("#popupContents").css({
+ "position": "absolute",
+ "top": windowHeight/2-popupHeight/2,
+ "left": windowWidth/2-popupWidth/2
+ });
+ //only need force for IE6
+
+ $("#backgroundPopup").css({
+ "height": windowHeight
+ });
+
+}
+
+
+//CONTROLLING EVENTS IN jQuery
+$(document).ready(function(){
+
+ //LOADING POPUP
+ //Click the button event!
+ $("#button").click(function(){
+ //centering with css
+ centerPopup();
+ //load popup
+ loadPopup();
+ });
+
+ //CLOSING POPUP
+ //Click the x event!
+ $("#popupContentsClose").click(function(){
+ disablePopup();
+ });
+ //Click out event!
+ $("#backgroundPopup").click(function(){
+ //disablePopup();
+ });
+ //Press Escape event!
+ $(document).keypress(function(e){
+ if(e.keyCode==27 && popupStatus==1){
+ disablePopup();
+ }
+ });
+
+ $("#announce").click(function(){
+ $.cookies.set("SURVEY", "YES", {expiresAt: getDateInSixMonths()});
+ window.location='http://www.qos.ch/mailman/listinfo/announce';
+ });
+});
+
diff --git a/logback-site/src/site/pages/license.html b/logback-site/src/site/pages/license.html
index dfc4fa2..e9c4a32 100644
--- a/logback-site/src/site/pages/license.html
+++ b/logback-site/src/site/pages/license.html
@@ -17,10 +17,6 @@
<div id="left">
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script type="text/javascript" src="templates/right.js" ></script>
- </div>
-
<div id="content">
<div class="section">
@@ -33,7 +29,7 @@
formally:</p>
<p class="source">Logback: the reliable, generic, fast and flexible logging framework.
-Copyright (C) 1999-2017, QOS.ch. All rights reserved.
+Copyright (C) 1999-2012, QOS.ch. All rights reserved.
This program and the accompanying materials are dual-licensed under
either the terms of the <a href="http://www.eclipse.org/legal/epl-v10.html">Eclipse Public License v1.0</a> as published by
diff --git a/logback-site/src/site/pages/mailinglist.html b/logback-site/src/site/pages/mailinglist.html
index 92b7477..cb55a46 100644
--- a/logback-site/src/site/pages/mailinglist.html
+++ b/logback-site/src/site/pages/mailinglist.html
@@ -18,10 +18,6 @@
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script type="text/javascript" src="templates/right.js" ></script>
- </div>
-
<div id="content">
<h2>Project Mailing Lists</h2>
diff --git a/logback-site/src/site/pages/manual/appenders.html b/logback-site/src/site/pages/manual/appenders.html
index 117d4a9..b37d3dd 100644
--- a/logback-site/src/site/pages/manual/appenders.html
+++ b/logback-site/src/site/pages/manual/appenders.html
@@ -28,9 +28,6 @@
<h1>Chapter 4: Appenders</h1>
- <a href="appenders_ja.html">和訳 (Japanese translation)</a>
-
-
<div class="quote">
<p><em>There is so much to tell about the Western country in
@@ -351,7 +348,7 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
<p class="example">Example: ConsoleAppender configuration
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-Console.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback_Console');">View as .groovy</span>
@@ -520,7 +517,7 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
</p>
<p class="example">Example: FileAppender configuration
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-fileAppender.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-fileAppender');">View as .groovy</span>
<pre id="logback-fileAppender" class="prettyprint source"><configuration>
@@ -561,7 +558,7 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
<p class="example">Example: Uniquely named FileAppender
configuration by timestamp
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-timestamp.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-timestamp');">View as .groovy</span>
<pre id="logback-timestamp" class="prettyprint source"><configuration>
@@ -597,7 +594,7 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
denotes the date pattern used to convert the current time (at which
the configuration file is parsed) into a string. The date pattern
should follow the conventions defined in <a
- href="https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a>. The
+ href="http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a>. The
<span class="attr">timeReference</span> attribute denotes the time
reference for the time stamp. The default is the
interpretation/parsing time of the configuration file, i.e. the
@@ -610,7 +607,7 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
<p>Experiment with the <code><timestamp></code> element by
running the command:</p>
- <p class="command">java chapters.appenders.ConfigurationTester src/main/resources/chapters/appenders/conf/logback-timestamp.xml</p>
+ <p class="command">java chapters.appenders.ConfigurationTester src/main/java/chapters/appenders/conf/logback-timestamp.xml</p>
<p>To use the logger context birth date as time reference, you
would set the <span class="attr">timeReference</span> attribute to
@@ -618,7 +615,7 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachabl
<p class="example">Example: Timestamp using context birth date as time reference
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-timestamp-contextBirth.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp-contextBirth.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-timestamp-contextBirth');">View as .groovy</span>
<pre id="logback-timestamp-contextBirth" class="prettyprint source"><configuration>
@@ -772,7 +769,9 @@ public interface RollingPolicy extends LifeCycle {
================= -->
- <h4 class="doAnchor" name="TimeBasedRollingPolicy">TimeBasedRollingPolicy </h4>
+ <h4 class="doAnchor"
+ name="TimeBasedRollingPolicy">TimeBasedRollingPolicy
+ </h4>
<p><a
href="../xref/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.html">
@@ -839,69 +838,28 @@ public interface RollingPolicy extends LifeCycle {
interpreted as directory separators.
</p>
- <h5>Multiple %d specifiers</h5>
-
- <p>It is possible to specify multiple %d specifiers but only
- one of which can be primary, i.e. used to infer the rollover
+ <p>It is possible to specify multiple %d tokens but only one
+ of which can be primary, i.e. used to infer the rollover
period. All other tokens <em>must</em> be marked as auxiliary
by passing the 'aux' parameter (see examples below).</p>
-
- <p>Multiple %d specifiers allow you to organize archive files
- in a folder structure different than that of the roll-over
- period. For example, the file name pattern shown below
- organizes log folders by year and month but roll-over log
- files every day at midnight.</p>
-
- <pre>/var/log/<b>%d{yyyy/MM, aux}</b>/myapplication.<b>%d{yyyy-MM-dd}</b>.log</pre>
-
- <h5>TimeZone</h5>
-
- <p>Under certain circumstances, you might wish to roll-over
- log files according to a clock in a timezone different than
- that of the host. It is possible to pass a timezone argument
- following the date-and-time pattern within the %d conversion
- specifier. For example:</p>
-
- <pre>aFolder/test.<b>%d</b>{yyyy-MM-dd-HH, <b>UTC</b>}.log</pre>
-
- <p>If the specified timezone identifier is unknown or
- misspelled, the GMT timezone is assumed as dictated by the <a
- href="http://docs.oracle.com/javase/6/docs/api/java/util/TimeZone.html#getTimeZone(java.lang.String)">TimeZone.getTimeZone(String)</a>
- method specification.
- </p>
</td>
</tr>
<tr>
<td><span class="prop" container="tbrp">maxHistory</span></td>
<td>int</td>
- <td>The optional <span class="prop">maxHistory</span> property
- controls the maximum number of archive files to keep,
- asynchronously deleting older files. For example, if you
- specify monthly rollover, and set maxHistory to 6, then 6
- months worth of archives files will be kept with files older
- than 6 months deleted. Note as old archived log files are
- removed, any folders which were created for the purpose of log
- file archiving will be removed as appropriate.
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="tbrp">totalSizeCap</span></td>
- <td>int</td>
- <td><p>The optional <span class="prop">totalSizeCap</span>
- property controls the total size of all archive files. Oldest
- archives are deleted asynchronously when the total size cap is
- exceeded. The <span class="prop">totalSizeCap</span> property
- requires <span class="option">maxHistory</span> property to be
- set as well. Moreover, the "max history" restriction is always
- applied first and the "total size cap" restriction applied
- second. </p>
+ <td>The optional <span class="prop">maxHistory</span>
+ property controls the maximum number of archive files to keep,
+ deleting older files. For example, if you specify monthly
+ rollover, and set maxHistory to 6, then 6 months worth of
+ archives files will be kept with files older than 6 months
+ deleted. Note as old archived log files are removed, any
+ folders which were created for the purpose of log file
+ archiving will be removed as appropriate.
</td>
</tr>
<tr >
- <td><span class="prop"
- container="tbrp">cleanHistoryOnStart</span></td>
+ <td><span class="prop" container="tbrp">cleanHistoryOnStart</span></td>
<td>boolean</td>
<td>
<p>If set to true, archive removal will be executed on
@@ -1021,15 +979,6 @@ public interface RollingPolicy extends LifeCycle {
at the beginning of every minute.
</td>
</tr>
- <tr>
- <td class="small">
- <em>/wombat/foo%d{yyyy-MM-dd_HH-mm, UTC}.log</em>
- </td>
- <td>Rollover at the beginning of every minute.</td>
- <td>Similar to previous cases, except that file names will be
- expressed in UTC.
- </td>
- </tr>
<tr>
@@ -1058,7 +1007,8 @@ public interface RollingPolicy extends LifeCycle {
</p>
- <p><code>TimeBasedRollingPolicy</code> supports automatic file
+ <p>Just like <code>FixedWindowRollingPolicy</code>,
+ <code>TimeBasedRollingPolicy</code> supports automatic file
compression. This feature is enabled if the value of the <span
class="prop">fileNamePattern</span> option ends with <em>.gz</em>
or <em>.zip</em>.
@@ -1156,7 +1106,7 @@ public interface RollingPolicy extends LifeCycle {
<p class="example">Example: Sample configuration of a
<code>RollingFileAppender</code> using a
<code>TimeBasedRollingPolicy</code>
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-RollingTimeBased.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingTimeBased.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-RollingTimeBased');">View as .groovy</span>
<pre id="logback-RollingTimeBased" class="prettyprint source"><configuration>
@@ -1166,10 +1116,8 @@ public interface RollingPolicy extends LifeCycle {
<!-- daily rollover -->
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
- <!-- keep 30 days' worth of history capped at 3GB total size -->
+ <!-- keep 30 days' worth of history -->
<maxHistory>30</maxHistory>
- <totalSizeCap>3GB</totalSizeCap>
-
</rollingPolicy></b>
<encoder>
@@ -1191,7 +1139,7 @@ public interface RollingPolicy extends LifeCycle {
<p class="example">Example: Sample configuration of a
<code>RollingFileAppender</code> using a
<code>TimeBasedRollingPolicy</code>
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-PrudentTimeBasedRolling');">View as .groovy</span>
<pre id="logback-PrudentTimeBasedRolling" class="prettyprint source"><configuration>
@@ -1201,7 +1149,6 @@ public interface RollingPolicy extends LifeCycle {
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
- <totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
@@ -1214,81 +1161,6 @@ public interface RollingPolicy extends LifeCycle {
</root>
</configuration></pre>
-
-
- <h3 class="doAnchor" name="SizeAndTimeBasedRollingPolicy">Size and
- time based rolling policy</h3>
-
-
- <p>Sometimes you may wish to archive files essentially by date but
- at the same time limit the size of each log file, in particular if
- post-processing tools impose size limits on the log files. In
- order to address this requirement, logback ships with
- <code>SizeAndTimeBasedRollingPolicy</code>.</p>
-
- <p>Note that <code>TimeBasedRollingPolicy</code> already allows
- limiting the combined size of archived log files. If you only wish
- to limit the combined size of log archives, then
- <code>TimeBasedRollingPolicy</code> described above and setting
- the <a href="#tbrpTotalSizeCap"><span
- class="option">totalSizeCap</span></a> property should be amply
- sufficent.
- </p>
-
- <p>Here is a sample configuration file demonstrating time and size
- based log file archiving.</p>
-
- <p class="example">Example: Sample configuration for
- <code>SizeAndTimeBasedFNATP</code>
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-sizeAndTime.xml)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-sizeAndTime');">View as .groovy</span>
- <pre id="logback-sizeAndTime" class="prettyprint source"><configuration>
- <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <file>mylog.txt</file>
- <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
- <!-- rollover daily -->
- <fileNamePattern><b>mylog-%d{yyyy-MM-dd}.<span class="big">%i</span>.txt</b></fileNamePattern>
- <b><!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB --></b>
- <b><maxFileSize>100MB</maxFileSize></b>
- <maxHistory>60</maxHistory>
- <totalSizeCap>20GB</totalSizeCap>
- </rollingPolicy>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
-
- <root level="DEBUG">
- <appender-ref ref="ROLLING" />
- </root>
-
-</configuration></pre>
-
- <p>Note the "%i" conversion token in addition to "%d". <b>Both the
- %i and %d tokens are mandatory.</b> Each time the current log file
- reaches <span class="prop">maxFileSize</span> before the current
- time period ends, it will be archived with an increasing index,
- starting at 0.</p>
-
- <p>Size and time based archiving supports deletion of old archive
- files. You need to specify the number of periods to preserve with
- the <span class="prop">maxHistory</span> property. When your
- application is stopped and restarted, logging will continue at the
- correct location, i.e. at the largest index number for the current
- period.
- </p>
-
- <p>In versions prior to 1.1.7, this document mentioned a component
- called <code>SizeAndTimeBasedFNATP</code>. However, given that
- <code>SizeAndTimeBasedFNATP</code> offers a simpler configuration
- structure, we no longer document
- <code>SizeAndTimeBasedFNATP</code>. Nevertheless, earlier
- configuration files using <code>SizeAndTimeBasedFNATP</code> will
- continue to work just fine. In fact,
- <code>SizeAndTimeBasedRollingPolicy</code> is implemented with a
- <code>SizeAndTimeBasedFNATP</code> subcomponent.</p>
<h4 class="doAnchor" name="FixedWindowRollingPolicy">FixedWindowRollingPolicy</h4>
@@ -1440,7 +1312,7 @@ public interface RollingPolicy extends LifeCycle {
</p>
<p class="example">Example: Sample configuration of a <code>RollingFileAppender</code> using a
- <code>FixedWindowRollingPolicy</code> (logback-examples/src/main/resources/chapters/appenders/conf/logback-RollingFixedWindow.xml)</p>
+ <code>FixedWindowRollingPolicy</code> (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingFixedWindow.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-RollingFixedWindow');">View as .groovy</span>
<pre id="logback-RollingFixedWindow" class="prettyprint source"><configuration>
@@ -1467,6 +1339,64 @@ public interface RollingPolicy extends LifeCycle {
</configuration></pre>
+ <h3 class="doAnchor" name="SizeAndTimeBasedFNATP">Size <b>and</b>
+ time based archiving
+ </h3>
+
+ <p>Sometimes you may wish to archive files essentially by date but
+ at the same time limit the size of each log file, in particular if
+ post-processing tools impose size limits on the log files. In
+ order to address this requirement, logback ships with a
+ sub-component for <code>TimeBasedRollingPolicy</code> called
+ <code>SizeAndTimeBasedFNATP</code>, where FNATP stands for File
+ Naming And Triggering Policy.</p>
+
+ <p>Here is a sample configuration file demonstrating time and size
+ based log file archiving.</p>
+
+ <p class="example">Example: Sample configuration for
+ <code>SizeAndTimeBasedFNATP</code>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-sizeAndTime.xml)</p>
+
+ <span class="asGroovy" onclick="return asGroovy('logback-sizeAndTime');">View as .groovy</span>
+ <pre id="logback-sizeAndTime" class="prettyprint source"><configuration>
+ <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>mylog.txt</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <!-- rollover daily -->
+ <fileNamePattern><b>mylog-%d{yyyy-MM-dd}.<span class="big">%i</span>.txt</b></fileNamePattern>
+ <b><timeBasedFileNamingAndTriggeringPolicy</b>
+ <b>class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"></b>
+ <!-- or whenever the file size reaches 100MB -->
+ <b><maxFileSize>100MB</maxFileSize></b>
+ <b></timeBasedFileNamingAndTriggeringPolicy></b>
+ </rollingPolicy>
+ <encoder>
+ <pattern>%msg%n</pattern>
+ </encoder>
+ </appender>
+
+
+ <root level="DEBUG">
+ <appender-ref ref="ROLLING" />
+ </root>
+
+</configuration></pre>
+
+ <p>Note the "%i" conversion token in addition to "%d". Each time
+ the current log file reaches <span
+ class="prop">maxFileSize</span> before the current time period
+ ends, it will be archived with an increasing index, starting at
+ 0.</p>
+
+ <p>Size and time based archiving supports deletion of old archive
+ files. You need to specify the number of periods to preserve with
+ the <span class="prop">maxHistory</span> property. When your
+ application is stopped and restarted, logging will continue at the
+ correct location, i.e. at the largest index number for the current
+ period.
+ </p>
+
<h2>
<a name="TriggeringPolicy" href="#TriggeringPolicy">Overview of
triggering policies</a>
@@ -1535,7 +1465,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
<p class="example">Example: Sample configuration of a
<code>RollingFileAppender</code> using a
<code>SizeBasedTriggeringPolicy</code>
- (logback-examples/src/main/resources/chapters/appenders/conf/logback-RollingSizeBased.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingSizeBased.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-RollingSizeBased');">View as .groovy</span>
<pre id="logback-RollingSizeBased" class="prettyprint source"><configuration>
@@ -1700,15 +1630,15 @@ public interface TriggeringPolicy<E> extends LifeCycle {
<td><span class="prop" container="socket">queueSize</span></td>
<td><code>int</code></td>
<td>
- <p>The <span class="prop">queueSize</span> property takes an
- integer (greater than zero) representing the number of logging
+ <p>The <span class="prop">queueSize</span> property takes a
+ non-negative integer representing the number of logging
events to retain for delivery to the remote receiver. When
- the queue size is one, event delivery to the remote
+ the queue size is zero, event delivery to the remote
receiver is synchronous. When the queue size is greater
- than one, new events are enqueued, assuming that there is
- space available in the queue. Using a queue length greater
- than one can improve performance by eliminating delays caused
- by transient network delays.
+ than zero, new events are enqueued, assuming that there is
+ space available in the queue. Using a non-zero queue length
+ can improve performance by eliminating delays caused by
+ transient network delays.
</p>
<p>See also the <span class="prop">eventDelayLimit</span>
@@ -1829,7 +1759,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
</p>
<p class="example">Example: SocketAppender configuration
- (logback-examples/src/main/resources/chapters/appenders/socket/client1.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/socket/client1.xml)</p>
<span class="asGroovy" onclick="return asGroovy('client1');">View as .groovy</span>
<pre id="client1" class="prettyprint source"><configuration>
@@ -1942,7 +1872,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
</p>
<p class="example">Example: SSLSocketAppender configuration
- (logback-examples/src/main/resources/chapters/appenders/socket/ssl/client.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/socket/ssl/client.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sslclient');">View as .groovy</span>
<pre id="sslclient" class="prettyprint source"><configuration debug="true">
@@ -2100,7 +2030,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
</p>
<p class="example">Example: Basic ServerSocketAppender Configuration
- (logback-examples/src/main/resources/chapters/appenders/socket/server4.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/socket/server4.xml)</p>
<pre id="SocketReceiver" class="prettyprint source"><configuration debug="true">
<appender name="SERVER"
class="ch.qos.logback.classic.net.server.ServerSocketAppender">
@@ -2126,7 +2056,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
<code>SSLServerSocketAppender</code>.</p>
<p class="example">Example: Basic SSLServerSocketAppender Configuration
- (logback-examples/src/main/resources/chapters/appenders/socket/ssl/server3.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/socket/ssl/server3.xml)</p>
<pre id="SocketReceiver" class="prettyprint source"><configuration debug="true">
<appender name="SERVER"
class="ch.qos.logback.classic.net.server.SSLServerSocketAppender">
@@ -2322,7 +2252,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
</p>
<p>If you don't specify a <span
class="prop">cyclicBufferTracker</span>, an instance of <a
- href="../xref/ch/qos/logback/core/spi/CyclicBufferTracker.html">CyclicBufferTracker</a>
+ href="../xref/ch/qos/logback/core/spi/CyclicBufferTrackerImpl.html">CyclicBufferTrackerImpl</a>
will be automatically created. By default, this instance
will keep events in a cyclic buffer of size 256. You may
change the size with the help of the <span
@@ -2364,7 +2294,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
<td><code>String</code></td>
<td>The outgoing email message will be encoded in the
designated <a
- href="https://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html">charset</a>. The
+ href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">charset</a>. The
default charset encoding is "UTF-8" which works well for most
purposes.
</td>
@@ -2487,7 +2417,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
<code>Email</code> application:
</p>
- <p class="example">Example: A sample <code>SMTPAppender</code> configuration (logback-examples/src/main/resources/chapters/appenders/mail/mail1.xml)</p>
+ <p class="example">Example: A sample <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/mail/mail1.xml)</p>
<span class="asGroovy" onclick="return asGroovy('mail1');">View as .groovy</span>
<pre id="mail1" class="prettyprint source"><configuration>
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
@@ -2587,7 +2517,7 @@ public interface TriggeringPolicy<E> extends LifeCycle {
desires, you may set a different buffer size as shown in the next example.
</p>
- <p class="example">Example: <code>SMTPAppender</code> configuration with a custom bufer size (logback-examples/src/main/resources/chapters/appenders/mail/customBufferSize.xml)</p>
+ <p class="example">Example: <code>SMTPAppender</code> configuration with a custom bufer size (logback-examples/src/main/java/chapters/appenders/mail/customBufferSize.xml)</p>
<pre class="prettyprint source"><configuration>
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
<smtpHost>${smtpHost}</smtpHost>
@@ -2685,7 +2615,7 @@ public class CounterBasedEvaluator extends ContextAwareBase implements EventEval
</p>
<p class="example">Example: <code>SMTPAppender</code> with custom
- <code>Evaluator</code> and buffer size (logback-examples/src/main/resources/chapters/appenders/mail/mail3.xml)</p>
+ <code>Evaluator</code> and buffer size (logback-examples/src/main/java/chapters/appenders/mail/mail3.xml)</p>
<span class="asGroovy" onclick="return asGroovy('mail3');">View as .groovy</span>
<pre id="mail3" class="prettyprint source"><configuration>
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
@@ -2735,7 +2665,7 @@ logger.error(<b>notifyAdmin</b>,
</p>
<p class="example">Example: <code>SMTPAppender</code> with
- <code>OnMarkerEvaluator</code> (logback-examples/src/main/resources/chapters/appenders/mail/mailWithMarker.xml)</p>
+ <code>OnMarkerEvaluator</code> (logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker.xml)</p>
<span class="asGroovy" onclick="return asGroovy('mailWithMarker');">View as .groovy</span>
<pre id="mailWithMarker" class="prettyprint source"><configuration>
@@ -2779,7 +2709,7 @@ logger.error(<b>notifyAdmin</b>,
</p>
<p class="example">Example: <code>SMTPAppender</code> with
- <code>JaninoEventEvaluator</code> (logback-examples/src/main/resources/chapters/appenders/mail/mailWithMarker_Janino.xml)</p>
+ <code>JaninoEventEvaluator</code> (logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker_Janino.xml)</p>
<span class="asGroovy" onclick="return asGroovy('mailWithMarker_Janino');">View as .groovy</span>
<pre id="mailWithMarker_Janino" class="prettyprint source"><configuration>
@@ -2801,7 +2731,7 @@ logger.error(<b>notifyAdmin</b>,
href="filters.html#GEventEvaluator">GEventEvaluator</a>.</p>
<p class="example">Example: the same with
- <code>GEventEvaluator</code> (logback-examples/src/main/resources/chapters/appenders/mail/mailWithMarker_GEvent.xml)</p>
+ <code>GEventEvaluator</code> (logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker_GEvent.xml)</p>
<span class="asGroovy" onclick="return asGroovy('mailWithMarker_GEventEvaluator');">View as .groovy</span>
<pre id="mailWithMarker_GEventEvaluator" class="prettyprint source"><configuration>
@@ -2833,7 +2763,7 @@ logger.error(<b>notifyAdmin</b>,
connection is encrypted right from the start.
</p>
- <h3 class="doAnchor" name="gmailSSL">SMTPAppender configuration
+ <h3> class="doAnchor"name="gmailSSL">SMTPAppender configuration
for Gmail (SSL)</h3>
<p>The next example shows you how to configure
@@ -2841,7 +2771,7 @@ logger.error(<b>notifyAdmin</b>,
<p class="example">Example:: <code>SMTPAppender</code> to Gmail
using SSL
- (logback-examples/src/main/resources/chapters/appenders/mail/gmailSSL.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/mail/gmailSSL.xml)</p>
<span class="asGroovy" onclick="return asGroovy('gmailSSLExample');">View as .groovy</span>
<pre id="gmailSSLExample" class="prettyprint source"><configuration>
@@ -2873,7 +2803,7 @@ logger.error(<b>notifyAdmin</b>,
<p>The next example shows you how to configure
<code>SMTPAppender</code> for Gmail for the STARTTLS protocol. </p>
- <p class="example">Example: <code>SMTPAppender</code> to GMAIL using STARTTLS (logback-examples/src/main/resources/chapters/appenders/mail/gmailSTARTTLS.xml)</p>
+ <p class="example">Example: <code>SMTPAppender</code> to GMAIL using STARTTLS (logback-examples/src/main/java/chapters/appenders/mail/gmailSTARTTLS.xml)</p>
<span class="asGroovy" onclick="return asGroovy('gmailSTARTTLSExample');">View as .groovy</span>
<pre id="gmailSTARTTLSExample" class="prettyprint source"><configuration>
@@ -2919,7 +2849,7 @@ logger.error(<b>notifyAdmin</b>,
<p class="example">Example: <code>SMTPAppender</code> with
MDCBasedDsicriminator
- (logback-examples/src/main/resources/chapters/appenders/mail/mailWithMDCBasedDiscriminator.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/mail/mailWithMDCBasedDiscriminator.xml)</p>
<span class="asGroovy" onclick="return asGroovy('mailWithMDCBasedDiscriminator');">View as .groovy</span>
<pre id="mailWithMDCBasedDiscriminator" class="prettyprint source"><configuration>
@@ -3311,7 +3241,7 @@ logger.error(<b>notifyAdmin</b>,
The following configuration file is what one would need.
</p>
- <p class="example">Example: <code>DBAppender</code> configuration (logback-examples/src/main/resources/chapters/appenders/db/append-toMySQL-with-driverManager.xml)</p>
+ <p class="example">Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-driverManager.xml)</p>
<span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-driverManager');">View as .groovy</span>
<pre id="append-toMySQL-with-driverManager" class="prettyprint source"><configuration>
@@ -3331,7 +3261,7 @@ logger.error(<b>notifyAdmin</b>,
<p>
The correct driver must be declared. Here, the <code>com.mysql.jdbc.Driver</code>
- class is used. The <span class="prop">url</span> must begin with <em>jdbc:mysql://</em>.
+ class is used. The <span class="prop">url</span> must begin with <em>jdbc:myslq://</em>.
</p>
<p>
@@ -3391,7 +3321,7 @@ logger.error(<b>notifyAdmin</b>,
<code>javax.sql.DataSource</code>.
</p>
- <p class="example">Example: <code>DBAppender</code> configuration (logback-examples/src/main/resources/chapters/appenders/db/append-with-datasource.xml)</p>
+ <p class="example">Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-with-datasource.xml)</p>
<span class="asGroovy" onclick="return asGroovy('append-with-datasource');">View as .groovy</span>
@@ -3500,7 +3430,7 @@ logger.error(<b>notifyAdmin</b>,
<p class="example">Example: <code>DBAppender</code> configuration
by <code>JNDIConnectionSource</code>
- (logback-examples/src/main/resources/chapters/appenders/db/append-via-jndi.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/db/append-via-jndi.xml)</p>
<span class="asGroovy" onclick="return asGroovy('append-via-jndi');">View as .groovy</span>
@@ -3544,7 +3474,7 @@ logger.error(<b>notifyAdmin</b>,
<p class="example">Example: <code>DBAppender</code> configuration
without pooling
- (logback-examples/src/main/resources/chapters/appenders/db/append-toMySQL-with-datasource.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource.xml)</p>
<span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource');">View as .groovy</span>
<pre id="append-toMySQL-with-datasource" class="prettyprint source"><configuration>
@@ -3581,7 +3511,7 @@ logger.error(<b>notifyAdmin</b>,
<p class="example">Example: <code>DBAppender</code> configuration
with pooling
- (logback-examples/src/main/resources/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml)</p>
<span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource-and-pooling');">View as .groovy</span>
<pre id="append-toMySQL-with-datasource-and-pooling" class="prettyprint source"><configuration>
@@ -3710,7 +3640,7 @@ logger.error(<b>notifyAdmin</b>,
<p>Here is a sample configuration using a
<code>SyslogAppender</code>.</p>
- <p class="example">Example: <code>SyslogAppender</code> configuration (logback-examples/src/main/resources/chapters/appenders/conf/logback-syslog.xml)</p>
+ <p class="example">Example: <code>SyslogAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-syslog.xml)</p>
<span class="asGroovy" onclick="return asGroovy('logback-syslog');">View as .groovy</span>
<pre id="logback-syslog" class="prettyprint source"><configuration>
@@ -3809,7 +3739,7 @@ logger.debug("Alice says hello"); </p>
<p class="example">Example: <code>SiftingAppender</code>
configuration
- (logback-examples/src/main/resources/chapters/appenders/sift/byUserid.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/sift/byUserid.xml)</p>
<span class="asGroovy" onclick="return asGroovy('byUserid');">View as .groovy</span>
@@ -3967,28 +3897,7 @@ import static ch.qos.logback.classic.ClassicConstants.FINALIZE_SESSION_MARKER;
flush the logging events from the queue. This can be achieved by
<a href="configuration.html#stopContext">stopping the
LoggerContext</a> which will close all appenders, including any
- <code>AsyncAppender</code> instances. <code>AsyncAppender</code>
- will wait for the worker thread to flush up to the timeout specified
- in <span class="prop">maxFlushTime</span>. If you find that queued events
- are being discarded during close of the <code>LoggerContext</code>, you
- may need to increase the time out. Specifying a value of 0 for
- <span class="prop">maxFlushTime</span> will force the <code>AsyncAppender</code>
- to wait for all queued events to be flushed before returning from
- the stop method.
- </p>
-
- <p><span class="label">Post shutdown cleanup</span>
- Depending on the mode of JVM shutdown, the worker thread processing the
- queued events can be interrupted causing events to be strandeds in the
- queue. This generally occurs when the <code>LoggerContext</code> is not
- stopped cleanly or when the JVM terminates outside of the typical control
- flow. In order to avoid interrupting the worker thread under these
- conditions, a shutdown hook can be inserted to the JVM runtime that
- <a href="configuration.html#stopContext">stops the LoggerContext properly</a>
- after JVM shutdown has been initiated. A shutdown hook may also be the
- preferred method for cleanly shutting down Logback when other shutdown hooks
- attempt to log events.
- </p>
+ <code>AsyncAppender</code> instances.</p>
<p>Here is the list of properties admitted by
@@ -4029,28 +3938,6 @@ import static ch.qos.logback.classic.ClassicConstants.FINALIZE_SESSION_MARKER;
class="prop">includeCallerData</span> property to true.
</td>
</tr>
- <tr>
- <td><span class="prop" container="async">maxFlushTime</span></td>
- <td><code>int</code></td>
- <td>Depending on the queue depth and latency to the referenced appender,
- the <code>AsyncAppender</code> may take an unacceptable amount of
- time to fully flush the queue. When the <code>LoggerContext</code> is
- stopped, the <code>AsyncAppender stop</code> method waits
- up to this timeout for the worker thread to complete. Use
- <span class="prop">maxFlushTime</span> to specify a maximum queue flush
- timeout in milliseconds. Events that cannot be processed within this
- window are discarded. Semantics of this value are identical to that of
- <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#join(long)">Thread.join(long)</a>.
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="async">neverBlock</span></td>
- <td><code>boolean</code></td>
- <td>If <code>false</code> (the default) the appender will block on
- appending to a full queue rather than losing the message. Set to
- <code>true</code> and the appender will just drop the message and
- will not block your application.</td>
- </tr>
</table>
<p>By default, event queue is configured with a maximum capacity
@@ -4098,7 +3985,7 @@ import static ch.qos.logback.classic.ClassicConstants.FINALIZE_SESSION_MARKER;
<p class="example">Example: <code>AsyncAppender</code>
configuration
- (logback-examples/src/main/resources/chapters/appenders/conc/logback-async.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conc/logback-async.xml)</p>
<span class="asGroovy" onclick="return asGroovy('asyncAppender');">View as .groovy</span>
@@ -4234,7 +4121,7 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
href="../xref/chapters/appenders/CountingConsoleAppender.html"><code>CountingConsoleAppender</code></a>
can be configured like any other appender. See sample
configuration file
- <em>logback-examples/src/main/resources/chapters/appenders/countingConsole.xml</em>
+ <em>logback-examples/src/main/java/chapters/appenders/countingConsole.xml</em>
for an example.
</p>
@@ -4316,7 +4203,7 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
</p>
<p class="example">Example: <code>SMTPAppender</code>
configuration
- (logback-examples/src/main/resources/chapters/appenders/conf/access/logback-smtp.xml)</p>
+ (logback-examples/src/main/java/chapters/appenders/conf/access/logback-smtp.xml)</p>
<pre class="prettyprint source"><appender name="SMTP"
class="ch.qos.logback.access.net.SMTPAppender">
@@ -4481,7 +4368,7 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
<p>Here is a sample configuration that uses <code>DBAppender</code>.</p>
- <p class="example">Example: DBAppender configuration <em>(logback-examples/src/main/resources/chapters/appenders/conf/access/logback-DB.xml)</em></p>
+ <p class="example">Example: DBAppender configuration <em>(logback-examples/src/main/java/chapters/appenders/conf/access/logback-DB.xml)</em></p>
<pre class="prettyprint source"><configuration>
@@ -4521,7 +4408,7 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
<p>Below is an example configuration file.</p>
- <p class="example">Example: SiftingAppender configuration (logback-examples/src/main/resources/chapters/appenders/conf/sift/access-siftingFile.xml)</p>
+ <p class="example">Example: SiftingAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/sift/access-siftingFile.xml)</p>
<pre class="prettyprint source"><configuration>
<appender name="SIFTING" class="ch.qos.logback.access.sift.SiftingAppender">
diff --git a/logback-site/src/site/pages/manual/appenders_ja.html b/logback-site/src/site/pages/manual/appenders_ja.html
deleted file mode 100644
index 5bc0a73..0000000
--- a/logback-site/src/site/pages/manual/appenders_ja.html
+++ /dev/null
@@ -1,2871 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第4章 アペンダー</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content" class="chapter">
-
- <h1>第4章 アペンダー</h1>
-
- <div class="quote">
-
- <p><em>西部について教えたいことが多すぎるのでどこから始めたらいいのかわからないよ。1つを選べば残りの100を捨てることになってしまう。最初の1つを決めるにはどうしたいいんだろう?</em></p>
-
- <p>—JOHN STEINBECK, <em>East of Eden</em></p>
- </div>
-
-
- <script src="../templates/creative.js" type="text/javascript"></script>
- <script src="../templates/setup.js" type="text/javascript"></script>
-
- <h2 class="doAnchor" name="whatIsAnAppender">アペンダーについて</h2>
-
- <p>logback はロギングイベントを出力する仕事を、アペンダーと呼ばれるコンポーネントに任せています。<a href="http://logback.qos.ch/xref/ch/qos/logback/core/Appender.html"><code>ch.qos.logback.core.Appender</code></a>インターフェイスを実装したものがアペンダーとして利用できます。このインターフェイスに宣言された重要なメソッドは次のとおりです。</p>
- <pre class="prettyprint source">package ch.qos.logback.core;
-
-import ch.qos.logback.core.spi.ContextAware;
-import ch.qos.logback.core.spi.FilterAttachable;
-import ch.qos.logback.core.spi.LifeCycle;
-
-
-public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachable {
-
- public String getName();
- public void setName(String name);
- <b>void doAppend(E event);</b>
-
-}</pre>
-
- <p><code>Appender</code>インターフェイスのほとんどのメソッドはゲッター、あるいはセッターです。<code>doAppend()</code>メソッドだけは特別で、唯一の引数として型<em>E</em>のオブジェクトを取ります。<em>E</em>の実際の型は、logbackモジュールによって異なります。logback-classic モジュールの場合、<em>E</em>は<a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/spi/ILoggingEvent.html">ILoggingEvent</a>になるでしょうし、logback-access モジュールでは<a href="http://logback.qos.ch/apidocs/ch/qos/logback/access/spi/AccessEvent.html">AccessEvent</a>になるでしょう。<code>doAppend()</code>メソッドは、おそらくlogbackフレームワークの中で最 [...]
- </p>
-
- <p>アペンダーには名前を付けられます。設定ファイル中で参照しやすいようにするためです。<code>Appender</code>インターフェイスは<code>FilterAttachable</code>インターフェイスを継承しています。つまり、アペンダーのインスタンスには一つ以上のフィルターを割り当てられるのです。フィルターについては、後の章で詳しく説明します。
- </p>
-
- <p>アペンダーには、ロギングイベントを出力することについて最終的な責任があります。しかし、アペンダー自体が書式化をするのではなく、<code>Layout</code>あるいは<code>Encoder</code>オブジェクトに処理を委譲します。レイアウトやエンコーダーは、ただ一つのアペンダーにだけ関連付けられ、そのアペンダーだけが参照することになります。アペンダーによっては、組み込みの、あるいは固定の書式が指定されています。そういうアペンダーには、レイアウトもエンコーダーも不要です。たとえば、 <code>SocketAppender</code>は、ロギングイベントを接続したリモートホストに転送する前に単純にシリアライズするだけです。
- </p>
-
-
- <h2 class="doAnchor" name="AppenderBase">AppenderBase</h2>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/AppenderBase.html">ch.qos.logback.core.AppenderBase</a></code>は、<code>Appender</code>インターフェイスを実装した抽象クラスです。このクラスは、どんなアペンダーにも必要な共通の機能として、名前や活性化状態やレイアウト、フィルターに対するゲッターおよびセッターメソッドが実装されています。logback の配布物に含まれるアペンダーはすべてこのクラスの派生クラスです。<code>AppenderBase</code>は抽象クラスですが、<code>Append</code>インターフェイスの<code>doAppend()</code>メソッドを実装しています。<code>AppenderBase</code>クラスの話は、実際にソースコードの抜粋を見ながら進めるのが一番わかりやすいと思います。
- </p>
-
-<pre class="prettyprint source">public synchronized void doAppend(E eventObject) {
-
- // prevent re-entry.
- if (guard) {
- return;
- }
-
- try {
- guard = true;
-
- if (!this.started) {
- if (statusRepeatCount++ < ALLOWED_REPEATS) {
- addStatus(new WarnStatus(
- "Attempted to append to non started appender [" + name + "].",this));
- }
- return;
- }
-
- if (getFilterChainDecision(eventObject) == FilterReply.DENY) {
- return;
- }
-
- // ok, we now invoke the derived class's implementation of append
- this.append(eventObject);
-
- } finally {
- guard = false;
- }
-}</pre>
-
- <p><code>doAppend()</code>メソッドはsynchronizedメソッドになっています。つまり、別のスレッドから同じアペンダーに安全にロギングできるのです。スレッド<em>T</em>が<code>doAppend()</code>メソッドを実行している間は、<em>T</em>だけが排他的にアペンダーにアクセスできるので、他のスレッドからの呼び出しはキューイングされます。
- </p>
-
- <p>synchronized が不適切な場合もあります。そういうときのために、logback の配布物には<a href="http://logback.qos.ch/xref/ch/qos/logback/core/AppenderBase.html"><code>AppenderBase</code></a>とよく似た<a href="http://logback.qos.ch/xref/ch/qos/logback/core/UnsynchronizedAppenderBase.html"><code>ch.qos.logback.core.UnsynchronizedAppenderBase</code></a>も含まれています。ややこしくなるので、<code>UnsynchronizedAppenderBase</code>については本章の後半で説明します。
- </p>
-
-
- <p><code>doAppend()</code>メソッドでは、まず最初にguard変数にtrueが設定されているかどうかをチェックします。trueだったら、ただちに終了します。そうでなければ、まずguard変数にtrueを設定してから次の処理に進みます。guard変数によって、<code>doAppend()</code>メソッドを再帰的に呼び出してしまうことを防いでいるのです。あるコンポーネントが、ログを取得するために<code>append()</code>というメソッドを呼び出したとしましょう。そうすると、今呼び出したアペンダーと同じアペンダーを直接呼び出すことになってしまうので、無限ループした結果スタックオーバーフローが発生してしまいます。
- </p>
-
- <p>次の式では<code>started</code>フィールドにtrueが設定されているかどうかをチェックします。trueでなければ、警告メッセージを出力して<code>doAppend()</code>メソッドは終了します。これは、クローズされたアペンダーには何も書き込めなくなるということです。<code>Appender</code>オブジェクトは<code>LifeCycle</code>インターフェイスを実装しているので、つまり<code>start()</code>メソッド、<code>stop()</code>メソッド、<code>isStarted()</code>メソッドを実装しています。Joran設定フレームワークは、アペンダーの全てのプロパティを設定してから、アペンダーを開始して活性化状態をアクティブにするため<code>start()</code>メソッドを呼び出します。アペンダーにもよりますが、指定されていないプロパティがあったり、プロパティに指定した値の影響で、開始できないことがあります。たとえば、<code>FIleAppender</ [...]
- </p>
-
- <p>アペンダーが開始できなかったとき、あるいは、停止してしまったときは、logback の内部状態管理システムによって警告メッセージが出力されます。何度か(ロギングを?)試みたあと、同じ内容の警告メッセージで溢れかえってしまうのを避けるため、<code>doAppend()</code>メソッドは警告メッセージを出力しないようになります。
- </p>
-
- <p>その次の<code>if</code>文では割り当てられたフィルターの応答をチェックします。フィルターチェインの応答によって、ロギングイベントを拒否するか受け入れるかが決まります。フィルターチェインが何も決めなかったら、デフォルトでロギングイベントは受け入れられるようになっています。
- </p>
-
- <p>その後は、派生クラスで実装されてた<code>append()</code>メソッドを呼び出します。このメソッドは、実際に適切なデバイスへロギングイベントを出力します。
- </p>
-
- <p>最後にguard変数が開放され、キューイングされた<code>doAppend()</code>メソッドの呼び出しが処理できるようになります。
- </p>
-
- <p>ここの説明では "プロパティ" という言葉の代わりに "オプション" という言葉を使いました。これは、JavaBeanの規約に従ったゲッターおよびセッターメソッドが用意された属性のことです。</p>
-
- <h1>logback-coreモジュール</h1>
-
- <p>logback-coreモジュールは、他のモジュールを構築する基盤となるモジュールです。一般的に、logbac-core モジュールのコンポーネントは、ある程度の(少なくとも最小限の)カスタマイズが必要です。以降の節では、カスタマイズしないでもすぐに利用できるアペンダーを紹介していきます。
- </p>
-
-
-
- <h2 class="doAnchor" name="OutputStreamAppender">OutputStreamAppender</h2>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/core/OutputStreamAppender.html"><code>OutputStreamAppender</code></a>は<code>java.io.OutputStream</code>にロギングイベントを出力します。このクラスは他のアペンダーを構築するための基本的なサービスを提供するものです。普通なら、利用者が<code>OutputStreamAppender</code>を直接インスタンス化することはありません。<code>java.io.OutputStream</code>を文字列で表現することはできないので、設定ファイルから<code>OutputStream</code>オブジェクトを指定することはできないのです。簡単に言うと、設定ファイルでは<code>OutputStreamAppender</code>を設定することはできません。しかし、<code>OutputStreamAppender</code>に設定できるプロパテ [...]
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
-
- <tr>
- <td><span class="prop" name="osaEncoder">encoder</span></td>
-
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/encoder/Encoder.html"><code>Encoder</code></a></td>
-
- <td><code>OutputStreamAppender</code>への出力を書式化する。エンコーダについては<a href="./05-encoders.html">別の章</a>で説明しています。
- </td>
- </tr>
-
- </table>
-
- <p><code>OutputStreamAppender</code>は<code>ConsoleAppender</code> 、 <code>FileAppender</code>の基底クラスです。<code>RollingFileAppender</code>の基底クラスはFileAppenderなので、これも含めておきます。次の図は<code>OutputStreamAppender</code>とそのサブクラスの関係を図示したものです。
- </p>
-
- <img src="images/chapters/appenders/appenderClassDiagram.jpg" alt="OutputStreamAppenderとサブクラスを示すUML図">
-
-
- <h2 class="doAnchor" name="ConsoleAppender">ConsoleAppender</h2>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/ConsoleAppender.html">ConsoleAppender</a></code>は名前のとおり、ロギングイベントをコンソールに出力します。正確に言うと、<em>System.out</em>あるいは<em>System.err</em>に出力します。デフォルトではSystem.outが使われます。<code>ConsoleAppender</code>は、利用者が指定したエンコーダーを使ってロギングイベントを書式化します。エンコーダーについては別の章で説明します。<em>System.out</em>と<em>System.err</em>の型は<code>java.io.PrintStream</code>です。つまり、いずれもバッファIO操作のための<code>OutputStreamWriter</code>にラップされているということです。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="conApp">encoder</span></td>
- <td>
- <a href="http://logback.qos.ch/xref/ch/qos/logback/core/encoder/Encoder.html"><code>Encoder</code></a>
- </td>
- <td><code>OutputStreamAppender</code>と同じです。</td>
- </tr>
- <tr>
- <td><span class="prop" container="conApp">target</span></td>
- <td><code>String</code></td>
- <td>文字列で、<em>System.out</em>か<em>System.err</em>を指定します。デフォルトは<em>System.outに</em>です。
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="conApp">withJansi</span></td>
- <td><code>boolean</code></td>
- <td><span class="prop">withJansi</span>プロパティの値にはデフォルトで<code>false</code>が設定されています。<span class="prop">withJansi</span>プロパティに<code>true</code>を指定すると、<a href="http://jansi.fusesource.org/">Jansi</a>ライブラリが有効化され、Windowsマシン上でANSIカラーコードがサポートされるようになります。Windows のホスト上でこのプロパティにtrueを指定する場合、クラスパス上にjansiライブラリのjarファイルを置かなければなりません。なお、UnixベースのOSであるLinuxやMac OS Xのターミナルは、デフォルトでANSIカラーコードをサポートしています。
-
- <p>Eclipse IDEから利用する場合は、<a href="http://www.mihai-nita.net/eclipse/">ANSI in Eclipse Console</a>プラグインをインストールしてみましょう。
- </p>
- </td>
- </tr>
-
- </table>
-
- <p><code>ConsoleAppender</code>の設定サンプルを見てください。
- </p>
-
-
-
- <p class="example">例:ConsoleAppenderの設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-Console.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback_Console');">Groovyで表示</span>
-
- <pre id="logback_Console" class="prettyprint source"><configuration>
-
- <b><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <!-- encoders are assigned the type
- ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
- <encoder>
- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
- </encoder>
- </appender></b>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p><em>logback-examples</em>ディレクトリに移動して、<a href="http://logback.qos.ch/setup.html">クラスパスを設定</a>すれば、次のコマンドで上の設定ファイルを使って実行できます。</p>
-
- <p class="source">java <a href="http://logback.qos.ch/xref/chapters/appenders/ConfigurationTester.html">chapters.appenders.ConfigurationTester</a> src/main/java/chapters/appenders/conf/logback-Console.xml</p>
-
-
- <h2 class="doAnchor" name="FileAppender">FileAppender</h2>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/core/FileAppender.html"><code>FileAppender</code></a>は<code>OutputStreamAppender</code>の派生クラスで、ファイルにロギングイベントを出力します。<span class="prop">file</span>オプションで対象のファイルを指定します。既にファイルが存在するとき、ファイル内容を切り捨てるか、追加するかどうかは、<span class="prop">append</span>プロパティの値に応じて決まります。
- </p>
-
- <table class="bodyTable properties striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="fileApppender">append</span></td>
- <td><code>boolean</code></td>
- <td>trueの場合、既存のファイルの末尾にロギングイベントを追加します。<span class="prop">append</span>プロパティがfalseの場合、既存のファイルの内容は捨てられてしまいます。デフォルトは<span class="option">true</span>です。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="fileApppender">encoder</span></td>
- <td>
- <a href="http://logback.qos.ch/xref/ch/qos/logback/core/encoder/Encoder.html"><code>Encoder</code></a>
- </td>
- <td><code>OutputStreamAppender</code>と同じです。</td>
- </tr>
-
-
- <tr>
- <td><span class="prop" container="fileApppender">file</span></td>
- <td><code>String</code></td>
- <td>書き込み先のファイル名です。ファイルが存在しない場合、新しく作成します。Windowsプラットフォームの利用者は、バックスラッシュをエスケープするの忘れがちなので注意してください。たとえば、<em>c:\temp\test.log</em>という文字列は意図したように解釈されません。<em>'\t'</em>はエスケープシーケンスの<em>タブ文字{\u0009}</em>として解釈されるでしょう。<em>c:/temp/test.log</em>と書くか、<em>c:\\temp\\test.log</em>のように書けばよいでしょう。デフォルト値はありません。
-
- <p>指定したファイルの親ディレクトリが存在しない場合、 <code>FileAppender</code>は途中の全てのディレクトリを作成します。
- </p>
- </td>
- </tr>
-
-
- <tr>
- <td><span class="prop" name="prudent">prudent</span></td>
- <td><code>boolean</code></td>
-
- <td>prudentモードでは、指定されたファイルに安全に書き込むようになります。同じファイルを対象にした他の<code>FileAppender</code>がいるとしても、それが別のJVMで動いているとしても、ましてや別のホストで動いているとしても、です。デフォルト値は<code>false</code>です。
-
- <p>prudent モードは、<a href="./appenders.html#prudentWithRolling">多少の制限</a>はあるものの、<code>RollingFileAppender</code>と組み合わせて利用することもできます。</p>
-
- <p>prudent モードがtrueなら、<span class="prop">append</span>プロパティも自動的にtrueになります。
- </p>
-
- <p>prudentモードは排他的なファイルロックを使用します。ファイルロックを使うと、ロギングイベントの出力にかかるコストがおよそ3倍程度になることが分かっています。標準的なPCで、<b>ローカル</b>のハードディスク上のファイルへ一つロギングイベントを出力をするとき、prudentモードがオフの場合はおよそ10マイクロ秒かかります。prudentモードをオンにすると、30マイクロ秒になります。言い換えると、prudentモードがオフの場合は毎秒100,000回のロギングイベントが処理できるのに対して、prudentモードがオンの場合は毎秒33,000回しか処理できなくなるということです。
- </p>
-
- <p>prudentモードでは、複数のJVMから同じファイルに行うIO操作を効果的にシリアライズします。したがって、JVMの数が多くなればなるほど、IO操作ごとの待ち時間が長くなります。IO操作の<em>合計時間</em>が、毎秒20回オーダーのロギング要求が処理できる程度であれば、性能への影響は無視してもよいでしょう。アプリケーションが毎秒100回以上のIO操作をするようであれば、きっと性能影響があるので<span class="prop">prudent</span>モードを使うのはやめてください。
- </p>
-
- <p><span class="label">ネットワークファイルロック</span>ネットワークファイルシステム上のログファイルを対象にすると非常にコストが高くなります。ネットワークファイルシステム越しのファイルロックは、プロセスがすでに所有しているロックをリリースする前に再取得する、という振る舞いに強く依存していることも同じくらい重要です。したがって1つのプロセスがログファイルを占有していると、他のプロセスからはデッドロックしているように見えるので、ロックを待ち続けることになってしまいます。
- </p>
-
- <p>prudentモードは、ネットワークの速度と同じくらいの影響をOSの実装からも受けます。私たちの提供しているとても小さいアプリケーションの<a href="https://gist.github.com/2794241">FileLockSimulator</a>を使えば、あなたの環境でprudentモードがどのように振る舞うかシミュレートできます。
- </p>
-
-
- </td>
-
- </tr>
- </table>
-
- <p><span class="label notice">即時フラッシュ</span>
-デフォルトでは、それぞれのロギングイベントは、最終的な出力ストリームに即時にフラッシュされます。これは、あなたのアプリケーションがアペンダーをちゃんとクローズしていない場合、ロギングイベントが失われないようにするためのより安全な方法です。しかし、ロギング要求のスループットが大幅に増加してしまう場合には、<code>Encorder</code>の<span class="prop">immediateFlush</span>プロパティに<code>false</code>を指定することもできます。エンコーダー、特に<a href="./encoders.html#LayoutWrappingEncoder"><code>LayoutWrappingEncoder</code></a>については別の章で説明します。</p>
-
- <p><code>FileAppender</code>の設定例を見てください。</p>
-
- <p class="example">例:FileAppenderの設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-fileAppender.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-fileAppender');">Groovyとして表示</span>
- <pre id="logback-fileAppender" class="prettyprint source"><configuration>
-
- <b><appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <file>testFile.log</file>
- <append>true</append>
- <!-- encoders are assigned the type
- ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
- <encoder>
- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
- </encoder>
- </appender></b>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
- <p><em>logback-examples</em>ディレクトリに移動すれば、次のコマンドで上の設定ファイルを使って実行できます。
-</p>
-
- <p class="source">java chapters.appenders.ConfigurationTester
- src/main/java/chapters/appenders/conf/logback-fileAppender.xml</p>
-
-
- <h3 class="doAnchor" name="uniquelyNamed">ファイル名を一意にする(タイムスタンプを使う)</h3>
-
- <p>アプリケーションの開発フェーズの間や、アプリケーションを実行している時間が短い(たとえば、バッチアプリケーション)場合は、アプリケーションを実行するたびに新しいログファイルを作るほうがよいでしょう。<code>timestamp要素</code>を使えば簡単に実現できます。以下に例を示します。</p>
-
-
- <p class="example">例:タイムスタンプを使ってファイル名を一意にするFileAppenderの設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-timestamp.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-timestamp');">Groovyとして表示</span>
- <pre id="logback-timestamp" class="prettyprint source"><configuration>
-
- <!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
- the key "bySecond" into the logger context. This value will be
- available to all subsequent configuration elements. -->
- <b><timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/></b>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <!-- use the previously created timestamp to create a uniquely
- named log file -->
- <file><b>log-${bySecond}.txt</b></file>
- <encoder>
- <pattern>%logger{35} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <p>timestamp要素には、<span class="attr">key属性</span>および<span class="attr">datePattern属性</span>という2つの必須属性と、<span class="attr">timeReference属性</span>という任意属性があります。<span class="attr">key属性</span>には、<a href="./configuration.html#variableSubstitution">変数</a>と同じく、他の設定要素からタイムスタンプを参照するときの名前を指定します。<span class="attr">datePattern</span>属性には、設定ファイルを解釈した時点の日時を文字列に変換するための日付パターン文字列を指定します。日付パターン文字列に指定できるのは、<a href="https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat [...]
- </p>
-
- <p>次のコマンドを実行して、<code>timestamp要素</code>がどうなるのか試してみましょう。</p>
-
- <p class="command">java chapters.appenders.ConfigurationTester src/main/java/chapters/appenders/conf/logback-timestamp.xml</p>
-
- <p>ロガーコンテキストを生成した日時を基準時間として使う場合、<span class="attr">timeReference属性</span>に"contextBirth"を指定します。</p>
-
-
- <p class="example">例:タイムスタンプの基準時間にロガーコンテキストを生成した日時を使用する(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/blogback-timestamp-contextBirth.xml">logback-examples/src/main/java/chapters/appenders/conf/blogback-timestamp-contextBirth.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-timestamp-contextBirth');">Groovyとして表示</span>
- <pre id="logback-timestamp-contextBirth" class="prettyprint source"><configuration>
- <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"
- <b>timeReference="contextBirth"</b>/>
- ...
-</configuration></pre>
-
- <h2 class="doAnchor" name="RollingFileAppender">RollingFileAppender</h2>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/core/rolling/RollingFileAppender.html"><code>RollingFileAppender</code></a>は<code>FileAppender</code>を拡張して、ログファイルを切り替えられるようにしたものです。たとえば、<code>RollingFileAppender</code>では、<em>log.txt</em>という名前のファイルにログを出力するようにした上で、一定の条件が満たされたら、出力先を別のファイルに変えることができます。
- </p>
-
- <p><code>RollingFileAppender</code>と連携する2つの重要なサブコンポーネントがあります。一つは<code>RollingPolicy</code>です。これはファイルを切り替えるために必要な処理を行います。<a href="./appenders.html#onRollingPolicies">詳しくは後述します</a>。もう一つは<code>TriggeringPolicy</code>です。これはいつ切り替えるのか決定するものです。こちらも<a href="./appenders.html#TriggeringPolicy">詳しくは後述します</a>。つまり、<code>RollingPolicy</code>が<em>what</em>を、<code>TriggeringPolicy</code>が<em>when</em>を表しているのです。</p>
-
- <p>どんな使い方をするにしても、<code>RollingFileAppender</code>には<code>RollingPolicy</code>と<code>TriggeringPolicy</code>の両方を設定しなければなりません。<code>RollingPolicy</code>は<code>TriggeringPolicy</code>インターフェイスを実装しているので、少なくともRollingPolicyだけは明示的に設定しなければなりません。
- </p>
-
- <p><code>RollingFileAppender</code>で利用出来るプロパティは次のとおりです。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="rfa">file</span></td>
- <td><code>String</code></td>
- <td><code>FileAppender</code>と同じです。</td>
- </tr>
- <tr>
- <td><span class="prop" container="rfa">append</span></td>
- <td><code>boolean</code></td>
- <td><code>FileAppender</code>と同じです。</td>
- </tr>
- <tr>
- <td><span class="prop" container="rfa">encoder</span></td>
- <td>
- <a href="http://logback.qos.ch/xref/ch/qos/logback/core/encoder/Encoder.html"><code>Encoder</code></a>
- </td>
- <td><code>OutputStreamAppender</code>と同じです。</td>
- </tr>
- <tr>
- <td><span class="prop" container="rfa">rollingPolicy</span></td>
- <td><code>RollingPolicy</code></td>
- <td>このオプションに指定するのは、<code>RollingFileAppender</code>がファイルを切り替える際に処理を委譲するコンポーネントです。詳細は後述します。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="rfa">triggeringPolicy</span></td>
- <td><code>TriggeringPolicy</code></td>
- <td>このオプションに指定するのは、<code>RollingFileAppender</code>にファイルを切り替えるタイミングを通知するコンポーネントです。詳細は後述します。
- </td>
- </tr>
- <tr>
- <td valign="top"><span class="prop" name="prudentWithRolling">prudent</span></td>
-
- <td valign="top"><code>boolean</code></td>
-
- <td valign="top">
- prudentモードでは、<a href="./appenders.html#FixedWindowRollingPolicy"><code>FixedWindowRollingPolicy</code></a>はサポートされていません。
-
- <p> <a href="./appenders.html#TimeBasedRollingPolicy"><code>TimeBasedRollingPolicy</code></a>を使えば<code>RollingFileAppender</code>でもprudentモードを利用できますが、二つの制限があります。
- </p>
-
- <ol>
- <li>purudentモードでは、ファイル圧縮オプションをサポートしていませんし、利用することもできません。(他のJVMがログファイルを圧縮している間、書き込むことはできません)</li>
-
- <li><code>FileAppender</code>の<span class="prop">file</span>プロパティを指定することはできません。空のままにしておかなければなりません。ほとんどのOSでは、他のプロセスが開いているファイルの名前を変えることはできません。
- </li>
-
- </ol>fileプロパティについては<code>FileAppender</code>の説明を参照してください。
- </td>
- </tr>
- </table>
-
- <h3 class="doAnchor" name="onRollingPolicies">ローリングポリシーの概要</h3>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/core/rolling/RollingPolicy.html"><code>RollingPolicy</code></a>は、ファイルの切り替えに伴う移動や名前の変更を行います。</p>
-
- <p><code>RollingPolicy</code>インターフェイスは次のようなものです。</p>
-
- <pre class="prettyprint source">package ch.qos.logback.core.rolling;
-
-import ch.qos.logback.core.FileAppender;
-import ch.qos.logback.core.spi.LifeCycle;
-
-public interface RollingPolicy extends LifeCycle {
-
- <b>public void rollover() throws RolloverFailure;</b>
- public String getActiveFileName();
- public CompressionMode getCompressionMode();
- public void setParent(FileAppender appender);
-}</pre>
-
- <p><code>rollover</code>メソッドによって、現在のログファイルのアーカイブ処理を行います。<code>getActiveFileName()</code>メソッドは、今まさにログを出力しているはずのログファイル名を算出するために呼び出されます。<code>getCompressionMode</code>メソッドの名前が示すとおり、RollingPolicyにはファイル圧縮モードを決める役割もあります。<code>RollingPolicy</code>から親となるアペンダーへの参照は、<code>setParent()</code>メソッドによって設定します。
- </p>
-
- <!-- =================
- ================= -->
-
-
- <h4 class="doAnchor" name="TimeBasedRollingPolicy">TimeBasedRollingPolicy</h4>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.html">TimeBasedRollingPolicy</a></code>はおそらく一番人気のあるポリシーです。これは、ファイル切り替えポリシーを日付や月などの日時に基いて定義するものです。
- <code>TimeBasedRollingPolicy</code>にはファイルを切り替えるタイミングを通知する役割もあります。実際に、 <code>TimeBasedTriggeringPolicy</code>は<code>RollingPolicy</code>と<code>TriggeringPolicy</code>の<em>両方</em>のインターフェイスを実装しています。
- </p>
-
- <p><code>TimeBasedRollingPolicy</code>には、必須プロパティの<span class="prop">fileNamePattern</span>と、いくつかの任意のプロパティが設定できます。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="tbrp">fileNamePattern</span></td>
- <td><code>String</code></td>
- <td><span class="prop">fileNamePattern</span>プロパティは必須プロパティで、切り替えるときのログファイル名を指定します。指定する値には、ファイル名と<em>%d変換指示子</em>が含まれます。<em>%d変換指示子</em>には、<code>java.text.SimpleDateFormat</code>クラスで定義された日付時刻のパターン文字列を指定します。日付時刻パターンが省略された場合、パターン文字列として<em>yyyy-MM-dd</em>が使われます。<b>ファイルの切り替え周期は、<span class="prop">fileNamePattern</span>に指定された値から推測されます。</b>
-
-
- <p><code>TimeBasedRollingPolicyの親アペンダーである<code>RollingFileAppender</code>の<span class="prop">file</span>プロパティは、指定することもできるし省略することもできます。</code><span class="prop">file</span>プロパティにファイル名を指定した場合、ログを出力するファイルとアーカイブファイルの場所を別々にすることができます。ログは常に<span class="prop">file</span>プロパティで指定されたファイルに出力されます。
-そうすると、有効なログファイルを常に同じ名前にしておくことができます。<span class="prop">file</span>プロパティを省略した場合、有効なログファイル名は、<span class="prop">fileNamePattern</span>プロパティに指定した値に基いて定期的に新しい名前になります。この振る舞いを明確に説明する例を以降に示します。
- </p>
-
- <p>%d{}変換指示子の内側に書かれる日付と時刻のパターン文字列は、java.text.SimpleDateFormatの規約にしたがったものです。<span class="option">fileNamePattern</span>プロパティの中であれば、日付と時刻のパターン文字列の中でも外でも、スラッシュ'/'およびバックスラッシュ'\'はディレクトリの区切り文字として扱われます。
- </p>
-
- <p>%dトークンはいくつでも指定することができますが、ファイル切り替え周期を推測するために使われるのは最初のものだけです。他のすべてのトークンには、'aux'パラメータを指定して補助であるという印を<em>付けなければなりません</em>。</p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="tbrp">maxHistory</span></td>
- <td>int</td>
- <td><span class="prop">maxHistory</span>プロパティは、任意プロパティです。削除せずに保持しておくアーカイブファイルの最大数を指定します。たとえば毎月切り替えるつもりでmaxHistoryに6を指定した場合、過去6ヶ月以内のアーカイブファイルは保持され、過去6ヶ月より古いファイルは削除されるでしょう。古くなったファイルだけが削除されるので、logbackが作成したディレクトリは削除されないので注意してください。
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="tbrp">cleanHistoryOnStart</span></td>
- <td>boolean</td>
- <td>
- <p>trueを指定した場合、アペンダーの開始時に古いアーカイブを削除します。デフォルトではfalseが設定されています。</p>
-
- <p>通常は、ファイルを切り替えるタイミングで古いアーカイブも削除されます。しかし、アプリケーションによっては切り替えのタイミングが来るまで実行し続けないことがあります。そういう短命なアプリケーションでは、古いアーカイブを削除するタイミングが来ない可能性があるのです。<span class="prop">cleanHistoryOnStart</span>プロパティにtrueを指定しておけば、アペンダーの開始時に古いアーカイブを削除することができます。</p>
- </td>
- </tr>
- </table>
-
-
- <p><code>fileNamePattern</code>の値とその効果について具体例を示します。</p>
-
-
-
- <table class="bodyTable striped">
- <tr>
- <th>
- <span class="prop">fileNamePattern</span>
- </th>
- <th>切り替えタイミング</th>
- <th>具体例</th>
- </tr>
- <tr>
- <td class="small">
- <em>/wombat/foo.%d</em>
- </td>
- <td>毎日深夜に切り替え。<em>%d変換指示子</em>に日付時刻パターンが省略されているので、デフォルトの<em>yyyy-MM-dd</em>が指定されたことになります。このパターン文字列の場合は、毎日切り替えることになります。
- </td>
-
- <td>
- <p><span class="prop">file</span>プロパティを指定しない場合:2006年11月23日中は<em>/wombat/foo.2006-11-23</em>に出力されます。23日の24時(24日の0時)以降、24日中は<em>/wombat/foo.2006-11-24</em>に出力されます。
- </p>
-
- <p><span class="prop">file</span>プロパティに<em>/wombat/foo.txt</em>を指定した場合:2006年11月23日中は<em>/wombat/foo.txt</em>に出力されます。23日24時(24日0時)に<em>foo.txt</em>は<em>/wombat/foo.2006-11-23</em>に変更されます。24日中は、新しく作成された<em>/wombat/foo.txt</em>に出力されます。
- </p>
-
- </td>
- </tr>
-
-
- <tr>
- <td class="small">
- <em>/wombat/%d{yyyy/MM}/foo.txt</em>
- </td>
- <td>月初めに切り替え。</td>
- <td>
- <p><span class="prop">file</span>プロパティを指定しない場合:2006年10月中は、<em>/wombat/2006/10/foo.txt</em>に出力されます。10月31日の24時(つまり11月1日の0時)以降、11月中は<em>/wombat/2006/11/foo.txt</em>に出力されます。
- </p>
-
- <p><span class="prop">file</span>プロパティに<em>/wombat/foo.txt</em>を指定した場合:出力先は常に<em>/wombat/foo.txt</em>です。2006年10月中は、<em>/wombat/foo.txt</em>に出力されます。10月31日の24時(つまり11月1日の0時)に<em>/wombat/foo.txt</em>は<em>/wombat/2006/10/foo.txt</em>に変更されます。11月中は、新しく作成された<em>/wombat/foo.txt</em>に出力されます。11月30日の24時(つまり12月1日の0時)に<em>/wombat/foo.txt</em>は<em>/wombat/2006/11/foo.txt</em>に変更されます。
- </p>
- </td>
- </tr>
- <tr>
- <td class="small">
- <em>/wombat/foo.%d{yyyy-ww}.log</em>
- </td>
-
- <td>週初めに切り替え。週の最初の日は、ロケールに依存するので注意してください。</td>
-
- <td>前の例と同じですが、切り替えが発生するのは週の初日です。
- </td>
- </tr>
- <tr>
- <td class="small">
- <em>/wombat/foo%d{yyyy-MM-dd_HH}.log</em>
- </td>
- <td>毎時0分に切り替え。</td>
- <td>前の例と同じですが、切り替えが発生するのは毎時0分です。
- </td>
- </tr>
- <tr>
- <td class="small">
- <em>/wombat/foo%d{yyyy-MM-dd_HH-mm}.log</em>
- </td>
- <td>毎分0秒に切り替え。</td>
- <td>前の例と同じですが、切り替えが発生するのは毎分0秒です。
-
- </td>
- </tr>
-
-
- <tr>
- <td class="small">
- <em>/foo/%d{yyyy-MM,<b>aux</b>}/%d.log</em>
- </td>
- <td>毎日深夜に切り替え。年と月からなる名前のフォルダにアーカイブを作成する。
- </td>
- <td>この例では、最初の%dトークンは補助(<b>aux</b>iliary)であるという印が付いています。したがって、日付時刻パターンの省略された二つ目の%dトークンが最初のものとして使われます。したがって、切り替えタイミングは日次(%dのデフォルトパターン)になり、アーカイブするフォルダ名はそのときの年と月になります。例えば、2006年11月中にアーカイブされたファイルはすべて<em>/foo/2006-11</em>というフォルダに置かれます。例えば<em>/foo/2006-11/2006-11-14.log</em>のようになります。
- </td>
-
- </tr>
- </table>
-
- <p>スラッシュまたはバックスラッシュ文字はフォルダ(ディレクトリ)の区切り文字として扱われます。存在しないフォルダは必要に応じて作成されるので、別々のフォルダにログファイルを作るのは簡単です。
- </p>
-
-
- <p><code>TimeBasedRollingPolicy</code>は、<code>FixedWindowRollingPolicy</code>のように自動ファイル圧縮をサポートしています。<span class="prop">fileNamePattern</span>オプションの値が<em>.gz</em>または<em>.zip</em>で終わっている場合、このフィーチャが有効になります。
- </p>
-
- <table class="bodyTable striped">
- <tr class="a">
- <th><span class="prop">fileNamePattern</span></th>
- <th>切り替えタイミング</th>
- <th>具体例</th>
- </tr>
- <tr>
- <td><em>/wombat/foo.%d.gz</em></td>
- <td>毎日深夜に切り替え。アーカイブファイルは自動的にgz圧縮する。</td>
- <td>
- <p><span class="prop">file</span>プロパティを指定しない場合:2009年11月23日中は<em>/wombat/foo.2009-11-23</em>に出力します。23日24時(24日0時)になったら、それまでログを出力していたファイルはgz圧縮されて<em>/wombat/foo.2009-11-23.gz</em>になります。11月24日中は<em>/wombat/folder/foo.2009-11-24</em>に出力されます。
- </p>
-
- <p><span class="prop">file</span>プロパティに<em>/wombat/foo.txt</em>を指定した場合:2009年11月23中は<em>/wombat/foo.txt</em>に出力されます。23日24時(24日0時)にgz圧縮されて<em>/wombat/foo.2009-11-23.gz</em>になります。11月24日中は新しく作られた<em>/wombat/foo.txt</em>に出力されます。24日24時(25日0時)に<em>/wombat/foo.txt</em>はgz圧縮されて<em>/wombat/foo.2009-11-24.gz</em>になります。
- </p>
- </td>
- </tr>
- </table>
-
- <p><span class="prop">fileNamePattern</span>には2つの目的があります。1つは、パターン文字列を処理して、logbackに切り替えタイミングを指示することです。もう1つはアーカイブファイル名を決めることです。パターン文字列の形が違っても切り替えタイミングが同じになることがあるので気をつけてください。パターン文字列が<em>yyyy at MM</em>でも<em>yyyy-MM</em>でも、切り替えタイミングは毎月ですが、アーカイブファイル名は異なります。
- </p>
-
- <p><span class="prop">file</span>プロパティを設定すると、アクティブなログファイルの場所とアーカイブファイルの場所を別々にすることができます。ログは<span class="prop">file</span>プロパティで指定したファイルに出力されます。つまり、アクティブなログファイルの名前は常に同じになるのです。ただし、<span class="prop">file</span>プロパティを省略した場合、アクティブなログファイルの名前は<span class="prop">fileNamePattern</span>に基づいたものになります。<span class="prop">file</span>オプションを設定しなければ、<a href="http://logback.qos.ch/codes.html#renamingError">ログファイルの名前変更エラー</a>を割けられます。これは外部からログファイルを参照している間に切り替えようとすると発生するエラーです。存在するときに発生する。
- </p>
-
- <p><span class="prop">maxHistory</span>プロパティは、削除せずに保持しておくアーカイブファイルの最大数を指定します。たとえば、切り替えタイミングが毎月で、<span class="prop">maxHistory</span>に6を指定していたら、6ヶ月以内のアーカイブは保持されますが、6ヶ月を超える古いアーカイブは削除されます。古いアーカイブは削除されてしまうので注意しましょう。logbackによって作られたフォルダも必要に応じて削除されてしまいます。
- </p>
-
- <p>技術的な都合により、ファイルの切り替えは時間ベースではなくロギングイベントの到着ベースで行われます。例えば、2002年3月8日時点で<span class="prop">fileNamePattern</span>に<em>YYYY-MM-DD</em>(毎日切り替え)が指定されていることにしましょう。すると、8日24時(9日0時)を過ぎてから最初のロギングイベントが到着した際にファイルの切り替えが行われます。しばらくロギングイベントが発生しなかった場合、たとえば0時を過ぎてから23分47秒後にロギングイベントが発生した場合、3月9日0時0分ではなく、0時23分47秒にファイルの切り替えが行われることになります。したがって、ファイル切り替えにはロギングイベントの頻度に応じた遅延が伴います。どれくらいの遅延があろうとも、切り替えアルゴリズムは常に正しく動作します。したがってあらゆるロギングイベントはそれが発生した時刻に基いて適切なファイルに出力されます。
- </p>
-
- <p><code>RollingFileAppender</code>と<code>TimeBasedRollingPolicy</code>の設定例を見てください。
- </p>
-
- <p class="example">例:<code>RollingFileAppender</code>と<code>TimeBasedRollingPolicy</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-RollingTimeBased.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-RollingTimeBased.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-RollingTimeBased');">Groovyとして表示</span>
- <pre id="logback-RollingTimeBased" class="prettyprint source"><configuration>
- <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <file>logFile.log</file>
- <b><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <!-- daily rollover -->
- <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
-
- <!-- keep 30 days' worth of history -->
- <maxHistory>30</maxHistory>
- </rollingPolicy></b>
-
- <encoder>
- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
- <p>次の例はprudentモードの例です。
- </p>
-
- <p class="example">例:prudentモードにした<code>RollingFileAppender</code>と<code>TimeBasedRollingPolicy</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-PrudentTimeBasedRolling');">Groovyとして表示</span>
- <pre id="logback-PrudentTimeBasedRolling" class="prettyprint source"><configuration>
- <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <b><!-- Support multiple-JVM writing to the same log file --></b>
- <b><prudent>true</prudent></b>
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
- <maxHistory>30</maxHistory>
- </rollingPolicy>
-
- <encoder>
- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <h4 class="doAnchor" name="FixedWindowRollingPolicy">FixedWindowRollingPolicy</h4>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.html">FixedWindowRollingPolicy</a></code>を使うと、固定幅アルゴリズムに従ってファイルの名前を変更することができます。
- </p>
-
- <p><span class="prop">fileNamePattern</span>オプションには、アーカイブファイル名のパターンを指定します。このオプションは必須<em>で</em>、パターン文字列中のどこかに整数トークンの<em>%i</em>を含めなければなりません。
- </p>
-
- <p><code>FixedWindowRollingPolicy</code>のプロパティは次のとおりです。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="fwrp">minIndex</span></td>
- <td><code>int</code></td>
- <td>
- <p>このオプションには固定幅の添字の下限値を指定します。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="fwrp">maxIndex</span></td>
- <td><code>int</code></td>
- <td>
- <p>このオプションには固定幅の添字の上限値を指定します。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="fwrp">fileNamePattern</span></td>
- <td><code>String</code></td>
- <td>
- <p>このオプションには<code>FixedWindowRollingPolicy</code>がログファイルをアーカイブするファイル名のパターン文字列を指定します。パターン文字列には<em>%i</em>を含めなければなりません。これは、現在の幅に追加する位置の添字になります。
- </p>
- <p>例えば、パターン文字列が<em>MyLogFile%i.log</em>、<em>minIndex</em>が1、<em>maxIndex</em>が3だとしたら、アーカイブファイル名は<em>MyLogFile1.log</em>、<em>MyLogFile2.log</em>、<em>MyLogFile3.log</em>のいずれかになります。
- </p>
- <p>自動ファイル圧縮を有効にする場合もこのプロパティで指定することになります。例えば、<span class="prop">fileNamePattern</span>に<em>MyLogFile%i.log.zip</em>が指定されている場合、アーカイブされたファイルは<em>zip形式</em>で圧縮されることになります。<em>gz形式</em>も有効です。
- </p>
- </td>
- </tr>
- </table>
-
- <p>固定幅切り替えポリシーでは、指定した窓の大きさによってはたくさんのファイル名を変更しなければなりません。ですので、あまりに大きな値を指定することは極力避けるようにしてください。利用者が指定した窓が大きすぎる場合、現在の実装は窓の大きさを自動的に20にしてします。
- </p>
-
- <p>固定幅切り替えポリシーの具体的な例を見ていきましょう。それぞれ、<span class="prop">minIndex</span>が<em>1</em>、<span class="prop">maxIndex</span>が<em>3</em>、<span class="prop">fileNamePattern</span>が<em>foo%i.log</em>、<span class="prop">file</span>プロパティが<em>foo.log</em>となっていることを想定しています。;
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>切り替え回数</th>
- <th>現在の出力対象</th>
- <th>アーカイブファイル</th>
- <th>説明</th>
- </tr>
- <tr>
- <td>0</td>
- <td>foo.log</td>
- <td>-</td>
- <td>まだ切り替えは発生していません。logbackは最初に指定されたファイルにログを出力しています。
- </td>
- </tr>
- <tr>
- <td>1</td>
- <td>foo.log</td>
- <td>foo1.log</td>
- <td>切り替えが発生しました。<em>foo.log</em>が<em>foo1.log</em>という名前に変更されました。新しく<em>foo.log</em>が作成され、現在の出力対象になりました。
- </td>
- </tr>
- <tr>
- <td>2</td>
- <td>foo.log</td>
- <td>foo1.log、foo2.log</td>
- <td>切り替えが発生しました。<em>foo1.log</em>が<em>foo2.log</em>という名前に変更され、<em>foo.log</em>が<em>foo1.log</em>という名前に変更されました。新しく<em>foo.log</em>が作成され、現在の出力対象になりました。
- </td>
- </tr>
- <tr>
- <td>3</td>
- <td>foo.log</td>
- <td>foo1.log、foo2.log、foo3.log</td>
- <td>切り替えが発生しました。<em>foo2.log</em>が<em>foo3.log</em>という名前に変更され、<em>foo1.log</em>が<em>foo2.log</em>という名前に変更され、<em>foo.log</em>が<em>foo1.log</em>という名前に変更されました。新しく<em>foo.log</em>が作成され、現在の出力対象になりました。
-
- </td>
- </tr>
- <tr>
- <td>4</td>
- <td>foo.log</td>
- <td>foo1.log、foo2.log、foo3.log</td>
- <td>以降の切り替えでは、最初にアーカイブ<em>foo3.log</em>を削除します。その他のファイルは、前のステップと同じように、添字を増やした名前に変更されます。以降は、常に1つのログファイル、3つのアーカイブファイルが存在することになります。
- </td>
- </tr>
- </table>
-
- <p><code>RollingFileAppender</code>と<code>FixedWindowRollingPolicy</code>の設定例を次に示します。<span class="prop">fileNamePattern</span>オプションに同じ情報が含まれているとはいえ、 <span class="prop">File</span>オプションは必須なので注意してください。
- </p>
-
- <p class="example">例:<code>RollingFileAppender</code>と<code>FixedWindowRollingPolicy</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-RollingFixedWindow.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-RollingFixedWindow.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-RollingFixedWindow');">Groovyとして表示</span>
- <pre id="logback-RollingFixedWindow" class="prettyprint source"><configuration>
- <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <b><file>test.log</file></b>
-
- <b><rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
- <fileNamePattern>tests.%i.log.zip</fileNamePattern>
- <minIndex>1</minIndex>
- <maxIndex>3</maxIndex>
- </rollingPolicy></b>
-
- <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
- <maxFileSize>5MB</maxFileSize>
- </triggeringPolicy>
- <encoder>
- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <h3 class="doAnchor" name="SizeAndTimeBasedFNATP">日時<b>と</b>サイズに基づいたログファイルのアーカイブ</h3>
-
- <p>基本的には日付でファイルをアーカイブしたいけど、後続処理ツールに指定できるログファイルにサイズ制限があるので、ログファイルのサイズも制限したいことがあるでしょう。そんなときは、logbackの配布物に含まれる<code>TimeBasedRollingPolicy</code>のサブコンポーネントである<code>SizeAndTimeBasedFNATP</code>を使うとよいでしょう。FNATP は File Naming And Triggering Policy の略です。</p>
-
- <p>日時とサイズに基づいてログファイルをアーカイブする設定ファイルの例を示します。</p>
-
- <p class="example">例:<code>SizeAndTimeBasedFNATP</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-sizeAndTime.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-sizeAndTime.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-sizeAndTime');">Groovyとして表示</span>
- <pre id="logback-sizeAndTime" class="prettyprint source"><configuration>
- <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <file>mylog.txt</file>
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <!-- rollover daily -->
- <fileNamePattern><b>mylog-%d{yyyy-MM-dd}.<span class="big">%i</span>.txt</b></fileNamePattern>
- <b><timeBasedFileNamingAndTriggeringPolicy</b>
- <b>class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"></b>
- <!-- or whenever the file size reaches 100MB -->
- <b><maxFileSize>100MB</maxFileSize></b>
- <b></timeBasedFileNamingAndTriggeringPolicy></b>
- </rollingPolicy>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
-
- <root level="DEBUG">
- <appender-ref ref="ROLLING" />
- </root>
-
-</configuration></pre>
-
- <p>"%d"トークンに加えて、"%i"トークンがあることに気づきましたか。次の切り替えタイミングがくるまでの間に、現在のログファイルが<span class="prop">maxFileSize</span>に指定したサイズを越えたら、添字を加算してアーカイブします。添字は0から始まります。</p>
-
- <p>日時とサイズに基づいたログファイルのアーカイブをしていても、古いアーカイブを削除することができます。残しておくアーカイブの数を<span class="prop">maxHistory</span>プロパティで指定しなければなりません。アプリケーションが停止してその後再起動した場合でも、正しい添字のファイルにログを出力します。
- </p>
-
- <h2>
- <a name="TriggeringPolicy" href="./appenders.html#TriggeringPolicy">トリガーポリシーについて</a>
- </h2>
-
- <p><code>RollingFileAppender</code>にファイルを切り替えるタイミングを通知するのが<a href="http://logback.qos.ch/xref/ch/qos/logback/core/rolling/TriggeringPolicy.html"><code>TriggeringPolicy</code></a>です。</p>
-
- <p><code>TriggeringPolicy</code>インターフェイスには1つだけメソッドが宣言されています。</p>
-
- <pre class="prettyprint source">package ch.qos.logback.core.rolling;
-
-import java.io.File;
-import ch.qos.logback.core.spi.LifeCycle;
-
-public interface TriggeringPolicy<E> extends LifeCycle {
-
- <b>public boolean isTriggeringEvent(final File activeFile, final <E> event);</b>
-}</pre>
-
- <p><code>isTriggeringEvent()</code>メソッドには、二つの引数があります。1つは現在有効なファイル、もう1つは処理中のロギングイベントです。これらのパラメータに基づいて、ファイルの切り替えをするべきかどうかを判断します。
- </p>
-
- <p>最もよく使われているトリガーポリシーは<code>TimeBasedRollingPolicy</code>です。これはローリングポリシーの別名です。他のローリングポリシーの説明と合わせて<a href="./appenders.html#TimeBasedRollingPolicy">説明</a>したとおりです。</p>
-
- <h4><a name="SizeBasedTriggeringPolicy" href="./appenders.html#SizeBasedTriggeringPolicy">SizeBasedTriggeringPolicy</a></h4>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.html">SizeBasedTriggeringPolicy</a></code>は現在有効なファイルのサイズを判断します。指定したサイズより大きくなった場合、<code>RollingFileAppender</code>に現在のファイルを切り替えるよう通知します。
- </p>
-
- <p><code>SizeBasedTriggeringPolicy</code>は<span class="prop">maxFileSize</span>パラメータだけを受け付けます。デフォルトは10MBです。</p>
-
- <p><span class="prop">maxFileSize</span>オプションはバイト、キロバイト、メガバイト、ギガバイト単位で指定できます。それぞれ<em>KB</em>、<em>MB</em>、<em>GB</em>という接尾辞を使うこともできます。たとえば、<em>5000000</em>、<em>5000KB</em>、<em>5MB</em>、<em>2GB</em>はすべて正しい値です。最初の三つは同じ値になります。
- </p>
-
- <p>ファイルサイズが5MBを越えたら切り替える場合の
-<code>RollingFileAppender</code>と<code>SizeBasedTriggeringPolicy</code>の設定例を見てみましょう。
- </p>
-
- <p class="example">例:<code>RollingFileAppender</code>と<code>SizeBasedTriggeringPolicy</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-RollingSizeBased.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-RollingSizeBased.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-RollingSizeBased');">Groovyとして表示</span>
- <pre id="logback-RollingSizeBased" class="prettyprint source"><configuration>
- <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <file>test.log</file>
- <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
- <fileNamePattern>test.%i.log.zip</fileNamePattern>
- <minIndex>1</minIndex>
- <maxIndex>3</maxIndex>
- </rollingPolicy>
-
- <b><triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
- <maxFileSize>5MB</maxFileSize>
- </triggeringPolicy></b>
- <encoder>
- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx -->
- <a name="Classic"></a>
- <h2>logback-classicモジュール</h2>
-
-
- <p>ロギングイベントはlogback-coreモジュールの中ではジェネリック型ですが、logback-classicでは<code>ILoggingEvent</code>のインスタンスになります。logback-classicでは、<code>ILoggingEvent</code>のインスタンスの具体的なパイプライン処理を行います。
-
- </p>
-
- <h3 class="doAnchor" name="SocketAppender">SocketAppenderとSSLSocketAppender</h3>
-
- <p>ここまでに紹介してきたアペンダーは、ローカルリソースだけにログを出力するものでした。対照的に、 <code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/SocketAppender.html">SocketAppender</a></code>はログをシリアライズした<code>ILoggingEvent</code>のインスタンスとしてリモートホストに送信するものとして設計されています。<code>SocketAppender</code>では、ロギングイベントを平文で送信します。<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/SSLSocketAppender.html">SSLSocketAppender</a></code>では、暗号化された安全なチャネルを介してロギングイベントを送信します。</p>
-
- <p>シリアライズされたロギングイベントの実際の型は、<code>ILoggingEvent</code>インターフェイスを実装した<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/spi/LoggingEventVO.html"><code>LoggingEventVO</code></a>です。ロギングイベントがどれだけ心配なのはわかりますが、リモートロギングが盗聴されることはありません。★受信したロギングイベントをデシリアライズしたら、ローカルで生成されたものとまったく同じように扱われます。それぞれのマシンで実行されている<code>SocketAppender</code>のインスタンスの出力書式がどれも同じになっていれば、中央ログサーバに直接ロギング出力を送りつけることができます。<code>SocketAppender</code>に割り当てられたレイアウトをリモートサーバに送ることはありません。シリアライズされたイベントを送信するからです。<code>SocketAppender< [...]
- </p>
-
- <p>ロギングイベントはネイティブのTCP実装によって自動的にバッファへ保存されます。つまり、リモートサーバへの通信速度がクライアントでロギングイベントを生成する速度より遅かったとしても、クライアントアプリケーションが通信速度に影響を受けることはない、ということです。通信速度がロギングイベントを生成する速度よりも遅ければ、クライアントは通信速度に合わせた速度でしか処理を進めることができません。極端な具体例ですが、リモートサーバへのネットワーク接続がダウンしている場合、最終的にクライアントはブロックしてしまいます。また、ネットワーク接続は生きててもリモートサーバがダウンしている場合、ロギングイベントはサーバが利用できないために破棄されてしまいますが、クライアントがブロックされることはありません。
- </p>
-
- <p>あらゆるロガーに<code>SocketAppender</code>が割り当てられていなかったとしても、コネクタースレッドが生きているかぎりGCに回収されることはありません。コネクタースレッドが死ぬのは、リモートサーバへの接続がダウンしたときだけです。このGCに伴う問題を回避するには、<code>SocketAppender</code>を明示的にクローズしなければなりません。長時間稼働するアプリケーションでは、非常に多くの<code>SocketAppender</code>のインスタンスを生成、破棄することになるので、このGCに伴う問題には注意してください。ほとんどのアプリケーションでは無視してもたいして問題になりません。<code>SocketAppender</code>をホストしているJVMが、<code>SocketAppender</code>をクローズする前に終了してしまうとしたら、それが明示的に行われるとしても、あるいは、GCの後であろうとも、通信用のパイプの中に残っていた未送信のデータは失われてしまうでしょう。これはWindowsベースの [...]
- </p>
-
- <p>リモートサーバは<span class="prop">remotehost</span>プロパティと<span class="prop">port</span>プロパティで指定します。
- <code>SocketAppender</code>のプロパティを表にまとめました。<code>SSLSocketAppender</code>にはこれよりも多くのプロパティが追加されています。詳しくは<a href="./usingSSL.html">SSLを使用する</a>の章を参照してください。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="socket">includeCallerData</span></td>
- <td><code>boolean</code></td>
- <td>
- <p><span class="prop" container="socket">includeCallerDataオプション</span>には真偽値を指定します。trueの場合、リモートホストでログの送信者情報が利用できるようになります。デフォルトでは発信者情報をサーバに送信しません。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="socket">port</span></td>
- <td><code>int</code></td>
- <td>
- <p>リモートサーバのポート番号です。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="socket">reconnectionDelay</span></td>
- <td><code><a href="http://logback.qos.ch/apidocs/ch/qos/logback/core/util/Duration.html">Duration</a></code></td>
- <td><span class="prop">reconnectionDelay</span>オプションには、待ち時間を表す文字列を指定します。たとえば、"10 seconds"と指定した場合、サーバへの接続が失敗するたびに10秒間待ってから、再接続を試みます。このオプションのデフォルト値は30秒です。0を指定すると再接続機能が無効になります。サーバへの接続が成功した場合、コネクタースレッドは存在しないはずなので注意してください。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="socket">queueSize</span></td>
- <td><code>int</code></td>
- <td>
- <p><span class="prop">queueSize</span>プロパティには、受信側に配信するために蓄えておくロギングイベントの数を、非負の整数で指定します。キューサイズが0の場合、イベントの配信は同期になります。キューサイズが0より大きい場合、キューに空きがあれば新しいロギングイベントはキューに入れられるようになります。キューの長さを0以外にすると、一時的なネットワークの遅延によって発生する配信の遅れを排除することができるので、性能が向上します。
- </p>
-
- <p><span class="prop">eventDelayLimit</span>プロパティのことも参照してください。</p>
-
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="socket">eventDelayLimit</span></td>
- <td><code><a href="http://logback.qos.ch/apidocs/ch/qos/logback/core/util/Duration.html">Duration</a></code></td>
- <td><span class="prop">eventDelayLimit</span>オプションには、"10 seconds"のような待ち時間を表す文字列を指定します。これは、ローカルキューが満杯になった際、蓄積されたロギングイベントを削除する前に待機する時間を表しています。リモートホストがロギングイベントを受信するのが継続的に遅い場合に発生する可能性があります。このオプションのデフォルト値は100ミリ秒です。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="socket">remoteHost</span></td>
- <td><code>String</code></td>
- <td>リモートサーバのホスト名です。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="socket">ssl</span></td>
- <td><code>SSLConfiguration</code></td>
- <td><code>SSLSocketAppender</code>だけがサポートするプロパティです。アペンダーから利用されるSSL設定を指定します。詳しくは<a href="./usingSSL.html">SSLを使用する</a>を参照してください。</td>
- </tr>
- </table>
-
- <h4>サーバ用のオプション</h4>
- <p>標準的なlogback-classicの配布物には、<code>SocketAppender</code>あるいは<code>SSLSocketAppender</code>からロギングイベントを受け取るための2つのサーバ用オプションが含まれています。</p>
- <ul>
- <li><code>ServerSocketReceiver</code>とそのSSL対応版の<code>SSLServerSocketReceiver</code>は、リモートホストのソケットアペンダーからロギングイベントを受け取るための受信用コンポーネントです。<em>logback.xml</em>で設定できるようになっています。設定内容については使用例と<a href="./receivers.html">レシーバーの章</a>を参照してください。
- </li>
- <li><code>SimpleSocketServer</code>とそのSSL対応版の<code>SimpleSSLSocketServer</code>は、スタンドアローンJavaアプリケーションから簡単に使うために用意されたものです。UnixシェルのCUI(コマンドラインインターフェイス)で設定できるようになっています。これらのアペンダーを設定したアプリケーションは、単純に<code>SocketAppender</code>または<code>SSLSocketAppender</code>のクライアントからロギングイベントが送信されてくるのを待ちます。受信したロギングイベントは、自身の設定に従ってロギングされます。使用例は次のとおりです。
- </li>
- </ul>
-
- <h4><a name="simpleSocketServer"></a> SimpleSocketServerの使い方</h4>
- <p><code>SimpleSocketServer</code>アプリケーションはコマンドライン引数を2つ取ります。<em>port</em>と<em>configFile</em>です。 <em>port</em>には待ち受けるポート番号を、<em>configFile</em>にはXML形式の設定ファイルを指定します。
- </p>
-
- <p><em>logback-examples</em>ディレクトリに移動してから、次のコマンドを実行すると<code>SimpleSocketServer</code>を開始できます。</p>
-
- <p class="source">java ch.qos.logback.classic.net.SimpleSocketServer 6000 \
- src/main/java/chapters/appenders/socket/server1.xml</p>
-
- <p>待ち受けるポート番号として6000、設定ファイルとして<em>server1.xml</em>を指定しています。この設定ファイルでは、ルートロガーに<code>ConsoleAppender</code>と<code>RollingFileAppender</code>を割り当てています。<code>SimpleSocketServer</code>を開始すれば、複数のロギングクライアントから<code>SocketAppender</code>を使ってロギングイベントを送信できるようになります。このマニュアルでは2つのクライアントを用意しています。<code>chapters.appenders.SocketClient1</code>と<code>chapters.appenders.SocketClient2</code>です。どちらもコンソールで利用者が何かキー入力するのを待つようになっています。利用者がキー入力したテキストはログレベルがDEBUGのロギングイベントに包まれてリモートサーバに送信されます。それぞれのクライアントの<code>Sock [...]
- </p>
-
- <p><code>SimpleSocketServer</code>をローカルホスト上で実行しているなら、次のようなコマンドで接続することができます。</p>
-
- <p class="source">java chapters.appenders.socket.SocketClient1 localhost 6000</p>
-
- <p>クライアントのコンソールに入力したテキストは、前の手順で開始した<code>SimpleSocketServer</code>のコンソールに1行ずつ出力されます。<code>SimpleSocketServer</code>を一旦停止してから再び開始しても、クライアント側では何もなかったかのように透過的に新しいサーバインスタンスに再接続します。しかし、切断中に発生したロギングイベントは単純に破棄されてしまい、取り返すことができません。
- </p>
-
- <p><code>SocketClient1</code>と違って、<code>SocketClient2</code>ではアプリケーション自体でlogbackを設定していません。XML形式の設定ファイルが必要です。設定ファイル<em>client1.xml</em>の内容は次のとおりです。<code>SocketAppender</code>を定義して、ルートロガーに割り当てています。
- </p>
-
- <p class="example">例:SocketAppenderの設定(<a href="http://logback.qos.ch/xref/chapters/appenders/socket/client1.xml">logback-examples/src/main/java/chapters/appenders/socket/client1.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('client1');">Groovyとして表示</span>
-<pre id="client1" class="prettyprint source"><configuration>
-
- <appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
- <remoteHost>${host}</remoteHost>
- <port>${port}</port>
- <reconnectionDelay>10000</reconnectionDelay>
- <includeCallerData>${includeCallerData}</includeCallerData>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SOCKET" />
- </root>
-
-</configuration></pre>
-
-<p>上記の設定スクリプトでは、<span class="prop">remoteHost</span>,
-<span class="prop">port</span>、<span class="prop">includeCallerData</span>の値が変数で指定されているのがわかりますか。これらの変数の値は、システムプロパティとして指定することができます。</p>
-
- <p class="source">java -Dhost=localhost -Dport=6000 -DincludeCallerData=false \
- chapters.appenders.socket.SocketClient2 src/main/java/chapters/appenders/socket/client1.xml</p>
-
- <p>このコマンドを実行すると、前の<code>SocketClient1</code>と同じ設定になります。
- </p>
-
- <p>ロギングイベントのシリアライズは非侵入型であることをもう一度アピールさせていただきます。デシリアライズされたロギングイベントは、普通のロギングイベントと全く同じ情報を持っています。したがって、自分が生成したロギングイベントであるかのように扱うことができるのです。ただし、デフォルトではシリアライズされたロギングイベントには送信者情報が含まれていません。この点を説明する例を示します。まず<code>SimpleSocketServer</code>を準備しましょう。</p>
-
- <p class="source"> java ch.qos.logback.classic.net.SimpleSocketServer 6000 \
- src/main/java/chapters/appenders/socket/server2.xml</p>
-
- <p>設定ファイル<em>server2.xml</em>では<code>ConsoleAppender</code>を定義しています。レイアウトには、他の情報と合わせて送信元のファイル名と行番号を指定しています。前のように設定ファイル<em>client1.xml</em>を引数として<code>SocketClient2</code>を起動します。サーバ側のコンソールに出力されたログには、送信元のファイル名と行番号の代わりに2つのクエスチョンマークが出力されているはずです。</p>
-
- <p class="source">2006-11-06 17:37:30,968 DEBUG [Thread-0] [?:?] chapters.appenders.socket.SocketClient2 - Hi</p>
-
- <p>この出力は簡単に変更できます。<code>SocketAppender</code>が送信者情報を含めるように設定するには、<span class="prop">includeCallerDataオプションにtrueを指定するだけです。</span>次のように実行すればよいです。</p>
-
- <pre class="source">java -Dhost=localhost -Dport=6000 -DincludeCallerData=true \
- chapters.appenders.socket.SocketClient2 src/main/java/chapters/appenders/socket/client1.xml</pre>
-
- <p>デシリアライズされたロギングイベントは、ローカルで生成されたロギングイベントと同じように扱うことができます。つまり、追加で何か処理するためにさらに別のリモートサーバに送信することができるのです。サーバを2つ用意して、最初のサーバがクライアントから受け取ったロギングイベントをトンネルのようにそのまま二つ目のサーバに転送するところを確認するのは、読者の演習課題にしておきます。
- </p>
-
- <h4><a name="simpleSSLSocketServer"></a> SimpleSSLSocketServerの使い方</h4>
-
- <p><code>SimpleSSLSocketServer</code>では、<code>SimpleSocketServer</code>と同様にコマンドライン引数で<em>port</em>と<em>configFile</em>を指定します。それに加えて、ロギングサーバのX.509証明書ファイルの場所とパスワードをシステムパラメータで指定しなければなりません。
- </p>
-
- <p><em>logback-examples</em>ディレクトリに移動してから、次のコマンドを実行すると<code>SimpleSSLSocketServer</code>を開始できます。</p>
-
- <p class="source">java -Djavax.net.ssl.keyStore=src/main/java/chapters/appenders/socket/ssl/keystore.jks \
- -Djavax.net.ssl.keyStorePassword=changeit \
- ch.qos.logback.classic.net.SimpleSSLSocketServer 6000 \
- src/main/java/chapters/appenders/socket/ssl/server.xml
- </p>
-
- <p>この例では、テストや検証で使う用のX.509証明書ファイルを指定して<code>SimpleSSLSocketServer</code>を実行しています。<strong>本番環境で<code>SimpleSSLSocketServer</code>を使う前に、ロギングサーバを識別するための正式なX.509証明書を手に入れなければなりません</strong> 。詳しくは<a href="./usingSSL.html">SSLを使用する</a>を参照してください。
- </p>
-
- <p>サーバの使用する設定ファイルのルート要素に<code>debug="true"</code>を指定しているので、サーバの開始ログを見ればSSLを設定していることがわかるでしょう。これはセキュリティポリシーが正しく設定されていることを確認するのに便利です。
- </p>
-
- <p>実行中の<code>SimpleSSLSocketServer</code>には、<code>SSLSocketAppender</code>を使って接続することができます。アペンダーの設定例は次のとおりです。</p>
-
- <p class="example">例:SSLSocketAppenderの設定(<a href="http://logback.qos.ch/xref/chapters/appenders/socket/ssl/client.xml">logback-examples/src/main/java/chapters/appenders/socket/ssl/client.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('sslclient');">Groovyとして表示</span>
-<pre id="sslclient" class="prettyprint source"><configuration debug="true">
-
- <appender name="SOCKET" class="ch.qos.logback.classic.net.SSLSocketAppender">
- <remoteHost>${host}</remoteHost>
- <port>${port}</port>
- <reconnectionDelay>10000</reconnectionDelay>
- <ssl>
- <trustStore>
- <location>${truststore}</location>
- <password>${password}</password>
- </trustStore>
- </ssl>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SOCKET" />
- </root>
-
-</configuration></pre>
-
- <p>前の例と同じく、<span class="prop">remoteHost</span>と<span class="prop">port</span>の値は変数になっています。また、<span class="prop">ssl</span>プロパティとネストしている<span class="prop">trustStore</span>プロパティが増えているので注意してください。locationとpasswordも変数になっています。例として用意したサーバが自己署名証明書を使っているので、これらの設定は必須です。<code>SSLSocketAppender</code>のSSL設定について、詳しくは<a href="./usingSSL.html">SSLを使用する</a>を参照してください。
- </p>
-
- <p>コマンドラインから、設定ファイルで使用している変数をシステムプロパティとして指定すれば、クライアントアプリケーションを実行することができます。</p>
-
- <p class="source">java -Dhost=localhost -Dport=6000 \
- -Dtruststore=file:src/main/java/chapters/appenders/socket/ssl/truststore.jks \
- -Dpassword=changeit \
- chapters.appenders.socket.SocketClient2 src/main/java/chapters/appenders/socket/ssl/client.xml
- </p>
-
- <p>前の例と同じく、クライアントアプリケーションのコンソールにメッセージを入力することができます。そうすると、メッセージは(安全な通信路上で)ロギングサーバに送信されます。そして、サーバ側のコンソールにログが出力されます。
- </p>
-
- <p>コマンドラインで指定した<em>truststore</em>プロパティには、信頼できるキーストアのURLを指定することに注意しましょう。<a href="./usingSSL.html">SSLを使用する</a>でも説明していますが、URLでクラスパス上のリソースを指定することもできます。</p>
-
- <p>前の例でサーバの起動時にいろいろと出力されているのと同じように、クライアントの設定ファイルのルート要素に<code>debug="true"</code>と指定しているので、クライアントの起動時にもSSL設定に関する情報が出力されています。ローカルポリシーの適合性の監査に役立つでしょう。
- </p>
-
-
- <h3 class="doAnchor" name="serverSocketAppender">ServerSocketAppenderとSSLServerSocketAppender</h3>
-
- <p>前に説明した<code>SocketAppender</code>コンポーネントとSSL対応版のSSLSocketAppenderは、ネットワークの向こう側のサーバにロギングイベントを配信するためのものです。アプリケーションがリモートロギングサーバに接続するために設計されています。場合によりますが、アプリケーションから特定のリモートロギングサーバへの接続を確立するのが不便だったり不可能だったりすることがあります。そういう場合のためにlogbackでは<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/server/ServerSocketAppender">ServerSocketAppender</a></code>が用意されています。
- </p>
-
- <p><code>ServerSocketAppender</code>は、特定のリモートロギングサーバとの接続を確立する代わりに、リモートクライアントからのTCPソケット接続を待ち受けます。アペンダーに送信されたロギングイベントは、接続しているクライアントに配布されます。接続しているクライアントがいなければ、ロギングイベントは<em>すぐに破棄されます</em>。
- </p>
-
- <p>logback は、普通の<code>ServerSocketAppender</code>だけでなく、SSL対応版の<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/server/SSLServerSocketAppender"><code>SSLServerSocketAppender</code></a>も用意しています。安全な、暗号化された通信路で接続したクライアントにロギングイベントを配布します。さらに、SSL対応版のアペンダーは、完全な相互認証をサポートしています。つまり、認証されたクライアントだけがロギングイベントを受信するためにアペンダーに接続できることが保証されるのです。
- </p>
-
- <p>通信路上でのロギングイベントの符号化方法は使用している<code>SocketAppender</code>に関わらず同一です。ロギングイベントは<code>ILoggingEvent</code>のインスタンスがシリアライズされたものです。接続を確立する方向だけが逆転しています。<code>SocketAppender</code>が特定のロギングサーバに対して接続を確立しようとする活性ピアとして振る舞うのに対して、<code>ServerSocketAppender</code>は受動的にクライアントからの接続を待ち受けます。</p>
-
- <p><code>ServerSocketAppender</code>の派生タイプは、logbackの他の<em>レシーバーコンポーネント</em>とは排他的に利用されることを想定しています。コンポーネントタイプに関する詳細については<a href="./receivers.html">レシーバー</a>を参照してください。</p>
-
- <p><code>ServerSocketAppender</code>の設定可能なプロパティを表にまとめました。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="serverSocketAppender">address</span></td>
- <td><code>String</code></td>
- <td>アペンダーが待ち受けるためのローカルネットワークインターフェイスに割り当てられたIPアドレス。このプロパティが指定されていない場合、アペンダーはすべてのネットワークインターフェイスで待ち受けます。</td>
- </tr>
- <tr>
- <td><span class="prop" container="serverSocketAppender">includeCallerData</span></td>
- <td><code>boolean</code></td>
- <td>
- <p>trueの場合、リモートホスト側で送信者情報が利用できるようになります。デフォルトでは、送信者情報はクライアントに送信されません。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="serverSocketAppender">port</span></td>
- <td><code>int</code></td>
- <td>
- <p>アペンダーが待ち受けるポート番号。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="serverSocketAppender">ssl</span></td>
- <td><code>SSLConfiguration</code></td>
- <td><code>SSLServerSocketAppender</code>でのみ使用出来るプロパティ。<a href="./usingSSL.html">SSLを使用する</a>で説明したように、アペンダーの使用するSSLの設定を指定します。</td>
- </tr>
- </table>
-
- <p><code>ServerSocketAppender</code>の使用例を次に示します。</p>
-
- <p class="example">例:ServerSocketAppenderの基本的な設定(<a href="http://logback.qos.ch/xref/chapters/appenders/socket/server4.xml">logback-examples/src/main/java/chapters/appenders/socket/server4.xml</a>)</p>
-<pre id="SocketReceiver" class="prettyprint source"><configuration debug="true">
- <appender name="SERVER"
- class="ch.qos.logback.classic.net.server.ServerSocketAppender">
- <port>${port}</port>
- <includeCallerData>${includeCallerData}</includeCallerData>
- </appender>
-
- <root level="debug">
- <appender-ref ref="SERVER" />
- </root>
-
-</configuration>
-</pre>
- <p>前の例との違いは、<em>class属性</em>に指定しているのが<code>SocketAppender</code>ではないこと、<span class="prop">remoteHost</span>プロパティが無いことだけなのがわかりましたか。このアペンダーはリモートロギングサーバに接続するのではなく、リモートホストからの接続を受動的に待ち受けます。
- </p>
-
- <p><code>SSLServerSocketAppender</code>の設定例は次のとおりです。</p>
-
- <p class="example">例:SSLServerSocketAppenderの基本的な設定(<a href="http://logback.qos.ch/xref/chapters/appenders/socket/server3.xml">logback-examples/src/main/java/chapters/appenders/socket/server3.xml</a>)</p>
-<pre id="SocketReceiver" class="prettyprint source"><configuration debug="true">
- <appender name="SERVER"
- class="ch.qos.logback.classic.net.server.SSLServerSocketAppender">
- <port>${port}</port>
- <includeCallerData>${includeCallerData}</includeCallerData>
- <ssl>
- <keyStore>
- <location>${keystore}</location>
- <password>${password}</password>
- </keyStore>
- </ssl>
- </appender>
-
- <root level="debug">
- <appender-ref ref="SERVER" />
- </root>
-
-</configuration>
-</pre>
-
- <p>前の例との主な違いは、<em>class属性</em>に<code>SSLServerSocketAppender</code>を指定していることと、ネストしている<span class="prop">ssl要素</span>があることです。この例ではアペンダー用のX.509証明書が置かれたキーストアが指定されています。SSLの設定について詳細は<a href="./usingSSL.html">SSLを使用する</a>を参照してください。
- </p>
-
- <p></p>
-
- <h3 class="doAnchor">SMTPAppender</h3>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/SMTPAppender.html"><code>SMTPAppender</code></a>は、一つ以上の固定サイズのバッファにロギングイベントを蓄積し、利用者が指定したイベントが発生したら適切なバッファを選んで内容をメールで送信します。SMTPによるメール送信は非同期で実行されます。デフォルトでは、ERRORレベルのロギングイベントがトリガとなってメールが送信されます。また、1つのバッファがすべてのロギングイベントから使用されます。
- </p>
-
- <p><code>SMTPAppender</code>の設定可能なプロパティを表にまとめました。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">smtpHost</span></td>
- <td><code>String</code></td>
- <td>SMTPサーバのホスト名。これは必須パラメータです。</td>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">smtpPort</span></td>
- <td><code>int</code></td>
- <td>SMTPサーバーの待ち受けポート番号。デフォルトでは25です。</td>
- </tr>
-
- <tr>
- <td><span class="prop" name="smtpTo">to</span></td>
- <td><code>String</code></td>
- <td>recipient のメールアドレスの<em>パターン</em>を指定します。指定したパターンは、送信されるメールそれぞれに対して、トリガとなったロギングイベントと共に評価されます。複数のrecipientを指定するときは、宛先アドレスをカンマ区切りにします。また、<code>to要素</code>を複数並べることもできます。
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">from</span></td>
- <td><code>String</code></td>
- <td><code>SMTPAppender</code>の送信するメールメッセージの originator を<a href="http://en.wikipedia.org/wiki/Email_address">一般的なメールアドレス形式</a>で指定します。送信者名を含めたい場合は "Adam Smith <smith at moral.org>" のようにします(XML形式の設定ファイルではブラケットを文字実態参照にします)。そうすると、メールでは "Adam Smith <smith at moral.org>" のようになります。
- </td>
- </tr>
- <tr>
- <td><span class="prop">subject</span></td>
- <td><code>String</code></td>
- <td>
- <p>メールの件名。<a href="./layouts.html#ClassicPatternLayout">PatternLayout</a>で利用できる全ての値を指定できます。レイアウトについては次の章で説明します。
- </p>
-
- <p>送信されるメールメッセージの件名には、メール送信をトリガしたロギングイベントを適用したパターンが指定されます。
- </p>
-
- <p><span class="prop">subject</span>オプションに指定されたパターンが "Log: %logger - %msg" で、"com.foo.Bar"ロガーが "Hello World" というメッセージのロギングイベントを発生して、このロギングイベントがトリガとなった場合、送信されるメールの件名は "Log: com.foo.Bar - Hello World" になるでしょう。
- </p>
-
- <p>デフォルトでは、"%logger{20} - %m" が設定されています。</p>
- </td>
-
- </tr>
- <tr>
- <td><span class="prop" container="smtp">discriminator</span></td>
- <td><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/sift/Discriminator.html">Discriminator</a></code></td>
- <td>
- <p><code>SMTPAppender</code>は、<span class="prop">弁別器</span>の返す値に基づいてバッファを選択して、発生したロギングイベントを振り分けます。デフォルトの弁別器は常に同じ値を返すので、全てのロギングイベントが常に同じバッファに振り分けられます。
- </p>
-
- <p>デフォルト以外の弁別器を指定すれば、特定のユーザー、ユーザーセッション、クライアントのIPアドレスに関連するロギングイベントを含むメールだけを送信することもできます。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" name="smtpAppender_Evaluator">evaluator</span></td>
- <td><code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/IEvaluator.html">IEvaluator</a></code></td>
- <td>
- <p>このオプションを指定するには、新しく<code>EventEvaluator要素</code>を宣言します。<code>SMTPAppender</code>の<code>Evaluator</code>として使いたいクラスの完全クラス名を、<span class="attr">class属性</span>に指定します。
- </p>
-
-
- <p>このオプションを指定しなかった場合、<code>SMTPAppender</code>は<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/OnErrorEvaluator.html">OnErrorEvaluator</a>のインスタンスを使用します。これは<em>ERROR</em>以上のロギングイベントが発生したらメール送信をトリガします。
- </p>
-
- <!--
- <p><code>EventEvaluator</code> objects are subclasses of the
- <code>JaninoEventEvaluatorBase</code> which depends on
- Janino. See the <a href="../dependencies.html">dependencies
- page</a> for more information.
- </p>
- -->
-
- <p>logback の配布物には他の評価器もいくつか含まれています。<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/OnMarkerEvaluator.html"><code>OnMarkerEvaluator</code></a>(詳しくは後述します)と、より強力な評価器の<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/JaninoEventEvaluator.html"><code>JaninoEventEvaluator</code></a>です。後者については<a href="./filters.html#evalutatorFilter">別の章</a>で紹介します。最新バージョンの配布物にはさらに強力な評価器である<a href="./filters.html#GEventEvaluator"><code>GEventEvaluator</code></a>が含まれます。
- </p>
-
- </td>
- </tr>
-
- <tr>
- <td valign="top"><span class="prop" container="smtp">cyclicBufferTracker</span></td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/CyclicBufferTracker.html"><code>CyclicBufferTracker</code></a>
- </td>
- <td>
- <p>名前が示す通り、<code>CyclicBufferTracker</code>クラスは循環バッファを追跡します。追跡は、前に説明した<span class="prop">弁別器</span>の返すキーに基づいて行われます。
- </p>
- <p><span class="prop">cyclicBufferTracker</span>指定しなかった場合、自動的に<a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/CyclicBufferTrackerImpl.html">CyclicBufferTrackerImpl</a>のインスタンスを生成して使用します。デフォルトで256個のロギングイベントを循環バッファに保持します。<span class="prop">bufferSize</span>オプションを指定してサイズを変更することもできます(下記参照)。</p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="smtp">username</span></td>
- <td><code>String</code></td> <td>平文のパスワード認証をするときに使用するユーザー名。デフォルトではnullです。</td>
- </tr>
- <tr class="alt">
- <td><span class="prop" container="smtp">password</span></td>
- <td><code>String</code></td>
- <td>平文のパスワード認証をするときに使用するパスワード。デフォルトではnullです。
-
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="smtp">STARTTLS</span> </td>
- <td><code>boolean</code></td>
- <td>trueを指定すると、サーバがサポートしているならSSL接続に切り替えるため、STARTTLSコマンドを発行します。接続が確立した時点では暗号化されていないので注意してください。デフォルトではfalseに設定されています。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="smtp">SSL</span></td>
- <td><code>boolean</code></td> <td>trueを指定するとサーバにSSL接続をします。デフォルトではfalseです。</td>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">charsetEncoding</span></td>
- <td><code>String</code></td>
- <td>送信されるメッセージは指定された<a href="https://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html">文字セット</a>でエンコードされます。デフォルトの文字セットは"UTF-8"ですが、ほとんどの場合十分でしょう。
- </td>
- </tr>
-
-
- <tr>
- <td><span class="prop" container="smtp">localhost</span></td>
- <td><code>String</code></td>
- <td>SMTPクライアントのホスト名が正しく設定されていない場合(例えば、ホスト名が完全修飾名ではない場合)、SMTPサーバの中にはそういうクライアントから送信された HELO/EHLO コマンドを拒否することがあります。この問題を解決するには、クライアントのホスト名として、<span class="prop">localhost</span>に完全修飾名を指定することができます。<a href="http://javamail.kenai.com/nonav/javadocs/com/sun/mail/smtp/package-summary.html">com.sun.mail.smtp</a>パッケージのドキュメントで説明されている "mail.smtp.localhost" パラメータも参考にしてください。</td>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">asynchronousSending</span></td>
- <td><code>boolean</code></td>
- <td>メール送信を非同期で行うかどうかを指定します。デフォルトはtrueです。しかし、非同期送信が不適切な場合もあります。たとえば、あなたのアプリケーションで致命的なエラーが発生した際、<code>SMTPAppender</code>でアラートメールを送信してから終了するとしても、その仕事を任されたスレッドにはメールを送信する時間が残されていないからです。そういう場合は同期的にメール送信をするためfalseを指定しましょう。
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">includeCallerData</span></td>
- <td><code>boolean</code></td>
- <td>デフォルトは<code>false</code>です。<span class="prop">asynchronousSending</span>が有効でログに送信者情報を含めたいときは<code>true</code>を指定しなければなりません。</td>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">sessionViaJNDI</span></td>
- <td><code>boolean</code></td>
- <td><code>javax.mail.Session</code>を使用してメールを送信します。デフォルトは<code>false</code>なので、<code>SMTPAppender</code>は利用者の指定した設定に従って<code>javax.mail.Session</code>インスタンスを構築します。<code>true</code>を指定するとJNDIから<code>javax.mail.Session</code>インスタンスを取得します。<span class="prop">jndiLocation</span>プロパティも参照してください。
-
- <p><span class="label">注意</span>JNDIから<code>Session</code>を取得すれば、設定する場所は減るし、同じ情報をあちこちで指定しなくてもよくなります。そうすると、アプリケーションはより<a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>になります。TomcatでJNDIリソースを設定する方法については<a href="http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html#JavaMail_Sessions">JNDIリソースハウツー</a>を参照してください。JNDIから<code>Session</code>オブジェクトを取得する場合は、ドキュメントに記載されているように、<em>mail.jar</em>と<em>activation.jar</em>をWebアプリケーションの<em>WEB-INF/lib</em>フォルダから取り除 [...]
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="smtp">jndiLocation</span></td>
- <td><code>String</code></td>
- <td>JNDIのjavax.mail.Sessionの位置を指定します。デフォルトは<span style="white-space:nowrap">"java:comp/env/mail/Session"</span>です。
- </td>
- </tr>
-
- </table>
-
- <p><code>SMTPAppender</code>は循環バッファで最新の256個のロギングイベントだけを保持します。バッファが一杯になったら古いロギングイベントを捨てます。したがって、<code>SMTPAppender</code>からメールで送信するロギングイベントの最大値は256個になります。つまり、アプリケーションコンテキストに妥当なメモリ量を割り当てられるよう、メモリ要件に合わせて制限できるということです。
- </p>
-
- <p><code>SMTPAppender</code>はJavaMail APIにも依存しています。テストされているJavaMail APIのバージョンは1.4です。JavaMail APIにはJavaBeans Activation フレームワークが必要です。<a href="http://java.sun.com/products/javamail/">JavaMail API</a>と<a href="http://java.sun.com/beans/glasgow/jaf.html">JavaBeans Activation フレームワーク</a>はそれぞれのウェブサイトからダウンロードすることができます。以降の例を試す前に、クラスパス上にこれらのjarファイルが配置されていることを確かめてください。
- </p>
-
- <p>サンプルアプリケーションでは、<a href="http://logback.qos.ch/xref/chapters/appenders/mail/EMail.html"><code>chapters.appenders.mail.EMail</code></a>がいくつかのログメッセージを生成したあとで、エラーメッセージを1つ生成しています。このアプリケーションの引数は二つあります。一つ目のパラメータは生成するロギングイベントの数となる整数値です。二つ目のパラメータはlogbackの設定ファイルです。<em>EMail</em>アプリケーションが最後に生成するロギングイベントのログレベルはERRORなので、メール送信をトリガします。
- </p>
-
- <p><code>Email</code>アプリケーションから使う設定ファイルは次のとおりです。</p>
-
- <p class="example">例:<code>SMTPAppender</code>の設定例(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/mail1.xml">logback-examples/src/main/java/chapters/appenders/mail/mail1.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('mail1');">Groovyとして表示</span>
- <pre id="mail1" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <smtpHost>ADDRESS-OF-YOUR-SMTP-HOST</smtpHost>
- <to>EMAIL-DESTINATION</to>
- <to>ANOTHER_EMAIL_DESTINATION</to> <!-- additional destinations are possible -->
- <from>SENDER-EMAIL</from>
- <subject>TESTING: %logger{20} - %m</subject>
- <layout class="ch.qos.logback.classic.PatternLayout">
- <pattern>%date %-5level %logger{35} - %message%n</pattern>
- </layout>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="EMAIL" />
- </root>
-</configuration></pre>
-
- <p>上記の設定ファイルで<code>chapters.appenders.mail.Email</code>アプリケーションを動かしてみる前に、smtpHostや<span class="prop">to</span>や<span class="prop">from</span>へ、あなたの環境に適した値を指定しなければなりません。設定ファイルに正しい値を指定したら次のコマンドを実行しましょう。</p>
-
-<div class="source"><pre>java chapters.appenders.mail.EMail 100 src/main/java/chapters/appenders/mail/mail1.xml</pre></div>
-
- <p>指定したrecipientには<code>PatternLayout</code>で指定したとおりに書式化された100個のロギングイベントが含まれたメールが届くはずです。Mozilla Thunderbird で受信したメールを開いたところを示します。
- </p>
-
- <p><img src="images/chapters/appenders/smtpAppender1.jpg" alt="結果の電子メール"></p>
-
- <p>設定ファイル<em>mail2.xml</em>では、<span class="prop">smtpHost</span>や<span class="prop">to</span>や<span class="prop">from</span>が変数で指定されています。<em>mail2.xml</em>の大事な部分を次に示します。
- </p>
-
- <pre class="prettyprint source"><appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <smtpHost>${smtpHost}</smtpHost>
- <to>${to}</to>
- <from>${from}</from>
- <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
-</appender></pre>
-
- <p>コマンドラインで必要なパラメータを指定します。</p>
-
-<div class="source"><pre>java -Dfrom=source at xyz.com -Dto=recipient at xyz.com -DsmtpHost=some_smtp_host \
- chapters.appenders.mail.EMail 10000 src/main/java/chapters/appenders/mail/mail2.xml
-</pre></div>
-
- <p>値はあなたの環境で利用できるものに置き換えてください。
- </p>
-
- <p>最後の例では、<code>PatternLayout</code>が<code>HTMLLayout</code>になっていました。これはログの内容をHTMLのテーブルとして書式化します。列の並びと順番は変更することができます。CSSも変更できます。<a href="./layouts.html#ClassicHTMLLayout">HTMLLayout</a>について詳しくはドキュメントを参照してください。
- </p>
-
- <p>循環バッファのサイズが256なので、recipientが受け取るメールでは256個のロギングイベントが綺麗にHTMLのテーブルに整形されるようになっています。<code>chapters.appenders.mail.Email</code>アプリケーションを実行して10000件のロギングイベントを生成しても、送信されるメールには最新の256件しか含まれないことになるので気をつけてください。
- </p>
-
- <p><img src="images/chapters/appenders/smtpAppender2.jpg" alt="第2回のメール"></p>
-
- <p>Mozilla ThunderbirdやEudoraやMS Outlookといったメールクライアントは、HTML形式のメールでもCSSをわりと上手く処理します。ですが、勝手にHTMLを平文テキストにダウングレードすることがあります。例えば、Thunderbird でHTMLメールを表示するには、"表示→メッセージ本文→オリジナルのHTML" でオプションを指定しなければなりません。Yahoo!メールはHTMLメールをサポートしており、CSSの対応具合はピカ一です。一方、Gmailは普通のHTMLテーブルはそのまま表示してくれますが、内部CSSによる整形はしてくれません。GmailはインラインCSSをサポートしていますが、インラインCSSを使うとHTMLソースコードが膨れ上がってしまうので、<code>HTMLLayout</code>ではインラインCSSを使用しません。</p>
-
- <h3 class="doAnchor" name="cyclicBufferSize">カスタムバッファサイズ</h3>
-
- <p>デフォルトでは、<code>SMTPAppender</code>から送信されるメッセージには最大で256件のロギングメッセージが含まれています。次の例に示すように、別のバッファサイズを指定することができます。
- </p>
-
- <p class="example">例: バッファサイズを変更した<code>SMTPAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/customBufferSize.xml">logback-examples/src/main/java/chapters/appender/mail/customBufferSize.xml</a>)</p>
- <pre class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <smtpHost>${smtpHost}</smtpHost>
- <to>${to}</to>
- <from>${from}</from>
- <subject>%logger{20} - %m</subject>
- <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
-
- <b><cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker"></b>
- <b><!-- send just one log entry per email --></b>
- <b><bufferSize>1</bufferSize></b>
- <b></cyclicBufferTracker></b>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="EMAIL" />
- </root>
-</configuration> </pre>
-
-
- <h3 class="doAnchor">トリガイベント</h3>
-
- <p>Evaluatorプロパティが指定されなかったら、<code>SMTPAppender</code>はデフォルトで<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/OnErrorEvaluator.html">OnErrorEvaluator</a>を使用して、ERRORレベルのロギングイベントの発生をトリガとしてメールを送信する。エラーの発生に応じて、メール送信をトリガするのはそれなりに合理的ですが、<code>EventEvaluator</code>インターフェイスの別の実装を指定すればデフォルトの振る舞いを上書きすることができます。
- </p>
-
- <p><code>SMTPAppender</code>は<code>evaluate()</code>メソッドを呼び出すことで、受け取ったロギングイベントを評価器に渡します。そのロギングイベントがメール送信をトリガするものなのか、単に循環バッファに入れておくだけでいいのかを判定するためです。評価器が評価した結果が真なら、メールを送信します。<code>SMTPAppender</code>の保持する評価器オブジェクトは1つだけです。このオブジェクトは、自身の内部状態を管理することができます。わかりにくいので、<code>CounterBasedEvaluator</code>クラスのコードで説明します。これはロギングイベントが1024件発生するたびにメール送信をトリガします。
- </p>
-
- <p class="example">例: 1024件ごとに評価値<code>true</code>を返す<code>EventEvaluator</code>インターフェイスの実装(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/CounterBasedEvaluator.java">logback-examples/src/main/java/chapters/appenders/mail/CounterBasedEvaluator.java</a>)</p>
-
- <pre class="prettyprint source">package chapters.appenders.mail;
-
-import ch.qos.logback.core.boolex.EvaluationException;
-import ch.qos.logback.core.boolex.EventEvaluator;
-import ch.qos.logback.core.spi.ContextAwareBase;
-
-public class CounterBasedEvaluator extends ContextAwareBase implements EventEvaluator {
-
- static int LIMIT = 1024;
- int counter = 0;
- String name;
-
- <b>public boolean evaluate(Object event) throws NullPointerException,
- EvaluationException {
- counter++;
-
- if (counter == LIMIT) {
- counter = 0;
-
- return true;
- } else {
- return false;
- }
- }</b>
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-}</pre>
-
- <p>このクラスは<code>ContextAwareBase</code>を継承して、<code>EventEvaluator</code>インターフェイスを実装しているのがわかるでしょうか。こうすれば、利用者は<code>EventEvaluator</code>としての中心機能に集中することができるし、基底クラスを使って共通する機能を提供できるようになります。
- </p>
-
- <p><code>SMTPAppender</code>の<span class="prop">evaluator</span>オプションを指定するということは、カスタム評価器を使うということです。次の設定ファイルではルートロガーに<code>SMTPAppender</code>を割り当てています。SMTPAppenderでは、<code>CounterBasedEvaluator</code>を評価器として指定しています。
- </p>
-
- <p class="example">例: <code>SMTPAppender</code>とカスタム<code>評価器</code>とバッファサイズの設定例(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/mail3.xml">logback-examples/src/main/java/chapters/appenders/mail/mail3.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('mail3');">Groovyとして表示</span>
- <pre id="mail3" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <b><evaluator class="chapters.appenders.mail.CounterBasedEvaluator" /></b>
- <smtpHost>${smtpHost}</smtpHost>
- <to>${to}</to>
- <from>${from}</from>
- <subject>%logger{20} - %m</subject>
-
- <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="EMAIL" />
- </root>
-</configuration></pre>
-
-
- <h3 class="doAnchor" name="OnMarkerEvaluator">マーカーに基づくトリガ</h3>
-
- <p>全てのERRORレベルのロギングイベントをトリガとしてメールを送信するデフォルトのポリシーは合理的ではありますが、メールを送信する機会が多すぎると対象になっているユーザのメールボックスを埋め尽くしてしまいます。logback の配布物には<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/OnMarkerEvaluator.html">OnMarkerEvaluator</a>というトリガポリシーも含まれています。これはマーカーに基づいてトリガするものです。原則として、利用者が指定したマーカーのロギングイベントが発生したときだけメール送信がトリガされます。次の例を見ればどういう動き方をするのかはっきりするでしょう。
- </p>
-
- <p><a href="http://logback.qos.ch/xref/chapters/appenders/mail/Marked_EMail.html">Marked_EMailの</a>アプリケーションには、ERRORレベルを含むいくつものロギング式があります。そのうちで、一つのロギング式にだけマーカーが指定されています。該当するコードは次のとおりです。
- </p>
-
- <pre class="prettyprint source">Marker notifyAdmin = MarkerFactory.getMarker("NOTIFY_ADMIN");
-logger.error(<b>notifyAdmin</b>,
- "This is a serious an error requiring the admin's attention",
- new Exception("Just testing"));</pre>
-
- <p>次の設定ファイルは、マーカーとしてNOTIFY_ADMINあるいはTRANSACTION_FAILUREを指定されたロギングイベントが発生したときだけメール送信をトリガするものです。
- </p>
-
- <p class="example">例: <code>OnMarkerEvaluator</code>を指定した<code>SMTPAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/mailWithMarker.xml">logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('mailWithMarker');">Groovyとして表示</span>
- <pre id="mailWithMarker" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <b><evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
- <marker>NOTIFY_ADMIN</marker>
- <!-- you specify add as many markers as you want -->
- <marker>TRANSACTION_FAILURE</marker>
- </evaluator></b>
- <smtpHost>${smtpHost}</smtpHost>
- <to>${to}</to>
- <from>${from}</from>
- <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
- </appender>
-
- <root>
- <level value ="debug"/>
- <appender-ref ref="EMAIL" />
- </root>
-</configuration></pre>
-
- <p>次のコマンドを実行してみましょう。</p>
-
- <pre class="source">java -Dfrom=source at xyz.com -Dto=recipient at xyz.com -DsmtpHost=some_smtp_host \
- chapters.appenders.mail.Marked_EMail src/main/java/chapters/appenders/mail/mailWithMarker.xml</pre>
-
-
- <h4 class="doAnchor" name="marker_JaninoEventEvaluator">JaninoEventEvaluatorを使ったマーカーに基づくトリガ</h4>
-
- <p>マーカーだけを対象にした<code>OnMarkerEvaluator</code>の代わりに、より汎用的な<a href="./filters.html#JaninoEventEvaluator"><code>JaninoEventEvaluator</code></a>を使うことができますし、それ以上に強力な<a href="./filters.html#GEventEvaluator"><code>GEventEvaluator</code></a>を使うことも出来ます。たとえば、次の設定ファイルは<code>OnMarkerEvaluator</code>の代わりに<code>JaninoEventEvaluator</code>を指定した以外は前の設定ファイルとまったく同じ内容になります。
- </p>
-
- <p class="example">例: <code>JaninoEventEvaluator</code>を指定した<code>SMTPAppender</code>の設定(logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker_Janino.xml)</p>
-
- <span class="asGroovy" onclick="return asGroovy('mailWithMarker_Janino');">Groovyとして表示</span>
- <pre id="mailWithMarker_Janino" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
- <expression>
- (marker != null) &&
- (marker.contains("NOTIFY_ADMIN") || marker.contains("TRANSACTION_FAILURE"))
- </expression>
- </evaluator>
- ... same as above
- </appender>
-</configuration></pre>
-
- <h4 class="doAnchor" name="marker_GEventEvaluator">GEventEvaluatorを使ったマーカーに基づくトリガ</h4>
-
- <p><a href="./filters.html#GEventEvaluator">GEventEvaluator</a>を使っている以外は前の例と同じ内容です。</p>
-
- <p class="example">例:<code>GEventEvaluator</code>を指定したSMTPAppenderの設定(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/mailWithMarker_GEvent.xml">logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker_GEvent.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('mailWithMarker_GEventEvaluator');">Groovyとして表示</span>
-
- <pre id="mailWithMarker_GEventEvaluator" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator">
- <expression>
- e.marker?.contains("NOTIFY_ADMIN") || e.marker?.contains("TRANSACTION_FAILURE")
- </expression>
- </evaluator>
- ... same as above
- </appender>
-</configuration></pre>
-
- <p>マーカーを指定されなかったロギングイベントの場合、e.markerはnullになるので注意してください。この例ではGroovyの<a href="http://groovy.codehaus.org/Null+Object+Pattern">安全なデリファレンス演算子</a>である .? 演算子を使っています。
- </p>
-
-
- <h3 class="doAnchor" name="smtpAuthentication">認証/ STARTTLS / SSL</h3>
-
- <p><code>SMTPAppender</code>では、平文のユーザーパスワード認証だけでなく、STARTTLSとSSLプロトコルの両方をサポートしています。STARTTLSとSSLの違いは、STARTTLSでは接続を確立するときは暗号化されないこと、そして、クライアントがSTARTTLSコマンドを発行してサーバがサポートしている場合はSSL接続に切り替えることです。SSLでは始めから通信が暗号化されます。
- </p>
-
- <h3>GmailにSSLで接続するSMTPAppenderの設定</h3>
-
- <p>次の例はGmailにSSLプロトコルで接続する<code>SMTPAppender</code>の設定です。</p>
-
- <p class="example">例:GmailにSSLで接続する<code>SMTPAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/gmaliSSL.xml">logback-examples/src/main/java/chapters/appenders/mail/gmaliSSL.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('gmailSSLExample');">Groovyとして表示</span>
- <pre id="gmailSSLExample" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <b><smtpHost>smtp.gmail.com</smtpHost></b>
- <b><smtpPort>465</smtpPort></b>
- <b><SSL>true</SSL></b>
- <b><username>YOUR_USERNAME at gmail.com</username></b>
- <b><password>YOUR_GMAIL_PASSWORD</password></b>
-
- <to>EMAIL-DESTINATION</to>
- <to>ANOTHER_EMAIL_DESTINATION</to> <!-- additional destinations are possible -->
- <from>YOUR_USERNAME at gmail.com</from>
- <subject>TESTING: %logger{20} - %m</subject>
- <layout class="ch.qos.logback.classic.PatternLayout">
- <pattern>%date %-5level %logger{35} - %message%n</pattern>
- </layout>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="EMAIL" />
- </root>
-</configuration></pre>
-
-
- <h3 class="doAnchor" name="gmailSTARTTLS">STARTTLSでGmailに接続するSMTPAppenderの設定</h3>
-
- <p>次の例はGmailにSTARTTLSで接続する<code>SMTPAppender</code>の設定です。
-</p>
-
- <p class="example">例:GmailにSTARTTLSで接続する<code>SMTPAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/gmailSTARTTLS.xml">logback-examples/src/main/java/chapters/appenders/mail/gmailSTARTTLS.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('gmailSTARTTLSExample');">Groovyとして表示</span>
- <pre id="gmailSTARTTLSExample" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <smtpHost>smtp.gmail.com</smtpHost>
- <smtpPort>587</smtpPort>
- <STARTTLS>true</STARTTLS>
- <username>YOUR_USERNAME at gmail.com</username>
- <password>YOUR_GMAIL_xPASSWORD</password>
-
- <to>EMAIL-DESTINATION</to>
- <to>ANOTHER_EMAIL_DESTINATION</to> <!-- additional destinations are possible -->
- <from>YOUR_USERNAME at gmail.com</from>
- <subject>TESTING: %logger{20} - %m</subject>
- <layout class="ch.qos.logback.classic.PatternLayout">
- <pattern>%date %-5level %logger - %message%n</pattern>
- </layout>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="EMAIL" />
- </root>
-</configuration></pre>
-
-
- <h3 class="doAnchor" name="smtpDiscriminator">MDCDiscriminatorを指定したSMTPAppenderの設定</h3>
-
-
- <p>前述したように、<code>SMTPAppender</code>にデフォルト以外の弁別器を指定すれば、特定のユーザ、ユーザセッション、送信元のIPアドレスを含むロギングイベントが発生した場合にだけメールメッセージを生成することができます。
- </p>
-
- <p>次の例は<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/sift/MDCBasedDiscriminator.html">MDCBasedDiscriminator</a>に"req.remoteHost"というキーを指定したものです。値として、架空のWebアプリケーションにアクセスしてきたクライアントのリモートホストのIPアドレスが設定されることを想定しています。Webアプリケーションなら<a href="./mdc.html#mis">MDCInsertingServletFilter</a>使ってMDCに値を設定することができます。
- </p>
-
- <p class="example">例:MDCDiscriminatorを指定した<code>SMTPAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/mail/mailWithMDCBasedDiscriminator.xml">logback-examples/src/main/java/chapters/appenders/mail/mailWithMDCBasedDiscriminator.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('mailWithMDCBasedDiscriminator');">Groovyとして表示</span>
- <pre id="mailWithMDCBasedDiscriminator" class="prettyprint source"><configuration>
- <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <smtpHost>ADDRESS-OF-YOUR-SMTP-HOST</smtpHost>
- <to>EMAIL-DESTINATION</to>
- <from>SENDER-EMAIL</from>
-
- <b><discriminator class="ch.qos.logback.classic.sift.MDCBasedDiscriminator"></b>
- <b><key>req.remoteHost</key></b>
- <b><defaultValue>default</defaultValue></b>
- <b></discriminator></b>
-
- <subject>${HOSTNAME} -- %X{req.remoteHost} %msg"</subject>
- <layout class="ch.qos.logback.classic.html.HTMLLayout">
- <pattern>%date%level%thread%X{req.remoteHost}%X{req.requestURL}%logger%msg</pattern>
- </layout>
- </appender>
-
- <root>
- <level level="DEBUG"/>
- <appender-ref ref="EMAIL" />
- </root>
-</configuration></pre>
-
- <p>こうすると、<code>SMTPAppender</code>の送信するメールそれぞれに<em>固有</em>のIPアドレスが記録されるようになるので、問題解決に役立ちます。
- </p>
-
- <h4 class="doAnchor" name="bufferManagement">高負荷システムにおけるバッファ管理(★要見直し)</h4>
-
- <p>内部的な事情ですが、弁別器が返す値ごとに循環バッファが作成されます。しかし、ほとんどの場合<span class="prop">maxNumberOfBuffers</span>(デフォルト値は64)はそのままです。バッファの数が<span class="prop">maxNumberOfBufferes</span>を越えてしまうと、一番最近更新されたバッファはすぐに自動的に破棄されてしまいます。もう一つの予防策として、直近の30分間に更新されなかったバッファはやはり自動的に破棄されてしまいます。</p>
-
- <p>毎分大量のトランザクションを処理するシステムでは、<span class="prop">maxNumberOfBuffers</span>(デフォルト値は64)が小さいと送信するメールに含まれるロギングイベントの数がとても少なくなってしまいます。大量のトランザクションが発生する場合、同じトランザクションには1つ以上のバッファが関連付けられてしまいます。弁別器が同じトランザクションには同じ値を返すので、バッファの破棄と生成が繰り返されてしまうからです。高負荷システムであっても、循環バッファの上限は<span class="prop">maxNumberOfBufferes</span>によって制御されてしまうので注意してください。
- </p>
-
- <p>ヨーヨー効果を避けるため、<code>SMTPAppender</code>は"FINALIZE_SESSION"というマーカーの指定されたロギングイベントを見つけたら、そのロギングイベントに対して弁別器の返す値に関連付けられたバッファを直ちに開放するようになっています。これにより、トランザクションの終了時に適切にバッファを廃棄できるようになります。そうすれば、<span class="prop">maxNumberOfBuffers</span>には、安全のためより大きな値の512や1024を指定することができます。メモリ不足の危険性はありません。
- </p>
-
- <p>循環バッファを管理するために協調的に機能する、3つの相補的な仕組みがあります。これらの仕組みが、高負荷システムであっても常に有効なバッファが利用できることを保証するのです。</p>
-
- <!-- =========================================================== -->
- <!-- =========================================================== -->
-
-
- <h3 class="doAnchor" name="DBAppender">DBAppender</h3>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/db/DBAppender.html"><code>DBAppender</code></a>はデータベース上の3つのテーブルに、Javaプログラミング言語に依存しない形式のロギングイベントを登録します。
- </p>
-
- <p>3つのテーブルとは、<em>logging_event</em>、<em>logging_event_property</em>、<em>logging_event_exception</em>です。<code>DBAppender</code>を使う前に事前に用意しておかなければなりません。logack の配布物にテーブルを作成するSQLスクリプトが含まれています。フォルダの場所は <em>logback-classic/src/main/java/ch/qos/logback/classic/db/script</em>です。一般的なデータベースそれぞれのスクリプトが用意されています。あなたの使用するデータベース用のスクリプトが無かったとしても、既存のスクリプトを参考にすれば自分で作るのは簡単です。logback の開発メンバーに教えてくれれば、喜んで今後のリリースに含めるようにします。
- </p>
-
- <p>あなたが使用しているJDBCドライバが、JDBC3.0で導入された<code>getGeneratedKeys()</code>メソッドをサポートしているなら、紹介したスクリプトでテーブルを作ること以外に必要な作業はありません。そうはいっても、データベースに対応する<code>SQLDialect</code>を指定しなければなりません。今のところ logback が対応しているSQL方言は、H2、HSQL、MS SQLServer、MySQL、Oracle、PostgreSQL、SQLite、Sybase です。</p>
-
- <p>データベースの種類と、<code>getGeneratedKeys()</code>メソッドの対応状況を表にまとめました。
- </p>
-
- <table class="bodyTable striped" border="0" cellpadding="4">
- <tr>
- <th>データベースの種類</th>
- <th>テストしたバージョン</th>
- <th>テストしたJDBCドライバのバージョン</th>
- <th>{0}getGeneratedKeys(){/0}メソッド
-の対応状況<br>
- </th>
-
- <th>logbackがSQL方言を提供しているかどうか
-<br></th>
- </tr>
-
- <tr>
- <td>DB2</td>
- <td>未テスト</td>
- <td>未テスト</td>
- <td>不明</td>
- <td>無し</td>
- </tr>
-
- <tr>
- <td>H2</td>
- <td>1.2.132</td>
- <td>-</td>
- <td>不明</td>
- <td>提供している</td>
- </tr>
-
- <tr>
- <td>HSQL</td>
- <td>1.8.0.7</td>
- <td>-</td>
- <td>未対応</td>
- <td>提供している</td>
- </tr>
-
- <tr>
- <td>Microsoft SQL Server</td>
- <td>2005</td>
- <td>2.0.1008.2(sqljdbc.jar)</td>
- <td>対応済み</td>
- <td>提供している
-</td>
- </tr>
-
- <tr>
- <td>MySQL</td>
- <td>5.0.22</td>
- <td>5.0.8(mysql-connector.jar)</td>
- <td>対応済み</td>
- <td>提供している
-</td>
- </tr>
-
- <tr>
- <td>PostgreSQL</td>
- <td>8.x</td>
- <td>8.4-701.jdbc4</td>
- <td>未対応</td>
- <td>提供している
-</td>
-
- </tr>
-
- <tr>
- <td>Oracle</td>
- <td>10g</td>
- <td>10.2.0.1(ojdbc14.jar)</td>
- <td>対応済み</td>
- <td>提供している
-</td>
- </tr>
-
- <tr>
- <td>SQLLite</td>
- <td>3.7.4</td>
- <td>-</td>
- <td>不明</td>
- <td>提供している
-</td>
- </tr>
-
-
- <tr>
- <td>Sybase SQLAnywhere</td>
- <td>10.0.1</td>
- <td>-</td>
- <td>不明</td>
- <td>提供している
-</td>
- </tr>
-
- </table>
-
- <p>検証したところ、"標準的"なPCでは1つのロギングイベントをデータベースに書き込むのにおよそ10ミリ秒かかるようです。コネクションプールを使えば1ミリ秒くらいは速くなるでしょう。一般的に利用できるほとんどのJDBCドライバではコネクションプールを使うことができるので、ぜひそうしてください。
- </p>
-
- <p><code>DBAppender</code>の設定方法はいろいろありますが、データベースに接続するツールや、データベース自体によって異なります。<code>DBAppender</code>の設定で重要なのは、<code>ConnectionSource</code>です。どういうものか簡単に説明しましょう。
- </p>
-
- <p><code>DBAppender</code>がデータベースに接続できたら、ロギングイベントは指定されたデータベースに送信されます。前述したとおり、logbackはロギングイベントを3つのテーブルに格納します。
- </p>
-
- <p><em>logging_event</em>テーブルには次のようなカラムがあります。</p>
- <table class="bodyTable striped">
- <tr>
- <th>カラム名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><b>timestamp</b></td>
- <td><code>big int</code></td>
- <td>ロギングイベントが作成された時のタイムスタンプ。</td>
- </tr>
- <tr>
- <td><b>formatted_message</b></td>
- <td><code>text</code></td>
-
- <td><code>org.slf4j.impl.MessageFormatter</code>で書式化されてからロギングイベントに設定されたメッセージ。引数のオブジェクトはメッセージにくっついています。</td>
- </tr>
- <tr>
- <td><b>logger_name</b></td>
- <td><code>varchar</code></td>
- <td>ロギング要求を発行したロガーの名前。</td>
- </tr>
- <tr>
- <td><b>level_string</b></td>
- <td><code>varchar</code></td>
- <td>ロギングイベントのレベル。</td>
- </tr>
- <tr>
- <td><b>reference_flag</b></td>
- <td><code>smallint</code></td>
- <td>
- <p>このフィールドは、ロギングイベントに例外オブジェクトが含まれているか、もしくは、<code>MDC</code>に関連する値が設定されていないかどうかを判定するため、logback が使用します。
- </p>
-
- <p>値は<code>ch.qos.logback.classic.db.DBHelper</code>が算出します。ロギングイベントに<code>MDC</code>あるいは<code>Context</code>プロパティが含まれるバア愛、このフラグ値は<em>1</em>になります。例外オブジェクトが含まれる場合は<em>2</em>になります。両方の要素が含まれている場合は<em>3</em>になります。
- </p>
- </td>
- </tr>
- <tr>
- <td><b>caller_filename</b></td>
- <td><code>varchar</code></td>
- <td>ロギング要求を発行した場所が含まれるファイル名。</td>
- </tr>
- <tr>
- <td><b>caller_class</b></td>
- <td><code>varchar</code></td>
- <td>ロギング要求を発行したクラス名。</td>
- </tr>
- <tr>
- <td><b>caller_method</b></td>
- <td><code>varchar</code></td>
- <td>ロギング要求を発行したメソッド名。</td>
- </tr>
- <tr>
- <td><b>caller_line</b></td>
- <td><code>char</code></td>
- <td>ロギング要求を発行した場所の行番号。</td>
- </tr>
- <tr>
- <td><b>event_id</b></td>
- <td><code>int</code></td>
- <td>データベースが払いだしたロギングイベントのID。</td>
- </tr>
- </table>
-
- <p><em>logging_event_property</em>には、<code>MDC</code>または<code>Context</code>に含まれるキーと値を格納します。次のようなカラムがあります。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>カラム名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><b>event_id</b></td>
- <td><code>int</code></td>
- <td>データベースが払いだしたロギングイベントのID。</td>
- </tr>
- <tr>
- <td><b>mapped_key</b></td>
- <td><code>varchar</code></td>
- <td><code>MDC</code>のキー値。</td>
- </tr>
- <tr>
- <td><b>mapped_value</b></td>
- <td><code>text</code></td>
- <td><code>MDC</code>の値。</td>
- </tr>
- </table>
-
- <p><em>logging_event_exception</em>テーブルには、次のようなカラムがあります。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>カラム名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><b>event_id</b></td>
- <td><code>int</code></td>
- <td>データベースが払いだしたロギングイベントのID。</td>
- </tr>
- <tr>
- <td><b>i</b></td>
- <td><code>smallint</code></td>
- <td>完全なスタックトレースを文字列化した際の各行の添字。</td>
- </tr>
- <tr>
- <td><b>trace_line</b></td>
- <td><code>varchar</code></td>
- <td>スタックトレースの文字列中の1行。</td>
- </tr>
- </table>
-
- <p><code>DBAppender</code>を使用した結果をもっと視覚的にわかりやすくお見せしましょう。次に示すのは、<code>DBAppender</code>がMySQLデータベースを使用した場合のスクリーンショットです。
- </p>
-
- <p><em>logging_event</em>テーブル</p>
-
- <img src="images/chapters/appenders/dbAppenderLE.gif" alt="ロギングイベントテーブル">
-
- <p><em>logging_event_exception</em>テーブル</p>
-
- <img src="images/chapters/appenders/dbAppenderLEException.gif" alt="ロギングイベント例外テーブル">
-
- <p><em>logging_event_property</em>テーブル</p>
-
- <img src="images/chapters/appenders/dbAppenderLEProperty.gif" alt="イベントログ記録Propertyテーブル">
-
-
- <h4>ConnectionSource</h4>
-
- <p><code>ConnectionSource</code>インターフェイスは、logbackが<code>java.sql.Connection</code>を取得するためのJDBC接続を透過的に取得するためのプラグイン可能な機能を提供するものです。<code>ConnectionSource</code>の実装クラスは3つあります。<code>DataSourceConnectionSource</code>、<code>DriverManagerConnectionSource</code>、<code>JNDIConnectionSource</code>です。
- </p>
-
- <p>最初に、<code>DriverManagerConnectionSource</code>を使ってMySQLデータベースに接続する例を見てみましょう。次の設定ファイルを見てください。
- </p>
-
- <p class="example">例: <code>DBAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/db/append-toMySQL-with-driveManger.xml">logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-driveManger.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-driverManager');">Groovyとして表示</span>
- <pre id="append-toMySQL-with-driverManager" class="prettyprint source"><configuration>
-
- <b><appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
- <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
- <driverClass>com.mysql.jdbc.Driver</driverClass>
- <url>jdbc:mysql://host_name:3306/datebase_name</url>
- <user>username</user>
- <password>password</password>
- </connectionSource>
- </appender></b>
-
- <root level="DEBUG" >
- <appender-ref ref="DB" />
- </root>
-</configuration></pre>
-
- <p>正しいJDBCドライバクラス名を指定してください。この例では<code>com.mysql.jdbc.Driver</code>です。<span class="prop">url</span>は<em>jdbc:mysql://</em>で始まらなければなりません。
- </p>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/db/DriverManagerConnectionSource.html">DriverManagerConnectionSource</a></code>は<code>ConnectionSource</code>の実装クラスで、JDBCの伝統的なやり方(接続用URLに基づくやり方)でデータベース接続を取得します。</p>
- <p>このクラスは<code>getConnection()</code>メソッドが呼ばれるたびに新しい<code>Connection</code>を生成することに注意してください。コネクションプーリングをサポートしているJDBCドライバーを使うか、コネクションプーリングを利用する<code>ConnectionSource</code>を自分で実装することをおすすめします。Java EE アプリケーションサーバの上で、<code>javax.sql.DataSource</code>をサポートしたJNDI実装を利用する場合は、後述する<a href="./appenders.html#JNDIConnectionSource"><code>JNDIConnectionSource</code></a>を参照してください。
- </p>
-<!--
-
- HAS TO BE TESTED
-
- <p>
- If you do not have another connection pooling mechanism built
- into your application, you can use the
- <a href="http://jakarta.apache.org/commons/dbcp/index.html">
- commons-dbcp </a> package from Apache:
- </p>
-
-<pre class="prettyprint source">
- <connectionSource
- class="ch.qos.logback.core.db.DriverManagerConnectionSource">
- <param name="driver" value="org.apache.commons.dbcp.PoolingDriver"/>
- <param name="url" value="jdbc:apache:commons:dbcp:/myPoolingDriver"/>
- </connectionSource>
-</pre>
-
- <p>
- Then the configuration information for the commons-dbcp
- package goes into the file <em>myPoolingDriver.jocl</em> and is
- placed in the classpath. See the
- <a href="http://jakarta.apache.org/commons/dbcp/index.html"> commons-dbcp </a>
- documentation for details.
- </p>
- -->
-
- <p><code>DataSource</code>を使ってデータベースに接続する場合もだいたい同じです。設定ファイルでは<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/db/DataSourceConnectionSource.html">DataSourceConnectionSource</a></code>を指定してください。JDBCの推奨するやり方(<code>javax.sql.DataSource</code>に基づくやり方)でデータベース接続(<code>Connection</code>)を取得します。
- </p>
-
- <p class="example">例: <code>DBAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/db/append-with-datasource.xml">logback-examples/src/main/java/chapters/appenders/db/append-with-datasource.xml</a>)</p>
-
-
- <span class="asGroovy" onclick="return asGroovy('append-with-datasource');">Groovyとして表示</span>
- <pre id="append-with-datasource" class="prettyprint source"><configuration debug="true">
-
- <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
- <b><connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
-
- <dataSource class="${dataSourceClass}">
- </b><!-- Joran cannot substitute variables
- that are not attribute values. Therefore, we cannot
- declare the next parameter like the others.
- -->
- <b><param name="${url-key:-url}" value="${url_value}"/>
- <serverName>${serverName}</serverName>
- <databaseName>${databaseName}</databaseName>
- </dataSource></b>
-
- <user>${user}</user>
- <password>${password}</password>
- </connectionSource>
- </appender>
-
- <root level="INFO">
- <appender-ref ref="DB" />
- </root>
-</configuration></pre>
-
- <p>この設定例ではたくさん変数を使っているので気をつけてください。1つの設定ファイルに接続情報の詳細をまとめておくと、logback と他のフレームワークで設定内容を共有できるので便利です。
- </p>
-
-<!-- TO BE TESTED
-
- <p>The connection created by
- <code>DataSourceConnectionSource</code> can be placed in a JNDI
- context by using <code>BindDataSourceToJNDIAction</code>. In that
- case, one has to specify the use of this class by adding a new
- rule to Joran, logback's configuration framework. Here is an
- excerpt of such a configuration file. </p>
-
-<div class="source"><pre><configuration>
- ..
- <b><newRule pattern="configuration/bindDataSourceToJNDI"
- actionClass="ch.qos.logback.core.db.BindDataSourceToJNDIAction"/>
-
- <bindDataSourceToJNDI /></b>
- ..
-</configuration></pre></div>
-
- <p> The <em>newRule</em> element teaches Joran to use specified
- action class with the given pattern. Then, we simply declare the
- given element. The action class will be called and our connection
- source will be bound to a JNDI context. </p>
-
- <p>This is a very powerful capability of Joran. If you'd like to
- read more about Joran, please see the <a
- href="onJoran.html">chapter to Joran</a>. </p>
-
- -->
-
- <h4 class="doAnchor" name="JNDIConnectionSource">JNDIConnectionSource</h4>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/db/JNDIConnectionSource.html">JNDIConnectionSource</a></code>もlogbackの配布物に含まれる<code>ConnectionSource</code>の実装クラスです。名前のとおり、JNDIから<code>javax.sql.DataSource</code>を取得し、そこから<code>java.sql.Connection</code>を取得します。<code>JNDIConnectionSource</code>は、Java EE アプリケーションサーバの内部か、アプリケーションサーバのクライアント(アプリケーションサーバの<code>javax.sql.DataSource</code>にリモートアクセスできることを想定しています)で使用することを念頭に設計されています。したがって、他にどんな便利機能を提供しているかはともかくとして、少なくともコネクションプーリングを [...]
-
- <p>次の例はTomcat用の設定ファイルから抜粋したものです。PostgreSQL で使うための設定ですが、サポートしているデータベースならどれでも同じように動くはずです。</p>
-
-<pre class="prettyprint source"><Context docBase="/path/to/app.war" path="/myapp">
- ...
- <Resource <b>name="jdbc/logging"</b>
- auth="Container"
- type="javax.sql.DataSource"
- username="..."
- password="..."
- driverClassName="org.postgresql.Driver"
- url="jdbc:postgresql://localhost/..."
- maxActive="8"
- maxIdle="4"/>
- ...
-</Context></pre>
-
- <p>Java EE アプリケーションサーバで定義した<code>DataSource</code>をlogbackの設定ファイルから参照するのは簡単です。</p>
-
- <p class="example">例:<code>JNDIConnectionSource</code>を使った<code>DBAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/db/append-via-jndi.xml">logback-examples/src/main/java/chapters/appenders/db/append-via-jndi.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('append-via-jndi');">Groovyとして表示</span>
-
-
-<pre id="append-via-jndi" class="prettyprint source"><configuration debug="true">
- <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
- <connectionSource class="ch.qos.logback.core.db.JNDIConnectionSource">
- <b><!-- please note the "java:comp/env/" prefix --></b>
- <b><jndiLocation>java:comp/env/jdbc/logging</jndiLocation></b>
- </connectionSource>
- </appender>
- <root level="INFO">
- <appender-ref ref="DB" />
- </root>
-</configuration></pre>
-
- <p>このクラスは引数無しのコンストラクタで<code>javax.naming.InitialContext</code>のインスタンスを生成するので注意してください。ほとんどの Java EE コンテナで正常に動作します。Java EE コンテナ以外で動かすときは、JNDIプロバイダのドキュメントで説明されたとおりに<em>jndi.properties</em>を用意してください。
- </p>
-
- <h4 class="doAnchor">コネクションプーリング</h4>
-
- <p>ロギングイベントはかなり高い頻度で生成されることがあります。ロギングイベントが生成されるのに合わせてデータベースに登録していなければなりません。そのためには、<code>DBAppender</code>でコネクションプーリングを利用するとよいでしょう。
- </p>
-
- <p><code>DBAppender</code>でコネクションプーリングを利用すると、著しく性能が改善することが実証されています。次の設定ファイルは、コネクションプーリング無しでMySQLデータベースにロギングイベントを登録するものです。
- </p>
-
- <p class="example">例: コネクションプーリング無しの<code>DBAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/db/append-toMySQL-with-datasource.xml">logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource');">Groovyとして表示</span>
- <pre id="append-toMySQL-with-datasource" class="prettyprint source"><configuration>
-
- <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
- <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
- <dataSource class="com.mysql.jdbc.jdbc2.optional.MysqlDataSource">
- <serverName>${serverName}</serverName>
- <port>${port$</port>
- <databaseName>${dbName}</databaseName>
- <user>${user}</user>
- <password>${pass}</password>
- </dataSource>
- </connectionSource>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="DB" />
- </root>
-</configuration></pre>
-
- <p>この設定ファイルでは、MySQLデータベースに500件のロギングイベントを送信するのになんと5秒もかかりました。つまり、1件あたり10ミリ秒もかかるのです。大規模なアプリケーションでは使いものにならないことがよくわかると思います。
- </p>
-
- <p><code>DBAppender</code>でコネクションプーリングを利用するには、外部ライブラリが必要です。次の例は<a href="http://sourceforge.net/projects/c3p0">c3p0</a>を使っています。c3p0を利用するには、まずダウンロードして、<em>c3p0-VERSION.jar</em>をクラスパス上に配置しなければなりません。
- </p>
-
- <p class="example">例: <code>DBAppender</code>でコネクションプーリングを利用する設定(<a href="http://logback.qos.ch/xref/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml">logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource-and-pooling');">Groovyとして表示</span>
- <pre id="append-toMySQL-with-datasource-and-pooling" class="prettyprint source"><configuration>
-
- <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
- <connectionSource
- class="ch.qos.logback.core.db.DataSourceConnectionSource">
- <b><dataSource
- class="com.mchange.v2.c3p0.ComboPooledDataSource">
- <driverClass>com.mysql.jdbc.Driver</driverClass>
- <jdbcUrl>jdbc:mysql://${serverName}:${port}/${dbName}</jdbcUrl>
- <user>${user}</user>
- <password>${password}</password>
- </dataSource></b>
- </connectionSource>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="DB" />
- </root>
-</configuration></pre>
-
- <p>この設定ファイルを使った場合、MySQLデータベースに500件のロギングイベントを送信するのにかかった時間は約0.5秒でした。1件あたりの所要時間は1ミリ秒です。つまり、10倍高速化できたことになります。
- </p>
-
- <h3 class="doAnchor" name="SyslogAppender">SyslogAppender</h3>
-
- <p>syslogプロトコルは非常に単純なプロトコルです。syslogの送信者は小さなメッセージをsyslogの受信者に送信します。一般的に受信者は<em>syslogデーモン</em>や<em>syslogサーバ</em>と呼ばれます。logbackは、<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/SyslogAppender.html"><code>SyslogAppender</code></a>を使ってリモートのsyslogデーモンにメッセージを送信することができます。
- </p>
-
- <p>SyslogAppenderの設定可能なプロパティは次のとおりです。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="syslog">syslogHost</span></td>
- <td><code>String</code></td>
- <td>syslogサーバのホスト名。</td>
- </tr>
- <tr>
- <td><span class="prop" container="syslog">port</span></td>
- <td><code>String</code></td>
- <td>syslogサーバーのポート番号。ほとんどの場合はデフォルト値の<em>514</em>を使うでしょう。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="syslog">facility</span></td>
- <td><code>String</code></td>
- <td>
- <p><span class="prop">facility</span>は、メッセージの送信元を区別するためのものです。</p>
- <p><span class="prop">facility</span>オプションには、次のいずれかの文字列を指定しなければなりません。<em>KERN、USER、MAIL、DAEMON、AUTH、SYSLOG、LPR、NEWS、UUCP、CRON、AUTHPRIV、FTP、NTP、AUDIT、ALERT、CLOCK、LOCAL0、LOCAL1、LOCAL2、LOCAL3、LOCAL4、のlocal5、LOCAL6、LOCAL7。</em>大文字小文字は区別されません。</p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="syslog">suffixPattern</span></td>
- <td><code>String</code></td>
- <td><p><span class="prop">suffixPattern</span>オプションには、syslogサーバに送信されるメッセージ中の任意部分の書式を指定します。デフォルトは<em>"[%thread] %logger %msg"</em>です。<code>PatternLayout</code>で使用できるものは、全て<span class="prop">suffixPattern</span>に指定することができます。
- </p>
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="syslog">stackTracePattern</span></td>
- <td><code>String</code></td>
- <td><p><span class="prop">stackTracePattern</span>プロパティには、スタックトレースの各行の先頭に表示する文字列を指定します。デフォルトはタブ文字、つまり "\t"です。<code>PatternLayout</code>で使用できるものは、全て<span class="prop">stackTracePattern</span>に指定することができます。</p>
- </td>
- </tr>
-
- <tr>
- <td><span class="prop" container="syslog">throwableExcluded</span></td>
- <td><code>boolean</code></td>
- <td><code>true</code>を指定すると、Throwableに関連付けられているスタックトレースの情報を省略するようになります。デフォルトは<code>falese</code>です。ですので、syslogサーバにはスタックトレースの情報が送信されます。</td>
- </tr>
-
-
- </table>
-
- <p>ロギングイベントに対する syslog の severity(重要度)は、ロギングレベルを変換したものになります。<em>DEBUG</em>は<em>7</em>、<em>INFO</em>は6、<em>WARN</em>は<em>4</em>、<em>ERROR</em>は<em>3</em>に変換されます。
- </p>
-
- <p>syslog要求の書式には厳密なルールがあるので、<code>SyslogAppender</code>はレイアウトを使用しません。しかし、<span class="prop">suffixPattern</span>オプションを使えば思った通りの内容を表示することができます。
- </p>
-
- <p><code>SyslogAppender</code>の設定例を見てみましょう。</p>
-
- <p class="example">例: <code>SyslogAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/logback-syslog.xml">logback-examples/src/main/java/chapters/appenders/conf/logback-syslog.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('logback-syslog');">Groovyとして表示</span>
- <pre id="logback-syslog" class="prettyprint source"><configuration>
-
- <appender name="SYSLOG" class="ch.qos.logback.classic.net.SyslogAppender">
- <syslogHost>remote_home</syslogHost>
- <facility>AUTH</facility>
- <suffixPattern>[%thread] %logger %msg</suffixPattern>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SYSLOG" />
- </root>
-</configuration></pre>
-
- <p>この設定ファイルを試してみるときは、リモートsyslogデーモンが外部からのリクエストを受け付けるようになっていることを先に確認しておいてください。経験上、デフォルトではsyslogデーモンはネットワークからのリクエストを拒否するようになっていることが多いです。
- </p>
-
-
- <h3 class="doAnchor" name="SiftingAppender">SiftingAppender</h3>
-
- <p>名前のとおり、<code>SiftingAppender</code>は設定に基づいてロギングイベントを分配(あるいはふるいにかける)ことができます。例えば、<code>SiftingAppender</code>がユーザーセッションに基づいてロギングイベントを分配するようになっていれば、ユーザーごとにログファイルを生成するようになるでしょう。
- </p>
-
-
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="sift">timeout</span></td>
- <td><code><a href="http://logback.qos.ch/apidocs/ch/qos/logback/core/util/Duration.html">Duration</a></code></td>
- <td><span class="prop">タイムアウト時間</span>を経過してもアクセスされなかったアペンダーは、古くなったものと判断されます。古くなったアペンダーは閉じられて、<code>SiftingAppender</code>から切り離されます。デフォルトは30分です。</td>
- </tr>
- <tr>
- <td><span class="prop" container="sift">maxAppenderCount</span></td>
- <td><code>integer</code></td>
- <td><code>SiftingAppender</code>が作成して管理できるアペンダーの最大数を指定します。デフォルトはInteger.MAX_VALUEです。</td>
- </tr>
- </table>
-
- <p><code>SiftingAppender</code>は実行時にアペンダーを作成します。<code>SiftingAppender</code>の設定で指定された設定テンプレート(<code>sift要素</code>で囲まれた部分です。後で例を示します)に従って作成します。<code>SiftingAppender</code>には、子アペンダーのライフサイクルを管理する責任があります。たとえば、 <code>SiftingAppender</code>は古くなったアペンダー自動的に閉じて削除します。<span class="prop">タイムアウト時間</span>で指定された時間を過ぎてもアクセスの無かったアペンダーを無効とみなすのです。
- </p>
-
- <p>ロギングイベントが発生したら、<code>SiftingAppender</code>は委譲する子アペンダーを選択します。選択条件は弁別器によって実行時に計算されます。利用者は<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/sift/Discriminator.html">Discriminator</a></code>で選択条件を指定することができます。例を見てみましょう。
- </p>
-
- <h4>例</h4>
-
- <p><a href="http://logback.qos.ch/xref/chapters/appenders/sift/SiftExample.html">SiftExample</a>アプリケーションは、アプリケーションが起動したことを表すメッセージをロギングします。その後、MDCのキー"uesrid"に"Alice"を設定して、メッセージをロギングします。該当するコードは次のとおりです。</p>
-
- <p class="source">logger.debug("Application started");
-MDC.put("userid", "Alice");
-logger.debug("Alice says hello"); </p>
-
- <p><code>SiftingAppender</code>で使う設定ファイルのテンプレートは次のようになっています。</p>
-
-
- <p class="example">例: <code>SiftingAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/sift/byUserid.xml">logback-examples/src/main/java/chapters/appenders/sift/byUserid.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('byUserid');">Groovyとして表示</span>
-
- <pre id="byUserid" class="prettyprint source"><configuration>
-
- <b><appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender"></b>
- <!-- in the absence of the class attribute, it is assumed that the
- desired discriminator type is
- ch.qos.logback.classic.sift.MDCBasedDiscriminator -->
- <b><discriminator></b>
- <b><key><span class="green">userid</span></key></b>
- <b><defaultValue>unknown</defaultValue></b>
- <b></discriminator></b>
- <b><sift></b>
- <b><appender name="FILE-<span class="green">${userid}</span>" class="ch.qos.logback.core.FileAppender"></b>
- <b><file><span class="green">${userid}</span>.log</file></b>
- <b><append>false</append></b>
- <b><layout class="ch.qos.logback.classic.PatternLayout"></b>
- <b><pattern>%d [%thread] %level %mdc %logger{35} - %msg%n</pattern></b>
- <b></layout></b>
- <b></appender></b>
- <b></sift></b>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SIFT" />
- </root>
-</configuration></pre>
-
-
- <p>discriminator 要素にclass属性がない場合、<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/sift/MDCBasedDiscriminator.html">MDCBasedDiscriminator</a>が設定されます。弁別器は、<span class="prop">key</span>プロパティで指定されたキーのMDC値を返します。MDC値がnullの場合は、<span class="prop">defaultValue</span>プロパティで指定した値を返します。
- </p>
-
- <p><code>SiftingAppender</code>による子アペンダーの管理機能は独特なものです。上記の例では、<code>SiftingAppender</code>によって複数の<code>FileAppender</code>が作られます。それぞれの<code>FileAppender</code>はキー"userid"でMDCに登録された値によって区別されます。キー"uesrid"のMDC値が新しい値のときは、新しい<code>FileAppender</code>インスタンスをゼロから作ります。<code>SiftingAppender</code>は自分が作ったアペンダーを追跡し続けます。30分間使われなかったアペンダーは自動的に閉じられ、破棄されます。
- </p>
-
- <p><span class="label notice">変数の公開</span>出力先リソースが別々な複数のアペンダーのインスタンスを利用するにはどうしたらいいでしょうか?弁別器のキーが<a href="./configuration.html#variableSubstitution">変数</a>として公開されるので、上記の例の場合は、アペンダーの設定テンプレート内で"userid"を指定しています。こうすると、子アペンダーに別々の出力先を設定できるようになります。
- </p>
-
- <p><code>SiftExample</code>アプリケーションの引数に設定ファイル"byUserid.xml"を指定して実行すると、"unknown.log" と"Alice.log"という2つのログファイルが作成されます。
- </p>
-
- <p><span class="label">ローカルスコープの変数</span>logback 1.0.12 から、ネストされたアペンダーからローカルスコープの変数が利用できるようになりました。また、<em><code>sift要素</code>内</em>で<a href="./configuration.html#definingProps">変数を定義</a>したり、変数の値を<a href="./configuration.html#definingPropsOnTheFly">実行時に算出</a>できるようになりました。<code>sift要素</code>の外側で定義された変数の値を組み合わせることもできます。
- </p>
-
- <h4 class="doAnchor" name="siftGettingTimeoutRight">適切な<span class="prop">タイムアウト</span>を設定する</h4>
-
- <p>アプリケーションによっては、適切な<span class="prop">タイムアウト時間</span>を決めるのが難しいことがあります。<span class="prop">タイムアウト時間</span>が短すぎると、ネストされたアペンダーが削除された直後に新しく生成されるようになってしまいます。これは<em>ゴミ漁り</em>と呼ばれる事象です。<span class="prop">タイムアウト時間</span>が長すぎると、立て続けにアペンダーが生成されるとリソース不足になってしまうかもしれません。<span class="prop">maxAppenderCount</span>が小さすぎても同じようにゴミ漁りが発生するかもしれません。
- </p>
-
- <p>どんな場合でも、ネストされたアペンダーが不要になる箇所を特定するのは簡単でしょう。そういう場所が特定できたら、あるいはほぼ確実にそうだと言える場所が特定できたら、そこに書かれているロギング式に<a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/ClassicConstants.html#FINALIZE_SESSION_MARKER">FINALIZE_SESSION</a>マーカーを指定しましょう。SiftingAppenderは<code>FINALIZE_SESSION</code>マーカーを指定されたロギングイベントを見つけたら、関連付けられたアペンダーはもう破棄していいいものと判断します。破棄されることになったアペンダーは、数秒間到着するであろうロギングイベントに備えて活性化した後、何も到着しなければそのままクローズします。
- </p>
-
- <pre class="prettyprint source">import org.slf4j.Logger;
-import static ch.qos.logback.classic.ClassicConstants.FINALIZE_SESSION_MARKER;
-
- void job(String jobId) {
-
- MDC.put("jobId", jobId);
- logger.info("Starting job.");
-
- ... do whather the job needs to do
-
- // will cause the nested appender reach end-of-life. It will
- // linger for a few seconds.
- logger.info(FINALIZE_SESSION_MARKER, "About to end the job");
-
- try {
- .. perform clean up
- } catch(Exception e);
- // This log statement will be handled by the lingering appender.
- // No new appender will be created.
- logger.error("unexpected error while cleaning up", e);
- }
- }
-
-</pre>
-
- <h3 class="doAnchor" name="AsyncAppender">AsyncAppender</h3>
-
- <p>AsyncAppenderは<a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/spi/ILoggingEvent.html">ILoggingEvent</a>を非同期的にロギングします。単にイベントディスパッチャとして機能するので、意味のある仕事をさせるには他のアペンダーを参照させなければなりません。</p>
-
- <p><span class="label notice">80%を越えると消えてしまう</span>
-AsyncAppenderはロギングイベントを<a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html">BlockingQueue</a>に蓄積します。<code>AsyncAppender</code>のワーカースレッドは、キューの先頭からロギングイベントを取り出して、<code>AsyncAppender</code>に割り当てられたアペンダーに振り分けます。キューの使用量が80%を超えている場合、デフォルトではTRACE、DEBUG、および、INFOレベルのログを捨ててしまいます。これは、ロギングイベントを失ってしまうリスクに見合うだけの性能影響があります。
- </p>
-
- <p><span class="label">アプリケーションの停止と再デプロイ</span>
-アプリケーションを停止、あるいは<code>再デプロイ</code>する前に、 AsyncAppenderを停止しなければなりません。全てのロギングイベントをキューから吐き出すためです。そのためには、<a href="./configuration.html#stopContext">LoggerContextを停止</a>すればよいです。<code>AsyncAppender</code>を含む全てのアペンダーを閉じます。</p>
-
-
- <p><code>AsyncAppender</code>の設定可能なプロパティは次のとおりです。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="async">queueSize</span></td>
- <td><code>int</code></td>
- <td>キューの最大容量。デフォルトは256です。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="async">discardingThreshold</span></td>
- <td><code>int</code></td>
- <td>デフォルトは20%です。キューの使用量が閾値を越えたら、INFO以下のロギングイベントは破棄、WARN以上のロギングイベントだけをキューイングするようになります。0を指定するとロギングイベントを破棄しないようになります。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="async">includeCallerData</span></td>
- <td><code>boolean</code></td>
- <td>送信者情報の抽出自体に時間がかかることがあります。性能上の兼ね合いにより、デフォルトではロギングイベントをキューに追加するとき、関連する送信者情報を抽出しないようになっています。代わりに、スレッド名などが"軽い"情報だけを<a href="./mdc.html">MDC</a>にコピーします。trueを指定した場合、完全な送信者情報を含めるようになります。
- </td>
- </tr>
- </table>
-
- <p>デフォルトでは、イベントキューに登録可能な件数は256件になっています。キューが一杯になると、新しくロギングイベントを登録しようとしていたアプリケーションスレッドは、ワーカースレッドによってキューのロギングイベントが処理されるまで、ブロックします。キューの使用量が最大使用量を下回るまで、アプリケーションスレッドはロギング要求を発行できなくなります。したがって、ロギングイベントのバッファ使用量が最大値付近で推移しているとき、このアペンダーはほぼ同期的なロギングをすることになります。これは必ずしも悪いことではありません。このアペンダーは、ロギングイベントのバッファ使用量が閾値を超えるほどに増加するまでは、ロギング処理よりもアプリケーションの実行時間が長くなるように設計されています。
- </p>
-
- <p>アプリケーションのスループットを最大化するためには、アペンダーのイベントキューの大きさを最適化する必要があり、それはいくつもの要因が絡んでいます。次に示す要因のいずれか、あるいは全てが、擬似的な同期的動作をさせる可能性があります。</p>
-
- <ul>
- <li>アプリケーションスレッドが多すぎる</li>
- <li>アプリケーションの呼び出しごとのロギング要求が多すぎる</li>
- <li>ロギングイベントごとに付随する情報が多すぎる</li>
- <li>子アペンダーのレイテンシが遅すぎる</li>
- </ul>
-
- <p>一般的には、アプリケーションの使用するヒープを減らして、ロギングイベントのキューを大きくすればよいでしょう。
- </p>
-
-
- <p><span class="label notice">非可逆な振る舞い</span>
-上記の議論を踏まえながらブロックする可能性を減らすため、AsyncAppenderはデフォルトでは利用可能なキューが最大値の20%未満になったらTRACE、DEBUG、INFOレベルのロギングイベントを破棄し、WARNとERRORレベルのロギングイベントだけを残すようになっています。そうすると、TRACE、DEBUG、INFOレベルのロギングイベントにコストをかけなくてもよくなるので、非同期処理を妨げず、高い性能を維持することができます。しきい値<span class="prop">discardingThreshold</span>を0にすればロギングイベントを破棄しないようにすることもできます。
- </p>
-
- <p class="example">例: <code>AsyncAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conc/logback-async.xml">logback-examples/src/main/java/chapters/appenders/conc/logback-async.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('asyncAppender');">Groovyとして表示</span>
-
- <pre id="asyncAppender" class="prettyprint source"><configuration>
- <appender name="<b>FILE</b>" class="ch.qos.logback.core.FileAppender">
- <file>myapp.log</file>
- <encoder>
- <pattern>%logger{35} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <b><appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"></b>
- <b><appender-ref ref="FILE" /></b>
- <b></appender></b>
-
- <root level="DEBUG">
- <appender-ref ref="<b>ASYNC</b>" />
- </root>
-</configuration></pre>
-
-
- <h3 class="doAnchor" name="WriteYourOwnAppender">アペンダーを自作する</h3>
-
-
- <p><code>AppenderBase</code>を使えば簡単にアペンダーを自作することができます。この基底クラスでは、フィルターやステータスメッセージの管理などほとんどのアペンダーが備えている機能を提供するものです。派生クラスでやることと言えば、<code>append(Object eventObject)</code>メソッドを実装するだけです。
- </p>
-
- <p>次に示す<code>CountingConsoleAppender</code>は、限られた数のロギングイベントをコンソールに出力する自作アペンダーです。指定された数のロギングイベントを処理したらシャットダウンします。ロギングイベントを書式化するために<code>PatternLayoutEncoder</code>を使用します。そして、<code>limit</code>というプロパティを設定することができます。また、<code>append(Object eventObject)</code>メソッド以外にもいくつかメソッドを用意しなければなりません。例を見ればわかりますが、これらのパラメータは logback のさまざまな設定の仕組みによって自動的に設定されます。
- </p>
-
- <em>例4<span class="autoExec"></span>: <code>CountingConsoleAppender</code> (<a href="http://logback.qos.ch/xref/chapters/appenders/CountingConsoleAppender.java">logback-examples/src/main/java/chapters/appenders/CountingConsoleAppender.java</a>)</em>
- <pre class="prettyprint source">package chapters.appenders;
-
-import java.io.IOException;
-
-import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.AppenderBase;
-
-
-public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
- static int DEFAULT_LIMIT = 10;
- int counter = 0;
- int limit = DEFAULT_LIMIT;
-
- PatternLayoutEncoder encoder;
-
- public void setLimit(int limit) {
- this.limit = limit;
- }
-
- public int getLimit() {
- return limit;
- }
-
- @Override
- public void start() {
- if (this.encoder == null) {
- addError("No encoder set for the appender named ["+ name +"].");
- return;
- }
-
- try {
- encoder.init(System.out);
- } catch (IOException e) {
- }
- super.start();
- }
-
- public void append(ILoggingEvent event) {
- if (counter >= limit) {
- return;
- }
- // output the events as formatted by our layout
- try {
- this.encoder.doEncode(event);
- } catch (IOException e) {
- }
-
- // prepare for next event
- counter++;
- }
-
- public PatternLayoutEncoder getEncoder() {
- return encoder;
- }
-
- public void setEncoder(PatternLayoutEncoder encoder) {
- this.encoder = encoder;
- }
-}</pre>
-
- <p><code>start()</code>メソッドでは、<code>PatternLayoutEncoder</code>が設定されているかチェックしています。エンコーダーが設定されなかった場合、アペンダーの起動は失敗となり、エラーメッセージを出力します。
- </p>
-
- <p>この自作アペンダーの見どころは次の2点です。</p>
-
- <ul>
-
- <li>JavaBeans の規約通りにアクセサを定義したプロパティは、logbackの他の設定と同じように処理されます。<code>start()</code>メソッドはlogbackの設定処理から自動的に呼び出されるようになっています。アペンダーのさまざまなプロパティの設定と、一貫性を整える役割があります。
- </li>
-
- <li><code>AppenderBase.doAppend()</code>メソッドは派生クラスのappend()メソッドを呼び出します。実際の出力は<code>append()</code>が行います。レイアウトによってロギングイベントを書式化するのもこのメソッドです。
- </li>
- </ul>
-
- <p><a href="http://logback.qos.ch/xref/chapters/appenders/CountingConsoleAppender.html"><code>CountingConsoleAppender</code></a>は他のアペンダーと同じように定義することができます。設定ファイルの例として<a href="http://logback.qos.ch/xref/chapters/appenders/countingConsole.xml"><em>logback-examples/src/main/java/chapters/appenders/countingConsole.xml</em></a>も見てください。
- </p>
-
-
- <h2 class="doAnchor" name="logback_access">Logback Access</h2>
-
- <p>logback-classic のほとんどのアペンダーと同じものが logback-access にもあります。基本的には同じように動きます。以降の節ではそれらの使い方を説明します。
- </p>
-
- <h3 class="doAnchor" name="AccessSocketAppender">SocketAppenderとSSLSocketAppender</h3>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/access/net/SocketAppender.html">SocketAppender</a></code>は、シリアライズした<code>AccessEvent</code>をネットワーク上のリモートホストに送信するために設計されています。リモートロギングは、アクセスイベントが重要であろうとなかろうと盗聴できないようになっています。受信したイベントをデシリアライズした後は、自分で生成したロギングイベントと同じように扱うことができます。
- </p>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/access/net/SSLSocketAppender.html">SSLSocketAppender</a></code>は基本的な<code>SocketAppender</code>を拡張したもので、Secure Sockets Layer(SSL)を介してリモートホストにログを転送します。
- </p>
-
- <p>logback-access の<code>SocketAppender</code>で設定可能なプロパティは、logback-classic の<code>SocketAppender</code>と同じです。
- </p>
-
- <h3 class="doAnchor" name="AccessServerSocketAppender">ServerSocketAppenderとSSLServerSocketAppender</h3>
-
- <p><code>SocketAppender</code>と同様に、<a href="http://logback.qos.ch/xref/ch/qos/logback/access/net/server/ServerSocketAppender.html"><code>ServerSocketAppender</code></a>はシリアライズした<code>AccessEvent</code>をネットワーク上のリモートホストに送信するために設計されています。<code>ServerSocketAppender</code>はサーバとして動作します。つまり、外部のクライアントがTCP接続してくるのを待ち受けます。アペンダーに渡されたロギングイベントは、接続している全てのクライアントに配布されます。
- </p>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/access/net/server/SSLServerSocketAppender.html">SSLSocketAppender</a></code>は基本的な<code>ServerSocketAppender</code>を拡張したもので、Secure Sockets Layer(SSL)を介してリモートホストにログを転送します。
- </p>
-
- <p>logback-access の<code>ServerSocketAppender</code>で設定可能なプロパティは、logback-classic の<code>ServerSocketAppender</code>と同じです。
- </p>
-
-
- <h3 class="doAnchor" name="AccessSMTPAppender">SMTPAppender</h3>
-
- <p>logback-access の<code><a href="http://logback.qos.ch/xref/ch/qos/logback/access/net/SMTPAppender.html">SMTPAppender</a></code>は、logback-classic と同じように動作します。tだ、<span class="prop">評価器</span>の設定はだいぶ違います。デフォルトでは、 <code>URLEvaluator</code>オブジェクトが使用されます。この評価器はロギング要求のURLと突き合わせるURLのリストを持っています。いずれかのURLにマッチするロギング要求が発生したら、<code>SMTPAppender</code>はメールを送信します。
- </p>
-
- <p>logback-access の<code>SMTPAppender</code>の設定例を見てみましょう。
- </p>
- <p class="example">例: <code>SMTPAppender</code>の設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/access/logback-smtp.xml">logback-examples/src/main/java/chapters/appenders/conf/access/logback-smtp.xml</a>)</p>
-
-<pre class="prettyprint source"><appender name="SMTP"
- class="ch.qos.logback.access.net.SMTPAppender">
- <layout class="ch.qos.logback.access.html.HTMLLayout">
- <pattern>%h%l%u%t%r%s%b</pattern>
- </layout>
-
- <b><Evaluator class="ch.qos.logback.access.net.URLEvaluator">
- <URL>url1.jsp</URL>
- <URL>directory/url2.html</URL>
- </Evaluator></b>
- <from>sender_email at host.com</from>
- <smtpHost>mail.domain.com</smtpHost>
- <to>recipient_email at host.com</to>
-</appender></pre>
-
- <p>このやり方では、特別な処理プロセスの中で重要な手順を通ったときにメールを送信するようなことができます。メールには、トリガとなったWebページにアクセスする一つ前のWebページが含まれます。他の情報を含めることもできます。
- </p>
-
- <h3 class="doAnchor" name="AccessDBAppender">DBAppender</h3>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/access/db/DBAppender.html"><code>DBAppender</code></a>はアクセスイベントをデータベースに登録するために使用します。
- </p>
-
- <p><code>DBAppender</code>は<em>access_event</em>テーブルと<em>access_event_header</em>テーブルを使います。いずれも<code>DBAppender</code>を使用する前に準備しなければなりません。テーブルを作成するSQLスクリプトはlogback の配布物に含まれています。<em>logback-access/src/main/java/ch/qos/logback/access/db/script</em>ディレクトリにあるはずです。一般的なデータベースそれぞれの専用スクリプトがあります。あなたの使用しているデータベース用のスクリプトが無かったとしても、他のスクリプトを参考にすれば簡単に作成できます。あなたの使っているデータベース用のスクリプトが無かった時は、作成したスクリプトをlogbackプロジェクトに送ってください。
- </p>
-
- <p><em>access_event</em>テーブルのカラムは次のとおりです。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>カラム名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><b>timestamp</b></td>
- <td><code>big int</code></td>
- <td>アクセスイベントの作成時のタイムスタンプ。</td>
- </tr>
- <tr>
- <td><b>requestURI</b></td>
- <td><code>varchar</code></td>
- <td>要求されたURI。</td>
- </tr>
- <tr>
- <td><b>requestURL</b></td>
- <td><code>varchar</code></td>
- <td>要求されたURL。これはリクエストメソッド、リクエストURI、リクエストプロトコルを組み合わせた文字列です。
- </td>
- </tr>
- <tr>
- <td><b>remoteHost</b></td>
- <td><code>varchar</code></td>
- <td>リモートホストの名前。</td>
- </tr>
- <tr>
- <td><b>remoteUser</b></td>
- <td><code>varchar</code></td>
- <td>リモートユーザの名前。
- </td>
- </tr>
- <tr>
- <td><b>remoteAddr</b></td>
- <td><code>varchar</code></td>
- <td>リモートIPアドレス。</td>
- </tr>
- <tr>
- <td><b>protocol</b></td>
- <td><code>varchar</code></td>
- <td><em>HTTP</em>または<em>HTTPS</em>などのリクエストプロトコル、。</td>
- </tr>
- <tr>
- <td><b>method</b></td>
- <td><code>varchar</code></td>
- <td>リクエストメソッド、<em>GET</em>か<em>POST</em>になるでしょう。</td>
- </tr>
- <tr>
- <td><b>serverName</b></td>
- <td><code>varchar</code></td>
- <td>リクエストを受け付けたサーバーの名前。</td>
- </tr>
- <tr>
- <td><b>event_id</b></td>
- <td><code>int</code></td>
- <td>アクセスイベントのデータベース上のID。</td>
- </tr>
- </table>
-
- <p><em>access_event_header</em>テーブルには、リクエストのヘッダ情報が登録されます。次のようなものです。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>カラム名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><b>event_id</b></td>
- <td><code>int</code></td>
- <td>アクセスイベントのデータベース上のID。</td>
- </tr>
- <tr>
- <td><b>header_key</b></td>
- <td><code>varchar</code></td>
- <td><em>User-Agent</em>などのリクエストヘッダー名。</td>
- </tr>
- <tr>
- <td><b>header_value</b></td>
- <td><code>varchar</code></td>
- <td><em>Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1) Gecko/20061010 Firefox/2.0</em>のようなリクエストヘッダー値。</td>
- </tr>
- </table>
-
- <p>logback-access の<code>DBAppender</code>に設定可能なプロパティは、logback-classic の<code>DBAppender</code>でも利用できます。logback-access の DBAppender でだけ設定可能なプロパティは次のとおりです。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td>
- <b>
- <span class="prop">insertHeaders</span>
- </b>
- </td>
- <td>
- <code>boolean</code>
- </td>
- <td>trueの場合、ロギング要求に含まれる全てのヘッダ情報を登録するようになります。
- </td>
- </tr>
- </table>
-
- <p><code>DBAppender</code>の設定例を見てください。</p>
-
- <p class="example">例:DBAppenderの設定(<em><a href="http://logback.qos.ch/xref/chapters/appenders/conf/access/logback-DB.xml</em>">logback-examples/src/main/java/chapters/appenders/conf/access/logback-DB.xml</em></a>)</p>
-
- <pre class="prettyprint source"><configuration>
-
- <appender name="DB" class="ch.qos.logback.access.db.DBAppender">
- <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
- <driverClass>com.mysql.jdbc.Driver</driverClass>
- <url>jdbc:mysql://localhost:3306/logbackdb</url>
- <user>logback</user>
- <password>logback</password>
- </connectionSource>
- <insertHeaders>true</insertHeaders>
- </appender>
-
- <appender-ref ref="DB" />
-</configuration></pre>
-
-
- <h3 class="doAnchor" name="AccessSiftingAppender">SiftingAppender</h3>
-
- <p>logback-access のSiftingAppenderは、logback-classic のSiftingAppenderとほとんど同じです。主な違いは、デフォルトの弁別器がMDCを参照するものではなく、<a href="http://logback.qos.ch/xref/ch/qos/logback/access/sift/AccessEventDiscriminator.html">AccessEventDiscriminator</a>になっていることです。AccessEventDiscriminatorは、その名のとおり、ネストされたアペンダーを選択するために、AccessEventのフィールドを使用します。指定されたフィールドの値がnullの場合<span class="prop">DefaultValue</span>プロパティの値が使用されます。
- </p>
-
- <p>AccessEventのフィールドとして指定できるのはCOOKIE、REQUEST_ATTRIBUTE、SESSION_ATTRIBUTE、REMOTE_ADDRESS、LOCAL_PORT、REQUEST_URIです。最初の3つのフィールドは単独で指定することはできません。<span class="prop">AdditionalKey要素</span>が必要なので注意してください。</p>
-
- <p>設定ファイルの例を示します。</p>
-
- <p class="example">例:SiftingAppenderの設定(<a href="http://logback.qos.ch/xref/chapters/appenders/conf/sift/access-siftingFile.xml">logback-examples/src/main/java/chapters/appenders/conf/sift/access-siftingFile.xml</a>)</p>
-
- <pre class="prettyprint source"><configuration>
- <appender name="SIFTING" class="ch.qos.logback.access.sift.SiftingAppender">
- <Discriminator class="ch.qos.logback.access.sift.AccessEventDiscriminator">
- <Key>id</Key>
- <FieldName>SESSION_ATTRIBUTE</FieldName>
- <AdditionalKey>username</AdditionalKey>
- <defaultValue>NA</defaultValue>
- </Discriminator>
- <sift>
- <appender name="access-$id-$username" class="ch.qos.logback.core.FileAppender">
- <file>byUser/access-$id-$username.log</file>
- <layout class="ch.qos.logback.access.PatternLayout">
- <pattern>%h %l %u %t \"%r\" %s %b</pattern>
- </layout>
- </appender>
- </sift>
- </appender>
- <appender-ref ref="SIFTING" />
-</configuration></pre>
-
-
- <p>この例では<code>SiftingAppender</code>が<code>FileAppender</code>をネストしています。キー要素の値"id"は、ネストされた<code>FileAppender</code>で変数として使用することができます。デフォルトの弁別器でもある<code>AccessEventDiscriminator</code>は AdditionalKey 要素で指定した"username" を<code>AccessEvent</code>のセッション属性から探します。指定した属性が無かったら、defaultValue要素の値"NA"を使用します。セッション属性の"username"には、アプリケーションのログインユーザー名が含まれていることを想定しています。ユーザーごとのアクセスログは、<em>byUser</em>フォルダの下にユーザー名入りのファイル名で出力されます。
- </p>
-
-
- <script src="http://logback.qos.ch/templates/footer.js" type="text/javascript"></script>
-
-
- </div>
-
-</body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/architecture.html b/logback-site/src/site/pages/manual/architecture.html
index 9cec151..b093ca6 100644
--- a/logback-site/src/site/pages/manual/architecture.html
+++ b/logback-site/src/site/pages/manual/architecture.html
@@ -27,8 +27,6 @@
<h1>Chapter 2: Architecture</h1>
- <a href="architecture_ja.html">和訳 (Japanese translation)</a>
-
<div class="quote">
<p><em>All true classification is genealogical.</em></p>
<p>—CHARLES DARWIN, <em>The Origin of Species</em></p>
diff --git a/logback-site/src/site/pages/manual/architecture_ja.html b/logback-site/src/site/pages/manual/architecture_ja.html
deleted file mode 100644
index 8a412cc..0000000
--- a/logback-site/src/site/pages/manual/architecture_ja.html
+++ /dev/null
@@ -1,619 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第2章 アーキテクチャ</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第2章 アーキテクチャ</h1>
-
- <div class="quote">
- <p><em>本物の分類学とは、系統学のことなのだ。</em></p>
- <p>—CHARLES DARWIN, <em>The Origin of Species</em></p>
-
- <p><em>文字で書かれたものを読むだけで、得られた情報を具体的な問題に適用し、読んだことを自分のものとして考えること無しには、問題そのものを学ぶことは、不可能ではないが困難だ。さらに、私たちは自ら発見した時にこそ最も良い学びを得るのだ。</em>
- </p>
- <p>—DONALD KNUTH, <em>The Art of Computer Programming</em></p>
- </div>
-
-
- <script src="../templates/creative.js" type="text/javascript"></script>
-
- <h2>Logbackのアーキテクチャ</h2>
-
- <p>logback の基本的なアーキテクチャは、さまざまな状況に対応できるよう、十分に汎用的になっています。今のところ、logbackは三つのモジュールに分割されています(logback-core、logback-classic、logback-access)。
- </p>
-
- <p><em>coreモジュール</em>は、他の二つのモジュールの足回りとして使用されています。<em>classic</em>モジュールは、 <em>core</em>を拡張するものです。classic モジュールは、著しく改善されたバージョンのlog4jとも考えられます。logback-classic は <a href="http://www.slf4j.org">SLF4J API</a> を直接実装しているので、log4j や java.util.logging(JUL)などの他のロギング実装と切り替えることができます。三つ目の<em>access</em>と呼ばれるモジュールは、HTTPのアクセスログ機能を提供するため、サーブレットコンテナと統合しています。access モジュールについては<a href="http://logback.qos.ch/access.html">別のドキュメント</a>に記載されています。
- </p>
-
- <p>このドキュメントの残りの部分では、logback-classicモジュールのことを "logback" と表記しています。
- </p>
-
- <h2>ロガー、アペンダー、レイアウト</h2>
-
- <p>logback は三つの主要なクラス(<code>Logger</code> 、 0}Appender、<code>Layout</code> )で成り立っています。これらの三つのコンポーネントが協調することで、開発者はメッセージを適切な種類、レベルでロギングできるようになっています。また、書式化や出力先を実行中に変更できるようにもなっています。
- </p>
-
- <p><code>Logger</code>クラスは、logback-classicモジュールに含まれています。一方、 <code>Appender</code>と<code>Layout</code>インタフェイスは、logback-coreモジュールに含まれています。logback-core モジュールは共通モジュールなので、logger の責務を含まないのです。
- </p>
-
- <h3 class="doAnchor" name="LoggerContext">ロガーコンテキスト</h3>
-
- <p>どんなロギングAPIであっても単純な<code>System.out.println</code>に勝る第一の、そして最大の利点があります。それは、特定のロギング式を無効にしつつ、他のロギング式には一切影響を与えない機能です。この機能は、ロギング空間、すなわち、すべてのロギング式からなる空間が、開発者の選択した基準に基いて分類されていることを前提としています。logback-classic モジュールにおいて、この分類は logger に固有のものです。全てのロガーは <code>LoggerContext</code> に接続します。<code>LoggerContext</code> には、接続してきたロガーを階層的な木構造として配置する責務があります。
- </p>
-
- <p>ロガーは名前を持ったエンティティです。名前は大文字と小文字が区別され、階層的な命名規則に従うようになっています。</p>
-
- <div class="definition">
- <div class="deftitle">名前の階層</div>
- <p>あるロガーの名前が、他のロガーの名前の中で「.」(ドット)で区切られた前置詞となっているとき、それぞれが先祖と子孫となります。自分自身や、自分の子にも祖先がいない場合、そのロガーは親になります。
- </p>
- </div>
-
- <p>たとえば、<code>"com.foo"</code>という名前のロガーは、<code>"com.foo.Bar"</code> というロガーの親になります。同様に、 <code>"java"</code>は<code>"java.util"</code>の親であると同時に、<code>"java.util.Vector"</code> の祖先になります。この命名スキームは、ほとんどの開発者がきちんと理解しなければならないものです。
- </p>
-
- <p>ルートロガーは、ロガー階層の最上位に存在するものです。複数の階層構造すべてに含まれるという意味で、例外的な存在です。他のロガーと同じように、名前で取得することができます。こんな風に。</p>
-
- <pre class="prettyprint source">Logger rootLogger = LoggerFactory.getLogger(<a href="http://www.slf4j.org/apidocs/constant-values.html#org.slf4j.Logger.ROOT_LOGGER_NAME">org.slf4j.Logger.ROOT_LOGGER_NAME</a>);</pre>
-
- <p>他のロガーも、org.slf4j.LoggerFactory</html>クラスの静的クラスメソッドである<code>getLogger</code>によって取得することができます。このメソッドは、パラメータとして欲しいロガーの名前を受け付けます。<code>Logger</code>インタフェイスの基本的なメソッドをいくつか以下に示します。
-
-
- <pre class="prettyprint source">package org.slf4j;
-public interface Logger {
-
- // Printing methods:
- public void trace(String message);
- public void debug(String message);
- public void info(String message);
- public void warn(String message);
- public void error(String message);
-}</pre>
-
-
-
- <h3 class="doAnchor" name="effectiveLevel">有効レベル(別名レベルの継承)</h3>
-
- <p>ロガーにはレベルを割り当てることができます。利用できるレベル(TRACE、DEBUG、INFO、WARNおよびERROR)は<code>ch.qos.logback.classic.Level</code>クラスに定義されています。logback では Level クラスは final として宣言されており、サブクラス化出来ないことに注意してください。より柔軟性のあるアプローチは<code>Marker</code>オブジェクトとして利用可能です。
- </p>
-
- <p>レベルの割り当てられていないロガーは、直近の祖先に割り当てられたレベルを継承します。より正確に言うと次のようになります。</p>
-
- <div class="definition">
-
-
- <p>与えられたロガー<em>L</em>の有効なレベルは、ロガー階層において最初に見つかったロガーのレベルに等しい。階層は<em>L</em>から始まり、ロートロガーに向かって進んでいく。
- </p>
- </div>
-
- <p>最終的に全てのロガーがレベルを継承できるように、ルートロガーには必ずレベルが割り当てられています。デフォルトではDEBUGになっています。</p>
-
- <p>以下は、レベル継承ルールに従ってロガーに割り当てられた有効レベルの例です。
- </p>
-
- <em>例1</em>
- <table class="bodyTable">
- <tr>
- <th>ロガー名</th>
- <th>割り当てられたレベル</th>
- <th>有効レベル</th>
- </tr>
- <tr class="alt">
- <td>ルートロガー</td>
- <td>DEBUG</td>
- <td>DEBUG</td>
- </tr>
- <tr>
- <td>X</td>
- <td>なし</td>
- <td>DEBUG</td>
- </tr>
-
- <tr class="alt">
- <td>X.Y</td>
- <td>なし</td>
- <td>DEBUG</td>
- </tr>
- <tr>
- <td>X.Y.Z</td>
- <td>なし</td>
- <td>DEBUG</td>
- </tr>
- </table>
-
- <p>上記の例では、ルートロガーにだけレベルが割り当てられています。レベルは<code>DEBUG</code>で 、他の全てのロガーに継承されています。
- </p>
-
- <em>例2</em>
- <table class="bodyTable">
- <tr>
- <th>ロガー名</th>
- <th>割り当てられたレベル</th>
- <th>有効レベル</th>
- </tr>
- <tr class="alt" align="left">
- <td>ルート</td>
- <td>ERROR</td>
- <td>ERROR</td>
- </tr>
- <tr align="left">
- <td>X</td>
- <td>INFO</td>
- <td>INFO</td>
- </tr>
-
- <tr class="alt" align="left">
- <td>X.Y</td>
- <td>DEBUG</td>
- <td>DEBUG</td>
- </tr>
- <tr align="left">
- <td>X.Y.Z</td>
- <td>WARN</td>
- <td>WARN</td>
- </tr>
- </table>
-
- <p>上記の例では、すべてのロガーにレベルが割り当てられています。レベルの継承は何も仕事をしていません。
- </p>
-
- <em>例3</em>
- <table class="bodyTable">
- <tr>
- <th>ロガー名</th>
- <th>割り当てられたレベル</th>
- <th>有効レベル</th>
- </tr>
- <tr class="alt" align="left">
- <td>ルート</td>
- <td>DEBUG</td>
- <td>DEBUG</td>
- </tr>
-
- <tr align="left">
- <td>X</td>
- <td>INFO</td>
- <td>INFO</td>
- </tr>
- <tr class="alt" align="left">
- <td>X.Y</td>
- <td>なし</td>
- <td>INFO</td>
- </tr>
- <tr align="left">
- <td>X.Y.Z</td>
- <td>ERROR</td>
- <td>ERROR</td>
- </tr>
- </table>
-
- <p>上記の例では、ルートロガーにDEBUG、<code>X</code>にINFO、<code>X.Y.Z</code>にERRORが割り当てられています。<code>X.Y</code>は親である<code>X</code>からレベルを継承しています。</p>
-
- <em>例4</em>
- <table class="bodyTable">
-
- <tr>
- <th>ロガー名</th>
- <th>割り当てられたレベル</th>
- <th>有効レベル</th>
- </tr>
- <tr class="alt" align="left">
- <td>ルート</td>
- <td>DEBUG</td>
- <td>DEBUG</td>
- </tr>
-
- <tr align="left">
- <td>X</td>
- <td>INFO</td>
- <td>INFO</td>
- </tr>
- <tr class="alt" align="left">
- <td>X.Y</td>
- <td>なし</td>
- <td>INFO</td>
- </tr>
- <tr align="left">
- <td>X.Y.Z</td>
- <td>なし</td>
- <td>INFO</td>
- </tr>
- </table>
-
-
- <p>上記の例では、ルートロガーにDEBUG、<code>X</code>にINFOが割り当てられています。<code>X.Y</code>および<code>X.Y.Z</code>は、最も近い親からレベルを継承しています。
- </p>
-
- <h3 class="doAnchor" name="basic_selection">印字メソッドと基本的な選択ルール</h3>
-
- <p>定義によると、印字メソッドはロギング要求のレベルを決定するものです。例えば、<code>L</code>がロガーのインスタンスだとすると、式<code>L.info("..")</code>はINFOレベルのロギングであることになります。</p>
-
-
- <p>ロギング要求は、そのロガーの有効レベル以上である場合に<em>有効</em>となります。そうでなければ、ロギング要求は<em>無効</em>になります。前述のように、レベルが割り当てられていないロガーは最も近い祖先から継承します。このルールは次のように要約できます。
- </p>
-
-
- <div class="definition">
- <div class="deftitle">基本的な選択ルール</div>
-
- <p>有効レベル<em>q</em>のロガーに発行されたレベル<em>p</em>のログ要求は、<em>p>=q</em>を満たす場合有効になる。
- </p>
- </div>
-
- <p>このルールはlogbackの中核を為すものです。レベルは次のような順序であることを想定しています。<code>TRACE < DEBUG < INFO < WARN < ERROR</code></p>
-
- <p>以下は、選択ルールをより具体的に示したものです。垂直方向のラベルはロギング要求のレベル<em>p</em>です。そして水平方向のラベルはロガーの有効レベル<em>q</em>です。行(ロギング要求のレベル)と列(ロガーの有効レベル)の交点が、基本的な選択ルールの適用結果を表しています。
- </p>
-
- <table width="80%">
- <tr>
- <td class="lgray_bg" rowspan="2"><br>ロギング要求のレベル<em>p</em></td>
- <td align="center" colspan="6" style="border-top:1px solid #dddddd">ロガーの有効レベル<em>q</em></td>
- </tr>
- <tr align="left">
- <th style="border-bottom:1px solid #dddddd">TRACE</th>
- <th style="border-bottom:1px solid #dddddd">DEBUG</th>
- <th style="border-bottom:1px solid #dddddd">INFO</th>
- <th style="border-bottom:1px solid #dddddd">WARN</th>
- <th style="border-bottom:1px solid #dddddd">ERROR</th>
- <th style="border-bottom:1px solid #dddddd">OFF</th>
- </tr>
- <tr align="left">
- <th class="lgray_bg">TRACE</th>
- <td><span class="greenBold">YES</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- </tr>
-
- <tr align="left">
- <th class="lgray_bg">DEBUG</th>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- </tr>
- <tr align="left">
- <th class="lgray_bg">INFO</th>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- </tr>
- <tr align="left">
- <th class="lgray_bg">WARN</th>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="redBold">NO</span></td>
- <td><span class="redBold">NO</span></td>
- </tr>
- <tr align="left">
- <th class="lgray_bg">ERROR</th>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="greenBold">YES</span></td>
- <td><span class="redBold">NO</span></td>
- </tr>
- </table>
-
- <p>選択ルールのコード例を次に示します。</p>
-
- <pre class="prettyprint source">import ch.qos.logback.classic.Level;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-....
-
-// "com.foo"という名前のロガーを取得します。
-// ロガーのインスタンスはレベルを設定するために ch.qos.logback.classic.Logger とします。
-ch.qos.logback.classic.Logger logger =
- (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.foo");
-// レベルに<span class="blue">INFO</span>を設定します。setLevel() メソッドは logback のロガーにしかありません。
-.setLevel(Level. <span class="blue">INFO</span>);
-
-Logger barlogger = LoggerFactory.getLogger("com.foo.Bar");
-
-// このロギング要求は有効です。<span class="green bold">WARN</span> >= <span class="blue">INFO</span>
-logger.<span class="green bold">warn</span>("Low fuel level.");
-
-// このロギング要求は無効です。<span class="green bold">DEBUG</span> < <span class="blue">INFO</span>.
-logger.<span class="green bold">debug</span>("Starting search for nearest gas station.");
-
-// "com.foo.Bar" という名前のロガーは、"com.foo" ロガーからレベルを継承します。
-// したがって、このロギング要求は有効です。<span class="green bold">INFO</span> >= <span class="blue">INFO</span>.
-barlogger.<span class="green bold">info</span>("Located nearest gas station.");
-
-// このロギング要求は無効です。<span class="green bold">DEBUG</span> < <span class="blue">INFO</span>.
-barlogger.<span class="green bold">debug</span>("Exiting gas station search");</pre>
-
- <a name="RetrievingLoggers"></a>
- <h3>ロガーの取得</h3>
- <p><code><a href="http://logback.qos.ch/apidocs/org/slf4j/LoggerFactory.html#getLogger(java.lang.String)">LoggerFactory.getLogger</a></code>を呼び出しましょう。
-同じ名前なら、常に同じロガーインスタンスへの参照を返します。
- </p>
-
- <p>例えば次のような場合は常に同じインスタンスを返します。</p>
- <pre class="prettyprint source">Logger x = LoggerFactory.getLogger("wombat");
-Logger y = LoggerFactory.getLogger("wombat");</pre>
-
- <p>
- <code>x</code>と<code>y</code>は、<em>完全に</em>同じオブジェクトを参照します。
- </p>
-
- <p>このように、一度ロガーのインスタンスを設定すれば、わざわざ参照を渡さなくても、コード中のどこででも同じインスタンスを取得することができます。現実世界の生物の親子関係とは矛盾していますが、logback のロガーは親と子のどちらが先に生成されても問題ありません。ただし、「親」ロガーから子孫ロガーを見つけようとするときは、事前にインスタンス化しておく必要があります。
- </p>
- <p>logback の実行環境の設定は、アプリケーションの初期化時に行われるのが一般的です。設定ファイルを読み込むようにするとよいでしょう。方法についてはすぐ後で説明します。
- </p>
- <p>logback では、<em>コンポーネント</em>ごとにロガーの名前を付けるのが簡単です。ロガーをクラスごとにインスタンス化すれば、それぞれのロガーの名前はクラスの完全名になります。これはロガーを定義する簡単かつ便利な方法です。クラスの完全名であるロガーの名前をログに出力するようになっていれば、メッセージを出力した箇所を特定するのは簡単です。ですが、これはロガーの命名戦略としてごく一般的な方法の一つでしかありません。logback 自体にロガーのインスタンス数の制限はありません。従って、開発者は自由に名前を付けることが出来ます。
- </p>
-
- <p>とはいえ、ロガーの名前にそれが置かれたクラスの完全名を付けることは、一般的に最も良い方法であるということが共通認識になっています。
- </p>
-
- <a name="AppendersAndLayouts"></a>
- <h3>アペンダーとレイアウト</h3>
-
- <p>ロガーのレベルに応じてロギング要求の有効無効を選択できる機能は、logbackの機能の一部でしかありません。logback は、ロギング要求を複数の宛先の送りつけることができます。logback では、宛先のことをアペンダーと呼びます。現在利用できるアペンダーには、コンソール、ファイル、MySQLやPostgreSQLやOracleなどのデータベースへのリモート接続、JMS、リモートSyslogデーモンなどがあります。
-
- <!--It is also possible to log asynchronously. -->
- </p>
-
- <p>ロガーには一つ以上のアペンダーを割り当てることができます。</p>
-
- <p>指定されたロガーにアペンダーを割り当てるには、<code><a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/Logger.html#addAppender(ch.qos.logback.core.Appender)">addAppender</a></code>メソッドを使います。有効なロギング要求は、ロガーに割り当てられた全てのアペンダーについて、階層関係が上位のアペンダーから順に転送されます。別の言い方をすると、ロガー階層からアペンダーも引き継ぐということです。例えば、ルートロガーにコンソールアペンダーを割り当てたなら、有効なロギング要求は少なくともコンソールに出力されることになります。さらに、ロガー<em>L</em>にファイルアペンダーが割り当てられたなら、<em>L</em>とその子孫全てにおいて、有効なロギング要求はコンソールとファイルの両方に出力されます。ロガーの additivity フラグを false に設定すれば、アペンダーを継承しないように振る舞いを変更するこ [...]
- </p>
-
- <p>アペンダーの加算ルールをまとめると次のようになります。
- </p>
- <div class="definition">
-
- <h4 class="deftitle"><a href="./01-architecture.html#additivity" name="additivity">アペンダーの加算性</a></h4>
-
- <p>ロガー<em>L</em>のログ出力は、<em>L</em>とその祖先も割り当てられた全てのアペンダーに転送される。これが「アペンダーの加算性」の定義である。
- </p>
-
- <p>ロガー<em>L</em>の祖先<em>P</em>の aditivity フラグが false の場合、<em>L</em>の出力は<em>L</em>自身に割り当てられたアペンダーと、祖先<em>P</em>に割り当てられたアペンダーだけに転送される。<em>P</em>よりも祖先のロガーのアペンダーには転送されない。</p>
-
- <p>デフォルトでは、ロガーの aditivity は true になっています。
- </p>
-
- </div>以上を踏まえた例を次の表に示します。<table class="bodyTable">
- <tr>
- <th>ロガー名</th>
- <th>割り当てられたアペンダー</th>
- <th>aditivity フラグ</th>
- <th>宛先</th>
- <th>コメント</th>
- </tr>
- <tr>
- <td>root</td>
- <td>A1</td>
- <td>適用できません</td>
- <td>A1</td>
-
- <td>ルートロガーは、ロガー階層の最上位になるため、aditivity フラグは無効です。
- </td>
- </tr>
- <tr class="alt">
- <td>x</td>
- <td>A-x1、A-x2</td>
- <td>true</td>
- <td>A1、A-x1、A-x2</td>
- <td>「x」のアペンダーとルートロガーのアペンダーが対象</td>
- </tr>
- <tr>
- <td>x.y</td>
- <td>なし</td>
- <td>true</td>
- <td>A1、A-x1、A-x2</td>
- <td>「x」のアペンダーとルートロガーのアペンダーが対象</td>
- </tr>
- <tr class="alt">
- <td>x.y.z</td>
- <td>A-xyz1</td>
- <td>true</td>
- <td>A1、A-x1、A-x2、A-xyz1</td>
- <td>「x.y.z」のアペンダーと「×」のアペンダーとルートロガーのアペンダーが対象</td>
- </tr>
- <tr>
- <td>security</td>
- <td>A-sec</td>
- <td class="blue"><span class="blue">false</span></td>
- <td>A-sec</td>
-
- <td>aditivity フラグが<code>false</code>なので、アペンダーは加算されません。A-sec だけが対象になります
- </td>
- </tr>
- <tr class="alt">
- <td>security.access</td>
- <td>なし</td>
- <td>true</td>
- <td>A-sec</td>
- <td>「security」のaditivityフラグが<code>false</code>なので、「security」のアペンダーだけが加算されます
- </td>
- </tr>
- </table>
-
-
- <p>利用者は、ほとんどの場合出力先だけでなく出力形式もカスタマイズしたがるでしょう。アペンダーと<em>レイアウト</em>を関連付けることで実現できます。レイアウトは、利用者の指定したとおりにロギング要求を整形するものです。一方、アペンダーは整形されたメッセージを指定された宛先に転送します。利用者は、logback の標準配布物に含まれる<code>PatternLayout</code>を使って、C言語の<code>printf</code>関数で使うような変換指示子によって出力形式を指定します。
- </p>
-
- <p>PatternLayoutの変換パターンが "%-4relative [%thread] %-5level %logger{32} - %msg%n" のとき、出力は次のようになります。</p>
-
- <div class="prettyprint source"><pre>176 [main] DEBUG manual.architecture.HelloWorld2 - Hello world.</pre></div>
-
- <p>最初のフィールドはプログラムが開始してからの経過時間をミリ秒にしたものです。二番目のフィールドはログ要求を行ったスレッドです。三番目のフィールドはログ要求のレベルです。四番目のフィールドはログ要求を行ったロガーの名前です。'-' より後のテキストはログ要求に指定されたメッセージになります。</p>
-
-
- <h3 class="doAnchor" name="parametrized">パラメータ化ロギング</h3>
-
- <p>ogbakc-classicのロガーは、<a href="http://www.slf4j.org/api/org/slf4j/Logger.html">SLF4JのLoggerインターフェイス</a>に含まれる一つ以上のパラメータを受け取る出力メソッドを実装しています。これらのメソッドは、コードの読みやすさへの影響を最小限に抑えながら、性能を改善するために用意されたものです。
- </p>
-
- <p></p>
-
- <pre class="prettyprint source">logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));</pre>
-
- <p>こんな書き方をしているロギング式があった場合、メッセージを組み立てるために、整数<code>i</code>と<code>entry[i]</code>を文字列にするコスト、文字列を連結する中間的なコストがかかるでしょう。これは、ロギング要求が有効かどうかに関わらずかかってしまうコストです。
- </p>
-
- <p>パラメータ構築のコストを回避するには、ロギング式全体をテスト条件で囲む方法があります。
- </p>
-
- <pre class="prettyprint source">if(logger.isDebugEnabled()) {
- logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
-}</pre>
-
-
- <p>こうすると、DEBUGレベルのロギング要求が無効になっていればパラメータ構築のコストはかからないでしょう。しかし、有効になっている場合、<code>debugEnabled</code>と<code>debug</code>のそれぞれでロガーのレベルが有効かどうかを判定することになってしまいます。ロガーのレベルの評価はロギング要求に対して1%未満の時間しかかからないので、実際のオーバーヘッドは些細なものです。</p>
-
- <h4>より良い方法</h4>
-
- <p>メッセージフォーマットに基づいた便利な方法があります。<code>entry</code>が何らかのオブジェクトを指すものとして、次のように書くことが出来ます。</p>
-
-
- <pre class="prettyprint source">Object entry = new SomeObject();
-logger.debug("The entry is {}.", entry);</pre>
-
- <p>ロギング要求が有効かどうかを判断した後にだけ、そして、それが有効な場合にだけ、ロガーはメッセージを書式化して、'{}' を <code>entry</code> の文字列表現で置き換えます。つまり、ロギング要求が無効な場合、このやり方だとパラメータ構築のコストが発生しません。
- </p>
-
-
- <p>以下の二行からはまったく同じ出力が得られます。しかし、 ロギング要求が<em>無効</em>な場合、二行目のやり方は一行目のやり方に比べて少なくとも30倍は遅くなるでしょう。
- </p>
-
- <pre class="prettyprint source">logger.debug("The new entry is "+entry+".");
-logger.debug("The new entry is {}.", entry);</pre>
-
-
- <p>二つ置換場所を指定することもできます。たとえば、次のように書くことができます。</p>
-
- <pre class="prettyprint source">logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);</pre>
-
- <p>引数が三つ以上になる場合、<code>Object[]</code>でラップしなければなりません。たとえば、次のように書くことができます。</p>
-
-
- <pre class="prettyprint source">Object[] paramArray = {newVal, below, above};
-logger.debug("Value {} was inserted between {} and {}.", paramArray);</pre>
-
-
- <a name="UnderTheHood"></a>
- <h3>内部実装を覗いてみよう</h3>
-
- <p>ここまでで、logback の中心的なコンポーネントについて紹介してきました。次のステップに進む準備は完璧です。利用者が logback の出力メソッドを呼び出した時に、logback フレームワークの内部でどんなことが起きているのか見ていきましょう。利用者が<em>com.wombat</em>という名前のロガーについて、<code>info()</code>を呼び出した時の様子を分析してみましょう。
- </p>
-
- <h4>ステップ1. フィルタチェインの決定</h4>
-
- <p><code>TurboFilter</code>が存在するならそれが呼び出されます。Turbo Filter コンテキストにまたがる閾値を設定できるし、いろんなイベントを捨てることができます。捨てるイベントは、<code>Marker</code> 、 <code>Level</code> 、 <code>Logger</code> 、メッセージ、<code>Throwable</code>といったロギング要求に関係する情報から判断します。フィルタチェインの結果が <code>FilterReply.DENY</code> だったら処理中のロギング要求はその時点で破棄します。<code>FilterReply.NEUTRAL</code> だったら次のステップ(ステップ2)に進みます。<code>FilterReply.ACCEPT</code> だったら、次のステップを無視してステップ3にジャンプします。
- </p>
-
- <h4>ステップ2. <a href="./02-architecture.html#basic_selection">基本的な選択ルール</a>の適用</h4>
-
- <p>このステップでは、logback はロガーの有効レベルとロギング要求のレベルを比較します。比較した結果ロギング要求が無効の場合は残りの処理は行わず、ロギング要求を破棄します。ロギング要求が破棄されなければ、次のステップに進みます。
- </p>
-
- <h4>ステップ3. <code>LoggingEvent</code>オブジェクトの作成</h4>
-
- <p>ロギング要求がここまでのフィルタを通過したら、logback はロギング要求に含まれる必要な情報を全て格納した<code>ch.qos.logback.classic.LoggingEvent</code> オブジェクトを作成します。中には、ロギング要求を受け付けたロガーインスタンス、ロギング要求のレベル、ロギング要求に指定された例外オブジェクト、現在の時間、現在のスレッド、ロギング要求を起こしたクラスに関するさまざまな情報、<code>MDC</code>などが含まれます。フィールドによってはレイジーな初期化となるものがあります。つまり、必要になった時点で初期化される、ということです。<code>MDC</code>は、ロギング要求の付加情報となります。MDCについては<a href="./08-mdc.html">以降の章</a>で詳しく説明します。</p>
-
- <h4>ステップ4. アペンダーの起動</h4>
-
- <p><code>LoggingEvent</code>オブジェクトを作ったら、logback は利用可能な全てのアペンダーについて <code>doAppend()</code>メソッドを呼び出します。ロガーコンテキストから受け継いだアペンダーが対象になります。
- </p>
-
- <p>logback の配布物に含まれているアペンダーは、すべて <code>AppenderBase</code> 抽象クラスを継承しています。<code>doAppend()</code>メソッドは synchronized として宣言されており、スレッドセーフであることが保証されています。<code>AppenderBase</code>クラスの<code>doAppend()</code>メソッドでは、アペンダーに割り当てられたフィルターが存在する場合、それを呼び出します。カスタムフィルターは、実行時にアペンダーに割り当てることができるフィルターのことです。<a href="./07-filters.html">別の章</a>で説明しています。
- </p>
-
- <h4>ステップ5. メッセージの書式化</h4>
-
- <p>ロギングイベントを書式化するのはアペンダーの責任です。しかし、全てでは無いにしてもいくつかのアペンダーは書式化のタスクをレイアウトに委譲します。レイアウトは、<code>LoggingEvent</code>のインスタンスを書式化して、文字列として返します。アペンダーによっては(<code>SocketAppender</code>など)、ロギングイベントを文字列に変換するのではなく、シリアライズすることがあります。つまり、アペンダーはレイアウトを持っていることもあるし、持っていないこともあるのです。
- </p>
-
- <h4>ステップ6. <code>LoggingEvent</code>の送信</h4>
-
- <p>完全に書式化されたロギングイベントは、それぞれのアペンダーの宛先に送信されます。
- </p>
-
- <p>このUMLのシーケンス図は、ここまでで紹介してきたステップ全体を概観するものです。図をクリックすればより大きなサイズの図を見ることができます。
- </p>
-
- <a href="underTheHood.html">
- <img src="images/chapters/architecture/underTheHoodSequence2_small.gif">
- </a>
-
-
- <h3 class="doAnchor" name="performance">性能</h3>
-
- <p>ロギングについてよく議論の的になる課題の一つとして、必要な計算コストがあります。そこそこの規模のアプリケーションであっても、数千に及ぶログ要求を生成することになるので、性能に関心があるのは当然です。開発中に私たちが一番多くの力と時間を費やしたのは、logback の性能を測定することと、性能を調整することでした。私たちがどれだけの労力を費やしてきたとしてもそれとは関係無く、利用者は次のような性能問題に注意しなければなりません。
- </p>
-
- <h4>問題1. ロギングが完全にオフになっているときの性能</h4>
-
- <p>ルートロガーのレベルに最高レベルの<code>Level.OFF</code>を設定すると、完全にロギングをオフにすることができます。完全にロギングをオフにすると、ロギング要求のコストはメソッド呼び出しと整数比較だけになります。3.2GHz の Pentium D のマシンの場合、通常ならそのコストは 20 マイクロ秒程度になります。
- </p>
-
- <p>しかし、メソッド呼び出しによっては隠れたパラメータ構築のコストが含まれます。例えば、ロガー<em>x</em>について次のように実装されていると</p>
-
- <pre class="prettyprint source">x.debug("Entry number: " + i + "is " + entry[i]);</pre>
-
- <p>パラメータ構築のコストが含まれることになります。つまり、整数<code>i</code>と<code>entry[i]</code>を文字列に変換するコストと、中間文字列を連結するコストです。これらのコストは、メッセージがログに出力されるかどうかは関係無くかかります。
- </p>
-
- <p>パラメータ構築のコストは、パラメータの数にもよりますが非常に高くなることがあります。パラメータ構築のコストを回避するため、SLF4Jのパラメータ化されたロギングを利用することができます。</p>
-
- <pre class="prettyprint source">x.debug("Entry number: {} is {}", i, entry[i]);</pre>
-
- <p>このやり方の場合パラメータ構築のコストは発生しません。前の<code>debug()</code>メソッドの呼び出し方に比べると、圧倒的に速くなります。メッセージが書式化されるのは、割り当てられたアペンダーにロギング要求が送信されるときだけだからです。また、メッセージを書式化するコンポーネントには、高度な最適化が行われています。
- </p>
-
- <p>そうはいっても、非常に範囲の狭いループ中にロギング式があると、呼び出し回数が非常におおくなります。性能が劣化する可能性があるため、何のメリットもありません。たとえロギングがオフになっていても、狭い範囲のループにロギング式が含まれていると、アプリケーションの動作が緩慢になってしまいます。それに、ロギングをオンにすると非常に大量の(そして役に立たない)出力が生じます。
- </p>
-
- <h4>問題2. ロギングをオンにした状態で、ロギングするかどうかを判定する場合の性能</h4>
-
- <p>logbackでは、ロガー階層を渡り歩く必要がありません。ロガーは、インスタンスが作成された時点で自分の有効レベル(ロガー自体のレベルと受け継いたレベルを考慮した結果)を知っています。親ロガーのレベルを変更すると、全ての子ロガーは変更通知を受け取ります。したがって、ロガーは祖先ロガーに問い合わせること無く、有効レベルに基いてロギング要求を受け付けるか拒否するかを瞬時に判断することができます。
- </p>
-
-
- <h4>問題3. 実際にロギングする(書式化と出力デバイスへの書き込み)</h4>
-
- <p>これは、ログ出力を書式化し、宛先へ送信するコストです。レイアウト(フォーマッター)の処理を出来る限り高速化するために、同じように過大な労力を費やしました。同じことがアペンダーにも当てはまります。ローカルマシン上のファイルにロギングするとき、実際のロギングのコストは9マイクロ秒から12マイクロ秒程度になりました。リモートサーバ上のデータベースにロギングするとき、これが数ミリ秒に跳ね上がります。
- </p>
-
- <p>logback は豊富な機能を備えていますが、設計上の第一目標は高速な実行速度であり、第二目標として挙げられていたのは信頼性だけでした。logback のコンポーネントは、性能改善のため何度も書き直されています。
- </p>
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/configuration.html b/logback-site/src/site/pages/manual/configuration.html
index f4e0502..ef4474b 100644
--- a/logback-site/src/site/pages/manual/configuration.html
+++ b/logback-site/src/site/pages/manual/configuration.html
@@ -30,10 +30,7 @@
</div>
<div id="content" class="chapter">
- <h1>Chapter 3: Logback configuration</h1>
-
- <a href="configuration_ja.html">和訳 (Japanese translation)</a>
-
+ <h1>Chapter 3: Logback configuration</h1>
<div class="quote">
<p><em>In symbols one observes an advantage in discovery which
@@ -101,21 +98,7 @@
classpath</a>..</p>
</li>
- <li><p>If no such file is found, <a
- href="http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html">
- service-provider loading facility</a> (introduced in JDK 1.6) is
- used to resolve the implementation of <a
- href="../xref/ch/qos/logback/classic/spi/Configurator.html">
- <code>com.qos.logback.classic.spi.Configurator</code></a>
- interface by looking up the file
- <em>META-INF\services\ch.qos.logback.classic.spi.Configurator</em>
- in the class path. Its contents should specify the fully
- qualified class name of the desired <code>Configurator</code>
- implementation.
- </p>
- </li>
-
- <li><p>If none of the above succeeds, logback configures itself
+ <li><p>If neither file is found, logback configures itself
automatically using the <a
href="../xref/ch/qos/logback/classic/BasicConfigurator.html"><code>BasicConfigurator</code></a>
which will cause logging output to be directed to the console.
@@ -124,28 +107,21 @@
</ol>
- <p>The last step is meant as last-ditch effort to provide a
- default (but very basic) logging functionality in the absence of a
+ <p>The fourth and last step is meant to provide a default (but
+ very basic) logging functionality in the absence of a
configuration file.
</p>
<p>If you are using Maven and if you place the
- <em>logback-test.xml</em> under the <em>src/test/resources</em>
- folder, Maven will ensure that it won't be included in the
- artifact produced. Thus, you can use a different configuration
- file, namely <em>logback-test.xml</em> during testing, and another
- file, namely, <em>logback.xml</em>, in production.
+ <em>logback-test.xml</em> under the
+ <em>src/test/resources</em> folder, Maven will ensure that it
+ won't be included in the artifact produced. Thus, you can use a
+ different configuration file, namely <em>logback-test.xml</em>
+ during testing, and another file, namely, <em>logback.xml</em>, in
+ production. The same principle applies by analogy for Ant.
</p>
- <p><span class="label">Fast start-up</span> It takes about 100
- miliseconds for Joran to parse a given logback configuration
- file. To shave off those miliseconds at aplication start up, you
- can use the service-provider loading facility (item 4 above) to
- load your own custom <code>Configurator</code> class with <a
- href="../xref/ch/qos/logback/classic/BasicConfigurator.html">BasicConfigrator</a>
- serving as a good starting point.</p>
-
<h3 class="doAnchor" name="automaticConf">Automatically
configuring logback</h3>
@@ -258,7 +234,7 @@ public class Foo {
</p>
<p class="example">Example: Basic configuration file
- (logback-examples/src/main/resources/chapters/configuration/sample0.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/sample0.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sample0');">View as .groovy</span>
@@ -308,13 +284,13 @@ public class Foo {
<pre class="prettyprint lang-java source">
-public static void main(String[] args) {
- // assume SLF4J is bound to logback in the current environment
- <b>LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
- // print logback's internal status
- <b>StatusPrinter.print(lc);</b>
- ...
-}</pre>
+ public static void main(String[] args) {
+ // assume SLF4J is bound to logback in the current environment
+ <b>LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
+ // print logback's internal status
+ <b>StatusPrinter.print(lc);</b>
+ ...
+ }</pre>
<p>If everything goes well, you should see the following output on the console</p>
@@ -337,13 +313,6 @@ public static void main(String[] args) {
which allow convenient access to logback's internal state.
</p>
- <h4 class="doAnchor" name="dumpingStatusData">Status data</h4>
-
- <p class="highlight">Enabling output of status data usually goes a
- long way in the diagnosis of issues with logback. As such, it is
- highly recommended and should be considered as a recourse of
- <b>first</b> resort.</p>
-
<p>Instead of invoking <code>StatusPrinter</code> programmatically
from your code, you can instruct the configuration file to dump
status data, even in the absence of errors. To achieve this, you
@@ -357,9 +326,10 @@ public static void main(String[] args) {
<code>DEBUG</code>.)
</p>
+
<p class="example">Example: Basic configuration file using debug
mode
- (logback-examples/src/main/resources/chapters/configuration/sample1.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/sample1.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sample1');">View as .groovy</span>
<pre id="sample1" class="prettyprint source">
@@ -378,7 +348,7 @@ public static void main(String[] args) {
</root>
</configuration></pre>
- <p>Setting <code>debug="true"</code> within the
+ <p>Setting the <code>debug</code> attribute within the
<configuration> element will output status information,
assuming that:
</p>
@@ -401,7 +371,6 @@ public static void main(String[] args) {
every case.</p>
-
<p><span class="label">Forcing status output</span> In the absence
of status messages, tracking down a rogue <em>logback.xml</em>
configuration file can be difficult, especially in production where
@@ -414,29 +383,6 @@ public static void main(String[] args) {
generated in case of errors.
</p>
- <p>By the way, setting <code>debug="true"</code> is strictly
- equivalent to installing an
- <code>OnConsoleStatusListener</code>. Status listeners are
- disccussed further below. The installation of
- <code>OnConsoleStatusListener</code> is shown next. </p>
-
- <p class="example">Example: Registering a status listener
- (logback-examples/src/main/resources/chapters/configuration/onConsoleStatusListener.xml)</p>
- <span class="asGroovy" onclick="return asGroovy('onConsoleStatusListener');">View as .groovy</span>
- <pre id="onConsoleStatusListener" class="prettyprint source"><configuration>
- <b><statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /></b>
-
- ... the rest of the configuration file
-</configuration></pre>
-
-
- <p>Enabling output of status data, either via the debug attribute
- or equivalently by installing <code>OnConsoleStatusListener</code>,
- will go a long way in helping you diagnose logback issues. As such,
- enabling logback status data is very highly recommended and should
- be considered as a recourse of <b>first</b> resort.
- </p>
-
<h3 class="doAnchor" name="configFileProperty">Specifying the
location of the default configuration file as a system
property</h3>
@@ -475,7 +421,7 @@ public static void main(String[] args) {
<p class="example">Example: Scanning for changes in configuration
file and automatic re-configuration
- (logback-examples/src/main/resources/chapters/configuration/scan1.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/scan1.xml)</p>
<span class="asGroovy" onclick="return asGroovy('scan1');">View as .groovy</span>
<pre id="scan1" class="prettyprint source">
@@ -492,7 +438,7 @@ public static void main(String[] args) {
example:</p>
<p class="example">Example: Specifying a different scanning period
- (logback-examples/src/main/resources/chapters/configuration/scan2.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/scan2.xml)</p>
<span class="asGroovy" onclick="return asGroovy('scan2');">View as .groovy</span>
<pre id="scan2" class="prettyprint source">
<configuration scan="true" <b>scanPeriod="30 seconds"</b> >
@@ -543,55 +489,6 @@ public static void main(String[] args) {
</p>
- <h4 class="doAnchor" name="packagingData">Enabling packaging data in stack traces</h4>
-
- <p class="highlight">While useful, packaging data is expensive to
- compute, especially in applications with frequent exceptions.</p>
-
- <p><span class="label notice">NOTE</span> As of version 1.1.4,
- packaging data is disabled by default. </p>
-
- <p>If instructed to do so, logback can include packaging data for
- each line of the stack trace lines it outputs. Packaging data
- consists of the name and version of the jar file whence the class
- of the stack trace line originated. Packaging data can be very
- useful in identifying software versioning issues. However, it is
- rather expensive to compute, especially in application where
- exceptions are thrown frequently. Here is a sample output:</p>
-
- <pre>14:28:48.835 [btpool0-7] INFO c.q.l.demo.prime.PrimeAction - 99 is not a valid value
-java.lang.Exception: 99 is invalid
- at ch.qos.logback.demo.prime.PrimeAction.execute(PrimeAction.java:28) [classes/:na]
- at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431) <b>[struts-1.2.9.jar:1.2.9]</b>
- at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236) [struts-1.2.9.jar:1.2.9]
- at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432) [struts-1.2.9.jar:1.2.9]
- at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) <b>[servlet-api-2.5-6.1.12.jar:6.1.12]</b>
- at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502) [jetty-6.1.12.jar:6.1.12]
- at ch.qos.logback.demo.UserServletFilter.doFilter(UserServletFilter.java:44) [classes/:na]
- at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115) <b>[jetty-6.1.12.jar:6.1.12]</b>
- at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:361) [jetty-6.1.12.jar:6.1.12]
- at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417) [jetty-6.1.12.jar:6.1.12]
- at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230) [jetty-6.1.12.jar:6.1.12]</pre>
-
-
- <p>Packaging data is disabled by default but can be enabled by
- configuration:</p>
-
-<pre class="prettyprint source">
-<configuration <span class="big bold">packagingData="true"</span>>
- ...
-</configuration></pre>
-
- <p>Alternatively, packaging data can be enabled/disabled
- programmatically by invoking the <a
- href="../apidocs/ch/qos/logback/classic/LoggerContext.html#setPackagingDataEnabled(boolean)">setPackagingDataEnabled(boolean)</a>
- method in <code>LoggerContext</code>, as shown next:</p>
-
-
-<pre class="prettyprint lang-java source">
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- <b>lc.setPackagingDataEnabled(true);</b>
-</pre>
<h3 class="doAnchor" name="joranDirectly">Invoking
<code>JoranConfigurator</code> directly</h3>
@@ -738,7 +635,7 @@ public class MyApp3 {
within a configuration file. Here is an example.</p>
<p class="example">Example: Registering a status listener
- (logback-examples/src/main/resources/chapters/configuration/onConsoleStatusListener.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml)</p>
<span class="asGroovy" onclick="return asGroovy('onConsoleStatusListener');">View as .groovy</span>
<pre id="onConsoleStatusListener" class="prettyprint source"><configuration>
@@ -796,35 +693,12 @@ import ch.qos.logback.classic.LoggerContext;
<b>LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
<b>loggerContext.stop();</b></pre>
- <p>In web-applications the above code could be invoked from within
- the <a
+ <p>In web-applications, such code would be invoked from within the
+ <a
href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html#contextDestroyed(javax.servlet.ServletContextEvent)">contextDestroyed</a>
method of <code>ServletContextListener</code> in order to stop
logback-classic and release resources.
- </p>
- <h4 class="doAnchor" name="shutdownHook">Stopping logback-classic
- via a shutdown hook</h4>
-
- <p>Installing a JVM shutdown hook is a convenient way for shutting
- down logback and releasing associated resources.
- </p>
-
-
- <pre class="prettyprint source"><configuration debug="true">
- <!-- in the absence of the class attribute, assume
- ch.qos.logback.core.hook.DelayingShutdownHook -->
- <b><shutdownHook/></b>
- ....
-</configuration></pre>
-
- <p>The default shutdown hook, namely <a
- href="../apidocs/ch/qos/logback/core/hook/DelayingShutdownHook.html">DelayingShutdownHook</a>,
- can delay shutdown by a user specified duration. Note that you may
- install a shutdown hook of your own making by setting the <span
- class="attr">class</span> attribute to correspond to your shutdown
- hook's class name.</p>.
-
<h2 class="doAnchor" name="syntax">Configuration file syntax</h2>
<p>As you have seen thus far in the manual with plenty of examples
@@ -847,7 +721,7 @@ import ch.qos.logback.classic.LoggerContext;
possible to specify the allowed syntax with a DTD file or an XML
schema. Nevertheless, the very basic structure of the configuration
file can be described as, <code><configuration></code> element,
- containing zero or more <code><appender></code> elements,
+ followed by zero or more <code><appender></code> elements,
followed by zero or more <code><logger></code> elements,
followed by at most one <code><root></code> element. The
following diagram illustrates this basic structure.</p>
@@ -963,7 +837,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Setting the level of a logger
- (logback-examples/src/main/resources/chapters/configuration/sample2.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/sample2.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sample2');">View as .groovy</span>
<pre id="sample2" class="prettyprint source"><configuration>
@@ -1004,7 +878,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Setting the level of multiple loggers
- (logback-examples/src/main/resources/chapters/configuration/sample3.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/sample3.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sample3');">View as .groovy</span>
<pre id="sample3" class="source prettyprint"><configuration>
@@ -1086,7 +960,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Logger level sample
- (logback-examples/src/main/resources/chapters/configuration/sample4.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/sample4.xml)</p>
<span class="asGroovy" onclick="return asGroovy('sample4');">View as .groovy</span>
<pre id="sample4" class="prettyprint source"><configuration>
@@ -1211,7 +1085,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Multiple loggers
- (logback-examples/src/main/resources/chapters/configuration/multiple.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/multiple.xml)</p>
<span class="asGroovy" onclick="return asGroovy('multiple');">View as .groovy</span>
<pre id="multiple" class="prettyprint source"><configuration>
@@ -1266,7 +1140,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Duplicate appender
- (logback-examples/src/main/resources/chapters/configuration/duplicate.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/duplicate.xml)</p>
<span class="asGroovy" onclick="return asGroovy('duplicate');">View as .groovy</span>
<pre id="duplicate" class="prettyprint source"><configuration>
@@ -1316,7 +1190,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Multiple appender
- (logback-examples/src/main/resources/chapters/configuration/restricted.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/restricted.xml)</p>
<span class="asGroovy" onclick="return asGroovy('restricted');">View as .groovy</span>
<pre id="restricted" class="prettyprint source"><configuration>
@@ -1359,7 +1233,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Additivity flag
- (logback-examples/src/main/resources/chapters/configuration/additivityFlag.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/additivityFlag.xml)</p>
<span class="asGroovy" onclick="return asGroovy('additivityFlag');">View as .groovy</span>
<pre id="additivityFlag" class="prettyprint source"><configuration>
@@ -1415,7 +1289,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Set the context name and display it
- (logback-examples/src/main/resources/chapters/configuration/contextName.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/contextName.xml)</p>
<span class="asGroovy" onclick="return asGroovy('contextName');">View as .groovy</span>
<pre id="contextName" class="prettyprint source"><configuration>
@@ -1448,11 +1322,10 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p>As in many scripting languages, logback configuration files
- support definition and substitution of variables. Variables have a
- <a href="#scopes">scope</a> (see below). Moreover, variables can be
+ support definition and substitution of variables. Variables can be
defined within the configuration file itself, in an external file,
in an external resource or even computed and <a
- href="#definingPropsOnTheFly">defined on the fly</a>.
+ href="#definingPropsOnTheFly">defined on the fly</a>.
</p>
<p class="highlight">Variable substitution can occur at any point in
@@ -1467,7 +1340,7 @@ import ch.qos.logback.classic.LoggerContext;
value held by the <em>aName</em> property.
</p>
-
+ <p>Variables have a <a href="#scopes">scope</a> (see below).</p>
<p>As they often come in handy, the HOSTNAME and CONTEXT_NAME
variables are automatically defined and have context scope.</p>
@@ -1487,7 +1360,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Simple Variable substitution
- (logback-examples/src/main/resources/chapters/configuration/variableSubstitution1.xml)
+ (logback-examples/src/main/java/chapters/configuration/variableSubstitution1.xml)
</p>
<span class="asGroovy" onclick="return asGroovy('variableSubstitution1');">View as .groovy</span>
@@ -1516,7 +1389,7 @@ import ch.qos.logback.classic.LoggerContext;
<p class="source">java -DUSER_HOME="/home/sebastien" MyApp2</p>
<p class="example">Example: System Variable substitution
- (logback-examples/src/main/resources/chapters/configuration/variableSubstitution2.xml)
+ (logback-examples/src/main/java/chapters/configuration/variableSubstitution2.xml)
</p>
<span class="asGroovy" onclick="return asGroovy('variableSubstitution2');">View as .groovy</span>
<pre id="variableSubstitution2" class="prettyprint source"><configuration>
@@ -1541,7 +1414,7 @@ import ch.qos.logback.classic.LoggerContext;
<p class="example">Example: Variable substitution using a
separate file
- (logback-examples/src/main/resources/chapters/configuration/variableSubstitution3.xml)
+ (logback-examples/src/main/java/chapters/configuration/variableSubstitution3.xml)
</p>
<span class="asGroovy" onclick="return asGroovy('variableSubstitution3');">View as .groovy</span>
<pre id="variableSubstitution3" class="prettyprint source"><configuration>
@@ -1567,7 +1440,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<em>Example: Variable file
- (logback-examples/src/main/resources/chapters/configuration/variables1.properties)</em>
+ (logback-examples/src/main/java/chapters/configuration/variables1.properties)</em>
<pre class="source">USER_HOME=/home/sebastien</pre>
@@ -1641,7 +1514,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: A variable defined in "context" scope
- (logback-examples/src/main/resources/chapters/configuration/contextScopedVariable.xml)
+ (logback-examples/src/main/java/chapters/configuration/contextScopedVariable.xml)
</p>
<span class="asGroovy" onclick="return
@@ -1695,7 +1568,7 @@ import ch.qos.logback.classic.LoggerContext;
</p>
<p class="example">Example: Nested variable references
- (logback-examples/src/main/resources/chapters/configuration/variables2.properties)</p>
+ (logback-examples/src/main/java/chapters/configuration/variables2.properties)</p>
<pre class="source">USER_HOME=/home/sebastien
fileName=myApp.log
@@ -1708,7 +1581,7 @@ fileName=myApp.log
<em>Example: Variable substitution using
a separate file
- (logback-examples/src/main/resources/chapters/configuration/variableSubstitution4.xml)</em>
+ (logback-examples/src/main/java/chapters/configuration/variableSubstitution4.xml)</em>
<pre class="prettyprint source"><configuration>
@@ -1944,7 +1817,7 @@ fileName=myApp.log
<p class="example">Example: Insert as properties env-entries
obtained via JNDI
- (logback-examples/src/main/resources/chapters/configuration/insertFromJNDI.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/insertFromJNDI.xml)</p>
<pre class="prettyprint source"><configuration>
<b><insertFromJNDI env-entry-name="java:comp/env/appName" as="<span class="green">appName"</span> /></b>
@@ -1977,7 +1850,7 @@ fileName=myApp.log
</p>
<p class="example">Example: File include
- (logback-examples/src/main/resources/chapters/configuration/containingConfig.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/containingConfig.xml)</p>
<pre class="prettyprint source"><configuration>
<b><include file="src/main/java/chapters/configuration/includedConfig.xml"/></b>
@@ -1994,7 +1867,7 @@ fileName=myApp.log
</p>
<p class="example">Example: File include
- (logback-examples/src/main/resources/chapters/configuration/includedConfig.xml)</p>
+ (logback-examples/src/main/java/chapters/configuration/includedConfig.xml)</p>
<pre class="source"><b class="green big"><included></b>
<appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
@@ -2037,7 +1910,7 @@ fileName=myApp.log
<p>If it cannot find the file to be included, logback will complain
by printing a status message. In case the included file is
- optional, you can suppress the warning message by setting <span
+ optional, you can suppres the error message by setting <span
class="attr">optional</span> attribute to <code>true</code> in the
<code><include></code> element.</p>
@@ -2100,6 +1973,7 @@ fileName=myApp.log
</p>
+
<script src="../templates/footer.js" type="text/javascript"></script>
</div>
</body>
diff --git a/logback-site/src/site/pages/manual/configuration_ja.html b/logback-site/src/site/pages/manual/configuration_ja.html
deleted file mode 100644
index 9bde5c1..0000000
--- a/logback-site/src/site/pages/manual/configuration_ja.html
+++ /dev/null
@@ -1,1273 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第3章 logbackの設定</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content" class="chapter">
-
- <h1>第3章 logbackの設定</h1>
-
- <div class="quote">
- <p><em>物事の本質を正確に表現するときは、記号を使うのが最も適している。また、記号によって表現されたものがあれば、思考に費やす労力が驚くほど軽減されるのだ。</em>
- </p>
- <p>—GOTTFRIED WILHELM LEIBNIZ</p>
- </div>
-
-
- <script src="../templates/creative.js" type="text/javascript"></script>
-
-
- <p>設定スクリプトの例を示しながら、logback の設定方法を説明していきます。logback は Joran という設定フレームワークを利用しています。Joran については<a href="./11-onJoran.html">後の章</a>で紹介します。
- </p>
-
-
- <h2 class="doAnchor" name="auto_configuration">logback の設定</h2>
-
- <p>アプリケーションコードにロギング要求を埋め込むには、かなりの計画と作業が必要です。調査したところ、だいたいコード全体の4%ほどがロギングのために使われていました。したがって、そこそこの規模のアプリケーションであっても、数千行のロギング行が含まれることになるのです。その数を考えれば、私たちにロギング式を管理するためのツールが必要となる理由が理解できるのではないでしょうか。
- </p>
-
- <p>logback はプログラム的に設定することもできるし、XML や Groovy で記述された設定スクリプトで設定することもできます。なお、log4jユーザーのために、<em>log4j.propertiesファイル</em>を<em>logback.xml</em>に変換する<a href="http://logback.qos.ch/translator/">PropertiesTranslator</a>を用意しています。
-
- </p>
-
- <p>さて、logback が設定するところを順番に見ていきましょう。</p>
-
- <ol>
- <li>
- <p>logback は<a href="./faq.html#configFileLocation">クラスパス</a>上で<em>logback.groovy</em>というファイルを探します。</p>
- </li>
-
- <li>
- <p>見つからなかったら、今度は<a href="./faq.html#configFileLocation">クラスパス</a>上で<em>logback-test.xml</em>というファイルを探します。</p>
- </li>
-
- <li><p>見つからなかったら、今度は<a href="./faq.html#configFileLocation">クラスパス</a>上で<em>logback.xml</em>というファイルを探します。</p>
- </li>
-
- <li><p>何も見つからなかったら、自動的に<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/BasicConfigurator.html"><code>BasicConfigurator</code></a>を使って設定します。ロギング出力は直接コンソールに出力されるようになります。
- </p>
- </li>
-
- </ol>
-
- <p>四番目のステップは、設定ファイルが見つからなかった場合デフォルトの(ごく基本的な)設定をする、ということです。
- </p>
-
-
- <p>もし Maven を使用しているなら、<em>src/test/resources</em> フォルダの下に <em>logback-test.xml</em>を置いている場合でも、それがアーティファクトに入り込まないことは Maven によって保証されます。したがって、テスト用と実際の環境用で、<em>logback-test.xml</em>と<em>logback.xml</em>を使い分けることができます。Antでも原則的に同じことができます。
- </p>
-
-
- <h3 class="doAnchor" name="automaticConf">logback の自動設定</h3>
-
- <p>logback を設定する一番簡単な方法は、デフォルト設定を使わせることです。仮に<code>MyApp1</code>というアプリケーションがあるつもりで、これがどのように行われるのか詳しく見てみましょう。
- </p>
-
- <p class="example">例:<code>BasicConfigurator</code>の使用例(<a href="http://logback.qos.ch/xref/chapters/configuration/MyApp1.html">logback-examples/src/main/java/chapters/configuration/MyApp1.java</a>)</p>
-
- <pre class="prettyprint source">package manual.configuration;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MyApp1 {
- final static Logger logger = LoggerFactory.getLogger(MyApp1.class);
-
- public static void main(String[] args) {
- logger.info("Entering application.");
-
- Foo foo = new Foo();
- foo.doIt();
- logger.info("Exiting application.");
- }
-}</pre>
-
- <p>このクラスでは、ロガーを静的クラスメンバ変数として定義しています。その後、<code>Foo</code>クラスのオブジェクトを生成します。<code>Foo</code>クラスの定義は次のとおりです。</p>
-
- <p class="example">例:ロギングするクラスの例(<a href="http://logback.qos.ch/xref/chapters/configuration/Foo.html">logback-examples/src/main/java/chapters/configuration/Foo.java</a>)
- </p>
-
- <pre class="prettyprint source">package chapters.configuration;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class Foo {
- static final Logger logger = LoggerFactory.getLogger(Foo.class);
-
- public void doIt() {
- logger.debug("Did it again!");
- }
-}</pre>
-
-
- <p>この章で紹介しているサンプルプログラムを実行するには、クラスパスに所定のjarファイルを置いておかなければなりません。詳しくは<a href="http://logback.qos.ch/setup.html">セットアップ</a>の説明をを参照してください。
- </p>
-
- <p><em>logback-test.xml</em>も<em>logback.xml</em>も無い場合、logback は<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/BasicConfigurator.html"><code>BasicConfigurator</code></a>によって最小限の設定を行います。最小限の設定としてやることは、ルートロガーに<code>ConsoleAppender</code>を割り当てることだけです。出力は<code>PatternLayoutEncoder</code>によって書式化されます。<code>PatternLayoutEncoder</code>には、<em>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</em>という書式化パターンが設定されています。また、ルートロガーにはデフォルトで<code>DEBUG</code>レベルが割り当てられます。
- </p>
-
- <p><em>java chapters.configuration.MyApp1</em>を実行すると次のような出力が得られます。</p>
-
- <p class="source">16:06:09.031 [main] INFO chapters.configuration.MyApp1 - Entering application.
-16:06:09.046 [main] DEBUG chapters.configuration.Foo - Did it again!
-16:06:09.046 [main] INFO chapters.configuration.MyApp1 - Exiting application.</p>
-
-
- <p class="highlight">(あるとしたら)logback を設定するコード以外に、クライアントコードは一切logbackに依存しません。ロギングフレームワークとしてlogbackを使用するアプリケーションがコンパイル時に依存するのはSLF4Jであって、logbackではありません。
- </p>
-
- <p><code>MyApp1</code>アプリケーションとlogbackのリンクは、アプリケーションが呼び出した<code>org.slf4j.LoggerFactory</code>クラスと<code>org.slf4j.Logger</code>クラスによって行われます。これらのクラスは、使用するロガーを(クラスローダーから?)取得し、つなぎあわせます。<code>Foo</code>クラスからlogbackへの依存は、<code>org.slf4j.LoggerFactory</code>と<code>org.slf4j.Logger</code>のimportを介した間接的なものであることに注意しましょう。SLF4Jはあらゆるロギングフレームワークから利用するための抽象層を備えています。おかで、ほとんどのコードをあるロギングフレームワークから別のロギングフレームワークに移行するのがとても簡単になっています。
- </p>
-
- <h3><em>logback-test.xml</em>または<em>logback.xml</em>による自動設定</h3>
-
- <p>前述したとおり、logback はクラスパス上で<em>logback-test.xml</em>や<em>logback.xml</em>を探して自分を設定しようとします。次に示す設定ファイルは、<code>BasicConfigurator</code>によって行われるのとまったく同じ内容の設定です。
- </p>
-
- <p class="example">例:基本的な設定ファイル(<a href="http://logback.qos.ch/xref/chapters/configuration/sample0.xml">logback-examples/src/main/java/chapters/configuration/sample0.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('sample0');">Groovyで見る</span>
-
-
- <pre id="sample0" class="prettyprint source"><configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <!-- encoders are assigned the type
- ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>ファイル名を<em>sample0.xml</em>から<em>logback.xml</em>(または<em>logback-test.xml</em>)に変更して、クラスパスに含まれるフォルダに置きましょう。そして<em>MyApp1</em>アプリケーションを実行すると、前の実行例と同じ出力結果が得られるはずです。</p>
-
- <h4 class="doAnchor" name="automaticStatusPrinting">警告やエラーが発生した際、ステータスメッセージを自動的に出力する</h4>
-
- <p class="highlight">設定ファイルを解析している間に警告やエラーが発生した場合、logback は内部状態を表すメッセージを自動的にコンソールに出力します。</p>
-
- <p>出力が重複することを避けるため、利用者が明示的にステータスリスナーを登録していた場合(後で例を示します)ステータスの自動出力は無効になります。</p>
-
- <p>警告やエラーが起きていなくても logback の内部状態を出力させたければ、<code>StatusPrinter</code>クラスの<code>print()</code>メソッドを使えばよいです。次の<em>MyApp2</em>アプリケーションは、内部状態を出力するためのコードが二行追加されていることを除いて<em>MyApp1</em>とまったく同じです。</p>
-
- <p class="example">例:logbackの内部状態を出力する(<a href="http://logback.qos.ch/xref/chapters/configuration/MyApp2.html">logback-examples/src/main/java/chapters/configuration/MyApp2.java</a>)</p>
-
-
-<pre class="prettyprint lang-java source">
- public static void main(String[] args) {
- // SLF4J が logback を使うようになっていると想定
- <b>LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
- // logback の内部状態を出力
- <b>StatusPrinter.print(lc);</b>
- ...
- }</pre>
-
- <p>何も問題が無ければ、コンソールに次のような出力が表示されます。</p>
-
- <div class="source longline"><pre>17:44:58,578 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml]
-17:44:58,671 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
-17:44:58,671 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
-17:44:58,687 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
-17:44:58,812 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Popping appender named [STDOUT] from the object stack
-17:44:58,812 |-INFO in ch.qos.logback.classic.joran.action.LevelAction - root level set to DEBUG
-17:44:58,812 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[root]
-
-17:44:58.828 [main] INFO chapters.configuration.MyApp2 - Entering application.
-17:44:58.828 [main] DEBUG chapters.configuration.Foo - Did it again!
-17:44:58.828 [main] INFO chapters.configuration.MyApp2 - Exiting application.
-</pre></div>
-
- <p>出力結果の最後の方に、前の例で出力されたものと同じ行があることが分かるでしょう。logback の内部メッセージには気をつけるようにしてください。<code>Status</code>オブジェクトを使うと内部状態に簡単にアクセスできます。
- </p>
-
- <p>コード中で<code>StatusPrinter</code>をプログラム的に呼び出す代わりに、設定ファイルで内部ステータスを出力するように指定することができます。警告やエラーが起きなくてもです。そのためには<em>configuration</em>要素の<span class="attr">debug</span>属性を設定します。この要素はXML形式の設定ファイルにおける最上位要素です。後で例を示します。<span class="attr">debug</span>属性はステータス情報にだけしか影響しないことは覚えておいてください。繰り返しますが、logback の他の設定には<em>影響しません</em>。ロガーレベルについても同様です。(たとえそうなっていて欲しくても、ルートロガーのログレベルは<code>DEBUG</code>に<em>なりません</em>。)
- </p>
-
-
- <p class="example">例:基本的な設定ファイルをデバッグモードにする(<a href="http://logback.qos.ch/xref/chapters/configuration/sample1.xml">logbackexamples/src/main/java/chapters/configuration/sample1.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('sample1');">Groovyで見る</span>
-
- <pre id="sample1" class="prettyprint source">
-<configuration <span class="big bold">debug="true"</span>>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <!-- encoders are by default assigned the type
- ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>configuration 要素の<code>debug</code>属性が設定されていると、次のような内部ステータスが出力されます。</p>
- <ol>
- <li>設定ファイルが見つかったかどうか</li>
- <li>設定ファイルのXML文法が適格かどうか</li>
- </ol>
-
- <p>これらのいずれかの条件が満たされなかった場合、設定ファイルを読み込むことができないので、Joran には<span class="attr">debug</span>属性を理解することができません。見つかった設定ファイルがXMLとして不適格な場合、logback はエラーと判断し、自動的に内部状態をコンソールに出力します。ですが、設定ファイルが見つからなかった場合、logback は内部状態を自動的に出力することはありません。それだけではエラーと見做すには不十分だからです。<a href="http://logback.qos.ch/xref/chapters/configuration/MyApp2.html"><em>MyApp2</em></a>アプリケーションの例で示したように、<code>StatusPrinter.print()</code>をプログラム的に呼び出していれば、どんな場合でも内部ステータス情報を確実に出力するようになります。</p>
-
-
- <p>ステータスメッセージが無くても<span class="label">強制的に</span>内部ステータス情報を出力させていると、不正な<em>logback.xml</em>がどこにあるのか突き止めるのが難しくなります。アプリケーションのソースコードを簡単に変更できない商用環境においては特にそうです。不正な設定ファイルの場所を見つけやすくするには、システムプロパティの"logback.statusListenerClass"(<a href="./03-configuration.html#logback.statusLC">すぐ後で説明します</a>)に<code>StatusListener</code>を指定するとよいでしょう。そうすれば、強制的にステータスメッセージを出力させることができます。"logback.statusListenerClass" システムプロパティを使うと、エラーが発生したときに自動的に出力されるメッセージを抑止することもできます。
- </p>
-
- <h3 class="doAnchor" name="configFileProperty">システムプロパティでデフォルトの設定ファイルの場所を指定する</h3>
-
- <p>システムプロパティの<code>"logback.configurationFile"</code>を使えば、デフォルトの設定ファイルの場所を指定することができます。このプロパティにはURL形式の値を指定します。クラスパス上のリソースやアプリケーションの外部のファイルを指定することができます。
- </p>
-
- <p class="source">java <b>-Dlogback.configurationFile=/path/to/config.xml</b> chapters.configuration.MyApp1</p>
-
- <p>ファイルの拡張子は ".xml" か ".groovy" でなければならないので注意してください。他の拡張子の場合は無視します。<a href="./03-configuration.html#logback.statusLC">ステータスリスナーを明示的に登録</a>しておくと、設定ファイルの場所を突き止めるのに役立つでしょう。</p>
-
-
- <h3 class="doAnchor" name="autoScan">設定ファイルが変更されたら自動的に再読み込みする</h3>
-
- <p class="highlight">logback-classic は設定ファイルの変更を監視することができます。そして、なんらか変更があった場合は自動的に再読み込みすることができます。</p>
-
- <p><code>configuration</code>要素の<span class="attr">scan</span>属性を設定すると、設定ファイルの監視と自動的な再読み込みができるようになります。
-
- </p>
-
- <p class="example">例:設定ファイルの変更の監視と自動的な再読み込み(<a href="http://logback.qos.ch/xref/chapters/configuration/scan1.xml">logback-examples/src/main/java/chapters/configuration/scan1.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('scan1');">Groovyで見る</span>
-<pre id="scan1" class="prettyprint source">
-<configuration <b>scan="true"</b>>
- ...
-</configuration> </pre>
-
-
- <p>デフォルトでは、設定ファイルを一分毎に監視します。<code>configuration</code>要素の<span class="attr">scanPeriod</span>属性に、監視周期を設定することができます。設定値はミリ秒、秒、分または時間単位で指定することができます。以下に例を示します。</p>
-
- <p class="example">例:デフォルトとは異なる監視周期を指定する(<a href="http://logback.qos.ch/xref/chapters/configuration/scan2.xml">logback-examples/src/main/java/chapters/configuration/scan2.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('scan2');">Groovyで見る</span>
- <pre id="scan2" class="prettyprint source">
-<configuration scan="true" <b>scanPeriod="30 seconds"</b> >
- ...
-</configuration> </pre>
-
- <p>時間の単位を指定しなかった場合ミリ秒として扱われますが、たいていの場合不適切だと思いますので<span class="label">注意</span>してください。時間単位を指定することを忘れないでください。
- </p>
-
- <p>舞台裏で起きていることを説明しましょう。scan 属性に true を指定すると、<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.html">ReconfigureOnChangeFilter</a>という<code>TurboFilter</code>の派生クラスがインストールされます。TurboFiltersについては<a href="./filters.html#TurboFilter">後の章</a> で説明します。設定ファイルのスキャンは「内部スレッド」で行います。ロガーの出力メソッドが呼び出されるときは常にスキャンされるということです。(訳注:正確には、出力メソッドが呼び出されるたびにフィルタが評価されるので、その都度 logback のコンテキストに指定された ThreadExecutor にファイルをスキャンするタスクが投入されます。そして、ThreadExecutor の管理するスレッドによって実行されます。 [...]
- </p>
-
- <p class="highlight">設定ファイルを変更すると、何回かロギング処理を実行した後で、かつ、監視周期に基いて決定した遅延時間が経過したら、自動的に再読み込みします。
- </p>
-
- <p><em>どんな</em>ロガーであれ、ロガーレベルがどうであれ、出力メソッドを呼び出すと<code>ReconfigureOnChangeFilter</code>も呼び出すことになるので、間違いなく致命的な性能影響があります。したがって、監視周期が経過していようともいまいとも、とてもコストの高い処理になります。性能を改善するため、実際に<code>ReconfigureOnChangeFilter</code>が有効になるのは、<em>N</em>回のロギングごとに一回だけです。あなたのアプリケーションがどれくらいの頻度でロギングするのかにもよるのですが、logback は<em>N</em>の値を実行している環境に合わせて調整します。Nのデフォルト値は16です。CPUを占有するアプリケーションの場合最大で2^16(=65536)にまで増えます。
- </p>
-
- <p>簡単に言うとこうなります。設定ファイルを変更すると、何回かロギング処理を実行した後で、かつ、監視周期に基いて決定した遅延時間が経過したら、自動的に再読み込みします。
- </p>
-
-
-
- <h3 class="doAnchor" name="joranDirectly"><code>JoranConfigurator</code>を直接呼び出す</h3>
-
- <p>logback は、logbac-core に含まれる Joran という設定用ライブラリを利用しています。logback のデフォルトの設定の仕組みでは、<code>JoranConfigurator</code>を呼び出して、クラスパス上で見つけたデフォルトの設定ファイルを渡すようになっています。何か理由があってデフォルトの設定の仕組みを上書きしたい場合、<code>JoranConfigurator</code>を直接呼び出すことができます。次に示す<em>MyApp3</em>アプリケーションでは、設定ファイルを引数としてJoranConfiguratorを呼び出しています。</p>
-
- <p class="example">例:<code>JoranConfigurator</code>を直接呼び出す(<a href="http://logback.qos.ch/xref/chapters/configuration/MyApp3.html">logback-examples/src/mian/java/chapters/configuration/MyApp3.java</a>)</p>
-
-<pre class="prettyprint source">package chapters.configuration;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.core.joran.spi.JoranException;
-import ch.qos.logback.core.util.StatusPrinter;
-
-public class MyApp3 {
- final static Logger logger = LoggerFactory.getLogger(MyApp3.class);
-
- public static void main(String[] args) {
- // SLF4J が logback を使うようになっていると想定
- <b>LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
-
- <b>try {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(context);
- // デフォルト設定を取り消すために context.reset() を呼び出す
- // 複数の設定を積み重ねる場合は呼ばないようにする
- context.reset();
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- // StatusPrinter will handle this
- }
- StatusPrinter.printInCaseOfErrorsOrWarnings(context);</b>
-
- logger.info("Entering application.");
-
- Foo foo = new Foo();
- foo.doIt();
- logger.info("Exiting application.");
- }
-}</pre>
-
- <p>アプリケーションは、新しく生成した<code>JoranConfigurator</code>を、有効な<code>LoggerContext</code>に設定してから、ロガーコンテキストを初期化します。そして、アプリケーションの引数として渡された設定ファイルを使ってconfiguratorに設定させています。警告やエラーが発生した場合、内部ステータスが出力されます。複数の設定を積み重ねる場合は、<code>context.reset()</code>を呼び出さないようにしなければなりません。</p>
-
- <h3 class="doAnchor" name="viewingStatusMessages">ステータスメッセージの内容</h3>
-
- <p>logback は <code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/status/StatusManager.html">StatusManager</a></code>オブジェクトに内部ステータス情報を蓄積しています。このオブジェクトは<code>LoggerContext</code>からアクセスすることができます。
- </p>
-
- <p><code>StatusManager</code>があれば、logbackのコンテキストに関連付けられた全てのステータス情報にアクセスすることができます。メモリ使用量を妥当なレベルで抑えるため、<code>StatusManager</code>のデフォルト実装ではステータスメッセージを先頭と末尾に分けて格納しています。先頭には最初の<em>H</em>個のステータスメッセージを格納し、末尾には最後の<em>T</em>個のステータスメッセージを格納します。今のところ<em>H</em>も<em>T</em>も150になっていますが、将来的にこの値は変更されるかもしれません。</p>
-
- <p>logback-classic の配布物には、ViewStatusMessagesServlet というサーブレットが含まれています。このサーブレットは、<code>LoggerContext</code>に関連付けられた<code>StatusManager</code>の持つステータスメッセージを、HTML の表で描画します。出力サンプルは次のようになります。
- </p>
-
- <a href="./lbClassicStatus.jpg">
- <img src="images/chapters/configuration/lbClassicStatus.jpg" alt="クリックすると拡大します" width="90%">
- </a>
-
- <p>Webアプリケーションにこのサーブレットを追加するには、<em>WEB-INF/web.xml</em>に次の行を追加します。</p>
-
- <pre class="prettyprint source"> <servlet>
- <servlet-name>ViewStatusMessages</servlet-name>
- <servlet-class>ch.qos.logback.classic.ViewStatusMessagesServlet</servlet-class>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>ViewStatusMessages</servlet-name>
- <url-pattern>/lbClassicStatus</url-pattern>
- </servlet-mapping></pre>
-
- <p><code>ViewStatusMessages</code>サーブレットにアクセスするためのURLは次のようになります。
-<code>http://host/yourWebapp/lbClassicStatus</code>
- </p>
-
- <h3 class="doAnchor" name="statusListener">ステータスメッセージの待ち受け</h3>
-
- <p><code>StatusManager</code>に<code>StatusListener</code>を割り当てて、ステータスメッセージを受け取った応答として直ちに何らかの処理を実行させることができます。ただし、ステータスメッセージを受け取ることができるのは logback の設定が完了した後になります。ステータスリスナーを登録しておくと、人間が介入しなくてもlogbackの内部状態を監視できるようになるので便利です。
- </p>
-
- <p>logback の配布物には<code>StatusListener</code>を実装した<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/status/OnConsoleStatusListener.html">OnConsoleStatusListener</a></code>というクラスが含まれています。名前が表すとおり、<em>到着した</em>ステータスメッセージを全てコンソールに出力します。
- </p>
-
- <p>これは、StatusManager に<code>OnConsoleStatusListenerを登録する<a href="http://logback.qos.ch/xref/chapters/configuration/AddStatusListenerApp.html">サンプルコード</a>です。</code>
- </p>
-
- <pre class="prettyprint source"> LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- StatusManager statusManager = lc.getStatusManager();
- OnConsoleStatusListener onConsoleListener = new OnConsoleStatusListener();
- statusManager.add(onConsoleListener);</pre>
-
- <p>ステータスリスナーは、登録された後に発生したステータスメッセージだけしか受け取らないので気をつけてください。それより前のステータスメッセージは受け取りません。ですので、ステータスリスナーの登録を設定ファイルの一番最初の方に置いて、他のディレクティブよりも先に評価されるようにするとよいでしょう。</p>
-
- <p>また、これは一つ以上のステータスリスナーを登録できるということでもあります。例を示します。</p>
-
- <p class="example">例:ステータスリスナーの登録(<a href="http://logback.qos.ch/xref/chapters/configuration/onConsoleStatusListener.xml">logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('onConsoleStatusListener');">Groovyで見る</span>
- <pre id="onConsoleStatusListener" class="prettyprint source"><configuration>
- <b><statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /></b>
-
- ... the rest of the configuration file
-</configuration></pre>
-
- <h3 class="doAnchor" name="logback.statusLC">システムプロパティ "logback.statusListenerClass"</h3>
-
- <p>ステータスリスナーを登録するには、システムプロパティの "logback.statusListenerClass" に、リスナークラス名を設定する方法もあります。例を示します。</p>
-
- <p class="source">java <b>-Dlogback.statusListenerClass</b>=ch.qos.logback.core.status.OnConsoleStatusListener ...</p>
-
- <p>logback の配布物にはいくつかのステータスリスナー実装が含まれています。<a href="http://logback.qos.ch/xref/ch/qos/logback/core/status/OnConsoleStatusListener.html">OnConsoleStatusListener</a> は、受け取ったステータスメッセージを、コンソール(例えばSystem.out)に出力します。<a href="http://logback.qos.ch/xref/ch/qos/logback/core/status/OnErrorConsoleStatusListener.html">OnErrorConsoleStatusListener</a> は、受け取ったステータスメッセージをSystem.errに出力します。<a href="http://logback.qos.ch/xref/ch/qos/logback/core/status/NopStatusListener.html">NopStatusListener</a>は、受け取っ [...]
-
-
- <p>設定の途中でステータスリスナーを登録したり、システムプロパティの"logback.statusListenerClass" でステータスリスナーを指定した場合は、<a href="./03-configuration.html#automaticStatusPrinting">メッセージステータスの自動出力(エラー発生時)</a>が無効になるので気をつけてください。つまり、<code>NopStatusListener</code>を使うように設定すると、内部ステータスの出力を完全に止めることが出来るのです。</p>
-
- <p class="source">java <b>-Dlogback.statusListenerClass</b>=ch.qos.logback.core.status.NopStatusListener ...</p>
-
-
- <h3 class="doAnchor" name="stopContext">logback-classic を止める</h3>
-
- <p>logback-classic が使用しているリソースを解放するには、どんな場合でもlogbackコンテキストを停止することをお勧めします。コンテキストを停止すると、コンテキストに定義されたロガーに割り当てられている全てのアペンダーを閉じて、すべてのアクティブなスレッドを停止します。
- </p>
-
-<pre class="prettyprint lang-java source">
-import org.sflf4j.LoggerFactory;
-import ch.qos.logback.classic.LoggerContext;
-...
-
-// SLF4J が logback を使うようになっていると想定
-<b>LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
-<b>loggerContext.stop();</b></pre>
-
- <p>Webアプリケーションの場合、logback-classic を停止してリソースを開放するために、<code>ServletContextListener</code>の<a href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html#contextDestroyed(javax.servlet.ServletContextEvent)">contextDestroyed</a>メソッドから上記のようなコードを実行します。
-
- <h2 class="doAnchor" name="syntax">設定ファイルの構文</h2>
-
- <p>ここまでに、たくさんのわかりやすい例を見てきてお分かりのとおり、logback はコードを再コンパイルすること無く、ロギングの振る舞いを変えることができます。アプリケーションの特定の部分でロギングを無効にする、UNIX Syslog デーモンに直接出力する、データベースに出力する、ログの可視化ツールに出力する、別の logback サーバにロギングイベントを転送する、こういった色んな設定が実に簡単にできるようになっています。ロギングイベントの転送について補足すると、ログの転送はローカルサーバーのポリシーに従って行われます。例えば、ロギングイベントを二つ目のリモートlogbackサーバーに転送する、というようなものです。
- </p>
-
- <p>このセクションの残りの部分では、設定ファイルの構文を紹介します。
- </p>
-
- <p>すでに何度か読んできたとおり、logback の設定ファイル構文はとても柔軟になっています。そのため、DTD や XML スキーマによって定義することができません。そうは言っても設定ファイルの基本的な構成要素について説明しないと始まらないでしょう。次のように定義されています。<code>configuration</code>要素は、0以上の<code>appender</code>要素、0以上の<code>logger</code>要素、1つの<code>root</code>要素によって構成されています。次の図は、この基本構造を図示したものです。</p>
-
-
- <p align="left">
- <img src="images/chapters/configuration/basicSyntax.png" alt="基本的な構文" title="基本構成ファイルの構造">
- </p>
-
-
- <p class="highlight">タグ名に大文字と小文字のどちらを使うべきなのかわからないときは、<a href="http://en.wikipedia.org/wiki/CamelCase">キャメルケース規約</a>に従ってもらえれば、ほとんどの場合は合っていると思います。</p>
-
- <h4 class="doAnchor" name="caseSensitivity">タグ名の大文字小文字の区別</h4>
-
- <p>logback 0.9.17 以降のリリースから、タグ名の大文字小文字は区別しないと明記されるようになりました。例えば、<code><logger></code>と<code><Logger></code>と<code><LOGGER></code>はどれもconfiguration要素の子要素として正しく、同じように解釈されます。XMLとしての適格性ルールは有効なままなので、開きタグを<code><xyz></code>として書いたら、閉じタグは<code></xyz></code>でなければなりません。<code></XyZ></code>ではダメです。<a href="./onJoran.html#implicit">暗黙的なルール</a>として、タグ名については最初の一文字以外は大文字小文字を区別するようになっています。したがって、<code><xyz></code>と<code><Xyz></code>は同じものとみなされますが、<code><x [...]
- </p>
-
- <h4 class="doAnchor" name="loggerElement">ロガーの設定について、あるいは、<code>logger</code>要素について</h4>
-
- <p>ここでは、少なくとも<a href="./architecture.html#effectiveLevel">レベルの継承</a>と<a href="./architecture.html#basic_selection">基本的な選択ルール</a>についてある程度理解しておかなければなりません。そうでなければ、あなたがエジブト語の学者でも無い限り、logback の設定ファイルはヒエログラフよりも意味の無いものでしかないでしょう。
- </p>
-
- <p>ロガーは<code>logger</code>要素で設定します。<code>logger</code>要素には少なくとも一つの<span class="attr">name属性</span>が必要です。<span class="attr">level属性</span>、そして<em>true</em>または<em>false</em>を指定できる<span class="attr">additivity属性</span>は任意です。<span class="attr">level属性</span>にはTRACE、DEBUG、INFO、WARN、ERROR、ALLまたはOFFのいずれかの文字列を指定できます。大文字小文字は区別しません。大文字小文字を区別しない特別な値として<em>INHERITED</em>またはその同義語として<em>NULL</em>を指定すると、祖先から継承したロガーのレベルを強制的に使用することができます。ロガーのレベルを設定した後で、祖先ロガーのレベルを継承するべきだったことがわかった場合に便利です。
- </p>
-
- <p class="highlight">
- log4jとは違って、logback-classic はロガーを設定した時に割り当てたどんなアペンダーもくクローズ<em>しない</em>し削除もしないので注意してください。
- </p>
-
- <p><code>logger要素</code>には任意個の<code>appender-ref要素</code>を含めることができます。参照しているアペンダーがロガーに割り当てられます。log4jとは違って、logback-classic はロガーを設定した時に割り当てたどんなアペンダーもくクローズ<em>しない</em>し削除もしないので注意してください。
- </p>
-
-
-
- <h4 class="doAnchor" name="rootElement">ルートロガー、あるいは、<code>root</code>要素について</h4>
-
- <p>ルートロガーは<code>root</code>要素で設定します。たった一つ、<span class="attr">level属性</span>だけを指定できます。ルートロガーにはadditivity属性などの他の属性を指定することはできません。さらに、ルートロガーの名前は予め"ROOT"になっているので、name属性も指定することはできません。level属性にはTRACE、DEBUG、INFO、WARN、ERROR、ALLまたはOFFのいずれかの文字列を指定できます。大文字小文字は区別しません。ルートロガーにはINHERITEDまたはその同義語であるNULLを指定することはできません。</p>
-
- <p class="highlight">log4jとは違って、logback-classic はルートロガーを設定した時に割り当てたどんなアペンダーもくクローズ<em>しない</em>し削除もしないので注意してください。</p>
-
- <p><code>logger要素</code>と同じく、<code>root要素</code>には任意個の<code>appender-ref要素</code>を含めることができます。参照しているアペンダーがロガーに割り当てられます。log4jとは違って、logback-classic はルートロガーを設定した時に割り当てたどんなアペンダーもくクローズ<em>しない</em>し削除もしないので注意してください。
-</p>
-
- <h4>例</h4>
-
- <p>ロガーあるいはルートロガーにレベルを設定するのは非常に簡単です。例を示します。"chapters.configuration" パッケージのコンポーネントから出力されていたDEBUGメッセージが不要になったとしましょう。次の設定ファイルはそれを実現するための例です。
- </p>
-
- <p class="example">例:ロガーのレベルを設定する(<a href="http://logback.qos.ch/xref/chapters/configuration/sample2.xml">logback-examples/src/main/java/chapters/configuration/sample2.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('sample2');">Groovyで見る</span>
- <pre id="sample2" class="prettyprint source"><configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <!-- encoders are assigned the type
- ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <b><logger name="chapters.configuration" level="INFO"/></b>
-
- <!-- 厳密にはここでルートロガーのlevel要素を設定する必要はありません -->
- <!-- デフォルトでDEBUGが指定されるからです -->
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-
-</configuration></pre>
-
- <p>この設定ファイルを<em>MyApp3</em>アプリケーションの引数として渡すと、次のような出力が得られます。</p>
-
-<pre class="source">17:34:07.578 [main] INFO chapters.configuration.MyApp3 - Entering application.
-17:34:07.578 [main] INFO chapters.configuration.MyApp3 - Exiting application.</pre>
-
- <p><a href="http://logback.qos.ch/xref/chapters/configuration/Foo.html">"chapters.configuration.Foo</a>"のロガーが出力していたDEBUGメッセージが抑止されていることに気づきましたか。気になるならFooクラスを見なおしてください。</p>
-
- <p>あらゆるロガーのレベルを思った通りに設定することができます。次の設定ファイルでは、<em>chapters.configuration</em>ロガーのレベルをINFOに設定していますが、同時に<em>chapters.configuration.Foo</em>のレベルを<code>DEBUG</code>に設定しています。</p>
-
- <p class="example">例:複数のロガーのレベルを設定する(<a href="http://logback.qos.ch/xref/chapters/configuration/sample3.xml">logback-examples/src/main/java/chapters/configuration/sample3.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('sample3');">Groovyで見る</span>
- <pre id="sample3" class="source prettyprint"><configuration>
-
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>
- %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
- </pattern>
- </encoder>
- </appender>
-
- <b><logger name="chapters.configuration" level="INFO" /></b>
- <b><logger name="chapters.configuration.Foo" level="DEBUG" /></b>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-
-</configuration></pre>
-
- <p><code>MyApp3</code>アプリケーションの引数にこの設定ファイルを指定して実行すると、コンソールには次のように出力されます。</p>
-
-<p class="prettyprint source">17:39:27.593 [main] INFO chapters.configuration.MyApp3 - Entering application.
-17:39:27.593 [main] DEBUG chapters.configuration.Foo - Did it again!
-17:39:27.593 [main] INFO chapters.configuration.MyApp3 - Exiting application.</p>
-
- <p><code>JoranConfiguration</code>が<em>sample3.xml</em>を設定した後のロガーとそのレベルを表にまとめました。
- </p>
-
- <table class="bodyTable">
- <tr>
- <th>ロガー名</th>
- <th>割り当てられたレベル</th>
- <th>有効レベル</th>
- </tr>
- <tr>
- <td>root</td>
- <td><code>DEBUG</code></td>
- <td><code>DEBUG</code></td>
- </tr>
- <tr class="alt">
- <td>chapters.configuration</td>
- <td><code>INFO</code></td>
- <td><code>INFO</code></td>
- </tr>
- <tr>
- <td>chapters.configuration.MyApp3</td>
- <td><code>null</code></td>
- <td><code>INFO</code></td>
- </tr>
- <tr class="alt">
- <td>chapters.configuration.Foo</td>
- <td><code>DEBUG</code></td>
- <td><code>DEBUG</code></td>
- </tr>
- </table>
-
- <p>これは、<code>MyApp3</code>クラスの<code>INFO</code>レベルのロギング式2つと、<code>Foo</code>クラスのdoIt()メソッドにあるDEBUGレベルのロギング式がいずれも有効であるということです。ルートロガーのレベルは常に非null値が指定されること、デフォルトではDEBUGが指定されていることに注意しましょう。
- </p>
-
- <p><a href="./architecture.html#basic_selection">基本的な選択ルール</a>についても考えてみましょう。ロギング要求が呼び出されるかどうかは、アペンダーを割り当てられたロガーに指定されたレベルそのものではなく、ロガーの有効レベルによって決定されるというものです。logback はまず最初にロギング式が有効かどうかを判定します。有効な場合は、ロガーのレベルに依らず、ロガー階層で見つかったアペンダーを呼び出します。設定ファイル<em>sample4.xml</em>でその点を確認しましょう。</p>
-
- <p class="example">例:ロガーレベルのサンプル(<a href="http://logback.qos.ch/xref/chapters/configuration/sample4.xml">logback-examples/src/main/java/chapters/configuration/sample4.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('sample4');">Groovyで見る</span>
- <pre id="sample4" class="prettyprint source"><configuration>
-
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>
- %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
- </pattern>
- </encoder>
- </appender>
-
- <b><logger name="chapters.configuration" level="INFO" /></b>
-
- <!-- turn OFF all logging (children can override) -->
- <root <b>level="OFF"</b>>
- <appender-ref ref="STDOUT" />
- </root>
-
-</configuration></pre>
-
- <p><em>sample4.xml</em>を設定した後のロガーとそのレベルを表にまとめました。
- </p>
-
- <table class="bodyTable">
- <tr>
- <th>ロガー名</th>
- <th>割り当てられたレベル</th>
- <th>有効レベル</th>
- </tr>
- <tr>
- <td>root</td>
- <td><code>OFF</code></td>
- <td><code>OFF</code></td>
- </tr>
- <tr class="alt">
- <td>chapters.configuration</td>
- <td><code>INFO</code></td>
- <td><code>INFO</code></td>
- </tr>
- <tr>
- <td>chapters.configuration.MyApp3</td>
- <td><code>null</code></td>
- <td><code>INFO</code></td>
- </tr>
- <tr class="alt">
- <td>chapters.configuration.Foo</td>
- <td><code>null</code></td>
- <td><code>INFO</code></td>
- </tr>
- </table>
-
- <p><em>sample4.xml</em>では、ConsoleAppenderに<em>STDOUT</em>という名前を付けて、ルートロガーに割り当てています。ルートロガーのレベルは<code>OFF</code>です。しかし、<em>MyApp3</em>の引数として<em>sample4.xml</em>を指定して実行すると次のような出力になってしまいます。</p>
-
- <div class="source"><pre>17:52:23.609 [main] INFO chapters.configuration.MyApp3 - Entering application.
-17:52:23.609 [main] INFO chapters.configuration.MyApp3 - Exiting application.</pre></div>
-
- <p>つまり、<code>INFO</code>レベルが有効レベルとなっているロガーである<code>chapters.configuration.MyApp3</code>と<code>chapters.configuration.Foo</code>のどちらも、ルートロガーのレベルによる影響を受けていないのです。蛇足ですが、Java実装の中では<em>chapters.configuration</em>ロガーを直接参照しているところはありませんが、実際に存在しています。設定ファイルで宣言されいるからです。
- </p>
-
- <h4 class="doAnchor" name="configuringAppenders">アペンダーの設定</h4>
-
- <p>アペンダーの設定は<code>appender要素</code>で行います。この要素には<span class="attr">name属性</span>と<span class="attr">class属性</span>という二つの必須属性があります。<span class="attr">name属性</span>にはアペンダーの名前を、<span class="attr">class属性</span>にはアペンダーのクラスの完全名を指定します。<code>appender要素</code>には任意個の<code>layout要素</code>と<code>encoder要素</code>と<code>filter要素</code>を含めることができます。<code>appender要素</code>には、これらの一般的な要素とは別に、アペンダークラスのJavaBean規約に従ったプロパティを任意の数だけ含めることができます。logbackのコンポーネントのどんなプロパティでも違和感無く設定できるのは、<a href="./onJoran.html">Jora [...]
- </p>
-
- <p align="left">
- <img src="images/chapters/configuration/appenderSyntax.png" alt="アペンダの構文" title="アペンダー要素構文">
- </p>
-
- <p><code>layout要素</code>にはclass属性が必須です。レイアウトクラスの完全名を指定します。<code>appender要素</code>と同じく、<code>layout要素</code>にはレイアウトクラスのプロパティを含めることができます。レイアウトクラスとして<code>PatternLayout</code>を指定するのが一般的なので、その場合class属性は省略できるようになっています。これは<a href="./onJoran.html#defaultClassMapping">デフォルトのクラスマッピングルール</a>で定義されています。
- </p>
-
- <p><code>encoder要素</code>にはclass属性が必須です。エンコーダクラスの完全名を指定します。エンコーダクラスとして<code>PaternLayoutEncoder</code>を指定するのが一般的なので、その場合class属性を省略できるようになっています。これは<a href="./onJoran.html#defaultClassMapping">デフォルトのクラスマッピングルール</a>で定義されています。
- </p>
-
- <p>複数のアペンダーにログを出力するのも、さまざまなアペンダーを定義してロガーから参照するのも簡単です。設定ファイルの例を示しましょう。</p>
-
- <p class="example">例:複数のロガー(<a href="http://logback.qos.ch/xref/chapters/configuration/multiple.xml">logback-examples/src/main/java/chapters/configuration/multiple.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('multiple');">Groovyで見る</span>
- <pre id="multiple" class="prettyprint source"><configuration>
-
- <appender name="<b>FILE</b>" class="ch.qos.logback.core.FileAppender">
- <file>myApp.log</file>
-
- <encoder>
- <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
- </encoder>
- </appender>
-
- <appender name="<b>STDOUT</b>" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <b><appender-ref ref="FILE" /></b>
- <b><appender-ref ref="STDOUT" /></b>
- </root>
-</configuration></pre>
-
- <p>この設定スクリプトでは、<em>FILE</em>と<em>STDOUT</em>というアペンダーを定義しています。<em>FILE</em>は<em>myApp.log</em>というファイルへログを出力するアペンダーです。このアペンダーのエンコーダーは<code>PatternLayoutEncoder</code>で、日付、ログレベル、スレッド名、ロガー名、ソースコードファイル名、ロギング式の書かれたソースコードファイル中の行番号、メッセージ、改行文字を出力します。二つ目のアペンダーは<code></code>STDOUT[/0}という名前です。これはコンソールにログを出力するアペンダーです。このアペンダーのエンコーダーは、メッセージと改行文字だけを出力します。
- </p>
-
- <p>二つのアペンダーはルートロガーに割り当てられています。それぞれ<em>appender-ref要素</em>から名前で参照されています。それぞれのアペンダーにエンコーダーを指定していることに気づきましたか。普通エンコーダーは複数のアペンダーから共有できるように設計されていません。レイアウトにも同じことが言えます。このように、logbackの設定ファイルは、エンコーダーやレイアウトを共有するためのいかなる構文上の手段も提供しません。
- </p>
-
- <h4 class="doAnchor" name="cumulative">アペンダーの積み重ね</h4>
-
- <p>デフォルトでは<b>アペンダーは積み重ねられていきます</b>。つまり、ロガーに割り当てられたアペンダーにログを出力するのとまったく同様に、祖先ロガーに割り当てられたアペンダーにもログが出力されます。従って、同じアペンダーを複数のロガーに割り当てると、ログ出力が重複することになります。
- </p>
-
- <p class="example">例:アペンダーの重複(<a href="http://logback.qos.ch/xref/chapters/configuration/duplicate.xml">logback-examples/src/main/java/chapters/configuration/duplicate.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('duplicate');">Groovyで見る</span>
- <pre id="duplicate" class="prettyprint source"><configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <logger name="chapters.configuration">
- <appender-ref ref="STDOUT" />
- </logger>
-
- <root level="debug">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p><code>MyApp3</code>アプリケーションの引数に<em>duplicate.xml</em>を指定して実行すると、次のような出力が得られます。</p>
-
-<p class="source">14:25:36.343 [main] INFO chapters.configuration.MyApp3 - Entering application.
-14:25:36.343 [main] INFO chapters.configuration.MyApp3 - Entering application.
-14:25:36.359 [main] DEBUG chapters.configuration.Foo - Did it again!
-14:25:36.359 [main] DEBUG chapters.configuration.Foo - Did it again!
-14:25:36.359 [main] INFO chapters.configuration.MyApp3 - Exiting application.
-14:25:36.359 [main] INFO chapters.configuration.MyApp3 - Exiting application.</p>
-
- <p>ログ出力の重複には気をつけましょう。<em>STDOUT</em>という名前のアペンダーは、ルートロガーと<em>chapters.configuration</em>ロガーに割り当てられています。ルートロガーは全てのロガーの祖先ロガーです。<em>chapters.configuration</em>ロガーは<em>chapters.configuration.MyApp3</em>ロガーと<em>chapters.configuration.Foo</em>ロガーの親ロガーです。子孫にあたるこれら二つのロガーによるロギング要求は二重に出力されます。なぜなら、<em>STDOUT</em>アペンダーが、<em>chapters.configuration</em>ロガーと<em>ルート</em>ロガーの両方に割り当てられているからです。
- </p>
-
- <p>アペンダーが積み重ねられるようになっているのは、決して新しい利用者を罠にかけるためではありません。これは非常に便利なフィーチャなのです。例えば、システム中の全てのロガーによるメッセージをコンソールに出力させつつ、特定のロガーのメッセージだけを特別なアペンダーに出力させるように設定することができるのです。
- </p>
-
- <p class="example">例:複数のアペンダー(<a href="http://logback.qos.ch/xref/chapters/configuration/restricted.xml">logback-examples/src/main/java/chapters/configuration/restricted.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('restricted');">Groovyで見る</span>
- <pre id="restricted" class="prettyprint source"><configuration>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <file>myApp.log</file>
- <encoder>
- <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
- </encoder>
- </appender>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <logger name="chapters.configuration">
- <appender-ref ref="FILE" />
- </logger>
-
- <root level="debug">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>この例では、システム中の全てのロガーのメッセージはコンソールアペンダーに出力されます。そして、<em>chapters.configuration</em>ロガーとその子孫ロガーからのロギング要求は<em>myApp.log</em>ファイルにも出力されます。
- </p>
-
- <h4 class="doAnchor" name="overrridingCumulativity">デフォルトの積み重ねを止める</h4>
-
- <p>デフォルトの積み重ねがニーズに合わない場合は、aditivity フラグに false を設定して止めることができます。そうすれば、ロガーツリーのある枝から下の部分では、ツリーの他の部分と違って、ロガーに割り当てられたアペンダーにだけ出力するようになります。
- </p>
-
- <p class="example">例:aditivity フラグ(<a href="http://logback.qos.ch/xref/chapters/configuration/aditivityFlag.xml">logback-examples/src/main/java/chapters/configuration/aditivityFlag.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('additivityFlag');">Groovyで見る</span>
- <pre id="additivityFlag" class="prettyprint source"><configuration>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <file>foo.log</file>
- <encoder>
- <pattern>%date %level [%thread] %logger{10} [%file : %line] %msg%n</pattern>
- </encoder>
- </appender>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <logger name="chapters.configuration.Foo" <b>additivity="false"</b>>
- <appender-ref ref="FILE" />
- </logger>
-
- <root level="debug">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>この例では<em>chapters.configuration.Foo</em>ロガーに<em>FILE</em>というアペンダーが割り当てられています。また、<em>chapters.configuration.Foo</em>ロガーのaditivityフラグにfalseが指定されているので、ログは<em>FILE</em>アペンダーにだけ出力されて、ログ階層の先祖に割り当てられているアペンダーには出力されません。他のロガーが<em>chapters.configuration.Foo</em>ロガーのaditivityフラグの設定に気づくことはありません。<code>MyApp3</code>アプリケーションを<em>aditivityFlag.xml</em>を引数として実行すると、コンソールに<em>chapters.configuration.MyApp3</em>ロガーからの出力が表示されます。しかし、<em>chapters.configuration.Foo</em>ロガーの出力が<em>foo.log</em>以外に表れることはありません。
- </p>
-
- <h3 class="doAnchor" name="contextName">コンテキスト名の設定</h3>
-
- <p><a href="./architecture.html#LoggerContext">前の章</a>で述べたように、全てのロガーはロガーコンテキストに割り当てられます。ロガーコンテキストのデフォルトの名前は「default」です。しかし、<code>contextNameディレクティブ</code>を使えば別の名前を付けることが出来ます。ロガーコンテキストの名前は一度設定したら<a href="http://logback.qos.ch/apidocs/ch/qos/logback/core/ContextBase.html#setName(java.lang.String)">変更できない</a>ので注意してください。複数のアプリケーションが同じ対象にロギングする場合、アプリケーションを区別しやすくするには、コンテキストに名前を付けるのが簡単でわかりやすい方法です。
- </p>
-
- <p class="example">例:コンテキスト名を設定して表示する(<a href="http://logback.qos.ch/xref/chapters/configuration/contextName.xml">logback-examples/src/main/java/chapters/configuration/contextName.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('contextName');">Groovyで見る</span>
- <pre id="contextName" class="prettyprint source"><configuration>
- <b><contextName>myAppName</contextName></b>
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d <b>%contextName</b> [%t] %level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>これはロガーコンテキストに名前を付ける例です。レイアウトのパターンに変換指示語として<a href="./layouts.html#conversionWord">contextName</a>を指定すると、コンテキスト名が出力されます。</p>
-
- <!-- =============================================================== -->
-
- <h3 class="doAnchor" name="variableSubstitution">変数の置換</h3>
-
- <p>このドキュメントの以前のバージョンでは、「変数の置換」ではなく「プロパティの置換」と呼んでいました。<span class="label"></span>どちらも相互に置き換えられるくらい同じ意味の言葉ですが、前者のほうが明確に意味を表していると思います。
- </p>
-
- <p>よくあるスクリプト言語のように、logbackの設定ファイルは変数を定義して、値と置き換えられるようになっています。変数は設定ファイルの中で定義することもできるし、外部のファイルで定義することもできます。そして外部リソースでも定義することもできるし、何らか計算することさえできます。また、<a href="./03-configuration.html#definingPropsOnTheFly">実行時に定義する</a>こともできます。
- </p>
-
- <p class="highlight">値を指定できるところなら設定ファイル中のどこでも変数を置換することができます。</p>
-
- <p>値を指定できるところなら設定ファイル中のどこでも変数を置換することができます。
-変数の置換をする構文はUnixシェルとよく似ています。<em>${</em>から始まり<em>}</em>で終わる文字列は、<em>プロパティの値</em>への参照と見做されます。<em>aName</em>というプロパティの場合文字列の"${aName}"は、その値に置き換えられます。<em></em>
- </p>
-
- <p>変数には<a href="./03-configuration.html#scopes">スコープ</a>があります(後で説明します)。</p>
-
- <p>HOSTNAME変数とCONTEXT_NAME変数はよく使われるので、コンテキストスコープを持つ変数として自動的に定義されます。</p>
-
- <h4 class="doAnchor" name="definingProps">変数の定義</h4>
-
- <p>変数は、設定ファイルや外部のプロパティファイル、あるいは外部リソースを読み込むとき、それぞれで一度だけ定義することができます。歴史的な理由により、<code>property</code>XML要素を使って変数を定義することになっていますが、logback 1.0.7以降では<code>variable要素</code>を使うことも出来ます。これらの要素は完全に互換性があります。</p>
-
- <p>設定ファイルの先頭で変数を定義する例を見てみましょう。定義された変数は、設定ファイルの後半のほうでログ出力用ファイルの位置を指定するために使われています。
- </p>
-
- <p class="example">例:変数の置換(<a href="http://logback.qos.ch/xref/chapters/configuration/variableSubstitution1.xml">logback-examples/src/main/java/chapters/configuration/variableSubstitution1.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('variableSubstitution1');">Groovyで見る</span>
- <pre id="variableSubstitution1" class="prettyprint source"><configuration>
-
- <b><property name="USER_HOME" value="/home/sebastien" /></b>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <b><file>${USER_HOME}/myApp.log</file></b>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
- <p>次は、システムプロパティを使って同じことをしてみましょう。設定ファイル中にproperty要素が宣言されていないので、logback はそれをシステムプロパティから探します。Javaのシステムプロパティはコマンドラインで次のように指定します。</p>
-
- <p class="source">java -DUSER_HOME="/home/sebastien" MyApp2</p>
-
- <p class="example">例:システム変数の置換(<a href="http://logback.qos.ch/xref/chapters/configuration/variableSubstitution2.xml">logback-examples/src/main/java/chapters/configuration/variableSubstitution2.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('variableSubstitution2');">Groovyで見る</span>
- <pre id="variableSubstitution2" class="prettyprint source"><configuration>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <b><file>${USER_HOME}/myApp.log</file></b>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <p>複数の変数が必要なときは、変数の定義だけを含むファイルを別に用意したほうが便利な場合もあります。構成例を示します。
- </p>
-
- <p class="example">例:別ファイルを使用する変数の置換(<a href="http://logback.qos.ch/xref/chapters/configuration/variableSubstitution3.xml">logback-examples/src/main/java/chapters/configuration/variableSubstitution3.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('variableSubstitution3');">Groovyで見る</span>
- <pre id="variableSubstitution3" class="prettyprint source"><configuration>
-
- <b><property file="src/main/java/chapters/configuration/variables1.properties" /></b>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <b><file>${USER_HOME}/myApp.log</file></b>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
- <p>この設定ファイルでは<em>variables1.properties</em>という名前のファイルを参照しています。指定されたファイルで定義された変数がローカルスコープに定義されます。<em>variable.properties</em>の内容は次のようなものです。
- </p>
-
- <em>例:変数定義ファイル(logback-examples/src/main/java/chapters/configuration/variables1.properties)</em>
-
- <pre class="source">USER_HOME=/home/sebastien</pre>
-
- <p>ファイルの代わりにクラスパス上のリソースを指定することもできます。</p>
-
- <pre class="prettyprint source"><configuration>
-
- <b><property resource="resource1.properties" /></b>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <b><file>${USER_HOME}/myApp.log</file></b>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <h4 class="doAnchor" name="scopes">スコープ</h4>
-
- <p><em>ローカルスコープ</em>、<em>コンテキストスコープ</em>、<em>システムスコープ</em>のそれぞれで変数を定義することができます。デフォルトのスコープはローカルスコープです。OSの提供する環境変数の読み込みはできますが、書き込みは出来ません。</p>
-
-
- <p><span class="label">ローカルスコープ</span>。ローカルスコープで定義された変数は、その変数が定義されている設定ファイルの解釈、実行が終了するまで有効です。当然ながら、設定ファイルを解釈、実行するたびに、ローカルスコープの変数は新しく定義されることになります。</p>
-
- <p><span class="label">コンテキストスコープ</span>。コンテキストスコープで定義された変数は、コンテキストに登録されます。コンテキストが破棄されるまで、あるいは、コンテキストが初期化されるまで有効です。つまり、一度コンテキストスコープで定義された変数はコンテキストの一部となるのです。ですので、全てのロギングイベントから利用できますし、そのイベントをシリアライズして送信した先のリモートホストでも利用できます。
- </p>
-
- <p><span class="label">システムスコープ</span>。システムスコープで定義された変数は、JVMのシステムプロパティに登録されます。JVMが停止するか、初期化されるまで有効です。
- </p>
-
- <p class="highlight">最初にローカルスコープで変数を検索します。そしてコンテキストスコープ、システムスコープの順に検索し、最後に<a href="http://docs.oracle.com/javase/tutorial/essential/environment/env.html">OSの環境変数</a>を検索します。
- </p>
-
- <p>変数を置換する際、最初にローカルスコープで変数を検索します。そしてコンテキストスコープ、システムスコープの順に検索し、最後に<a href="http://docs.oracle.com/javase/tutorial/essential/environment/env.html">OSの環境変数</a>を検索します。
-
- </p>
-
- <p>変数のスコープは、<code>property要素</code>、<code>define要素</code>、<code>insertFromJNDI要素</code>の<span class="attr">scope属性</span>で指定します。<span class="attr">scope属性</span>に指定できるのは、"local"、"context"、"system" のいずれかの文字列です。scope属性を指定しなかった場合、スコープは常に"local"と見做されます。
- </p>
-
- <p class="example">例:変数をコンテキストスコープで定義する(<a href="http://logback.qos.ch/xref/chapters/configuration/contextScopedVariable.xml">logback-examples/src/main/java/chapters/configuration/contextScopedVariable.xml</a>)</p>
-
- <span class="asGroovy" onclick="return
- asGroovy('contextScopedVariable');">Groovyで見る</span>
- <pre id="contextScopedVariable" class="prettyprint source"><configuration>
-
- <property <b class="big">scope="context"</b> name="nodeId" value="firstNode" />
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <b><file>/opt/${nodeId}/myApp.log</file></b>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
- <p>この例では<em>nodeId変数</em>をコンテキストスコープで定義しています。この変数は全てのロギングイベントで有効であり、シリアライズ化して送信した先のリモートホストでも利用できます。</p>
-
-
- <h3 class="doAnchor" name="defaultValuesForVariables">変数のデフォルト値</h3>
-
- <p>特定の状況では、変数が宣言されていなかったり、値がnullの場合、デフォルト値が使えるようになっているほうが望ましいことがあります。<a href="http://tldp.org/LDP/abs/html/parameter-substitution.html">Bash</a>と同じく、<b>":-"</b>演算子を使ってデフォルト値を指定することができます。例えば、 <em>aName</em>という名前の変数が定義されていない場合、<code>"${aName <b>:-golden</b> }"</code>という文字列を変数置換した結果は"goleden"になります。</p>
-
- <h3 class="doAnchor" name="nestedSubst">変数のネスト</h3>
-
- <p>変数はネストすることができます。変数の名前として、デフォルト値として、値として、他の変数を指定することができます。</p>
-
-
- <h4>値のネスト</h4>
- <p>変数の値を定義するとき、他の変数を指定することができます。例えば、宛先のディレクトリだけでなく、ファイル名も変数で指定したい場合、それぞれの変数をまとめた第三の変数"destination"を定義して、それを利用できるのです。プロパティファイルの例を示します。
- </p>
-
- <p class="example">例:変数のネスト(<a href="http://logback.qos.ch/xref/chapters/configuration/variables2.properties">logback-examples/src/main/java/chapters/configuration/variables2.properties</a>)</p>
-
- <pre class="source">USER_HOME=/home/sebastien
-fileName=myApp.log
-<b>destination=${USER_HOME}/${fileName}</b></pre>
-
- <p>"destination"変数の定義で、"USER_HOME"変数と"fileName"変数を組み合わせていることが分かりますか。
- </p>
-
- <em>例:別のファイルを使用した変数の置換(logback-examples/src/main/java/chapters/configuration/variableSubstitution4.xml)</em>
-
- <pre class="prettyprint source"><configuration>
-
- <property file="variables2.properties" />
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <b><file>${destination}</file></b>
- <encoder>
- <pattern>%msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <h4>名前のネスト</h4>
-
- <p>変数を参照するとき、変数の名前として、他の変数を指定することができます。たとえば、"uesrid"変数に"alice"という文字列が指定されていることにしましょう。そうすると、"${${userid}.password}"という文字列は、"alice.password"変数を参照することになるのです。</p>
-
- <h4>デフォルト値のネスト</h4>
-
- <p>変数のデフォルト値に他の変数を指定することができます。たとえば、'id'変数に値が割り当てられておらず、'userid'変数には"alice"という文字列が指定されていることにしましょう。そうすると、"${id<b>:-</b>${userid}}" という文字列は"alice"という文字列になるのです。
- </p>
-
-
- <!-- ==============================================================
- -->
- <h3 class="doAnchor" name="hostname">HOSTNAME変数</h3>
-
- <p>あると便利なので、<code>HOSTNAME</code>変数は自動的にコンテキストスコープに定義されるようになっています。</p>
-
- <!-- ============================================================== -->
- <h3 class="doAnchor" name="context_name">CONTEXT_NAME変数</h3>
-
- <p>変数名のとおり、<code>CONTEXT_NAME</code>変数には、現在のロギングコンテキストの名前が設定されています。</p>
-
- <!-- ============================================================== -->
-
- <h3 class="doAnchor" name="timestamp">タイムスタンプを設定する</h3>
-
- <p><em>timestamp要素</em>を使うと、現在の日付と時刻に応じた値を持つプロパティを定義することができます。<em>timestamp要素</em>については<a href="./appenders.html#uniquelyNamed">後続の章</a>で説明します。</p>
-
- <!-- ============================================================== -->
- <h3 class="doAnchor" name="definingPropsOnTheFly">実行時に変数を定義する</h3>
-
- <p><code>define要素</code>を使うと動的に変数を定義できます。define要素には二つの必須属性<span class="attr">name属性</span>と<span class="attr">class属性</span>があります。<span class="attr">name属性</span>には変数の名前を指定します。<span class="attr">class属性</span>には<a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/PropertyDefiner.html">PropertyDefiner</a>インターフェイスを実装したクラスの完全名を指定します。<code>PropertyDefiner</code>の<code>getPropertyValue()</code>メソッドの返す値が、変数の値になります。<span class="attr">scope属性</span>で<a href="./03-configuration.html#scop [...]
- </p>
-
- <p>以下に例を示します。</p>
-
- <pre class="prettyprint source"><configuration>
-
- <define name="rootLevel" class="a.class.implementing.PropertyDefiner">
- <shape>round</shape>
- <color>brown</color>
- <size>24</size>
- </define>
-
- <root level="${rootLevel}"/>
-</configuration></pre>
-
- <p>この例では、"a.class.implementing.PropertyDefiner"クラスのプロパティとして、shape、color、sizeを指定しています。指定したプロパティのセッターメソッドが<code>PropertyDefiner</code>クラスに定義されていれば、logback は設定ファイルで指定されたプロパティの値をインスタンスに設定することができます。</p>
-
-
-
- <p>logback の配布物には現在のところ非常に単純な二つの<code>PropertyDefiner</code>実装クラスが含まれてます。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>実装クラス名</th>
- <th>説明</th>
- </tr>
-
- <tr>
- <td><a href="http://logback.qos.ch/apidocs/ch/qos/logback/core/property/FileExistsPropertyDefiner.html"><code>FileExistsPropertyDefiner</code></a>
- </td>
- <td><span class="prop">path</span>プロパティに指定したファイルが存在していれば"true"を、そうでなければ"false"を返します。
- </td>
- </tr>
- <tr>
- <td><a href="http://logback.qos.ch/apidocs/ch/qos/logback/core/property/FileExistsPropertyDefiner.html"><code>ResourceExistsPropertyDefiner</code></a>
- </td>
- <td>クラスパス上に指定された<span class="prop">リソース</span>が存在すれば"true"を、そうでなければ"false"を返します。
- </td>
- </tr>
- </table>
-
- <!-- ============================================================== -->
-
- <h3 class="doAnchor" name="conditional">設定ファイル内の条件分岐</h3>
-
- <p>開発環境、テスト環境、本番環境のような環境ごとに用意されたlogback設定ファイルと格闘しなければならないことがよくあります。これらの設定ファイルの内容はほとんど同じですが、少しだけ異なる箇所があります。同じような設定ファイルの重複を避けるため、logback は設定ファイル中で条件分岐できるようになっています。<code>if要素</code>、<code>then要素</code>、<code>else要素</code>を使えば、さまざまな環境用のファイルを一つにまとめることができるのです。条件分岐できるようにするため、<a href="http://logback.qos.ch/setup.html#janino">Jainoライブラリ</a>を使用しています。
- </p>
-
- <p>条件分岐式の一般的な形式を次に示します。</p>
-
- <pre class="prettyprint source">
- <!-- if-then form -->
- <if condition="some conditional expression">
- <then>
- ...
- </then>
- </if>
-
- <!-- if-then-else form -->
- <if condition="some conditional expression">
- <then>
- ...
- </then>
- <else>
- ...
- </else>
- </if></pre>
-
- <p>condition属性に指定するのはJavaの条件式です。コンテキストスコープとシステムスコープの変数が利用できます。<code>property()</code>メソッドか、その省略形である<code>p()</code>メソッドの引数としてヘンス名を渡すと、その値を文字列として返します。たとえば、"k"という値の変数の値にアクセスするには、<code>property("k")</code>あるいは<code>p("k")</code>という書き方をします。変数"k"が未定義ならproperty()メソッドは空文字列を返します。nullではありません。つまり、nullチェックは不要です。</p>
-
- <p><code>isDefined()</code>メソッドを使うと、変数が定義されているかどうかを確かめることが出来ます。たとえば、変数"k"が定義されているかどうかをチェックするには<code>isDefined("k")</code>と書けばよいです。他にも、nullチェックをするための<code>isNull()</code>メソッドが用意されています。
-
-例: <code>isNull("k")</code></p>
-
- <pre class="prettyprint source"><configuration debug="true">
-
- <b><if condition='property("HOSTNAME").contains("torino")'></b>
- <b><then></b>
- <appender name="CON" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d %-5level %logger{35} - %msg %n</pattern>
- </encoder>
- </appender>
- <root>
- <appender-ref ref="CON" />
- </root>
- <b></then></b>
- <b></if></b>
-
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <file>${randomOutputDir}/conditional.log</file>
- <encoder>
- <pattern>%d %-5level %logger{35} - %msg %n</pattern>
- </encoder>
- </appender>
-
- <root level="ERROR">
- <appender-ref ref="FILE" />
- </root>
-</configuration></pre>
-
-
- <p><code>configuratoin要素</code>の中なら<em>どこにでも</em>条件分岐を置くことが出来ます。if-then-else式をネストすることもできます。しかし、XML文法は非常に面倒ですし、汎用プログラミング言語の基盤には不適切です。したがって、条件分岐が多すぎると、設定ファイルはあっという間に他の人には理解できないものになってしまいます。ましてや、後で自分が読み返しても理解できないでしょう。
- </p>
-
-
- <!-- ============================================================== -->
-
- <h3 class="doAnchor" name="insertFromJNDI">JNDIから変数を取得する</h3>
-
- <p>特定の状況下では、JNDIに格納されたenvの内容を参照したいこともあるでしょう。<code>insertFromJNDIディレクティブ</code>を使うと、JNDIに格納されたenvを取得して、ローカルスコープの変数<span class="attr">として</span>取り込むことができます。他の変数と同じく、<em>scope属性</em>に指定した<a href="./03-configuration.html#scopes">別のスコープ</a>に新しい変数を登録することができます。
- </p>
-
- <p class="example">例:JNDI経由で取得したenvを変数として登録する(<a href="http://logback.qos.ch/xref/chapters/configuration/insertFromJNDI.xml">logback-examples/src/main/java/chapters/configuration/insertFromJNDI.xml</a>)</p>
-
- <pre class="prettyprint source"><configuration>
- <b><insertFromJNDI env-entry-name="java:comp/env/appName" as="<span class="green">appName"</span> /></b>
- <b><contextName><span class="green">${appName}</span></contextName></b>
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d ${CONTEXT_NAME} %level %msg %logger{50}%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-</configuration></pre>
-
- <p>この例は、env の "java:comp/env/appName"を<span class="variable">appName</span>という名前の変数として登録するものです。<code>contextNameディレクティブ</code>で指定しているコンテキスト名には、その前に定義されている<code>insertFromJNDIディレクティブ</code>で登録した変数を使用していることがわかりますか。
- </p>
-
- <h3 class="doAnchor" name="fileInclusion">ファイルの取り込み</h3>
-
- <p>Joranは、設定ファイルの一部として別のファイルを読み込むことができます。そのためには、<code>include要素</code>として宣言します。</p>
-
- <p class="example">例:ファイルの取り込み(<a href="http://logback.qos.ch/xref/chapters/configuration/containingConfig.xml">logback-examples/src/main/java/chapters/configuration/containingConfig.xml</a>)</p>
-
- <pre class="prettyprint source"><configuration>
- <b><include file="src/main/java/chapters/configuration/includedConfig.xml"/></b>
-
- <root level="DEBUG">
- <appender-ref ref="includedConsole" />
- </root>
-
-</configuration></pre>
-
- <p>取り込まれるファイルでは、全ての要素が<code>included要素</code>の中に入っていなければなりません。<code>ConsoleAppender</code>を宣言する例を示します。</p>
-
- <p class="example">例:ファイルの取り込み(<a href="http://logback.qos.ch/xref/chapters/configuration/includedConfig.xml">logback-examples/src/main/java/chapters/configuration/includedConfig.xml</a>)</p>
-
- <pre class="source"><b class="green big"><included></b>
- <appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>"%d - %m%n"</pattern>
- </encoder>
- </appender>
-<b class="green big"></included></b></pre>
-
-
- <p>繰り返しになりますが、取り込まれるファイルでは、<code class="big green">included要素</code>が必須です。</p>
-
- <p>include する対象として指定するのは、外部ファイルだけではなく、クラスパス上のリソースでも、URLでもよいです。</p>
-
- <ul>
-
- <li><b>ファイルの場合:</b><br>ファイルを取り込むには<span class="attr">file属性</span>を使用します。相対パスを指定できますが、カレントディレクトリとして使われるのはアプリケーションが設定したものになります。設定ファイルのパスとは無関係なので注意してください。</li>
-
- <li><p><b>リソースの場合:</b><br>クラスパス上のファイルなどのリソースを取り込むには<span class="attr">resource属性</span>を使用します。</p>
-
- <pre class="prettyprint source"><include resource="includedConfig.xml"/></pre>
-
- </li>
-
- <li><p><b>URLの場合:</b><br>URLから取得できるコンテンツを取り込むには<span class="attr">url属性</span>を使用します。</p>
-
- <pre class="prettyprint source"><include url="http://some.host.com/includedConfig.xml"/></pre>
-
- </li>
- </ul>
-
- <p>指定されたファイルが存在しなかった場合、logback はステータスメッセージを出力してそのことを報告します。取り込もうとしているファイルが<span class="attr">任意の</span>ものである場合、<code>include要素のoptional属性に<code>true</code>を指定しておけば、エラーメッセージを抑止することができます。</code></p>
-
-
- <pre class="prettyprint source"><include optional="true" ..../></pre>
-
- <!-- ==================== ContextListener =================== -->
- <h2 class="doAnchor" name="contextListener">コンテキストリスナーを追加する</h2>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/spi/LoggerContextListener.html">LoggerContextListener</a>インターフェイスのインスタンスは、ロガーコンテキストのライフサイクルに関連するイベントを待ち受けます。
- </p>
-
-
- <p><code>JMXConfigurator</code>は<code>LoggerContextListener</code>インターフェイスの実装の一つです。詳しくは<a href="./jmxConfig.html">後の章</a>で説明します。
- </p>
-
- <h3 class="doAnchor" name="LevelChangePropagator">LevelChangePropagator</h3>
-
- <p>バージョン0.9.25から、logback-classic の配布物には<code>LoggerContextListener</code>インターフェイスの実装である<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/jul/LevelChangePropagator.html">LevelChangePropagator</a>が含まれるようになりました。これは、logback-classic のあらゆるロガーのレベルの変更を捉えて、java.util.logging フレームワークに伝播します。ログレベルの変化を伝播するのはコストが高いので、ロギング式を無効にすることで改善されたはずの性能が台無しになってしまいます。<a href="http://download.oracle.com/javase/1.5.0/docs/api/java/util/logging/LogRecord.html?is-external=true">LogRecord</a>のインスタンスはロギング式が有効な [...]
- </p>
-
-
- <p>contextListener要素に<code>LevelChangePropagator</code>を登録するには次のようにします。</p>
-
- <pre class="prettyprint source"><configuration debug="true">
- <b><contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/></b>
- ....
-</configuration></pre>
-
- <p>LevelChangePropagatorのプロパティ<span class="option">resetJUL</span>を指定すると、j.u.l.loggers に指定されていたレベルがすべて初期化されます。ただし、ハンドラーはそのまま残ります。</p>
-
- <pre class="prettyprint source"><configuration debug="true">
- <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
- <b><resetJUL>true</resetJUL></b>
- </contextListener>
- ....
-</configuration></pre>
- <p>
- </p>
-
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/encoders.html b/logback-site/src/site/pages/manual/encoders.html
index 674b676..3b359c7 100644
--- a/logback-site/src/site/pages/manual/encoders.html
+++ b/logback-site/src/site/pages/manual/encoders.html
@@ -27,8 +27,6 @@
<h1>Chapter 5: Encoders</h1>
- <a href="encoders_ja.html">和訳 (Japanese translation)</a>
-
<div class="quote">
<p><b>ACTION THIS DAY</b> Make sure they have all they want on
extreme priority and report to me that this has been done.
diff --git a/logback-site/src/site/pages/manual/encoders_ja.html b/logback-site/src/site/pages/manual/encoders_ja.html
deleted file mode 100644
index 89398bb..0000000
--- a/logback-site/src/site/pages/manual/encoders_ja.html
+++ /dev/null
@@ -1,175 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"></meta>
- <title>第5章 エンコーダ</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第5章 エンコーダー</h1>
-
- <div class="quote">
- <p><b>ACTION THIS DAY</b>
-彼らの要求するものを全て最優先にして、それが終わったら報告してくれ。
- </p>
- <p>アラン・チューリングと彼の同僚の暗号解読者が署名した破格の予算請求書について、1941年10月、チャーチル首相がヘイスティングス・イスメイ将軍に伝えた言葉</p>
- </div>
-
- <script src="../templates/creative.js" type="text/javascript"></script>
- <script src="../templates/setup.js" type="text/javascript"></script>
-
-
- <h2 class="doAnchor">エンコーダーとは何か</h2>
-
- <p>エンコーダーの役割は、ロギングイベントをバイト配列に変換するだけでなく、そのバイト配列を<code>OutputStream</code>に書き込むことです。エンコーダーはlogback 0.9.19から導入されました。以前のバージョンでは、ほとんどのアペンダーはロギングイベントを文字列に変換して<code>java.io.Writer</code>に書き込むのをレイアウトに任せていました。また、以前のバージョンでは、利用者は<code>FileAppender</code>に<code>PatternLayout</code>をネストしていました。logback 0.9.19になってから、<code>FileAppender</code>もその派生クラスも、<a href="http://logback.qos.ch/codes.html#layoutInsteadOfEncoder">エンコーダーを利用するようになり、レイアウトを使わなくなりました</a>。
- </p>
-
- <p>どうしてこんな破壊的な変更をしたのか?</p>
-
- <p>詳細は次章で説明しますが、レイアウトにできるのはロギングイベントを文字列に変換することだけです。また、レイアウトはロギングイベントを書き込む間何もできません。ロギングイベントをまとめてバッチ的に処理することができないのです。対照的にエンコーダーはバイト配列を書式化している間だけでなく、書式化されたバイト配列を書き込んでいる間も完全に主導権を握っています。
- </p>
-
- <p>現時点では、利便性のあるエンコーダーは<code>PatternLayoutEncoder</code>だけです。単に<code>PatternLayout</code>をラップしただけで、ほとんどの仕事は任せてしまいます。一見すると、エンコーダーは不必要な複雑さだけをもたらしているようにも見えます。しかし、私たちは新しく強力なエンコーダーが登場することによってこういった印象を上書きしてくれることに期待しています。</p>
-
- <h2 class="doAnchor" name="interface">エンコーダーインターフェイス</h2>
-
- <p>エンコーダーの役割は、到着したロギングイベントをバイト配列に変換すること<b>と</b>変換されたバイト配列を適切な<code>OutputStream</code>に書き込むことです。前述したように、エンコーダーは親のアペンダーが管理している<code>OutputStream</code>に対して、いつ、どんなバイト配列を書き込むのか完全に制御することができます。<a href="http://logback.qos.ch/xref/ch/qos/logback/core/encoder/Encoder.html">エンコーダのインターフェイス</a>を見てみましょう。
-
- </p>
- <pre class="prettyprint source">package ch.qos.logback.core.encoder;
-
-public interface Encoder<E> extends ContextAware, LifeCycle {
-
- /**
- * This method is called when the owning appender starts or whenever output
- * needs to be directed to a new OutputStream, for instance as a result of a
- * rollover.
- */
- void init(OutputStream os) throws IOException;
-
- /**
- * Encode and write an event to the appropriate {@link OutputStream}.
- * Implementations are free to defer writing out of the encoded event and
- * instead write in batches.
- */
- void doEncode(E event) throws IOException;
-
-
- /**
- * This method is called prior to the closing of the underling
- * {@link OutputStream}. Implementations MUST not close the underlying
- * {@link OutputStream} which is the responsibility of the owning appender.
- */
- void close() throws IOException;
-}</pre>
-
- <p>見ての通り、<code>Encoder</code>インターフェイスには少ししかメソッドが宣言されていません。ですが、これらのメソッドだけで驚くほどたくさんの仕事ができるのです。
- </p>
-
-
- <h2 class="doAnchor">LayoutWrappingEncoder</h2>
-
- <p>logback0.9.19より前は、ほとんどのアペンダーがログの出力形式の面倒をレイアウトにまかせていました。レイアウトインターフェイスを使用するコードが大量に残っているので、レイアウトとエンコーダーを仲介する方法が必要でした。それをするのが<a href="http://logback.qos.ch/xref/ch/qos/logback/core/encoder/LayoutWrappingEncoder.html">LayoutWrappingEncoder</a>です。LayoutWrappingEncoder はエンコーダーインターフェイスを実装しています。そして、ラップしたレイアウトにロギングイベントを文字列に変換する仕事を委譲します。
- </p>
-
- <p><code>LayoutWrappingEncoder</code>のコードを一部抜粋して紹介します。レイアウトインスタンスにどうやって委譲しているのかがわかるでしょうか。。</p>
-
- <pre class="prettyprint source">package ch.qos.logback.core.encoder;
-
-public class LayoutWrappingEncoder<E> extends EncoderBase<E> {
-
- protected Layout<E> layout;
- private Charset charset;
- private boolean immediateFlush = true;
-
- public void doEncode(E event) throws IOException {
- String txt = layout.doLayout(event);
- outputStream.write(convertToBytes(txt));
- if (immediateFlush)
- outputStream.flush();
- }
-
- private byte[] convertToBytes(String s) {
- if (charset == null) {
- return s.getBytes();
- } else {
- return s.getBytes(charset);
- }
- }
-}</pre>
-
- <p><code>doEncode()</code>メソッドは、まず最初に受け取ったロギングイベントをラップしたレイアウトで文字列に変換します。そして変換結果の文字列を、使用者が指定した文字セットで符号化してバイト配列に変換します。次に、変換されたバイト配列を親アペンダーの<code>OutputStream</code>に書き込みます。デフォルトでは<code>OutputStream</code>をすぐにフラッシュします。ただし、<span class="prop">immediateFlush</span>プロパティに明示的にfalseが指定されているときはフラッシュしません。<span class="prop">immediateFlush</span>プロパティにfalseを指定しておくと、ロギングのスループットが大幅に向上します。設定例については、次の<code>PatternLayoutEncoder</code>のところで紹介します。
- </p>
-
-
- <h2 class="doAnchor">PatternLayoutEncoder</h2>
-
- <p><code>PatternLayout</code>は最も広く使われているレイアウトです。この一般的なユースケースに対応するため、logbackは<code>PatternLayoutEncoder</code>を提供しています。これは、<code>PatternLayout</code>のインスタンスだけをラップするようにした<code>LayoutWrappingEncoder</code>の派生クラスです。
- </p>
-
- <p>logback0.9.19の頃は、<code>FileAppender</code>やその派生クラスの設定には必ず<code>PatternLayout</code>が使われていました。今は代わりに<code>PatternLayoutEncoder</code>を使わなければなりません。これについては、<a href="http://logback.qos.ch/codes.html#layoutInsteadOfEncoder">logbackのエラーコード</a>でも説明しています。
- </p>
-
- <h4 class="doAnchor" name="immediateFlush"><span class="prop">immediateFlush</span>プロパティ</h4>
-
- <p><code>PatternLayoutEncoder</code> は<a href="http://logback.qos.ch/xref/ch/qos/logback/core/encoder/LayoutWrappingEncoder.html"><code>LayoutWrappingEncoder</code></a>の派生クラスなので、<span class="prop">immediateFlush</span>プロパティを設定することができます。<span class="prop">immediateFlush</span>のデフォルト値は"true"です。出力ストリームをすぐにフラッシュすることで、ロギングイベントがディスクに書き込まれること、アプリケーションが終了するときにちゃんとアペンダーを閉じなかったときでも、ロギングイベントが失われないことを保証することができます。一方、このプロパティに"false"を指定すると、(それが必要なのかどうかはわかりませんが)ロギングのスループットが5倍にまで向上する可能性があります。前述したとおり [...]
- </p>
-
- <p><code>FileAppender</code>に<code>PatternLayoutEncoder</code>を指定した設定例を見てみましょう。<span class="prop">immediateFlush</span>プロパティにはfalseを指定しています。</p>
-
-<pre class="prettyprint"><appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <file>foo.log</file>
- <encoder>
- <pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern>
- <!-- this quadruples logging throughput -->
- <b><immediateFlush>false</immediateFlush></b>
- </encoder>
-</appender></pre>
-
-
- <h4 class="doAnchor" name="outputPatternAsHeader">ヘッダに出力形式を入れる</h4>
-
- <p>ログファイルの解析を容易にするため、logbackはログファイルの先頭にログの出力形式を出力することができます。この機能はデフォルトでは<b>無効</b>になっています。<code>PatternLayoutEncoder</code>の<span class="prop">outputPatternAsHeader</span>プロパティにtrueを指定すれば、有効化することができます。以下に例を示します。</p>
-
-<pre class="prettyprint"><appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <file>foo.log</file>
- <encoder>
- <pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern>
- <b><outputPatternAsHeader>true</outputPatternAsHeader></b>
- </encoder>
-</appender></pre>
-
- <p>この設定を使うと次のように出力されます。</p>
-
- <pre>#logback.classic pattern: %d [%thread] %-5level %logger{36} - %msg%n
-2012-04-26 14:54:38,461 [main] DEBUG com.foo.App - Hello world
-2012-04-26 14:54:38,461 [main] DEBUG com.foo.App - Hi again
-...</pre>
-
- <p>先頭行の"#logback.classic pattern"が出力形式として出力されたヘッダです。</p>
-
-
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-
- </div>
- </body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/filters.html b/logback-site/src/site/pages/manual/filters.html
index 610f9f7..fc15ae5 100644
--- a/logback-site/src/site/pages/manual/filters.html
+++ b/logback-site/src/site/pages/manual/filters.html
@@ -30,8 +30,6 @@
<h1>Chapter 7: Filters</h1>
- <a href="filters_ja.html">和訳 (Japanese translation)</a>
-
<div class="quote">
<p><em>Have lots of ideas and throw away the bad ones. You aren't
going to have good ideas unless you have lots of ideas and some
@@ -137,7 +135,7 @@ public class SampleFilter extends Filter<ILoggingEvent> {
</p>
<em>Example: SampleFilter configuration
- (logback-examples/src/main/resources/chapters/filters/SampleFilterConfig.xml)</em>
+ (logback-examples/src/main/java/chapters/filters/SampleFilterConfig.xml)</em>
<span class="asGroovy" onclick="return asGroovy('SampleFilterConfig');">View as .groovy</span>
<pre id="SampleFilterConfig" class="prettyprint source"><configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
@@ -194,7 +192,7 @@ public class SampleFilter extends Filter<ILoggingEvent> {
</p>
<em>Example: Sample LevelFilter configuration
- (logback-examples/src/main/resources/chapters/filters/levelFilterConfig.xml)</em>
+ (logback-examples/src/main/java/chapters/filters/levelFilterConfig.xml)</em>
<span class="asGroovy" onclick="return asGroovy('levelFilterConfig');">View as .groovy</span>
<pre id="levelFilterConfig" class="prettyprint source"><configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
@@ -227,7 +225,7 @@ public class SampleFilter extends Filter<ILoggingEvent> {
</p>
<em>Example: Sample ThresholdFilter configuration
- (logback-examples/src/main/resources/chapters/filters/thresholdFilterConfig.xml)</em>
+ (logback-examples/src/main/java/chapters/filters/thresholdFilterConfig.xml)</em>
<span class="asGroovy" onclick="return asGroovy('thresholdFilterConfig');">View as .groovy</span>
<pre id="thresholdFilterConfig" class="prettyprint source"><configuration>
<appender name="CONSOLE"
@@ -529,7 +527,7 @@ public class SampleFilter extends Filter<ILoggingEvent> {
<p>Here is a concrete example.</p>
<em>Example: Basic event evaluator usage
- (logback-examples/src/main/resources/chapters/filters/basicEventEvaluator.xml)</em>
+ (logback-examples/src/main/java/chapters/filters/basicEventEvaluator.xml)</em>
<span class="asGroovy" onclick="return asGroovy('basicEventEvaluator');">View as .groovy</span>
<pre id="basicEventEvaluator" class="prettyprint source longline"><configuration>
@@ -663,7 +661,7 @@ java chapters.filters.FilterEvents src/main/java/chapters/filters/basicConfigura
<p>An example should clarify the point:</p>
- <em>Example: Defining matchers in an event evaluator (logback-examples/src/main/resources/chapters/filters/evaluatorWithMatcher.xml)</em>
+ <em>Example: Defining matchers in an event evaluator (logback-examples/src/main/java/chapters/filters/evaluatorWithMatcher.xml)</em>
<span class="asGroovy" onclick="return asGroovy('evaluatorWithMatcher');">View as .groovy</span>
<pre id="evaluatorWithMatcher" class="prettyprint source"><configuration debug="true">
@@ -820,7 +818,7 @@ public class SampleTurboFilter extends TurboFilter {
</p>
<em>Example: Basic custom <code>TurboFilter</code> configuration
- (logback-examples/src/main/resources/chapters/filters/sampleTurboFilterConfig.xml)</em>
+ (logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml)</em>
<span class="asGroovy" onclick="return asGroovy('sampleTurboFilterConfig');">View as .groovy</span>
@@ -860,7 +858,7 @@ public class SampleTurboFilter extends TurboFilter {
<em>Example: <code>MDCFilter</code> and <code>MarkerFilter</code>
configuration
- (logback-examples/src/main/resources/chapters/filters/turboFilters.xml)</em>
+ (logback-examples/src/main/java/chapters/filters/turboFilters.xml)</em>
<span class="asGroovy" onclick="return asGroovy('turboFilters');">View as .groovy</span>
<pre id="turboFilters" class="prettyprint source"><configuration>
@@ -989,7 +987,7 @@ logger.debug("Hello {}.", name1);</pre>
<em>Example: <code>DuplicateMessageFilter</code>
- configuration (logback-examples/src/main/resources/chapters/filters/duplicateMessage.xml)</em>
+ configuration (logback-examples/src/main/java/chapters/filters/duplicateMessage.xml)</em>
<span class="asGroovy" onclick="return asGroovy('duplicateMessage');">View as .groovy</span>
<pre id="duplicateMessage" class="prettyprint source"><configuration>
@@ -1149,7 +1147,7 @@ logger.debug("Hello {}.", name1);</pre>
(Not Found)</a> HTTP response code. Every request resulting in a
404 will be printed on the console.</p>
-<em>Example: Access Evaluator (logback-examples/src/main/resources/chapters/filters/accessEventEvaluator.xml)</em>
+<em>Example: Access Evaluator (logback-examples/src/main/java/chapters/filters/accessEventEvaluator.xml)</em>
<pre class="prettyprint source"><configuration>
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
@@ -1171,7 +1169,7 @@ logger.debug("Hello {}.", name1);</pre>
</p>
- <em>Example 6.10: Access Evaluator (logback-examples/src/main/resources/chapters/filters/accessEventEvaluator2.xml)</em>
+ <em>Example 6.10: Access Evaluator (logback-examples/src/main/java/chapters/filters/accessEventEvaluator2.xml)</em>
<pre class="prettyprint source"><configuration>
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
diff --git a/logback-site/src/site/pages/manual/filters_ja.html b/logback-site/src/site/pages/manual/filters_ja.html
deleted file mode 100644
index 8ed082a..0000000
--- a/logback-site/src/site/pages/manual/filters_ja.html
+++ /dev/null
@@ -1,818 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第7章 フィルター</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第7章 フィルター</h1>
-
- <div class="quote">
- <p><em>たくさんのアイデアを集めて悪いものを捨てていこう。たくさんのアイデアと、自分なりの基準が無ければ、いいアイデアに巡り会えることはない。</em></p>
-
- <p>—LINUS PAULING</p>
- </div>
-
- <script src="../templates/creative.js" type="text/javascript"></script>
-
- <p>ここまでに、<a href="http://logback.qos.ch/manual/architecture.html#basic_selection">基本的な選択ルール</a>がlogback-classicモジュールの中核を担っていることを説明してきました。本章では、それに加えてフィルタリングの方法を紹介します。
- </p>
-
-
- <p>logbackのフィルターは、三値論理に基づいて合成や連結を駆使して、任意に複雑な条件を実現することができます。主に Linux の iptables から着想を得たものです。
- </p>
-
- <script src="../templates/setup.js" type="text/javascript"></script>
-
- <h2>logback-classicモジュール</h2>
-
-
- <p>logback-classic モジュールには二種類のフィルターがあります。通常フィルターとターボフィルターです。
- </p>
-
- <h3 class="doAnchor" name="filter">通常フィルター</h3>
-
- <p>通常フィルターとは、<a href="http://logback.qos.ch/xref/ch/qos/logback/core/filter/Filter.html"><code>Filter</code></a>抽象クラスを継承したものです。本質的には<code>ILoggingEvent</code>を引数にとる<code>decide()</code>メソッドを実装することが目的です。
- </p>
-
-
- <p>フィルターは順序付きリストにまとめて扱われます。また、三値論理に基づいて扱われます。それぞれのフィルターの<code>decide(ILoggingEvent event)</code>メソッドが順番に呼び出されます。このメソッドは<a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/FilterReply.html"><code>FilterReply</code></a>列挙型の値である、<code>DENY</code> 、 <code>NEUTRAL</code>または<code>ACCEPT</code>を返します。<code>decide()</code>メソッドが<code>DENY</code>を返したら、そのロギングイベントは残りのフィルターに渡されることなく、ただちに破棄されます。<code>NEUTRAL</code>を返したら、リスト内の次のフィルターに渡されます。リストの末尾に到達したら、そのロギングイベントは通常通りに処理されることになります。<code>ACCEPT [...]
- </p>
-
- <p>logback-classicモジュールでは、<code>Appender</code>にフィルターを追加することが出来ます。アペンダーに複数のフィルターを登録すれば、ロギングイベントをさまざまな条件で篩にかけられるようになります。ロギングメッセージの内容やMDCの内容、時刻や日付などロギングイベントのあらゆる内容を判定できるのです。
- </p>
-
- <h3 class="doAnchor" name="yourOwnFilter">フィルターを自作する</h3>
-
- <p>フィルターを自作するのは簡単です。<code>Filter</code>抽象クラスを継承して<code>decide()</code>メソッドを実装するだけです。
- </p>
-
- <p>例としてSampleFilterクラスを見てください。<code>decide()</code>メソッドがACCEPTを返すのは、ロギングイベントのメッセージに "sample" という文字列が含まれる場合だけです。その他の場合はNEUTRALを返すようになっています。
- </p>
-
- <p class="example">例:基本的な自作フィルター(<a href="http://logback.qos.ch/xref/chapters/filters/SampleFilter.html">logback-examples/src/main/java/chapters/filters/SampleFilter.java</a>)</p>
-
- <pre class="prettyprint source">package chapters.filters;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.filter.Filter;
-import ch.qos.logback.core.spi.FilterReply;
-
-public class SampleFilter extends Filter<ILoggingEvent> {
-
- @Override
- public FilterReply decide(ILoggingEvent event) {
- if (event.getMessage().contains("sample")) {
- return FilterReply.ACCEPT;
- } else {
- return FilterReply.NEUTRAL;
- }
- }
-}</pre>
-
- <p>次の設定ファイルでは、<code>ConsoleAppender</code>に<code>SampleFilter</code>を割り当てています。
- </p>
-
- <p class="example">例:SampleFilterの設定(<a href="http://logback.qos.ch/xref/chapters/filters/SampleFilterConfig.xml">logback-examples/src/main/java/chapters/filters/SampleFilterConfig.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('SampleFilterConfig');">Groovyとして表示</span>
- <pre id="SampleFilterConfig" class="prettyprint source"><configuration>
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-
- <b><filter class="chapters.filters.SampleFilter" /></b>
-
- <encoder>
- <pattern>
- %-4relative [%thread] %-5level %logger - %msg%n
- </pattern>
- </encoder>
- </appender>
-
- <root>
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>設定フレームワークの Joran を使えばフィルターのプロパティやサブコンポーネントを指定するのも簡単です。フィルタークラスにフィールドのセッターメソッドを追加すれば、<code>filter要素</code>にネストしてプロパティの値を指定することができます。
- </p>
-
- <p>たいていの場合フィルタリング条件には2つの直行する条件が含まれています。マッチするかどうかの条件と、何を返すのかの条件です。たとえば、メッセージが"foobar"だったらACCEPTを返し、そうでなければNEUTRALを返すフィルターもありますし、メッセージが"foobar"だったらNEUTRALを返し、そうでなければDENYを返すフィルターもあります。
- </p>
-
- <p>logback の配布物には、この直交性に焦点を当てた<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/filter/AbstractMatcherFilter.html">AbstractMatcherFilter</a></code>が含まれています。このクラスはフィルター条件の判定結果に基づいて何らかの値を返すスケルトンです。判定結果が真の時に返す値を<em>OnMatch</em>プロパティに、偽の時に返す値を<em>OnMismatch</em>プロパティに指定することができます。logbackの配布物に含まれるほとんどの通常フィルターは<code>AbstractMatcherFilter</code>を継承しています。
- </p>
-
- <h3 class="doAnchor" name="levelFilter">LevelFilter</h3>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/filter/LevelFilter.html">LevelFilter</a></code>は、ロギングイベントのログレベルの正確なマッチングに基づいたフィルタリングをします。ログレベルが設定されたレベルと等しければ、<span class="option">omMatch</span>プロパティあるいは<span class="option">omMismach</span>プロパティに設定された値に応じて、ロギングイベントを受け入れるか拒否するかが決まります。設定ファイルを見てみましょう。
- </p>
-
- <p class="example">例:LevelFilterの設定例(<a href="http://logback.qos.ch/xref/chapters/filters/levelFilterConfig.xml">logback-examples/src/main/java/chapters/filters/levelFilterConfig.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('levelFilterConfig');">Groovyとして表示</span>
- <pre id="levelFilterConfig" class="prettyprint source"><configuration>
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <b><filter class="ch.qos.logback.classic.filter.LevelFilter">
- <level>INFO</level>
- <onMatch>ACCEPT</onMatch>
- <onMismatch>DENY</onMismatch>
- </filter></b>
- <encoder>
- <pattern>
- %-4relative [%thread] %-5level %logger{30} - %msg%n
- </pattern>
- </encoder>
- </appender>
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-</configuration></pre>
-
- <h3 class="doAnchor" name="thresholdFilter">ThresholdFilter</h3>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/filter/ThresholdFilter.html">ThresholdFilter</a></code>は、ログレベルが指定されたしきい値より低いロギングイベントをフィルタリングします。ログレベルがしきい値と同じかより高い場合、<code>ThresholdFilter</code>の<code>decide()</code>はNEUTRALを返します。一方、しきい値より低いログレベルのロギングイベントは拒否します。設定ファイルを見てみましょう。
- </p>
-
- <p class="example">例:ThresholdFilterの設定例(<a href="http://logback.qos.ch/xref/chapters/filters/thresholdFilterConfig.xml">logback-examples/src/main/java/chapters/filters/thresholdFilterConfig.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('thresholdFilterConfig');">Groovyとして表示</span>
- <pre id="thresholdFilterConfig" class="prettyprint source"><configuration>
- <appender name="CONSOLE"
- class="ch.qos.logback.core.ConsoleAppender">
- <!-- deny all events with a level below INFO, that is TRACE and DEBUG -->
- <b><filter class="ch.qos.logback.classic.filter.ThresholdFilter">
- <level>INFO</level>
- </filter></b>
- <encoder>
- <pattern>
- %-4relative [%thread] %-5level %logger{30} - %msg%n
- </pattern>
- </encoder>
- </appender>
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-</configuration></pre>
-
-
- <h2 class="doAnchor" name="evalutatorFilter">EvaluatorFilter</h2>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/core/filter/EvaluatorFilter.html"><code>EvaluatorFilter</code></a>は内部で<code>EventEvaluator</code>を使用する汎用的なフィルターです。名前のとおり、ロギングイベントが<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/boolex/EventEvaluator.html">EventEvaluator</a></code>に指定された条件を満たすかどうかを評価します。評価結果がなんであれ、<code>EvaluatorFilter</code>に設定された<span class="option">onMatch</span>プロパティまたは<span class="option">onMismatch</span>プロパティの値を返します。
- </p>
-
-
- <p><code>EventEvaluator</code>は抽象クラスです。つまり、<code>EventEvaluator</code>を継承すれば、独自のイベント評価ロジックを実装することができます。
- </p>
-
-
- <!-- ======================== GEventEvaluator ========================= -->
-
- <h3 class="doAnchor" name="GEventEvaluator">GEventEvaluator</h3>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/GEventEvaluator.html">GEventEvaluator</a>は<a href="http://logback.qos.ch/xref/ch/qos/logback/core/boolex/EventEvaluator.html"><code>EventEvaluator</code></a>の派生クラスで、評価条件に結果が真偽値になるGroovy言語で書かれた任意の式を指定することができます。私たちはこのGroovy言語で書かれた式のことを "Groovy評価式" と呼んでいます。Groovy評価式を使うと、ロギングイベントをこれまでにないくらい柔軟にフィルタリングできるようになります。<code>GEventEvaluator</code> を使うにはGroovyのランタイムが必要です。設定ドキュメントの<a href="http://logback.qos.ch/setup.html#groovy"> [...]
- </p>
-
- <p>Groovy評価式は設定ファイルを解釈する際にコンパイルされます。どのように実行させるのかか、利用者が考える必要はありません。しかし、Groovy言語として間違いが無いことを保証するのは使用者の責任です。
- </p>
-
- <p>Groovy評価式は一度に1つのロギングイベントを扱います。logbackは、ロギングイベントを<a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/spi/ILoggingEvent.html">ILoggingEvnet</a>型の変数'<em>event</em>'あるいは'<em>e</em>'として用意します。また、ログレベルのTRACE、DBUG、INFO、WARN、ERROR は、Groovy評価式から同じ名前の変数として使用することが出来ます。したがって、"event.level == DEBUG" と "e.level == DEBUG" は同じ意味のGroovy評価式ということになります。ロギングイベントのログレベルがDEBUGの場合、式の値は<code>true</code>になります。他の比較演算子を使うときは、ログレベルの変数に<code>toInt()</code>演算子を適用して、整数値として評価しなければなりません。
- </p>
-
- <p>具体的な例を見てみましょう。</p>
-
- <span class="asGroovy" onclick="return asGroovy('GEventEvaluator');">Groovyとして表示</span>
- <pre id="GEventEvaluator" class="prettyprint source"><configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <b><filter class="ch.qos.logback.core.filter.EvaluatorFilter">
- <evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator">
- <expression>
- e.level.toInt() >= WARN.toInt() && <!-- Stands for && in XML -->
- !(e.mdc?.get("req.userAgent") =~ /Googlebot|msnbot|Yahoo/ )
- </expression>
- </evaluator>
- <OnMismatch>DENY</OnMismatch>
- <OnMatch>NEUTRAL</OnMatch>
- </filter></b>
- <encoder>
- <pattern>
- %-4relative [%thread] %-5level %logger - %msg%n
- </pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
-
- <p>この設定は、ログレベルがWARN以上で、ユーザーエージェントがクローラー(GooglebotやmsnbotやYahoo)以外のロギングイベントのメッセージをコンソールに出力します。ロギングイベントに関連付けられた MDC の "req.userAgent" の値を正規表現<code>/Googlebot|msnbot|Yahoo/</code>で評価して、ユーザーエージェントを判定しています。MDCがnullになることもあるので、Groovyの<a href="http://groovy.codehaus.org/Null+Object+Pattern">安全なデリファレンス演算子</a>(?.)を使っています。同じことをJava言語で実装するともっと長くなってしまうでしょう。
- </p>
-
- <p>ユーザーエージェント文字列がいつMDCに登録されたのか疑問に思うかもしれません。説明しておくべきでしたが、logbackの配布物に含まれている<a href="http://logback.qos.ch/manual/mdc.html#mis"><code>MDCInsertingServletFilter</code></a>を使っています。詳しくは後の章で説明します。
- </p>
-
- <!-- ==================== JaninoEventEvaluator ======================== -->
-
- <h3 class="doAnchor" name="JaninoEventEvaluator">JaninoEventEvaluator</h3>
-
-
- <p>logback-classicの配布物には、<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/boolex/JaninoEventEvaluator.html">JaninoEventEvaluator</a>という<code>EventEvaluator</code>の別の実装クラスが含まれています。これは、booleanを返す任意のJava言語のブロックを評価するものです。私たちはこのJava言語で書かれた式のことを"<em>Java評価式</em>”と呼んでいます。Java評価式を使うとロギングイベントを柔軟にフィルタリングできるようになります。<code>JaninoEventEvaluator</code>を使用するには<a href="http://docs.codehaus.org/display/JANINO/Home">Janinoライブラリ</a>が必要です。設定方法は設定ドキュメントの<a href="http://logback.qos.ch/setup.html# [...]
- </p>
-
- <p>Java評価式は設定ファイルを解釈する間にコンパイルされます。どのように呼び出すのか、利用者は気にすることはありません。ですが、Java言語の式が真偽値を返すものであることを保証するのは利用者の責任です。</p>
-
-
- <p>Java評価式は一度に1つのロギングイベントを扱います。logback-classicは、ロギングイベントのいろいろなフィールドをJava評価式から参照できる変数として自動的に公開します。公開する変数の名前は大文字小文字を区別するものです。表にまとめました。
- </p>
-
- <table class="bodyTable">
- <tr>
- <th>変数名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td>event</td>
- <td><code>LoggingEvent</code></td>
-
- <td>ロギング要求に関連付けられたロギングイベントそのもの。以下の変数はロギングイベントから参照することができます。たとえば、 <code>event.getMessage()</code>は<em>message</em>変数と同じ文字列を返します。
- </td>
- </tr>
-
- <tr class="alt">
- <td>message</td>
- <td><code>String</code></td>
- <td>ロギング要求に指定されたメッセージそのものです。ロガー<em>l</em>について l.info("Hello {}", name); というロギング式があったとき、"Hello {}" がメッセージとなります。</td> </tr>
-
- <tr>
- <td>formattedMessage</td>
- <td><code>String</code></td>
- <td>ロギング要求の書式化されたメッセージ。ロガー<em>l</em>について l.info("Hello {}", name); というロギング式があったとき、nameの値が"Alice"なら、"Hello Alice" が書式化されたメッセージになります。</td>
- </tr>
-
- <tr class="alt">
- <td>logger</td>
- <td><code>String</code></td>
- <td>ロガーの名前。
- </td>
- </tr>
-
- <tr>
- <td>loggerContext</td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/spi/LoggerContextVO.html"><code>LoggerContextVO</code></a></td>
- <td>ロギングイベントが割り当てられたロガーコンテキストの、値オブジェクトとしてのビュー。
- </td>
- </tr>
-
-
- <tr class="alt">
- <td>level</td>
- <td><code>int</code></td>
- <td>ログレベルに対応する整数値。ログレベルを含む評価式を簡潔にするため、<em>DEBUG</em>、<em>INFO
-</em>、<em>WARN</em>、<em>ERROR</em>が利用できるようになっています。たとえば、<em> level > INFO </em> は正しい評価式です。
- </td>
- </tr>
-
- <tr>
- <td>timeStamp
- </td>
- <td><code>long</code></td>
- <td>ロギングイベントの作成時のタイムスタンプ。
- </td>
- </tr>
- <tr class="alt">
- <td>marker</td>
- <td><code>Marker</code></td>
- <td>ロギング要求に関連付けられた<code>Marker</code>オブジェクト。マーカーオブジェクトがnullの場合もあるので、<code>NullPointerException</code>を避けるためにnullチェックをするのは使用者の責任です。
- </td>
- </tr>
- <tr>
- <td>mdc</td>
- <td><code>Map</code></td>
- <td>ロギングイベントの作成時に関連付けられたMDC。<em>mdc.get("MYKEY")</em>とすると値を参照できます。logback-classic 0.9.30以降では、'mdc'変数は決してnullになりません。
-
- <p>Janino はジェネリクスをサポートしていないので、<code>java.util.Map</code>には型パラメータがありません。つまり、<code>mdc.get()</code>の返り値の型は<code>Object</code>であって<code>String</code>ではないのです。戻り値で<code>String</code>のメソッドを実行するには、<code>String</code>にキャストしなければなりません。こんな感じです。
- <code>((String) mdc.get("k")).contains("val")</code>
- </p>
- </td>
- </tr>
-
- <tr class="alt">
- <td>throwable</td>
- <td>java.lang.Throwable</td>
- <td>ロギングイベントに例外オブジェクトが関連付けられていないときは、"throwable"変数はnullになります。"throwable"変数はシリアライズすると失われてしまいます。したがって、リモートサーバ側ではこの値は常にnullになります。ローカルとリモートで同じ評価式を使いたい場合は、次項の<code>throwableProxy</code>変数を使用してください。
- </td>
- </tr>
-
- <tr>
- <td>throwableProxy</td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/spi/IThrowableProxy.html"><code>IThrowableProxy</code></a></td>
- <td>ロギングイベント関連付けられた例外オブジェクトのプロキシオブジェクト。例外オブジェクトが関連付けられていないとき、"throwableProxy"変数はnullになります。"throwable"変数と違って、例外オブジェクトがロギングイベントに関連付けられているときは、シリアライズされてリモートサーバに渡された後でも "throwableProxy"変数の値はnullになりません。
- </td>
- </tr>
-
-
-
- </table>
-
- <p>具体的な例を見てみましょう。</p>
-
- <p class="example">例:評価式の基本的な使い方(<a href="http://logback.qos.ch/xref/chapters/filters/basicEventEvaluator.xml">logback-examples/src/main/java/chapters/filters/basicEventEvaluator.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('basicEventEvaluator');">Groovyとして表示</span>
- <pre id="basicEventEvaluator" class="prettyprint source longline"><configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <b><filter class="ch.qos.logback.core.filter.EvaluatorFilter">
- <evaluator> <!-- defaults to type ch.qos.logback.classic.boolex.JaninoEventEvaluator -->
- <expression><span class="green">return message.contains("billing");</span></expression>
- </evaluator>
- <OnMismatch>NEUTRAL</OnMismatch>
- <OnMatch>DENY</OnMatch>
- </filter></b>
- <encoder>
- <pattern>
- %-4relative [%thread] %-5level %logger - %msg%n
- </pattern>
- </encoder>
- </appender>
-
- <root level="INFO">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>設定ファイル中の太字部分で、<code>ConsoleAppender</code>に<code>EvaluatorFilter</code>を追加しています。<code>EvaluationFilter</code>に追加されたのは<code>JaninoEventEvaluator</code>です。<code>evaluator要素</code>の<span class="attr">class属性</span>を省略すると、Joranはデフォルトの<code>JaninoEventEvaluator</code>を使用します。これはJoranが暗黙的にコンポーネントの型を推測する<a href="http://logback.qos.ch/manual/onJoran.html#defaultClassMapping">珍しいケース</a>の1つです。
- </p>
-
- <p><em>expression要素</em>に指定されているのは評価式です。<code>return message.contains("billing");</code>という式の値は真偽値です。<em>message変数</em>は、<code>JaninoEventEvaluator</code>が自動的に公開した変数です。
- </p>
-
- <p><span class="option">OnMismatch</span>プロパティにNEUTRALが、<span class="option">OnMatch</span>プロパティにDENYが指定されているので、このフィルターはメッセージに"billing"という文字列の含まれているロギングイベントをすべて拒否することになります。
- </p>
-
- <p><a href="http://logback.qos.ch/xref/chapters/filters/FilterEvents.html"><code>FilterEvents</code></a>アプリケーションでは、0〜9までの連番を付けられた10個のロギング要求を生成します。まずはフィルター無しで<code>FilterEvents</code>を実行してみましょう。</p>
-
-<div class="source"><pre>
-java chapters.filters.FilterEvents src/main/java/chapters/filters/basicConfiguration.xml
-</pre></div>
-
- <p>次のように、全てのロギング要求が出力されます。</p>
-
-<div class="source"><pre>0 [main] INFO chapters.filters.FilterEvents - logging statement 0
-0 [main] INFO chapters.filters.FilterEvents - logging statement 1
-0 [main] INFO chapters.filters.FilterEvents - logging statement 2
-0 [main] DEBUG chapters.filters.FilterEvents - logging statement 3
-0 [main] INFO chapters.filters.FilterEvents - logging statement 4
-0 [main] INFO chapters.filters.FilterEvents - logging statement 5
-0 [main] ERROR chapters.filters.FilterEvents - <b>billing statement 6</b>
-0 [main] INFO chapters.filters.FilterEvents - logging statement 7
-0 [main] INFO chapters.filters.FilterEvents - logging statement 8
-0 [main] INFO chapters.filters.FilterEvents - logging statement 9</pre></div>
-
-
-
- <p>この中から"billing statement"を取り除きたいものとします。上記の<em>basicEventEvaluator.xml</em>では、メッセージに"billing"を含むロギングイベントをフィルタリングするので、まさに今欲しいものです。</p>
-
- <p><em>basicEventEvaluator.xml</em>を使って実行してみましょう。</p>
- <p class="source">java chapters.filters.FilterEvents src/main/java/chapters/filters/basicEventEvaluator.xml</p>
- <p>次のような出力になります。</p>
-
- <p class="source">0 [main] INFO chapters.filters.FilterEvents - logging statement 0
-0 [main] INFO chapters.filters.FilterEvents - logging statement 1
-0 [main] INFO chapters.filters.FilterEvents - logging statement 2
-0 [main] DEBUG chapters.filters.FilterEvents - logging statement 3
-0 [main] INFO chapters.filters.FilterEvents - logging statement 4
-0 [main] INFO chapters.filters.FilterEvents - logging statement 5
-0 [main] INFO chapters.filters.FilterEvents - logging statement 7
-0 [main] INFO chapters.filters.FilterEvents - logging statement 8
-0 [main] INFO chapters.filters.FilterEvents - logging statement 9</p>
-
-
- <p>Java評価式にはJavaのコードブロックを指定できます。つまり次のようなものでも正しい式なのです。</p>
-
- <pre class="prettyprint source"><evaluator>
- <expression>
- if(logger.startsWith("org.apache.http"))
- return true;
-
- if(mdc == null || mdc.get("entity") == null)
- return false;
-
- String payee = (String) mdc.get("entity");
-
- if(logger.equals("org.apache.http.wire") && <!-- & encoded as & -->
- payee.contains("someSpecialValue") &&
- !message.contains("someSecret")) {
- return true;
- }
-
- return false;
- </expression>
-</evaluator></pre>
-
-
- <h2 class="doAnchor" name="matcher">マッチャー</h2>
-
- <p><code>String</code>の<a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#matches%28java.lang.String%29">matchs()</a>メソッドを使えば文字列のパターンマッチをすることができます。ですが、毎回<code>Pattern</code>(正規表現)オブジェクトをコンパイルするコストがかかるので、つまりフィルターが呼び出されるたびにコストがかかることになってしまいます。このオーバーヘッドを無くすため、<a href="http://logback.qos.ch/xref/ch/qos/logback/core/boolex/Matcher.html">Matcher</a>オブジェクトを事前に複数用意することができます。定義したマッチャーオブジェクトは評価式の中から名前で参照できるようになります。</p>
-
- <p>マッチャーの使用例を見てみましょう。</p>
-
- <p class="example">例:マッチャーの定義(<a href="http://logback.qos.ch/xref/chapters/filters/evaluatorWithMatcher.xml">logback-examples/src/main/java/chapters/filters/evaluatorWithMatcher.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('evaluatorWithMatcher');">Groovyとして表示</span>
-
- <pre id="evaluatorWithMatcher" class="prettyprint source"><configuration debug="true">
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
- <evaluator>
- <b><matcher>
- <Name>odd</Name>
- <!-- filter out odd numbered statements -->
- <regex>statement [13579]</regex>
- </matcher>
-
- <expression>odd.matches(formattedMessage)</expression></b>
- </evaluator>
- <OnMismatch>NEUTRAL</OnMismatch>
- <OnMatch>DENY</OnMatch>
- </filter>
- <encoder>
- <pattern>%-4relative [%thread] %-5level %logger - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p><em>evaluatorWithMatcher.xml</em>の設定を使ってみましょう。</p>
- <p class="source">java chapters.filters.FilterEvents src/main/java/chapters/filters/evaluatorWithMatcher.xml</p>
- <p>コンソールには次のように出力されます。</p>
-
- <p class="source">260 [main] INFO chapters.filters.FilterEvents - logging statement 0
-264 [main] INFO chapters.filters.FilterEvents - logging statement 2
-264 [main] INFO chapters.filters.FilterEvents - logging statement 4
-266 [main] ERROR chapters.filters.FilterEvents - billing statement 6
-266 [main] INFO chapters.filters.FilterEvents - logging statement 8</p>
-
- <p>マッチャーを追加したければ、<code>matcher要素</code>を追加すればよいでしょう。</p>
-
-
-
-
-
- <!-- ================================================================ -->
- <!-- ===================== TURBO FILTER ============================= -->
- <!-- ================================================================ -->
-
- <h2 class="doAnchor" name="TurboFilter">TurboFilters</h2>
-
- <p><code>ターボフィルター</code>とは、<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/turbo/TurboFilter.html"><code>TurboFilter</code></a>抽象クラスを継承したオブジェクトのことです。通常フィルターと同様に、三値論理でロギングイベントを評価します。
- </p>
-
- <p>全体的に前に説明したフィルターと同じように動作します。ただし、<code>Filter</code>と<code>TurboFilter</code>には大きな違いが2つあります。
- </p>
-
- <p><code>TurboFilter</code>はロギングコンテキストに紐付けられています。したがって、アペンダーが使用されたときにだけ呼ばれるのではなく、ロギング要求が発生するたびに呼ばれることになります。つまり、ターボフィルターの有効範囲はアペンダーに割り当てられたフィルターよりも広いのです。
- </p>
-
- <p>さらに重要なのは、ターボフィルターが呼ばれるのは<code>LoggingEvent</code>オブジェクトが作成される前だということです。
- <code>TurboFilter</code>オブジェクトは、ロギング要求をフィルタリングするのにロギングイベントを必要としません。つまり、ターボフィルターはロギングイベントの高速なフィルタリングを意図したものなのです。
- </p>
-
-
- <h3 class="doAnchor" name="yourOwnTurboFilter">ターボフィルターを自作する</h3>
-
- <p><code>ターボフィルター</code>を自作するには、<code>TurboFilter</code>抽象クラスを継承するだけです。前述のとおり、フィルターを自作するには<code>decide()</code>メソッドを実装するだけでいいのです。少し複雑なフィルターの実装例を見てみましょう。</p>
-
- <p class="example">例:基本的な自作<code>TurboFilter</code>(<a href="http://logback.qos.ch/xref/chapters/filters/SampleTurboFilter.html">logback-examples/src/main/java/chapters/filters/SampleTurboFilter.java</a>)</p>
-
-<pre class="prettyprint source">package chapters.filters;
-
-import org.slf4j.Marker;
-import org.slf4j.MarkerFactory;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.turbo.TurboFilter;
-import ch.qos.logback.core.spi.FilterReply;
-
-public class SampleTurboFilter extends TurboFilter {
-
- String marker;
- Marker markerToAccept;
-
- @Override
- public FilterReply decide(Marker marker, Logger logger, Level level,
- String format, Object[] params, Throwable t) {
-
- if (!isStarted()) {
- return FilterReply.NEUTRAL;
- }
-
- if ((markerToAccept.equals(marker))) {
- return FilterReply.ACCEPT;
- } else {
- return FilterReply.NEUTRAL;
- }
- }
-
- public String getMarker() {
- return marker;
- }
-
- public void setMarker(String markerStr) {
- this.marker = markerStr;
- }
-
- @Override
- public void start() {
- if (marker != null && marker.trim().length() > 0) {
- markerToAccept = MarkerFactory.getMarker(marker);
- super.start();
- }
- }
-}
-</pre>
-
- <p>この<code>ターボフィルター</code>は、特定のマーカーが含まれているロギングイベントを受け付けます。マーカーが見つからなかったら、チェーン内の次のフィルターに引き継ぎます。
- </p>
-
- <p>柔軟性を考慮して、チェックするマーカーを設定ファイルで指定できるよう、アクセサメソッドが定義されています。他にも、設定ファイルの解釈中に、指定されたオプションをチェックするため、<code>start()</code>メソッドを実装しています。
- </p>
-
- <p>自作した<code>ターボフィルター</code>を使う設定ファイルは次のとおりです。
- </p>
-
- <p class="example">例:基本的な自作<code>TurboFilter</code>の設定(<a href="http://logback.qos.ch/xref/chapters/filters/sampleTurboFilterConfig.xml">logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('sampleTurboFilterConfig');">Groovyとして表示</span>
-
- <pre id="sampleTurboFilterConfig" class="prettyprint source"><configuration>
- <b><turboFilter class="chapters.filters.SampleTurboFilter">
- <Marker>sample</Marker>
- </turboFilter></b>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>
- %-4relative [%thread] %-5level %logger - %msg%n
- </pattern>
- </encoder>
- </appender>
-
- <root>
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>logback-classicの配布物にはいくつか<code>TurboFilter</code>の実装クラスが含まれています。<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/turbo/MDCFilter.html"><code>MDCFilter</code></a>を使うとMDC内の指定された値の存在をチェックすることができますし、<a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/turbo/DynamicThresholdFilter.html"><code>DynamicThresholdFilter</code></a>を使うとMDCのキーまたはレベルをしきい値でフィルタリングすることができます。また、<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/turbo/MarkerFilter.html"><code>MarkerFilter [...]
-
- <p><code>MDCFilter</code>と<code>MarkerFilter</code>の両方を使う設定を見てみましょう。
- </p>
-
- <p class="example">例:<code>MDCFilter</code>と<code>MarkerFilter</code>の設定例(<a href="http://logback.qos.ch/xref/chapters/filters/turboFilters.xml">logback-examples/src/main/java/chapters/filters/turboFilters.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('turboFilters');">Groovyとして表示</span>
- <pre id="turboFilters" class="prettyprint source"><configuration>
-
- <turboFilter class="ch.qos.logback.classic.turbo.MDCFilter">
- <MDCKey>username</MDCKey>
- <Value>sebastien</Value>
- <OnMatch>ACCEPT</OnMatch>
- </turboFilter>
-
- <turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
- <Marker>billing</Marker>
- <OnMatch>DENY</OnMatch>
- </turboFilter>
-
- <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%date [%thread] %-5level %logger - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="INFO">
- <appender-ref ref="console" />
- </root>
-</configuration></pre>
-
- <p>次のコマンドを実行してみましょう。</p>
-
- <p class="source">java chapters.filters.FilterEvents src/main/java/chapters/filters/turboFilters.xml</p>
-
- <p>前に見たように、<a href="http://logback.qos.ch/xref/chapters/filters/FilterEvents.html"><code>FilterEvents</code></a>アプリケーションは0〜9の連番を付けて10個のロギング要求を生成します。3番目と6番目を除く他のロギング要求のログレベルは<em>INFO</em>です。これはルートロガーに割り当てたログレベルと同じです。3番目のロギング要求のログレベルは<em>DEBUGレベル</em>で、これは有効レベルを下回っています。ですが、3番目のロギング要求を生成する直前に、MDCのキー"username"には値"sebastien"が設定され、直後に取り除かれています。そして、<code>MDCFIlter</code>はこのロギング要求だけを受け入れるようになっています。6番目のロギング要求はログレベル<em>ERROR</em>で、かつ、"billing" というマーカーが指定されています。このロギング要求はMarkerFilter(二つ目のターボフィルター) [...]
- </p>
-
- <p>結果として、<code>FilterEvents</code>アプリケーションに<em>turboFilters.xml</em>を指定した場合は次のように出力されます。</p>
-
- <p class="source">2006-12-04 15:17:22,859 [main] INFO chapters.filters.FilterEvents - logging statement 0
-2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 1
-2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 2
-2006-12-04 15:17:22,875 [main] DEBUG chapters.filters.FilterEvents - logging statement 3
-2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 4
-2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 5
-2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 7
-2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 8
-2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 9</p>
-
-
- <p>有効レベルは<em>INFO</em>なのに、3番目のロギング要求、つまり、ログレベルがDEBUGのロギング要求が出力されています。これは最初の<code>TurboFilter</code>が受け入れたからです。
- </p>
-
- <p>また、6番目のロギング要求はログレベルが<em>ERROR</em>なのに出力されていません。二つ目の<code>TurboFilter</code>の<span class="option">OnMatch</span>プロパティに<em>DENY</em>が指定されていたからです。
- </p>
-
-
-
-
- <h3 class="doAnchor" name="DuplicateMessageFilter">DuplicateMessageFilter</h3>
-
- <p><code>DuplicateMessageFilter</code>の利点は異なる見え方をします。メッセージの重複を検出し、一定回数以上繰り返す場合は、メッセージを破棄します。
- </p>
-
- <p>繰り返しの検出は、単純に文字列が一致するかどうかを見ています。数文字違うだけでそれは別のメッセージとして扱われるので、重複メッセージとしては検出しません。たとえばこんな風に書いたとしましょう。</p>
-
- <pre class="prettyprint source">logger.debug("Hello "+name0);
-logger.debug("Hello "+name1);</pre>
-
- <p><code>name0</code>と<code>name1</code>が別の値だとしたら、これらのメッセージは別のものであるとみなされます。利用者のニーズによりますが、将来のリリースでは文字列の類似度をチェックすることになりそうです。完全に同一ではないけどよく似ているメッセージの繰り返しを排除するたmです。
- </p>
-
- <p>ロギングメッセージに引数を指定している場合、書式化される前のメッセージが判定対象になるので注意してください。たとえば次の二つのロギング式のメッセージ部分はどちらも同じ "Hello {}." なので、これは重複メッセージと判定されます。
- </p>
-
- <pre class="prettyprint source">logger.debug("Hello {}.", name0);
-logger.debug("Hello {}.", name1);</pre>
-
- <p>繰り返しを許容する回数は<span class="option">AllowedRepetitions</span>プロパティで指定します。allowedRepetitionsプロパティに1を指定した場合、最初のメッセージは出力されて、2番目のメッセージは破棄されます。同様に、2を指定したら、1番目、2番目のメッセージは出力されて、三番目以降のメッセージは破棄されます。デフォルトは5が設定されています。
- </p>
-
- <p>繰り返しを検出するには、内部的に古いメッセージへの参照をキャッシュしておかなければなりません。このキャッシュのサイズは<span class="option">CacheSize</span>プロパティによって決まります。デフォルトは100(個)が設定されています。
- </p>
-
-
- <p class="example">例:<code>DuplicateMessageFilter</code>の設定例(<a href="http://logback.qos.ch/xref/chapters/filters/duplicateMessage.xml">logback-examples/src/main/java/chapters/filters/duplicateMessage.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('duplicateMessage');">Groovyとして表示</span>
- <pre id="duplicateMessage" class="prettyprint source"><configuration>
-
- <b><turboFilter class="ch.qos.logback.classic.turbo.DuplicateMessageFilter"/></b>
-
- <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%date [%thread] %-5level %logger - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="INFO">
- <appender-ref ref="console" />
- </root>
-</configuration></pre>
-
- <p><code>FilterEvents</code>アプリケーションに<em>duplicateMessage.xml</em>を指定した場合の出力は次のようになります。</p>
-
- <p class="source">2008-12-19 15:04:26,156 [main] INFO chapters.filters.FilterEvents - logging statement 0
-2008-12-19 15:04:26,156 [main] INFO chapters.filters.FilterEvents - logging statement 1
-2008-12-19 15:04:26,156 [main] INFO chapters.filters.FilterEvents - logging statement 2
-2008-12-19 15:04:26,156 [main] INFO chapters.filters.FilterEvents - logging statement 4
-2008-12-19 15:04:26,156 [main] INFO chapters.filters.FilterEvents - logging statement 5
-2008-12-19 15:04:26,171 [main] ERROR chapters.filters.FilterEvents - billing statement 6</p>
-
- <p>"logging statement 0" は、書式化する前のメッセージ"logging statement {}" によって出力された<em>最初</em>のメッセージです。"logging statement 1"が1回目の<em>繰り返し</em>、"logging statement 2"が2回目の繰り返しとなります。<em>3回目</em>の繰り返しとなる"logging statement 3"はログレベルがDEBUGのはずなので、<a href="http://logback.qos.ch/manual/architecture.html#basic_selection">基本的な選択ルール</a>によって破棄されました。つまり、ターボフィルターは基本的な選択ルールを含む他のフィルターに先駆けて呼び出されるということなのです。したがって、後続の処理チェインの中で破棄されてしまうのですが、<code>DuplicateMessageFilter</code>は"logging statement 3"を繰り返しメッセージだと判断したはずです。し [...]
- </p>
-
- <h1 class="doAnchor" name="logbac-access">logback-access モジュール</h1>
-
- <p>logback-access モジュールは logback-classic モジュールとほとんど同じ機能を提供します。具体的には、<code>Filter</code>オブジェクトはlogback-classic と同じように利用可能できますし、同じように動作します。一点だけ大きく違うころがあって、それは<code>LoggingEvent</code>のインスタンスではなく <a href="http://logback.qos.ch/xref/ch/qos/logback/access/spi/AccessEvent.html"><code>AccessEvent</code></a>のインスタンスを使うということです。現時点では、logback-access の配布物に含まれているフィルターの数はそれほど多くありません。追加のフィルターを提案したいときは、logback-dev メーリングリスト宛に連絡してください。
- </p>
-
- <h2 class="doAnchor" name="countingFilter"><code>CountingFilter</code></h2>
-
- <p>logback-access では、<a href="http://logback.qos.ch/manual/xref/ch/qos/logback/access/filter/CountingFilter.html"><code>CountingFilter</code></a>を使ってWebサーバへのアクセス統計情報を集めることができます。<code>CountingFilter</code>は、初期化時に実行プラットフォームの JMX サーバーに自身を MBean として登録します。その後は、MBean に統計情報を問い合わせることができるようになります。分平均、時間平均、日平均、週平均、月平均などです。他にも、集計単位の一つ前の情報と全体の合計を参照することができます。
- </p>
-
- <p><code>CountingFilter</code>を使用する設定ファイルを見てみましょう。</p>
-
- <pre class="prettyprint source"><configuration>
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
-
- <b><filter class="ch.qos.logback.access.filter.CountingFilter">
- <name>countingFilter</name>
- </filter></b>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%h %l %u %t \"%r\" %s %b</pattern>
- </encoder>
- </appender>
-
- <appender-ref ref="STDOUT" />
-</configuration></pre>
-
- <p><code>CountingFilter</code>の収集する統計情報は、例えば<code>jconsole</code>から JMX サーバにアクセスして参照することができます。</p>
-
-
- <img alt="jconsoleを経由してCountingFilterにアクセス" src="images/chapters/filters/countingFilter.png">
-
-
- <h3 class="doAnchor" name="access_EvalutorFilter">EvaluatorFilter</h3>
-
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/core/filter/EvaluatorFilter.html"><code>EvaluatorFilter</code></a>は<code>EventEvaluator</code>をカプセル化した汎用的なフィルターです。名前が示すように、 <code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/boolex/EventEvaluator.html">EventEvaluator</a></code>は指定された条件を評価して、イベントがその条件を満たすかどうかを判定します。条件を満たす場合もそうでない場合も、<code>EvaluatorFilter</code>の<span class="option">onMatch</span>プロパティ、または、<span class="option">onMismatch</span>プロパティに指定された値を返します。<code>Eva [...]
-
-
- <p><code>EventEvaluator</code>は抽象クラスです。
-つまり、<code>EventEvaluator</code>を継承すれば、独自のイベント評価ロジックを実装することができます。
-logback-accessの配布物には<a href="http://logback.qos.ch/xref/ch/qos/logback/access/boolex/JaninoEventEvaluator.html">JaninoEventEvaluator</a>という実装クラスが含まれています。これは、booleanを返す任意のJava言語のブロックを評価するものです。私たちはこのJava言語で書かれた式のことを"<em>Java評価式</em>”と呼んでいます。
-Java評価式を使うとロギングイベントを柔軟にフィルタリングできるようになります。
-<code>JaninoEventEvaluator</code>を使用するには<a href="http://docs.codehaus.org/display/JANINO/Home">Janinoライブラリ</a>が必要です。
-設定方法は設定ドキュメントの<a href="http://logback.qos.ch/setup.html#janino">対応するセクション</a>を参照してください。
-
- </p>
-
- <p>Java評価式は設定ファイルを解釈する間にコンパイルされます。
-どのように呼び出すのか、利用者は気にすることはありません。
-ですが、Java言語の式が真偽値を返すものであることを保証するのは利用者の責任です。
-</p>
-
-
- <p>Java評価式は一度に1つのイベントを扱います。logback-accessは、<code>AccessEvent</code>を<b><code>event</code></b>という名前の変数として公開します。<code>event</code>変数を介して、HTTPリクエストやHTTP応答に関連付けられたさまざまなデータを参照することができます。正確なところは<a href="http://logback.qos.ch/xref/ch/qos/logback/access/spi/AccessEvent.html">AccessEvent</a>クラスの<code>ソースコード</code>を読んでください。
- </p>
-
- <p>次の設定ファイルでは、応答コード<a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5">404(Not Found)</a>をひっかけます。つまり、応答コードが404になったHTTPリクエストをすべてコンソールに出力するのです。</p>
-
- <p class="example">例:Access Evaluator(<a href="http://logback.qos.ch/xref/chapters/filters/accessEventEvaluator.xml">logback-examples/src/main/java/chapters/filters/accessEventEvaluator.xml</a>)</p>
-
-<pre class="prettyprint source"><configuration>
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <b><filter class="ch.qos.logback.core.filter.EvaluatorFilter">
- <evaluator>
- <expression>event.getStatusCode() == 404</expression>
- </evaluator>
- <onMismatch>DENY</onMismatch>
- </filter></b>
- <encoder><pattern>%h %l %u %t %r %s %b</pattern></encoder>
- </appender>
-
- <appender-ref ref="STDOUT" />
-</configuration></pre>
-
- <p>次の設定ファイルでは、やはり404エラーをひっかけているのですが、CSSファイルを要求したものだけをひっかけています。
- </p>
-
-
- <p class="example">例6.10:Access Evaluator(<a href="http://logback.qos.ch/xref/chapters/filters/accessEventEvaluator2.xml">logback-examples/src/main/java/chapters/filters/accessEventEvaluator2.xml</a>)</p>
-
- <pre class="prettyprint source"><configuration>
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
- <evaluator name="Eval404">
- <expression>
- <b>(event.getStatusCode() == 404)</b>
- <b>&&</b> <!-- ampersand characters need to be escaped -->
- <b>!(event.getRequestURI().contains(".css"))</b>
- </expression>
- </evaluator>
- <onMismatch>DENY</onMismatch>
- </filter>
-
- <encoder><pattern>%h %l %u %t %r %s %b</pattern></encoder>
- </appender>
-
- <appender-ref ref="STDOUT" />
-</configuration>
- </pre>
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-
- </div>
-</body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/groovy.html b/logback-site/src/site/pages/manual/groovy.html
index 0c43100..7d34167 100644
--- a/logback-site/src/site/pages/manual/groovy.html
+++ b/logback-site/src/site/pages/manual/groovy.html
@@ -31,11 +31,8 @@
<div id="content" class="chapter">
<h1>Chapter 12: Groovy Configuration</h1>
-
- <a href="groovy_ja.html">和訳 (Japanese translation)</a>
-
- <div class="quote">
+ <div class="quote">
<p><em>It is better to be a human being dissatisfied than a pig
satisfied; better to be a Socrates dissatisfied than a fool
satisfied. And if the fool or the pig thinks otherwise, it is
@@ -252,7 +249,7 @@ root(DEBUG, ["FILE"])</pre>
formatted according to the <code>datePattern</code> parameter. The
<code>datePattern</code> parameter should follow the conventions
defined by <a
- href="https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a>. If
+ href="http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a>. If
the <code>timeReference</code> value is unspecified, it defaults
to -1, in which case current time, that is time when the
configuration file is parsed, is used as the time
diff --git a/logback-site/src/site/pages/manual/groovy_ja.html b/logback-site/src/site/pages/manual/groovy_ja.html
deleted file mode 100644
index 24c13a4..0000000
--- a/logback-site/src/site/pages/manual/groovy_ja.html
+++ /dev/null
@@ -1,364 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第12章 Groovyによる設定</title>
-
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
-
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content" class="chapter">
-
- <h1>第12章 Groovyによる設定</h1>
-
- <div class="quote">
- <p><em>満足した豚になるより不満を抱えた人間になるほうがずっと良い。ましてや、満足気な愚か者になるより不満だらけのソクラテス派になるほうがずっと良い。豚や愚か者がこれとは異なる主張をしたとしても、それは彼らに良いとされる側の経験が無いからなのだ。
- </em>
- </p>
- <p>-ジョン·スチュアート·ミル、 <em>功利主義</em></p>
- </div>
- <script src="../templates/creative.js" type="text/javascript"></script>
-
-
- <p>ドメイン固有言語やDSLはかなり普及しています。XMLベースのlogbackの設定は、DSLのインスタンスとみなすことができます。XMLの性質上、設定ファイルは非常に冗長でかさばるものになります。さらに、logbackのコードの大部分はXMLベースの設定ファイル処理専用のJoranと呼ばれるものです。Joranは、変数置換や条件分岐、および実行時の拡張など、気の利いた機能をサポートしています。しかし、Joranの問題は複雑さだけではありません。ユーザーエクスペリエンスは不十分ですし、直感とはかけ離れています。
- </p>
-
- <p>この章で説明するGroovyベースのDSLは、一貫性があり、直感的で、かつ、強力であることを目指しています。XMLの設定ファイルでできることはすべて、それもより短い行数で実現することができます。Groovyスタイルの設定ファイルへの移行を支援するために、<a href="http://logback.qos.ch/translator/asGroovy.html">既存の<em>logback.xml</em>を自動的に<em>logback.groovy</em>へ変換するツールを用意しました</a>。
- </p>
-
-
- <h2 class="doAnchor">基本的な哲学</h2>
-
- <p>基本的なルールを説明します。<em>logback.groovy</em>はGroovyのプログラムです。Groovy言語はJava言語のスーパーセットなので、Javaにできるあらゆる設定アクションと同じことを<em>logback.groovy</em>で実行することができます。ですが、logbackをJavaの構文でプログラム的に設定するのはかなり厄介なので、logback専用の拡張構文を追加しました。logback専用の拡張構文はできるだけ少なくなるようにしましたし、実際のところほんのわずかしかありません。Groovyに慣れているとしても本章に目を通してもらって、<em>logback.groovy</em>を書くのは非常に簡単であることを理解してください。Groovyに不慣れな方であっても、<em>logback.xml</em>を使い続けるより<em>logback.groovy</em>の記法のほうがずっとわかりやすいと思えるようになるはずです。
- </p>
-
- <p>改めて整理します。<em>logback.groovy</em>は最小限のlogback専用の拡張がなされたGroovyプログラムです。<em>logback.groovy</em>の中では、クラスのimportや変数定義、変数評価、GString の${..}記法、if-else構文などのGroovyの機能は<em>全て</em>利用可能です。</p>
-
- <h2 class="doAnchor">自動import</h2>
-
- <p><span class="label">logback1.0.10以降</span>決まりきったものになる共通するクラスやパッケージのimportをしなくてもすむように、自動的にimportします。したがって、組み込みのアペンダーやレイアウトについてはわざわざimport文を書かなくても設定だけでよいのです。もちろん、デフォルトのimportでカバーされていないクラスやパッケージがあるなら、それは自分でやらなければなりません。</p>
-
- <p>デフォルトのimport対象は次のとおりです。</p>
-
- <ul>
- <li><span class="code">import ch.qos.logback.core.*;</span></li>
- <li><span class="code">import ch.qos.logback.core.encoder.*;</span></li>
- <li><span class="code">import ch.qos.logback.core.read.*;</span></li>
- <li><span class="code">import ch.qos.logback.core.rolling.*;</span></li>
- <li><span class="code">import ch.qos.logback.core.status.*;</span></li>
- <li><span class="code">import ch.qos.logback.classic.net.*;</span></li>
- <li><span class="code">import ch.qos.logback.classic.encoder.PatternLayoutEncoder;</span></li>
- </ul>
-
- <p>さらに、<span class="code">ch.qos.logback.classic.Level</span>の全ての定数は、大文字バージョンと小文字バージョンのそれぞれでstatic importされます。つまり、スクリプトでは<em>INFO</em>と<em>info</em>のどちらでも利用できます。</p>
-
-
- <h2 class="doAnchor" name="sift">SiftingAppenderはサポートされなくなりました</h2>
-
- <p><span class="label">logback1.0.12以降</span>Groovy設定ファイルでは<code>SiftingAppender</code>はサポートされなくなりました。需要がありそうなら復活するかもしれません。</p>
-
- <h2 class="doAnchor" name="entensions"><em>logback.groovy</em>用の拡張構文</h2>
-
- <p><span class="green">基本的に<em>logback.groovyの構文</em>は、次に説明する半ダースほどのメソッドで構成されています。これらは実際に定義する順番とは逆順に並んでいます。</span>厳密に言えば、これらのメソッドの呼び出し順序は1つの例外(アペンダーはそれを割り当てるロガーの前に定義しなければならない)を除いて重要ではありません。</p>
-
-
-
- <!-- ========================================================== -->
-
- <h3> • <span class="code">root(Level level, List<String> appenderNames = [])</span></h3>
-
- <p><code>root</code>メソッドはルートロガーのログレベルを設定するために使用します。第二引数のappenderName(<code>List<String></code>)は任意で、ルートロガーに割り当てるアペンダーを名前で指定します。引数に値を指定しなければ、空のリストが指定されたものとして扱います。。Groovyでは空のリストを<code>[]</code>で記述します。</p>
-
- <p>ルートロガーのログレベルにWARNを設定するには次のように記述します。</p>
-
- <pre class="prettyprint source">root(WARN)</pre>
-
- <p>ルートロガーのログレベルにINFOを設定し、"CONSOLE"アペンダーと"FILE"アペンダーを割り当てるには次のように記述します。</p>
-
- <pre class="prettyprint source">root(INFO, ["CONSOLE", "FILE"])</pre>
-
- <p>"CONSOLE"と"FILE"という名前のアペンダーはすでに定義されているものとします。アペンダーの定義の仕方はすぐ後で説明します。
- </p>
-
- <!-- ========================================================== -->
-
- <h3>• <span class="code">logger(String name, Level level, List<String> appenderNames = [], <br> Boolean additivity = null)</span></h3>
-
- <p><code>logger()</code>メソッドは引数を四つとります。後ろの二つは任意です。第一引数にはロガーの名前を指定します。第二引数にはロガーのログレベルを指定します。ログレベルに<code>null</code>を指定すると、直近の祖先ロガーに指定されたログレベルを<a href="./01-architecture.html#effectiveLevel">継承</a>するという意味になります。第三引数は<code>List<String></code>で任意です。省略した場合は空のリストを指定したものとして扱います。リストにはロガーに割り当てるアペンダーの名前を並べます。第四引数は<code>Boolean</code>でこちらも任意です。<a href="./01-architecture.html#additivity">additivityフラグ</a>として使われます。省略した場合は<code>null</code>が指定されたものとして扱います。
- </p>
-
- <p>たとえば、次のスクリプトはロガー名として"com.foo"、ログレベルとしてINFOを設定します。</p>
-
- <pre class="prettyprint source">logger("com.foo", INFO)</pre>
-
- <p>次のスクリプトは、ロガー名として"com.foo"、ログレベルとしてDEBUG、そしてアペンダーに"CONSOLE"を割り当てます。</p>
-
- <pre class="prettyprint source">logger("com.foo", DEBUG, ["CONSOLE"])</pre>
-
- <p>次のスクリプトは前のスクリプトとほとんど同じですが、additivityフラグにfalseを設定します。</p>
-
- <pre class="prettyprint source">logger("com.foo", DEBUG, ["CONSOLE"], false)</pre>
-
-
- <!-- ========================================================== -->
- <h3>• <span class="code">appender(String name, Class clazz, Closure closure = null)</span></h3>
-
- <p>appender()メソッドでは、第一引数にアペンダーの名前を指定します。第二引数は必須で、インスタンス化するアペンダーのクラスを指定します。第三引数には、そのほかの設定をするクロージャーを指定します。省略した場合はnullになります。</p>
-
- <p>ほとんどのアペンダーは、ちゃんと動作するためにプロパティを設定したりサブコンポーネントを注入しなければなりません。プロパティを設定するには '='演算子(代入)を使用します。サブコンポーネントを注入するには、プロパティ名をメソッド名のように記述して、引数にインスタンス化するクラスを指定します。このコーディング規約は、アペンダーのあらゆるサブコンポーネントについても同じように再帰的に適用されるものです。このアプローチは<em>logback.groovy</em>の中核を為すもので、覚えなければならない唯一の規約となるでしょう。</p>
-
- <p>例を見てみましょう。次のスクリプトは"FILE"という名前の<code>FileAppender</code>をインスタンス化して、<span class="option">file</span>プロパティに"testFile.log"を設定し、<span class="option">append</span>プロパティにfalseを設定しています。encoderには<code>PatternLayoutEncoder</code>を注入しています。encoderのpatternプロパティには" - %level %logger - %msg%n"を設定しています。そしてこのアペンダーをルートロガーに割り当てます。</p>
-
- <pre class="prettyprint source">appender("FILE", FileAppender) {
- file = "testFile.log"
- append = true
- encoder(PatternLayoutEncoder) {
- pattern = "%level %logger - %msg%n"
- }
-}
-
-root(DEBUG, ["FILE"])</pre>
-
- <p>
- </p>
-
-
- <!-- ========================================================== -->
- <h3>• <span class="code">timestamp(String datePattern, long timeReference = -1)</span></h3>
-
- <p><code>timestamp()</code>メソッドは、<code>datePattern</code>に指定された書式文字列で<code>timeReference</code>に指定されたlong値の時間を書式化した文字列を返します。第一引数の<code>datePattern</code>に指定する書式文字列は、<a href="https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a>で定義されている規則に従わなければなりません。第二引数の<code>timeReference</code>が省略された場合-1が指定されたものとして扱います。これは設定ファイルを解析しているときの現在日時を表す値です。状況によりますが、基準時間として<code>context.birthTime</code>を使うこともあるでしょう。
- </p>
-
- <p>次の例では、 <code>bySecond</code>変数に"yyyyMMdd'T'HHmmss"という書式で文字列化した現在日時を代入していますそして、"bySecond" 変数を<span class="option">file</span>プロパティの値として使っています。
- </p>
-
-<pre class="prettyprint source"><b>def bySecond = timestamp("yyyyMMdd'T'HHmmss")</b>
-
-appender("FILE", FileAppender) {
- <b>file = "log-${bySecond}.txt"</b>
- encoder(PatternLayoutEncoder) {
- pattern = "%logger{35} - %msg%n"
- }
-}
-root(DEBUG, ["FILE"])</pre>
-
- <!-- ========================================================== -->
- <h3>• <span class="code">conversionRule(String conversionWord, Class converterClass)</span></h3>
-
- <p><a href="./06-layouts.html#customConversionSpecifier">変換指定子</a>を自作しても、logbackに教えてあげなければ利用できません。このlogback.groovyでは、logbackが<code>%sample</code>という変換指定子に対してMySampleConverterを呼び出すようにしています。
- </p>
-
- <pre class="prettyprint source">
-import chapters.layouts.MySampleConverter
-
-conversionRule("sample", MySampleConverter)
-appender("STDOUT", ConsoleAppender) {
- encoder(PatternLayoutEncoder) {
- pattern = "%-4relative [%thread] %<b>sample</b> - %msg%n"
- }
-}
-root(DEBUG, ["STDOUT"])</pre>
-
- <!-- ========================================================== -->
- <h3>• <span class="code">scan(String scanPeriod = null)</span></h3>
-
- <p>scan()メソッドを使うと、logbackが定期的にlogback.groovyの変更を監視するようになります。logbackは変更を検出するたびに<em>logback.groovy</em>を再読み込みします。</p>
-
- <pre class="prettyprint source">scan()</pre>
-
- <p>デフォルトでは、一分ごとに設定ファイルの変更を監視します。監視周期を指定するには、"scanPeriod" 文字列引数を指定します。"scanPeriod" に指定する文字列には、時間単位としてミリ秒、秒、分または時間を含めることができます。例をみてください。</p>
-
- <pre class="prettyprint source">scan("30 seconds")</pre>
-
- <p>時間単位がない場合ミリ秒が指定されたものとして扱いますが、ほとんどの場合これは不適切な単位です。デフォルトの監視周期を変更する場合は、時間単位を指定することを忘れないでください。どのように変更を監視するのかについて詳しくは<a href="./03-configuration.html#autoScan">自動再読み込みのセクション</a>を参照してください。
- </p>
-
- <!-- ========================================================== -->
-
- <h3>• <span class="code">statusListener(Class listenerClass)</span></h3>
-
- <p><code>statusListener()</code>メソッドは、指定したリスナークラスをステータスリスナーとして追加します。例を見てください。</p>
-
- <pre class="prettyprint source">import chapters.layouts.MySampleConverter
-
-<b>// statusListener()メソッドの呼び出しはimport文の直後、他の式よりも前に置くことを強く推奨します</b>
-<b>statusListener(OnConsoleStatusListener)</b></pre>
-
- <p><a href="./03-configuration.html#statusListener">ステータスリスナー</a>については前の章で説明しました。</p>
-
- <h3>• <span class="code">jmxConfigurator(String name)</span></h3>
-
- <p><a href="./10-jmxConfig.html"><code>JMXConfigurator</code></a>のMBeanを登録します。MBean名としてデフォルトのオブジェクト名(<code>ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator</code>)を使うには引数を指定せずに呼び出してください。</p>
-
- <pre class="prettyprint source">jmxConfigurator()</pre>
-
- <p><code>Name</code>キーに"default"以外の値を指定するには、<code>jmxConfigurator()</code>メソッドの引数として指定するだけです。</p>
-
- <pre class="prettyprint source">jmxConfigurator('MyName')</pre>
-
- <p>オブジェクト名全体を指定したい場合は、正確なオブジェクト名文字列を引数に指定してください。</p>
-
- <pre class="prettyprint source">jmxConfigurator('myApp:type=LoggerManager')</pre>
-
- <p>このメソッドは、指定された文字列をオブジェクト名として使おうとしてから、それが有効なオブジェクト名ではなかったら、フォールバックとして"Name"キーの値にします。</p>
-
- <!-- ========================================================== -->
-
- <h2 class="doAnchor" name="internalDSL">内部DSL、すべてはGroovyの賜物だ!</h2>
-
- <p><em>logback.groovy</em>は内部DSLです。つまり、内容自体が実行可能なGroovyスクリプトなのです。したがって、logback.groovyの中ではGroovy言語に備わっているクラスimport、GString、変数定義、GString文字列中の${..}記法の評価、if-else文などのあらゆる機能を利用することができるのです。以降の説明では<em>logback.groovy</em>における典型的なGroovy言語の使用例を紹介します。
- </p>
-
-
- <h3 class="doAnchor" name="varedef">変数定義、そしてGString</h3>
-
- <p><em>logback.groovy</em>の中ならどこでも変数を定義することができますし、その変数をGString文字列の中で評価することができます。例を見てください。</p>
-
- <pre class="prettyprint source">// USER_HOME 変数にシステムプロパティの "user.home" の値を代入します
-<b>def USER_HOME = System.getProperty("user.home")</b>
-
-appender("FILE", FileAppender) {
- // USER_HOME 変数を使います
- <b>file = "${USER_HOME}/myApp.log"</b>
- encoder(PatternLayoutEncoder) {
- pattern = "%msg%n"
- }
-}
-root(DEBUG, ["FILE"])</pre>
-
-
- <h3 class="doAnchor" name="printing">コンソールへの出力</h3>
-
- <p>Groovyの<code>println()</code>メソッドを使ってコンソールに出力することができます。例を見てください。</p>
-
- <pre class="prettyprint source">def USER_HOME = System.getProperty("user.home");
-<b>println "USER_HOME=${USER_HOME}"</b>
-
-appender("FILE", FileAppender) {
- <b>println "Setting [file] property to [${USER_HOME}/myApp.log]"</b>
- file = "${USER_HOME}/myApp.log"
- encoder(PatternLayoutEncoder) {
- pattern = "%msg%n"
- }
-}
-root(DEBUG, ["FILE"])</pre>
-
-
- <h3 class="doAnchor" name="automaticallyExported">自動的に公開されるフィールド</h3>
-
- <h4 class="doAnchor" name="hostname">'hostname' 変数</h4>
-
- <p>'hostname' 変数にはスクリプトを実行しているホスト名が設定されています。このドキュメントの著者には正確な説明はできませんが、可視範囲のルールがあるため、'hostname'変数が利用できるのは最上位のスコープだけで、ネストされたスコープからは参照できません。次の例を見ればどういうことかわかるでしょう。
- </p>
-
- <pre class="prettyprint source">// will print "hostname is x" where x is the current host's name
-println "Hostname is ${hostname}"
-
-appender("STDOUT", ConsoleAppender) {
- <b>// will print "hostname is null"</b>
- <b>println "Hostname is ${hostname}" </b>
-}</pre>
-
- <p>すべてのスコープでhostname変数を使いたいなら、次のように別の変数に代入して参照しなければなりません。</p>
-
- <pre class="prettyprint source">// define HOSTNAME by assigning it hostname
-def HOSTNAME=hostname
-// will print "hostname is x" where x is the current host's name
-println "Hostname is ${HOSTNAME}"
-
-appender("STDOUT", ConsoleAppender) {
- // will print "hostname is x" where x is the current host's name
- println "Hostname is ${HOSTNAME}"
-}</pre>
-
-
- <h3 class="doAnchor" name="everythingIsContext">現在のコンテキストを参照するContextAwareが全ての土台になっている</h3>
-
- <p><em>logback.groovy</em>スクリプトは<a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/ContextAware.html">ContextAware</a>オブジェクト上で実行されます。したがって、<code>context</code>変数からいつでも現在のコンテキストにアクセスすることができます。それに、<code>addInfo()</code>メソッドや<code>addWarn()</code>メソッド、<code>addError()</code>メソッドで、<code>StatusManager</code>にステータスメッセージを伝えることができます。</p>
-
- <pre class="prettyprint source">// always a good idea to add an on console status listener
-statusListener(OnConsoleStatusListener)
-
-// set the context's name to wombat
-<b>context.name = "wombat"</b>
-// add a status message regarding context's name
-<b>addInfo("Context name has been set to ${context.name}")</b>
-
-def USER_HOME = System.getProperty("user.home");
-// add a status message regarding USER_HOME
-<b>addInfo("USER_HOME=${USER_HOME}")</b>
-
-appender("FILE", FileAppender) {
- // add a status message regarding the file property
- <b>addInfo("Setting [file] property to [${USER_HOME}/myApp.log]")</b>
- file = "${USER_HOME}/myApp.log"
- encoder(PatternLayoutEncoder) {
- pattern = "%msg%n"
- }
-}
-root(DEBUG, ["FILE"])</pre>
-
-
- <h3 class="doAnchor">条件付き設定</h3>
-
- <p>Groovyは本格的なプログラミング言語なので、条件分岐を使うと1つの<em>logback.groovy</em>をdevelopment、testing、productionといったいろいろな環境で使い回すことができます。</p>
-
- <p>次のスクリプトでは、ホスト名が本番環境のホスト名である pixie あるいは orion 以外の場合コンソールアペンダーが有効になるようにしています。ローリングファイルアペンダーの出力ディレクトリがホスト名に依存していることにも気をつけてください。</p>
-
- <pre class="prettyprint source">// always a good idea to add an on console status listener
-statusListener(OnConsoleStatusListener)
-
-def appenderList = ["ROLLING"]
-def WEBAPP_DIR = "."
-def consoleAppender = true;
-
-// does hostname match pixie or orion?
-if (hostname =~ /pixie|orion/) {
- WEBAPP_DIR = "/opt/myapp"
- consoleAppender = false
-} else {
- appenderList.add("CONSOLE")
-}
-
-if (consoleAppender) {
- appender("CONSOLE", ConsoleAppender) {
- encoder(PatternLayoutEncoder) {
- pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
- }
- }
-}
-
-appender("ROLLING", RollingFileAppender) {
- encoder(PatternLayoutEncoder) {
- Pattern = "%d %level %thread %mdc %logger - %m%n"
- }
- rollingPolicy(TimeBasedRollingPolicy) {
- FileNamePattern = "${WEBAPP_DIR}/log/translator-%d{yyyy-MM}.zip"
- }
-}
-
-root(INFO, appenderList)</pre>
-
-
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
- </div>
- </body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/index.html b/logback-site/src/site/pages/manual/index.html
index 3ee3d31..acd9bbd 100644
--- a/logback-site/src/site/pages/manual/index.html
+++ b/logback-site/src/site/pages/manual/index.html
@@ -25,7 +25,6 @@
<h2>The logback manual</h2>
- <a href="index_ja.html">和訳 (Japanese translation)</a>
<p>The complete logback manual documents the latest version of
logback framework. In over 150 pages and dozens of concrete
diff --git a/logback-site/src/site/pages/manual/index_ja.html b/logback-site/src/site/pages/manual/index_ja.html
deleted file mode 100644
index c0ed9df..0000000
--- a/logback-site/src/site/pages/manual/index_ja.html
+++ /dev/null
@@ -1,115 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>Logbackマニュアル</title>
-
- <link rel="stylesheet" type="text/css" href="../css/common.css" />
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen" />
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print" />
-
- </head>
- <body dir="ltr">
- <script type="text/javascript">prefix='../';</script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h2>logback マニュアル</h2>
-
-
- <p>このマニュアルでは、logbackフレームワークの最新バージョンについて説明しています。百五十ページを超える説明、および、数十もの具体例によって、logback のフィーチャの基本的な使い方と応用的な使い方を説明します。大きく次のような内容が含まれています。</p>
-
-
- <div>
- <ul>
- <li><p>logbackの全体的なアーキテクチャ</p></li>
- <li><p>最高のプラクティスとアンチパターンについての議論</p></li>
- <li><p>XML形式のlogback設定</p></li>
- <li><p>アペンダー</p></li>
- <li><p>エンコーダー</p></li>
- <li><p>レイアウト</p></li>
- <li><p>フィルター</p></li>
- <li><p>診断コンテキスト(MDC)</p></li>
- <li><p>logbackの設定システム Joran の解説</p></li>
- </ul>
- </div>
-
-
- <p>このマニュアルは、logback の API をかなり詳細に説明したもので、フィーチャや設計の理論的な根拠も含まれます。執筆したのは logback プロジェクトの主要な貢献者である CekiGülcü と Sébastien Pennec です。
-このマニュアルの対象者としては、Javaによる開発の経験はあるけど logback を使ったことがない人から、logback について経験豊富な人までを想定しています。入門資料と多くの具体例を手がかりにすれば、例え未経験であってもすぐに慣れることができるはずです。
- </p>
-
-
-
- <div>
- <p>ここまでで特に疑問に思うことがなければ、早速ここから読み進めてください。</p>
-
- <ul>
- <li><p>
- <a href="introduction_ja.html"><b>第1章:はじめに</b></a>
- </p></li>
- <li><p>
- <a href="architecture_ja.html"><b>第2章:アーキテクチャ</b></a>
- </p></li>
- <li><p>
- <a href="configuration_ja.html"><b>第3章:設定</b></a>
- </p></li>
-
- <li><p>
- <a href="appenders_ja.html"><b>第4章:アペンダー</b></a>
- </p></li>
-
- <li><p><a href="encoders_ja.html"><b>第5章:エンコーダー</b></a></p>
- </li>
-
- <li><p>
- <a href="layouts_ja.html"><b>第6章:レイアウト</b></a>
- </p></li>
-
- <li><p>
- <a href="filters_ja.html"><b>第7章:フィルタ</b></a>
- </p></li>
-
- <li><p>
- <a href="mdc_ja.html"><b>第8章:診断コンテキスト(MDC)</b></a>
- </p></li>
-
- <li><p>
- <a href="loggingSeparation_ja.html"><b>第9章:ログの分離</b></a>
- </p></li>
-
- <li><p>
- <a href="jmxConfig_ja.html"><b>第10章:JMXコンフィギュレーター</b></a>
- </p></li>
-
- <li><p>
- <a href="onJoran_ja.html"><b>第11章:Joran</b></a>
- </p></li>
-
- <li><p><a href="groovy_ja.html"><b>第12章:Groovyによる設定</b></a></p></li>
-
- <li><p>
- <a href="migrationFromLog4j_ja.html"><b>第13章:log4jからの移行</b></a>
- </p></li>
-
- <li><p>
- <a href="receivers_ja.html"><b>第14章:レシーバー</b></a>
- </p></li>
-
- <li><p>
- <a href="usingSSL_ja.html"><b>第15章:SSLの使用</b></a>
- </p></li>
-
- </ul>
- </div>
-
- <script src="../templates/footer.js" type="text/javascript"></script>
- </div>
- </body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/introduction.html b/logback-site/src/site/pages/manual/introduction.html
index 2bb8ea4..f8aa345 100644
--- a/logback-site/src/site/pages/manual/introduction.html
+++ b/logback-site/src/site/pages/manual/introduction.html
@@ -42,11 +42,8 @@
<script src="../templates/creative.js" type="text/javascript"></script>
-
<h2>What is logback?</h2>
- <a href="introduction_ja.html">和訳 (Japanese translation)</a>
-
<p>Logback is intended as a successor to the popular log4j
project. It was designed by Ceki Gülcü, log4j's
founder. It builds upon a decade of experience gained in
diff --git a/logback-site/src/site/pages/manual/introduction_ja.html b/logback-site/src/site/pages/manual/introduction_ja.html
deleted file mode 100644
index dffc697..0000000
--- a/logback-site/src/site/pages/manual/introduction_ja.html
+++ /dev/null
@@ -1,165 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第1章:はじめに</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
-
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第1章 はじめに</h1>
-
- <div class="quote">
- <p><em>やる気のもたらす効果には驚くべきものがある。例え簡単なシステムであろうとも、一つでも稼働しているシステムがあれば熱意は燃え上がる。新しいグラフィカルソフトウェアを使って、スクリーンに画像が表示されたなら、たとえそれが単純な四角形であったとしても、その効果は倍増する。システムを稼働させるまでのプロセス一つ一つにそういう瞬間があるものだ。チームが四ヶ月かけて何かを成し遂げたなら、きっとそれ以上に複雑なことが出来るほどに成長できることに気付かされたものだ。</em></p>
-
- <p>—FREDERICK P. BROOKS, JR., <em>The Mythical Man-Month</em></p>
- </div>
-
-
- <script src="../templates/creative.js" type="text/javascript"></script>
-
- <h2>logbackとは何か?</h2>
-
- <p>Logback は巷で大人気の log4j プロジェクトの後継プロジェクトです。log4j の創始者であるCekiGülcü によって設計されました。強固で頑健なロギングシステムの十年間に及ぶ経験に基いて設計、構築されています。おかげで、logback は既存のロギングシステムと比べてより高速で、より小さなフットプリントを持つようになりました。場合によってはその差は非常に大きなこともあります。同じくらい重要なのが、logback は他のロギングシステムには無い<a href="http://logback.qos.ch/reasonsToSwitch.html">固有の便利なフィーチャ</a>を提供していることです。
- </p>
-
- <h2>最初のステップ</h2>
-
- <script src="../templates/setup.js" type="text/javascript"></script>
-
- <a name="Requirements"></a>
- <h3>必要条件</h3>
-
- <p>logback-classic モジュールを動かす際は、クラスパス上に <em>slf4j-api.jar</em> と <em>logback-core.jar</em> と <em>logback-classic.jar</em> が配置されている必要があります。
- </p>
-
- <p><em>logback-*.jar</em> ファイルは logback の配布物に含まれていますが、 {0]slf4j-api-1.7.6.jar は別のプロジェクトである <a href="http://www.slf4j.org">SLF4J</a> の配布物です。
- </p>
-
- <p>さあ、logback を使ってみましょう。</p>
-
-<em>例1.1:ロギングの基本的なテンプレート( <a href="http://logback.qos.ch/xref/chapters/introduction/HelloWorld1.html">logback-examples/src/main/java/chapters/introduction/HelloWorld1.java</a> )</em>
-<pre class="prettyprint source">package chapters.introduction;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class HelloWorld1 {
-
- public static void main(String[] args) {
-
- Logger logger = LoggerFactory.getLogger("chapters.introduction.HelloWorld1");
- logger.debug("Hello world.");
-
- }
-}</pre>
-
- <p><code>HelloWorld1</code>クラスは <code>chapters.introduction</code> パッケージに定義されています。最初に SLF4J の API である <a href="http://slf4j.org/api/org/slf4j/Logger.html"><code>Logger</code></a> と <a href="http://slf4j.org/api/org/slf4j/LoggerFactory.html"><code>LoggerFactory</code></a> を <code>org.slf4j</code> パッケージからインポートしています。
- </p>
-
-
- <p>main()メソッドの最初の行では、<code>LoggerFactory</code>クラスの static メソッドである <code>getLogger</code> メソッドの返す<code>Logger</code> クラスのインスタンスを、<code>logger</code>変数に代入します。logger には "chapters.introduction.HelloWorld1" という名前が付けられています。次の処理では、引数として "Hello World" を渡して、logger の<code>debug</code>メソッドを呼び出しています。これを一言で表すと、main メソッドでは、"Hello World" というメッセージの DEBUG レベルのロギングがある、と言えます。
- </p>
-
- <p>上記の例では、logbackのクラスを一つも参照していないことに注意してください。ほとんどの場合、ロギングは本来の仕事ではないので、あなたのクラスでは SLF4J のクラスをインポートするだけでよいのです。このように、全てではないにしても、あなたのクラスの大半はSLF4J APIを使用するだけで、logbackの存在には気づかないでしょう。
- </p>
-
-
- <p>このサンプルアプリケーション(<em>chapters.introduction.HelloWorld1</em>)は次のコマンドで実行することができます。</p>
- <div class="source"><pre>java chapters.introduction.HelloWorld1</pre></div>
-
- <p><code>HelloWorld1</code>アプリケーションを実行すると、コンソールに何かが一行出力されます。logbackのデフォルトの設定ポリシーにより、デフォルトの設定ファイルが見つからない場合はルートロガーに<code>ConsoleAppender</code>を割り当てるようになっています。
- </p>
-
- <p class="source">20:49:07.962 [main] DEBUG chapters.introduction.HelloWorld1 - Hello world.</p>
-
- <p>logback は組み込みの状態管理システムによって、内部状態をレポートすることができます。<code>StatusManager</code>と呼ばれるコンポーネントを通じて、logback が有効になってから発生した重要なイベントの回数にアクセスすることができます。しばらくは、<code>StatusPrinter</code> クラスの<code>print()</code>メソッドによって logback の内部状態を出力することにします。
- </p>
-
-<em>例:ロガーの内部状態を出力する( <a href="http://logback.qos.ch/xref/chapters/introduction/HelloWorld2.html">logback-examples/src/main/java/chapters/introduction/HelloWorld2.java</a> )</em>
-<pre class="prettyprint source">package chapters.introduction;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-<b>import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.core.util.StatusPrinter;</b>
-
-public class HelloWorld2 {
-
- public static void main(String[] args) {
- Logger logger = LoggerFactory.getLogger("chapters.introduction.HelloWorld2");
- logger.debug("Hello world.");
-
- // print internal state
- <b>LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- StatusPrinter.print(lc);</b>
- }
-}</pre>
-
-
- <p><code>HelloWorld2</code>アプリケーションを実行すると次のように出力されます。</p>
-
-<div class="source longline"><pre>12:49:22.203 [main] DEBUG chapters.introduction.HelloWorld2 - Hello world.
-12:49:22,076 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
-12:49:22,078 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
-12:49:22,093 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.xml]
-12:49:22,093 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Setting up default configuration.
-</pre></div>
-
-
- <p>これは、logback が設定ファイルである <em>logback-test.xml</em> と <em>logback.xml</em> を見つけられなかったことを意味しています(詳しくは後述します)。そして、デフォルトポリシー(基本的な<code>ConsoleAppender</code>を使います)を使うように自分自身を設定しています。<code>Appender</code>とは、出力先として使用されるクラスのことです。既存のアペンダーには、コンソール、ファイル、Syslog、TCPソケット、JMSなどをいろいろな出力先のクラスが存在します。ユーザーは自分たちの状況に応じたアペンダーを簡単に作ることができます。
- </p>
-
- <p>異常が起きた場合、内部状態を自動的にコンソールに出力するようになっています。</p>
-
- <p>前の例はかなり単純なものでした。とはいえ、大きなアプリケーションで行われている実際のロギングもそんなに大きく変わるものではありません。一般的なロギング文の形式は変わらないでしょう。違うとしたら設定処理ですね。しかし、必要に応じたカスタマイズや設定をしたくなるでしょう。logbackを設定する方法については、以降の章で説明します。
- </p>
-
- <p>前述した例では、<code>StatusPrinter.print()</code>メソッドによって内部状態を出力するように命令していることに注意してください。logback の内部状態は、logback に起因する問題を調査するために非常に役立ちます。
- </p>
-
- <p>あなたのアプリケーションでロギングを有効にするための手順は次の三つです。
- </p>
-
- <ol>
- <li>logback の環境を準備します。やり方はさまざまです。詳細は後述します。</li>
-
- <li>ロギングをしたい全てのクラスで、<code>org.slf4j.LoggerFactory</code>の<code>getLogger()</code>メソッドによって<code>Logger</code>のインスタンスを取得しましょう。<code>getLogger()</code>メソッドにはクラス名やクラスオブジェクト自体を引数にしましょう。</li>
-
- <li>logger インスタンスのロギング用メソッドを呼び出しましょう。debug() info() warn() error() といったものがあります。そうすれば、アペンダーとして設定した出力先にログが出力されます。</li>
- </ol>
-
-
- <h2 class="doAnchor" name="building">logbackをビルドする</h2>
-
- <p>logback はビルドツールとして Maven を使用しています。<a href="http://maven.apache.org">Maven</a> はオープンソースのビルドツールで、広く利用されているものです。
- </p>
-
- <p>Maven をインストールしたら、logback の配布物を展開して、展開先のディレクトリに移動します。そして <code>mvn install</code> コマンドを実行すれば、全てのモジュールがビルドされます。Mavenは必要な外部ライブラリを自動的にダウンロードします。
- </p>
-
- <p>logback の配布物には完全なソースコードが含まれているので、編集して自分だけのバージョンのライブラリをビルドすることができます。あなたが修正したバージョンの logback は、LGPL ライセンス、もしくは、EPL ライセンスに従って再配布することもできます。
- </p>
-
- <p>IDE から logback をビルドする場合は<a href="http://logback.qos.ch/setup.html#ide">クラスパスの設定について説明したページ</a>を参照してください。</p>
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/jmxConfig.html b/logback-site/src/site/pages/manual/jmxConfig.html
index aeee141..86fee32 100644
--- a/logback-site/src/site/pages/manual/jmxConfig.html
+++ b/logback-site/src/site/pages/manual/jmxConfig.html
@@ -29,8 +29,6 @@
<div id="content">
<h1>Chapter 10: JMX Configurator</h1>
-
- <a href="jmxConfig_ja.html">和訳 (Japanese translation)</a>
<p>As its name indicates, <code>JMXConfigurator</code> allows
configuration of logback via JMX. In a nutshell, it lets you
diff --git a/logback-site/src/site/pages/manual/jmxConfig_ja.html b/logback-site/src/site/pages/manual/jmxConfig_ja.html
deleted file mode 100644
index 2b71a42..0000000
--- a/logback-site/src/site/pages/manual/jmxConfig_ja.html
+++ /dev/null
@@ -1,290 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第10章 JMXコンフィギュレーター</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第10章 JMXコンフィギュレーター</h1>
-
- <p>名前のとおり、<code>JMXConfigurator</code>を使うとJMX経由でlogbackを設定することができます。つまり、デフォルトの設定ファイルで設定されたlogbackを、指定したパスやURLに配置した設定ファイルの内容で再設定したり、ロガーの一覧を取得したり、ロガーのレベルを変更することができるのです。
- </p>
-
- <h3>JMXコンフィギュレーターを使用する</h3>
-
-
- <p>サーバーを実行しているJVMがJDK1.6以降なら、コマンドラインから<code>jconsole</code>コマンドを実行するだけで、実行中のサーバーのMBeanServerにアクセスすることができます。古いJVMで実行している場合は<a href="./10-jmxConfig.html#jmxEnablingServer">サーバーでJMXを有効化する</a>のセクションを読んでおいてください。
- </p>
-
- <p>次のように設定ファイルに1行追加するだけで<code>JMXConfigurator</code>が有効になります。</p>
-
- <pre class="prettyprint source"><configuration>
- <b><jmxConfigurator /></b>
-
- <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
- <layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>%date [%thread] %-5level %logger{25} - %msg%n</Pattern>
- </layout>
- </appender>
-
- <root level="debug">
- <appender-ref ref="console" />
- </root>
-</configuration></pre>
-
- <p><em>jconsole</em>でサーバーに接続すれば、MBeans タブに表示される "ch.qos.logback.classic.jmx.Configurator" フォルダの下にいろいろなコマンドがぶら下がっているのが確認できます。スクリーンショットを見てください。</p>
-
- <h3 class="doAnchor" name="jmxConfigurator"><code>jconsole</code>で<code>JMXConfigurator</code>を表示している様子</h3>
-
- <img src="images/chapters/jmxConfigurator/jmxConfigurator.gif" alt="jmxConfigurator">
-
- <p>次のような操作を実行することができます。</p>
-
- <ul>
- <li>デフォルトの設定ファイルを使用してlogbackを再設定します。</li>
-
- <li>URLに配置された設定ファイルを使用して再設定します。</li>
- <li>ファイルパスに配置された設定ファイルを使用して再設定します。</li>
-
- <li>指定したロガーのレベルを設定します。nullを設定するには文字列"null"を指定します。</li>
- <li>指定したロガーのレベルを取得します。nullになることがあります。</li>
- <li>指定したロガーの<a href="./01-architecture.html#effectiveLevel">有効レベル</a>を取得します。</li>
- </ul>
-
- <p><code>JMXConfigurator</code>はAttributesとして存在しているロガーの一覧と、ステータスの一覧を公開します。</p>
-
- <p>ステータスの一覧は、logbackの内部状態を診断するのに役立ちます。</p>
-
- <img src="images/chapters/jmxConfigurator/statusList.gif" alt="statusList.gif">
-
- <h3 class="doAnchor" name="leak">メモリリークを避ける</h3>
-
- <p>アプリケーションがWebサーバーやアプリケーションサーバにデプロイされているときは、<code>JMXConfigurator</code>のインスタンスをJVMのMBeanサーバーに登録すると、システムクラスローダーの参照をアプリケーションが持つようになってしまいます。これはアプリケーションが停止したり再デプロイされたときにJMXConfiguratorがガベージコレクションされてしまうのを防ぐためですが、そのせいで深刻なメモリリークが生じてしまいます。</p>
-
- <p>したがって、スタンドアローンなJavaアプリケーションではないときは、必ず<code>JMXConfigurator</code>のインスタンスの登録をJVMのMBeanサーバーから解除しなければなりません。適切な<code>LoggerContetext</code>の<code>reset()</code>メソッドを呼べば、すべてのJMXConfiguratorのインスタンスは自動的に解除されるはずです。ロガーコンテキストを初期化するなら、<code>javax.servlet.ServletContextListener</code>の<code>contextDestroyed()</code>メソッドがちょうど良い場所です。サンプルコードを見てみましょう。</p>
-
- <pre class="prettyprint source">import javax.servlet.ServletContextEvent;
-import javax.servlet.ServletContextListener;
-
-import org.slf4j.LoggerFactory;
-import ch.qos.logback.classic.LoggerContext;
-
-public class MyContextListener implements ServletContextListener {
-
- public void contextDestroyed(ServletContextEvent sce) {
- <b>LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();</b>
- <b>lc.stop();</b>
- }
-
- public void contextInitialized(ServletContextEvent sce) {
- }
-} </pre>
-
-
- <!-- ============ Multiple web-applications ================== -->
-
-
- <h2 class="doAnchor" name="multiple">複数のWebアプリケーションで<code>JMXConfigurator</code>を使用する</h2>
-
- <p>複数のアプリケーションを同じサーバーにデプロイしている、<a href="./09-loggingSeparation.html#contextSelectors">コンテキストセレクタ</a>を上書きせずデフォルトのまま使っている、それぞれのアプリケーションの<em>WEB-INF/lib</em>フォルダに<em>logback-*.jar</em>と<em>slf4j-api.jar</em>を置いている、これらが全て当てはまるなら、それぞれのアプリケーションの<code>JMXConfigurator</code>のインスタンスは同じ名前("ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator")で登録されてしまうでしょう。言い換えると、何もしなければそれぞれのアプリケーションのロガーコンテキストに関連付けられた<code>JMXConfigurator</code>のインスタンスは衝突してしまうのです。
- </p>
-
- <p>衝突を避けるには、単に<a href="./03-configuration.html#contextName">アプリケーションのロガーコンテキストに名前を付ける</a>だけでよいのです。そうすれば、<code>JMXConfigurator</code>には自動的にその名前が設定されます。
- </p>
-
- <p>たとえば、それぞれ"コアラ"と"コウモリ"という名前のアプリケーションをデプロイしているものとします。そして、コアラのlogback.xmlには次のような設定がされているとしましょう。</p>
-
- <pre class="prettyprint source"><configuration>
- <b><contextName>Koala</contextName></b>
- <jmxConfigurator/>
- ...
-<configuration></pre>
-
- <p>また、コウモリのlogback.xmlには次のように設定がされていることにします。</p>
-
- <pre class="prettyprint source"><configuration>
- <b><contextName>Wombat</contextName></b>x
- <jmxConfigurator/>
- ...
-<configuration></pre>
-
- <p>そうすると、jconsoleのMBeanタブには、次のように二つの独立した<code>JMXConfigurator</code>のインスタンスが表示されるはずです。</p>
-
- <img src="images/chapters/jmxConfigurator/multiple.gif" alt="multiple.gif">
-
- <p>MBeanサーバーに登録されるJMXConfiguratorの名前は、<code>jmxConfigurator要素</code>の"objectName"属性で指定することができます。</p>
-
- <!-- ============ JMX enabling your server ================== -->
-
- <h3 class="doAnchor" name="jmxEnablingServer">JMXを有効化する</h3>
-
- <p>JDK1.6以降のJVMでサーバーを実行している場合はデフォルトでJMXが有効になっています。</p>
-
- <p>JDK1.6以前の古いJVMを使っている場合は、サーバーのJMX関連のドキュメントを確認することをおすすめします。たとえば<a href="http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html">Tomcat</a>や<a href="http://docs.codehaus.org/display/JETTY/JMX">Jetty</a>にはドキュメントがあります。それはさておき、このドキュメントではTomcatとJettyの設定方法を簡単に説明していきます。
- </p>
-
- <!-- ================ Configuring Jetty ================== -->
-
- <h4>JettyでJMXを有効にする(JDK 1.5およびJDK 1.6で動作確認済み)</h4>
-
- <p>以降の設定はJDK1.5とJDK1.6で動作確認しています。JDK1.6以降のJVMでは、デフォルトでJMXが有効になっています。以降の設定をしてもよいですが、特に何も変わりません。JDK1.5のJVMで実行するJettyでJMXを有効にするには、設定ファイル<em>$JETTY_HOME/etc/jetty.xml</em>にいくつか設定を追加する必要があります。追加するのは次の設定です。</p>
-
- <pre class="prettyprint source"><Call id="MBeanServer" class="java.lang.management.ManagementFactory"
- name="getPlatformMBeanServer"/>
-
-<Get id="Container" name="container">
- <Call name="addEventListener">
- <Arg>
- <New class="org.mortbay.management.MBeanContainer">
- <Arg><Ref id="MBeanServer"/></Arg>
- <Call name="start" />
- </New>
- </Arg>
- </Call>
-</Get> </pre>
-
- <p>Jettyの公開するMBeanに<code>jconsole</code>でアクセスしたいときは、Jettyを実行するJVMにシステムプロパティ"com.sun.management.jmxremote"を指定しておかなければなりません。
- </p>
-
- <p>スタンドアローン版のJettyなら次のように実行します。</p>
-
-
- <p class="source">java <b>-Dcom.sun.management.jmxremote</b> -jar start.jar [config files]</p>
-
- <p>MavenのプラグインからJettyを実行する場合は、システムプロパティ"com.sun.management.jmxremote"をシェル変数<code>MAVEN_OPTS</code>で指定しなければなりません。</p>
-
- <p class="source"><b>MAVEN_OPTS="-Dcom.sun.management.jmxremote</b>" mvn jetty:run</p>
-
- <p>そうすれば、<code>jconsole</code>でJettyの公開するMBeanとして<code>JMXConfigurator</code>にアクセスすることができます。</p>
-
- <img src="images/chapters/jmxConfigurator/jconsole15_jetty.gif" alt="jconsole15_jetty.gif">
-
- <p>接続したら、<a href="./10-jmxConfig.html#jmxConfigurator">前のスクリーンショット</a>のように<code>JMXConfigurator</code>にアクセスできるはずです。</p>
-
- <h4>JettyにMX4Jを入れる(JDK 1.5およびJDK 1.6で動作確認済み)</h4>
-
- <p>MX4JのHTTPインターフェイスを経由して<code>JMXConfigurator</code>にアクセスしたいときは、前に説明した設定ファイルに管理ポート番号の設定を追加します。<a href="http://mx4j.sourceforge.net/">MX4J</a>はすでにダウンロード済みであることにします。
- </p>
-
- <pre class="prettyprint source"><Call id="MBeanServer"
- class="java.lang.management.ManagementFactory"
- name="getPlatformMBeanServer"/>
-
-<Get id="Container" name="container">
- <Call name="addEventListener">
- <Arg>
- <New class="org.mortbay.management.MBeanContainer">
- <Arg><Ref id="MBeanServer"/></Arg>
- <b><Set name="managementPort">8082</Set></b>
- <Call name="start" />
- </New>
- </Arg>
- </Call>
-</Get>
- </pre>
-
- <p>なお、<em>mx4j-tools.jar</em>はJettyのクラスパス上に配置しておいてください。
- </p>
-
- <p>MavenのプラグインからJettyを実行する場合は、依存関係に<em>mx4j-tools</em>を追加してください。</p>
-
- <pre class="prettyprint source"><plugin>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>maven-jetty-plugin</artifactId>
- <configuration>
- <jettyConfig>path/to/jetty.xml</jettyConfig>
- ...
- </configuration>
- <b><dependencies>
- <dependency>
- <groupId>mx4j</groupId>
- <artifactId>mx4j-tools</artifactId>
- <version>3.0.1</version>
- </dependency>
- </dependencies></b>
-</plugin></pre>
-
- <p>この設定でJettyを起動すると、ブラウザで次のURLから<code>JMXConfigurator</code>にアクセスできるようになります。アクセスした後は "ch.qos.logback.classic" を探してください。</p>
-
- <p class="source"><a href="http://localhost:8082/">http://localhost:8082/</a></p>
-
- <p>MX4Jにアクセスしているところのスクリーンショットです。</p>
-
- <img src="images/chapters/jmxConfigurator/mx4j_jetty.gif" alt="mx4j_jetty.gif">
-
-
- <!-- ================ Tomcat ================== -->
-
- <h4>Tomcat用のJMXの設定(JDK 1.5およびJDK 1.6で動作確認済み)</h4>
-
- <p>JDK1.6以降のJVMを使用しているならJMXはデフォルトで有効になっているので以降の設定をする必要はありません。JDK1.5の場合は<em>$TOMCAT_HOME/bin/catalina.sh(Windowsの場合はcatalina.bat)</em>の適切な場所に次の設定を追加する必要があります。</p>
-
- <p class="source">CATALINA_OPTS="-Dcom.sun.management.jmxremote"</p>
-
- <p>そうすれば、<code>jconsole</code>を使ってTomcatの公開するMBeanとして<code>JMXConfigurator</code>にアクセスできるようになります。</p>
-
- <p class="source"></p>
-
- <img src="images/chapters/jmxConfigurator/jconsole15_tomcat.gif" alt="jconsole15_tomcat.gif">
-
- <p>接続したら、<a href="./10-jmxConfig.html#jmxConfigurator">前のスクリーンショット</a>のように<code>JMXConfigurator</code>にアクセスできるはずです。
-</p>
-
-
- <h4>TomcatにMX4Jを入れる(JDK 1.5およびJDK 1.6で動作確認済み)</h4>
-
- <p>MX4JのWebインターフェイスを使ってJMXのコンポーネントにアクセスしたくなるかもしれません。そうするために必要な設定方法を説明します。</p>
-
- <p><a href="http://mx4j.sourceforge.net/">MX4J</a>はすでにダウンロードしてあることにしましょう。<em>mx4j-tools.jar</em>を<em>$TOMCAT_HOME/bin</em>フォルダーにおいてください。それから、<em>$TOMCAT_HOME/bin/catalina.sh(Windowsの場合はcatalina.bat)</em>の適切な場所に次の設定を追加します。</p>
-
- <p class="source"><!-- at the beginning of the file -->
-CATALINA_OPTS="-Dcom.sun.management.jmxremote"
-
-<!-- in the "Add on extra jar files to CLASSPATH" section -->
-CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/mx4j-tools.jar</p>
-
- <p>最後に、<em>$TOMCAT_HOME/conf/server.xmlで新しい<code>Connector要素</code>を宣言します。</em></p>
-
-
- <pre class="prettyprint source"><Connector port="0"
- handler.list="mx"
- mx.enabled="true"
- mx.httpHost="localhost"
- mx.httpPort="8082"
- protocol="AJP/1.3" /></pre>
-
- <p>Tomcatを起動したら、ブラウザで次のURLからJMXConfiguratorにアクセスできるようになります。アクセスした後は "ch.qos.logback.classic" を探してください。</p>
-
- <p class="source"><a href="http://localhost:8082">http://localhost:8082/</a></p>
-
- <p>MX4Jにアクセスしているところのスクリーンショットです。
-</p>
-
- <img src="images/chapters/jmxConfigurator/mx4j_tomcat.gif" alt="mx4j_tomcat.gif">
-
-
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-
- </div>
-</body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/layouts.html b/logback-site/src/site/pages/manual/layouts.html
index 32c44d8..7e78711 100644
--- a/logback-site/src/site/pages/manual/layouts.html
+++ b/logback-site/src/site/pages/manual/layouts.html
@@ -29,8 +29,6 @@
<div id="content">
<h1>Chapter 6: Layouts</h1>
-
- <a href="layouts_ja.html">和訳 (Japanese translation)</a>
<div class="quote">
<p>TCP implementations will follow a general principle of
@@ -162,7 +160,7 @@ public class MySampleLayout extends LayoutBase<ILoggingEvent> {
<code>MySampleLayout</code>. Here is the configuration file:</p>
<em>Example: Configuration of MySampleLayout
- (logback-examples/src/main/resources/chapters/layouts/sampleLayoutConfig.xml)</em>
+ (logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig.xml)</em>
<span class="asGroovy" onclick="return asGroovy('sampleLayoutConfig');">View as .groovy</span>
<pre id="sampleLayoutConfig" class="prettyprint source"><configuration>
@@ -543,7 +541,7 @@ WARN [main]: Message 2</p>
<p>Used to output the date of the logging event. The date
conversion word admits a pattern string as a parameter. The
pattern syntax is compatible with the format accepted by <a
- href="https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html"><code>java.text.SimpleDateFormat</code></a>.</p>
+ href="http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html"><code>java.text.SimpleDateFormat</code></a>.</p>
<p>You can specify the string <em>"ISO8601"</em> for the
ISO8601 date format. Note that the %date conversion word
@@ -626,9 +624,7 @@ WARN [main]: Message 2</p>
<tr >
<td class="word" name="caller">
<b>caller{depth}</b>
- <b>caller{depthStart..depthEnd}</b>
<b>caller{depth, evaluator-1, ... evaluator-n}</b>
- <b>caller{depthStart..depthEnd, evaluator-1, ... evaluator-n}</b>
</td>
<td>
@@ -660,16 +656,7 @@ Caller+1 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)</pre>
Caller+0 at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22)
Caller+1 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)
Caller+2 at mainPackage.ConfigTester.main(ConfigTester.java:38)</pre>
-
- <p>A range specifier can be added to the <em>caller</em> conversion specifier's
- options to configure the depth range of the information to be displayed.
- </p>
-
- <p>For example, <b>%caller{1..2}</b> would display the following excerpt:</p>
-
-<pre class="source white_bg">0 [main] DEBUG - logging statement
-Caller+0 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)</pre>
-
+
<p>This conversion word can also use evaluators to test
logging events against a given criterion before computing
caller data. For example, using <b>%caller{3,
@@ -1381,7 +1368,7 @@ Wrapped by: org.springframework.BeanCreationException: Error creating bean with
<em>
Example: Highlighting levels
- (logback-examples/src/main/resources/chapters/layouts/highlighted.xml)
+ (logback-examples/src/main/java/chapters/layouts/highlighted.xml)
</em>
<span class="asGroovy" onclick="return asGroovy('highlighted');">View as .groovy</span>
@@ -1458,7 +1445,7 @@ Wrapped by: org.springframework.BeanCreationException: Error creating bean with
<em>
Example: Sample usage of EventEvaluators
- (logback-examples/src/main/resources/chapters/layouts/callerEvaluatorConfig.xml)
+ (logback-examples/src/main/java/chapters/layouts/callerEvaluatorConfig.xml)
</em>
<span class="asGroovy" onclick="return asGroovy('callerEvaluatorConfig');">View as .groovy</span>
@@ -1636,7 +1623,7 @@ public class ExceptionEvaluatorExample {
<em>
Example: Sample usage of EventEvaluators
- (logback-examples/src/main/resources/chapters/layouts/exceptionEvaluatorConfig.xml)
+ (logback-examples/src/main/java/chapters/layouts/exceptionEvaluatorConfig.xml)
</em>
<pre class="prettyprint source"><configuration>
@@ -2083,14 +2070,6 @@ java.lang.Exception: display
</td>
</tr>
<tr>
- <td class="word" name="elapsedSeconds"><b>T / elapsedSeconds</b></td>
- <td>
- <p>
- The time taken to serve the request, in seconds.
- </p>
- </td>
- </tr>
- <tr>
<td class="word" name="dateAccess"><b>t / date</b></td>
<td>
<p>Outputs the date of the logging event. The date
@@ -2115,14 +2094,6 @@ java.lang.Exception: display
</td>
</tr>
<tr>
- <td class="word" name="queryString"><b>q / queryString</b></td>
- <td>
- <p>
- Request query string, prepended with a '?'.
- </p>
- </td>
- </tr>
- <tr>
<td class="word" name="requestURI"><b>U / requestURI</b></td>
<td>
<p>
@@ -2130,24 +2101,12 @@ java.lang.Exception: display
</p>
</td>
</tr>
- <tr>
- <td class="word" name="sessionID"><b>S / sessionID</b></td>
- <td>
- <p>Session ID.</p>
- </td>
- </tr>
<tr >
<td class="word" name="server"><b>v / server</b></td>
<td>
<p>Server name.</p>
</td>
</tr>
- <tr>
- <td class="word" name="threadName"><b>I / threadName</b></td>
- <td>
- <p>Name of the thread which processed the request.</p>
- </td>
- </tr>
<tr class="b">
<td class="word" name="localPort"><b>localPort</b></td>
<td>
diff --git a/logback-site/src/site/pages/manual/layouts_ja.html b/logback-site/src/site/pages/manual/layouts_ja.html
deleted file mode 100644
index eb26921..0000000
--- a/logback-site/src/site/pages/manual/layouts_ja.html
+++ /dev/null
@@ -1,1645 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"></meta>
- <title>第6章 レイアウト</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第6章 レイアウト</h1>
-
- <div class="quote">
- <p>TCPの実装は頑健性の一般原則に従う。つまり、自分自身の行動は保守的に、他者から行われる行動については寛容さを持って受け入れるということだ。
- </p>
- <p>-JON POSTEL、RFC 793</p>
- </div>
-
- <script src="../templates/creative.js" type="text/javascript"></script>
- <script src="../templates/setup.js" type="text/javascript"></script>
-
- <h2 class="doAnchor">レイアウトとは何か</h2>
-
- <p>レイアウトといってもフロリダ州の大規模集合住宅とは何の関係もありません。レイアウトはlogbackのコンポーネントであり、受け取ったロギングイベントを文字列に変換する役割を担っています。<a href="http://logback.qos.ch/xref/ch/qos/logback/core/Layout.html"><code>Layout</code></a>インターフェイスの<code>format()</code>メソッドは、引数としてロギングイベントとみなされる(任意の型の)オブジェクトを受け取り、文字列を返します。<code>Layout</code>インターフェイスの概要を次に示します。
- </p>
-
- <pre class="prettyprint source">public interface Layout<E> extends ContextAware, LifeCycle {
-
- String doLayout(E event);
- String getFileHeader();
- String getPresentationHeader();
- String getFileFooter();
- String getPresentationFooter();
- String getContentType();
-}</pre>
-
- <p>このインターフェイスは簡潔ですが、あらゆる書式化のニーズを十分に満たしています。<em>Catch-22</em>に登場するテキサス育ちの開拓者であるジョセフ・ヘラーならこう叫んでいるところです。「レイアウトを実装しようにもたったの5つしかメソッドがない!!?ナンデ?!」
- </p>
-
- <h2>Logback-classic モジュール</h2>
-
- <p>logback-classic モジュールは<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/spi/ILoggingEvent.html">ch.qos.logback.classic.spi.ILoggingEvent</a></code>だけを扱うようになっています。この節を読み進めていけば理由が明らかになります。</p>
-
- <h2 class="doAnchor" name="writingYourOwnLayout">レイアウトを自作する</h2>
-
- <p>logback-classic モジュールで使うために、簡潔で十分な機能性のあるレイアウトを自作してみましょう。出力したいのは次のようなものです。アプリケーションが起動してから経過した時間、ロギングイベントのログレベル、ブラケットで囲んだ呼び出しスレッド名、ロガー名、ダッシュ(-のこと)とそれに続くロギングイベントのメッセージ、最後に改行文字も加えておきましょう。
- </p>
-
- <p>出力例は次のようになります。</p>
-
- <div class="source">10489 DEBUG [main] com.marsupial.Pouch - Hello world.</div>
-
- <p>テキサスの開拓者が実装したレイアウトのコードを見てましょう。</p>
- <p class="example">例:自作レイアウトのサンプル実装(<a href="http://logback.qos.ch/xref/chapters/layouts/MySampleLayout.html">logback-examples/src/main/java/chapters/layouts/MySampleLayout.java</a>)</p>
-
- <pre class="prettyprint source">package chapters.layouts;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.LayoutBase;
-
-public class MySampleLayout extends LayoutBase<ILoggingEvent> {
-
- public String doLayout(ILoggingEvent event) {
- StringBuffer sbuf = new StringBuffer(128);
- sbuf.append(event.getTimeStamp() - event.getLoggingContextVO.getBirthTime());
- sbuf.append(" ");
- sbuf.append(event.getLevel());
- sbuf.append(" [");
- sbuf.append(event.getThreadName());
- sbuf.append("] ");
- sbuf.append(event.getLoggerName();
- sbuf.append(" - ");
- sbuf.append(event.getFormattedMessage());
- sbuf.append(CoreConstants.LINE_SEP);
- return sbuf.toString();
- }
-}</pre>
-
- <p><code>MySampleLayout</code>は<a href="http://logback.qos.ch/xref/ch/qos/logback/core/LayoutBase.html"><code>LayoutBase</code></a>を継承しているのに気付きましたか。このクラスは全てのレイアウトのインスタンスに共通する内部状態を管理するものです。例えば、レイアウトが開始しているか、停止しているか、ヘッダーはあるか、フッターはあるか、コンテンツタイプはあるか、といったものです。おかげで、開発者は書式化の方法にだけ集中することができるのです。<code>LayoutBase</code>はジェネリッククラスです。上記のコードでは、<code>MySampleLayout</code>は<code>LayoutBase<ILoggingEvent></code>を継承しています。
- </p>
-
- <p><code>doLayout(ILoggingEvent event)</code>メソッド(<code>MySampleLayout</code>の実装する唯一のメソッドです)では、最初に空の<code>StringBuffer</code>を生成して、ロギングイベントのパラメータを付け足していきます。開拓者らしく、慎重に書式化したようです。ロギング要求で1つ以上のパラメータが渡されることを考えればこれは大事なことです。</p>
-
- <p><code>doLayout()</code>メソッドでは、StringBufferにいろいろな文字列を追加したあとで1つの文字列に変換して、その文字列を呼び出し元に返します。
- </p>
-
- <p>上記の<code>doLayout</code>メソッドでは、ロギングイベントに含まれる可能性のあるあらゆる例外を無視します。実際のレイアウトの実装では、ほぼ確実に例外の内容を出力したいはずです。
- </p>
-
- <h3 class="doAnchor" name="configuringYourOwnLayout">自作レイアウトの設定</h3>
-
- <p>自作レイアウトは、他のコンポーネントと同じように設定されます。前述したように<code>FileAppender</code>とその派生クラスにはエンコーダーが必要です。<code>FileAppender</code>のニーズを満たすため、<code>LayoutWrappingEncoder</code>に自作した<code>MySampleLayout</code>をラップしてみましょう。次のような設定になります。</p>
-
- <p class="example">例:MySampleLayoutの設定(<a href="http://logback.qos.ch/xref/chapters/layouts/sampleLayoutConfig.xml">logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('logback_Console');">Groovyで表示</span>
-<pre id="sampleLayoutConfig" class="prettyprint source"><configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <b><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"></b>
- <b><layout class="chapters.layouts.MySampleLayout" /></b>
- <b></encoder></b>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>サンプルアプリケーションの<code><a href="http://logback.qos.ch/xref/chapters/layouts/SampleLogging.html">chapters.layouts.SampleLogging</a></code>は、一つ目の引数で指定された設定ファイルを使ってlogbackを設定します。そして、デバッグメッセージとエラーメッセージを1つづつロギングします。</p>
-
- <p><em>logback-examples</em>ディレクトリに移動して、次のコマンドを実行してみましょう。
- </p>
-
- <p class="command">java chapters.layouts.SampleLogging src/main/java/chapters/layouts/sampleLayoutConfig.xml</p>
-
- <p>コンソールには次のように出力されます。</p>
-
-<div class="source"><pre>0 DEBUG [main] chapters.layouts.SampleLogging - Everything's going well
-0 ERROR [main] chapters.layouts.SampleLogging - maybe not quite...</pre></div>
-
- <p>簡単でしょう?エレア派の懐疑論者ピュロンは、それ自体が不確実であるということ以外に確実なことは無い、と主張しました。つまり、確かなことなど何もないというのです。彼はきっとこう質問するでしょう。「それでレイアウトのオプションについてはどうなっているの?」上記の自作レイアウトを少し変更したバージョンが<a href="http://logback.qos.ch/xref/chapters/layouts/MySampleLayout2.html"><code>MySampleLayout2.java</code></a>です。このマニュアル全体を通じて言えることですが、レイアウトでもlogbackの他のコンポーネントでも、単にセッターメソッドを設定するだけでプロパティを指定できるようになります。
- </p>
-
- <p><a href="http://logback.qos.ch/xref/chapters/layouts/MySampleLayout2.html"><code>MySampleLayout2</code></a>クラスには、2つのプロパティがあります。一つ目は、出力されるメッセージの先頭に追加する接頭辞です。二つ目は、ロギング要求を送信したスレッドの名前を表示するかどうかを選択する真偽値です。
- </p>
-
- <p><a href="http://logback.qos.ch/xref/chapters/layouts/MySampleLayout2.html"><code>MySampleLayout2</code></a>のコードを見てみましょう。</p>
-
- <pre class="prettyprint source">package chapters.layouts;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.LayoutBase;
-
-public class MySampleLayout2 extends LayoutBase<ILoggingEvent> {
-
- String prefix = null;
- boolean printThreadName = true;
-
- <b>public void setPrefix(String prefix) {
- this.prefix = prefix;
- }
-
- public void setPrintThreadName(boolean printThreadName) {
- this.printThreadName = printThreadName;
- }</b>
-
- public String doLayout(ILoggingEvent event) {
- StringBuffer sbuf = new StringBuffer(128);
- <b>if (prefix != null) {
- sbuf.append(prefix + ": ");
- }</b>
- sbuf.append(event.getTimeStamp() - event.getLoggerContextVO().getBirthTime());
- sbuf.append(" ");
- sbuf.append(event.getLevel());
- <b>if (printThreadName) {
- sbuf.append(" [");
- sbuf.append(event.getThreadName());
- sbuf.append("] ");
- } else {
- sbuf.append(" ");
- }</b>
- sbuf.append(event.getLoggerName());
- sbuf.append(" - ");
- sbuf.append(event.getFormattedMessage());
- sbuf.append(LINE_SEP);
- return sbuf.toString();
- }
-}</pre>
-
-
- <p>プロパティのセッターメソッドを追加すれば設定ファイルから指定できるようになります。<code>printThreadName</code>プロパティの型は真偽値(boolean)であって文字列(<code>String</code>)ではないので注意してください。logbackのコンポーネントの設定については、<a href="http://logback.qos.ch/manual/configuration.html">設定に関する章</a>で詳しく説明しています。<a href="http://logback.qos.ch/manual/onJoran.html">Joranの章</a>にはより詳細な説明があります。<code>MySampleLayout2</code>のために特別に誂えた設定ファイルは次のとおりです。
- </p>
-
-
- <span class="asGroovy" onclick="return asGroovy('MySampleLayout2');">Groovyとして表示</span>
- <pre id="MySampleLayout2" class="prettyprint source"><configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
- <layout class="chapters.layouts.MySampleLayout2">
- <b><prefix>MyPrefix</prefix></b>
- <b><printThreadName>false</printThreadName></b>
- </layout>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p></p>
-
-
- <h2 class="doAnchor" name="ClassicPatternLayout">PatternLayout</h2>
-
- <p>logback-classic の配布物には、<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/PatternLayout.html">PatternLayout</a></code>と呼ばれる柔軟性のあるレイアウトが含まれています。他のレイアウトと同じく、<code>PatternLayout</code>はロギングイベントを受け取って<code>文字列</code>を返します。<code>文字列</code>は、変換パターン文字列を調整してカスタマイズすることができます。
- </p>
-
- <p><code>PatternLayout</code>の変換パターン文字列はC言語の<code>printf()</code>関数と非常によく似たもので、文字列リテラルと<em>変換指定</em>と呼ばれる書式制御式で構成されています。変換パターン文字列には、どんな文字列リテラルでも入れることができます。変換指定はパーセント記号"%"で始まり、オプションの<em>書式修飾子</em>、<em>変換指定子</em>、括弧で囲まれたパラメータが続いたものです。変換指定子には変換したいデータフィールドを指定します。例えばロガー名、レベル、日付、スレッド名などです。書式修飾子には、フィールド幅、パディング、左揃えや右揃えを指定します。
- </p>
-
- <p>既に何度か述べたとおり、<code>FileAppender</code>とその派生クラスにはエンコーダーが必要です。結局、<code>FileAppender</code>やその派生クラスと<code>PatternLayout</code>を一緒に使うには、エンコーダーでラップしなければなりません。<code>FileAppender</code>と<code>PatternLayout</code>を組み合わせることがあまりにも一般的になってしまったことを考慮して、logback の配布物には<code>PatternLayoutEncoder</code>を含めるようになりました。これは単に<code>PatternLayout</code>をラップするだけのエンコーダーなので、エンコーダーであるにも関わらずPatternLayoutのように扱えるようになっています。プログラム的に<code>ConsoleAppender</code>と<code>PatternLayoutEncoder</code>を設定する例を示します。</p>
-
-
- <p class="example">例:PatternLayoutの使用例(<a href="http://logback.qos.ch/xref/chapters/layouts/PatternSample.html">logback-examples/src/main/java/chapters/layouts/PatternSample.java</a>)</p>
-
- <pre class="prettyprint source">package chapters.layouts;
-
-import org.slf4j.LoggerFactory;
-
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.ConsoleAppender;
-
-public class PatternSample {
-
- static public void main(String[] args) throws Exception {
- Logger rootLogger = (Logger)LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
- LoggerContext loggerContext = rootLogger.getLoggerContext();
- // we are not interested in auto-configuration
- loggerContext.reset();
-
- <b>PatternLayoutEncoder encoder = new PatternLayoutEncoder();</b>
- <b>encoder.setContext(loggerContext);</b>
- <b>encoder.setPattern("%-5level [%thread]: %message%n");</b>
- <b>encoder.start();</b>
-
- ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<ILoggingEvent>();
- appender.setContext(loggerContext);
- appender.setEncoder(encoder);
- appender.start();
-
- rootLogger.addAppender(appender);
-
- rootLogger.debug("Message 1");
- rootLogger.warn("Message 2");
- }
-}</pre>
-
- <p>この例では、変換パターン文字列として<b>"%-5level [%thread] %msg%n"</b>が設定されています。logbackに組み込みの変換指定子については後で簡単に説明します。<code>PatternSample</code>アプリケーションを実行してみましょう。</p>
-
- <p class="source">java java chapters.layouts.PatternSample</p>
-
- <p>コンソールにに次のように出力されます。</p>
-
- <p class="source">DEBUG [main]: Message 1
-WARN [main]: Message 2</p>
-
- <p>変換パターン文字列の<b>"%-5level [%thread] %msg%n"</b>には、文字列リテラルと変換指定子を明示的に区切る文字が無いことに気付きましたか。変換パターン文字列を解析する際、<code>PatternLayout</code>は文字列リテラル(空白文字、括弧、コロンなど)と変換指定を分離することができます。上記の例では、変換指定"%-5level"は、ロギングイベントのレベルを5文字の幅に左揃えすることを意味します。書式指定子については後で説明します。
- </p>
-
- <p><code>PatternLayout</code>は変換パターン文字列をグループ化するために括弧を使います。<b>つまり '('と ')'には特別な意味があるので、リテラル文字列として使うときはエスケープしなければならないということです。</b> 括弧の特殊な性質について詳しくは<a href="http://logback.qos.ch/manual/layouts.html#Parentheses">後で説明</a>します。
- </p>
-
- <p>前述のとおり、変換指定によっては括弧で囲んでオプションの引数を指定することができます。例えばこういう書き方です。<code>%logger{10}</code>"logger" が変換指定子で、10が引数です。オプションの指定の仕方について詳しくは<a href="http://logback.qos.ch/manual/layouts.html#cwOptions">後で説明</a>します。
- </p>
-
- <p>利用できる変換指定とオプションを表にまとめました。1つのセルに複数の変換指定子が登場する場合、それらは別名という意味です。
- </p>
-
- <table class="bodyTable properties striped" border="0">
- <tr>
- <th><a name="conversionWord" href="http://logback.qos.ch/manual/layouts.html#conversionWord">変換指定子</a></th>
- <th>効果</th>
- </tr>
-
- <tr>
- <td class="word" name="logger">
- <a name="logger" href="http://logback.qos.ch/manual/layouts.html#logger"><span class="anchor"></span></a>
- <b>c</b>{<em>length</em>} <br>
- <b>lo</b>{<em>length</em>} <br>
- <b>logger</b>{<em>length</em>} <br>
- </td>
-
- <td>ロギングイベントを生成する一番元になったロガーの名前を出力します。
-
- <p>この変換指定子に指定できるオプションは整数値だけです。ロガー名は省略アルゴリズムに従って、意味が通る程度に短縮されます。0を指定すると特別な振る舞いをします。ロガー名文字列の中で一番右端のドット(.)から右側だけを残すようになります。省略アルゴリズムの例を表にまとめました。
- </p>
-
- <table class="bodyTable dark" border="0" cellpadding="8">
- <tr>
- <th>変換指定</th>
- <th>ロガー名</th>
- <th>結果</th>
- </tr>
- <tr>
- <td>%logger</td>
- <td>mainPackage.sub.sample.Bar</td>
- <td>mainPackage.sub.sample.Bar</td>
- </tr>
-
- <tr>
- <td>%logger{0}</td>
- <td>mainPackage.sub.sample.Bar</td>
- <td>Bar</td>
- </tr>
-
- <tr>
- <td>%logger{5}</td>
- <td>mainPackage.sub.sample.Bar</td>
- <td>m.s.s.Bar</td>
- </tr>
-
- <tr>
- <td>%logger{10}</td>
- <td>mainPackage.sub.sample.Bar</td>
- <td>m.s.s.Bar</td>
- </tr>
-
- <tr>
- <td>%logger{15}</td>
- <td>mainPackage.sub.sample.Bar</td>
- <td>m.s.sample.Bar</td>
- </tr>
-
- <tr>
- <td>%logger{16}</td>
- <td>mainPackage.sub.sample.Bar</td>
- <td>m.sub.sample.Bar</td>
- </tr>
-
- <tr>
- <td>%logger{26}</td>
- <td>mainPackage.sub.sample.Bar</td>
- <td>mainPackage.sub.sample.Bar</td>
- </tr>
- </table>
-
- <p>オプションで指定した長さを越えるとしても、一番右側のドット(.)から後ろは省略されないので気をつけてください。それ以外の部分は最短で1文字になりますが、削除することはありません。</p>
-
- </td>
- </tr>
-
- <tr>
- <td class="word" name="class">
- <b>C</b>{<em>length</em>} <br>
- <b>class</b>{<em>length</em>} <br>
- </td>
-
- <td>
- <p>ロギング要求を生成した呼び出し元のクラスの完全名を出力します。</p>
-
- <p><em>%logger</em>と同じように、引数の整数値に合わせて名前を短縮します。0には特別な意味があり、パッケージ名を除いた単純クラス名を出力するようになります。デフォルトでは、完全クラス名が出力されます。
- </p>
-
- <p>送信側のクラス情報を生成するのはとても高速とは言えません。実行速度が問題にならない場合にだけ使うほうが良いでしょう。
- </p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="contextName">
- <b>contextName</b><br>
- <b>cn</b><br></td>
- <td>ロギングイベントを生成したロガーの割り当てられたロギングコンテキストの名前。</td>
- </tr>
- <tr>
- <td class="word" name="date">
- <b>d</b>{<em>pattern</em>} <br>
- <b>date</b>{<em>pattern</em>} <br>
- <b>d</b>{<em>pattern</em>, <em>timezone</em>} <br>
- <b>date</b>{<em>pattern</em>, <em>timezone</em>} <br>
- </td>
- <td>
- <p>ロギングイベントの日時を出力するために使います。引数として日時パターン文字列を指定することができます。日時パターン文字列は<a href="https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html"><code>java.text.SimpleDateFormat</code></a>と互換性があります。</p>
-
- <p>引数に<em>"ISO8601"</em>と指定すると ISO8601 の書式になります。日時パターン文字列が指定されなかった場合、デフォルトは<a href="http://en.wikipedia.org/wiki/ISO_8601">ISO8601書式</a>になるので注意してください。</p>
-
- <p>いくつかサンプルを見てください。ここでは日時が2006年10月20日(金曜日)であることを想定しています。これはこのマニュアルを書いた人が昼食から戻ってきた日時です。</p>
-
- <table class="bodyTable dark" cellpadding="8">
- <tr>
- <th>変換パターン</th>
- <th>結果</th>
- </tr>
- <tr>
- <td>%d</td>
- <td>2006-10-20 14:06:49,812</td>
- </tr>
- <tr>
- <td>%date</td>
- <td>2006-10-20 14:06:49,812</td>
- </tr>
- <tr>
- <td>%date{ISO8601}</td>
- <td>2006-10-20 14:06:49,812</td>
- </tr>
- <tr>
- <td>%date{HH:mm:ss.SSS}</td>
- <td>14:06:49.812</td>
- </tr>
- <tr>
- <td>%date{dd MMM yyyy;HH:mm:ss.SSS}</td>
- <td>20 oct. 2006;14:06:49.812 </td>
- </tr>
- </table>
-
- <p>二番目の引数にはタイムゾーンを指定します。たとえば、'%date{HH:mm:ss.SSS, Australia/Perth}' と指定すると、世界中で一番孤立しているオーストラリアのパースの時刻を出力するようになります。タイムゾーンが指定されなかった場合、JVMのタイムゾーンが使用されます。指定したタイムゾーンが未知のものであったりタイプミスだった場合、<a href="http://docs.oracle.com/javase/6/docs/api/java/util/TimeZone.html#getTimeZone(java.lang.String)">TimeZone.getTimeZone(String)</a>メソッドの仕様に基づいてGMTが指定されたものとして解釈します。
- </p>
-
- <p><span class="label">よくある間違い</span>は、カンマ(,)が引数の区切り文字として解釈されてしまうことです。<code>HH:mm:ss,SSS</code>というパターン文字列は<code>HM:mm:ss</code>というパターン文字列<code>SSS</code>というタイムゾーンが指定されたものとして解釈されてしまいます。日時パターン文字列にカンマ(,)を入れたければ、パターン文字列をクォートで囲んでください。たとえば次のようにします。%date{<b>"</b>HH:mm:ss,SSS<b>"</b>}.
- </p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="file">
- <b>F</b><br /><b>
-file</b>
- </td>
-
- <td>
- <p>ロギング要求を発行したクラスのソースコードファイル名を出力します。
- </p>
-
- <p>ファイル情報を生成するのはとても高速であるとは言えません。実行速度が問題にならない場合にだけ使うほうが良いでしょう。
- </p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="caller">
- <b>caller{depth}</b><br />
-<b>caller{depth, evaluator-1, ... evaluator-n}</b>
- </td>
-
- <td>
- <p>ロギングイベントを生成した呼び出し元の位置情報(スタックの深さ、ソースコードファイルの行番号)。
- </p>
-
- <p>位置情報の中身はJVM実装によって変わりますが、普通ならロギングイベントを生成したメソッドの定義されたクラスの完全名、ソースコードファイル名、行番号が含まれます。
- </p>
-
- <p>表示されるメソッド呼び出しの深さを指定するため、オプションとして整数値を指定できます。
- </p>
-
- <p>例えば、<b>%caller{2}</b>と書いたら次のように出力されます。</p>
-
-<pre class="source white_bg">0 [main] DEBUG - logging statement
-Caller+0 at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22)
-Caller+1 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)</pre>
-
- <p>そして<b>%caller{3}</b>と書いたら次のように出力されます。</p>
-
-<pre class="source white_bg">16 [main] DEBUG - logging statement
-Caller+0 at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22)
-Caller+1 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)
-Caller+2 at mainPackage.ConfigTester.main(ConfigTester.java:38)</pre>
-
- <p>ロギングイベントの送信元情報を計算するかどうかを判定するため、オプションとして評価器を指定できるようになっています。たとえば、<b>%caller{3,CALLER_DISPLAY_EVAL}</b>と指定すると評価器の<em>CALLER_DISPLAY_EVAL</em>が<b>真</b>を返す場合にだけ、3行分のスタックトレースを出力することになります。
- </p>
-
- <p>評価器の種類は後で紹介します。</p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="line">
- <b>L</b><br /><b>
-line</b>
- </td>
-
- <td><p>ロギング要求が生成されたソースコードファイル中の行番号を出力します。</p>
-
- <p>行番号を算出するのは決して高速とは言えません。実行速度が問題にならない場合にだけ使うほうが良いでしょう。
-
- </p>
- </td>
- </tr>
-
-
- <tr>
- <td class="word" name="message">
- <b>m</b><br /><b>
-msg</b><br /><b>
-message</b>
- </td>
- <td>
- <p>アプリケーションがロギングイベントに関連付けたメッセージを出力します。
- </p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="method">
- <b>M</b><br /><b>
-method</b>
- </td>
-
- <td>
- <p>ロギング要求が生成されたメソッド名を出力します。</p>
- <p>メソッド名を生成するのは決して高速とは言えません。実行速度が問題にならない場合にだけ使うほうが良いでしょう。
-</p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="newline">
- <b>n</b>
- </td>
-
- <td>
- <p>プラットフォーム依存の行区切り文字を出力します。</p>
- <p>この変換指定子を使っても、行区切り文字として可搬性の無い"\n" や"\r\n" を指定した場合と性能は変わりません。したがって、どんなときでも行区切り文字そのものではなく、この変換指定子を使うべきです。
- </p>
- </td>
-
- </tr>
-
- <tr>
- <td class="word" name="level">
- <b>p</b><br /><b>
-le</b><br /><b>
-level</b>
- </td>
- <td>ロギングイベントのレベルを出力します。</td>
- </tr>
-
- <tr>
-
- <td class="word" name="relative">
- <b>r</b><br /><b>
-relative</b>
- </td>
-
- <td>アプリケーションが開始してから、ロギングイベントを生成するまでの経過時間をミリ秒単位で出力します。
- </td>
- </tr>
-
-
- <tr>
- <td class="word" name="relative">
- <b>t</b><br /><b>
-thread</b>
- </td>
-
- <td>ロギングイベントを生成したスレッドの名前を出力します。
- </td>
-
- </tr>
-
- <tr>
- <td class="word" name="mdc">
- <b>X</b>{<em>key:-defaultVal</em>} <br>
- <b>mdc</b>{<em>key:-defaultVal</em>} <br>
- </td>
-
- <td>
-
- <p>ロギングイベントを生成したスレッドに関連付けられていたMDC(診断コンテキスト)の値を出力します。
- </p>
-
- <p><b>%mdc{uesrid}</b>のように<b>mdc</b>オプションにキーが指定されている場合、対応するMDCの値が出力されます。MDCの値がnullの場合、 <b>:-</b>演算子で指定したデフォルト値が出力されます。デフォルト値が無かったら空文字列が出力されます。
- </p>
-
- <p>キーが未指定のときは、MDCの内容がすべて出力されます。そのときの書式は"key1=val1,key2=val2"のようになります。
- </p>
-
- <p>詳しくは<a href="http://logback.qos.ch/manual/mdc.html">MDCの章</a>を参照してください。</p>
-
- </td>
- </tr>
- <tr>
- <td class="word" name="ex">
- <b>ex</b>{<em>depth</em>} <br>
- <b>exception</b>{<em>depth</em>} <br>
- <b>throwable</b>{<em>depth</em>} <br>
- <br>
- <b>ex</b>{depth, evaluator-1, ..., evaluator-n} <br>
- <b>exception</b>{depth, evaluator-1, ..., evaluator-n} <br>
- <b>throwable</b>{depth, evaluator-1, ..., evaluator-n}
- </td>
-
- <td>
- <p>ロギングイベントに例外オブジェクトが関連付けられていたら、その例外オブジェクトのスタックトレースを出力します。デフォルトでは完全なスタックトレースを出力します。
- </p>
-
- <p><em></em>throwable変換指定子に指定できるオプションは次のとおりです。</p>
- <ul>
- <li><em>short</em> :スタックトレースの一行目だけを出力します</li>
- <li><em>full</em> :完全なスタックトレースを出力します</li>
- <li>任意の整数:スタックトレースの先頭から数えて指定した行数を出力します</li>
- </ul>
-
- <p>いくつか例を見てみましょう。</p>
-
- <table class="bodyTable">
- <tr class="a">
- <th>変換指定</th>
- <th>結果</th>
- </tr>
- <tr class="b">
- <td>%ex</td>
- <td><pre>mainPackage.foo.bar.TestException: Houston we have a problem
- at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)
- at mainPackage.foo.bar.TestThrower.readyToLaunch(TestThrower.java:17)
- at mainPackage.ExceptionLauncher.main(ExceptionLauncher.java:38)</pre></td>
- </tr>
- <tr class="a">
- <td>%ex{short}</td>
- <td><pre>mainPackage.foo.bar.TestException: Houston we have a problem
- at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)</pre></td>
- </tr>
- <tr class="b">
- <td>%ex{full}</td>
- <td><pre>mainPackage.foo.bar.TestException: Houston we have a problem
- at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)
- at mainPackage.foo.bar.TestThrower.readyToLaunch(TestThrower.java:17)
- at mainPackage.ExceptionLauncher.main(ExceptionLauncher.java:38)</pre></td>
- </tr>
- <tr class="a">
- <td>%ex{2}</td>
- <td><pre>mainPackage.foo.bar.TestException: Houston we have a problem
- at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)
- at mainPackage.foo.bar.TestThrower.readyToLaunch(TestThrower.java:17)</pre></td>
- </tr>
- </table>
-
- <p>スタックトレースを出力するかどうかを判定するため、オプションとして評価器を指定できるようになっています。例えば、<b>%ex{full,EX_DISPLAY_EVAL}</b>と指定した場合、評価器<em>EX_DISPLAY_EVAL</em>が<b>偽</b>を返すときだけ例外オブジェクトの完全なスタックトレースが出力されます。評価器についてはこのドキュメントの後のほうで説明しています。
- </p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="xThrowable">
- <b>xEx</b>{<em>depth</em>} <br>
- <b>xException</b>{<em>depth</em>} <br>
- <b>xThrowable</b>{<em>depth</em>} <br>
- <br>
- <b>xEx</b>{depth, evaluator-1, ..., evaluator-n} <br>
- <b>xException</b>{depth, evaluator-1, ..., evaluator-n} <br>
- <b>xThrowable</b>{depth, evaluator-1, ..., evaluator-n}
- </td>
-
- <td>
- <p>クラスのパッケージングに関する情報が追加されていること以外は%throwableと同様です。</p>
-
- <p>変換パターン文字列に%xThrowableや他のthrowable関連の変換指定子を指定しなかった場合、<code>PatternLayout</code>は末尾に%xThrowableを自動的に追加します。スタックトレースの情報は非常に重要だからです。スタックトレースを出力したくなければ、%xThrowableの代わりに%nopexを指定すればよいです。%nopexの説明も参照してください。
- </p>
-
- <p>例外のスタックトレースの各行の終わりに、そのクラスが含まれるjarファイル名とMANIFEST.MFに書かれた"Implementation-Version"が追加されます。この画期的なテクニックを考案したのは<a href="http://macstrac.blogspot.com/2008/09/better-stack-traces-in-java-with-log4j.html">James Strachan</a>です。パッケージングの情報が不確かな場合、先頭にチルダ(~)が付きます。
- </p>
-
- <p>例を見てみましょう。</p>
-
- <p class="source small">java.lang.NullPointerException
- at com.xyz.Wombat(Wombat.java:57) <b><span class="red">~</span>[wombat-1.3.jar:1.3]</b>
- at com.xyz.Wombat(Wombat.java:76) ~[wombat-1.3.jar:1.3]
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.5.0_06]
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.5.0_06]
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.5.0_06]
- at java.lang.reflect.Method.invoke(Method.java:585) ~[na:1.5.0_06]
- at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59) [junit-4.4.jar:na]
- at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98) [junit-4.4.jar:na]
- ...etc </p>
-
- <p>logbackはパッケージング情報が正しく出力されるよう、適切な幅を確保します。どれだけクラスローダーの階層が複雑になっていても頑張ります。残念ながら正確性が担保できないときは先頭にチルダ(~)を付けます。従って、理屈の上では実際のパッケージング情報とは異なる内容を出力させることも可能です。ですから、前の例で Wombat クラスのパッケージング情報の先頭にはチルダ(~)があるので、本当は [wombat.jar:1.7] となるはずだったかもしれないのです。
- </p>
-
- <p><a href="http://jira.qos.ch/browse/LBCLASSIC-212">利用者からのフィードバックによると</a>、NetBeansはパッケージング情報を縮めてしまうそうです。Netbeansのユーザーは、変換パターン文字列の最後に"%ex"を追加して、スタックトレースにパッケージング情報が出てこないようにしたほうが良いでしょう。たとえば、"%d %logger - %m%n" という変換パターン文字列を使っているなら、"%d %logger - %m%n<b>%ex</b>" と書き換えればよいのです。</p>
- </td>
-
- </tr>
-
- <tr>
- <td class="word" name="nopex">
- <b>nopex</b> <br>
- <b>nopexception</b>
- </td>
-
- <td>
- <p>スタックトレースの情報を<em>扱うように見えます</em>が、実際は何も出力しません。つまり、うまく例外を無視できるのです。
- </p>
-
- <p>%nopex変換指定子を使うと、<code>PatternLayout</code>が内部的に実装している安全弁を無かったことにします。安全弁とは、変換パターン文字列に例外を扱う変換指定子が含まれていなかったらこっそり最後に%xThrowableを追加することです。
- </p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="marker">
- <b>marker</b>
- </td>
-
- <td>
- <p>ロギング要求に関連付けられたマーカーを出力します。</p>
-
- <p>マーカーに子マーカーがある場合、次のような書式で両方のマーカーを出力します。
- </p>
- <p>
- <em>parentName [ child1, child2 ]</em>
- </p>
- </td>
- </tr>
-
-
- <tr>
- <td class="word" name="property">
- <b>property{key}</b>
- </td>
-
- <td><p><em>キー</em>という名前のプロパティに設定された値を出力します。関連するドキュメントは<a href="http://logback.qos.ch/manual/configuration.html#variableSubstitution">変数の定義</a>と<a href="http://logback.qos.ch/manual/configuration.html#scopes">変数のスコープ</a>です。
-
- <em>キー</em>がロガーコンテキストのプロパティではなかったら、システムプロパティを探します。</p>
-
-
- <p><em>キー</em>に対するデフォルト値はありません。プロパティが見つからなかったら、"Property_HAS_NO_KEY"という文字列が値になります。エラーであることがすぐにわかりますね。</p>
-
- </td>
- </tr>
-
- <tr>
- <td class="word" name="replace">
- <b>replace(<em>p</em>){r, t}</b>
- </td>
-
- <td>
- <p>変換パターン文字列"p"について、正規表現'r'にマッチした部分を文字列't'で置き換えます。たとえば、"%replace(%msg){'\s',''}" とすると、ロギングイベントに設定されたメッセージに含まれるすべての空白文字を削除します。
- </p>
-
- <p>変換パターン文字列"p"はどれだけ複雑になってもいいですし、複数の変換指定を含めることもできます。たとえば、"%replace(%logger %msg)'\.','/'}" とすると、ロガー名とメッセージに含まれる全てのドット(.)をスラッシュ(/)で置き換えます。
- </p>
-
- </td>
- </tr>
-
-
- <tr>
- <td class="word" name="rootException">
- <b>rEx</b>{<em>depth</em>} <br>
- <b>rootException</b>{<em>depth</em>} <br>
- <br>
- <b>rEx</b>{depth, evaluator-1, ..., evaluator-n} <br>
- <b>rootException</b>{depth, evaluator-1, ..., evaluator-n}
- </td>
-
- <td>
- <p>ロギングイベントに例外オブジェクトが関連付けられていたら、その例外オブジェクトのスタックトレースを出力します。
-標準とは逆に、例外の発生元から順番にスタックトレースを出力します。こんな出力になります(サンプルなのでだいぶ削っています)。</p>
-
- <pre class="small">java.lang.NullPointerException
- at com.xyz.Wombat(Wombat.java:57) ~[wombat-1.3.jar:1.3]
- at com.xyz.Wombat(Wombat.java:76) ~[wombat-1.3.jar:1.3]
-Wrapped by: org.springframework.BeanCreationException: Error creating bean with name 'wombat':
- at org.springframework.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248) [spring-2.0.jar:2.0]
- at org.springframework.AbstractBeanFactory.getBean(AbstractBeanFactory.java:170) [spring-2.0.jar:2.0]
- at org.apache.catalina.StandardContext.listenerStart(StandardContext.java:3934) [tomcat-6.0.26.jar:6.0.26]
-</pre>
-
- <p>%rootExceptionには、%xExceptionと同じオプションを指定できます。それに、パッケージング情報も出力します。簡単に言うと、%rootException は %xException とほとんど変わりませんが、スタックトレースの出力順だけが逆になっているのです。
- </p>
-
- <p>%のrootExceptionの作者であるTomasz Nurkiewiczは、自身のブログエントリ<a href="http://nurkiewicz.blogspot.com/2011/09/logging-exceptions-root-cause-first.html">"Logging eceptions root cause first"</a>で解説しています。</p>
- </td>
- </tr>
-
- </table>
-
-
- <h4 class="doAnchor" name="percentIsSpecial">%文字の特別な意味</h4>
-
- <p>変換パターン文字列というコンテキストにおいて、%文字には特別な意味があります。文字列リテラルとして使用するにはバックスラッシュ(\)を前につけてエスケープしなければなりません。たとえば "%d %p \%%m%n" といったようにします。
- </p>
-
- <h4 class="doAnchor" name="restrictionsOnLiterals">変換指定子の直後の文字列リテラルの制限</h4>
-
- <p>ほとんどの場合文字列リテラルにはスペースや他の区切り文字が含まれるので、変換指定子と混同されることはありません。例えば、変換パターン文字列"%level [%thread] - %mmessage%n" には文字列リテラル <code>" ["</code>と<code>"] - "</code>が含まれています。しかし、Javaの識別子に使える文字リテラルが変換指定子の直後に現れると、logbackの文字列パターン解析器はその文字リテラルも変換指定子の一部だと勘違いしてしまいます。例えば、変換パターン文字列 "%date<b>%nHello</b>" は、%date と %nHello という二つの変換指定子として解釈されてしまいます。もちろん、%nHello は変換指定子に存在しないため、logback は %PARSER_ERROR[nHello] というエラーを出力するでしょう。%nのすぐ後に文字列リテラル "Hello" を出したければ、%nに空の引数リストを指定すればよいでしょう。たとえば、"%date<b>%n{}</b>Hello" とすれ [...]
-
- </p>
-
- <h2 class="doAnchor" name="formatModifiers">書式修飾子</h2>
-
- <p>デフォルトでは、関連する情報はそのまま出力されます。しかし、書式修飾子を使えばそれぞれのデータを出力する幅の最小値と最大値、それに文字揃えを変えることが出来ます。
- </p>
-
- <p>書式修飾子のオプションは%記号と修飾文字の間に入れます。
- </p>
-
- <p>最初に紹介する書式修飾子のオプションは<em>左揃え</em>です。これはただのマイナス(-)を指定します。次は<em>最小幅</em>です。整数値で出力する文字数を指定します。出力する文字列長が指定した文字数より小さい時は、最小幅を全てうめるまで右側か左側のどちらかをパディングします。デフォルトは右揃えなので左側にパディングしますが、左揃えにして右側にパディングさせることもできます。パディング文字は半角スペースです。出力する文字列長が指定した文字数より大きい時は、全て出力できるように幅を広げます。後ろを切り捨てることはありません。
- </p>
-
- <p>この振る舞いは最大幅を指定すれば変えられます。<em>最大幅</em>はドット(.)の後に整数値で指定します。出力する文字列長が指定した文字数より大きい時は、溢れた分だけ出力する文字列の<em>先頭</em>から削除されます。たとえば、最大幅を8にしたとき、出力する文字列長が10だったら、先頭の2文字が削除されることになります。C言語のprintf関数なら文字列の後ろのほうが削除されるので、逆の振る舞いをすることになります。
- </p>
-
- <p>ドット(.)に続けてマイナス文字(-)を指定すれば、後ろから削除することもできます。その場合、最大幅が8として、出力する文字列長が10だったら、末尾の2文字が削除されることになります。
- </p>
-
- <p>書式修飾子の例をいくつか見ていきましょう。
- </p>
-
- <table class="bodyTable" border="0" cellpadding="8">
- <tr>
- <th>書式修飾子</th>
- <th>左寄せ</th>
- <th>最小幅</th>
- <th>最大幅</th>
- <th>コメント</th>
- </tr>
- <tr class="a">
- <td align="center">%20logger</td>
- <td align="center">しない</td>
- <td align="center">20</td>
- <td align="center">なし</td>
- <td>ロガー名が20文字未満であれば半角スペースで左側にパディングします。
- </td>
- </tr>
- <tr class="b">
- <td align="center">%-20logger</td>
- <td align="center">する</td>
- <td align="center">20</td>
- <td align="center">なし</td>
- <td>ロガー名が20文字未満であれば半角スペースで右側にパディングします。
- </td>
- </tr>
- <tr class="a">
- <td align="center">%.30logger</td>
- <td align="center">指定できない</td>
- <td align="center">なし</td>
- <td align="center">30</td>
- <td>ロガー名が30文字を超える場合、先頭から切り捨てます。
- </td>
- </tr>
- <tr class="b">
- <td align="center">%20.30logger</td>
- <td align="center">しない</td>
- <td align="center">20</td>
- <td align="center">30</td>
- <td>ロガー名が20文字未満であれば半角スペースで左側にパディングします。ロガー名が30文字を超える場合、先頭から切り捨てます。
- </td>
- </tr>
- <tr class="a">
- <td align="center">%-20.30logger</td>
- <td align="center">する</td>
- <td align="center">20</td>
- <td align="center">30</td>
- <td>ロガー名が20文字未満であれば半角スペースで右側にパディングします。ロガー名が30文字を超える場合、<em>先頭</em>から切り捨てます。
- </td>
- </tr>
- <tr class="b">
- <td align="center">%.-30logger</td>
- <td align="center">指定できない</td>
- <td align="center">なし</td>
- <td align="center">30</td>
- <td>ロガー名が30文字を超える場合、<em>末尾</em>から切り捨てます。
- </td>
- </tr>
- </table>
-
- <p>書式修飾子による文字列の切り捨ての例を表にまとめました。角括弧"[]"は出力される文字列ではなく、出力幅を示しているだけなので注意してください。</p>
-
-
- <table class="bodyTable" border="0" cellpadding="8">
- <tr>
- <th>書式修飾子</th>
- <th>ロガー名</th>
- <th>結果</th>
- </tr>
- <tr class="b">
- <td align="center">[%20.20logger]</td>
- <td align="center">main.Name</td>
- <td align="center"><pre>[ main.Name]</pre></td>
- </tr>
- <tr class="a">
- <td align="center">[%-20.20logger]</td>
- <td align="center">main.Name</td>
- <td align="center"><pre>[main.Name ]</pre></td>
- </tr>
- <tr class="a">
- <td align="center">[%10.10logger]</td>
- <td align="center">main.foo.foo.bar.Name</td>
- <td align="center"><pre>[o.bar.Name]</pre></td>
- </tr>
- <tr class="b">
- <td align="center">[%10.-10logger]</td>
- <td align="center">main.foo.foo.bar.Name</td>
- <td align="center"><pre>[main.foo.f]</pre></td>
- </tr>
- </table>
-
- <h3 class="doAnchor" name="oneLetterLevel">レベルを1文字で出力する</h3>
-
- <p>ロギングレベルをTRACE、DEBUG、WARN、INFO、ERRORのような文字列として出力するのではなく、T、D、W、I、Eのように一文字だけ出力したい場合もあるでしょう。<a href="http://logback.qos.ch/manual/layouts.html#customConversionSpecifier">カスタムコンバーター</a>を実装してもできるでしょうし、書式修飾子を使うこともできます。書式修飾子を使うなら<code>"%.-1level"</code>とすればよいでしょう。
- </p>
-
- <h2 class="doAnchor" name="cwOptions">変換指定子のオプション</h2>
-
- <p>変換指定子にはオプションを指定することができます。オプションは必ず中括弧で囲むようにします。オプションで何ができるのか、すでに目にしてきたものがあります。たとえば、<em>%mdc{someKey}</em>のようにMDC変換指定子と組み合わせることができます。
- </p>
-
- <p>変換指定子のオプションは複数になるかもしれません。たとえば、評価器を使う変換指定子があります。すぐ後で説明しますが、こんな風に評価器の名前を複数並べることがあるかもしれません。</p>
-
- <pre class="prettyprint source"><pattern>%-4relative [%thread] %-5level - %msg%n \
- <b>%caller{2, DISP_CALLER_EVAL, OTHER_EVAL_NAME, THIRD_EVAL_NAME}</b></pattern></pre>
-
- <p>指定するオプションに括弧、スペース、カンマなどの特別な文字が含まれるときは、シングルクォートやダブルクォートで囲みます。たとえば、次のような変換パターン文字列になります。</p>
-
- <pre class="prettyprint source"><pattern>%-5level - %replace(%msg)<b>{'\d{14,16}', 'XXXX'}</b>%n</pattern></pre>
-
-
- <p>この例では、<code>replace</code>変換指定子にオプションとして<code>\d{14,16}</code>と<code>XXXX</code>を指定しています。これは、メッセージ中に14桁から16桁の数字文字列があったらそれをXXXXで置き換えるものです。クレジットカード番号をマスクするのに役立ちます。"\d"は一桁の数字を表す正規表現の省略形です。後ろに"{14,16}"をつけているので、一つ前の文字、つまり一桁の数字が14個から16個繰り返される場合にマッチすることになります。
- </p>
-
- <h2 class="doAnchor" name="Parentheses">括弧は特別扱い</h2>
-
- <p>logbackでは、パターン文字列の中の括弧は、トークンをグループ化するものとして扱います。それぞれのグループはそれ自体を1つのパターン文字列として扱うことができます。logback0.9.27から、<a href="http://logback.qos.ch/manual/layouts.html#replace">%replace</a>のような変換指定子を組み合わせて部分パターン文字列を作れるようになりました。
- </p>
-
- <p>こんなパターン文字列があるとします。</p>
-
- <p class="source"><b>%-30(</b>%d{HH:mm:ss.SSS} [%thread]<b>)</b> %-5level %logger{32} - %msg%n</p>
-
- <p>これは、部分パターン文字列"%d{HH:mm:ss.SSS} [%thread]" によって生成された出力をグループ化します。つまり、この部分パターン文字列によって生成された出力が30文字未満の文字列だった場合、右側にパディングされるのです。
- </p>
-
- <p>グループ化しなかった場合はこういう出力になります。</p>
-
- <p class="source">13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Classload hashcode is 13995234
-13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Initializing for ServletContext
-13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Trying platform Mbean server
-13:09:30 [pool-1-thread-1] INFO ch.qos.logback.demo.LoggingTask - Howdydy-diddly-ho - 0
-13:09:38 [btpool0-7] INFO c.q.l.demo.lottery.LotteryAction - Number: 50 was tried.
-13:09:40 [btpool0-7] INFO c.q.l.d.prime.NumberCruncherImpl - Beginning to factor.
-13:09:40 [btpool0-7] DEBUG c.q.l.d.prime.NumberCruncherImpl - Trying 2 as a factor.
-13:09:40 [btpool0-7] INFO c.q.l.d.prime.NumberCruncherImpl - Found factor 2
- </p>
-
- <p>"%-30()" でグループ化するとこうなります。</p>
-
- <p class="source">13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Classload hashcode is 13995234
-13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Initializing for ServletContext
-13:09:30 [main] DEBUG c.q.logback.demo.ContextListener - Trying platform Mbean server
-13:09:30 [pool-1-thread-1] INFO ch.qos.logback.demo.LoggingTask - Howdydy-diddly-ho - 0
-13:09:38 [btpool0-7] INFO c.q.l.demo.lottery.LotteryAction - Number: 50 was tried.
-13:09:40 [btpool0-7] INFO c.q.l.d.prime.NumberCruncherImpl - Beginning to factor.
-13:09:40 [btpool0-7] DEBUG c.q.l.d.prime.NumberCruncherImpl - Trying 2 as a factor.
-13:09:40 [btpool0-7] INFO c.q.l.d.prime.NumberCruncherImpl - Found factor 2
- </p>
-
-
- <p>後者のほうが読みやすいんじゃないでしょうか。</p>
-
- <p>括弧を文字列リテラルとして扱いたいときは、バックスラッシュ(\)でエスケープしなければなりません。こんな感じです。
-"<b>\(</b>%d{HH:mm:ss.SSS} [%thread]<b>\)</b>"
- </p>
-
- <h2 class="doAnchor" name="coloring">カラー化</h2>
-
- <p><a href="http://logback.qos.ch/manual/layouts.html#Parentheses">括弧</a>でグループ化した部分パターン文字列には色を指定することができます。logback1.0.5から<code>PatternLayout</code>で指定できるようになった色付け用の変換指定子は次のとおりです。
- <ul>
- <li>"%black"</li>
- <li>"%red"</li>
- <li>"%green"</li>
- <li>"%yellow"</li>
- <li>"%blue"</li>
- <li>"%magenta"</li>
- <li>"%cyan"</li>
- <li>"%white"</li>
- <li>"%gray"</li>
- <li>"%boldRed"</li>
- <li>"%boldGreen"</li>
- <li>"%boldYellow"</li>
- <li>"%boldBlue"</li>
- <li>"%boldMagenta"</li>
- <li>"%boldCyan"</li>
- <li>"%boldWhite"</li>
- <li>"%highlight"</li>
- </ul>
- これらの変換指定子にはオプションとして部分パターン文字列を指定することが想定されています。そしてその部分パターン文字列から生成された出力には色が付きます。
- </p>
-
- <p>色付けをわかりやすく説明する設定ファイルを次に示します。%cyan変換指定子には部分パターン文字列として"%logger{15}"を指定してあるのがわかりますか。こうすると、ロガー名は15文字に短縮されるだけでなく、文字色がシアンになります。%highlight変換指定子を使うと、部分パターン文字列の文字色が、ログレベルがERRORなら赤太字、ログレベルがWARNなら赤字、ログレベルがINFOなら青字、それ以外のログレベルならデフォルトの色になります。</p>
-
- <p class="example">例:ログレベルに応じた強調表示(<a href="http://logback.qos.ch/xref/chapters/layouts/highlighed.xml">logback-examples/src/main/java/chapters/layouts/highlighed.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('highlighted');">Groovyとして表示</span>
-
-
-<pre id="highlighted" class="prettyprint"><configuration debug="true">
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <!-- On Windows machines setting withJansi to true enables ANSI
- color code interpretation by the Jansi library. This requires
- org.fusesource.jansi:jansi:1.8 on the class path. Note that
- Unix-based operating systems such as Linux and Mac OS X
- support ANSI color codes by default. -->
- <b><withJansi>true</withJansi></b>
- <encoder>
- <pattern>[%thread] <b>%highlight(%-5level)</b> <b>%cyan(%logger{15})</b> - %msg %n</pattern>
- </encoder>
- </appender>
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>この設定ファイルを使うと次のように出力されます。</p>
-
-<pre class="source">[main] <span style="color:#611">WARN</span> <span style="color:#2bd">c.l.TrivialMain</span> - a warning message 0
-[main] DEBUG <span style="color:#2bd">c.l.TrivialMain</span> - hello world number1
-[main] DEBUG <span style="color:#2bd">c.l.TrivialMain</span> - hello world number2
-[main] <span style="color:#00f">INFO</span> <span style="color:#2bd">c.l.TrivialMain</span> - hello world number3
-[main] DEBUG <span style="color:#2bd">c.l.TrivialMain</span> - hello world number4
-[main] <span style="color:#611">WARN</span> <span style="color:#2bd">c.l.TrivialMain</span> - a warning message 5
-[main] <span style="color:#f00">ERROR</span> <span style="color:#2bd">c.l.TrivialMain</span> - Finish off with fireworks</pre>
-
- <p>色付け用変換指定子を使うとパターン文字列が複数行になってしまうこともあります。<a href="http://logback.qos.ch/manual/layouts.html#customConversionSpecifier">変換指定を自作する</a>では設定ファイルで使用できる変換指定子を登録する手順について議論しています。</p>
-
- <h2 class="doAnchor" name="Evaluators">評価器</h2>
-
- <p>前述したように、オプションをリストで指定できると、変換指定子に<a href="http://logback.qos.ch/xref/ch/qos/logback/core/boolex/EventEvaluator.html">EventEvaluator</a>に基づく動的な振る舞いを複数指定できる必要があるときは便利です。
- <code>EventEvaluator</code>の役割は、ロギングイベントが基準に合致するかどうかを判定することです。
- </p>
-
- <p>早速<code>EventEvaluator</code>の例を見てみましょう。次の設定ファイルは、ロギングイベントの日付、スレッド、レベル、メッセージと送信者情報をコンソールに出力するものです。ロギングイベントの送信者情報を抽出するのはとてもコストが高いので、特定のロガーが生成したロギング要求の場合だけに限定しています。さらに、メッセージに特定の文字列が含まれている場合だけにしています。ですので、特定のロギングイベントについてだけ、送信者情報の生成と出力を行うことになります。そうすれば、送信者情報のいらないケースではアプリケーションの性能ペナルティが発生しません。
- </p>
-
- <p>評価器と<em>具体的な評価式</em>については、<a href="http://logback.qos.ch/manual/filters.html#evalutatorFilter">フィルタの章の独立したセクション</a>で紹介しています。もし評価器を実戦投入しようとしているなら必ず読んでおいてください。この後で紹介する例では、明示的に書いていませんが<code>JaninoEventEvaluator</code>を使用しています。ですので実行するには<a href="http://docs.codehaus.org/display/JANINO/Home">Jainoライブラリ</a>が必要になります。設定方法をまとめたドキュメントの<a href="http://logback.qos.ch/setup.html#janino">該当するセクション</a>を読んでください。</p>
-
- <p class="example">例:EventEvaluatorsの使用例(<a href="http://logback.qos.ch/xref/chapters/callerEvaluatorConfig.xml">logback-examples/src/main/java/chapters/callerEvaluatorConfig.xml</a>)</p>
-<span class="asGroovy" onclick="return asGroovy('callerEvaluatorConfig');">Groovyとして表示</span>
-
-
- <pre id="callerEvaluatorConfig" class="prettyprint source"><configuration>
- <b><evaluator name="DISP_CALLER_EVAL">
- <expression>logger.contains("chapters.layouts") && \
- message.contains("who calls thee")</expression>
- </evaluator></b>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>
- %-4relative [%thread] %-5level - %msg%n<b>%caller{2, DISP_CALLER_EVAL}</b>
- </pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>この設定ファイル中の評価式は、ロガー名に"chapters.layouts" が含まれており、かつ、メッセージに"who clals thee" が含まれているロギングイベントにマッチするものです。XMLのエンコーディングルールに従うため、&文字は&のようにエスケープしなければなりません。</p>
-
- <p>この設定ファイルを使用するクラスを見てみましょう。</p>
-
- <p class="example">例:EventEvaluatorsの使用例(<a href="http://logback.qos.ch/xref/chapters/CallerEvaluatorExample.html">logback-examples/src/main/java/chapters/CallerEvaluatorExample.java</a>)</p>
- <pre class="prettyprint source">package <b>chapters.layouts</b>;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.core.joran.spi.JoranException;
-import ch.qos.logback.core.util.StatusPrinter;
-
-public class CallerEvaluatorExample {
-
- public static void main(String[] args) {
- Logger logger = LoggerFactory.getLogger(CallerEvaluatorExample.class);
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
-
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- // StatusPrinter will handle this
- }
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
-
- for (int i = 0; i < 5; i++) {
- if (i == 3) {
- logger.debug(<b>"who calls thee</b>?");
- } else {
- logger.debug("I know me " + i);
- }
- }
- }
-}</pre>
-
- <p>このアプリケーションは特別何もしません。forループでロギング要求を5回生成します。三回目だけ "who calls thee?" というメッセージを出力します。
- </p>
-
- <p>次のコマンドで実行します。</p>
-
- <p class="source">java chapters.layouts.CallerEvaluatorExample src/main/java/chapters/layouts/callerEvaluatorConfig.xml</p>
-
- <p>そうすると、コンソールに次のように出力されます。</p>
-
- <div class="source"><pre>0 [main] DEBUG - I know me 0
-0 [main] DEBUG - I know me 1
-0 [main] DEBUG - I know me 2
-0 [main] DEBUG - who calls thee?
-Caller+0 at chapters.layouts.CallerEvaluatorExample.main(CallerEvaluatorExample.java:28)
-0 [main] DEBUG - I know me 4</pre></div>
-
-
- <p>ロギング要求が生成されたら、そのロギングイベントが評価されます。三回目のロギングイベントだけが評価条件にマッチするので、送信者情報が出力されます。他のロギングイベントは評価基準とマッチしないので送信者情報が出力されていません。
- </p>
-
-
- <p>現実世界のシナリオに対応できるように評価式を変更することにしましょう。例えばロガー名とロギング要求のレベルを組み合わせることもできます。そうすれば、ロギング要求のレベルが<em>WARN</em>より高くて、かつ、アプリケーションの重要部品、例えばお金に絡むトランザクションを処理するモジュールで生成された場合にだけ送信者情報を出力する、といったことができるでしょう。
- </p>
-
- <p><b>重要:</b> <em>caller変換指定</em>によって送信者情報が出力されるのは、評価式が<b>true</b>と<em>評価された</em>ときだけです。</p>
-
- <p>別の状況を考えてみましょう。ロギング要求に例外オブジェクトが設定されていると、スタックトレースも出力されます。しかし、特定の例外オブジェクトのスタックトレースは出力したくないこともあります。
- </p>
-
- <p>次のコードでは、例外オブジェクトを指定したロギング要求を3つ生成しています。二つ目の例外オブジェクトは他のものと違ってメッセージに "do not display this" という文字列が含まれていますし、例外クラスが <code>chapters.layouts.TestException</code>になっています。このメッセージを指示とみなして、二つ目の例外オブジェクトのスタックトレースが出力されないようにしてみましょう。</p>
-
- <p class="example">例:ExceptionEventEvaluatorsの使用例(<a href="http://logback.qos.ch/xref/chapters/ExceptionEvaluatorExample.html">logback-examples/src/main/java/chapters/ExceptionEvaluatorExample.java</a>)</p>
-<pre class="prettyprint source">package chapters.layouts;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.core.joran.spi.JoranException;
-import ch.qos.logback.core.util.StatusPrinter;
-
-public class ExceptionEvaluatorExample {
-
- public static void main(String[] args) {
- Logger logger = LoggerFactory.getLogger(ExceptionEvaluatorExample.class);
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
-
- try {
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- lc.reset();
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- // StatusPrinter will handle this
- }
- StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
-
- for (int i = 0; i < 3; i++) {
- if (i == 1) {
- logger.debug("logging statement " + i, new TestException(
- "do not display this"));
- } else {
- logger.debug("logging statement " + i, new Exception("display"));
- }
- }
- }
-}</pre>
-
- <p>次の設定ファイルで指定した評価式は、<code>chapters.layouts.TextException</code>の例外オブジェクトが設定されたロギングイベントにマッチします。この例外型はスタックトレースの出力を抑止したい型そのものです。
- </p>
-
- <p class="example">例:ExceptionEventEvaluatorsの使用例(<a href="http://logback.qos.ch/xref/chapters/exceptionEvaluatorConfig.xml">logback-examples/src/main/java/chapters/exceptionEvaluatorConfig.xml</a>)</p>
- <pre class="prettyprint source"><configuration>
-
- <b><evaluator name="DISPLAY_EX_EVAL">
- <expression>throwable != null && throwable instanceof \
- chapters.layouts.TestException</expression>
- </evaluator></b>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%msg%n<b>%ex{full, DISPLAY_EX_EVAL}</b></pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>この設定は、<em>chapters.layouts.TestException</em>のインスタンスが設定されたロギング要求については、常にスタックトレースの出力を抑止します。
- </p>
-
- <p>実行してみましょう。</p>
-
- <p class="source">java chapters.layouts.ExceptionEvaluatorExample src/main/java/chapters/layouts/exceptionEvaluatorConfig.xml</p>
-
- <p>そうすると、次のような出力になります。</p>
-
-<p class="source">logging statement 0
-java.lang.Exception: display
- at chapters.layouts.ExceptionEvaluatorExample.main(ExceptionEvaluatorExample.java:43) [logback-examples-0.9.19.jar:na]
-logging statement 1
-logging statement 2
-java.lang.Exception: display
- at chapters.layouts.ExceptionEvaluatorExample.main(ExceptionEvaluatorExample.java:43) [logback-examples-0.9.19.jar:na]</p>
-
-
- <p>二つ目のロギング要求による出力にはスタックトレースが含まれていないことがわかりますか。うまく<code>TestException</code>のスタックトレースを出力しないようにできました。スタックトレースの各行の最後にある角括弧で囲まれた部分は<a href="http://logback.qos.ch/manual/layouts.html#xThrowable">パッケージング情報</a>です。</p>
-
- <p><b><em>%ex</em></b>変換指定があるので、<em>評価式</em>の結果が<b>false</b>になったときだけスタックトレースが出力されるようになっています。</p>
-
-
-
- <h2 class="doAnchor" name="customConversionSpecifier">変換指定子を自作する</h2>
-
- <p>ここまでに、<code>PatternLayout</code>に組み込みの変換指定子を見てきました。ですが、変換指定子を自作することもできるのです。</p>
-
- <p>カスタム変換指定子を作るには2つの手順を踏みます。
- </p>
-
- <h4>ステップ1</h4>
-
- <p>まず、<code>ClassicConverter</code>を継承したクラスを作ります。<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/pattern/ClassicConverter.html">ClassicConverter</a></code>の役割は、<code>ILoggingEvent</code>から情報を抽出して出力する文字列を生成することです。たとえば、 %logger変換指定子を実装した<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/pattern/LoggerConverter.html">LoggerConverter</a></code>は、<code>ILoggingEvent</code>から抽出したロガーの名前を文字列として返します。ロガー名の省略はこの手順で行います。</p>
-
- <p>アプリケーションが起動してからの経過時間をナノ秒単位で返すカスタム変換指定子の実装を見てみましょう。</p>
-
- <p class="example">例:自作コンバーターの例(<a href="http://logback.qos.ch/xref/chapters/MySampleConverter.html">logback-examples/src/main/java/chapters/MySampleConverter.java</a>)</p>
-<pre class="prettyprint source">public class MySampleConverter extends ClassicConverter {
-
- long start = System.nanoTime();
-
- <b>@Override</b>
- <b>public String convert(ILoggingEvent event) {</b>
- <b>long nowInNanos = System.nanoTime();</b>
- <b>return Long.toString(nowInNanos-start);</b>
- <b>}</b>
-}</pre>
-
- <p>この実装は非常に簡単です。<code>MySampleConverter</code>クラスは<code>ClassicConverter</code>を継承しており、<code>convert(ILoggingEvent)</code>メソッドはアプリケーションが起動してからの経過時間をナノ秒単位で計算して、それを文字列化しているだけです。
- </p>
-
- <h4>ステップ2</h4>
-
- <p>logback に自作した<code>Converter</code>のことを教えなければいけません。そのためには、設定ファイルで新しい変換指定子を宣言する必要があります。</p>
-
- <p class="example">例:自作コンバーターの設定例(<a href="http://logback.qos.ch/xref/chapters/mySampleConverterConfig.xml">logback-examples/src/main/java/chapters/mySampleConverterConfig.xml</a>)</p>
-<span class="asGroovy" onclick="return asGroovy('mySampleConverterConfig');">Groovyとして表示</span>
-<pre id="mySampleConverterConfig" class="prettyprint source"><configuration>
-
- <b><conversionRule conversionWord="nanos"
- converterClass="chapters.layouts.MySampleConverter" /></b>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern><b>%-6nanos</b> [%thread] - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>設定ファイルで宣言した新しい変換指定子は、<code>PatternLayout</code>に指定する変換パターン文字列の中で他の変換指定と同じように使うことが出来ます。</p>
-
- <p>実行してみましょう。</p>
-
- <div class="source">java chapters.layouts.SampleLogging src/main/java/chapters/layouts/mySampleConverterConfig.xml </div>
-
- <p>次のような出力になるはずです。</p>
-
- <pre class="source">4868695 [main] DEBUG - Everything's going well
-5758748 [main] ERROR - maybe not quite...</pre>
-
-
- <p>オプションの扱い方や、もっと複雑な振る舞いをさせるやり方を知りたければ、<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/pattern/MDCConverter.html"><code>MDCConverter</code></a>などの既存の<code>Converter</code>実装を見てみるとよいでしょう。独自の色付けをしたければ<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/pattern/color/HighlightingCompositeConverter.html"><code>HighlightingCompositeConverter</code></a>を参考にするとよいでしょう。
- </p>
-
-
-
- <h2 class="doAnchor" name="ClassicHTMLLayout">HTMLLayout</h2>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/html/HTMLLayout.html"><code>HTMLLayout</code></a>はHTML形式のログを出力します(logback-classicに含まれています)。<code>HTMLLayout</code>はHTMLのテーブルを出力します。それぞれの行がロギングイベントに対応しています。</p>
-
- <p>デフォルトのCSSを使った<code>HTMLLayout</code>の出力例を見てください。</p>
- <img src="images/chapters/layouts/htmlLayout0.gif" alt="HTMLレイアウトサンプル画像">
-
- <p>テーブルの列は変換パターン文字列で指定します。<a href="http://logback.qos.ch/manual/layouts.html#ClassicPatternLayout"><code>PatternLayout</code></a>のドキュメントに書かれた変換パターン文字列の説明を見てください。テーブルの形も内容も全て制御することができます。<code>PatternLayout</code>で使えるあらゆるコンバーターを使うことができます。
- </p>
-
- <p>自由に使えるとはいえ一つだけ例外的な制限があります。<code>PatternLayout</code>と<code>HTMLLayout</code>を使うときは、変換パターン文字列中で変換指定を半角スペースで区切ってはいけません。もっというと文字列リテラルを使わないようにしてください。変換パターン文字列中の変換指定はそれぞれがテーブルの列になるからです。同様に、変換指定を区切るつもりの文字列リテラルはそれぞれが列になってしまいます。下手をすると、横に超長いテーブルが出力されてしまうかもしれません。</p>
-
- <p><code>HTMLLayout</code>の使い方を説明する設定ファイルを見てください。
- </p>
-
- <p class="example">例:HTMLLayoutの設定例(<a href="http://logback.qos.ch/xref/chapters/htmlLayoutConfig1.xml">logback-examples/src/main/java/chapters/htmlLayoutConfig1.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('htmlLayoutConfig1');">Groovyとして表示</span>
-<pre id="htmlLayoutConfig1" class="prettyprint source"><configuration debug="true">
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
- <layout class="ch.qos.logback.classic.html.HTMLLayout">
- <b><pattern>%relative%thread%mdc%level%logger%msg</pattern></b>
- </layout>
- </encoder>
- <file>test.html</file>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration>
-</pre>
-
- <p><a href="http://logback.qos.ch/xref/chapters/layouts/TrivialMain.html">TrivialMain</a>アプリケーションは、いくつかログを出力してから最後に例外オブジェクトを指定したログを出力します。実行してみましょう。</p>
-
- <p class="source">java chapters.layouts.TrivialMain src/main/java/chapters/layouts/htmlLayoutConfig1.xml</p>
-
- <p>すると、カレントフォルダに<em>test.html</em>というファイルが作成されます。<em>test.html</em>をブラウザで見ると次のようになっているでしょう。</p>
- <img src="images/chapters/layouts/htmlLayout1.png" alt="HTMLレイアウトサンプル画像">
-
- <h3>スタックトレース</h3>
-
- <p>スタックトレースを出力するには<em>%ex変換指定</em>を指定します。そうすると専用の列が追加されます。ほとんどの場合スタックトレースの列は空なので、無駄に画面を専有することでしょう。さらに、スタックトレースを専用の列に出力したところで読みやすくはならないです。なお、スタックトレースを出力するには、<em>%ex変換指定</em>を指定する以外の方法があります。
- </p>
-
- <p>よりよい解決策は、自分で<code>IThrowableRenderer</code>インターフェイスを実装することです。実装したクラスは、例外オブジェクトに関係する情報を出力するため、<code>HTMLLayout</code>に割り当てることができます。デフォルトでは、<code>HTMLLayout</code>インスタンスに<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/html/DefaultThrowableRenderer.html">DefaultThrowableRenderer</a></code>が割り当てられています。これは例外オブジェクトのスタックトレースを<em>新しい行</em>に出力します。前の図を見るとわかりますが多少読みやすいです。
- </p>
-
- <p>それでも理由があって<em>%ex</em>を使いたいときは、設定ファイルに<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/html/NOPThrowableRenderer.html">NOPThrowableRenderer</a></code>を指定すればスタックトレースを別々の行に出力しないようにできます。あなたの望み通りに全てが上手くいくようなアイデアはありません。それでも、こうしたいという気持ちがあればきっと実現できます。
- </p>
-
- <h3>CSS</h3>
-
- <p><code>HTMLLayout</code>で生成したHTMLの見た目はCSSで調整することができます。特別な指定がなければ、<code>HTMLLayout</code>は組み込みのCSSを使います。しかし、外部のCSSを使うようにも指定できます。そのためには、<code>layout要素</code>に<code>cssBuilder要素</code>をネストさせればよいです。
- </p>
-
-<pre class="prettyprint source"><layout class="ch.qos.logback.classic.html.HTMLLayout">
- <pattern>%relative...%msg</pattern>
- <cssBuilder class="ch.qos.logback.classic.html.UrlCssBuilder">
- <!-- url where the css file is located -->
- <url>http://...</url>
- </cssBuilder>
-</layout></pre>
-
-
- <p><code>HTMLLayout</code>は<code>SMTPAppender</code>と組み合わせて使われることがあります。そうするとメールの内容がHTMLで綺麗に飾られたものになります。</p>
-
-
- <h2 class="doAnchor" name="log4jXMLLayout">Log4jのXMLLayout</h2>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/log4j/XMLLayout.html">XMLLayout</a> (logback-classicに含まれています)を使うとlog4j.dtdに準拠した書式で出力できるようになります。つまり、<a href="http://logging.apache.org/chainsaw/index.html">Chainsaw</a>や<a href="http://vigilog.sourceforge.net/">Vigilog</a>などの、<a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/XMLLayout.html">log4jのXML書式</a>を入力とするツールと相互運用できるのです。
- </p>
-
-
- <p>オリジナルのXMLLayoutはlog4j1.2.15で導入されたものです。logback-classic の XMLLayoutには<span class="option">locationInfo</span>と<span class="option">properties</span>という二つのプロパティが指定できます。<span class="option">locationInfo</span>プロパティにtrueを指定すると、ロギングイベントの位置情報(送信者情報)を含められるようになります。<span class="option">property</span>プロパティにtrueを指定すると、MDCの情報を含められるようになります。どちらのプロパティもデフォルトはfalseです。
- </p>
-
- <p>設定例を見てみましょう。</p>
-
- <p class="example">例:Log4jXMLLayoutの例(<a href="http://logback.qos.ch/xref/chapters/log4jXMLLayout.xml">logback-examples/src/main/java/chapters/log4jXMLLayout.xml</a>)</p>
-
-<span class="asGroovy" onclick="return asGroovy('log4jXMLLayout');">Groovyとして表示</span>
- <pre id="log4jXMLLayout" class="prettyprint source"><configuration>
- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
- <file>test.xml</file>
- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
- <layout class="ch.qos.logback.classic.log4j.XMLLayout">
- <locationInfo>true</locationInfo>
- </layout>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="FILE" />
- </root>
-</configuration> </pre>
-
- <h1 class="doAnchor" name="logback-access">logback access モジュール</h1>
-
- <p>logback-access モジュールのほとんどのレイアウトは、logback-classic モジュールのレイアウトをそのまま移植しただけです。logback-classic モジュールと logback-access モジュールは用途が違うのですが、だいたい同じ機能を提供しています。</p>
-
- <h2>レイアウトを自作する</h2>
-
- <p>logback-access 用の<code>レイアウト</code>を自作するのは、logback-classic の<code>レイアウト</code>を自作するのとほとんど変わりありません。</p>
-
-
- <h3 class="doAnchor" name="AccessPatternLayout">PatternLayout</h3>
-
- <p>logback-access の<code><a href="http://logback.qos.ch/xref/ch/qos/logback/access/PatternLayout.html">PatternLayout</a></code>は、logback-classic とほとんど同じように設定することができます。ですが、HTTPリクエストやHTTPレスポンスにしか無い、ロギングに適した情報のための変換指定が追加されています。
- </p>
-
- <p>logback-accessの<code>PatternLayout</code>で使える変換指定を表にまとめました。</p>
-
- <table class="bodyTable striped" border="0" cellpadding="8">
- <tr>
- <th align="center">変換指定</th>
- <th align="center">効果</th>
- </tr>
- <tr>
- <td class="word" name="remoteIP">
- <b>a</b><br /><b>
-remoteIP</b>
- </td>
- <td>
- <p>リモートIPアドレス。</p>
- </td>
- </tr>
- <tr>
- <td class="word" name="localIP"><b>A</b><br /><b>
-localIP</b></td>
- <td>
- <p>ローカルIPアドレス。</p>
- </td>
- </tr>
- <tr>
- <td class="word" name="bytesSent"><b>b</b><br /><b>
-B</b><br /><b>
-bytesSent</b></td>
- <td>
- <p>レスポンスのコンテンツ長。
- </p>
- </td>
- </tr>
- <tr>
- <td class="word" name="clientHost"><b>h</b><br /><b>
-clientHost</b></td>
- <td>
- <p>リモートホスト名。
- </p>
- </td>
- </tr>
- <tr>
- <td class="word" name="protocol"><b>H</b><br /><b>
-protocol</b></td>
- <td>
- <p>リクエストプロトコル。</p>
- </td>
- </tr>
- <tr>
- <td class="word" name="remoteLogName"><b>l</b></td>
- <td>
- <p>リモートログ名。logback-accessではこのコンバーターの値は常に "-" です。
- </p>
- </td>
- </tr>
-
- <tr>
- <td class="word" name="reqParameter"><b>reqParameter{paramName}</b></td>
- <td>
- <p>リクエストパラメータ。</p>
- <p>この変換指定子は、オプションで指定されたリクエストパラメータを探します。</p>
- <p><b>%reqParameter{input_data}</b>とすると、リクエストパラメータのinput_dataの値を出力します。</p>
- </td>
- </tr>
- <tr>
- <td class="word" name="header"><b>i{header}</b><br /><b>
-header{header}</b></td>
- <td>
- <p>リクエストヘッダ。</p>
- <p>この変換指定子はオプションで指定されたリクエストヘッダを探します。</p>
- <p><b>%header{Referer}</b>とすると、リクエストヘッダのRefererの値を出力します。</p>
- <p>オプションを指定しなかったら、利用可能なヘッダを全て出力します。
- </p>
- </td>
- </tr>
- <tr>
- <td class="word" name="requestMethod"><b>m</b><br /><b>
-requestMethod</b></td>
- <td>
- <p>リクエストメソッド。</p>
- </td>
- </tr>
- <tr>
- <td class="word" name="requestURL"><b>r</b><br /><b>
-requestURL</b></td>
- <td>
- <p>要求されたURL。
- </p>
- </td>
- </tr>
- <tr>
- <td class="word" name="statusCode"><b>s</b><br /><b>
-statusCode</b></td>
- <td>
- <p>レスポンスのステータスコード。</p>
- </td>
- </tr>
- <tr>
- <td class="word" name="elapsedTime"><b>D</b><br /><b>
-elapsedTime</b></td>
- <td>
- <p>リクエストを処理するのにかかった時間。ミリ秒単位です。
- </p>
- </td>
- </tr>
- <tr>
- <td class="word" name="dateAccess"><b>t</b><br /><b>
-date</b></td>
- <td>
- <p>ロギングイベントの日時を出力します。オプションとして、<code>java.text.SimpleDateFormat</code>で使用できる日時パターン文字列を指定します。<em>ISO8601</em>も有効な値です。
- </p>
- <p>具体的には、<b>%t {HH:mm:ss,SSS} </b>や、<b>%t{dd MMM yyyy;HH:mm:ss,SSS}</b>などです。日時パターン文字列が指定されなかったら、共通ログ書式の日時パターン文字列である<b>T6{dd/MMM/yyyy:HH:mm:ss Z}</b>が指定されたものとして扱います。
- </p>
- </td>
- </tr>
- <tr>
- <td class="word" name="httpUser"><b>u</b><br /><b>
-user</b></td>
- <td>
- <p>リモートユーザー。
- </p>
- </td>
- </tr>
- <tr>
- <td class="word" name="requestURI"><b>U</b><br /><b>
-requestURI</b></td>
- <td>
- <p>要求されたURI。</p>
- </td>
- </tr>
- <tr>
- <td class="word" name="server"><b>v</b><br /><b>
-server</b></td>
- <td>
- <p>サーバー名。</p>
- </td>
- </tr>
- <tr class="b">
- <td class="word" name="localPort"><b>localPort</b></td>
- <td>
- <p>ローカルポート番号。</p>
- </td>
- </tr>
- <tr class="a">
- <td class="word" name="reqAttribute"><b>reqAttribute{attributeName}</b></td>
- <td>
- <p>リクエストの属性。</p>
- <p>この変換指定子はオプションで指定された属性を探します。
-</p>
- <p><b>%reqAttribute{SOME_ATTRIBUTE}</b>とすると、リクエスト属性SOME_ATTRIBUTEの値を出力します。</p>
- </td>
- </tr>
- <tr class="b">
- <td class="word" name="reqCookie"><b>reqCookie{cookie}</b></td>
- <td>
- <p>リクエストクッキー。</p>
- <p>この変換指定子はオプションで指定されたリクエストクッキーを探します。
-</p>
- <p><b>%cookie{COOKIE_NAME}</b>とすると、クッキーCOOKIE_NAMEの値を出力します。</p>
- </td>
- </tr>
- <tr class="a">
- <td class="word" name="responseHeader"><b>responseHeader{header}</b></td>
- <td>
- <p>レスポンスヘッダー。
- </p>
- <p>この変換指定子はオプションで指定されたレスポンスヘッダを探します。
-</p>
- <p><b>%responseHeader{Server}</b>とすると、レスポンスヘッダServerの値を出力します。</p>
- </td>
- </tr>
- <tr class="b">
- <td class="word" name="requestContent"><b>requestContent</b></td>
- <td>
- <p>この変換指定はリクエストの中身、つまり、リクエストの<code>InputStream</code>を出力します。実際は、<code><a href="http://logback.qos.ch/xref/ch/qos/logback/access/servlet/TeeFilter.html">TeeFilter</a></code>によって元の<code>HttpServletRequest</code>を<code>TeeHttpServletRequest</code>に置き換えます。だから、データを失わずに何度でもリクエストの<code>InputStream</code>にアクセスできるのです。
- </p>
- </td>
- </tr>
- <tr class="a">
- <td class="word" name="fullRequest"><b>fullRequest</b></td>
- <td>
- <p>リクエストに関連するヘッダ、コンテンツを全て出力します。
- </p>
- </td>
- </tr>
- <tr class="b">
- <td class="word" name="responseContent"><b>responseContent</b></td>
- <td>
- <p>レスポンスの中身、つまり、レsポンスの<code>InputStream</code>を出力します。実際は、<code>TeeFilter</code>によって元の<code>HttpServletResponse</code>を<code>TeeHttpServletResponse</code>に置き換えます。だから、データを失わずに何度でもレスポンスの<code>InputStream</code>にアクセスできるのです。
- </p>
- </td>
- </tr>
- <tr class="a">
- <td class="word" name="fullResponse"><b>fullResponse</b></td>
- <td>
- <p>レスポンスに関連するヘッダ、コンテンツを全て出力します。
- </p>
- </td>
- </tr>
- </table>
-
- <p>logback-accessの<code>PatternLayout</code>ではさらに3つのキーワードが利用できます。これはいわゆるショートカットです。</p>
-
- <table class="bodyTable">
- <tr>
- <th>キーワード</th>
- <th>等価な変換パターン文字列</th>
- </tr>
- <tr class="a">
- <td><em>common</em>
-<em>CLF</em></td>
- <td><em>%h %l %u [%t] "%r" %s %b</em></td>
- </tr>
- <tr class="b">
- <td><em>combined</em></td>
- <td><em>%h %l %u [%t] "%r" %s %b "%i{Referer}" "%i{User-Agent}"</em></td>
- </tr>
-
- </table>
-
-
- <p>キーワード<em>common</em>は変換文字列パターン<em>'%h %l %u [%t] "%r" %s %b'</em>と同じ意味になります。先頭から順番に、クライアントホスト、リモートログ名、ユーザー名、日時、リクエストURL、ステータスコード、レスポンスのコンテンツ長が出力されます。</p>
-
- <p>キーワード<em>combined</em>は変換文字列パターン<em>'%h %l %u [%t]
- "%r" %s %b "%i{Referer}" "%i{User-Agent}"'</em>のショートカットです。先頭は<em>common</em>キーワードの変換パターン文字列とほとんど代わりませんが、referer、user-agent というリクエストヘッダが追加されているのが違います。</p>
-
- <h3 class="doAnchor" name="AccessHTMLLayout">HTMLLayout</h3>
-
- <p>logback-accessモジュールの<a href="http://logback.qos.ch/xref/ch/qos/logback/access/html/HTMLLayout.html"><code>HTMLLayout</code></a>は、logback-classicモジュールの<a href="http://logback.qos.ch/manual/layouts.html#ClassicHTMLLayout"><code>HTMLLayout</code></a>とほとんど変わりません。
- </p>
-
- <p>デフォルトでは次の項目を含む表を作ります。</p>
-
- <ul>
- <li>リモートIP</li>
- <li>日付</li>
- <li>リクエストURL</li>
- <li>レスポンスのステータスコード</li>
- <li>コンテンツ長</li>
- </ul>
-
- <p>logack-accessの<code>HTMLLayout</code>による出力例を見てください。</p>
- <img src="images/chapters/layouts/htmlLayoutAccess.gif" alt="アクセスHTMLレイアウトサンプル画像">
-
- <p>実際に使うと上でもっと良くするにはどうしたらいいでしょうか?log4j.properties for logback <a href="http://logback.qos.ch/translator/">translator</a>は、logback-access の<code>RollingFileAppender</code>と<code>HTMLLayout</code>を使ってリアルタイム出力をするようになっています。</p>
-
-
- <p>Webアプリケーションの<a href="http://logback.qos.ch/translator/">translator</a>に対するユーザーからのリクエストに対して、都度新しいアクセスログが出力されます。<a href="http://logback.qos.ch/translator/logs/access.html">このリンク先</a>でそれを見ることが出来ます。</p>
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/loggingSeparation.html b/logback-site/src/site/pages/manual/loggingSeparation.html
index 7074d36..55cb8e0 100644
--- a/logback-site/src/site/pages/manual/loggingSeparation.html
+++ b/logback-site/src/site/pages/manual/loggingSeparation.html
@@ -27,8 +27,6 @@
<div id="content">
<h1>Chapter 9: Logging separation</h1>
-
- <a href="loggingSeparation_ja.html">和訳 (Japanese translation)</a>
<div class="quote">
<p><em>It is not knowledge, but the act of learning, not
diff --git a/logback-site/src/site/pages/manual/loggingSeparation_ja.html b/logback-site/src/site/pages/manual/loggingSeparation_ja.html
deleted file mode 100644
index 68bed13..0000000
--- a/logback-site/src/site/pages/manual/loggingSeparation_ja.html
+++ /dev/null
@@ -1,270 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第9章 ログの分離</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第9章 ログの分離</h1>
-
- <div class="quote">
- <p><em>知識ではなくそれを学ぼうとする行為、所持することではなく得ようとする行為、それこそが最上の娯楽なのです。私は課題を研究し尽くしてしまうと、誰にも見つからないようにそこから離れてしまいます。私という決して満足できない人間は、何かを成し遂げた後平和裏に過ごすのではなく、すぐに違うことを始めてしまう奇人なのです。1つの国を征服したそばから、次の国に手を出そうとする、世界を征服するというのはこういうことなんだという確信があります。</em></p>
-
- <p>-カール・フレデリッヒ・ガウス、1808年に記されたボヨイへの手紙</p>
-
- <p><em>薄い絹のような洋服であってもほとんどの湿疹は隠れてしまう。</em></p>
-
- <p>-アルベール・カミュ、 <em>秋</em></p>
-
- </div>
-
- <script src="../templates/creative.js" type="text/javascript"></script>
- <script src="../templates/setup.js" type="text/javascript"></script>
-
- <h2>問題:ログの分離</h2>
-
- <p>本章では、同じWebコンテナあるいはEJBコンテナ上で稼働する複数のアプリケーションで、ログを分離するにはどうすればいいのか検討します。文中で"application"という言葉を使う時は、WebアプリケーションかJ2EEアプリケーションのどちらかを表しています。分離されたログ環境では、それぞれのアプリケーションは独立したlogback環境になります。したがって、アプリケーションのlogbackの設定は、他の設定には影響しません。技術的な言葉で言うと、それぞれのWebアプリケーションは専用の独立した<code>LoggerContext</code>を使用します。logbackに話を戻します。<code>LoggerContext</code>に生成されたロガーオブジェクトは、メモリ上に残っている間はLoggerContextに割り当てられたままです。類似の問題として、アプリケーションのロギングとコンテナのロギングの分離、というものがあります。
- </p>
-
- <h2 class="doAnchor" name="easy">一番簡単でわかりやすい方法</h2>
-
- <p>コンテナが子孫優先クラスローディングをサポートしていることにしましょう。その場合 slf4j と logback の jar ファイルをアプリケーション自体に含めるようにすればログを分離することができます。Webアプリケーションなら<em>WEB-INF/lib</em>ディレクトリの下に置くだけで、アプリケーションごとのロギングを分離するには十分です。logbackがメモリにロードされるとき、<em>WEB-INF/classes</em>に置かれた<em>logback.xml</em>のコピーが選ばれます。
- </p>
-
- <p>コンテナがクラスローダーを別々にしてくれるので、Webアプリケーションは自分の<code>LoggerContext</code>に自分の<em>logback.xml</em>を選ばせることができます。</p>
-
- <p>朝飯前です。</p>
-
- <p>少し正確さにかけますね・・・SLF4Jとlogbackを全てのアプリケーションからアクセスできる場所に置かなければならないこともあるでしょう。共有ライブラリがSLF4Jを使っている場合などです。そうすると、全てのアプリケーションは同じlogback環境を共有することになってしまいます。他にも、全てのアプリケーションから参照できる場所にSLF4Jとlogbackを置かなければならないような状況はあるでしょう。そして、それはクラスローダー分離に基づくログの分離を不可能にしてしまいます。絶望しなくてもいいですよ。まだ希望は残されています。読み進めてください。
- </p>
-
- <h2 class="doAnchor" name="contextSelectors">コンテキストセレクタ</h2>
-
- <p>logbackにはメモリにロードされている単一のインスタンスによって複数のLoggerContextを扱う仕組みがあります。次のように書いたとしましょう。</p>
-
- <pre class="prettyprint source">Logger logger = LoggerFactory.getLogger("foo");</pre>
-
- <p><code>LoggerFactory</code>の<code>getLogger()</code>メソッドは、SLF4Jのバインディングに<code>ILoggerFactory</code>を問い合わせます。SLF4Jがlogbackにバインドされているときは、<code>ILoggerFactory</code>を返すというタスクが、<a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/selector/ContextSelector.html">ContextSelector</a>に委譲されるのです。<code>ContextSelector</code>は常に<code>LoggerContext</code>のインスタンスを返すので気をつけておきましょう。ContextSelectorは、<code>ILoggerFactory</code>インターフェイスを実装しています。言い換えると、コンテキストセレクタは独自の基準に従って<code>LoggerContext</c [...]
- </p>
-
- <p>デフォルトでは、logbackバインディングは<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/selector/DefaultContextSelector.html">DefaultContextSelector</a>を使います。これは、デフォルトのロガーコンテキストと呼ばれる常に同じ<code>LoggerContext</code>を返します。</p>
-
- <p>システムプロパティの<em>logback.ContextSelector</em>を使うと、別のコンテキストセレクタを指定することができます。コンテキストセレクタに<code>myPackage.myContextSelector</code>を指定したければ、次のように指定すればよいのです。</p>
-
- <p class="source">-Dlogback.ContextSelector=myPackage.myContextSelector</p>
-
- <p>コンテキストセレクタは、<code>ContextSelector</code>インターフェイスを実装しなければなりません。そして、<code>LoggerContext</code>を唯一の引数とするコンストラクタが必要です。
- </p>
-
-
- <h3 class="doAnchor" name="ContextJNDISelector">ContextJNDISelector</h3>
-
- <p>logback-classic の配布物には<code>ContextJNDISelector</code>というコンテキストセレクタが含まれています。これは JNDI を介して参照できるロガーコンテキストを選択できるようにするものです。これは J2EE の仕様にある JNDI のデータ分離に基づいています。したがって、同じ環境変数を使って、アプリケーションごとに異なる値を渡すことが出来るようになります。言い換えると、単独のLoggerFactoryを全てのアプリケーションで共有している状態でも、それぞれのアプリケーションによる<code>LoggerFactory.getLogger()</code>の呼び出しに対して、独立したロガーコンテキストに割り当てられたロガーを返すようになるのです。これでログを分離することができるでしょう。
- </p>
-
- <p><code>ContextJNDISelector</code>を有効化するには、システムプロパティの<em>logback.ContextSelector</em>に"JNDI"を指定します。</p>
-
- <p class="source">-Dlogback.ContextSelector=JNDI</p>
-
- <p><code>JNDI</code>という値は、<code>ch.qos.logback.classic.selector.ContextJNDISelector</code>の省略形です。</p>
-
- <h3 class="doAnchor" name="settingJNDIVariables">JNDI変数の設定</h3>
-
- <p>それぞれのアプリケーションが、専用のコンテキスト名を設定しなければなりません。Webアプリケーションの場合、JNDI環境変数は<em>web.xml</em>で指定します。アプリケーション名が "knobi" なら、web.xml に次のような設定を追加すればよいでしょう。</p>
-
- <pre class="prettyprint source"><env-entry>
- <env-entry-name>logback/context-name</env-entry-name>
- <env-entry-type>java.lang.String</env-entry-type>
- <env-entry-value>kenobi</env-entry-value>
-</env-entry></pre>
-
- <p><code>ContextJNDISelector</code>が有効になっているとしたら、kenobiアプリケーションのロガーは"kenobi"ロガーコンテキストに割り当てられたものになっているでしょう。また、"kenobi"ロガーコンテキストの設定ファイルは、<em>命名規約</em>にしたがって <em>logback-kenobi.xml</em>という名前になります。スレッドコンテキストクラスローダーの<em>リソース</em>から見つけて初期化に使われます。つまり、kenobiアプリケーションの<em>WEB-INF/classes</em>の下に<em>logback-kenobi.xml</em>を配置しておかなければなりません。
- </p>
-
- <p>"logback/configuration-resource" という JNDI 環境変数を使えば、命名規約に関わらず他の名前の設定ファイルを使うこともできます。例えば、kenobiアプリケーションで命名規約に従った<em>logback-kenobi.xml</em>ではなく<em>aFolder/my_config.xml</em>を使うとしたら、次のような設定をweb.xmlに追加することになります。</p>
-
-
- <pre class="prettyprint source"><env-entry>
- <env-entry-name>logback/configuration-resource</env-entry-name>
- <env-entry-type>java.lang.String</env-entry-type>
- <env-entry-value>aFolder/my_config.xml</env-entry-value>
-</env-entry></pre>
-
- <p><em>my_config.xml</em>は、<em>WEB-INF/classes/aFolder/</em>の下に置かなければなりません。設定ファイルは、現在のスレッドのコンテキストクラスローダーによってJavaのリソースと同じように探索されるということを覚えておいてください。
- </p>
-
-
- <h3 class="doAnchor" name="jndiTomcat">ContextJNDISelectorを使うためのTomcatの設定</h3>
-
- <p>まず、logback.jar(logback-classic-1.1.2.jar logback-core-1.1.1.jar slf4j-api-1.7.6.jar)をTomcatのグローバルな共有クラスフォルダ(shared)に置きましょう。Tomcat 6.x の場合は、<em>$TOMCAT_HOME/lib</em> の下に置いてください。
- </p>
-
- <p>そして、<em>$TOMCAT_HOME/bin/catalina.sh(Windows の場合は catalina.bat)</em>の適切な場所で、次のようにシステムプロパティの<em>logback.ContextSelector</em>を設定してください。</p>
-
- <p class="source">JAVA_OPTS="$JAVA_OPTS -Dlogback.ContextSelector=JNDI"</p>
-
-
- <h3 class="doAnchor" name="hotDeploy">ホットデプロイ</h3>
-
- <p>アプリケーションがリサイクルされるとき、あるいは、シャットダウンするとき、利用中の<code>LoggerContext</code>はクローズしましょう。確実にガベージコレクションされるためには欠かせません。声を大にしておすすめします。logbackの配布物には<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/selector/servlet/ContextDetachingSCL.html"><code>ContextDetachingSCL</code></a>という<code>ServletContextListener</code>が含まれています。これは古いアプリケーションのインスタンスに関連付けられている<code>ContextSelector</code>をデタッチするためだけに用意されたものです。<em>web.xml</em>に次のような設定を追加すれば有効になります。</p>
-
- <pre class="prettyprint source"><listener>
- <listener-class>ch.qos.logback.classic.selector.servlet.ContextDetachingSCL</listener-class>
-</listener></pre>
-
- <p>ほぼ全てのコンテナ実装は、web.xml に記載された順番でリスナーの<code>contextInitialized()</code>メソッドを呼び出します。ですが、<code>contextDestroyed()</code>メソッドの呼び出される順番は記載された順番の<span class="label notice">逆順</span>です。つまり、<em>web.xml</em>に複数の<code>ServletContextListener</code>を宣言している場合は、<code>ContextDetachingSCL</code>を<em>先頭</em>で宣言しなければならないということです。そうすれば、<code>contextDestroyed()</code>メソッドは<em>一番最後</em>に呼び出されるようになります。</p>
-
- <h3 class="doAnchor" name="betterPerf">パフォーマンスの改善</h3>
-
- <p><code>ContextJNDISelector</code>が有効になっていると、ロガーを取得するたびにJNDIの検索が行われるようになります。このことが、性能に悪影響を及ぼす可能性があります。特に静的変数ではない(インスタンス変数の)ロガーを使っている場合はその可能性は高まります。logbackの配布物には<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/selector/servlet/LoggerContextFilter.html">LoggerContextFilter</a>というサーブレットフィルターが含まれています。これはJNDIの検索にかかるコストを解消するために設計されたものです。web.xmlに次のような設定を追加すれば有効になります。
-</p>
-
- <pre class="prettyprint source"><filter>
- <filter-name>LoggerContextFilter</filter-name>
- <filter-class>ch.qos.logback.classic.selector.servlet.LoggerContextFilter</filter-class>
-</filter>
-<filter-mapping>
- <filter-name>LoggerContextFilter</filter-name>
- <url-pattern>/*</url-pattern>
-</filter-mapping></pre>
-
- <p>HTTPリクエストを受け付けたら、まず初めに<code>LoggerContextFilter</code>はアプリケーションに関連付けられたロガーコンテキストを取得して、<code>ThreadLocal</code>に保存します。<code>ContextJNDISelector</code>は、最初に<code>ThreadLocal</code>変数が設定されているかどうかをチェックします。設定されているときは、JNDIの検索をスキップします。HTTPリクエストの処理の最後に、<code>ThreadLocal</code>変数はnullにされるので気をつけてください。<code>LoggerContextFilter</code>を使うようにすると、ロギングの性能は大幅に改善します。
- </p>
-
- <p><code>ThreadLocal</code>の変数はnullになるので、アプリケーションがリサイクルされるときや停止するときのガベージコレクションでちゃんと回収されます。</p>
-
-
- <h2 class="doAnchor" name="tamingStaticRefs">共有ライブラリ内部の静的参照を飼いならす</h2>
-
- <p>全てのアプリケーションでSLF4Jとlogbackを共有しているとき、<code>ContextJNDISelector</code>を使うとうまくログを分離できます。<code>ContextJNDISelector</code>が有効なら、それぞれのアプリケーションの<code>LoggerFactory.getLogger()</code>メソッドの呼び出しは、アプリケーションに関連付けられたロガーコンテキストに割り当てられたロガーを返してくれます。</p>
-
- <p>静的変数としてロガーを参照するのが一般的なイディオムです。</p>
-
- <pre class="prettyprint source">public class Foo {
- <b>static</b> Logger logger = LoggerFactory.getLogger(Foo.class);
- ...
-}</pre>
-
- <p>静的変数でロガーを参照するのは、メモリとCPUのどちらにとっても効率的です。そのクラスの全てのインスタンスは、ただ一つの参照を使いまわせるからです。また、ロガーのインスタンスを取得するのは、クラスがメモリにロードされたときだけです。ロガー静的変数を持っているクラスが kenobi アプリケーションに含まれているなら、そのロガーのインスタンスは<code>ContextJNDISelector</code>から取得したkenobi用のロガーコンテキストに割り当てられることになります。同様に、別のアプリケーション yoda に含まれているクラスのロガーインスタンスは、やはり<code>ContextJNDISelector</code>から取得した yoda用のロガーコンテキストに割り当てられることになります。
- </p>
-
- <p>もし<em>kenobi</em>アプリケーションと<em>yoda</em>アプリケーションの両方で共有しているライブラリに含まれる<code>Mustafar</code>クラスだったら、ただし<code>Mustafar</code>クラスではインスタンス変数やローカル変数でロガーを参照していたらどうなるでしょうか。<code>LoggerFactory.getLogger()</code>メソッドは、それが呼ばれたアプリケーションに関連付けられたロガーコンテキストに割り当てられたロガーを返してくれるでしょう。しかし、<code>Mustafar</code>クラスが静的変数でロガーを参照していたらどうなるでしょう。その場合、最初にそのクラスを参照したアプリケーションに関連付けられたロガーコンテキストに割り当てられたロガーになってしまいます。つまり、<code>ContextJNDISelector</code>は、共有ライブラリのクラスが保持する静的変数のロガーについては、ログの分離ができないのです。このような状況は特に限定的なもので、長い間解決策 [...]
-
-
- <p>この問題を文句のつけようもないくらいに完全に解決するには、別の観点でロガーの内部事情に切り込まなければなりません。たとえば、ロガーは実際の仕事をするロガーを内包するものとして、ロガーに対するメッセージは内包するロガーに委譲するようにします。そして、内包されたロガーは適切なロガーコンテキストを参照するようにするのです。このアプローチは実装が大変だし、オーバーヘッドが非常に高くなってしまうでしょう。取りかかる気にはなれません。
- </p>
-
- <p>クラスの共有を止めて、アプリケーションの内部に移動してしまうのが、"共有クラスの静的ロガー"問題に対するお手軽な解決方法の1つであることは言うまでもありません。共有しないようにするのが不可能なら、<a href="http://logback.qos.ch/manual/appenders.html#SiftingAppender"><code>SiftingAppender</code></a>の魔法を使ってログの分離を実現するしかないでしょう。
- </p>
-
- <p>logbackの配布物には<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/sift/JNDIBasedContextDiscriminator.html">JNDIBasedContextDiscriminator</a>という弁別器が含まれています。これは<code>ContextJNDISelector</code>の返すロガーコンテキストの名前を返すものです。<code>SiftingAppender</code>と<code>JNDIBasedContextDiscriminator</code>を組み合わせると、アプリケーションごとに別々のアペンダーインスタンスを生成することができます。
- </p>
-
- <pre class="prettyprint source"><configuration>
-
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
-
- <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
- <discriminator class="ch.qos.logback.classic.sift.JNDIBasedContextDiscriminator">
- <defaultValue>unknown</defaultValue>
- </discriminator>
- <sift>
- <appender name="FILE-${contextName}" class="ch.qos.logback.core.FileAppender">
- <file><b>${contextName}.log</b></file>
- <encoder>
- <pattern>%-50(%level %logger{35}) cn=%contextName - %msg%n</pattern>
- </encoder>
- </appender>
- </sift>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SIFT" />
- </root>
-</configuration></pre>
-
-
- <p>kenobi と yoda というWebアプリケーションがあるとして、この設定ファイルを使うと yoda のログは <em>yoda.log</em>に、kenobi のログは<em>kenobi.log</em>に出力されるようになります。これは共有クラスの静的ロガーでも有効です。</p>
-
- <p><a href="http://github.com/ceki/logback-starwars">logback-starwars</a>プロジェクトを使えば、ここで説明したテクニックを実際に試してみることができます。
- </p>
-
-
- <p>上記のアプローチは、ログの分離問題を解決できますがかなり複雑です。適切な<code>ContextJNDISelector</code>の設定や、アペンダーを<code>SiftingAppender</code>でラップするこは、手傷を負った猛獣のように手が付けられません。
- </p>
-
- <p>それぞれのロギングコンテキストは、同じ設定ファイルでも、それぞれ別の設定ファイルでも設定できることを忘れないようにしましょう。選ぶのはあなたです。コンテキストごとに設定ファイルをメンテナンスするよりは、全て同じ設定ファイルを使うようにするほうが簡単です。アプリケーションごとに設定ファイルをメンテナンスするのは大変ですが、柔軟性はあります。</p>
-
- <p>これで終わりでしょうか?勝どきを上げて、気持ちよく我が家に帰れるのでしょうか?実はまだ続くんです。</p>
-
- <p><code>yoda</code>が<code>kenobi</code>より前に初期化されるとしましょう。<code>yoda</code>を初期化するため、<code>http://localhost:port/yoda/servlet</code>を参照して<code>YodaServlet</code>を呼び出します。このサーブレットは単に挨拶を返すだけです。ただし、ログを取得してから<code>Mustafar</code>の<code>foo()</code>メソッドを呼び出します。このメソッドは単純にログを取得するだけのものです。
- </p>
-
- <p><code>YodaServlet</code>が呼び出された後、<em>yoda.log</em>の内容は次のようになります。</p>
-
- <pre class="source">DEBUG ch.qos.starwars.yoda.YodaServlet cn=yoda - in doGet()
-DEBUG ch.qos.starwars.shared.Mustafar cn=yoda - in foo()</pre>
-
- <p>どちらのログも、"yoda"アプリケーションに関連付けられたロガーコンテキストによるものであることが分かりますか。ここからサーバーが停止するまで、<code>ch.qos.starwars.shared.Mustafar</code>のロガーは、"yoda"コンテキストに割り当てられたものになります。
- </p>
-
- <p><code>http://localhost:port/kenobi/servlet</code>にアクセスした後の<em>kenobi.log</em>の内容は次のようになります。</p>
-
- <pre class="source">DEBUG ch.qos.starwars.kenobi.KenobiServlet <b>cn=kenobi</b> - in doGet()
-DEBUG ch.qos.starwars.shared.Mustafar <b>cn=yoda</b> - in foo()</pre>
-
- <p>なんと、<code>ch.qos.starwars.shared.Mustafar</code>のロガーは<em>kenobi.log</em>に出力しているのに、"yoda"コンテキストに割り当てられているロガーのままです。つまり、別のロガーコンテキストに割り当てられたロガーが同じファイル(この場合は<em>kenobi.log</em>)に出力してしまうのです。それぞれのコンテキストが参照している<code>FileAppender</code>のインスタンスは、別々の<code>SiftingAppender</code>のインスタンスに内包されたもので、同じファイルにログを出力しています。ログの分離は思った通りに機能しているように見えますが、<span class="option">prudent</span>モードを有効化しない限り、FileAppender は同じファイルへのログの書き込みを安全に行うことができません。そうしないとファイルの内容が壊れてしまいます。</p>
-
- <p>prudent モードを有効にした設定ファイルを見てください。</p>
-
- <pre class="prettyprint source"><configuration>
-
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
-
- <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
- <discriminator class="ch.qos.logback.classic.sift.JNDIBasedContextDiscriminator">
- <defaultValue>unknown</defaultValue>
- </discriminator>
- <sift>
- <appender name="FILE-${contextName}" class="ch.qos.logback.core.FileAppender">
- <file>${contextName}.log</file>
- <b><prudent>true</prudent></b>
- <encoder>
- <pattern>%-50(%level %logger{35}) cn=%contextName - %msg%n</pattern>
- </encoder>
- </appender>
- </sift>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SIFT" />
- </root>
-</configuration></pre>
-
-
- <p>ここまでの議論を読み解いてきて、その上で logback-starwars プロジェクトを試してみたのなら、きっともうロギングのことが頭から離れなくなっていると思います。これ以上のことは<a href="http://www.qos.ch/shop/products/professionalSupport">専門家の助け</a>を借りるしかないでしょう。</p>
-
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-
- </body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/mdc.html b/logback-site/src/site/pages/manual/mdc.html
index 450548e..b7013e8 100644
--- a/logback-site/src/site/pages/manual/mdc.html
+++ b/logback-site/src/site/pages/manual/mdc.html
@@ -28,8 +28,6 @@
<h1>Chapter 8: Mapped Diagnostic Context</h1>
- <a href="mdc_ja.html">和訳 (Japanese translation)</a>
-
<div class="quote">
<p><em>Lock the doors.</em></p>
<p>—LEROY CAIN, Flight Director, Columbia Mission Control</p>
@@ -676,15 +674,6 @@ public class UserServletFilter implements Filter {
</tr>
<tr class="alt">
- <td><code>req.method</code></td>
- <td>
- as returned by <a
- href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletRequest.html#getMethod%28%29">getMethod()</a>
- method
- </td>
- </tr>
-
- <tr>
<td><code>req.requestURI</code></td>
<td>
as returned by <a
@@ -693,7 +682,7 @@ public class UserServletFilter implements Filter {
</td>
</tr>
- <tr class="alt">
+ <tr >
<td><code>req.requestURL</code></td>
<td>
as returned by <a
@@ -702,7 +691,7 @@ public class UserServletFilter implements Filter {
</td>
</tr>
- <tr>
+ <tr class="alt">
<td><code>req.queryString</code></td>
<td>
as returned by <a
@@ -710,7 +699,7 @@ public class UserServletFilter implements Filter {
</td>
</tr>
- <tr class="alt">
+ <tr>
<td><code>req.userAgent</code></td>
<td>value of the "User-Agent" header
</td>
diff --git a/logback-site/src/site/pages/manual/mdc_ja.html b/logback-site/src/site/pages/manual/mdc_ja.html
deleted file mode 100644
index edcfc4b..0000000
--- a/logback-site/src/site/pages/manual/mdc_ja.html
+++ /dev/null
@@ -1,542 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第8章 診断コンテキスト</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第8章 診断コンテキスト</h1>
-
- <div class="quote">
- <p><em>ドアを閉めなさい</em></p>
- <p>—LEROY CAIN, Flight Director, Columbia Mission Control</p>
- </div>
-
- <script src="../templates/creative.js" type="text/javascript"></script>
-
- <p>logbackの設計目標の1つとして、複雑な分散アプリケーションの監査とデバッグに使うことがあります。現実世界のほとんどの分散型システムは、同時に複数のクライアントの相手をしなければなりません。こういうシステムの典型的なマルチスレッドの実装は、スレッドが別々のクライアントを処理するものです。それぞれのクライアントに対するログ出力を分離するために実際に行われているアプローチは、クライアントごとに新しいロガーを用意するという少々残念なものです。このやり方ではやたらめったらロガーを生成することになりますし、管理のためのオーバーヘッドも馬鹿になりません。
- </p>
-
- <script src="../templates/setup.js" type="text/javascript"></script>
-
-
- <p>もう少し軽めのやり方としては、リクエストを受け付けたクライアントの固有の情報をログに出力する方法があります。この方法は書籍「Patterns for Logging Diagnostic Messages in Pattern Languages of Program Design 3」(Addison-Wesley, 1997)でニール・ハリソンが紹介しています。logback が利用しているのはSLF4J API の診断コンテキスト(MDC)で、これはさっき紹介した技法を応用したものです。
- </p>
-
- <p>リクエストごとの固有の情報として、利用者はコンテキストの情報を<code>MDC</code>(Mapped Diagnostic Contextの略です)に設定します。MDCクラスの特筆すべき部分を紹介します。メソッドの完全な説明は<a href="http://www.slf4j.org/api/org/slf4j/MDC.html">MDCのjavadoc</a>を参照してください。
- </p>
-
-<pre class="prettyprint source">package org.slf4j;
-
-public class MDC {
- //Put a context value as identified by <em>key</em>
- //into the current thread's context map.
- <b>public static void put(String key, String val);</b>
-
- //Get the context identified by the <code>key</code> parameter.
- <b>public static String get(String key);</b>
-
- //Remove the context identified by the <code>key</code> parameter.
- <b>public static void remove(String key);</b>
-
- //Clear all entries in the MDC.
- <b>public static void clear();</b>
-}</pre>
-
- <p><code>MDC</code>クラスには静的メソッドしかありません。おかげで、開発者が<em>診断コンテキスト</em>に設定した情報は、logback のありとあらゆるコンポーネントから取得できるようになるのです。<code>MDC</code>はコンテキストの情報を<em>スレッドごとに</em>管理します。子スレッドは、親の診断コンテキストの<em>コピー</em>を自動的に継承します。普通なら、開発者はクライアントから受け付けた新しい要求の処理を始めるところで、クライアント識別子、IPアドレス、リクエストパラメーターなどの適切なコンテキスト情報を<code>MDC</code>に設定します。logback のコンポーネントがちゃんと設定されていれば、こういった情報は自動的にログ項目に含まれるようになります。
- </p>
-
- <p>logback-classic の MDC 実装は、値の書き込みが比較的穏やかに行われることを想定しているのでくれぐれも注意してください。</p>
-
- <p><code><a href="http://logback.qos.ch/xref/chapters/mdc/SimpleMDC.html">SimpleMDC</a></code>アプリケーションを使ってこの基本原則を説明しましょう。
- </p>
- <p class="example">例7.1:MDCの基本的な使い方(<a href="http://logback.qos.ch/xref/chapters/mdc/SimpleMDC.html">logback-examples/src/main/java/chapters/mdc/SimpleMDC.java</a>)</p>
-<pre class="prettyprint source">package chapters.mdc;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.MDC;
-
-import ch.qos.logback.classic.PatternLayout;
-import ch.qos.logback.core.ConsoleAppender;
-
-public class SimpleMDC {
- static public void main(String[] args) throws Exception {
-
- // You can put values in the MDC at any time. Before anything else
- // we put the first name
- MDC.put("first", "Dorothy");
-
- [ SNIP ]
-
- Logger logger = LoggerFactory.getLogger(SimpleMDC.class);
- // We now put the last name
- MDC.put("last", "Parker");
-
- // The most beautiful two words in the English language according
- // to Dorothy Parker:
- logger.info("Check enclosed.");
- logger.debug("The most beautiful two words in English.");
-
- MDC.put("first", "Richard");
- MDC.put("last", "Nixon");
- logger.info("I am not a crook.");
- logger.info("Attributed to the former US president. 17 Nov 1973.");
- }
-
- [ SNIP ]
-
-}</pre>
-
- <p>mainメソッドでは、まずキー<em>first</em>で値<em>Drothy</em>を<code>MDC</code>に設定します。<code>MDC</code>に指定するキーも値も利用者の自由です。同じキーで書き込むと前の値を上書きします。コード上ではlogbackの設定が行われているところです。</p>
-
- <p>簡潔にするため、logbackを<a href="http://github.com/qos-ch/logback/blob/master/logback-examples/src/main/java/chapters/mdc/simpleMDC.xml">simpleMDC.xml</a>で設定しているところは省略しました。設定ファイル中の該当する箇所は次のようになっています。
- </p>
-
- <pre class="prettyprint source"><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <layout>
- <Pattern><b>%X{first} %X{last}</b> - %m%n</Pattern>
- </layout>
-</appender></pre>
-
-
-
- <p><code>PatternLayout</code>の変換パターン文字列中の<em>%X変換指定子</em>の使い方を見てください。<em>%X変換指定子</em>二回登場しています。一つ目のキーには<em>first</em>、二つ目のキーには<em>last</em>を指定しています。<code>SimpleMDC.class</code>のロガーを取得した後で、MDCにキー<em>last</em>で値<em>Parker</em>を設定しています。それから、メッセージを変えて二回ロギング要求を発行しています。最後に、また別の値を<code>MDC</code>に設定してから、いくつかロギング要求を発行しています。SimpleMDCを実行すると次のような出力になります。</p>
-
-<div class="source"><pre>Dorothy Parker - Check enclosed.
-Dorothy Parker - The most beautiful two words in English.
-Richard Nixon - I am not a crook.
-Richard Nixon - Attributed to the former US president. 17 Nov 1973.</pre></div>
-
-
- <p><code>SimpleMDC</code>アプリケーションを見れば、logbackを適切に設定すると、<code>MDC</code>の値がどのようにレイアウトされて出力されるのかがわかります。また、<code>MDC</code>に設定された情報はロガーの呼び出し一度だけでなく、何度も利用できることがわかります。
- </p>
-
- <h3 class="doAnchor">応用</h3>
-
- <p>診断コンテキストが一番脚光を浴びるのはクライアント・サーバーアーキテクチャだ。一般的に、複数のクライアントはサーバ上の複数のスレッドで処理されます。しかし<code>MDC</code>クラスには静的メソッドしかないので、診断コンテキストはスレッドごとに管理するしかありません。つまり、サーバー上のスレッドそれぞれが<code>MDC</code>の分のコストを負うことになるのです。<code>MDC</code>の<code>put()</code>や<code>get()</code>ような操作は、<em>現在の</em>スレッドと子スレッドの<code>MDC</code>にしか影響しません。他のスレッドの<code>MDC</code>は影響を受けないのです。<code>MDC</code>の情報はスレッドごとに管理されているので、それぞれのスレッドは自分用の<code>MDC</code>を持っていることになります。したがって、開発者はスレッド安全性やスレッド間同期のことを考える必要はありません。<code>MDC</code>はそういったことを安全に [...]
- </p>
-
- <p>次の例は少し凝っています。クライアント・サーバ環境でどのように<code>MDC</code>を使うのか説明したものです。サーバーは例7.2の<code>NumberCrucher</code>インターフェイスを実装します。<code>The NumberCruncher</code>インターフェイスには、<code>factor()</code>というメソッドが1つあるだけです。クライアントは、RMIによってサーバアプリケーションの<code>factor()</code>メソッドを呼び出して、指定した整数の素因数を取得します。
- </p>
-
- <p class="example">例7.2:サービスインターフェイス(<a href="http://logback.qos.ch/xref/chapters/mdc/NumberCruncher.html">logback-examples/src/main/java/chapters/mdc/NumberCruncher.java</a>)</p>
-
-<pre class="prettyprint source">package chapters.mdc;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-/**
- * NumberCruncher factors positive integers.
- */
-public interface NumberCruncher extends Remote {
- /**
- * Factor a positive integer <code>number</code> and return its
- * <em>distinct</em> factor's as an integer array.
- * */
- int[] factor(int number) throws RemoteException;
-}</pre>
-
- <p>例7.3の<code>NumberCruncherServer</code>アプリケーションが<code>NumberCruncher</code>インターフェイスを実装しています。mainメソッドはlocalhost上でRMIレジストリを公開して、well-knownポートでリクエストを待ち受けます。
- </p>
-
- <p class="example">例7.3:サーバー実装(<a href="http://logback.qos.ch/xref/chapters/mdc/NumberCruncherServer.html">logback-examples/src/main/java/chapters/mdc/NumberCruncherServer.java</a>)</p>
-
-<pre class="prettyprint source">package chapters.mdc;
-
-import java.rmi.RemoteException;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.Vector;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.MDC;
-
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.core.joran.spi.JoranException;
-
-
-/**
- * A simple NumberCruncher implementation that logs its progress when
- * factoring numbers. The purpose of the whole exercise is to show the
- * use of mapped diagnostic contexts in order to distinguish the log
- * output from different client requests.
- * */
-public class NumberCruncherServer extends UnicastRemoteObject
- implements NumberCruncher {
-
- private static final long serialVersionUID = 1L;
-
- static Logger logger = LoggerFactory.getLogger(NumberCruncherServer.class);
-
- public NumberCruncherServer() throws RemoteException {
- }
-
- public int[] factor(int number) throws RemoteException {
- // The client's host is an important source of information.
- try {
- <b>MDC.put("client", NumberCruncherServer.getClientHost());</b>
- } catch (java.rmi.server.ServerNotActiveException e) {
- logger.warn("Caught unexpected ServerNotActiveException.", e);
- }
-
- // The information contained within the request is another source
- // of distinctive information. It might reveal the users name,
- // date of request, request ID etc. In servlet type environments,
- // useful information is contained in the HttpRequest or in the
- // HttpSession.
- <b>MDC.put("number", String.valueOf(number));</b>
-
- logger.info("Beginning to factor.");
-
- if (number <= 0) {
- throw new IllegalArgumentException(number +
- " is not a positive integer.");
- } else if (number == 1) {
- return new int[] { 1 };
- }
-
- Vector<Integer> factors = new Vector<Integer>();
- int n = number;
-
- for (int i = 2; (i <= n) && ((i * i) <= number); i++) {
- // It is bad practice to place log requests within tight loops.
- // It is done here to show interleaved log output from
- // different requests.
- logger.debug("Trying " + i + " as a factor.");
-
- if ((n % i) == 0) {
- logger.info("Found factor " + i);
- factors.addElement(new Integer(i));
-
- do {
- n /= i;
- } while ((n % i) == 0);
- }
-
- // Placing artificial delays in tight loops will also lead to
- // sub-optimal results. :-)
- delay(100);
- }
-
- if (n != 1) {
- logger.info("Found factor " + n);
- factors.addElement(new Integer(n));
- }
-
- int len = factors.size();
-
- int[] result = new int[len];
-
- for (int i = 0; i < len; i++) {
- result[i] = ((Integer) factors.elementAt(i)).intValue();
- }
-
- <b>// clean up
- MDC.remove("client");
- MDC.remove("number");</b>
-
- return result;
- }
-
- static void usage(String msg) {
- System.err.println(msg);
- System.err.println("Usage: java chapters.mdc.NumberCruncherServer configFile\n" +
- " where configFile is a logback configuration file.");
- System.exit(1);
- }
-
- public static void delay(int millis) {
- try {
- Thread.sleep(millis);
- } catch (InterruptedException e) {
- }
- }
-
- public static void main(String[] args) {
- if (args.length != 1) {
- usage("Wrong number of arguments.");
- }
-
- String configFile = args[0];
-
- if (configFile.endsWith(".xml")) {
- try {
- LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator configurator = new JoranConfigurator();
- configurator.setContext(lc);
- lc.reset();
- configurator.doConfigure(args[0]);
- } catch (JoranException je) {
- je.printStackTrace();
- }
- }
-
- NumberCruncherServer ncs;
-
- try {
- ncs = new NumberCruncherServer();
- logger.info("Creating registry.");
-
- Registry registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
- registry.rebind("Factor", ncs);
- logger.info("NumberCruncherServer bound and ready.");
- } catch (Exception e) {
- logger.error("Could not bind NumberCruncherServer.", e);
-
- return;
- }
- }
-}</pre>
-
- <p>特に大事なのが<code>factor(int number)</code>メソッドの実装です。最初に、<code>MDC</code>へキー<em>client</em>でクライアントのホスト名を設定しています。そして、クライアントから渡された素因数分解する数をキー<em>number</em>で<code>MDC</code>に設定します。計算が終わったらクライアントに結果を返します。ですが、結果を返す前に、キー<em>client</em>とキー<em>number</em>で設定された値をクリアするため、<code>MDC.remove()</code>メソッドを呼んでいます。普通なら<code>put()</code>操作と<code>remove()</code>操作が同じ数だけ登場するべきです。そうしないと、<code>MDC</code>に特定のキーの値が残ってしまうからです。出来る限り<code>remove()</code>操作をfinallyブロックで実行するように仕込んでおくことをおすすめします。確実に実行されることを保証するためです。
- </p>
-
- <p>理屈っぽい説明が続きましたが、cruncer アプリケーションを実行する準備が整いました。次のコマンドを実行してサーバーを起動しましょう。</p>
-
-<div class="source"><pre>java chapters.mdc.NumberCruncherServer src/main/java/chapters/mdc/mdc1.xml</pre></div>
-
- <p><em>mdc1.xml</em>の内容は次のとおりです。</p>
-
- <p class="example">例7.4:設定ファイル(<a href="http://logback.qos.ch/xref/chapters/mdc/mdc1.xml">logback-examples/src/main/java/chapters/mdc/mdc1.xml</a>)</p>
-
-<pre class="prettyprint source"><configuration>
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <layout>
- <Pattern>%-4r [%thread] %-5level <b>C:%X{client} N:%X{number}</b> - %msg%n</Pattern>
- </layout>
- </appender>
-
- <root level="debug">
- <appender-ref ref="CONSOLE"/>
- </root>
-</configuration></pre>
-
- <p><span class="option">パターン·</span>オプションに<em>%X変換指定子</em>が使われているのを見てください。
- </p>
-
- <p>次のコマンドで<code>NumberCruncherClient</code>アプリケーションを実行しましょう。</p>
-
-<div class="source"><pre>java chapters.mdc.NumberCruncherClient <em>hostname</em></pre></div>
-
- <p><em>hostname</em>の部分には<code>NumberCruncherServer</code>を実行しているサーバのホスト名を指定します。</p>
-
- <p>複数のクライアントを実行して、最初に起動したクライアントがサーバに129を要求して、その後すぐに二つ目のクライアントから71を要求したときのサーバ側のコンソールには、次のように出力されています。</p>
-
-<div class="source"><pre>
-<b>70984 [RMI TCP Connection(4)-192.168.1.6] INFO C:orion N:129 - Beginning to factor.</b>
-70984 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 2 as a factor.
-71093 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 3 as a factor.
-71093 [RMI TCP Connection(4)-192.168.1.6] INFO C:orion N:129 - Found factor 3
-71187 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 4 as a factor.
-71297 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 5 as a factor.
-71390 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 6 as a factor.
-<b>71453 [RMI TCP Connection(5)-192.168.1.6] INFO C:orion N:71 - Beginning to factor.</b>
-71453 [RMI TCP Connection(5)-192.168.1.6] DEBUG C:orion N:71 - Trying 2 as a factor.
-71484 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 7 as a factor.
-71547 [RMI TCP Connection(5)-192.168.1.6] DEBUG C:orion N:71 - Trying 3 as a factor.
-71593 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 8 as a factor.
-71656 [RMI TCP Connection(5)-192.168.1.6] DEBUG C:orion N:71 - Trying 4 as a factor.
-71687 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 9 as a factor.
-71750 [RMI TCP Connection(5)-192.168.1.6] DEBUG C:orion N:71 - Trying 5 as a factor.
-71797 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 10 as a factor.
-71859 [RMI TCP Connection(5)-192.168.1.6] DEBUG C:orion N:71 - Trying 6 as a factor.
-71890 [RMI TCP Connection(4)-192.168.1.6] DEBUG C:orion N:129 - Trying 11 as a factor.
-71953 [RMI TCP Connection(5)-192.168.1.6] DEBUG C:orion N:71 - Trying 7 as a factor.
-72000 [RMI TCP Connection(4)-192.168.1.6] INFO C:orion N:129 - Found factor 43
-72062 [RMI TCP Connection(5)-192.168.1.6] DEBUG C:orion N:71 - Trying 8 as a factor.
-72156 [RMI TCP Connection(5)-192.168.1.6] INFO C:orion N:71 - Found factor 71</pre></div>
-
- <p>クライアントは<em>orion</em>というホスト名のマシンで実行されていることがわかります。サーバーがほぼ同時に別のスレッドでクライアントの要求を処理する場合でも、それぞれのクライアントからのリクエストによるログ出力は、<code>MDC</code>の出力を見れば分かるようになっています。たとえば、<em>number</em>として印付けられた素因数分解する数です。
- </p>
-
- <p>注意深い人なら、スレッド名を見るだけでもリクエストを区別できることが分かるでしょう。サーバ側の実装がスレッドを再利用するようになっていると混乱させられるかもしれません。そうなってしまったら、いつリクエストを受け付けて、いつ応答を返したのかを特定するのは難しいかもしれません。<code>MDC</code>を管理するのはアプリケーション開発者なので、そういった問題が起きることはありません。
- </p>
-
-
-
- <h3 class="doAnchor" name="autoMDC"><code>MDC</code>への自動的なアクセス</h3>
-
- <p>これまでに見てきたように、<code>MDC</code>があると複数のクライアントの相手をするとき便利です。ユーザー認証のあるWebアプリケーションなら、<code>MDC</code>にユーザー名を設定して、ログアウトするときにそれを削除するようにしておくのが、1つの簡単なソリューションになるでしょう。残念ながら、そのテクニックを使っていても常に確実な結果を得られるわけではありません。<code>MDC</code>がスレッド毎にデータを管理している限り、サーバがスレッドをリサイクするようになっていると、間違った情報が設定されていることがあるかもしれません。</p>
-
- <p>リクエストを処理するとき、いつでも<code>MDC</code>に正しい情報が設定されていることを確実にするためにできるのは、処理の始めにユーザー名を設定して、処理の終わりに削除することです。こういう場合サーブレット<code><a href="http://java.sun.com/javaee/5/docs/api/javax/servlet/Filter.html">Filter</a></code>を使うとよいでしょう。
- </p>
-
- <p>サーブレットフィルターの<code>doFilter()</code>メソッドで、リクエストに関連する情報(cookieも)を集めて、それを<code>MDC</code>に設定するのです。他のフィルターで行う後続処理やサーブレットからは、自動的に今設定したばかりのMDCの情報を参照することができます。最後にまたサーブレットフィルターが仕事をするとき、MDCに設定した内容を削除することができます。
- </p>
-
- <p>フィルターの実装例を見てみましょう。</p>
-
- <p class="example">例7.5:ユーザー名サーブレットフィルター(<a href="http://logback.qos.ch/xref/chapters/mdc/UserServletFilter.html">logback-examples/src/main/java/chapters/mdc/UserServletFilter.html</a>)</p>
-
-<pre class="prettyprint source">package chapters.mdc;
-
-import java.io.IOException;
-import java.security.Principal;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-
-import org.slf4j.MDC;
-
-public class UserServletFilter implements Filter {
-
- private final String USER_KEY = "username";
-
- public void destroy() {
- }
-
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
-
- boolean successfulRegistration = false;
-
- HttpServletRequest req = (HttpServletRequest) request;
- Principal principal = req.getUserPrincipal();
- // Please note that we could have also used a cookie to
- // retrieve the user name
-
- if (principal != null) {
- String username = principal.getName();
- successfulRegistration = registerUsername(username);
- }
-
- try {
- chain.doFilter(request, response);
- } finally {
- if (successfulRegistration) {
- MDC.remove(USER_KEY);
- }
- }
- }
-
- public void init(FilterConfig arg0) throws ServletException {
- }
-
-
- /**
- * Register the user in the MDC under USER_KEY.
- *
- * @param username
- * @return true id the user can be successfully registered
- */
- private boolean registerUsername(String username) {
- if (username != null && username.trim().length() > 0) {
- MDC.put(USER_KEY, username);
- return true;
- }
- return false;
- }
-}</pre>
-
- <p><code>doFilter()</code>メソッドが呼ばれたら、最初にリクエストオブジェクトから<code>java.security.Principal</code>オブジェクトを取得します。このオブジェクトからは、現在認証されているユーザーのユーザー名を取得することができます。ユーザー情報があったらそれを<code>MDC</code>に設定します。</p>
-
- <p>フィルターチェインが完了すると、フィルターでは<code>MDC</code>からユーザー情報を削除します。</p>
-
- <p>ここで紹介したやり方は、スレッドがリクエストを処理している間だけMDCに値を設定するものです。他のスレッドは影響を受けません。さらに、あらゆるスレッドが、任意の時点で正確なMDCデータを持つようになります。</p>
-
-
-
- <h3 class="doAnchor" name="managedThreads">MDCおよび管理スレッド</h3>
-
- <p>ワーカースレッドが自身を初期化するとき、どんなときでも診断コンテキストを継承するわけではありません。これは<code>java.util.concurrent.Executors</code>がスレッドを管理しているときに発生します。例えば、 <code>newCachedThreadPool</code>は<code>ThreadPoolExecutor</code>オブジェクトを作成しますが、他のスレッドプールを生成するコードでも、スレッドの生成は複雑なロジックになっています。
- </p>
-
- <p>そういう場合、元のスレッド(master)でタスクをエグゼキューターに渡す前に、<code>MDC.getCopyOfContextMap()</code>メソッドを呼ぶようにするとよいでしょう。タスクが実行されるとき、まず最初に<code>MDC.setContextMapValues()</code>メソッドを呼ぶようにするべきです。そうすると新しい<code>Executor</code>のスレッドに、元のMDCの値を関連付けることができます。
- </p>
-
- <h3 class="doAnchor" name="mis">MDCInsertingServletFilter</h3>
-
- <p>Webアプリケーションでは、受け付けたHTTPリクエストに関連するホスト名、リクエストURI、ユーザーエージェント文字列などがわかるようになっていると便利なのはよくご存知だと思います。<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/helpers/MDCInsertingServletFilter.html"><code>MDCInsertingServletFilter</code></a>はMDCに次のようなキーと値を設定します。
- </p>
-
- <table class="bodyTable">
- <tr>
- <th>キー</th>
- <th>値</th>
- </tr>
-
- <tr class="alt">
- <td><code>req.remoteHost</code></td>
- <td><a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/ServletRequest.html#getRemoteHost%28%29">getRemoteHost()</a>メソッドの返すホスト名</td>
- </tr>
-
- <tr>
- <td><code>req.xForwardedFor</code></td>
- <td><a href="http://en.wikipedia.org/wiki/X-Forwarded-For">"X-Forwarded-For"</a>ヘッダーの値</td>
- </tr>
-
- <tr class="alt">
- <td><code>req.requestURI</code></td>
- <td><a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletRequest.html#getRequestURI%28%29">getRequestURI()</a>メソッドの返すリクエストURI</td>
- </tr>
-
- <tr>
- <td><code>req.requestURL</code></td>
- <td><a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletRequest.html#getRequestURL%28%29">getRequestURL()</a>メソッドの返すリクエストURL</td>
- </tr>
-
- <tr class="alt">
- <td><code>req.queryString</code></td>
- <td><a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletRequest.html#getQueryString%28%29">getQueryString()</a>メソッドの返すクエリ文字列</td>
- </tr>
-
- <tr>
- <td><code>req.userAgent</code></td>
- <td>"User-Agent" ヘッダーの値</td>
- </tr>
-
- </table>
-
- <p><code>MDCInsertingServletFilter</code>を使用するには、Webアプリケーションの<em>web.xml</em>に次の設定を追加します。</p>
-
- <pre class="prettyprint source"><filter>
- <filter-name>MDCInsertingServletFilter</filter-name>
- <filter-class>
- ch.qos.logback.classic.helpers.MDCInsertingServletFilter
- </filter-class>
-</filter>
-<filter-mapping>
- <filter-name>MDCInsertingServletFilter</filter-name>
- <url-pattern>/*</url-pattern>
-</filter-mapping> </pre>
-
- <p><b>複数のフィルターを使用している場合、<code>MDCInsertingServletFilter</code>を他のフィルターより先に宣言するようにしてください。</b> たとえば、アプリケーションの主な処理がフィルター'F'で行われるとしたら、その前に<code>MDCInsertingServletFilter</code>を置かないと、MDCに設定される値を'F'から参照することはできません。
- </p>
-
- <p>フィルターを配置したら、上記のMDCのキーを%X変換指定子で使えるようになります。例えば、リモートホストとリクエストURIを一行に出したければ、次のような変換パターン文字列を指定すればよいでしょう。</p>
-
- <p class="source">%X{req.remoteHost} %X{req.requestURI}%n%d - %m%n</p>
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/menu.js b/logback-site/src/site/pages/manual/menu.js
index 7071c5a..972dcb7 100644
--- a/logback-site/src/site/pages/manual/menu.js
+++ b/logback-site/src/site/pages/manual/menu.js
@@ -15,17 +15,3 @@ document.write('<p class="menu"><a href="groovy.html"><b>Ch12: Groovy Configurat
document.write('<p class="menu"><a href="migrationFromLog4j.html"><b>Ch13: Migration from log4j</b></a></p>');
document.write('<p class="menu"><a href="receivers.html"><b>Ch14: Receivers</b></a></p>');
document.write('<p class="menu"><a href="usingSSL.html"><b>Ch15: Using SSL</b></a></p>');
-
-document.write('<p style="border: 1px solid #cccccc;"></p>');
-document.write('<p style="border: 1px solid #cccccc;"></p>');
-document.write('<p/>');
-document.write('<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>');
-//<!-- logback -->
-document.write('<ins class="adsbygoogle"');
-document.write(' style="display:block"');
-document.write(' data-ad-client="ca-pub-7471410671306824"');
-document.write(' data-ad-slot="6377851613"');
-document.write(' data-ad-format="auto"></ins>');
-document.write('<script>');
-document.write('(adsbygoogle = window.adsbygoogle || []).push({});');
-document.write('</script>');
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/menu_ja.js b/logback-site/src/site/pages/manual/menu_ja.js
deleted file mode 100644
index 529072d..0000000
--- a/logback-site/src/site/pages/manual/menu_ja.js
+++ /dev/null
@@ -1,16 +0,0 @@
-document.write('<p class="menu_header">目次</p>');
-document.write('<p class="menu"><a href="introduction_ja.html"><b>第1章 はじめに</b></a></p>');
-document.write('<p class="menu"><a href="architecture_ja.html"><b>第2章 アーキテクチャ</b></a></p>');
-document.write('<p class="menu"><a href="configuration_ja.html"><b>第3章 設定</b></a></p>');
-document.write('<p class="menu"><a href="appenders_ja.html"><b>第4章 アペンダー</b></a></p>');
-document.write('<p class="menu"><a href="encoders_ja.html"><b>第5章 エンコーダー</b></a></p></p>');
-document.write('<p class="menu"><a href="layouts_ja.html"><b>第6章 レイアウト</b></a></p>');
-document.write('<p class="menu"><a href="filters_ja.html"><b>第7章 フィルター</b></a></p>');
-document.write('<p class="menu"><a href="mdc_ja.html"><b>第8章 診断コンテキスト(MDC)</b></a></p>');
-document.write('<p class="menu"><a href="loggingSeparation_ja.html"><b>第9章 ログの分離</b></a></p>');
-document.write('<p class="menu"><a href="jmxConfig_ja.html"><b>第10章 JMXコンフィギュレーター</b></a></p>');
-document.write('<p class="menu"><a href="onJoran_ja.html"><b>第11章 Joran</b></a></p>');
-document.write('<p class="menu"><a href="groovy_ja.html"><b>第12章 Groovyによる設定</b></a></p>');
-document.write('<p class="menu"><a href="migrationFromLog4j_ja.html"><b>第13章 log4jから移行する</b></a></p>');
-document.write('<p class="menu"><a href="receivers_ja.html"><b>第14章 レシーバー</b></a></p>');
-document.write('<p class="menu"><a href="usingSSL_ja.html"><b>第15章 SSLを使用する</b></a></p>');
diff --git a/logback-site/src/site/pages/manual/migrationFromLog4j.html b/logback-site/src/site/pages/manual/migrationFromLog4j.html
index 4b05556..96fef84 100644
--- a/logback-site/src/site/pages/manual/migrationFromLog4j.html
+++ b/logback-site/src/site/pages/manual/migrationFromLog4j.html
@@ -28,8 +28,6 @@
<h1>Chapter 13: Migration from log4j</h1>
- <a href="migrationFromLog4j_ja.html">和訳 (Japanese translation)</a>
-
<div class="quote">
<p><em>The more things change, the more they remain the
same. </em></p>
diff --git a/logback-site/src/site/pages/manual/migrationFromLog4j_ja.html b/logback-site/src/site/pages/manual/migrationFromLog4j_ja.html
deleted file mode 100644
index 5226e0e..0000000
--- a/logback-site/src/site/pages/manual/migrationFromLog4j_ja.html
+++ /dev/null
@@ -1,157 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第13章 log4jからの移行</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第13章 log4jからの移行</h1>
-
- <div class="quote">
- <p><em>多くのものが変化し、多くのものがそのままである。</em></p>
-
- <p>—ALPHONSE KARR, <em>Les Guêpes</em></p>
- </div>
-
- <p>本章ではカスタマイズされたlog4jのコンポーネントのアペンダーやレイアウトをlogback-classicに移行する方法について議論します。
- </p>
-
- <p>log4j のクライアントAPIとして<code>org.apache.log4j</code>パッケージの<code>Logger</code>や<code>Category</code>を使っているだけなら、SLF4Jの<a href="http://www.slf4j.org/migrator.html">SLF4J移行ツール</a>で自動的に移行することができます。<em>log4j.properties</em>から同じ内容のlogback.xmlを作るには、<a href="http://logback.qos.ch/translator/">log4j.properties トランスレーター</a>が使えます。
- </p>
-
- <p>広い観点から見ると、log4jとlogback-classicは密接に関連し合っています。ロガーやアペンダー、レイアウトといった基本的なコンポーネントはどちらのフレームワークにもありますし、目的も同じです。同様に、どちらのフレームワークにも一番重要な内部データ構造として<code>LoggingEvent</code>がありますが、実装まで完全に同じわけではありません。一番の違いは、logback-classic の<code>LoggingEvent</code>は<code>ILoggingEvent</code>インターフェイスを実装しているところです。log4jのコンポーネントをlogback-classicに移行するために必要な変更のほとんどは、<code>LoggingEvent</code>の実装の差異を埋めることに費やされます。差異があるといってもその範囲は限られているので安心してください。出来る限りの努力をしたにも関わらず移行がうまくいかなかったら、<a href="http://logback.qos.ch/mailinglist.ht [...]
- </p>
-
-
- <h3 class="doAnchor" name="log4jLayout">log4jのレイアウトを移行する</h3>
-
- <p>さあ移行してみましょう。対象はlog4j の単純なレイアウト<a href="http://logback.qos.ch/xref/chapters/migrationFromLog4j/TrivialLog4jLayout.html">TrivialLog4jLayout</a>ということにします。これはロギングイベントのメッセージを指定された書式で書式化した文字列を返すものです。コードを見てください。
- </p>
-
-
- <pre class="prettyprint source">package chapters.migrationFromLog4j;
-
-import org.apache.log4j.Layout;
-import org.apache.log4j.spi.LoggingEvent;
-
-public class TrivialLog4jLayout extends Layout {
-
- public void activateOptions() {
- // there are no options to activate
- }
-
- public String format(LoggingEvent loggingEvent) {
- return loggingEvent.getRenderedMessage();
- }
-
- public boolean ignoresThrowable() {
- return true;
- }
-}</pre>
-
- <p>logback-classicで等価なレイアウト<a href="http://logback.qos.ch/xref/chapters/migrationFromLog4j/TrivialLogbackLayout.html">TrivialLogbackLayout</a>は次のようになります。</p>
-
- <pre class="prettyprint source">package chapters.migrationFromLog4j;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.LayoutBase;
-
-public class TrivialLogbackLayout extends <b>LayoutBase<ILoggingEvent></b> {
-
- public String <b>doLayout</b>(ILoggingEvent loggingEvent) {
- return loggingEvent.getMessage();
- }
-} </pre>
-
- <p>ご覧のように、文字列を書式化するメソッドはlog4jでは<code>format()</code>でしたが、logback-classic では<code>doLayout()</code>なのです。また、logback-classic には<code>ignoresThrowable()</code>に相当するメソッドはありません。logback-classicのレイアウトは<code>LayoutBase<ILoggingEvent></code>を継承しなければならないので気をつけてください。
- </p>
-
- <p><code>activateOptions()</code>メソッドの効果については大いに議論の余地があります。log4jでは、log4j configurator(<code>PropertyConfigurator</code>あるいは<code>DOMConfiguration</code>) から、レイアウトの全てのオプションが設定された後に<code>activateOptions()</code>メソッドが呼ばれるようになっています。したがって、レイアウトには自分に指定されたオプションの整合性をチェックするタイミングが無いので、全て自分で賄わなければなりません。</p>
-
-
- <p>logback-classic では、レイアウトは<a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/LifeCycle.html">LifeCycle</a>インターフェイスを実装しなければなりません。このインターフェイスには<code>start()</code>メソッドがあります。この<code>start()</code>メソッドは、log4jの<code>activateOptions()</code>メソッドとほぼ同様の役割を果たします。
- </p>
-
- <h3 class="doAnchor" name="log4jAppender">log4jのアペンダーを移行する</h3>
-
- <p>アペンダーの移行は、レイアウトの移行とほとんど同じです。単純なアペンダー<a href="http://logback.qos.ch/xref/chapters/migrationFromLog4j/TrivialLog4jAppender.html">TrivialLog4jAppender</a>を移行することを考えてみましょう。このアペンダーはレイアウトの返す文字列をコンソールに出力するだけのものです。</p>
-
- <pre class="prettyprint source">package chapters.migrationFromLog4j;
-
-import org.apache.log4j.AppenderSkeleton;
-import org.apache.log4j.spi.LoggingEvent;
-
-
-public class TrivialLog4jAppender extends AppenderSkeleton {
-
- protected void append(LoggingEvent loggingevent) {
- String s = this.layout.format(loggingevent);
- System.out.println(s);
- }
-
- public void close() {
- // nothing to do
- }
-
- public boolean requiresLayout() {
- return true;
- }
-}</pre>
-
- <p>logback-classicで等価なアペンダー<a href="http://logback.qos.ch/xref/chapters/migrationFromLog4j/TrivialLogbackAppender.html">TrivialLogbackAppender</a>は次のようになります。</p>
-
-
- <pre class="prettyprint source">package chapters.migrationFromLog4j;
-
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.AppenderBase;
-
-public class TrivialLogbackAppender extends AppenderBase<ILoggingEvent> {
-
- @Override
- public void start() {
- if (this.layout == null) {
- addError("No layout set for the appender named [" + name + "].");
- return;
- }
- super.start();
- }
-
- @Override
- protected void append(ILoggingEvent loggingevent) {
- // note that AppenderBase.doAppend will invoke this method only if
- // this appender was successfully started.
-
- String s = this.layout.doLayout(loggingevent);
- System.out.println(s);
- }
-}</pre>
-
-
- <p>コードを比べてみると分かるのですが、<code>append()</code>メソッドはそのままです。logbackでは<code>requiresLayout()</code>メソッドを使用しないので、これは削除できます。logbackの<code>stop()</code>メソッドは、log4jの<code>close()</code>メソッドと同じ意味です。logback-classicの<code>AppenderBase</code>には何もしない<code>stop()</code>メソッドの実装があるので、今回のように単純なアペンダーならそれで十分でしょう。
- </p>
-
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/onJoran.html b/logback-site/src/site/pages/manual/onJoran.html
index 269dac4..c5183ae 100644
--- a/logback-site/src/site/pages/manual/onJoran.html
+++ b/logback-site/src/site/pages/manual/onJoran.html
@@ -28,8 +28,6 @@
<h1>Chapter 11: Joran</h1>
- <a href="onJoran_ja.html">和訳 (Japanese translation)</a>
-
<div class="quote">
<p><em>The answer, my friend, is blowin' in the wind, The answer
is blowin' in the wind.</em></p>
@@ -186,10 +184,9 @@
<pre class="prettyprint source">package ch.qos.logback.core.joran.action;
import org.xml.sax.Attributes;
-import org.xml.sax.Locator;
-import ch.qos.logback.core.joran.spi.InterpretationContext;
+import ch.qos.logback.core.joran.spi.ExecutionContext;
-public abstract class Action extends ContextAwareBase {
+public abstract class Action {
/**
* Called when the parser encounters an element matching a
* {@link ch.qos.logback.core.joran.spi.Pattern Pattern}.
diff --git a/logback-site/src/site/pages/manual/onJoran_ja.html b/logback-site/src/site/pages/manual/onJoran_ja.html
deleted file mode 100644
index 6712fff..0000000
--- a/logback-site/src/site/pages/manual/onJoran_ja.html
+++ /dev/null
@@ -1,433 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第11章 Joran</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第11章 Joran</h1>
-
- <div class="quote">
- <p><em>答えは風に吹かれている。答えは風に吹かれている。</em></p>
-
- <p>—BOB DYLAN, <em>The Freewheelin' Bob Dylan</em></p>
- </div>
-
- <p>Joranとは、ジュネーブ湖で一年中吹きすさんでいる冷たい北西風のことです。ジュネーブ湖は西ヨーロッパの中央からやや右側にある湖で、ヨーロッパにいくつもある他の湖と比べるとずっと狭い湖です。しかし、平均水深は153メートルと非常に深く、西ヨーロッパ最大の淡水湖として知られています。
- </p>
-
-
- <p>これまでの章で説明したように、logbackはJoran設定フレームワークの成熟した、柔軟で、強力な機能を頼りにしています。logbackのモジュールが提供する機能の大部分は、Joran無しでは実現できません。この章では、Joranの設計の根幹部分と、顕著な特徴に焦点を当てていきます。
- </p>
-
- <p>Joranはロギングとは完全に無関係な、汎用設定システムです。この点を明らかにするため、logback-coreモジュールにはロガーに関わる要素が一切存在しないことに触れておかなければなりません。また、本章に登場するほとんどの例に、ロガーもアペンダーもレイアウトも出てこないこともそれを後押ししています。
- </p>
-
- <p>この章で使っている例は<em>LOGBACK_HOME/logback-examples/src/main/java/chapters/onJoran</em>に配置されています。
- </p>
-
- <p>Joranのインストールは簡単です。<a href="http://logback.qos.ch/download.html">logbackをダウンロード</a>して、クラスパスに<em>logback-core-1.1.2.jar</em>を追加するだけです。</p>
-
- <h2 class="doAnchor">歴史的な観点</h2>
-
- <p>リフレクションは、宣言的にソフトウェアシステムを設定できるようにしてくれる、Java言語の強力な機能です。たとえば、EJBの重要なプロパティの多くは<em>ejb.xml</em>で設定します。EJBがJavaで実装されているとしても、それらのプロパティのほとんどが<em>ejb.xml</em>で指定されるのです。同じように、logbackの設定もXML形式の設定ファイルで指定します。JDK1.5から導入されたアノテーションは、以前ならXMLで設定されていたものを置き換えるためにEJB3.0で多用されています。Joranもアノテーションは利用しますが、ほんの少しだけです。EJBに比べてlogbackの設定には動的な要素が多いので、Joranでアノテーションを活用できる範囲が限られてしまうのです。
- </p>
-
- <p>logbackの前身のlog4jでは、<code>DOMConfigurator</code>(log4j1.2.x以降に含まれています)がXML形式の設定ファイルをパースするために使われていました。<code>DOMConfigurator</code>は、設定ファイルの構造を変えるたびに、コードを微調整しなければならない作りになっていました。修正したコードは、再コンパイルして再デプロイしなければなりません。同じくらい重要なのが、<code>DOMConfigurator</code>のコードは、たくさんのまばらなif/else文を含む子要素をループするような作りになっていたことです。たいして役に立ちませんでしたし、冗長であちこちに重複があるコードでした。このとき、<a href="http://jakarta.apache.org/commons/digester/">Apace commons-digester</a>ではパターンマッチ規則に基づいたXMLのパースができていました。digesterは、パース時に指定したパターンにマッチしたら、こちらも [...]
- </p>
-
- <p>私たちは<code>DOMConfigurator</code>の経験を武器にしてlogbackで使うための設定フレームワーク<code>Joran</code>の開発を始めました。Joranはcommons-digesterに強く影響を受けています。にもかかわらず、使っている用語が若干異なります。たとえば、commons-digester だとルールとパターンは一緒に使うものでした。Digesterの<code>addRule(String pattern, Rule rule)</code>メソッドがいい例です。私たちは、ルールがルールによって構成されている(再帰的という意味ではなく別の意味で)と、不必要な混乱を招くことに気づきました。そこで、Joranではルールがパターンとアクションで構成されるものとしました。アクションとは、対応するパターンがマッチしたときに行われる操作です。パターンとアクションの関係が、Joranの中核を為していると言ってもおかしくありません。それが顕著にあらわれているのが、単純なパターンを使って非常に複雑な要件を満たすことができ [...]
- </p>
-
- <h3 class="doAnchor" name="saxOrDom">SAXかDOMか</h3>
-
- <p>SAXのAPIはイベントベースのアーキテクチャなので、SAXをベースにしたツールで前方参照を扱うのは決して簡単なことではありません。前方参照とは、現在の要素よりも後で定義される要素を参照することです。同様に循環参照も手強い相手です。一般的な話ですが、DOM APIなら全要素を検索対象にできるし、前方の要素にジャンプすることもできるのです。
- </p>
-
- <p>こういった柔軟性についてのあれこれを鑑みて、Joranでは当初DOM APIを使ってパースしていました。試行錯誤の後、パターンとアクションの形式で表現されたルールを解釈する上で、DOMツリーをパースしてる途中で離れた要素にジャンプできても意味が無いことが明らかになりました。<em>Joranに必要だったのは、XMLドキュメントの要素を、深さ優先で逐次的に走査していくことだけだったのです。</em>
- </p>
-
- <p>また、SAX APIには要素の位置を取得するものがあったので、Joranは問題のあった行番号と列番号を表示できるようにもなりました。位置情報があれば、パースエラーの起きている場所を簡単に特定することができます。
- </p>
-
- <h3>対象外事項</h3>
-
- <p>高度な可変性を求められていることもあり、JoranのAPIは数千要素にもなる巨大なXMLドキュメントを扱うようには設計されていません。
- </p>
-
-
- <h3 class="doAnchor" name="pattern">パターン</h3>
-
- <p>Joranのパターンとは基本的に文字列です。<em>正確なパターン</em>と<em>ワイルドカードパターン</em>の2種類があります。パターン"a/b" は、最上位要素<code>a</code>にネストされた要素<code>b</code>にマッチします。他の要素にはマッチしないことから、これは<em>正確なパターン</em>だと言えます。</p>
-
- <p>ワイルドカードは、接尾辞または接頭辞をマッチさせるときに使われます。たとえばパターン"*/a" は接尾辞が"a"であるものすべてにマッチします。つまり、XMLドキュメント中で要素<code>a</code>をネストしているあらゆる要素がマッチするのです。パターン"a/*"は接頭辞が"a"なので、要素<code>a</code>がネストしているあらゆる要素がマッチすることになります。
- </p>
-
- <h3 class="doAnchor" name="action">アクション</h3>
-
- <p>前に述べたように、Joranはパターンに関連付けられたルールをパースします。アクションは、<a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/action/Action.html"><code>Action</code></a>クラスを継承したもので、次のような抽象メソッドで肉付けします。他のメソッドは簡潔にするために省略されています。
- </p>
-
-
- <pre class="prettyprint source">package ch.qos.logback.core.joran.action;
-
-import org.xml.sax.Attributes;
-import ch.qos.logback.core.joran.spi.ExecutionContext;
-
-public abstract class Action {
- /**
- * Called when the parser encounters an element matching a
- * {@link ch.qos.logback.core.joran.spi.Pattern Pattern}.
- */
- public abstract void begin(InterpretationContext ic, String name,
- Attributes attributes) throws ActionException;
-
- /**
- * Called to pass the body (as text) contained within an element.
- */
- public void body(InterpretationContext ic, String body)
- throws ActionException {
- // NOP
- }
-
- /*
- * Called when the parser encounters an endElement event matching a
- * {@link ch.qos.logback.core.joran.spi.Pattern Pattern}.
- */
- public abstract void end(InterpretationContext ic, String name)
- throws ActionException;
-}</pre>
-
- <p>ごらんのように、アクションは<code>begin()</code>メソッドと<code>end()</code>メソッドを実装しなければなりません。<code>body()</code>メソッドを実装するかどうかは選択可能ですが。<code>Action</code>クラスは空実装を提供しているからです。</p>
-
-
- <h3 class="doAnchor" name="ruleStore">RuleStore</h3>
-
- <p>前述のように、パターンマッチと関連するアクションの実行がJoranの中心的な考え方です。ルールはパターンとアクションを関連付けるものです。そして<a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/spi/RuleStore.html">RuleStore</a>に保存されます。
- </p>
-
- <p>前述したとり、JoranはSAX APIを使っています。SAX APIとは、XMLドキュメントのそれぞれの要素についてstart/body/endというイベントを生成しながらパースを進めていくものです。Joranコンフィギュレーターは、イベントを受け付けると<em>今のパターン</em>に対応したアクションをルールストアから探してきます。たとえば、最上位要素<em>A</em>にネストされた要素<em>B</em>のstart/body/endイベントなら、今のパターンとは"A/B"になります。今のパターンとは、JoranがSAXイベントを受け付けながら自動的に調整するデータ構造なのです。</p>
-
- <p>今のパターンにいくつかのルールがマッチするときは、正確なマッチが接尾辞マッチより優先されます。そして接尾辞マッチは接頭辞マッチより優先されます。実装の詳細については<a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/spi/SimpleRuleStore.html">SimpleRuleStoreの</a>を参照してください。
- </p>
-
-
- <h3 class="doAnchor" name="interpretationContext">解釈コンテキスト</h3>
-
- <p>いろいろなアクションが協調して動作させるため、beginメソッドとendメソッドの一つ目の引数に解釈コンテキストが渡されます。解釈コンテキストには、オブジェクトスタック、オブジェクトマップ、エラーリスト、アクションを呼び出したJoranインタプリタへの参照が含まれています。解釈コンテキストの完全なフィールドが知りたければ<a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/spi/InterpretationContext.html"><code>InterpretationContext</code></a>を見てください。
- </p>
-
- <p>アクションは、共通のオブジェクトスタックに対するフェッチ、プッシュ、ポップといった操作や、共通のオブジェクトマップに対してキーと共にオブジェクトをプットしたりフェッチしたりすることで、他のアクションと共同作業をすることができます。また、解釈コンテキストの<code>StatusManager</code>にエラーを追加することで、問題が起きたことを報告することができます。
- </p>
-
- <h3 class="doAnchor" name="helloWorld">こんにちは</h3>
-
- <p>最初に、Joranを使うために必要最低限の構成を見てもらいます。<code><a href="http://logback.qos.ch/xref/chapters/onJoran/helloWorld/HelloWorldAction.html">HelloWorldAction</a></code>は、<code>begin()</code>でコンソールに"Hello World"と出力するだけの小さなアクションです。XMLファイルはコンフィギュレーターでパースします。この章の説明用に、非常に小さくて単純な<a href="http://logback.qos.ch/xref/chapters/onJoran/SimpleConfigurator.html"><code>SimpleConfigurator</code></a>というコンフィギュレーターを用意しました。<a href="http://logback.qos.ch/xref/chapters/onJoran/helloWorld/HelloWorld.html"><code>HelloWo [...]
-
- <ul>
- <li>ルールマップと<code>Context</code>を用意します</li>
- <li><code>HelloWorldAction</code>と<em>hello-world</em>パターンを関連付けて、パースルールを用意します</li>
- <li><code>SimpleConfigutator</code>を用意して、ルールマップを渡します</li>
- <li>XMLファイルを引数として、コンフィギュレーターの<code>doConfigure()</code>メソッドを呼び出します</li>
- <li>最後に、もしあれば解釈コンテキストに蓄積されたステータスメッセージを出力します</li>
- </ul>
-
- <p><em>hello.xml</em>には何もネストしていない1つのhello-world要素があります。<em>logback-examples/src/main/java/chapters/onJoran/helloWorld/</em>フォルダを参照してください。
- </p>
-
- <p><em>hello.xml</em>ファイルを指定してHelloWorldアプリケーションを実行すると、コンソールに"Hello World"と出力します。</p>
-
- <p class="command">java chapters.onJoran.helloWorld.HelloWorld src/main/java/chapters/onJoran/helloWorld/hello.xml</p>
-
- <p>ルールストアに新しいルールを追加したり、XMLドキュメントを変更してみたり、新しいアクションを追加するなど、いろいろと試してみたくなったでしょう?
- </p>
-
- <!-- ====================================================== -->
-
- <h3 class="doAnchor" name="calculator">アクションの協調</h3>
-
- <p>共通のオブジェクトスタックを通じて協調して簡単な計算をするアクションが、<em>logback-examples/src/main/java/joran/calculator/</em>ディレクトリに入っています。
- </p>
-
- <p><em>calculator1.xml</em>を見ると、<code>literal要素</code>をネストした<code>computation要素</code>があるので見てみましょう。
- </p>
-
- <p class="example">例10:Calculatorの設定例(<a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/calculator1.xml">logback-examples/src/main/java/chapters/onJoran/calculator/calculator1.xml</a>)</p>
-
- <pre class="prettyprint source"><computation name="total">
- <literal value="3"/>
-</computation></pre>
-
- <p><code><a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/Calculator1.html">Calculator1</a></code>アプリケーションでは、さまざまな解析ルール(パターンとアクション)を宣言しています。これらはXMLドキュメントの内容に基づき、協調して結果を算出するものです。
- </p>
-
- <p><em>calculator1.xml</em>を指定して<code>Calculator1</code>を実行してみましょう。</p>
-
- <p class="command">java chapters.onJoran.calculator.Calculator1 src/main/java/chapters/onJoran/calculator/calculator1.xml</p>
-
- <p>次のように出力されます。</p>
-
- <p class="console">The computation named [total] resulted in the value 3</p>
-
-
- <p>上記の<em>calculator1.xml</em>は次のように解釈されます。</p>
-
- <ul>
- <li>computation要素のstartイベントが、"/computation" パターンとみなされます。<code><a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/Calculator1.html">Calculator1</a></code>アプリケーションは"/computation"パターンと<a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/ComputationAction1.html"><code>ComputationAction1</code></a>を関連付けています。ですので、<code>ComputationAction1</code>のインスタンスの<code>begin()</code>メソッドが実行されます。
- </li>
-
- <li><p>literal要素のstartイベントが、"/computation/literal" パターンとみなされます。"/computation/literal" パターンは<code><a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/LiteralAction.html">LiteralAction</a></code>と関連付けられています。ですので、<code>LiteralAction</code>のインスタンスの<code>begin()</code>メソッドが実行されます。</p>
- </li>
-
- <li><p>また、literal要素のendイベントより、<code>LiteralAction</code>のインスタンスの<code>end()</code>メソッドを実行されます。</p>
- </li>
-
-
- <li><p>同様に、computation要素のendイベントより、<code>ComputationAction1</code>のインスタンスの<code>end()</code>メソッドが実行されます。
- </p>
- </li>
- </ul>
-
- <p>ここで注目して欲しいのは、アクションがどのように協調しているのかということです。<code>LiteralAction</code>は設定ファイルからリテラル値を読み取り、<code>InterpretationContext</code>の保持しているオブジェクトスタックに登録します。オブジェクトスタックに登録された値は、他のアクションから読み書きすることができるようになります。ここでは、 <code>ComputationAction1</code>の<code>end()</code>メソッドが、オブジェクトスタックから値をポップして、出力しています。
- </p>
-
- <!-- TO BE CONTINUED -->
-
- <p>次に<em>calculator2.xml</em>を見てみましょう。前の例よりも少し複雑で、面白いことをしています。</p>
-
- <p class="example">例10:Calculatorの設定例(<a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/calculator2.xml">logback-examples/src/main/java/chapters/onJoran/calculator/calculator2.xml</a>)</p>
-
- <pre class="prettyprint source"><computation name="toto">
- <literal value="7"/>
- <literal value="3"/>
- <add/>
- <literal value="3"/>
- <multiply/>
-</computation></pre>
-
-
- <p>前の例と同じく、literal要素に対応する<code><a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/LiteralAction.html">LiteralAction</a></code>は、解釈コンテキストのオブジェクトスタックに整数値を登録します。ここ(<em>calculator2.xml</em>)ではまず7と3が登録されています。add要素には<a href="http://logback.qos.ch/xref/chapters/onJoran/calculator/AddAction.html"><code>AddAction</code></a>が関連付けられています。これはオブジェクトスタックから二回整数値をポップして、それらを加算した結果をオブジェクトスタックにプッシュするものです。次のliteral要素に対応するLiteralActionは、オブジェクトスタックの一番上に整数値3をプッシュします。multiply要素には<a href="http://lo [...]
-
- <p class="command">java chapters.onJoran.calculator.Calculator1 src/main/java/chapters/onJoran/calculator/calculator2.xml </p>
-
- <p>そうすると、次のように出力されます。</p>
-
- <p class="console">The computation named [toto] resulted in the value 30 </p>
-
-
- <!--
-
-
- <p>Finally, a <em>calculator3.xml</em> is also provided, to
- demonstrate the possibility elements that contain instances of the
- same element. Here's the content of <em>calculator3.xml</em>:</p>
-
- <em>Example 10.<span class="autoEx"/>: Calculator configuration file
- (logback-examples/src/main/java/chapters/onJoran/calculator/calculator3.xml)</em>
-
-<pre class="prettyprint source"><computation name="toto">
- <computation>
- <literal value="7"/>
- <literal value="3"/>
- <add/>
- </computation>
-
- <literal value="3"/>
- <multiply/>
-</computation></pre>
-
- <p>Much like the use of parentheses in an algebrical equation, the
- presence of a <code>computation</code> element nested in another is
- managed by the <a
- href="../xref/chapters/onJoran/calculator/ComputationAction2.html">
- <code>ComputationAction2</code></a> class using an internal
- stack. The well-formedness of XML will guarantee that a value saved
- by one <code>begin()</code> will be consumed only by the matching
- <code>end()</code> method.</p>
- -->
-
- <h3 class="doAnchor" name="implicit">暗黙的なアクション</h3>
-
- <p>ここまでに紹介してきたルールの定義は明示的なアクションと呼ばれます。現在のxml要素に対応するパターンとアクションのペアを、ルールストアから1つだけ取り出すことができるからです。しかし、高度な拡張性を備えたシステムにおいて、コンポーネントの種類は膨大な数になります。それゆえに、すべてのパターンに明示的なアクションを関連付けるのはとても面倒なことになるのです。
- </p>
-
- <p>そうは言っても、高度な拡張性を備えたシステムなら、ルールに付随するコンポーネントそれぞれに結びついたルールを、循環して見つけることができます。そのようにルールを発見できるとすると、logbackの設定ファイルをパースする時点では未知のコンポーネントが含まれるコンポーネントを扱うことができるようになります。たとえば、Apacne Ant では、<code>addFile</code>や<code>addClassPath</code>といったコンポーネントを発見するメソッドを使うことで、設定ファイルをパースする時点では未知のタグを含んだタスクを扱えるようになっています。Antはタスクの処理中に未知のタグを発見すると、タグ名に基づいたクラスのオブジェクトを生成し、タスクの実装クラスに宣言されているaddXメソッドを呼び出して、親のオブジェクトに登録します。
- </p>
-
- <p>Joranは暗黙的なアクションとして同じような機能を実現しています。現在のパターンが明示的なアクションにマッチしなかった時のために、暗黙的なアクションの一覧を保持するようになっています。しかし、暗黙的なアクションを適用することが必ずしも適切ではない場合があります。そこで、Joranは暗黙的なアクションを実行する前に、現在の状況が妥当であるかどうかを確認するようになっています。Joranからの確認に対して、これから実行されようとするアクションが肯定を返すときだけ、アクションを呼び出します。この例外対応によって、複数の暗黙的なアクションを備えつつ、適切なアクションが無ければ何もしないことの両方のケースに対応できるのです。
- </p>
-
- <p>暗黙的なアクションの作成例が<em>logback-examples/src/main/java/chapters/onJoran/implicit</em>にあります。
- </p>
-
- <p><a href="http://logback.qos.ch/xref/chapters/onJoran/implicit/PrintMe.html"><code>PrintMe</code></a>アプリケーションでは、"/*/foo" パターンと<a href="http://logback.qos.ch/xref/chapters/onJoran/implicit/NOPAction.html"><code>NOPAction</code></a>アクションを関連付けています。このパターンは任意のfoo要素にマッチします。<code>NOPAction</code>の<code>begin()</code>メソッドと<code>end()</code>メソッドは、名前のとおり空っぽです。<code>PrintMe</code>アプリケーションは、暗黙的なアクションの一覧に<a href="http://logback.qos.ch/xref/chapters/onJoran/implicit/PrintMeImplicitAction.html">Pri [...]
- </p>
-
- <p>暗黙的なアクションがどのように振る舞うのか、<em>implicit1.xml</em>で試してみましょう。</p>
-
- <p class="example">例10: 暗黙的なルールの使い方(<a href="http://logback.qos.ch/xref/chapters/onJoran/implicit/implicit1.xml">logback-examples/src/main/java/chapters/onJoran/implicit/implicit1.xml</a>)</p>
-
- <pre class="prettyprint source"><foo>
- <xyz printme="true">
- <abc printme="true"/>
- </xyz>
-
- <xyz/>
-
- <foo printme="true"/>
-
-</foo></pre>
-
- <p>実行してみましょう。</p>
-
- <p class="command">java chapters.onJoran.implicit.PrintMe src/main/java/chapters/onJoran/implicit/implicit1.xml</p>
- <p>次のように出力されます。</p>
-
- <p class="console">Element [xyz] asked to be printed.
-Element [abc] asked to be printed.
-20:33:43,750 |-ERROR in c.q.l.c.joran.spi.Interpreter@<b>10:9</b> - no applicable action for [xyz], current pattern is [[foo][xyz]]</p>
-
- <p><code>NOPAction</code>が"*/foo"パターンに関連付けられているので、foo要素について<code>NOPAction</code>の<code>begin()</code>メソッドと<code>end()</code>メソッドが実行されているはずです。そのため、foo要素については<code>PrintMeImplicitAction</code>は呼び出されないのです。他の明示的なアクションがマッチしない要素について、<code>PrintMeImplicitAction{\0}の<code>isApplicable()</code></code>メソッドが呼び出されます。isApplicable()メソッドは、<span class="attr">printme属性</span>にtrueが指定されている場合にだけtrueを返します。したがって、最初のxyz要素とabc要素についてはtrueを返します。10行目の二つ目のxyz要素には適用可能なアクションがないので、内部エラーメッセージが出力されます。エラーメッセージは<code> [...]
- </p>
-
- <h3 class="doAnchor" name="iaPractice">暗黙的なアクションの実装</h3>
-
- <p>logback-classic モジュールと logback-access モジュールのそれぞれの Joran コンフィギュレーターには、暗黙的なアクションが2つだけ含まれています。<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/action/NestedBasicPropertyIA.html">NestedBasicPropertyIA</a></code>と<a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.html"><code>NestedComplexPropertyIA</code></a>です。</p>
-
- <p><code>NestedBasicPropertyIA</code>は、プリミティブ型あるいはそのラッパークラス、列挙型、"valueOf" 規約に則った任意のクラスのプロパティに適用可能なアクションです。このアクションが適用可能なプロパティは<em>基本型</em>あるいは<em>単純型</em>と呼ばれています。"valueOf" 規約に則るというのは、<code>java.lang.String</code>を引数とする静的メソッド<code>valueOf()</code>によってインスタンス化できる、ということです。<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/Level.html"><code>Level</code></a>や<a href="http://logback.qos.ch/xref/ch/qos/logback/core/util/Duration.html"><code>Duration</code></a>、<a href="http://logback.q [...]
- </p>
-
- <p><code>NestedComplexPropertyIA</code>は、<code>NestedBasicPropertyIA</code>が適用できない場合に、<em>かつ</em>、オブジェクトスタックの一番上のオブジェクトに、現在の要素名に対応するセッターあるいはアダーメソッドがある場合に適用可能なアクションです。このアクションが適用可能なプロパティは、更に他のコンポーネントを内包することがあるので注意しましょう。このアクションが適用可能なプロパティは<em>複雑型</em>と呼ばれています。<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.html">NestedComplexPropertyIA</a></code>が複雑型のプロパティを見つけると、ネストされたコンポーネントに対応する適切なクラスをインスタンス化して、親のコンポーネント(オブジェクトスタックの一番上のオブジェクト)に設定します。<sp [...]
-
- <ol>
- <li>親のオブジェクトのプロパティのクラスを決定する内部的なルールに基づいて決められたクラス名</li>
- <li>セッターメソッドの@DefaultClassアノテーションに指定あされ</li>
-
- <li>セッターメソッドの引数が公開コンストラクタを持つ具象クラスならそのクラス名</li>
- </ol>
-
- <h4 class="doAnchor" name="defaultClassMapping">デフォルトのクラスマッピング</h4>
-
- <p>logback-classic では、親のクラスとプロパティ名に対応するデフォルトのクラスを規定した内部的なルールがあります。表にまとめました。</p>
-
- <table class="bodyTable">
- <tr>
- <th>親クラス</th>
- <th>プロパティ名</th>
- <th>ネストするコンポーネントのデフォルトクラス</th>
- </tr>
-
- <tr>
- <td>ch.qos.logback.core.AppenderBase</td>
- <td>encoder</td>
- <td>ch.qos.logback.classic.encoder.PatternLayoutEncoder</td>
- </tr>
-
- <tr class="alt">
- <td>ch.qos.logback.core.UnsynchronizedAppenderBase</td>
- <td>encoder</td>
- <td>ch.qos.logback.classic.encoder.PatternLayoutEncoder</td>
- </tr>
-
- <tr>
- <td>ch.qos.logback.core.AppenderBase</td>
- <td>layout</td>
- <td>ch.qos.logback.classic.PatternLayout</td>
- </tr>
-
- <tr class="alt">
- <td>ch.qos.logback.core.UnsynchronizedAppenderBase</td>
- <td>layout</td>
- <td>ch.qos.logback.classic.PatternLayout</td>
- </tr>
-
- <tr>
- <td>ch.qos.logback.core.filter.EvaluatorFilter</td>
- <td>evaluator</td>
- <td>ch.qos.logback.classic.boolex.JaninoEventEvaluator</td>
- </tr>
- </table>
-
- <p>これらは将来的に変更されるかもしれません。最新のルールについては、logback-classic モジュールの<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/joran/JoranConfigurator.html">JoranConfigurator</a>の<code>addDefaultNestedComponentRegistryRules()</code>メソッドを参照してください。
- </p>
-
- <p>logback-accessモジュールのルールも似たようなものです。ネストするコンポーネントのデフォルトクラスについては、パッケージ名を ch.qos.logback.classic から ch.qos.logback.access に読み替えてください。最新のルールについては、logback-access モジュールの<a href="http://logback.qos.ch/xref/ch/qos/logback/access/joran/JoranConfigurator.html">JoranConfigurator</a>の<code>addDefaultNestedComponentRegistryRules()</code>メソッドを参照してください。
-
- </p>
-
- <h4 class="doAnchor">コレクション型のプロパティ</h4>
-
-
- <p>logbackの暗黙的なアクションは、単独の基本型プロパティ、複雑型プロパティに加えて、コレクション型のプロパティにも対応しています。ただし、セッターメソッドの代わりに、アダーメソッドを用意する必要があります。</p>
-
- <h3 class="doAnchor" name="newRule">その場で新しいルールを定義する</h3>
-
- <p>Joranには、XMLドキュメントを解釈している途中でも、Joranコンフィギュレーターに新しいルールを教えるためのアクションが含まれています。サンプルコードが<em>logback-examples/src/main/java/chapters/onJoran/newRule</em>ディレクトリにあります。<code><a href="http://logback.qos.ch/xref/chapters/onJoran/newRule/NewRuleCalculator.html">NewRuleCalculator</a></code>アプリケーションは、二つのルールを定義しています。1つは最上位要素を処理するためのもので、二つ目は動的に新しいルールを定義するためのものです。<code>NewRuleCalculator</code>の関連するコードをピックアップしました。
- </p>
-
- <pre class="prettyprint source">ruleMap.put(new Pattern("*/computation"), new ComputationAction1());
-<b>ruleStore.addRule(new Pattern("/computation/newRule"), new NewRuleAction());</b></pre>
-
- <p><a href="http://logback.qos.ch/xref/ch/qos/logback/core/joran/action/NewRuleAction.html"><code>NewRuleAction</code></a>はlogback-coreの一部で、他のアクションと同じように動作します。パーサーが<em>newRule要素</em>を見つけるたびに、このアクションの<code>begin()</code>メソッドと<code>end()</code>メソッドが呼び出されます。<code>begin()</code>メソッドは、 <em>pattern属性</em>と<em>actionClass属性</em>を探します。その後、対応するアクションクラスをインスタンス化し、Joranのルールストアにパターンとアクションの関連付けを新しいルールとして追加します。</p>
-
-
- <p>XMLドキュメント中では次のように新しいルールを宣言します。</p>
-
- <pre class="prettyprint source"><newRule pattern="*/computation/literal"
- actionClass="chapters.onJoran.calculator.LiteralAction"/></pre>
-
- <p>newRule宣言を使って、<code>NewRuleCalculator</code>に<code>Calculator1</code>のような振る舞いをさせることができます。</p>
-
- <p class="example">例10: 動的にルールを定義する設定例(<a href="http://logback.qos.ch/xref/chapters/onJoran/newrule/newRule.xml">logback-examples/src/main/java/chapters/onJoran/newrule/newRule.xml</a>)</p>
-
- <pre class="prettyprint source"><computation name="toto">
- <newRule pattern="*/computation/literal"
- actionClass="chapters.onJoran.calculator.LiteralAction"/>
- <newRule pattern="*/computation/add"
- actionClass="chapters.onJoran.calculator.AddAction"/>
- <newRule pattern="*/computation/multiply"
- actionClass="chapters.onJoran.calculator.MultiplyAction"/>
-
- <computation>
- <literal value="7"/>
- <literal value="3"/>
- <add/>
- </computation>
-
- <literal value="3"/>
- <multiply/>
-</computation></pre>
-
-
- <p class="command">実行してみましょう。
-java chapters.onJoran.newRule.NewRuleCalculator src/main/java/chapters/onJoran/newRule/newRule.xml</p>
-
- <p>次のように出力されます。</p>
-
- <p class="console">The computation named [toto] resulted in the value 30</p>
-
- <p>これは<a href="./10-onJoran.html#calculator">元のCalculator1</a>の出力とまったく同じです。</p>
-
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/receivers.html b/logback-site/src/site/pages/manual/receivers.html
index 11425ca..205b104 100644
--- a/logback-site/src/site/pages/manual/receivers.html
+++ b/logback-site/src/site/pages/manual/receivers.html
@@ -28,8 +28,6 @@
<h1>Chapter 14: Receivers</h1>
- <a href="receivers_ja.html">和訳 (Japanese translation)</a>
-
<div class="quote">
<p><em>You cannot swim for new horizons until you have courage
@@ -185,7 +183,7 @@
to the local console appender.</p>
<p class="example">Example: Basic ServerSocketReceiver Configuration
- (logback-examples/src/main/resources/chapters/receivers/socket/receiver1.xml)</p>
+ (logback-examples/src/main/java/chapters/receivers/socket/receiver1.xml)</p>
<span class="asGroovy" onclick="return asGroovy('receiver1');">View as .groovy</span>
<pre id="receiver1" class="prettyprint source"><configuration debug="true">
@@ -245,7 +243,7 @@
that acts in the server role.</p>
<p class="example">Example: Basic SSLServerSocketReceiver Configuration
- (logback-examples/src/main/resources/chapters/receivers/socket/receiver2.xml)</p>
+ (logback-examples/src/main/java/chapters/receivers/socket/receiver2.xml)</p>
<span class="asGroovy" onclick="return asGroovy('receiver2');">View as .groovy</span>
<pre id="receiver2" class="prettyprint source"><configuration debug="true">
@@ -385,7 +383,7 @@
appender acts as a server.</p>
<p class="example">Example: Basic SocketReceiver Configuration
- (logback-examples/src/main/resources/chapters/receivers/socket/receiver3.xml)</p>
+ (logback-examples/src/main/java/chapters/receivers/socket/receiver3.xml)</p>
<span class="asGroovy" onclick="return asGroovy('receiver3');">View as .groovy</span>
<pre id="receiver3" class="prettyprint source"><configuration debug="true">
@@ -427,14 +425,10 @@
succeeds or until the logger context is shut down. The delay
interval between attempts is configurable using the
<span class="prop">reconnectionDelay</span> property as shown in the
- example configuration.
- </p>
-
- <p class="source">java -Dhost=localhost -Dport=6000 \
+ example configuration.<p class="source">java -Dhost=localhost -Dport=6000 \
chapters.receivers.socket.ReceiverExample \
src/main/java/chapters/receivers/socket/receiver3.xml</p>
-
<p>We can provide a remote appender to which our example receiver
can connect, using the same appender example used previously. The
example loads a logback configuration containing a
@@ -463,7 +457,7 @@
</p>
<p class="example">Example: Basic SSLSocketReceiver Configuration
- (logback-examples/src/main/resources/chapters/receivers/socket/receiver4.xml)</p>
+ (logback-examples/src/main/java/chapters/receivers/socket/receiver4.xml)</p>
<span class="asGroovy" onclick="return asGroovy('receiver4');">View as .groovy</span>
<pre id="receiver4" class="prettyprint source"><configuration debug="true">
diff --git a/logback-site/src/site/pages/manual/receivers_ja.html b/logback-site/src/site/pages/manual/receivers_ja.html
deleted file mode 100644
index b6d2138..0000000
--- a/logback-site/src/site/pages/manual/receivers_ja.html
+++ /dev/null
@@ -1,343 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第14章 レシーバー</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
-
- <h1>第14章 レシーバー</h1>
-
- <div class="quote">
-
- <p><em>岸が見えなくなることを恐れない勇気が無ければ、地平線の向こうまで泳ぎ着くことはできない。</em></p>
-
- <p>—WILLIAM FAULKNER</p>
- </div>
-
-
- <script type="text/javascript" src="../templates/creative.js"></script>
- <script type="text/javascript" src="../templates/setup.js"></script>
-
- <h2 class="doAnchor" name="whatIsAReceiver">レシーバーとは何か?</h2>
-
- <p><em>レシーバー</em>とは、リモートアペンダーからロギングイベントを受信し、ローカルポリシーに基づいてログに記録するlogbackのコンポーネントです。ソケットベースのアペンダーとレシーバーを組み合わせることで、分散アプリケーションのロギングイベントをネットワーク越しに配信する高度なトポロジーを実現することができます。</p>
-
- <p>レシーバーは<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/ReceiverBase.html">ch.qos.logback.classic.net.ReceiverBase</a></code>クラスを継承しています。おかげで<a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/LifeCycle.html">LifeCycle</a>に参加できるし、レシーバー自体が<a href="http://logback.qos.ch/xref/ch/qos/logback/core/spi/ContextAware.html">ContextAware</a>になります。</p>
-
- <p>歴史的な経緯により、logback によるネットワーク越しのロギングイベントの配信は<code>SocketAppender</code>と<code>SimpleSocketServer</code>によって実現されてきました。アペンダーはクライアントとして動作します。サーバーアプリケーションへのネットワーク接続を確立し、ロギングイベントを配信するのです。レシーバーコンポーネントと対応するアペンダーを使うことで、より優れた柔軟性を実現することができます。</p>
-
- <p>レシーバーコンポーネントは他のlogbackのコンポーネントと同様に<em>logback.xml</em>で設定します。つまり、<a href="./11-onJoran.html">Joran</a>の全ての機能を利用することができるのです。さらに、複数のレシーバーコンポーネントを設定するだけで、<em>あらゆる</em>アプリケーションのリモートアペンダーからロギングイベントを受け付けることができます。</p>
-
- <p>アペンダーとレシーバー間のネットワーク接続の確立はどちら側からでも始めることができます。レシーバーはサーバーとして振る舞うことができます。つまり、クライアントたるリモートアペンダーからの接続を待ち受けることができます。レシーバーはクライアントとして振る舞うこともできます。サーバーとして振る舞うリモートアペンダーに対してネットワーク接続を確立することができるのです。アペンダーとレシーバーのそれぞれの役割とは無関係に、<em>ロギングイベントは常にアペンダーからレシーバーに送信されます</em>。</p>
-
- <p>レシーバーからアペンダーに接続できることは、特定の状況においてとても有用です。</p>
- <ul>
- <li>セキュリティ上の観点から、中央ロギングサーバーはファイアーウォールの後ろ側に配置されることが多いです。つまり、外部からの接続が許されないのです。レシーバーコンポーネントがクライアントとして振る舞うことで、中央ロギングサーバー(ファイアーウォールの内側)から対象のアプリケーション(ファイアーウォールの外側)に接続することができます。
- </li>
- <li>IDEのプラグインなどの開発者ツールに最適です。また、実行中のアプリケーションが生成するロギングイベントのストリームへのアクセスを、企業統制の仕組みによって管理するのにも適しています。伝統的に、logbackでこのような状況に対応する(たとえばlogback Beagleなど)には、宛先のアプリケーション(たとえばIDEで実行される開発者ツール)がサーバーの役割を担う必要がありました。管理が大変になることは明らかです。特に、開発者のワークステーションで実行しているツールならなおさらです。モバイルPCが一般的になってきているのも悩みの種になります。今では、それらのツールはクライアントとしてのレシーバーコンポーネントを実装すればよくなりました。手元でロギングイベントをフィルタしたり、警告を上げたり、内容を確認するには、リモートアペンダーに接続すればよいのです。
- </li>
- </ul>
-
- <p>logbackの設定には、サーバーあるいはクライアントのいずれかの役割を担うレシーバーコンポーネントを混在させることができます。数少ない制限として、サーバーとして振る舞うレシーバーコンポーネントはそれぞれ固有のポート番号で接続を待ち受けなければならないということと、クライアントとして振る舞うレシーバーコンポーネントはそれぞれただ1つのリモートアペンダーにしか接続してはならないということがあります。</p>
-
- <h2 class="doAnchor" name="receiverServerComponents">サーバーとして振る舞うレシーバー</h2>
-
- <p>サーバーとして振る舞うレシーバーはリモートアペンダーからの接続を待ち受けます。これはスタンドアローンの<code>SimpleSocketServer</code>アプリケーションと同じ機能です。ただし、レシーバーコンポーネントなら、<em>logback.xml</em>に設定するだけで、logback-classicモジュールを使っている<em>あらゆる{</em>\1}アプリケーションからロギングイベントを受信することができます。</p>
-
- <p>
- <img border="1" src="images/chapters/receivers/serverSocketReceiver.png">
- </p>
-
- <p>logbackの配布物には二つのレシーバーコンポーネントが含まれています。<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/server/ServerSocketReceiver.html">ServerSocketReceiver</a></code>とそのSSL対応の<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/server/SSLServerSocketReceiver.html"><code>SSLServerSocketReceiver</code></a>です。どちらも<code>SocketAppender</code>(あるいは<code>SSLSocketAppender</code>)からの接続を待ち受けるように設計されています。</p>
-
- <p><code>ServerSocketReceiver</code>の設定可能なプロパティは次のとおりです。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="serverSocketReceiver">address</span></td>
- <td><code>String</code></td>
- <td>レシーバーが待ち受けるローカルネットワークインターフェイスのネットワークアドレス。このプロパティが指定されない場合、レシーバーは全てのネットワークインターフェイスで待ち受けるようになります。</td>
- </tr>
- <tr>
- <td><span class="prop" container="serverSocketReceiver">port</span></td>
- <td><code>int</code></td>
- <td>レシーバーが待ち受けるTCPのポート番号。このプロパティが指定されない場合、デフォルト値が使用されます。</td>
- </tr>
- <tr>
- <td><span class="prop" container="serverSocketReceiver">ssl</span></td>
- <td><code>SSLConfiguration</code></td>
- <td><code>SSLServerSocketReceiver</code>でのみサポートされているプロパティです。このプロパティには<a href="./15-usingSSL.html">SSLを使用する</a>で説明されているSSLの設定を指定します。</td>
- </tr>
- </table>
-
- <h3 class="doAnchor" name="usingServerSocketReceiver">ServerSocketReceiverの使い方</h3>
-
- <p>次の設定は、最小限のアペンダーとロガーの設定とともに<code>ServerSocketReceiver</code>を使用するものです。リモートアペンダーから受信したロギングイベントは、ルートロガーに渡されて、ローカルのコンソールアペンダーに配信されます。</p>
-
- <p class="example">例:基本的なServerSocketReceiverの設定(<a href="http://logback.qos.ch/xref/chapters/receivers/socket/receiver1.xml">logback-examples/src/main/java/chapters/receivers/socket/receiver1.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('receiver1');">Groovyとして表示</span>
- <pre id="receiver1" class="prettyprint source"><configuration debug="true">
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-
- <receiver class="ch.qos.logback.classic.net.server.ServerSocketReceiver">
- <port>${port}</port>
- </receiver>
-
-</configuration></pre>
-
- <p>レシーバーコンポーネントの<em>class属性</em>に指定した値によって、レシーバーのサブタイプを指定します。ここでは<code>ServerSocketReceiver</code>を指定しています。</p>
-
- <p>例として、<code>SimpleSocketServer</code>と非常によく似た機能を持ったサーバーアプリケーションを用意しました。logbackの設定ファイルへのパスをコマンドライン引数から受け取って、指定された設定ファイルを読み込みます。この例のアプリケーションは大した仕事をするわけではありませんが、<code>ServerSocketReceiver</code> (あるいは<code>SSLServerSocketReceiver</code>)は<em>どんな</em>アプリケーションからでも利用できることを覚えておきましょう。
- </p>
-
- <p>コマンドをプロンプトで<em>logback-examplesディレクトリ</em>に移動して、次のコマンドを実行しましょう。</p>
-
- <p class="source">java -Dport=6000 <a href="http://logback.qos.ch/xref/chapters/receivers/socket/ReceiverExample.html">chapters.receivers.socket.ReceiverExample</a> \
- src/main/java/chapters/receivers/socket/receiver1.xml</p>
-
- <p>クライアントアプリケーションで<code>SocketAppender</code>を設定して、実行中のレシーバーに接続することができます。サンプルのクライアントアプリケーションは、上記のレシーバーに接続する設定ファイルを読み込むだけのものです。クライアントアプリケーションはユーザー入力を待ちます。ユーザー入力はそのままレシーバーに中継されます。クライアントアプリケーションは次のように実行します。</p>
-
- <p class="source">java -Dhost=localhost -Dport=6000 \
- <a href="http://logback.qos.ch/xref/chapters/receivers/socket/AppenderExample.html">chapters.receivers.socket.AppenderExample </a>\
- src/main/java/chapters/receivers/socket/appender1.xml</p>
-
- <h3 class="doAnchor" name="usingSSLServerSocketReceiver">SSLServerSocketReceiverの使い方</h3>
-
- <p>次の設定は、前の設定とは違ってSSLに対応したレシーバーを使うものです。</p>
-
- <p class="example">例:基本的なSSLServerSocketReceiverの設定(<a href="http://logback.qos.ch/xref/chapters/receivers/socket/receiver2.xml">logback-examples/src/main/java/chapters/receivers/socket/receiver2.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('receiver2');">Groovyとして表示</span>
- <pre id="receiver2" class="prettyprint source"><configuration debug="true">
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-
- <receiver class="ch.qos.logback.classic.net.server.SSLServerSocketReceiver">
- <port>${port}</port>
- <ssl>
- <keyStore>
- <location>${keystore}</location>
- <password>${password}</password>
- </keyStore>
- </ssl>
- </receiver>
-
-</configuration></pre>
-
- <p>前の<code>ServerSocketReceiver</code>を使った設定とこちらの設定で根本的に違うのは、レシーバーの<em>class属性</em>に<code>SSLServerSocketReceiver</code>が指定されていることと、<span class="prop">ssl</span>プロパティがネストされていることです。sslプロパティにはレシーバーの秘密鍵と証明書が配置されたキーストアの場所とパスワードを、変数で指定しています。sslプロパティの設定内容について詳しくは<a href="./15-usingSSL.html">SSLを使用する</a>を参照してください。</p>
-
- <p>いくつか引数を追加して次のようにサーバーアプリケーションを実行します。</p>
-
- <p class="source">java -Dport=6001 \
- -Dkeystore=file:src/main/java/chapters/appenders/socket/ssl/keystore.jks \
- -Dpassword=changeit \
- chapters.receivers.socket.ReceiverExample \
- src/main/java/chapters/receivers/socket/receiver2.xml</p>
-
- <p>コマンドラインで指定したプロパティ<em>keystore</em>には、キーストアのfileから始まるURLを指定します。<a href="./15-usingSSL.html">SSLを使用する</a>でも説明していますが、クラスパス上のリソースを指定することもできます。</p>
-
- <p>このレシーバーには、クライアントアプリケーションから<code>SSLSocketAppender</code>で接続することができます。SSL対応のアペンダーを使う設定ファイルを、前の例で使用したクライアントアプリケーションから使うことができます。次のように実行します。</p>
-
- <p class="source">java -Dhost=localhost -Dport=6001 \
- -Dtruststore=file:src/main/java/chapters/appenders/socket/ssl/truststore.jks \
- -Dpassword=changeit \
- chapters.receivers.socket.AppenderExample \
- src/main/java/chapters/receivers/socket/appender2.xml</p>
-
- <p>この例では自己署名したX.509証明書を使用していますが、これを使っていいのはテストや実験的な用途だけです。<strong>本番環境では、SSL対応のアペンダーのために適切なX.509証明書を使うようにしてください</strong> 。詳細は<a href="./15-usingSSL.html">SSLを使用する</a>を参照してください。</p>
-
- <h2 class="doAnchor" name="receiverClientComponents">クライアントとして振る舞うレシーバー
-</h2>
-
- <p>クライアントとして振る舞うように設定したレシーバーは、リモートアペンダーに接続します。リモートアペンダーは<code>ServerSocketAppender</code>などのサーバ型でなければなりません。</p>
-
- <p>
- <img border="1" src="images/chapters/receivers/socketReceiver.png">
- </p>
-
- <p>logackの配布物にはクライアントとして振る舞うレシーバーコンポーネントが2つ含まれています。<code><a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/SocketReceiver.html">SocketReceiver</a></code>とそのSSL対応版の<a href="http://logback.qos.ch/xref/ch/qos/logback/classic/net/SSLSocketReceiver.html"><code>SSLSocketReceiver</code></a>です。どちらのレシーバーもリモートアペンダー(<code>ServerSocketAppender</code>あるいは<code>SSLServerSocketAppender</code>)に対して接続を確立するようになっています。</p>
-
- <p><code>SocketReceiver</code>の派生クラスで設定可能なプロパティは次のとおりです。</p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="SocketReceiver">remoteHost</span></td>
- <td><code>String</code></td>
- <td>リモートアペンダーのホスト名またはIPアドレス。</td>
- </tr>
- <tr>
- <td><span class="prop" container="SocketReceiver">port</span></td>
- <td><code>int</code></td>
- <td>リモートアペンダーの待ち受けポート番号。</td>
- </tr>
- <tr>
- <td><span class="prop" container="socket">reconnectionDelay</span></td>
- <td><code>int</code></td>
- <td>接続異常が発生した後で、再接続をする前に待機する時間を表す正の整数値。単位はミリ秒。デフォルト値は30000(30秒)です。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="SocketReceiver">ssl</span></td>
- <td><code>SSLConfiguration</code></td>
- <td><code>SSLSocketReceiver</code>でのみ設定可能なプロパティ。<a href="./15-usingSSL.html">SSLを使用する</a>で説明しているとおり、SSLの設定を指定します。</td>
- </tr>
- </table>
-
- <h3 class="doAnchor" name="usingSocketReceiver">SocketReceiverの使い方</h3>
-
- <p><code>SocketReceiver</code>の設定は<code>ServerSocketReceiver</code>の設定と非常によく似ています。これらの差は、サーバーとクライアントという真逆の役割に起因するものです。<code>SocketReceiver</code>はクライアントで、リモートアペンダはサーバーとして動作します。</p>
-
- <p class="example">例:基本的なSocketReceiverの設定(<a href="http://logback.qos.ch/xref/chapters/receivers/socket/receiver3.xml">logback-examples/src/main/java/chapters/receivers/socket/receiver3.xml</a>)</p>
- <span class="asGroovy" onclick="return asGroovy('receiver3');">Groovyとして表示</span>
- <pre id="receiver3" class="prettyprint source"><configuration debug="true">
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%date %-5level [%thread] %logger - %message%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-
- <receiver class="ch.qos.logback.classic.net.SocketReceiver">
- <remoteHost>${host}</remoteHost>
- <port>${port}</port>
- <reconnectionDelay>10000</reconnectionDelay>
- </receiver>
-
-</configuration></pre>
-
- <p>この設定だと、logbackは<em>host</em>変数で指定されたホストの、<em>port</em>変数で指定されたポート番号で実行中の<code>ServerSocketAppender</code>へ接続します。リモートアペンダーから受け取ったロギングイベントは、手元でコンソールアペンダーに渡されます。
- </p>
-
- <p>コマンドプロンプトで<em>logback-examples</em>ディレクトリに移動して、次のコマンドを実行してみましょう。</p>
-
-
-
- <p>サンプルアプリケーションは上記の設定ファイルを読み込んだあと、リモートアペンダーからのロギングイベントを待ち受けます。リモートアペンダーが落ちているときは、定期的に<em>接続を拒否された</em>メッセージが出力されます。再接続が成功するか、アプリケーションが停止するまで、レシーバーは定期的にリモートアペンダーへの再接続を繰り返します。設定例にあるとおり、再接続の間隔は<span class="prop">reconnectionDelay</span>プロパティで指定することができます。<p class="source">java -Dhost=localhost -Dport=6000 \
- chapters.receivers.socket.ReceiverExample \
- src/main/java/chapters/receivers/socket/receiver3.xml</p>
-
- <p>この例のレシーバーは、前のアプリケーションのアペンダーにそのまま接続できます。アペンダー用のサンプルアプリケーションは、<code>ServerSocketAppender</code>を使った設定ファイルを読み込んでから、ユーザー入力を待ちます。ユーザー入力はアペンダーに接続してきたレシーバーに配信されます。アペンダー用のサンプルアプリケーションを実行してみましょう。</p>
-
- <p class="source">java -Dport=6000 \
- chapters.receivers.socket.AppenderExample \
- src/main/java/chapters/receivers/socket/appender3.xml</p>
-
- <p>レシーバーが接続する前に入力したメッセージは破棄されます。わかりやすいですね。</p>
-
- <h3 class="doAnchor" name="usingSSLSocketReceiver">SocketSSLReceiverの使い方</h3>
-
-
- <p><code>SSLSocketReceiver</code>の設定は<code>SocketReceiver</code>の設定とほとんど変わりません。根本的に違うのは、レシーバーのclass属性の指定と、<span class="prop">ssl</span>プロパティがネストされていることです。基本的な設定を見てみましょう。</p>
-
- <p class="example">例:基本的なSSLSocketReceiverの設定(<a href="http://logback.qos.ch/xref/chapters/receivers/socket/receiver4.xml">logback-examples/src/main/java/chapters/receivers/socket/receiver4.xml</a>)</p>
-
- <span class="asGroovy" onclick="return asGroovy('receiver4');">Groovyとして表示</span>
- <pre id="receiver4" class="prettyprint source"><configuration debug="true">
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%date %-5level [%thread] %logger - %message%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-
- <receiver class="ch.qos.logback.classic.net.SSLSocketReceiver">
- <remoteHost>${host}</remoteHost>
- <port>${port}</port>
- <reconnectionDelay>10000</reconnectionDelay>
- <ssl>
- <trustStore>
- <location>${truststore}</location>
- <password>${password}</password>
- </trustStore>
- </ssl>
- </receiver>
-
-</configuration></pre>
-
- <p><em>class</em>属性に<code>SSLSocketReceiver</code>を指定していること、そして、リモートアペンダーが信頼できるかどうかを検証するために使用するトラストストアの場所とパスワードを指定しているところが重要なところです。sslプロパティの設定内容について詳しくは<a href="./15-usingSSL.html">SSLを使用する</a>を参照してください。
-
- </p>
-
- <p>この設定をつかってレシーバーのサンプルアプリケーションを実行しましょう。</p>
-
- <p class="source">java -Dhost=localhost -Dport=6001 \
- -Dtruststore=file:src/main/java/chapters/appenders/socket/ssl/truststore.jks \
- -Dpassword=changeit \
- chapters.receivers.socket.ReceiverExample \
- src/main/java/chapters/receivers/socket/receiver4.xml</p>
-
- <p>アプリケーションが開始すると、レシーバーは設定ファイルで指定されたリモートアペンダーに接続しようとします。まだアペンダーが実行されていないときは、定期的に"接続を拒否されました"というメッセージがログに出力されrます。レシーバーは<span class="prop">reconnectionDelay</span>プロパティで指定した時間間隔で、アペンダーに接続できるまで、再接続を繰り返します。
- </p>
-
- <p>レシーバーが接続するアペンダーのためのサンプルアプリケーションを実行しましょう。アプリケーションが開始すると、アプリケーションはユーザー入力を待ち受けます。<code>SSLServerSocketAppender</code>はレシーバーからの接続を待ち受けつつ、接続されているレシーバーにユーザー入力をメッセージとして発生したロギングイベントを配信します。アペンダーのサンプルアプリケーションを実行しましょう。</p>
-
- <p class="source">java -Dport=6001 \
- -Dkeystore=file:src/main/java/chapters/appenders/socket/ssl/keystore.jks \
- -Dpassword=changeit \
- chapters.receivers.socket.AppenderExample \
- src/main/java/chapters/receivers/socket/appender4.xml</p>
-
- <p>レシーバーが接続していない状態で何か入力しても、そのメッセージは単純に破棄されるだけです。</p>
-
- <p>繰り返しになりますが、この例では自己署名したX.509証明書を使用していますが、これはあくまでもテストだからです。<strong>本番環境においては、SSL対応のlogbackコンポーネントが自身の身元を証明するため、適切なX.509証明書を取得しなければなりません</strong>。詳しくは<a href="./15-usingSSL.html">SSLを使用する</a>を参照してください。
-</p>
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-
- </p></div>
- </body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/usingSSL.html b/logback-site/src/site/pages/manual/usingSSL.html
index 77b7fd3..b6dd8eb 100644
--- a/logback-site/src/site/pages/manual/usingSSL.html
+++ b/logback-site/src/site/pages/manual/usingSSL.html
@@ -25,11 +25,7 @@
<script src="menu.js" type="text/javascript"></script>
</div>
<div id="content">
-
<h1>Chapter 15: Using SSL</h1>
-
-
- <a href="usingSSL_ja.html">和訳 (Japanese translation)</a>
<div class="quote">
@@ -653,14 +649,14 @@
<th>Description</th>
</tr>
<tr>
- <td><a name="parameters.excludedCipherSuites"></a>
- <span class="prop" container="parameters">excludedCipherSuites</span></td>
+ <td><a name="parameters.excludedCipherSpecs"></a>
+ <span class="prop" container="parameters">excludedCipherSpecs</span></td>
<td><code>String</code></td>
<td>
- <p>Specifies a comma-separated list of SSL cipher suite names or
+ <p>Specifies a comma-separated list of SSL cipher spec names or
patterns to disable during session negotiation. This property is
used to filter the cipher suites supported by the SSL engine,
- such that any cipher suite matched by this property is disabled.
+ such that any cipher spec matched by this property is disabled.
</p>
<p>Each field in the comma-separated list specified for this
property may be a simple string or a regular expression.
@@ -668,16 +664,16 @@
<p>See the <a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">
Standard Names</a> specification in the
<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">
- JSSE Reference Guide</a> for a list of cipher suite names.
+ JSSE Reference Guide</a> for a list of cipher spec names.
</p>
</td>
</tr>
<tr>
- <td><a name="parameters.includedCipherSuites"></a>
- <span class="prop" container="parameters">includedCipherSuites</span></td>
+ <td><a name="parameters.includedCipherSpecs"></a>
+ <span class="prop" container="parameters">includedCipherSpecs</span></td>
<td><code>String</code></td>
<td>
- <p>Specifies a comma-separated list of SSL cipher suite names or
+ <p>Specifies a comma-separated list of SSL cipher spec names or
patterns to enable during session negotiation. This property is
used to filter the cipher suites supported by the SSL engine,
such that only those cipher suites matched by this property are
@@ -689,7 +685,7 @@
<p>See the <a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">
Standard Names</a> specification in the
<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">
- JSSE Reference Guide</a> for a list of cipher suite names.
+ JSSE Reference Guide</a> for a list of cipher spec names.
</p>
</td>
</tr>
@@ -1261,8 +1257,8 @@ Trust this certificate? [no]: <Enter "yes">
<h3>Client and Server Cannot Agree on a Cipher Suite</h3>
<p>NOTE: <strong>This problem usually occurs only when you are
explicitly
- <a href="#parameters.excludedCipherSuites">excluding</a> or
- <a href="#parameters.includedCipherSuites">including</a> SSL
+ <a href="#parameters.excludedCipherSuites">excluding</a> or
+ <a href="#parameters.includedCipherSuites">including</a> SSL
cipher suites in your configuration</strong>.
</p>
diff --git a/logback-site/src/site/pages/manual/usingSSL_ja.html b/logback-site/src/site/pages/manual/usingSSL_ja.html
deleted file mode 100644
index 77a1002..0000000
--- a/logback-site/src/site/pages/manual/usingSSL_ja.html
+++ /dev/null
@@ -1,811 +0,0 @@
-<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
- <title>第15章 SSLを使用する</title>
- <link rel="stylesheet" type="text/css" href="../css/common.css"></link>
- <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen"></link>
- <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print"></link>
- <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"></link>
- </head>
- <body dir="ltr" onload="prettyPrint(); decorate();">
- <script type="text/javascript">prefix='../';</script>
- <script type="text/javascript" src="../js/prettify.js"></script>
- <script src="../templates/header.js" type="text/javascript"></script>
- <script type="text/javascript" src="../js/dsl.js"></script>
- <script type="text/javascript" src="../js/jquery-min.js"></script>
- <script type="text/javascript" src="../js/decorator.js"></script>
- <div id="left">
- <noscript>Please turn on Javascript to view this menu</noscript>
- <script src="../templates/left.js" type="text/javascript"></script>
- </div>
- <div id="right">
- <script src="menu_ja.js" type="text/javascript"></script>
- </div>
- <div id="content">
- <h1>第15章 SSLを使用する</h1>
-
- <div class="quote">
-
- <p><em>建築物と創造物の間には越えられない壁があります。それは、建築物は作られた後でしか愛されることができないのに、創造物は存在する前から愛されていることです。</em></p>
- <p>—CHARLES DICKENS</p>
- </div>
-
- <script type="text/javascript" src="../templates/creative.js"></script>
-
- <p>logbackはソケットベースのアペンダーから遠隔のレシーバーにログを配信するために、Secure Socket Layer(SSL)を使用することが出来ます。SSLに対応したアペンダーとレシーバーを使うと、シリアライズされたロギングイベントはセキュアなチャネルで配信されます。
- </p>
-
- <h2 class="doAnchor">SSLとそれを使うコンポーネントの役割</h2>
-
- <p>アペンダーやレシーバーはサーバーとしても振る舞うし、クライアントとしても振る舞うことができます。これはネットワーク接続を始める方向によるものです。サーバーとして振る舞うとき、logbackのコンポーネントは外部のクライアントコンポーネントからの接続を待ち受けます。逆に、クライアントとして振る舞うコンポーネントは、外部のサーバーコンポーネントに接続し始めます。たとえば、<em>クライアント</em>として振る舞うアペンダーは、<em>サーバー</em>として振る舞うレシーバーに接続するのです。あるいは、<em>クライアント</em>として振る舞うレシーバーが、 <em>サーバー</em>として振る舞うアペンダーに接続します。</p>
-
- <p>コンポーネントの役割は、基本的にコンポーネントタイプによって決まります。たとえば、 <code>SSLServerSocketAppender</code>はサーバーとして振る舞うアペンダーコンポーネントですし、<code>SSLSocketAppender</code>はクライアントとして振る舞うアペンダーコンポーネントです。このように、開発者もアプリケーション管理者も、思った通りの方向でネットワーク接続を始められるようにlogbackのコンポーネントを設定することができます。</p>
-
- <p>SSLのコンテキストにおいて接続を開始する方向は非常に重要です。なぜなら、サーバーコンポーネントは接続してくるクライアントに対してX.509証明書を使って自分のことを証明しなければならないからです。クライアントコンポーネントはサーバーに接続するとき、信頼できるかどうかをサーバーの証明書で検証します。開発者やアプリケーション管理者はlogbackのコンポーネントの役割をきちんと理解しておかなければなりません。つまり、サーバーならキーストア(サーバーのX.509証明書を配置します)を適切に構成し、クライアントならトラストストア(信頼できるサーバーかどうかを検証するときに使用する自己署名ルート証明書を配置します)を適切に構成しなければなりません。</p>
-
- <p>SSLが<em>相互認証</em>するように設定されている場合、サーバーコンポーネントとクライアントコンポーネントの両方が、それぞれのピアから信頼性を検証された正当なX.509証明書を持っていなければなりません。相互認証はサーバーコンポーネントで設定するものなので、開発者もアプリケーション管理者も、コンポーネントがちゃんとサーバーとして振る舞っていることをきちんと把握しておかなければなりません。</p>
-
- <p>本章では、サーバーとして振る舞うアペンダーやレシーバーのことを、単に<em>サーバーコンポーネント</em>あるいは<em>サーバー</em>と呼ぶことにします。そして、クライアントとして振る舞うコンポーネントは<em>クライアントコンポーネント</em>あるいは<em>クライアント</em>と呼ぶことにします。
-
- <h2 class="doAnchor">SSLとX.509証明書</h2>
-
- <p>SSLに対応したlogbackコンポーネントを使うには、SSLサーバーとして動作するコンポーネントが自分のことを証明するのに、X.509証明書(秘密鍵とそれに対応する証明書、および、CAの証明書チェーン)が必要になります。相互認証を使いたいときは、SSLクライアントとして動作するコンポーネントの証明書も必要です。
- </p>
- <p>民間の証明機関(CA)だけでなく、独自のCAで発行した証明書を使うことができるのですが、自己署名した証明書を使うこともできます。必要事項は次のとおりです。</p>
- <ol>
- <li>(自己署名証明書を使わない場合)サーバーコンポーネントに、サーバーの秘密鍵を含むキーストア、対応する証明書、およびCAの証明書チェーンを指定しなければなりません。
- </li>
- <li>クライアントコンポーネントに、信頼されたルートCA証明書(複数可)または、サーバの自己署名ルート証明書を含むトラストストアを指定しなければなりません。
- </li>
- </ol>
-
- <h2 class="doAnchor">SSL用のlogbackコンポーネントの設定</h2>
- <p>logbackがSSL対応するのに使っているJava Secure Sockets Extension(JSSE)とJava 暗号化アーキテクチャ(JCA)には設定可能な項目がたくさんあります。また、プラグイン可能なフレームワークなので、組み込みのSSLとプラットフォーム固有の暗号化機能は差し替え可能になっています。SSLに対応したlogbackのコンポーネントでは、SSLエンジンと暗号化プロバイダーに設定できることは全て設定できるようになっています。ですので、利用者によって固有のセキュリティ要件を満たすことができます。
- </p>
-
- <h3>JSSEのシステムプロパティを使った基本的なSSLの設定</h3>
- <p>SSLに対応したlogbackのコンポーネントでは、SSLの設定可能なプロパティのほとんどについて妥当な初期値が用意されています。したがって、ほとんどの場合いくつかJSEEのシステムプロパティを指定するだけで済むでしょう。
- </p>
-
- <p>このセクションの残りの部分では、ほとんどの環境で必要になる特定のJSSEプロパティについて説明します。システムプロパティを使ってJSSEをカスタマイズする方法の詳細については、
-<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#InstallationAndCustomization">JSSEのカスタマイズ</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>を参照してください。
- </p>
-
- <p>サーバーとして振る舞うSSL対応のlogbackアペンダーやレシーバー(<code>SSLServerSocketReceiver</code>や<code>SSLServerSocketAppender</code>や<code>SimpleSSLSocketServer</code>)を使うときは、JSSEのシステムプロパティで秘密鍵と証明書を含むキーストアの場所と種類とパスワードを指定しなければなりません。
- </p>
-
- <h4><a name="basicConfig.keyStore"></a>サーバー側でキーストアを指定するためのシステムプロパティ</h4>
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><code>javax.net.ssl.keyStore</code></td>
- <td>サーバーコンポーネントの秘密鍵と証明書を含むファイルの、ファイルシステム上のパスを指定します。</td>
- </tr>
- <tr>
- <td><code>javax.net.ssl.keyStoreType</code></td>
- <td>キーストアの種類を指定します。このプロパティが指定されていない場合、プラットフォームのデフォルト(JKS)になります。
- </td>
- </tr>
- <tr>
- <td><code>javax.net.ssl.keyStorePassword</code></td>
- <td>キーストアにアクセスするためのパスワードを指定します。
- </td>
- </tr>
- </table>
-
- <p><a href="./15-usingSSL.html#Examples">こちらの例</a>で、SSL対応のサーバーコンポーネントを実行する際にシステムプロパティを指定する方法を確認してください。
- </p>
-
- <p>サーバーコンポーネントが民間の証明機関(CA)で署名された証明書を使うときは、<strong>おそらくクライアントコンポーネントでSSLの設定をする必要はありません。</strong>サーバー側では、JVMのシステムプロパティとしてキーストアを指定するだけでよいです。
- </p>
-
- <p>自己署名したサーバー証明書か、Javaのデフォルトのトラストストアに含まれないルート証明書(社内用の証明局など)で署名したサーバー証明書を使うときは、JSEEシステムプロパティでトラストストアの場所、種類、パスワードを指定するか、サーバー証明書を署名した信頼できるルート証明書を指定しなければなりません。<strong>SSL対応のクライアントコンポーネントを利用するアプリケーションごとに、これらのシステムプロパティを設定しなければなりません</strong> 。
- </p>
-
- <h4><a name="basicConfig.trustStore"></a>クライアント側でトラストストアを指定するためのシステムプロパティ</h4>
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><code>javax.net.ssl.trustStore</code></td>
- <td>サーバーコンポーネントの証明書か、サーバー証明書に署名した認証局(CA)の信頼できるルート証明書のファイルシステム上のパスを指定します。</td>
- </tr>
- <tr>
- <td><code>javax.net.ssl.trustStoreType</code></td>
- <td>トラストストアの種類を指定します。このプロパティが指定されていない場合、プラットフォームのデフォルト(JKS)になります。
- </td>
- </tr>
- <tr>
- <td><code>javax.net.ssl.trustStorePassword</code></td>
- <td>トラストストアにアクセスするためのパスワードを指定します。
- </td>
- </tr>
- </table>
-
- <p><a href="./15-usingSSL.html#Examples">こちらの例</a>で、SSL対応のクライアントコンポーネントを実行する際にシステムプロパティを指定する方法を確認してください。
- </p>
-
- <h3 class="doAnchor"><a name="SSLConfiguration"></a>高度なSSLの設定</h3>
- <p>JSSEシステムプロパティによる基本的なSSLの設定だけでは足りないことがあります。Webアプリケーションで<code>SSLServerSocketReceiver</code>を使用しているとき、WebクライアントがWebサーバーを識別するための証明書と、ロギングクライアントがロギングサーバーを識別するための証明書では別のものを使いたいはずです。ロギングサーバーには、認証、および、認可されたリモートロガーだけが接続できるよう、SSLのクライアントを認証したいこともあるでしょう。あるいは、内部ネットワークではSSLプロトコルと暗号スイートを使わなければならない、というポリシーを強制する組織があるかもしれません。これらのいずれかのニーズを満たすためには、logbackの高度なSSL設定オプションを確かめておいたほういいでしょう。</p>
- <p>logbackのコンポーネントでSSLを設定するときは、<code>ssl</code>プロパティに指定します。
- </p>
- <p><code>SSLServerSocketReceiver</code>を使うときは、keystoreプロパティでサーバーの証明書を含んだキーストアを指定します。
- </p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-ssl-serverKeyStore');">Groovyとして表示</span>
- <pre id="logback-ssl-serverKeyStore" class="prettyprint source"><configuration>
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="CONSOLE" />
- </root>
-
- <receiver class="ch.qos.logback.classic.net.server.SSLServerSocketReceiver">
- <ssl>
- <keyStore>
- <location>classpath:/logging-server-keystore.jks</location>
- <password>changeit</password>
- </keyStore>
- </ssl>
- </receiver>
-
-</configuration></pre>
-
- <p>ここでは、キーストアの場所にアプリケーションのクラスパスのルートに配置された<em>logging-server-keystore.jks</em>が指定されています。もちろん、fileから始まるURLを指定することもできます。
- </p>
- <p>アプリケーションで<code>SSLSocketAppender</code>を使いたいけど、アプリケーション自体の(JSEEの)デフォルトのトラストストアを変更したくないときは、<code>javax.net.ssl.trustStore</code>プロパティを使うことができます。
- </p>
-
- <span class="asGroovy" onclick="return asGroovy('logback-ssl-clientTrustStore');">Groovyとして表示</span>
- <pre id="logback-ssl-clientTrustStore" class="prettyprint source"><configuration>
- <appender name="SOCKET" class="ch.qos.logback.classic.net.SSLSocketAppender">
- <ssl>
- <trustStore>
- <location>classpath:/logging-server-truststore.jks</location>
- <password>changeit</password>
- </trustStore>
- </ssl>
- </appender>
-
- <root level="debug">
- <appender-ref ref="SOCKET" />
- </root>
-
-</configuration></pre>
-
- <p>ここでは、トラストストアの場所にアプリケーションのクラスパスのルートに配置された<em>logging-server-truststore.jks</em>が指定されています。
-もちろん、fileから始まるURLを指定することもできます。
-
- </p>
-
- <h4>SSLプロパティ</h4>
-
- <p>JSSEは設定可能なオプションを大量に公開しています。logbackのSSL対応では公開された設定のほとんどを設定ファイル中で指定できるようになっています。XML形式の設定ファイルでは、SSLの各種設定をssl要素で設定します。ssl要素に対応しているのは<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/SSLConfiguration.html">SSLConfiguration</a></code>クラスです。
- </p>
-
- <p>SSLに対応したコンポーネントを設定するには、デフォルト値では困る時にこれらのプロパティを設定するだけでよいです。なんでもかんでも設定してしまうと、こんがらがってしまって問題を解析するのがとてもむずかしくなってしまいます。
- </p>
-
- <p>SSLの設定におけるトップレベルのプロパティは次のとおりです。これらのプロパティの多くについて、さらに下位のプロパティが存在します。トップレベルなプロパティの一覧表の後に説明します。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>Type</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="ssl">keyManagerFactory</span></td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/KeyManagerFactoryFactoryBean.html">
- <code>KeyManagerFactoryFactoryBean</code></a>
- </td>
- <td><code><a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/net/ssl/KeyManagerFactory.html">KeyManagerFactory</a></code>の設定を指定します。このプロパティが設定されていない場合は、JVMのデフォルトのファクトリが使われます。<a href="./15-usingSSL.html#KeyManagerFactoryFactoryBean">キーマネージャファクトリの設定</a>を参照してください。
- </td>
- </tr>
- <tr>
- <td><a name="ssl.keyStore"></a><span class="prop" container="ssl">keyStore</span></td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/KeyStoreFactoryBean.html">
- <code>KeyStoreFactoryBean</code></a>
- </td>
- <td>
- <p><code><a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/security/KeyStore.html">KeyStore</a></code>の設定を指定します。キーストアには、少なくとも1つのX.509証明書(秘密鍵と対応する証明書、あるいはCA証明書チェーン)が含まれていなければなりません。この証明書がSSLのリモートピアに提示されます。
- </p>
- <p>SSLクライアント(<code>SSLSocketAppender</code>など)の設定に<span class="prop" container="ssl">keyStore</span>プロパティが必要になるのは、リモートピアへの接続にクライアント認証が必要な場合だけです。
- </p>
- <p>SSLサーバー(<code>SimpleSSLSocketServer</code>など)の<span class="prop" container="ssl">keyStore</span>プロパティには、サーバー証明書を格納したキーストアを指定します。このプロパティが設定されていない場合は、JSSEのシステムプロパティ<code>javax.net.ssl.keyStore</code>に、サーバーのキーストアの場所を指定しておかなければなりません。詳細は<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#InstallationAndCustomization">JSSEのカスタマイズ</a>を参照してください。
- </p>
- <p><a href="./15-usingSSL.html#KeyStoreFactoryBean">キーストアの設定</a>については後述します。
- </p>
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="ssl">parameters</span></td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/SSLParametersConfiguration.html">
- <code>SSLParametersConfiguration</code></a></td>
- <td>SSLセッションのネゴシエーションで使用するいろいろなパラメータを指定します。<a href="./15-usingSSL.html#SSLParametersConfiguration">SSLパラメータの設定</a>については後述します。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="ssl">protocol</span></td>
- <td><code>String</code></td>
- <td><code><a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/net/ssl/SSLContext.html">SSLContext</a></code>を作成するために使用するSSLプロトコルを指定します。<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>に記載された<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">標準名</a>を指定してください。このプロパティが設定されていない場合は、JVMのデフォルトのプロトコル名が使用されます。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="ssl">provider</span></td>
- <td><code>String</code></td>
- <td><code><a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/net/ssl/SSLContext.html">SSLContext</a></code>を作成するために使用するJSSEプロバイダー名を指定します。このプロパティが設定されていない場合は、JVMのデフォルトのJSSEプロバイダ名が使用されます。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="ssl">secureRandom</span></td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/SecureRandomFactoryBean.html">
- <code>SecureRandomFactoryBean</code></a>
- </td>
- <td><code><a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/security/SecureRandom.html">SecureRandom</a></code>(安全な乱数生成器)の設定を指定します。このプロパティが設定されていない場合は、JVMのデフォルトの乱数生成器が使用されます。<a href="./15-usingSSL.html#SecureRandomFactoryBean">安全な乱数生成器の設定</a>については後述します。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="ssl">trustManagerFactory</span></td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/TrustManagerFactoryFactoryBean.html">
- <code>TrustManagerFactoryFactoryBean</code></a>
- </td>
- <td><code><a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/net/ssl/TrustManagerFactory.html">TrustManagerFactory</a></code>の設定を指定します。このプロパティが設定されていない場合は、JVMのデフォルトのファクトリーを使用します。<a href="./15-usingSSL.html#TrustManagerFactoryFactoryBean">トラストマネージャファクトリー</a>については後述します。
- </td>
- </tr>
- <tr>
- <td><a name="ssl.trustStore"></a><span class="prop" container="ssl">trustStore</span></td>
- <td><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/KeyStoreFactoryBean.html">
- <code>KeyStoreFactoryBean</code></a>
- </td>
- <td>
- <p>SSLのリモートピアの同一性を検証するために使う<code><a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/security/KeyStore.html">KeyStore</a></code>の設定を指定します。キーストアには少なくとも1つ以上の<em>トラストアンカー</em>が含まれていなければなりません。"信頼できる"と印の付けられた自己署名証明書のことです。一般的に、トラストストアには自己署名CA証明書が含まれています。
- </p>
- <p>このプロパティで指定したトラストストアは、JSSEの<code>java.net.ssl.trustStore</code>システムプロパティで指定された全てのトラストストアを上書きします。詳細は<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#InstallationAndCustomization">JSSEのカスタマイズ</a>を参照してください。
-
- </p>
- </td>
- </tr>
- </table>
-
- <h4 class="doAnchor"><a name="KeyStoreFactoryBean"></a>キーストアの設定</h4>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/KeyStoreFactoryBean.html">KeyStoreFactoryBean</a></code>は、X.509証明書を格納した<a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/security/KeyStore.html"><code>KeyStore</code></a>を作成するために必要な設定を提供します。このファクトリーBeanのプロパティは、<a href="./15-usingSSL.html#SSLConfiguration">SSLの設定</a>で紹介した<a href="./15-usingSSL.html#ssl.keyStore"><span class="prop" container="ssl">keyStore</span></a>および<a href="./15-usingSSL.html#ssl.tr [...]
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="keyStore">location</span></td>
- <td><code>String</code></td>
- <td>キーストアの場所をURLで指定します。ファイルシステム上のキーストアを指定するときは、<code>file:</code>形式のURLを指定します。<code>classpath:</code>形式のURLを指定すれば、クラスパス上のリソースを指定することもできます。URLスキームがないときは、<code>classpath:</code>が指定されたものとして扱います。</td>
- </tr>
- <tr>
- <td><span class="prop" container="keyStore">password</span></td>
- <td><code>String</code></td>
- <td>キーストアにアクセスするためのパスワードを指定します。</td>
- </tr>
- <tr>
- <td><span class="prop" container="keyStore">provider</span></td>
- <td><code>String</code></td>
- <td><code>KeyStore</code>を作成するために使用するJCAプロバイダー名を指定します。このプロパティが設定されていない場合は、JVMのデフォルトのキーストアプロバイダーが使用されます。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="keyStore">type</span></td>
- <td><code>String</code></td>
- <td><code>KeyStore</code>の種類を指定します。指定できるのは、<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html">Java暗号化アーキテクチャ</a>に記載された仕様である<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html#AppA">標準名</a>です。このプロパティが設定されていない場合は、JVMのデフォルトが使用されます。
- </td>
- </tr>
- </table>
-
- <h4><a name="KeyManagerFactoryFactoryBean"></a>キーマネージャファクトリーの設定</h4>
-
- <p><a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/net/ssl/KeyManagerFactory.html"><code>KeyManagerFactory</code></a>を作成するために必要な設定は、<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/KeyManagerFactoryFactoryBean.html">KeyManagerFactoryFactoryBean</a></code>によって提供されます。普通はキーマネージャーファクトリーの明示的な設定は不要です。ほぼ全ての場合にJVMのデフォルトのファクトリーで十分だからです。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="keyManagerFactory">algorithm</span></td>
- <td><code>String</code></td>
- <td><code>KeyManagerFactory</code>が使うアルゴリズム名を指定します。指定できるのは、<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>に記載された<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">標準名</a>だけです。このプロパティが設定されていない場合は、JVMのデフォルトのアルゴリズムが使用されます。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="keyManagerFactory">provider</span></td>
- <td><code>String</code></td>
- <td><code>SecureRandom</code>生成器を生成するのに使われるJCAプロバイダー名を指定します。このプロパティが設定されていない場合は、JVMのデフォルトのJSSEプロバイダーが使用されます。
- </td>
- </tr>
- </table>
-
- <h4 class="doAnchor"><a name="SecureRandomFactoryBean"></a>安全な乱数生成器の設定</h4>
-
- <p><a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/security/SecureRandom.html"><code>SecureRandom</code></a>生成器を作成するために必要な設定は、<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/SecureRandomFactoryBean.html">SecureRandomFactoryBean</a></code>によって提供されます。JVMのデフォルトの乱数生成器で十分なことがほとんどなので、普通は明示的に設定する必要がありません。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="secureRandom">algorithm</span></td>
- <td><code>String</code></td>
- <td><code>安全な乱数生成器</code>のアルゴリズム名を指定します。指定できるのは<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html">Java暗号化アーキテクチャの</a>に記載された<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html#AppA">標準名</a>だけです。このプロパティが設定されていない場合は、JVMのデフォルトの乱数生成アルゴリズムが使用されます。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="secureRandom">provider</span></td>
- <td><code>String</code></td>
- <td><code>安全な乱数生成器</code>を生成するために使われるJCAプロバイダー名を指定します。このプロパティが設定されていない場合は、JVMのデフォルトのJSSEプロバイダ名が使用されます。
- </td>
- </tr>
- </table>
-
- <h4><a name="SSLParametersConfiguration"></a> SSLパラメータの設定</h4>
-
- <p><code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/SSLParametersConfiguration.html">SSLParametersConfiguration</a></code>を使って、SSLプロトコル、暗号スイート、およびクライアント認証オプションをカスタマイズすることができます。
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><a name="parameters.excludedCipherSpecs"></a>
- <span class="prop" container="parameters">excludedCipherSpecs</span></td>
- <td><code>String</code></td>
- <td>
- <p>セッションネゴシエーションをする際に除外するSSL暗号方式名をカンマ区切りリストで指定します。このプロパティに指定する値は、SSLエンジンがサポートしている暗号方式を限定するために使用されます。マッチした暗号方式はすべて無効になります。
- </p>
- <p>カンマ区切りリストのそれぞれの項目には単純な文字列あるいは正規表現を指定することができます。
- </p>
- <p>指定できるのは、<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">標準名</a>にあるものだけです。
- </p>
- </td>
- </tr>
- <tr>
- <td><a name="parameters.includedCipherSpecs"></a>
- <span class="prop" container="parameters">includedCipherSpecs</span></td>
- <td><code>String</code></td>
- <td>
- <p>セッションネゴシエーションをする際に使用するSSL暗号方式名をカンマ区切りリストで指定します。
-このプロパティに指定する値は、SSLエンジンがサポートしている暗号方式を特定するために使用されます。マッチした暗号方式はすべて有効になります。
- </p>
- <p>カンマ区切りリストのそれぞれの項目には単純な文字列あるいは正規表現を指定することができます。
- </p>
- <p>指定できるのは、<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">標準名</a>にあるものだけです。
-
- </p>
- </td>
- </tr>
- <tr>
- <td><a name="parameters.excludedProtocols"></a>
- <span class="prop" container="parameters">excludedProtocols</span></td>
- <td><code>String</code></td>
- <td>
- <p>セッションネゴシエーションをする際に除外するSSLプロトコル名をカンマ区切りリストで指定します。このプロパティに指定する値は、SSLエンジンがサポートしているSSLプロトコルを限定するために使用されます。マッチしたSSLプロトコルはすべて無効になります。
- </p>
- <p>カンマ区切りリストのそれぞれの項目には単純な文字列あるいは正規表現を指定することができます。
- </p>
- <p>指定できるのは、<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">標準名</a>にあるものだけです。
- </p>
- </td>
- </tr>
- <tr>
- <td><a name="parameters.includedProtocols"></a>
- <span class="prop" container="parameters">includedProtocols</span></td>
- <td><code>String</code></td>
- <td>
- <p>セッションネゴシエーションをする際に使用するSSLプロトコル名をカンマ区切りリストで指定します。
-このプロパティに指定する値は、SSLエンジンがサポートしているSSLプロトコルを特定するために使用されます。マッチしたSSLプロトコルはすべて有効になります。
-
- </p>
- <p>カンマ区切りリストのそれぞれの項目には単純な文字列あるいは正規表現を指定することができます。
-
- </p>
- <p>指定できるのは、<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">標準名</a>にあるものだけです。
- </p>
- </td>
- </tr>
- <tr>
- <td><a name="parameters.needClientAuth"></a>
- <span class="prop" container="parameters">needClientAuth</span></td>
- <td><code>boolean</code></td>
- <td>サーバー側でクライアント認証が<em>必要</em>なときは、このプロパティに<code>true</code>を指定します。クライアントコンポーネント(<code>SSLSocketAppender</code>など)の場合はこのプロパティは無視されます。
- </td>
- </tr>
- <tr>
- <td><a name="parameters.wantClientAuth"></a>
- <span class="prop" container="parameters">wantClientAuth</span></td>
- <td><code>boolean</code></td>
- <td>サーバー側でクライアント認証が<em>必要</em>なときは、このプロパティに<code>true</code>を指定します。
-クライアントコンポーネント(<code>SSLSocketAppender</code>など)の場合はこのプロパティは無視されます。
-
- </td>
- </tr>
- </table>
-
- <h4><a name="TrustManagerFactoryFactoryBean"></a>トラストマネージャファクトリーの設定</h4>
-
- <p><a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/net/ssl/TrustManagerFactory.html"><code>TrustManagerFactory</code></a>を作成するために必要な設定は、<code><a href="http://logback.qos.ch/xref/ch/qos/logback/core/net/ssl/TrustManagerFactoryFactoryBean.html">TrustManagerFactoryFactoryBean</a></code>が提供します。JVMのデフォルトのファクトリーで十分なことがほとんどなので、普通は明示的に設定する必要がありません。
-
- </p>
-
- <table class="bodyTable striped">
- <tr>
- <th>プロパティ名</th>
- <th>型</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><span class="prop" container="trustManagerFactory">algorithm</span></td>
- <td><code>String</code></td>
- <td><code>TrustManagerFactory</code>のアルゴリズム名を指定します。指定できるのは、<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html">JSSEリファレンスガイド</a>の<a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">標準名</a>にあるものだけです。このプロパティが設定されていない場合は、JVMのデフォルトのキーマネージャのアルゴリズムが使用されます。
- </td>
- </tr>
- <tr>
- <td><span class="prop" container="trustManagerFactory">provider</span></td>
- <td><code>String</code></td>
- <td><code>安全な乱数生成器</code>を生成するために使われるJCAプロバイダー名を指定します。このプロパティが設定されていない場合は、JVMのデフォルトのJSSEプロバイダが使用されます。
- </td>
- </tr>
- </table>
-
- <h2 class="doAnchor"><a name="Examples"></a>例</h2>
-
- <h3>JSSEシステムプロパティを使用する</h3>
- <p>JSSEシステムプロパティは、サーバーのX.509証明書を含むキーストアの場所とパスワードを指定するために使われます。また、クライアントコンポーネントが信頼できるサーバーかどうかを検証するために使用する、自己署名ルートCA証明書を含むトラストストアの場所とパスワードを指定します。</p>
-
- <h4>サーバーのキーストアを指定する</h4>
- <p>サーバーコンポーネントを実行する場合、サーバーの証明書を含むキーストアの場所とパスワードを指定しなければなりません。そのために、JSSEシステムプロパティを使用することができます。logbackの配布物に含まれる<code>SimpleSSLSocketServer</code>を実行してみましょう。</p>
-
- <p class="source">java -DkeyStore=/etc/logback-server-keystore.jks \
- -DkeyStorePassword=changeit -DkeyStoreType=JKS \
- ch.qos.logback.net.SimpleSSLSocketServer 6000 /etc/logback-server-config.xml</p>
-
- <p>JSSEシステムプロパティの<em>keyStore</em>に、サーバーのキーストアへのパスを指定するのを忘れないようにしてください。そのパスを<em>logback.xml</em>で指定するときはURLで指定します。</p>
-
- <p>この例ではlogbackの配布物に含まれているスタンドアローンのサーバーアプリケーションを実行しました。どんなアプリケーションでも、logbackのサーバーコンポーネントを使う場合は同じようにシステムプロパティを指定できます。
-
- <h4>クライアントのトラストストアを指定する</h4>
-
- <p>クライアントコンポーネントを使用する場合、信頼できるサーバーかどうかを検証するために使用する、ルートCA証明書を含むトラストストアの場所とパスワードを指定しなければなりません。そのためにJSSEシステムプロパティを使用することができます。logbackのSSL対応のクライアントコンポーネントを複数使用する<code>com.example.MyLoggingApplication</code>を実行してみましょう。</p>
-
- <p class="source">java -DtrustStore=/etc/logback-client-truststore.jks \
- -DtrustStorePassword=changeit -DtrustStoreType=JKS \
- com.example.MyLoggingApplication</p>
-
- <p>JSSEシステムプロパティの<em>trustStore</em>に、トラストストアへのパスを指定するのを忘れないようにしてください。そのパスを<em>logback.xml</em>で指定するときはURLで指定します。</p>
-
- <h3>サーバーコンポーネントの自己署名証明書を生成して利用する</h3>
- <p>自己署名証明書を生成するには、Javaランタイム環境(JRE)に同梱されている<em>keytoolユーティリティ</em>を使用します。以下の手順では、サーバーコンポーネントの自己署名X.509証明書をキーストアに配置してから、クライアントコンポーネントの使用するトラストストアを作成します。
- </p>
-
- <h4>サーバコンポーネントの証明書の生成</h4>
- <p>次のコマンドを実行すると、<em>server.keystore</em>というファイル名の自己署名クライアント証明書を生成します。</p>
- <pre class="source">keytool -genkey -alias server -dname "CN=my-logging-server" \
- -keyalg RSA -validity 365 -keystore server.keystore
-Enter keystore password: <Enter password of your choosing>
-Re-enter new password: <Re-enter same password>
-Enter key password for <my-logging-server>
- (RETURN if same as keystore password): <Press RETURN>
-</pre>
-
- <p><em>dname</em>に指定した<em>my-logging-server</em>は、正当なものであればどんなものでも構いません。サーバーを実行するホストの完全修飾ドメイン名にするとよいでしょう。<em>validity</em>には証明書の有効期限が切れるまでの日数を指定します。</p>
-
- <p>本番環境の設定で重要になるのが、サーバー証明書を配置するキーストアにとても強力なパスワードを指定することです。このパスワードによって、サーバーの秘密鍵にアクセスできるのが限られた関係者だけであることを保証します。後の手順でこのパスワードが必要になるので、サーバーの設定をするときに心の中にメモしておいてください。
- </p>
-
- <h4>クライアントコンポーネント用のトラストストアの作成</h4>
- <p>クライアントコンポーネントの設定に使用するため、前の手順で作成したサーバーの証明書をキーストアからエクスポートして、トラストストアにインポートしましょう。次のコマンドを実行すると、証明書をエクスポートして<em>server.truststore</em>というファイル名のトラストストアにインポートします。</p>
-
- <pre class="source">keytool -export -rfc -alias server -keystore server.keystore \
- -file server.crt
-Enter keystore password: <Enter password you chose for in previous step>
-
-keytool -import -alias server -file server.crt -keystore server.truststore
-Enter keystore password: <Enter password of your choosing>
-Re-enter new password: <Re-enter same password>
-Owner: CN=my-logging-server
-Issuer: CN=my-logging-server
-Serial number: 6e7eea40
-Valid from: Sun Mar 31 07:57:29 EDT 2013 until: Mon Mar 31 07:57:29 EDT 2014
-
- ...
-
-Trust this certificate? [no]: <Enter "yes">
-</pre>
-
- <p>最初のコマンドは、キーストアからエクスポートしたサーバー証明書(サーバーの秘密鍵ではありません)を<em>server.crt</em>というファイル名で保存します。二つ目のコマンドは、サーバー証明書を含んだ<em>server.truststore</em>という新しいトラストストアを作成します。
- </p>
-
- <p>本番環境の設定で重要になるのが、トラストストアにとても強力な、そして、サーバーのキーストアに使用したパスワードとは異なるパスワードを設定することです。ここで指定したパスワードは、クライアントのアペンダーの設定に必要になるので心の中にメモしておいてください。
- </p>
-
- <h4>サーバコンポーネントの設定</h4>
- <p><em>server.keystore</em>をアプリケーションアーカイブの内部に取り込まなければならないかもしれません。キーストアはアプリケーションのクラスパスリソースとして扱うこともできますし、単にサーバーを実行するホストのファイルシステム上に配置することもできます。設定ファイルからキーストアの場所を指定するときは、<code>classpath:</code>から始まるURLか、<code>file:</code>から始まるURLのいずれかを指定します。設定ファイルを見てみましょう。</p>
-
- <p class="example">例:サーバーコンポーネントの設定</p>
- <pre class="prettyprint source"><configuration debug="true">
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-
- <server class="ch.qos.logback.classic.net.server.SSLServerSocketReceiver">
- <ssl>
- <keyStore>
- <location>classpath:server.keystore</location>
- <password>${server.keystore.password}</password>
- </keyStore>
- </ssl>
- </server>
-</configuration></pre>
-
- <p>この例では、キーストアがアプリケーションのクラスパスのルートに配置されていることを前提としています。</p>
-
- <p>また、キーストアのパスワードには<em>server.keystore.password</em>という変数を指定しています。こうしておけば、どの設定ファイルにもパスワードを書いておかなくてもよくなります。たとえば、アプリケーションが起動した後、ロギングシステムを設定する前にコンソールでパスワード入力を促すプロンプトを出すようにして、システムプロパティ<em>server.keystore.password</em>をプログラム的に設定すればよいのです。
- </p>
-
- <h4>クライアントコンポーネントの設定</h4>
- <p>クライアントとして振る舞うSSL対応のコンポーネントを使用するアプリケーションそれぞれについて、<em>server.truststore</em>をアプリケーションアーカイブの内部に取り込まなければならないかもしれません。トラストストアはアプリケーションのクラスパスリソースとして扱うこともできますし、単にクライアントを実行するホストのファイルシステム上に配置することもできます。
-設定ファイルからトラストストアの場所を指定するときは、<code>classpath:</code>から始まるURLか、<code>file:</code>から始まるURLのいずれかを指定します。
-アペンダーの設定を見てみましょう。</p>
-
- <p class="example">例:アペンダーの設定</p>
-
- <pre class="prettyprint source"><configuration debug="true">
- <appender name="SOCKET" class="ch.qos.logback.classic.net.SSLSocketAppender">
- <remoteHost>${host}</remoteHost>
- <ssl>
- <trustStore>
- <location>classpath:server.truststore</location>
- <password>${server.truststore.password}</password>
- </trustStore>
- </ssl>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="SOCKET" />
- </root>
-</configuration></pre>
-
- <p>この例では、トラストストアがアプリケーションのクラスパスのルートに配置されていることを前提としています。</p>
-
- <p>また、トラストストアのパスワードには<em>server.truststore.password</em>という変数を指定しています。
-こうしておけば、どの設定ファイルにもパスワードを書いておかなくてもよくなります。
-たとえば、アプリケーションが起動した後、ロギングシステムを設定する前にコンソールでパスワード入力を促すプロンプトを出すようにして、システムプロパティ<em>server.truststore.password</em>をプログラム的に設定すればよいのです。
-
- </p>
-
- <h2>SSLの設定を監査する</h2>
- <p>安全な通信が必要とされる環境では、SSLを使うコンポーネントがローカルセキュリティポリシーを満たしていることを検証するため、設定内容を監査しなければならない。logbackでは、自身を初期化している間に行われるSSLの設定について詳細なロギング情報を提供することでこれに対応しています。設定中で<code>debug</code>プロパティを使うことで、監査ログを有効化することができます。</p>
-
- <pre class="prettyprint source"><configuration debug="true">
-
- ...
-
-</configuration></pre>
-
- <p>debugプロパティを有効にすると、ロギングシステムの初期化中に行われるSSLの設定に関するあらゆる情報が得られるようになります。SSL設定の監査ログとして出力されるのは次のようなものです。</p>
-
- <p class="example">例:SSL設定の監査ログ</p>
-
- <pre>06:46:31,941 |-INFO in SSLServerSocketReceiver at 4ef18d37 - SSL protocol 'SSL' provider 'SunJSSE version 1.6'
-06:46:31,967 |-INFO in SSLServerSocketReceiver at 4ef18d37 - key store of type 'JKS' provider 'SUN version 1.6': file:src/main/java/chapters/appenders/socket/ssl/keystore.jks
-06:46:31,967 |-INFO in SSLServerSocketReceiver at 4ef18d37 - key manager algorithm 'SunX509' provider 'SunJSSE version 1.6'
-06:46:31,973 |-INFO in SSLServerSocketReceiver at 4ef18d37 - secure random algorithm 'SHA1PRNG' provider 'SUN version 1.6'
-06:46:32,755 |-INFO in SSLParametersConfiguration at 4a6f19d5 - enabled protocol: SSLv2Hello
-06:46:32,755 |-INFO in SSLParametersConfiguration at 4a6f19d5 - enabled protocol: SSLv3
-06:46:32,755 |-INFO in SSLParametersConfiguration at 4a6f19d5 - enabled protocol: TLSv1
-06:46:32,756 |-INFO in SSLParametersConfiguration at 4a6f19d5 - enabled cipher suite: SSL_RSA_WITH_RC4_128_MD5
-06:46:32,756 |-INFO in SSLParametersConfiguration at 4a6f19d5 - enabled cipher suite: SSL_RSA_WITH_RC4_128_SHA
-06:46:32,756 |-INFO in SSLParametersConfiguration at 4a6f19d5 - enabled cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
-</pre>
-
- <p>ここで示した出力は大幅にカットしてありますが、一般的には次のようなものが含まれています。
- <ul>
- <li>完全なプロトコルのリスト</li>
- <li>プロバイダー</li>
- <li>アルゴリズム</li>
- <li>暗号スイート</li>
- <li>キーストアやトラストストアの場所</li>
- </ul>
- </p>
-
- <p>この監査ログに取り扱いに注意の必要な情報が含まれることはありませんが、セキュリティのベストプラクティスとしては、本番環境の設定の妥当性が確認されたなら、監査ログは無効化するべきです。<code>debug</code>プロパティを消すか、<code>false</code>を指定すれば監査ログは無効化されます。
- </p>
-
- <h2>SSLの設定誤りを解決する</h2>
- <p>SSLの設定が間違っていると、普通ならクライアントとサーバーのコンポーネントの間でセッションを確立できなくなります。これは、クライアントがサーバーに接続しようとしてそれができなかったときにそれぞれで例外をスローすることによって明らかになります。
- </p>
- <p>例外メッセージの内容は、見ているログによって異なります。それは、セッションネゴシエーション中に報告されるエラーの原因は、主にプロトコルの制限によるものだからです。したがって、セッションネゴシエーションの問題を解決するには、クライアントとサーバーの両方のログを調査しなければなりません。
- </p>
-
- <h3>サーバの証明書が使用できません</h3>
- <p>サーバーの証明書が使用できない時、サーバコンポーネントを起動すると次のような例外メッセージがログに出力されます。</p>
-
- <p><em>javax.net.ssl.SSLException: No available certificate or
- key corresponds to the SSL cipher suites which are enabled</em>
- </p>
-
- <p>ほとんどの場合、サーバーの秘密鍵に対応する証明書を含むキーストアの場所を設定し忘れていることが原因です。
- </p>
-
- <h4>ソリューション</h4>
- <p>システムプロパティの<a href="./15-usingSSL.html#basicConfig.keyStore">キーストア</a>か、サーバーコンポーネントの<span class="prop">ssl</span>の設定で<span class="prop"><a href="./15-usingSSL.html#ssl.keyStore">keyStore</a></span>プロパティに、サーバ証明書を含むキーストアの場所を指定してください。あと、キーストアのパスワードも指定してください。
- </p>
-
- <h3>クライアントはサーバーを信頼できません</h3>
- <p>クライアントがサーバに接続しようとするとき、次のような例外メッセージがログに現れます。</p>
-
- <p><em>javax.net.ssl.SSLHandshakeException:
- sun.security.validator.ValidatorException:
- PKIX path building failed</em>
- </p>
- <p>これは、クライアントがサーバーの提示した証明書を信頼できないと判断した場合に発生します。よくある原因としては、サーバーが自己署名サーバー証明書(あるいは内部の認証局で署名したサーバー証明書)を使っている上で、クライアントの使用するトラストストアにサーバーの自己署名証明書が含まれていない(あるいはサーバー証明書に署名したCAの信頼できるルート証明書が含まれていない)ことです。
- </p>
- <p>サーバー証明書が失効している場合も同じような現象が発生します。サーバー側のログを見ることが出来るなら、クライアントが接続しようとするたびに次のような例外メッセージが現れているのがわかると思います。</p>
-
- <p><em>javax.net.ssl.SSLHandshakeException: Received fatal alert: ...</em>
- </p>
-
- <p>例外メッセージの後半部分には、クライアントがサーバー証明書を拒否した理由を表すコードが現れます。
- </p>
- <table class="bodyTable striped">
- <tr>
- <th>コード</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><code>certificate_unknown</code></td>
- <td>クライアントのトラストストアが正しく設定されていないことを示しています。
- </td>
- </tr>
- <tr>
- <td><code>certificate_expired</code></td>
- <td>サーバー証明書が失効しているので更新が必要なことを示しています。
- </td>
- </tr>
- <tr>
- <td><code>certificate_revoked</code></td>
- <td>サーバー証明書に署名した認証局(CA)が、そのサーバー証明書を無効にしたことを示しています。サーバー証明書を更新しなければなりません。
- </td>
- </tr>
- </table>
-
- <h4>ソリューション</h4>
- <p>サーバー側のログに<code>certificate_unknown</code>が現れているときは、システムプロパティ<a href="./15-usingSSL.html#basicConfig.trustStore">トラストストア</a>か、アペンダーの<span class="prop">ssl</span>設定に<a href="./15-usingSSL.html#ssl.trustStore">trustStore</a>プロパティを指定してください。サーバーの自己署名証明書か、証明書に署名したCAのルート証明書を格納した<span class="prop">トラストストア</span>の場所と、アクセスするためのパスワードを指定しなければなりません。
- </p>
-
- <p>サーバー側のログに<code>certificate_expired</code>か<code>certificate_revoked</code>が現れているときは、新しいサーバー証明書が必要です。サーバーの設定で指定したキーストアの場所に、新しいサーバー証明書と対応する秘密鍵を配置してください。自己署名サーバー証明書を使っているときは、クライアントのアペンダーの設定に指定されているトラストストアにも新しい証明書を配置しなければなりません。
- </p>
-
- <h3>サーバーはクライアントを信頼できません
-</h3>
- <p>注: <strong>この問題が生じるのは、サーバーがクライアント証明書を要求するように明示的に設定している場合だけです(<a href="./15-usingSSL.html#parameters.needClientAuth"><span class="prop">needClientAuth</span></a>か<a href="./15-usingSSL.html#parameters.wantClientAuth"><span class="prop">wantClientAuth</span></a>プロパティを指定したときです)。</strong>
- </p>
-
- <p>クライアントがサーバに接続しようとするとき、次のような例外メッセージがログに現れます。
-</p>
-
- <p><em>javax.net.ssl.SSLHandshakeException: Received fatal
- alert: ...</em>
- </p>
-
- <p>例外メッセージの後半部分には、サーバーがクライアントの証明書を拒否した理由を表すコードが現れます。
-
- </p>
- <table class="bodyTable striped">
- <tr>
- <th>コード</th>
- <th>説明</th>
- </tr>
- <tr>
- <td><code>certificate_unknown</code></td>
- <td>サーバのトラストストアが正しく設定されていないことを示しています。
- </td>
- </tr>
- <tr>
- <td><code>certificate_expired</code></td>
- <td>クライアントの証明書が失効しているので更新が必要なことを示しています。
-
- </td>
- </tr>
- <tr>
- <td><code>certificate_revoked</code></td>
- <td>クライアントの証明書に署名した認証局(CA)が、その証明書を無効にしたことを示しています。証明書を更新しなければなりません。
-
- </td>
- </tr>
- </table>
-
- <h4>ソリューション</h4>
- <p>クライアント側のログに<code>bad_certificate</code>が現れているときは、システムプロパティ<a href="./15-usingSSL.html#basicConfig.trustStore">トラストストア</a>かサーバーコンポーネントの<span class="prop">ssl</span>設定の<span class="prop"><a href="./15-usingSSL.html#ssl.trustStore">trustStore</a></span>プロパティに、トラストストアの場所とパスワードを指定しなければなりません。トラストストアにはクライアントの自己署名証明書か、証明書に署名したCAのルート証明書が含まれていなければなりません。
- </p>
-
- <p>サーバー側のログに<code>certifacte_expired</code>あるいは<code>certificate_revoked</code>が現れているときは、新しい証明書が必要です。クライアントの設定で指定したキーストアの場所に、新しい証明書と対応する秘密鍵を配置してください。自己署名証明書を使っているときは、サーバーの設定に指定されているトラストストアにも新しい証明書を配置しなければなりません。
-
- </p>
-
- <h3>クライアントとサーバー間でSSLプロトコルを合意できません</h3>
- <p>注: <strong>この問題が生じるのは、明示的にSSLプロトコルを<a href="./15-usingSSL.html#parameters.excludedProtocols">除外</a>したり<a href="./15-usingSSL.html#parameters.includedProtocols">指定</a>している場合だけです</strong> 。
- </p>
-
- <p>クライアントがサーバに接続しようとするとき、次のような例外メッセージがログに現れます。</p>
-
- <p><em>javax.net.ssl.SSLHandshakeException: Received fatal
- alert: handshake_failure</em>
- </p>
-
- <p>サーバーのログに現れるメッセージのほうがわかりやすいです。</p>
-
- <p><em>javax.net.ssl.SSLHandshakeException: SSLv2Hello is disabled</em>
- </p>
-
- <p>一方のピアで除外したプロトコルが、もう一方のピアでは除外されていない場合に発生します。</p>
-
- <h4>ソリューション</h4>
- <p>サーバーとクライアントの両方で、<a href="./15-usingSSL.html#parameters.excludedProtocols"><span class="prop">excludedProtocols</span></a>と<a href="./15-usingSSL.html#parameters.includedProtocols"><span class="prop">includedProtocols</span></a>に指定した値を確認してください。
- </p>
-
- <h3>クライアントとサーバー間で暗号スイートを合意できません
-</h3>
- <p>注: <strong>この問題が生じるのは、明示的に暗号スイートを<a href="./15-usingSSL.html#parameters.excludedCipherSuites">除外</a>したり<a href="./15-usingSSL.html#parameters.includedCipherSuites">指定</a>している場合だけです</strong> 。
- </p>
-
- <p>クライアントがサーバに接続しようとするとき、次のような例外メッセージがログに現れます。
-</p>
-
- <p><em>javax.net.ssl.SSLHandshakeException: Received fatal
- alert: handshake_failure</em>
- </p>
-
- <p>サーバーのログに現れるメッセージのほうがわかりやすいです。
-</p>
-
- <p><em>javax.net.ssl.SSLHandshakeException: no cipher suites in common</em>
- </p>
-
- <p>クライアントとサーバーそれぞれの暗号スイート一覧について、1つも一致するものが無い場合に発生します。</p>
-
- <h4>ソリューション</h4>
- <p>サーバーとクライアントの両方で、<a href="./15-usingSSL.html#parameters.excludedCipherSuites"><span class="prop">excludedCipherSuites</span></a>と<a href="./15-usingSSL.html#parameters.includedCipherSuites"><span class="prop">includedCipherSuites</span></a>に指定した値を確認してください。
-
- </p>
-
- <script src="../templates/footer.js" type="text/javascript"></script>
-
- </p></p></div>
- </body>
-</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/news.html b/logback-site/src/site/pages/news.html
index c903a8b..39170b1 100644
--- a/logback-site/src/site/pages/news.html
+++ b/logback-site/src/site/pages/news.html
@@ -19,9 +19,6 @@
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="templates/right.js" type="text/javascript"></script>
- </div>
<div id="content">
<h2>Logback News</h2>
@@ -30,426 +27,7 @@
the <a href="http://www.qos.ch/mailman/listinfo/announce">QOS.ch
announce</a> mailing list.</p>
-
- <hr width="80%" align="center" />
-
- <h3>January 20th, 2017, Release of version 1.1.9</h3>
-
-
- <p>Logback's internal executor service had a thread pool size of 2
- which could be used up rather quickly, e.g. configuration scanning
- in addition to an active <code>ServerSocketAppender</code>. When
- both threads where permanently in use, compression could not
- proceed. To alleviate this problem, the thread pool size has been
- increased to 8. See issue <a
- href="https://jira.qos.ch/browse/LOGBACK-1238">LOGBACK-1238</a>
- for more details.
- </p>
-
- <p>Fixed issue with <code>FileAppender</code> instances embedded
- within <code>SiftingAppender</code> reporting filename collisions
- after reaching timeout and subsequently restarted. This problem
- was reported in <a
- href="https://jira.qos.ch/browse/LOGBACK-1167">LOGBACK-1167</a> by
- Michael Edgar.
- </p>
-
- <p>Fixed <code>SizeAndTimeBasedFNATP</code> deprecation warning
- emitted even the replacement,
- i.e. <code>SizeAndTimeBasedRollingPolicy</code>, is in use. See <a
- href="http://jira.qos.ch/browse/LOGBACK-1236">LOGBACK-1236</a>. This
- issue was reported by Claudius Nicolae.
- </p>
-
- <p>Added proper implementation for
- <code>LobackValve.getScheduledExecutorService()</code> method. The
- missing implementation manifested itself in the form of an
- <code>UnsupportedOperationException</code> thrown by
- LogbackValve. This problem is further described in <a
- href="http://jira.qos.ch/browse/LOGBACK-1181">LOGBACK-1181</a>
- reported by Andreas von Roepenack.
- </p>
-
- <hr width="80%" align="center" />
-
- <h3>December 9th, 2016, Release of version 1.1.8</h3>
-
- <p>Removed the two period safeguard, aka untouchable periods, for
- archive removal beyond the size specified by <span
- class="option">totalSizeCap</span> in
- <code>TimeBasedRollingPolicy</code>. It turns out the safegaurd is
- not required and is unexpected as attested by <a
- href="http://jira.qos.ch/browse/LOGBACK-1166">LOGBACK-1166</a>.
- </p>
-
- <p>Fixed issue with Joran incorrectly reporting "Unexpected
- aggregationType AS_BASIC_PROPERTY_COLLECTION". This issue was
- raised in <a
- href="http://jira.qos.ch/browse/LOGBACK-1158">LOGBACK-1158</a> by
- Christian Hübner.
- </p>
-
- <p>Gaffer (logback's groovy configurator) now supports the
- <code>valueOf</code> convention. This issue was raised in <a
- href="http://jira.qos.ch/browse/LOGBACK-1232">LOGBACK-1232</a> by
- Frans Orsel.
- </p>
-
- <p>The <code>org.slf4j.impl.StaticLoggerBinder</code> class
- shipping in logback-classic no longer catches
- <code>Throwable</code> but <code>Exception</code>. This change was
- requested in <a
- href="http://jira.qos.ch/browse/LOGBACK-1159">LOGBACK-1159</a> by
- David J. M. Karlsen.
- </p>
-
- <p><code>BeanDescriptionFactory</code> no longer outputs a
- superflous warning message in case the class contains bridge
- methods. This fixes <a
- href="http://jira.qos.ch/browse/LOGBACK-1164">LOGBACK-1164</a>
- reported by Phil Clay.
- </p>
-
- <!--
- <p>Added logback-bom module for use as a Maven "Bill of Materials"
- <em>pom</em> file. This was requested in <a
- href="http://jira.qos.ch/browse/LOGBACK-1157">LOGBACK-1157</a>
- Joerg Sesterhenn.</p>
- -->
-
- <hr width="80%" align="center" />
-
- <h3>March 29th, 2016, Release of version 1.1.7</h3>
-
- <p>Logback is now <a href="
- http://docs.oracle.com/javase/8/docs/technotes/guides/compactprofiles/compactprofiles.html">compact3
- profile</a> compatible. This improvement was requested in <a
- href="http://jira.qos.ch/browse/LOGBACK-1071">LOGBACK-1071</a> by
- Axel Fontaine with Max Urech providing the relevant pull-request.
- </p>
-
- <p>Fixed <code>ConcurrentModificationException</code> being thrown
- when the <code>reset()</code> method is invoked on the
- <code>LoggerContext</code> instance. This issue was reported in <a
- href="http://jira.qos.ch/browse/LOGBACK-397">LOGBACK-397</a> by
- Szczepan Faber with Ross Sargant providing the relevant test case.
- </p>
-
- <p><code>TimeBasedRollingPolicy</code> now supports the <a
- href="manual/appenders.html#tbrpTotalSizeCap"><span
- class="option">totalSizeCap</span></a> property which allows the
- user to limit the total size of archived logs.
- </p>
-
- <p><a
- href="manual/appenders.html#SizeAndTimeBasedRollingPolicy"><code>SizeAndTimeBasedRollingPolicy</code></a>
- offers the same functionality as
- <code>SizeAndTimeBasedFNATP</code> did previously but with a
- simpler configuration structure.
- </p>
-
- <p>Archive removal by <code>RollingFileAppender</code> is now
- performed asynchronously.</p>
-
- <p>Unnecessary and incompatible %i token in <span
- class="option">fileNamePattern</span> option with
- <code>RollingFileAppender/TimeBasedRollingPolicy</code> is now
- detected and the user alerted to the misconfiguration
- problem. This fixes <a
- href="http://jira.qos.ch/browse/LOGBACK-1143">LOGBACK-1143</a>.
- </p>
-
-
- <p>Joran can now handle logger names ending with a $, i.e. the
- first character in variable substitution. This issue was raised in
- <a href="http://jira.qos.ch/browse/LOGBACK-1149">LOGBACK-1149</a>
- by by Stevo Slavic.
- </p>
-
-
-
- <hr width="80%" align="center" />
-
- <h3>February 29th, 2016, Release of version 1.1.6</h3>
-
- <p><code>LogbackValve</code> (in logback-access) now attempts to
- load the configuration file as a resource if it cannot be found on
- the filesystem (<a
- href="http://jira.qos.ch/browse/LOGBACK-1069">LOGBACK-1069</a>). This
- is helpful in scenarios where applications are using an embedded
- Tomcat server.</p>
-
- <p><code>JMXConfigurator.reloadDefaultConfiguration()</code>
- method now tolerates programmatic configuration without a
- URL. This change was provided by Vedran Pavic in <a
- href="https://github.com/qos-ch/logback/pull/302">PR 302</a>.
- </p>
-
- <p><code>RollingFileAppender</code> will output an error message
- if the date time pattern in the %d token within the <span
- class="option">fileNamePattern</span> is not collision free. This
- fixes <a
- href="http://jira.qos.ch/browse/LOGBACK-1137">LOGBACK-1137</a>. In
- a similar vein, every instance of <code>FileAppender</code> will
- now detect if it shares the same <span class="option">File</span>
- option value as given for an appender defined earlier. In
- addition, <code>RollingFileAppender</code> instances now check for
- colliding <span class="option">FileNamePattern</span> values.</p>
-
- <p>Fixed <code>NullPointerException</code> thrown by
- <code>RollingFileAppender</code> if the name of the rollover
- target path did not contain a parent. This issue was reported in
- <a href="http://jira.qos.ch/browse/LOGBACK-1054">LOGBACK-1054</a>
- by Paulius Matulionis. Analysis of the problem and the relevant PR
- was provided by Ferenc Palkovics.</p>
-
- <p><code>BasicConfigurator.configure</code> method call executes
- significatly faster. Improved documentation for configuration
- using JDK 1.6 service-provider facility. These changes are in
- response to <a
- href="http://jira.qos.ch/browse/LOGBACK-1141">LOGBACK-1141</a>
- requesting faster logback start-up time.
- </p>
-
-
- <p>Fixed issue with variable substitution with the value ending in
- a colon. This problem was reported in <a
- href="http://jira.qos.ch/browse/LOGBACK-1140">LOGBACK-1140</a> by
- Eric Cook.</p>
-
- <hr width="80%" align="center" />
-
- <h3>February 13th, 2016, Release of version 1.1.5</h3>
-
- <div class="breaking">
- <h4>MDC values are no longer inherited by child threads.</h4>
- </div>
-
- <p>Child threads no longer inherit MDC values. In previous
- versions of logback as well as log4j 1.x, MDC values were
- inherited by child threads. Several users have argued convincingly
- that MDC inheritance by child threads was unhelpful and even
- dangerous. This change fixes <a
- href="http://jira.qos.ch/browse/LOGBACK-422">LOGBACK-422</a> and <a
- href="http://jira.qos.ch/browse/LOGBACK-624">LOGBACK-624</a>
- </p>
-
- <p>When the <code>FileNamePattern</code> string for
- <code>RollingFileAppender/SizeAndTimeBasedFNATP</code> lacks a %i
- token, then compression for the second archive in the same period
- cannot occur as the target file already exists. Under those
- circumstances, logback leaves behind .tmp files as reported in <a
- href="http://jira.qos.ch/browse/LOGBACK-992">LOGBACK-992</a>, <a
- href="http://jira.qos.ch/browse/LOGBACK-173">LOGBACK-173</a> and
- <a
- href="http://jira.qos.ch/browse/LOGBACK-920">LOGBACK-920</a>. In
- this release, this particular condition is detected by
- <code>RollingFileAppender</code> which will not start but alert
- the user instead.
- </p>
-
- <p>AsyncAppender is now configurable to never block. This feature
- was requested by Jeff Wartes in <a
- href="http://jira.qos.ch/browse/LOGBACK-898">LOGBACK-898</a> with
- Jeff Wartes and Gareth Davis providing the relevant patch.
- </p>
-
-
- <hr width="80%" align="center" />
-
- <h3>February 11th, 2016, Release of version 1.1.4</h3>
-
- <div class="breaking">
- <h4>Logback 1.1.4 requires SLF4J version 1.7.16 or later.</h4>
- </div>
-
- <p>Added event replay support as introduced in SLF4J version
- 1.7.15. In most circumstances, logack-classic should run fine with
- earlier versions of slf4j-api, including all versions in the 1.6.x
- and 1.7.x series. However, with a version of slf4j-api.jar earlier
- than 1.7.15 in the classpath, attempting introspection of a
- <code>Logger</code> instance will result in a
- <code>NoClassDefFoundError</code> similar to that shown below.
- </p>
-
- <pre class="prettyprint source">Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/event/LoggingEvent
- at java.lang.Class.getDeclaredMethods0(Native Method)
- at java.lang.Class.privateGetDeclaredMethods(Class.java:2451)
- at java.lang.Class.privateGetPublicMethods(Class.java:2571)
- at java.lang.Class.getMethods(Class.java:1429)
- at java.beans.Introspector.getPublicDeclaredMethods(Introspector.java:1261)
- at java.beans.Introspector.getTargetMethodInfo(Introspector.java:1122)
- at java.beans.Introspector.getBeanInfo(Introspector.java:414)
- at java.beans.Introspector.getBeanInfo(Introspector.java:161)
- </pre>
-
- <p>
- </p>
-
- <div class="breaking">
- <h4>Packaging data (as output in stack traces) is now disabled
- by default.
- </h4>
- </div>
-
- <p>In case an application throws exceptions frequently, then
- computing packaging data can be very costly and will cause the
- application to run slower. Making bad worse. To alleviate this
- problem, packaging data is no longer computed by default. It has
- to be <a href="manual/configuration.html#packagingData">enabled
- explicitly</a>. In the absence of explicit instructions, i.e the
- user has not specified a converter handling exceptions,
- <code>PatternLayout</code> in logback-classic will follow the
- settings defining for the logging environment. If packaging data
- is disabled, then it add %ex as a suffix in the pattern, and if
- packaging data is enabled then %xEx will be added. These changes
- fix <a
- href="http://jira.qos.ch/browse/LOGBACK-730">LOGBACK-730</a> and
- <a href="http://jira.qos.ch/browse/LOGBACK-966">LOGBACK-966</a>.
- </p>
-
-
- <p>Fixed a bug in
- <code>TimeBasedFileNamingAndTriggeringPolicyBase</code> causing
- time-based rolling policies to always rollover according to the
- local system time and ignore the time zone passed in the file name
- pattern. The issue was reported by Lukasz Sanek who also provided
- the the relevant fix. </p>
-
- <p><code>AsyncAppenderBase</code> now restores the current
- thread's interrupt flag when catching an
- <code>InterruptedException</code>. The issue
- (<a href="http://jira.qos.ch/browse/LOGBACK-910">LOGBACK-910</a>) was
- raised by Henrik Nordvik who also provided the relevant fix.</p>
-
<hr width="80%" align="center" />
-
- <h3>24th of March 2015, Release of version 1.1.3</h3>
-
-
- <div class="breaking">
- <h4>As of version 1.1.3, all logback modules require JDK 1.6
- instead of previously JDK 1.5. This change was put to
- consultation on the logback mailing lists with no objections
- raised.</h4>
- </div>
-
-
- <p>Fixed <code>FileAppender</code>'s prudent mode so that it properly recovers
- from IO Errors
- (<a href="http://jira.qos.ch/browse/LOGBACK-1046">LOGBACK-1046</a>) </p>
-
- <p>Irrelevant or internal stack trace lines can now be omitted. Pull request
- provided by Tomasz Nurkiewicz
- (<a href="http://jira.qos.ch/browse/LOGBACK-540">LOGBACK-540</a>).</p>
-
- <p><code>AccessEvent</code> now creates a copy of request attributes when
- its <code>prepareForDeferredProcessing()</code> method is called. This makes
- attributes visible even if an appender uses a background thread to process
- events.
- (<a href="http://jira.qos.ch/browse/LOGBACK-1033">LOGBACK-1033</a>)</p>
-
- <p>All threads opened by <code>ch.qos.logback.core.util.ExecutorServiceUtil#THREAD_FACTORY</code>
- are now daemons, which fixes an application hang on shutdown when <code>LoggerContext#stop()</code>
- is not called (<a href="http://jira.qos.ch/browse/LOGBACK-929">LOGBACK-929</a>).
- Note that daemon threads are abruptly terminated by the JVM, which may cause
- undesirable results, such as corrupted files written by the <code>FileAppender</code>.
- It is still highly recommended for the application to call <code>LoggerContext#stop()</code>
- (e.g., in a shutdown hook) to gracefully shutdown appenders.</p>
-
- <p>Fixed an issue with <code>RollingFileAppender</code> where the first
- rollover file could be unintentionally deleted, depending on the specified
- filename pattern
- (<a href="http://jira.qos.ch/browse/LOGBACK-894">LOGBACK-894</a>).</p>
-
- <p>Fixed an issue with <code>TeeHttpServletResponse</code>
- where the system default encoding would be used instead of the
- response encoding when constructing a new writer
- (<a href="http://jira.qos.ch/browse/LOGBACK-1023">LOGBACK-1023</a>).</p>
-
- <p>Fixed <code>ConfigurationDelegate.groovy</code> to allow any appender
- that implements <code>AppenderAttachable</code>, which supports third-party
- appenders, such as <b>reactor-logback's</b> <code>AsyncAppender</code>
- (<a href="http://jira.qos.ch/browse/LOGBACK-1008">LOGBACK-1008</a>)</p>
-
- <p>Added support for specifying the callstack depth range in the
- <code>PatternLayout</code>. For example, <code>%caller{1..2}</code>
- displays the first two calls in the callstack.</p>
-
- <p>Added HTTP request method to <code>MDCInsertingServletFilter</code>.</p>
-
- <p>Fixed time-zone dependent code in <code>RollingCalendarTest</code>.
- (<a href="http://jira.qos.ch/browse/LOGBACK-116">LOGBACK-116</a>)
- </p>
-
- <p>Simplified connection logic of SocketApender to reduce multi-threading
- overhead and unnecessary instantiation of <code>SocketConnector</code>
- objects.</p>
-
- <p>Fixed race condition in <code>SMTPAppenderBase</code> causing missing or
- duplicate emails.
- (<a href="http://jira.qos.ch/browse/LOGBACK-909">LOGBACK-909</a>)
- </p>
-
- <p>Fixed an issue with <code>FileAppender</code> in prudent mode, where
- an interrupt could prevent further access to the file
- (<a href="http://jira.qos.ch/browse/LOGBACK-875">LOGBACK-875</a>).</p>
-
- <p>Fixed <code>IllegalStateException</code> when multiple threads
- write files to same directory
- (<a href="http://jira.qos.ch/browse/LOGBACK-128">LOGBACK-128</a>).</p>
-
- <p>Changed queue consumption strategy in <code>AbstractSocketAppender</code>
- from "take" to "peek/remove" in order to avoid losing an event on each socket
- connection break. Zero is now a deprecated queue size. A queue size of one
- should be taken instead to indicate synchronous processing.
- (<a href="http://jira.qos.ch/browse/LOGBACK-977">LOGBACK-977</a>)
- </p>
-
- <p><code>RequestLogImpl</code> now has an overridable <code>configure</code>
- method to allow extending implementations to configure it via methods
- other than the <code>logback-access.xml</code> file.</p>
-
- <p>Fixed a bug in <code>AccessEvent</code> which could cause any
- <code>AsyncAppender</code> based appender to corrupt the request
- headers, request parameters, or response headers, before logging.</p>
-
- <p>SQL scripts to setup your logback database are now provided as
- JAR resources
- (<a href="http://jira.qos.ch/browse/LOGBACK-948">LOGBACK-948</a>).
- </p>
-
- <p>Threads created internally by logback are now named
- <i>logback-n</i>, where <i>n</i> is an integer. For the
- first thread <i>n</i> is set to 1, for each successive thread
- <i>n</i> is incremented by 1.</p>
-
- <p>Added max runtime parameter to <code>AsyncAppender</code> to allow
- the appender to flush events, up to a maximum delay, during a stop
- of the LoggerContext. This can be used to ensure that all queued
- events are flushed.</p>
-
- <p>Added new configuration element <code>shutdownHook</code> to allow the
- user to specify a ShutdownHook implementation that will stop the Logback
- context upon JVM exit.
- </p>
-
- <p><code>BasicStatusManager</code> now prevents adding more than
- one instance of <code>OnConsoleStatusListener</code> as a status
- listener. This fixes <a
- href="http://jira.qos.ch/browse/LOGBACK-976">LOGBACK-976</a>.
- </p>
-
- <p><code>TimeBasedRollingPolicy</code> now accepts a time zone in
- its <code>%d</code> conversion pattern. (<a
- href="http://jira.qos.ch/browse/LOGBACK-611">LOGBACK-611</a>)
- </p>
-
- <p>It is now possible to configure the character encoding used by
- <code>SyslogAppender</code> to encode messages using the
- <code>setCharset()</code> method. This fixes <a
- href="http://jira.qos.ch/browse/LOGBACK-732">LOGBACK-732</a>
- </p>
<h3>2nd of April, 2014 - Release of version 1.1.2</h3>
@@ -466,7 +44,7 @@
</p>
<p>Fixed <code>NullPointerException</code> when substituting blank variables
- (<a href="http://jira.qos.ch/browse/LOGBACK-959">LOGBACK-959</a>)</p>
+ (<a href="http://jira.qos.ch/browse/LOGBACK-959">LOGBACK-959</a>)
<p>Fixed <code>NullPointerException</code> that occurs when stopping a
<code>SyslogAppender</code> that did not properly initialize, e.g.,
@@ -481,12 +59,7 @@
<p>In case of missing included files, IncludeAction no longer
prints a stack trace but prints a warning instead. (<a
- href="http://jira.qos.ch/browse/LOGBACK-954">LOGBACK-954</a>)</p>
-
- <p>Fixed character escaping in XMLLayout
- (<a href="http://jira.qos.ch/browse/LOGBACK-728">LOGBACK-728</a>)
- and HTMLLayout
- (<a href="http://jira.qos.ch/browse/LOGBACK-440">LOGBACK-440</a>).</p>
+ href="http://jira.qos.ch/browse/LOGBACK-954">LOGBACK-954</a>)
<hr width="80%" align="center" />
diff --git a/logback-site/src/site/pages/reasonsToSwitch.html b/logback-site/src/site/pages/reasonsToSwitch.html
index 146abc6..c6f150a 100644
--- a/logback-site/src/site/pages/reasonsToSwitch.html
+++ b/logback-site/src/site/pages/reasonsToSwitch.html
@@ -19,10 +19,6 @@
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="templates/right.js" type="text/javascript"></script>
- </div>
-
<div id="content">
<h2>Reasons to prefer logback over log4j</h2>
diff --git a/logback-site/src/site/pages/setup.html b/logback-site/src/site/pages/setup.html
index 48de8b0..df76d03 100644
--- a/logback-site/src/site/pages/setup.html
+++ b/logback-site/src/site/pages/setup.html
@@ -43,15 +43,15 @@
</p>
+
<h3 class="doAnchor" name="commandLine">Running from the command
line</h3>
- <p>You can launch the first sample application,
- <em>chapters.introduction.HelloWord1</em> with the following
- command. This assumes that your current directory is
+ <p>Assuming your current directory is
<em>$LOGBACK_HOME/logback-examples</em>, where
<em>$LOGBACK_HOME</em> stands for the directory where you
- installed logback:
+ installed logback, you can launch the first sample application,
+ <em>chapters.introduction.HelloWord1</em> with the following command:
</p>
<p class="source">java -cp lib/slf4j-api-${slf4j.version}.jar;../logback-core-${project.version}.jar;\
@@ -78,76 +78,6 @@
<em>$LOGBACK_HOME/logback-examples</em> directory.
</p>
-
- <h2 class="doAnchor" name="mavenBuild">Maven dependency
- declaration</h2>
-
- <p>To use logback-classic in your Maven project, declare the
- following dependency in your project's <em>pom</em> file.</p>
-
- <pre class="prettyprint source"><dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <version>${project.version}</version>
-</dependency></pre>
-
- <p><span class="label notice">TRANSITIVITY</span> Note that in
- addition to <em>logback-classic.jar</em>, the above declaration
- will automatically pull-in <em>slf4j-api.jar</em> and
- <em>logback-core.jar</em> into your project by virtue of Maven's
- transitivity rules.</p>
-
-
- <p>To include logback-access in your Maven project, declare the following
- dependency in your project's <em>pom</em> file.</p>
-
- <pre class="prettyprint source"><dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-access</artifactId>
- <version>${project.version}</version>
-</dependency></pre>
-
- <h4>Maven "Bill of materials" (useful for large teams)</h4>
-
- <p>To facilitate the synchronization of logback and slf4j modules,
- we provide a "Bill of materials" pom file. It can be imported in
- the <code>dependencyManagement</code> section of your parent
- <code>pom</code> file, as shown below.
- </p>
-
- <pre class="prettyprint source"><dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-bom</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>import</scope>
- <dependency>
- ...
- </dependencies>
-</dependencyManagement></pre>
-
- <p>Importing logback-bom as shown above allows you to declare the
- version for logback/slf4j modules in one step and keep them in
- sync. This can be convenient particularly in larger software
- teams.</p>
-
- <p>Note that you still need to declare a dependency on
- logback-classic (or logback-access). However, you no longer will
- have to specify the version.</p>
-
- <p>After logback-bom is imported, the previous dependency declaration
- becomes:</p>
-
- <pre class="prettyprint source"><dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <!-- Look mom, no version! -->
-</dependency></pre>
-
- <h2 class="doAnchor" name="optionalDeps">Optional dependencies</h2>
-
<h3 class="doAnchor" name="SMTP"><code>SMTPAppender</code> requires
JavaMail API</h3>
@@ -226,7 +156,7 @@
- <h2 class="doAnchor" name="ide">Building with an IDE</h2>
+ <h3 class="doAnchor" name="ide">Building with an IDE</h3>
<p>If you wish to contribute to the project or just hack for fun,
you will probably want to import logback as a project into your
@@ -260,15 +190,20 @@
<h3 class="doAnchor" name="eclipse">Building with Eclipse</h3>
<p>Building logback under Eclipse is a little trickier. Here are
- instructions for building logback under Eclipse using the maven
- eclipse:eclipse plugin.
+ instructions for building logback under Eclipse in 61 easy steps.
</p>
-
- <p>The procedure outlines below assumes that M2Eclipse is not
- active. If you have <code>m2eclipse</code> installed, you can
- disable it by removing the Maven Nature for a given project. In
- later versions of Eclipse, m2eclipse is installed by default.
+ <p>The author does not wish to unduly disparage
+ <code>m2eclipse</code>. However, as of this writing, that is
+ October 2011, it appears that the key to building logback under
+ Eclipse is to avoid using <code>m2eclipse</code>. If you have
+ <code>m2eclipse</code> installed, you can disable it by removing
+ the Maven Nature for a given project. In later versions of Eclipse,
+ m2eclipse is installed bu default. As of logback version 1.0.7, the
+ <em>pom.xml</em> file for logback-core now deactivates m2eclipse as
+ explained in <a
+ href="http://wiki.eclipse.org/M2E_plugin_execution_not_covered#ignore_plugin_goal">M2E
+ plugin wiki</a>.
</p>
<p>And without further ado here are the steps:
@@ -289,10 +224,13 @@
<p>You first need to determine the update site appropriate
for your version of Eclipse. The list of available update
sites is available from <a
- href="https://github.com/groovy/groovy-eclipse/wiki">Groovy
- Eclipse Wiki</a>.
+ href="http://groovy.codehaus.org/Eclipse+Plugin">Groovy
+ project documentation</a>.
+ </p>
+ <p>For example, for Eclipse 4.2 (Juno) the URL of the
+ update site is
+ "http://dist.springsource.org/release/GRECLIPSE/e4.2/".
</p>
-
</li>
<li>In Eclipse, select Help → Intall new Software →
@@ -311,7 +249,11 @@
where $LOGBACK_HOME stands for the location where you cloned the
logback project from github </li>
-
+ <li>In case they exist, remove <em>.settings</em>,
+ <em>.classpath</em>, <em>.project</em> folders (again if any)
+ under $LOGBACK_HOME and its sub-folders. Somehow, this step seems
+ to be crucial.</li>
+
<li>From the command line, run <code>mvn eclipse:eclipse</code>
in $LOGBACK_HOME</li>
@@ -319,52 +261,27 @@
General→ Existing Projects into Workspace, select
$LOGBACK_HOME folder for the import
</li>
-
- <!--
- <li>In Eclipse, remove the
- "**/EvaluatorTemplate.groovy" inclusion pattern from
- the
- logback-classic/src/main/groovy build path (logback-classic→
- project properties → Java Build Path) as shown next:
-
- <p><img src="images/setup/remove_evaluator_template.jpg"/> </p>
-
- </li>
- -->
-
- <!--
- <li>In Eclipse, remove the
+
+ <li>In Eclipse, remove the
logback-classic/target/generated-sources/groovy-stubs/main
directory from the list of source folders (logback-classic→
- project properties → Java Build Path) as shown next.
-
- <p><img src="images/setup/remove_gen_src.jpg"/> </p>
-
+ project properties → Java Build Path)
</li>
- -->
<li>In Eclipse, clean all projects in Eclipse (Project →
Clean)
</li>
- <li>In Eclipse, select logback-classic project and check that it has
- "Groovy" nature. If not add it by right clicking on logback-classic project →
- Groovy → Convert Groovy to Project.
+ <li>In Eclipse, select logback-classic project and convert it to
+ "Groovy project" (right click on logback-classic project →
+ Configure → Convert Groovy to Project)
</li>
</ol>
<p>The above listed procedure has been last tested by the author
- using Eclipse Luna on February 25th, 2016.</p>
-
-
- <p><span class="label notice">Call for volunteers</span> Given that many
- users prefer M2Eclipse for building projects under Eclipse IDE, we
- are looking for volunteers to help work out the steps for building
- logback with M2Eclipse.
- </p>
-
+ using Eclipse Juno on April 4th 2013.</p>
<script src="templates/footer.js" type="text/javascript"></script>
</div>
diff --git a/logback-site/src/site/pages/templates/creative.js b/logback-site/src/site/pages/templates/creative.js
index d9badf7..78b2b40 100644
--- a/logback-site/src/site/pages/templates/creative.js
+++ b/logback-site/src/site/pages/templates/creative.js
@@ -5,7 +5,7 @@ document.write(' <td> ');
document.write(' <p class="author">');
document.write(' Authors: Ceki Gülcü, Sébastien Pennec, Carl Harris');
document.write(' <br/>');
-document.write(' Copyright © 2000-2016, QOS.ch</p>');
+document.write(' Copyright © 2000-2012, QOS.ch</p>');
document.write(' </td>');
document.write(' <td>');
document.write(' <a rel="license"');
diff --git a/logback-site/src/site/pages/templates/footer.js b/logback-site/src/site/pages/templates/footer.js
index 73f766f..0f4685b 100644
--- a/logback-site/src/site/pages/templates/footer.js
+++ b/logback-site/src/site/pages/templates/footer.js
@@ -3,7 +3,7 @@ document.write('<table class="footer" border="0">')
document.write('<tr>')
-document.write('<td valign="top">Copyright © 2017 <a href="http://www.qos.ch/">QOS.ch</a></td>')
+document.write('<td valign="top">Copyright © 2013 <a href="http://www.qos.ch/">QOS.ch</a></td>')
document.write(' <td rowspan="2">');
document.write(' <a href="http://twitter.com/qos_ch">');
diff --git a/logback-site/src/site/pages/templates/left.js b/logback-site/src/site/pages/templates/left.js
index 5a0c278..cf769dd 100644
--- a/logback-site/src/site/pages/templates/left.js
+++ b/logback-site/src/site/pages/templates/left.js
@@ -26,16 +26,6 @@ document.write('<p class="menu"><a href="http://logback.qos.ch/translator/asGroo
document.write('</p>');
document.write('</div>');
-document.write('<p> </p>');
+document.write('<p/>');
-document.write('<div class="pub">');
-document.write(' <a href="http://twitter.com/qos_ch" style="">');
-document.write(' <img alt="Follow @qos_ch" src="images/follow_us.png" />');
-document.write(' </a>');
-document.write('</div>');
-
-document.write('<p> </p>');
-document.write('<div class="pub"><img src="https://travis-ci.org/qos-ch/logback.svg?branch=master"/></div>');
-
-
-//document.write('<div class="jobadd"><p><a href="'+prefix +'job.html">Your career<br/>@QOS.ch</a></p></div>');
\ No newline at end of file
+document.write('<div class="jobadd"><p><a href="'+prefix +'job.html">Your career<br/>@QOS.ch</a></p></div>');
\ No newline at end of file
diff --git a/logback-site/src/site/pages/templates/right.js b/logback-site/src/site/pages/templates/right.js
index c8d4a0d..493ae09 100644
--- a/logback-site/src/site/pages/templates/right.js
+++ b/logback-site/src/site/pages/templates/right.js
@@ -1,11 +1,19 @@
-document.write(' <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>');
-// <!-- SLF4J -->
-document.write(' <ins class="adsbygoogle"');
-document.write(' style="display:block"');
-document.write(' data-ad-client="ca-pub-7471410671306824"');
-document.write(' data-ad-slot="6377851613"');
-document.write(' data-ad-format="auto"></ins>');
-document.write(' <script>');
-document.write(' (adsbygoogle = window.adsbygoogle || []).push({});');
-document.write(' </script>;');
+//document.write('<p class="menu"><a href="'+prefix+'10reasons.ppt">10 reasons for migrating</a>')
+document.write('<p class="menu_header">New and noteworthy</p>')
+
+document.write('<p class="menu"><a href="http://stubbisms.wordpress.com/2008/07/15/some-serious-logging-niceness-logback-with-eclipse-plugin/">Logging niceness</a>')
+
+document.write('<p class="menu"><a href="http://wimpi.coalevo.net/2008/04/logger-name-based-filtering-in-logback.html">Filtering by logger name</a>')
+
+document.write('<p class="menu"><a href="http://out-println.blogspot.com/2007/09/slf4j-and-logback.html">SLF4J and Logback</a>')
+
+
+document.write('<p class="menu"><a href="http://wizardforge.org/pc?action=showVersion&id=72">Configuration Wizard</a>')
+
+document.write('<p class="menu"><a href="http://xhab.blogspot.com/2007/03/new-logging-experience.html">A new logging experience!</a>')
+
+document.write('<p class="menu"><a href="http://javablog.smilehouse.com/blog/default/Java/2007/02/02/Writing-rotated-and-compressed-access-logs-with-logback">Writing rotated and compressed access logs</a>')
+
+
+document.write('</p>')
diff --git a/logback-site/src/site/pages/volunteer.html b/logback-site/src/site/pages/volunteer.html
index e1b4612..5a5fd36 100644
--- a/logback-site/src/site/pages/volunteer.html
+++ b/logback-site/src/site/pages/volunteer.html
@@ -17,10 +17,6 @@
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="templates/left.js" type="text/javascript"></script>
</div>
- <div id="right">
- <script src="templates/right.js" type="text/javascript"></script>
- </div>
-
<div id="content">
diff --git a/logback-site/src/site/resources/images/follow_us.png b/logback-site/src/site/resources/images/follow_us.png
deleted file mode 100644
index fe3a388..0000000
Binary files a/logback-site/src/site/resources/images/follow_us.png and /dev/null differ
diff --git a/logback-site/src/site/resources/images/setup/remove_evaluator_template.jpg b/logback-site/src/site/resources/images/setup/remove_evaluator_template.jpg
deleted file mode 100644
index be9455d..0000000
Binary files a/logback-site/src/site/resources/images/setup/remove_evaluator_template.jpg and /dev/null differ
diff --git a/logback-site/src/site/resources/images/setup/remove_gen_src.jpg b/logback-site/src/site/resources/images/setup/remove_gen_src.jpg
deleted file mode 100644
index 7be5c95..0000000
Binary files a/logback-site/src/site/resources/images/setup/remove_gen_src.jpg and /dev/null differ
diff --git a/pom.xml b/pom.xml
index 117f25c..3afac14 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,14 +1,13 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-parent</artifactId>
- <version>1.1.9</version>
+ <version>1.1.2</version>
<packaging>pom</packaging>
-
<name>Logback-Parent</name>
<description>logback project pom.xml file</description>
@@ -37,6 +36,7 @@
<connection>git at github.com:ceki/logback.git</connection>
</scm>
+
<modules>
<module>logback-core</module>
<module>logback-classic</module>
@@ -46,24 +46,28 @@
</modules>
<properties>
- <maven.compiler.source>1.6</maven.compiler.source>
- <maven.compiler.target>1.6</maven.compiler.target>
+ <!-- target JDK version == source JDK version -->
+ <jdk.version>1.5</jdk.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <!-- slf4j.version property is used below, in
+ logback-classic/pom.xml and in setClasspath.cmd -->
+ <slf4j.version>1.7.6</slf4j.version>
<junit.version>4.10</junit.version>
<javax.mail.version>1.4</javax.mail.version>
- <janino.version>2.7.8</janino.version>
- <groovy.version>2.4.0</groovy.version>
- <!-- slf4j.version property is used below, in
- logback-classic/pom.xml and in setClasspath.cmd
- -->
- <slf4j.version>1.7.22</slf4j.version>
+ <janino.version>2.6.1</janino.version>
+ <groovy.version>2.0.7</groovy.version>
+
<consolePlugin.version>1.1.0</consolePlugin.version>
- <tomcat.version>7.0.59</tomcat.version>
+ <tomcat.version>7.0.21</tomcat.version>
<jetty.version>7.5.1.v20110908</jetty.version>
<jansi.version>1.9</jansi.version>
- <javadoc.plugin.version>2.9.1</javadoc.plugin.version>
- <cobertura.maven.plugin.version>2.6</cobertura.maven.plugin.version>
+
+ <maven-compiler-plugin.version>2.3.2</maven-compiler-plugin.version>
+ <maven-jar-plugin.version>2.3.1</maven-jar-plugin.version>
+ <maven-surefire-plugin.version>2.14.1</maven-surefire-plugin.version>
<maven-license-plugin.version>1.9.0</maven-license-plugin.version>
+ <findbugs-maven-plugin.version>2.5</findbugs-maven-plugin.version>
+
</properties>
<developers>
@@ -78,6 +82,7 @@
<name>Joern Huxhorn</name>
<email>huxi at undisclosed.org</email>
</developer>
+
</developers>
<dependencies>
@@ -88,44 +93,46 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.assertj</groupId>
- <artifactId>assertj-core</artifactId>
- <version>1.7.1</version>
+ <groupId>org.easytesting</groupId>
+ <artifactId>fest-assert</artifactId>
+ <version>1.2</version>
<scope>test</scope>
</dependency>
</dependencies>
+
<dependencyManagement>
<dependencies>
- <!-- start of dependencies duplicated from logback-bom/pom.xml -->
+ <!-- Project modules -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${project.version}</version>
</dependency>
+
<dependency>
<groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
+ <artifactId>logback-core</artifactId>
<version>${project.version}</version>
+ <type>test-jar</type>
</dependency>
+
<dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>${slf4j.version}</version>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>${project.version}</version>
</dependency>
+
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-core</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
</dependency>
- <!-- end of dependencies duplicated from logback-bom/pom.xml -->
-
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
@@ -141,6 +148,7 @@
<artifactId>jansi</artifactId>
<version>${jansi.version}</version>
</dependency>
+
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
@@ -171,21 +179,32 @@
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
+
+
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>${tomcat.version}</version>
</dependency>
+
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-coyote</artifactId>
<version>${tomcat.version}</version>
</dependency>
+
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
</dependency>
+ <!--
+ <dependency>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>servlet-api-2.5</artifactId>
+ <version>6.1.1</version>
+ </dependency>
+ -->
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_1.1_spec</artifactId>
@@ -196,11 +215,6 @@
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
- <dependency>
- <groupId>joda-time</groupId>
- <artifactId>joda-time</artifactId>
- <version>2.9.2</version>
- </dependency>
</dependencies>
</dependencyManagement>
@@ -210,113 +224,37 @@
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
- <version>2.8</version>
+ <version>2.0</version>
</extension>
</extensions>
- <pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-clean-plugin</artifactId>
- <version>2.6.1</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.5.1</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-deploy-plugin</artifactId>
- <version>2.8.2</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-install-plugin</artifactId>
- <version>2.5.2</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-resources-plugin</artifactId>
- <version>2.6</version> <!-- 2.7 causes failure, review in order to update -->
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-site-plugin</artifactId>
- <version>3.4</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.19.1</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <version>2.5</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>${javadoc.plugin.version}</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <version>2.10</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-release-plugin</artifactId>
- <version>2.5.1</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- <version>2.4</version>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>findbugs-maven-plugin</artifactId>
- <version>3.0.0</version>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>2.5.3</version>
- </plugin>
-
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>animal-sniffer-maven-plugin</artifactId>
- <version>1.14</version>
- <configuration>
- <ignores>
- <ignore>sun.reflect.Reflection</ignore>
- </ignores>
- <signature>
- <groupId>org.codehaus.mojo.signature</groupId>
- <artifactId>java16</artifactId>
- <version>1.0</version>
- </signature>
- </configuration>
- </plugin>
-
- </plugins>
-
- </pluginManagement>
-
<plugins>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${maven-compiler-plugin.version}</version>
+ <configuration>
+ <source>${jdk.version}</source>
+ <target>${jdk.version}</target>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${maven-surefire-plugin.version}</version>
+ </plugin>
+
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
+ <version>2.1.2</version>
<executions>
<execution>
- <id>attach-sources</id>
+ <phase>package</phase>
<goals>
<goal>jar</goal>
- <goal>test-jar</goal>
</goals>
</execution>
</executions>
@@ -324,8 +262,27 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>${maven-jar-plugin.version}</version>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-eclipse-plugin</artifactId>
+ <version>2.8</version>
+ <configuration>
+ <downloadSources>true</downloadSources>
+ <downloadJavadocs>true</downloadJavadocs>
+ <sourceIncludes>
+ <sourceInclude>**/*.java</sourceInclude>
+ </sourceIncludes>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
- <version>2.5.3</version>
+ <version>2.1</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/dist.xml</descriptor>
@@ -335,10 +292,17 @@
<outputDirectory>target/site/dist/</outputDirectory>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <!-- avoid "Duplicate entry" warnings -->
+ <version>2.1.0</version>
+ </plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
+ <version>${findbugs-maven-plugin.version}</version>
<configuration>
<threshold>High</threshold>
<!--<trace>true</trace>-->
@@ -346,37 +310,34 @@
</configuration>
</plugin>
-
-
-
<!-- ================ site plugin ==================== -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
+ <version>3.0</version>
<configuration>
<reportPlugins>
-
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
- <version>2.5</version>
+ <version>2.3</version>
<configuration>
<aggregate>true</aggregate>
<javadocDir>target/site/apidocs/</javadocDir>
<linkJavadoc>true</linkJavadoc>
</configuration>
</plugin>
-
+
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
- <version>2.10.1</version>
+ <version>2.8</version>
<configuration>
<aggregate>true</aggregate>
- <linksource>true</linksource>
+ <!--<linksource>true</linksource>-->
<links>
<link>
- http://docs.oracle.com/javase/6/docs/api/
+ http://java.sun.com/j2se/1.5.0/docs/api
</link>
</links>
<groups>
@@ -411,23 +372,27 @@
</reportPlugins>
</configuration>
</plugin>
+
</plugins>
</build>
<distributionManagement>
-
<site>
- <id>qos_ch</id>
- <url>scp://te.qos.ch/var/www/logback.qos.ch/htdocs/</url>
+ <id>pixie</id>
+ <url>scp://pixie.qos.ch/var/www/logback.qos.ch/htdocs/</url>
</site>
<repository>
<id>sonatype-nexus-staging</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
+
+ <!--<id>pixie</id>-->
+ <!--<url>scp://pixie.qos.ch/var/mvnrepo/</url>-->
</repository>
</distributionManagement>
+
<profiles>
<profile>
<id>testSkip</id>
@@ -450,7 +415,6 @@
<aggregate>true</aggregate>
<includes>
<include>src/**/*.java</include>
- <include>src/**/*.groovy</include>
</includes>
<useDefaultExcludes>true</useDefaultExcludes>
<useDefaultMapping>true</useDefaultMapping>
@@ -464,6 +428,7 @@
</plugin>
</plugins>
</build>
+
</profile>
<profile>
@@ -473,13 +438,12 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
- <version>${javadoc.plugin.version}</version>
+ <version>2.8</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
- <goal>test-jar</goal>
</goals>
</execution>
</executions>
@@ -488,6 +452,7 @@
</build>
</profile>
+
<profile>
<id>sign-artifacts</id>
<build>
@@ -495,7 +460,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
- <version>1.6</version>
+ <version>1.1</version>
<executions>
<execution>
<id>sign-artifacts</id>
@@ -510,36 +475,6 @@
</build>
</profile>
- <profile>
- <id>cobertura</id>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-site-plugin</artifactId>
- <configuration>
- <reportPlugins>
-
-
-
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>cobertura-maven-plugin</artifactId>
- <version>${cobertura.maven.plugin.version}</version>
- <configuration>
- <formats>
- <format>html</format>
- </formats>
- <aggregate>true</aggregate>
- </configuration>
- </plugin>
- </reportPlugins>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </profile>
-
</profiles>
diff --git a/src/main/assembly/dist.xml b/src/main/assembly/dist.xml
index 6b375f7..1873f9c 100644
--- a/src/main/assembly/dist.xml
+++ b/src/main/assembly/dist.xml
@@ -66,17 +66,6 @@
<exclude>*.bak</exclude>
</excludes>
</fileSet>
- <!--
- <fileSet>
- <directory>logback-bom/</directory>
- <outputDirectory>logback-bom/</outputDirectory>
- <includes>
- <include>
- pom.xml
- </include>
- </includes>
- </fileSet>
- -->
<!-- Module Source directories -->
<fileSet>
<directory>logback-core/src/</directory>
diff --git a/src/main/clas/signed-clas.txt b/src/main/clas/signed-clas.txt
index 75e9e86..28ad0ae 100644
--- a/src/main/clas/signed-clas.txt
+++ b/src/main/clas/signed-clas.txt
@@ -32,26 +32,6 @@ Gregory A. Denton WA, USA 2013-05-02
Mikhail Mazursky Bashkortostan,Russia 2013-10-02
Marvin B. Lillehaug Trondheim, Norway 2014-01-20
Chetan Mehrotra Uttar Pradesh, India 2014-02-04
-Eric Dahl NE, US 2014-02-04
-Adam Gent MA, USA 2014-04-01
-Sebastian Groebler Berlin, Germany 2014-07-17
-Alexander Dorokhine CA, USA 2014-12-07
-Yuji Okazawa Tokyo, Japan 2015-04-01
-Lukasz Cwik WA, USA 2015-06-11
-Juan Pablo Santos Madrid, Spain 2015-06-15
-Gareth Davis Cambridge, UK 2015-07-15
-Marek Szalik Warszawa, Poland 2015-11-25
-Pavel Boldyrev Ontario, Canada 2015-12-22
-Christoph Zauner Ennsdorf, Austria 2016-01-11
-David Roberge Maine, USA 2016-02-14
-Adam Batkin Connecticut, USA 2016-02-14
-Ville Koskela Washington, USA 2016-02-19
-Vedran Pavic Croatia 2016-02-23
-Max Urech AG, Swizerland 2016-03-17
-Kenneth Gendron CA, USA 2016-04-01
-Espen A. Fossen Norway 2016-04-07
-Scott Babcock WA, USA 2016-12-22
-
Justification for CLAs
----------------------
@@ -70,11 +50,10 @@ Public License 1.0 (in addition to LGPL) in logback version
logback and it was a fairly painless process. Without the CLA on file,
dual-licensing logback would have been near impossible.
-3) by virtue of clauses 4 and 5 of the CLA, the contributor vouches
-for his/her contributions as his/her own and that he/she is entitled
-to grant the license. Thus, QOS.ch takes a lesser risk when
-distributing software because QOS.ch can claim that some vetting has
-been performed (due diligence).
+3) by virtue of clause 3 of the CLA, the contributor vouches for
+his/her contributions as his/her own. Thus, QOS.ch takes a lesser risk
+when distributing software because QOS.ch can claim that some vetting
+has been performed (due diligence).
A more detailed discussion of CLAs can be found at [2].
diff --git a/src/main/licenseHeader.txt b/src/main/licenseHeader.txt
index 3c97b18..49f6f08 100644
--- a/src/main/licenseHeader.txt
+++ b/src/main/licenseHeader.txt
@@ -1,5 +1,5 @@
Logback: the reliable, generic, fast and flexible logging framework.
-Copyright (C) 1999-2015, QOS.ch. All rights reserved.
+Copyright (C) 1999-2013, QOS.ch. All rights reserved.
This program and the accompanying materials are dual-licensed under
either the terms of the Eclipse Public License v1.0 as published by
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/logback.git
More information about the pkg-java-commits
mailing list