Spring MVC x wildfly 17 x logbackconfiguration - spring-mvc

So I have a project for which I need to set up logback. This project is strictly spring MVC(can't be upgraded to spring-boot). It is deployed on wildfly 17.0.1.
I have a few questions regarding this.
So I did the setup of logback and logs are generated fine. But auto scan of the configuration file logback.xml is not working.
My setup
This is the only dependency I've added to my project. Logback is set up to bridge via slf4j(set up in wildfly)
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.9</version>
</dependency>
This is my logback.xml file.
<configuration scan="true" scan_period="2 seconds" debug="false" packagingData="false">
<property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
<property name="LOG_DIR" value="path/to/dir" />
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/server.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<!-- <level>INFO</level>-->
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/server.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>365</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${PATTERN}</pattern>
</encoder>
</appender>
<appender name="APP_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/app.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<!-- <level>INFO</level>-->
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/uix.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>365</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${PATTERN}</pattern>
</encoder>
</appender>
<appender name="ACCESS_APP_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/access.app.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<!-- <level>INFO</level>-->
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/access.app.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>365</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${PATTERN}</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
</root>
<logger name="com.package.path" level="INFO" additivity="false">
<appender-ref ref="ACCESS_APP_FILE"/>
</logger>
<logger name="com.package.path.2" level="INFO" additivity="false">
<appender-ref ref="APP_FILE"/>
</logger>
</configuration>
This logback.xml file is placed in wildfly's standalone folder for me to be able to change the runtime log level(reference to logback.xml is given in standalone.sh). But this is not working and after searching for it, people suggested putting it in the target folder which does not make sense(since I then can't change the log level once *.war is deployed).
So can someone suggest what can be done here where I can achieve changing log level at runtime?
The console Appender does not work at all. Logs that are supposed to be seen in the console, are stored in a log file. But I also want them to be displayed on the console too. I'm using the same configuration file as above. Can you help me with this too?
Things I've done
Added jboss-deployment-structure.xml and excluded other logging libraries from wildfly or even my own project.
Setting LogContext and setting configuration file in the project which also didn't work.
Any help is much appreciated :)

Related

Log4net starts working when setting internal debugging on

I have .NET 4.5.2 Web API 2 application on IIS 8 server which uses log4net (1.2.13.0) for logging. I'm also using Windsor Castle. The problem is that log4net logging is working fine on production server for days, even weeks. But then, for unknown reason, it stops writing anything to log file. My log4net configuration is following:
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="TextFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:\Logs\MyApplication.log" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %level %property{Guid} - %message%n" />
</layout>
</appender>
<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="toaddress#domain.com" />
<from value="noreply#domain.com" />
<subject value="MyApplication production environment - ERROR" />
<smtpHost value="my.smtp.server.com" />
<bufferSize value="1" />
<lossy value="false" />
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="ERROR" />
</evaluator>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="ERROR" />
<acceptOnMatch value="true" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %level %property{Guid} - %message%n" />
</layout>
</appender>
<root>
<level value="All"></level>
<appender-ref ref="TextFileAppender" />
<appender-ref ref="SmtpAppender"/>
</root>
</log4net>
</configuration>
I first tried setting write permissions to the Logs-folder for IIS accounts - without any effect. I first suspected this since this is customer's server and it's possible that some admin was messing around with folder permissions. Then I set log4net internal debugging on with following settings:
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
<appSettings>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="log4net.txt" />
</listeners>
</trace>
</system.diagnostics>
It writes log4net.txt file, and everything seems to be in order. Some example from the internal log:
log4net: Searched for existing files in [C:\Logs]
log4net: curSizeRollBackups starts at [0]
log4net: [.2016-05-26] vs. [.2016-05-30]
log4net: Initial roll over to [C:\Logs\MyApplication.log.2016-05-26]
log4net: Moving [C:\Logs\MyApplication.log] -> [C:\Logs\MyApplication.log.2016-05-26]
log4net: curSizeRollBackups after rollOver at [0]
log4net: Opening file for writing [C:\Logs\MyApplication.log] append [True]
log4net: Created Appender [TextFileAppender]
log4net: Adding appender named [TextFileAppender] to logger [root].
log4net: Loading Appender [SmtpAppender] type: [log4net.Appender.SmtpAppender]
As you can see, there was 4 days gap when logs were not written. But now the strange thing. The logging is now also successfully written to C:\Logs\MyApplication.log file, even when I remove settings for log4net internal debugging. So it seems that setting log4net internal debugging on fixed the problem. But this is not proper long term solution.
Any ideas what's happening here?

