I am using a spring boot application, and i have logback.xml
which after build I store outside the jar.
In application.yml I declare the path to my logback:
logging:
config: logback.xml
I add dependency which has its own logback.xml.Now when i start my app with command
java -Dspring.profiles.active=local -Dspring.config.location=configLocation -jar ./my-app.jar
i see in log:
18:10:51,480 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
18:10:51,481 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
18:10:51,482 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [jar:file:/C:/projects/RegistryBack/registry-app/target/itr-registry-distribution/itr-registry.jar!/BOOT-INF/lib/mq-logback-appender-2.1.jar!/logback.xml]
My logback is not used, but is taken from the library:/BOOT-INF/lib/mq-logback-appender-2.1.jar!/logback.xml.
I could force my logback.xml to be used with commands used only together:
-Dlogging.config=./logback.xml -Dlogback.configurationFile=./logback.xml
but this is strange and seems very bad.
Related
I have a question regarding the location where I should save my logback.xml file so that my program can find it. I now saved it in src/main/resources, but it cannot find it. I know this since
String URL = "logback.xml";
System.out.println(ClassLoader.getSystemResource(URL));
returns null.
The logger does work, but prints all information to the command line
null
13:05:26.606 [main] DEBUG o.j.f.c.master.AbstractMaster - Number of columns: 18
13:05:26.613 [main] DEBUG o.j.f.c.master.AbstractMaster - Objective value: 479.0
13:05:26.666 [main] DEBUG o.j.f.c.master.AbstractMaster - Number of columns: 113
13:05:26.668 [main] DEBUG o.j.f.c.master.AbstractMaster - Objective value: 272.0
13:05:26.693 [main] DEBUG o.j.f.c.master.AbstractMaster - Number of columns: 118
13:05:26.694 [main] DEBUG o.j.f.c.master.AbstractMaster - Objective value: 238.0
13:05:26.721 [main] INFO o.j.f.c.master.AbstractMaster - Best objective value found: 238.0
13:05:26.721 [main] INFO o.j.f.c.master.AbstractMaster - (d1-s2-s2-d1) (s2-c1-s2) (s2-c3-c2-
s2);238.0 chosen with value: 1.0 resulting in cost: 238.0
The content of my logback.xml file is
<configuration scan="true" info="true">
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>myApp.log</file>
<append>false</append>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%msg%n</pattern>
</layout>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<logger name="algorithms.MultiLabel.cg.master" level="OFF"/>
<root level="debug"> <!-- levels: OFF, info, debug -->
<appender-ref ref="FILE" />
<appender-ref ref="STDOUT" />
</root>
</configuration>
Next I make some changes to the logback.xml file and again save it in the src/main/resources folder. If I now run my program again, I suddenly get the following output.
file:./target/classes/logback.xml
13:06:41,631 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
13:06:41,631 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
13:06:41,632 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:./target/classes/logback.xml]
13:06:41,715 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
13:06:41,720 |-INFO in ReconfigureOnChangeFilter{invocationCounter=0} - Will scan for changes in [[.\target\classes\logback.xml]] every 60 seconds.
13:06:41,720 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - Adding ReconfigureOnChangeFilter as a turbo filter
13:06:41,731 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.FileAppender]
13:06:41,733 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [FILE]
13:06:41,783 |-WARN in ch.qos.logback.core.FileAppender[FILE] - This appender no longer admits a layout as a sub-component, set an encoder instead.
13:06:41,783 |-WARN in ch.qos.logback.core.FileAppender[FILE] - To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.
13:06:41,783 |-WARN in ch.qos.logback.core.FileAppender[FILE] - See also http://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details
13:06:41,783 |-INFO in ch.qos.logback.core.FileAppender[FILE] - File property is set to [myApp.log]
13:06:41,787 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
13:06:41,789 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
13:06:41,790 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
13:06:41,797 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [algorithms] to OFF
13:06:41,797 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to INFO
13:06:41,797 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [FILE] to Logger[ROOT]
13:06:41,798 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
13:06:41,798 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
13:06:41,800 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator#36f6e879 - Registering current configuration as safe fallback point
Best objective value found: 238.0
(d1-s2-s2-d1) (s2-c1-s2) (s2-c3-c2-s2);238.0 chosen with value: 1.0 resulting in cost: 238.0
Why does it now find the file in the folder ./target (where the src folder also is located), even though I did not save it there?
All information that it is printing is coming from the master package, which I set to "OFF", so how come it is still printing it?
I am looking forward to any suggestions/explanations!
I am trying to change my existing application which runs on tomcat to SpringBoot. It runs till the actual SpringBoot starts. I have a similar application which runs on springBoot. That is how I know it runs till springboot.
My main method:
#Configuration
#EnableAutoConfiguration
#ComponentScan
public class Main {
public static void main(String[] args) {
//Every argument passed needs to become a system property
for (String arg : args) {
System.getProperties().setProperty(arg.split("=")[0], arg.split("=")[1]);
}
SpringApplication.run(Main.class, args);
}}
POM.xml has the springboot parent tag :
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.M4</version>
</parent>
I have springboot maven plugin :
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
properties has the start tag:
<start-class>com.sample.requesthandler.Main</start-class>
Dependencies has starter-web and starter-acuator:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
I tried to run the main method with #componentScan having the basePackages which looks like:
#ComponentScan(basePackages="com.sample.requesthandler")
This did not help.
I tried adding #SpringBootApplication annotation at the top of main class. That did not help too.
Below is the full log:
15:59:29,832 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type
[ch.qos.logback.core.ConsoleAppender]
15:59:29,833 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
15:59:29,833 |-INFO in
ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming
default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for
[encoder] property
15:59:29,834 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [big-sur] to ERROR
15:59:29,834 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [big-sur] to false
15:59:29,834 |-INFO in
ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender
named [FILE] to Logger[big-sur]
15:59:29,835 |-INFO in
ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender
named [STDOUT] to Logger[big-sur]
15:59:29,835 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [big-sur] to INFO
15:59:29,835 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [big-sur] to false
15:59:29,835 |-INFO in
ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender
named [FILE] to Logger[big-sur]
15:59:29,835 |-INFO in
ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender
named [STDOUT] to Logger[big-sur]
15:59:29,835 |-INFO in
ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of
ROOT logger to INFO
15:59:29,835 |-INFO in
ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender
named [FILE] to Logger[ROOT]
15:59:29,835 |-INFO in
ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender
named [STDOUT] to Logger[ROOT]
15:59:29,835 |-INFO in
ch.qos.logback.classic.joran.action.ConfigurationAction - End of
configuration.
15:59:29,835 |-INFO in
ch.qos.logback.classic.joran.JoranConfigurator#351d00c0 - Registering
current configuration as safe fallback point
My other project starts springBoot right after this line.
What am I missing? Thanks in advance.
Try to modify the version,like this
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath />
</parent>
The issue was with the logback.xml. It had multiple tags with same format. I have updated the logback.xml and it fixed the issue. Now I am able to start the spring boot application properly.
Thank you every for your time!
Your main class should implement CommandLineRunner interface from Spring Boot.
Recently I've been working with logback and everything was going smooth until I tried to use Marker Filters together with the conditional xml tags.
What I wanted to do is to have a marker filtering system that would, depending on a property previously set, choose the adequate marker filters for my appenders.
My current code is bellow:
<configuration scan="true" scanPeriod="30 seconds">
<if condition='property("severityLevel").equals("SEVERITY-2")'>
<then>
<turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
<Marker>SEVERITY-1</Marker>
<OnMatch>DENY</OnMatch>
</turboFilter>
</then>
</if>
<!-- Console Appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level - ${appName} - %marker - %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE"/>
<appender-ref ref="STDOUT"/>
</root>
</configuration>
The property severityLevel comes from the configurator property that I set before initializing the logger:
LoggerContext aLoggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
JoranConfigurator aConfigurator = new JoranConfigurator();
aConfigurator.setContext(aLoggerContext);
aLoggerContext.reset();
aLoggerContext.putProperty(APPLICATION_NAME, config.getApplicationName());
aLoggerContext.putProperty(LOG_MAX_FILE_SIZE, config.getLogMaxFileSize().toString());
aLoggerContext.putProperty(LOG_KEEP_FOR_DAYS, config.getLogKeepForDays().toString());
aLoggerContext.putProperty("severityLevel", "SEVERITY-2");
System.out.println(aLoggerContext.getProperty("severityLevel"));
try
{
aConfigurator.doConfigure(FileUtils.cleanPath(FileUtils.determineServletRealPath(""), false) + LOGBACK_CONFIGURATION_FILE_PATH);
}
catch (JoranException e)
{
StatusPrinter.printIfErrorsOccured(aLoggerContext);
throw e;
}
The expected behaviour would be that only SEVERITY-2 level messages would be logged. Instead, I keep getting all messages.
If I take the If condition out of the logback.xml file it will work fine but I still need to have another condition for a SEVERITY-3 in which both level 2 and level 1 will be denied and therefore I would need the If condition.
Some status messages from the logs:
|-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
|-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
|-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [vfs:/Applications/wildfly-10.1.0.Final/standalone/deployments/mw-file-extractor.war/WEB-INF/classes/logback.xml]
|-INFO in ch.qos.logback.core.joran.spi.ConfigurationWatchList#6b14b260 - URL [vfs:/Applications/wildfly-10.1.0.Final/standalone/deployments/mw-file-extractor.war/WEB-INF/classes/logback.xml] is not of type file
|-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
|-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - Will scan for changes in [vfs:/Applications/wildfly-10.1.0.Final/standalone/deployments/mw-file-extractor.war/WEB-INF/classes/logback.xml]
|-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - Setting ReconfigureOnChangeTask scanning period to 30 seconds
|-ERROR in ch.qos.logback.core.joran.conditional.IfAction - Could not find Janino library on the class path. Skipping conditional processing.
|-ERROR in ch.qos.logback.core.joran.conditional.IfAction - See also http://logback.qos.ch/codes.html#ifJanino
|-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
|-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
|-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
|-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
|-INFO in ch.qos.logback.classic.joran.JoranConfigurator#726fa157 - Registering current configuration as safe fallback point
Does anyone know what am I doing wrong?
Found out, with the help of #Ceki and Logback debug messages that I was missing the Janino library for the use of conditionals.
Adding both janino-3.0.8.jar and commons-compiler-3.0.8.jar fixed the issue.
In my application, I'm using SLF4j as logging facade with multiple bindings present as
slf4j-simple-1.6.2.jar
logback-classic-1.0.4.jar
Both of these are defined in pom.xml as
**<!--MANDATORY -->**
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.2</version>
</dependency>
**<!--SIMPLY DUMPS THE MESSAGE TO ERROR STREAM -->**
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.2</version>
</dependency>
**<!--logback : further configuration in logback.xml -->**
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.4</version>
</dependency>
A simple test program, which can be run natively
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TimePass {
private Logger log = LoggerFactory.getLogger(getClass());
public static void main(String[] args) {
new TimePass().run();
}
private void run() {
System.out.println(log);
log.info("WE ARE RUNNING");
System.out.println("HIHIHIHI");
}
}
This project/webapp is deployed on 2 locations.
But when I run it on both, the results are strikingly different.
On 1 instance, output is
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/hemant/.m2/repository/org/slf4j/slf4j-simple/1.6.2/slf4j-simple-1.6.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/hemant/.m2/repository/ch/qos/logback/logback-classic/1.0.4/logback-classic-1.0.4.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
0 [main] INFO com.expertly.bin.TimePass - WE ARE RUNNING
org.slf4j.impl.SimpleLogger(com.expertly.bin.TimePass)
HIHIHIHI
While on the other, its
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/hemant/.m2/repository/ch/qos/logback/logback-classic/1.0.4/logback-classic-1.0.4.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/hemant/.m2/repository/org/slf4j/slf4j-simple/1.6.2/slf4j-simple-1.6.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
14:58:18,760 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
14:58:18,760 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
14:58:18,760 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/home/hemant/Project/Expertly/ee/workspace/branches/integration/target/ROOT/WEB-INF/classes/logback.xml]
14:58:18,823 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
14:58:18,827 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.classic.sift.SiftingAppender]
14:58:18,831 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [SIFT]
14:58:18,853 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.sift.MDCBasedDiscriminator] for [discriminator] property
14:58:18,859 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender]
14:58:18,862 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [FILE-HIBERNATE]
14:58:18,868 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter#59:13 - no applicable action for [Encoding], current pattern is [[configuration][appender][Encoding]]
14:58:18,897 |-WARN in ch.qos.logback.core.rolling.RollingFileAppender[FILE-HIBERNATE] - This appender no longer admits a layout as a sub-component, set an encoder instead.
14:58:18,897 |-WARN in ch.qos.logback.core.rolling.RollingFileAppender[FILE-HIBERNATE] - To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.
14:58:18,897 |-WARN in ch.qos.logback.core.rolling.RollingFileAppender[FILE-HIBERNATE] - See also http://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details
14:58:18,905 |-INFO in ch.qos.logback.core.rolling.FixedWindowRollingPolicy#1fc6e42 - Will use zip compression
14:58:18,910 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[FILE-HIBERNATE] - Active log file name: catalina.base_IS_UNDEFINED/logs/hibernate.log
14:58:18,910 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[FILE-HIBERNATE] - File property is set to [catalina.base_IS_UNDEFINED/logs/hibernate.log]
14:58:18,911 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.classic.net.SMTPAppender]
14:58:18,918 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [EMAIL]
14:58:18,937 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to ERROR
14:58:18,937 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [EMAIL] to Logger[ROOT]
14:58:18,937 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.hibernate.type] to INFO
14:58:18,937 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [org.hibernate.type] to false
14:58:18,937 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [FILE-HIBERNATE] to Logger[org.hibernate.type]
14:58:18,937 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.hibernate] to INFO
14:58:18,938 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [org.hibernate] to false
14:58:18,938 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [FILE-HIBERNATE] to Logger[org.hibernate]
14:58:18,938 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG
14:58:18,938 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [SIFT] to Logger[ROOT]
14:58:18,938 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
14:58:18,939 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator#1aaf0b3 - Registering current configuration as safe fallback point
Logger[com.expertly.bin.TimePass]
HIHIHIHI
The issue seems to be in both the cases, multiple bindings were enlisted but in different order.
**In Case 1 : where it logged :
1. slf4j-simple-1.6.2.jar
2. logback-classic-1.0.4.jar
And it used first binding to log
In Case 2 : where it didnt log, the order was opposite and hence it went for looking for logback.xml and couldn't resolve the webcontainer specific variables (${catalina.home})**
I don't know the reason for this reversal.
I need both the bindings. Just in case when I run a java file natively, I want slf4j-simple binding to preceed the logback binding.
Thanks in advance.
As explained in the page pointed to in the error message, this is not a good idea. Quoting the note from that page:
The warning emitted by SLF4J is just that, a warning. Even when multiple bindings are present, SLF4J will pick one logging framework/implementation and bind with it. The way SLF4J picks a binding is determined by the JVM and for all practical purposes should be considered random. As of version 1.6.6, SLF4J will name the framework/implementation class it is actually bound to.
Using logback-1.0.13.jar and JDK 1.6u34.
I have a Java web app (WAR) with the following WEB-INF/classes/logback.xml:
<configuration debug="true" scan="true" scanPeriod="5 minutes">
<appender name="logManager-smtpAppender" class="ch.qos.logback.classic.net.SMTPAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>NEUTRAL</onMismatch>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<asynchronousSending>false</asynchronousSending>
<sessionViaJNDI>true</sessionViaJNDI>
<jndiLocation>java:comp/env/mail/Session-local</jndiLocation>
<subject>%logger{20} - %m</subject>
<layout class="ch.qos.logback.classic.html.HTMLLayout"/>
<cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker">
<bufferSize>25</bufferSize>
</cyclicBufferTracker>
</appender>
<root level="ALL">
<appender-ref ref="logManager-smtpAppender" />
</root>
</configuration>
And the following ${TOMCAT_HOME}/conf/context.xml (global context.xml for all web apps):
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<Resource
name="mail/Session-local"
auth="Container"
type="javax.mail.Session"
mail.smtp.host="my.smtp.server"
mail.user="smtp_user"
mail.password="smtp_password"
mail.transport.protocol="smtp"
mail.smtp.auth="true"
mail.smtp.port="25"
mail.smtp.starttls.enable="true"
/>
</Context>
And have the Java Mail API 1.4.3 (which I have verified contains a javax.mail.Authenticator class) on my runtime classpath at WEB-INF/lib/javax-mail-1.4.3.jar). I also have it in Tomcat's lib directory (${TOMCAT_HOME}/lib).
And am getting the following stack trace:
13:34:09,178 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
13:34:09,179 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
13:34:09,181 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/home/myuser/sandbox/dsi/workbench/tomcat/6.0.32/apache-tomcat-6.0.32/webapps/myapp/WEB-INF/classes/logback.xml]
13:34:09,469 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - Setting ReconfigureOnChangeFilter scanning period to 5 minutes
13:34:09,470 |-INFO in ReconfigureOnChangeFilter{invocationCounter=0} - Will scan for changes in [[/home/myuser/sandbox/dsi/workbench/tomcat/6.0.32/apache-tomcat-6.0.32/webapps/myapp/WEB-INF/classes/logback.xml]] every 300 seconds.
13:34:09,470 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - Adding ReconfigureOnChangeFilter as a turbo filter
13:34:11,782 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.classic.net.SMTPAppender]
13:34:11,830 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [logManager-smtpAppender]
13:34:11,939 |-INFO in ch.qos.logback.classic.net.SMTPAppender[logManager-smtpAppender] - Looking up javax.mail.Session at JNDI location [java:comp/env/mail/Session-local]
13:34:11,992 |-ERROR in ch.qos.logback.classic.net.SMTPAppender[logManager-smtpAppender] - Failed to obtain javax.mail.Session from JNDI location [java:comp/env/mail/Session-local]
13:34:11,992 |-ERROR in ch.qos.logback.classic.net.SMTPAppender[logManager-smtpAppender] - Failed to obtain javax.mail.Session. Cannot start.
13:34:11,993 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to ALL
13:34:11,996 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [logManager-smtpAppender] to Logger[ROOT]
13:34:11,997 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
13:34:12,000 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator#63220fd1 - Registering current configuration as safe fallback point
13:39:49,988 |-WARN in ch.qos.logback.classic.net.SMTPAppender[logManager-smtpAppender] - Attempted to append to non started appender [logManager-smtpAppender].
13:39:49,988 |-WARN in ch.qos.logback.classic.net.SMTPAppender[logManager-smtpAppender] - Attempted to append to non started appender [logManager-smtpAppender].
13:39:50,598 |-WARN in ch.qos.logback.classic.net.SMTPAppender[logManager-smtpAppender] - Attempted to append to non started appender [logManager-smtpAppender].
13:39:51,275 |-WARN in ch.qos.logback.classic.net.SMTPAppender[logManager-smtpAppender] - Attempted to append to non started appender [logManager-smtpAppender].
13:39:51,833 |-WARN in ch.qos.logback.classic.net.SMTPAppender[logManager-smtpAppender] - Attempted to append to non started appender [logManager-smtpAppender].
Any ideas as to why Logback can't retrieve my JNDI Mail Session from Tomcat's context.xml? This is preventing the SMTPAppender from starting and being able to log messages. Thanks in advance!
First, don't put the mail JAR in both locations, but in Tomcat's lib folder. If you are using Maven, use provided scope for the corresponding <dependency /> to not package it in the WAR.
Second, do you have a <resource-ref /> element for the mail session in your web.xml? If not, look here for a sample.
Another alternative is to make the session <resource /> global (in server.xml) and link to it from the context.xml, as described here.
HTH,
Jukka