How to write all log output to file spring boot - java

I'm using logback-spring.xml in a spring boot project. I want to log all uncaught exceptions to a file. Basically just direct the output from the console to a file. I've tried several variations of logback-spring.xml.
I tried this
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="com.mine" level="WARN" additivity="false">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</logger>
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE">
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
</appender-ref>
</root>
</configuration>
with this in my main method SLF4JBridgeHandler.install();
I've tried this from the spring docs
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
this is in my application.yml
logging:
file: C:\dev\assessment-tool\logs\application.log
config: classpath:logback-spring.xml
For these it will log all the start up logging messages but when an exception is thrown and not caught it goes to the console and doesn't show up in the log file. How can I make uncaught exceptions go to a log file?

The problem is on the levels you're assigning to the loggers in the logback-spring.xml file.
According to the logback architecture documentation, (you can check it here) "The effective level for a given logger L, is equal to the first non-null level in its hierarchy, starting at L itself and proceeding upwards in the hierarchy towards the root logger".
You're assigning level "INFO" on your root logger, and level "WARN" on the logger "com.mine". None of them get "called" when there is an exception, ex: logger.error(Exception e).
One solution is assign the level "DEBUG" or "ERROR" to the logger "com.mine" or to the root logger, because they have attached the appender "FILE".

Related

log4j.properties file to log4j2.xml conversion

I am upgrading from log4j1.x to log4j-2.8.2
I am trying to convert my existing log4j.properties file to equivalent log4j2.xml.
My first question is can I write log4j2.proeprties file instead of log4j2.xml file?
I found some equivalent tags to log4j.proeprties file in log4j2.xml.
I did not find tags for the below lines. can anybody suggest on this?
# LoggerFactory for ESAPI to utilize Log4J
log4j.loggerFactory=org.owasp.esapi.reference.Log4JLoggerFactory
log4j.category.Default=ALL, CONSOLE, RollingFile2, edelivery
log4j.rootCategory=OFF
log4j.logger.org.apache=INFO
log4j.logger.IntrusionDetector=ERROR
log4j.logger.org.springframework=WARN
Thanks in advance.
What i am sure is:
See the last three lines:
log4j.logger.org.apache=INFO
log4j.logger.IntrusionDetector=ERROR
log4j.logger.org.springframework=WARN
I think in log4j.xml they should be instead of like these below:
<Logger name="org.apache" level="INFO"/>
<Logger name="IntrusionDetector" level="ERROR"/>
<Logger name="org.springframework" level="WARN"/>
And what I am not sure is:
these two lines:
log4j.category.Default=ALL, CONSOLE, RollingFile2, edelivery
log4j.rootCategory=OFF
I guess you have configured some appenders with the name in above line like:
<appender name="CONSOLE">
other proerties....
</appender>
so i think you could try to use these in your log4j.xml:
<root>
<appender-ref ref="ALL" />
<appender-ref ref="CONSOLE" />
<appender-ref ref="RollingFile2" />
<appender-ref ref="edelivery" />
</root>
And What I really don't know is:
log4j.loggerFactory=org.owasp.esapi.reference.Log4JLoggerFactory
I Know nothing about esapi so i could not suggest how to deal with it, hope someone else to give more answer.

How to disable console logging in spring-boot?

I'm using the default logging configuration of spring-boot.
How can I prevent the console output, while keeping the logging into a logfile configured with logging.file=myfile.log?
My goal is to not having console windows output, but only logging to that file.
Without having to create a specific logback.xml configuration. Because I'm using spring-boot for not having to configure the logging myself.
It turned out if I set the following property empty, the console logging is disabled:
logging.pattern.console=
Or commenting in xml if you use it
<!--<root level="error">-->
<!--<appender-ref ref="console"/>-->
<!--</root>-->
I created a file called logback.xml with the content:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="org.springframework" level="ERROR"/>
<logger name="org.hibernate" level="ERROR"/>
</configuration>
See this link for more information: https://www.mkyong.com/spring-boot/spring-boot-test-how-to-stop-debug-logs/
Create a file logback-spring.xml in /resources/ folder of your application.
Copy the below content in logback-spring.xml
<?xml version = "1.0" encoding = "UTF-8"?>
<configuration>
<appender name = "STDOUT" class = "ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%m%n</pattern>
</encoder>
</appender>
<root level = "INFO">
<appender-ref ref = "STDOUT"/>
</root>
</configuration>
All the supported logging systems can have the logger levels set in the Spring Environment using ‘logging.level.*=LEVEL’ where ‘LEVEL’ is one of TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF. The root logger can be configured using logging.level.root. Example application.properties:
logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
Check this information: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html
You could also overwrite the logback configuration and provide the value OFF to it.
<configuration>
<!-- turn OFF all logging (children can override) -->
<root level="OFF">
<appender-ref ref="STDOUT" />
</root>
</configuration>
You can find more information at the following link: https://logback.qos.ch/manual/configuration.html#rootElement

Logback: separate logging WARN / TRACE