How to configure Log4j in Spring for MyBatis SQL queries?

I have the a Spring MVC project with mybatis 3.3.0 and mybatis-spring 1.2.3 and I want to configure log4j in my project. And I'm not using mybatis-config.xml for setting up mybatis sql session factory. So I cannot use the following setting,
<configuration>
<settings>
...
<setting name="logImpl" value="LOG4J"/>
...
</settings>
</configuration>
So, I have the following config in my
spring-context.xml,
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="typeAliasesPackage" value="com.sample.model"/>
<property name="mapperLocations" value="classpath*:com/sample/mappers/*.xml" />
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.sample.mappers" />
</bean>
And configured this log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%p] %c{1} - %m%n"/>
</layout>
</appender>
<logger name="java.sql" additivity="false">
<level value="debug"/>
<appender-ref ref="STDOUT"/>
</logger>
<logger name="org.apache.ibatis" additivity="false">
<level value="debug"/>
<appender-ref ref="STDOUT"/>
</logger>
<logger name="org.mybatis.spring" additivity="false">
<level value="debug"/>
<appender-ref ref="STDOUT"/>
</logger>
<logger name="com.sample.mappers">
<level value="debug"/>
<appender-ref ref="STDOUT"/>
</logger>
<root>
<priority value ="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
The above configuration doesn't print the sql queries executed or the prepared statements. So as documented in mybatis logging page and from this answer, I used the log4j.properties instead of xml config,
log4j.properties
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
log4j.logger.com.sample.mappers=DEBUG
# SqlMap logging configuration.
log4j.logger.org.mybatis.spring=DEBUG
log4j.logger.org.apache.ibatis=DEBUG
log4j.logger.org.apache.ibatis.jdbc.ScriptRunner=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d [%p] %c{1} - %m%n
I had the common-logging removed from the pom.xml too. But that also doesn't seem to work.
How to set MyBatis to print all the sql queries(PreparedStatements)?
If in case MyBatis is not detecting the log4j, Is there any way to tell MyBatis to use log4j as the default logging framework without using the mybatis-config.xml?
I found the solution and now I can see all the Prepared Statements and all of the Mapper interface queries & parameters in my console. Invoking this line of code once the server started up before calling any MyBatis queries works fine,
org.apache.ibatis.logging.LogFactory.useLog4JLogging();
Other methods for other loggin frameworks are mentioned here.
If you choose to call one of these methods, you should do so before
calling any other MyBatis method. Also, these methods will only switch
to the requested log implementation if that implementation is
available on the runtime classpath. For example, if you try to select
Log4J logging and Log4J is not available at runtime, then MyBatis will
ignore the request to use Log4J and will use it's normal algorithm for
discovering logging implementations.
I also hided the following two dependencies in my pom.xml,
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
Once I set to use log4j as default logger using useLog4JLogging() method, in console I could see MyBatis picking up the log4j as its logger framework now.
[DEBUG] org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.

log4net doesn't create log file when deployed on IIS7

Good morning everybody,
I have a log4net issue that didn't exist when I was developing on my
local machine, but once I deployed the application to a server, log4net stopped working.
This is the server configuration :
-Windows XP SP3
-IIS 7
-framework .Net v4
This is the log4net configuration in the web.config of the website:
<configuration>
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="log.txt" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="30MB" />
<staticLogFileName value="false" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n" />
</layout>
</appender>
</log4net>
</configuration>
I also have a class library and this is its App.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
</configSections>
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender" >
<param name="File" value="log.txt" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="30MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n" />
</layout>
</appender>
</log4net>
</configuration>
This is how I call the log function on every class:
private static readonly ILog log = LogManager.GetLogger(typeof(AppDomain));
...and this is how i call it :
log.Error("\n\t=>" + ex.GetBaseException().Message + "\n\r" + " # " + Environment.StackTrace);
It could be that you do not have permissions to write to the file 'log.txt'.
I don't know what the current directory would be but it's unlikely to be somewhere IIS can write to.
You need to create a folder somewhere and grant access for IIS to write to it, I understand you need to grant access to the IIS_IUSRS group and then specify the absolute path to that file. e.g.
<param name="File" value="D:\Logs\log.txt" />
..using the path to your preferred location.
When it comes to writing log files I tend not to try and write my log files anywhere in the program files directory or anything in any virtual directory just because of the previous battles I've had with security issues. Currently I'm using something like the following for all my log4net log files:
<file type="log4net.Util.PatternString" value="${ALLUSERSPROFILE}/<Product Name>/Logs/<Program Name>/<Program Name>.log" />
${ALLUSERSPROFILE} is the key above. This directory typically doesn't have the security restrictions as virtual directory and the program files directory. I've found that I haven't had any trouble since I've been using this path.
This envrionment variable takes you to the ProgramData directory in Windows Vista, 7, 8, Server 2008 etc. I think XP takes you to a different place but still a directory with relaxed permissions.
On a side note your log statement above:
log.Error("\n\t=>" + ex.GetBaseException().Message + "\n\r" + " # " + Environment.StackTrace);
Can be shortened to: log.Error(ex); Unless the formatting is a must. But if you write it like that and deploy your binaries with the pdbs the exceptions you log will contain the full stack trace and the line number the error occurred on.
Edit:
Log files will also fail to create if you have invalid log4net configuration. If you are sure that you have write access to the folder specified in your log4net configuration I would suggest enabling log4net debugging by first setting debug="true" in your log4net config section:
<log4net debug="true">
...
</log4net>
Setting the above debug flag will tell log4net to output all it's logging via windows trace listeners. To capture this trace listener output you will have to add a section like the following to your app.config:
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\tmp\log4net.txt" />
</listeners>
</trace>
</system.diagnostics>
Make sure the path specified in the above trace listener config in app.config exists and that you have write access to the folder!
I had the same problem myself and it turned out that I had forgot to set the "Build Action" for the configuration file. Therefore the log4net.config file was not deployed, and this is of course needed to make the application write the log file.
The log folder directory should be given the permission under which IIS is running. e.g. if IIS is run as network service then add Network service account the directory and give full permission to it.
Check with reference to following configuration in web.config. If everything good , check the write permission of inetpub sub-folder using the application pool owner. If not grant full permission.
Hope it will resolve your issue
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net debug="true">
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="logs\log.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5p %d %5rms %-22.22c{1} %-18.18M - %m%n %newline--%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingLogFileAppender" />
</root>
</log4net>

log4net does not write in IIS 6.0

I have the following log4net configuration:
<log4net>
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<!-- Pattern to output the caller's file name and line number -->
<conversionPattern value="%date [%thread] %-5level %ndc - %message%newline" />
</layout>
</appender>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="C:/logs/mysystem.log" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<maximumFileSize value="1024MB" />
<maxSizeRollBackups value="30" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level - %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="Console" />
<appender-ref ref="RollingFile" />
</root>
in the local machine it works fine, but when I deploy the web site to the remote server (IIS 6.0) it does not create the log file despite the fact that the system is running.
The AppPool identity is configured to "Network Service".
Any idea?
When the application pool is configured to "Network Service" it does not have sufficient permissions to write to the file system, therefore the log file does not created.
Configure the identity of the app pool to "Local System", it will work fine!
You can grant access "Network Service" access to the logs folder by create a ACE on the folder using the machines name as the principle. Changing the pool identity to "Local System" can have undesirable effects so I would avoid that.
Another approach is to create a domain user and add this user to the machine IIS_WPG group. Change the pool identity to use this user. You can then grant appropriate folder access to this user.

log4net for NHibernate not writing anything into ASP.NET trace

Odd one this.
I am using NHibernate with one website. I have configured log4net to show me all SQL and and errors in the trace. It all works swimmingly.
I start using NHibernate in the other website - same solution, built on top of same class libraries. I copy the configuration data in web.config from one website to the other:
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
<log4net>
<appender name="AspNetTraceAppender" type="log4net.Appender.AspNetTraceAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<logger name="NHibernate.SQL" additivity="false">
<level value="DEBUG" />
<appender-ref ref="AspNetTraceAppender" />
</logger>
<root>
<level value="ERROR"/>
<appender-ref ref="AspNetTraceAppender"/>
</root>
</log4net>
Obviously the new website also has a reference to log4net.dll.
But in the new website, I get no NHibernate output in the trace!
To the best of my knowledge, with log4net you just reference the dll, set up the config and off you go.
Can anyone think what I might be missing?
Thanks
David
Looks like you're forgetting to initialize it.
Take a look at the comment section of this post:
Logging NHibernate SQL with log4net in ASP.NET

Resources