I'm trying to configure logback to print:
- everything (level trace or debug) to the screen
- everything (level trace or debug) to the debugfile
- warnings and above to an error file
My logback.xml config is like this:
...
<logger name="be" level="TRACE">
<appender-ref ref="FILE-AUDIT" />
<appender-ref ref="STDOUT" />
</logger>
<root level="WARN">
<appender-ref ref="FILE-ERROR" />
</root>
However, the error and debug file contain exactly the same, being ALL logging (debug and error). I've already tried to play with the additivity option, but that's apparently not what I need.
The second question is that I use name "be" to have all classes under be.* but actually I want to capture everything there (com.* as well).
Found a solution by adding a filter to the appender:
<appender name="FILE-ERROR"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- deny all events with a level below WARNING -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>

Log4j2: SMTPAppender does not send mails with error or fatal level

I recognized some problems with the SMTPAppender in log4j2. Whenever log events with the level error or fatal are created without having an event with the level info before no mail is sent and the fatal event disappears.
Here is my log4j2 configuration file (log4j2.xml) and a small program (LogTest.java) to reproduce the problem:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="warn">
<!-- mail server configuration -->
<properties>
<property name="receipients">me#example.com</property>
<property name="from">me#example.com</property>
<property name="smtpHost">smtp.example.com</property>
<property name="smtpPort">25</property>
<property name="smtpProtocol">smtp</property>
<property name="smtpUser">me</property>
<property name="smtpPassword">secret</property>
</properties>
<appenders>
<!-- appender to write all info events to stdout -->
<Console name="Console" target="SYSTEM_OUT">
<ThresholdFilter level="info" onMatch="NEUTRAL" onMismatch="DENY"/>
</Console>
<!-- appender to send mails (default: error and fatal events)-->
<SMTP name="Mailer" suppressExceptions="false"
subject="Error log" to="${receipients}" from="${from}"
smtpHost="${smtpHost}" smtpPort="${smtpPort}"
smtpProtocol="${smtpProtocol}" smtpUsername="${smtpUser}"
smtpPassword="${smtpPassword}" smtpDebug="false" bufferSize="2">
</SMTP>
<!-- appender to send mails asynchronously -->
<Async name="AsyncMailer" >
<appender-ref ref="Mailer"/>
</Async>
</appenders>
<loggers>
<!-- logger to send mail on (at least) info level events -->
<logger name="LogTest" level="info" additivity="true">
<appender-ref ref="AsyncMailer"/>
</logger>
<!-- root logger to see what happens (info level and "above") -->
<root level="info">
<appender-ref ref="Console"/>
</root>
</loggers>
</configuration>
I used this small program to reproduce the problem (LogTest.java):
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
class LogTest
{
private static Logger logger=LogManager.getLogger("LogTest");
public void testlogger()
{
/* --> uncomment to enable first mail
logger.info("test info 1");
*/
logger.fatal("test fatal 1");
/* --> uncomment to enable second mail
logger.info("test info 2");
*/
logger.fatal("test fatal 2");
}
public static void main(String[] args)
{
LogTest app=new LogTest();
app.testlogger();
}
}
If you uncomment the two marked positions everything work like intended: two mails are sent - each containing the fatal-event and the prior info event. Additionally the 4 events are printed to stdout:
test info 1
test fatal 1
test info 2
test fatal 2
Now, if you only activate/uncomment the second position - the second mail (fatal2) is sent as intended (again with the prior info2 event), but even though the first fatal event is printed to stdout the mail is eaten up. The output looks as follows:
test fatal 1
test info 2
test fatal 2
Personally, for me it seems like I got something wrong and mis-configured log4j2 or it might be a bug.
Thanks for your help in advance.
*Jost
Note:
For the tests I used log4j2-beta7 downloaded from the project's website.
The documentation can be found here.
At first glance this looks like a bug. Does it still happen if you remove the LogTest logger and configure your root logger like this?
<root level="info">
<appender-ref ref="Console"/>
<appender-ref ref="AsyncMailer"/>
</root>
FYI, if later you need different log levels on the different appenders you can achieve that like this (no need for a separate logger):
<root level="trace">
<appender-ref ref="A" level="info" />
<appender-ref ref="B" level="debug" />
</root>

Allow future developers block my logger

I am using logback for logging and have no logger set, just root logger:
<root>
<level value="ALL" />
<appender-ref ref="FILE" />
<appender-ref ref="STDOUT" />
</root>
In class it looks like this:
Logger log = LoggerFactory.getLogger(foo.bar.MyClass.class); // foo.bar is package definition
Can future developers block my logging by defining rules for my packages, like this:
<logger name="foo.bar" level="OFF" />
Or, I must define my logger in class like this:
Logger log = LoggerFactory.getLogger("MyCoolLogger");
And people can disable it thanks to given name:
<logger name="MyCoolLogger" level="OFF" />
Yes.
Logback loggers inherit settigns from their parent loggers, so foo.bar.MyClass will inherit settings from foo.bar

Categories

Resources