Amazon AWS Spring MVC log4j2 logging - spring-mvc

Not sure if it is a right place, but will try here.
I have a Spring MVC app deployed on Amazon Elastic Beantalk, using log4j2.
Locally, the logs work well.
this is the config:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
<RollingFile
name="MyFile"
fileName="${sys:catalina.home}/logs/log4j2.log"
filePattern="${sys:catalina.home}/logs/log4j2-%d{MM-dd-yyyy}-%i.log"
immediateFlush="true">
<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="5 MB"/>
</Policies>
<DefaultRolloverStrategy max="2000"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="debug"/>
<Root level="info">
<AppenderRef ref="STDOUT"/>
<AppenderRef ref="MyFile"/>
</Root>
</Loggers>
</Configuration>
But on EC2 amazon instance, where the ElasticBeanstalk app is running, no appenders working. even SYSTEM_OUT doesn't logged into catalina.out. Absolutely no clue why can that happens :(
Btw before i have experience using ElasticBeanstalk, and usually hadprobs with File appender, but at least log is appended to catalina.out .
Any idea what should i check?

Related

How to stop node from logging node.conf during startup

How do I stop the node from printing the node.conf in the logs?
I understand we can change the logging level since the node.conf is printed at INFO level, but I want to avoid that as much as possible since I still want some other information that is at INFO level to be printed out.
The contents of node.conf are printed at INFO level by the net.corda.node.services.config.ConfigHelper class. To prevent the contents of node.conf from being printed to the logs, you'd have to specify a custom logging configuration so that for the net.corda.node.services.config.ConfigHelper class, only messages at WARN or above should be printed to the logs.
The process for providing a custom Log4J2 logging configuration file for your node is documented here. You need to:
Create the custom logging file (e.g. test.xml)
Point your node to the custom logging file when starting the node (e.g. java -Dlog4j.configurationFile=test.xml -jar corda.jar)
Here's an example test.xml that prevents the contents of node.conf being printed to the logs:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Properties>
<Property name="log-path">logs</Property>
<Property name="log-name">node-${hostName}</Property>
<Property name="archive">${log-path}/archive</Property>
</Properties>
<Appenders>
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout pattern="%highlight{%level{length=1} %d{HH:mm:ss} %T %c{1}.%M - %msg%n}{INFO=white,WARN=red,FATAL=bright red blink}"/>
</Console>
<RollingFile name="RollingFile-Appender"
fileName="${log-path}/${log-name}.log"
filePattern="${archive}/${log-name}.%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="[%-5level] %d{ISO8601}{GMT+0} [%t] %c{1} - %msg%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>
<DefaultRolloverStrategy min="1" max="10">
<Delete basePath="${archive}" maxDepth="1">
<IfFileName glob="${log-name}*.log.gz"/>
<IfLastModified age="60d">
<IfAny>
<IfAccumulatedFileSize exceeds="10 GB"/>
</IfAny>
</IfLastModified>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console-Appender"/>
<AppenderRef ref="RollingFile-Appender"/>
</Root>
<Logger name="net.corda" level="error" additivity="false">
<AppenderRef ref="Console-Appender"/>
<AppenderRef ref="RollingFile-Appender"/>
</Logger>
<Logger name="net.corda.node.services.config.ConfigHelper" level="warn" additivity="false">
<AppenderRef ref="RollingFile-Appender"/>
</Logger>
</Loggers>
</Configuration>
Note the final Logger block. We specify that any messages from net.corda.node.services.config.ConfigHelper (e.g. the contents of node.conf) should only be printed if they are at level WARN or above.
#Joel is there any way to point all the nodes to one custom logging file? I.e, when executing runnodes.jar, could you pass a single logfile as a paramater, i.e:
java -jar -Dlog4j.configurationFile=/Users/username/Desktop/Prototype/config/dev/log4j2.xml runnodes.jar
This doesn't seem to work... so curious.

Can't enable spring orm/transaction logging even when log4j.xml is configured

I have a configuration problem regarding enabling spring related logging in my application as I'm using EclipseLink,JPA 2.0 & Spring 4.0, I need to verify when the entity manager is closed or cleaned up while doing transactions.
My application is JTA enabled so everything is controlled by my container (Websphere).Here is my log4j.xml
<?xml version="1.0"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="true" xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- CONSOLE normally used in desktop environment -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<param name="Threshold" value="DEBUG"/>
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%-8X{context}] %-5p %-40.40c{2} - %m%n"/>
</layout>
</appender>
<appender name="FILE_APPENDER" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="C:\\proj\\was\\logs\\spring.log"/>
<param name="DatePattern" value="'-'yyyy-MM-dd'.txt'"/>
<param name="Threshold" value="DEBUG"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-4p [%t] %C{2} - %m%n"/>
</layout>
</appender>
<!-- Spring -->
<logger name="org.springframework.transaction" additivity="false">
<level value="DEBUG" />
<appender-ref ref="FILE_APPENDER"/>
</logger>
<logger name="org.springframework.orm.jpa.EntityManagerFactoryUtils" additivity="false">
<level value="DEBUG" />
<appender-ref ref="FILE_APPENDER"/>
</logger>
<logger name="org.springframework.orm.jpa" additivity="false">
<level value="DEBUG" />
<appender-ref ref="FILE_APPENDER"/>
</logger>
<root>
<level value="DEBUG" />
<appender-ref ref="console" />
<appender-ref ref="FILE_APPENDER" />
</root>
</log4j:configuration>
I have also tried many solutions like this, but it didn't help.Please help me where I'm going wrong?
From your comment, it seems that you not have the adapter slf4j to log4j. Or have another adapter.
To check the adapter in use, use the code:
StaticLoggerBinder binder = StaticLoggerBinder.getSingleton();
System.out.println(binder.getLoggerFactoryClassStr());
If it is not the log4j12 adapter showing:
Check on the war, you should have a slf4j-api-xxxx.jar in WEB-INF/lib.
put the slf4j-log4j12-xxxx.jar (same version) into WEB-INF/lib
if there is logback-xxxxx.jar remove it, else slf4j will take it to log
if there is log4j-over-slf4j-xxxx.jar remove it, else it is possible that log4j log will be redirected to slf4j that will redirect to log4j and so on..
there is perhaps another adapter (slf4j-jcl-xxxx.jar for instance) that need to be removed.
Logger Hierarchy
In most logging systems, logger has the parent and child relationship, in which children inherit
Level
Appender
ResourceBoudle
from father logger. And the root logger exists at the top of inheritance. The children will send log event to father logger depending on additivity. False means it will not send log to father logger.
So, from your original config, you didn't allow Spring related logger to send log to your root logger.
Suggestions
So, now we understand that we should set additivity to true and change the log4j config into like following:
<logger name="org.springframework.transaction" additivity="true"/>
<logger name="org.springframework.orm.jpa.EntityManagerFactoryUtils" additivity="true"/>
<logger name="org.springframework.orm.jpa" additivity="true"/>
<root>
<level value="DEBUG" />
<appender-ref ref="console" />
<appender-ref ref="FILE_APPENDER" />
</root>
More
Here and here are the blog posts I write about slf4j & log4j & logback, which Spring uses, and you can read to enhance the understanding of logging;
If you change the additivity and still can't see the log in console/file, I suggest you set a breakpoint at any logging line in EntityManagerFactoryUtils, then step in code to see what's wrong;
Update
The logger of EntityManagerFactoryUtils, as we can from source code, is not slf4j or log4j. It is commons logging. So your log4j config about this class will not work.
import org.apache.commons.logging.Log;
private static final Log logger = LogFactory.getLog(EntityManagerFactoryUtils.class);
In order to make your config work, you should make some bridge work:
exclude commons-logging.jar from spring-orm
add jcl-over-slf4j.jar
make sure you have slf4j-api & slf4j-log4j
By looking at the Jars on your classpath some cleaning is probably required, but in order to do so we need to understand what each of the Jars do.
log4j-1.2.9.jar
Is the implementation of Log4j. This one is required in order to log anything using Log4j and of course reading your log4j configuration file.
slf4j.api-1.6.1.jar
Is the Slf4j API library, Only required if you or some of your third-party dependencies use Slf4j for logging, which seem quite likely as you already have it on your classpath. This allows you to write to the logs through Slf4J API, e.g:
private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(MyLoggingClass.class);
slf4j.jdk14-1.6.1.jar
Is a JDK 1.4, also known as java.util.logging binding for Slf4j used to use java.util.logging as the logging engine when Slf4j is used. Obviously we're going to use log4j as the logging implementation and not java.util.logging meaning this should be removed.
slf4j-log4j12-1.7.12.jar
Is a log4j 1.2 binding for Slf4j, required to route logs from Slf4j to your Log4j implementation. This one is only required if slf4j.api-1.6.1.jar was required. However, versions should be harmonized in order to avoid conflicts.
commons-logging-1.1.1.jar and
commons-logging.jar
As far as I can tell those are both the commons logging framework. This is the logging framework used by Spring. However, you should only have one of those on your classpath, where I recommend using the one which reveals it's version.
Having the correct Jars on your classpath, commons logging should be able to pick up the correct logging implementation for you (which in your case is Log4j). If that's not the case, explicitly put a file named commons-logging.properties on the root of your classpath and add the following line to it:
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4jLogger
forcing it to use Log4j as the logging implementation.

Logs from java.util.logging in ICM

In my cartridge I use an external library that logs with java.util.logging. I want to redirect the log to SLF4J/logback, but somehow this does not work as I would expect it (logs are empty). Here is the relevant logback configuration:
<appender name="PayPal_LogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>TRACE</level>
</filter>
<File>${intershop.logfile.Directory}/paypal-${intershop.logfile.NamePostfix}.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${intershop.logfile.Directory}/paypal-${intershop.logfile.NamePostfix}.%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
<encoder>
<pattern>
[%date{yyyy-MM-dd HH:mm:ss.SSS Z}] %-5level ${intershop.HostName} ${intershop.InstallationID} ${intershop.ServerName} [%mdc{requestsite}] [%mdc{requestapplication}] %logger [%marker] [%mdc{request.type}] [%mdc{session.id}] [%mdc{request.uuid}] "%thread" %msg %ex%n
</pattern>
</encoder>
</appender>
<logger name="com.paypal" additivity="false">
<level value="TRACE" />
<appender-ref ref="Error" />
<appender-ref ref="PayPal_LogFile" />
</logger>
JUL logs in DEBUG level, DEBUG level is allowed for com.paypal and I believe that this should be translated to INFO in SLF4J. What's wrong?
I'll answer my own question.
The reason for the trouble is the additivity="false" property of the logger.
Background: Routing from other logging frameworks to SLF4J is generally easy via the so called bridges unless we speak about JUL. See the details here. ICM implements its own bridge between JUL and SLF4J and there is a subtle bug inside. The logging handler of the ICM is attached to the root level and any appender with additivity="false" won't work because it will never reach the root level.
The bug seems to be here com.intershop.beehive.core.internal.log.JavaLoggingAdapter:
handler = new JavaLoggingHandler();
handler.setLevel(Level.ALL);
Logger root = LogManager.getLogManager().getLogger("");
root.addHandler(handler);
I've changed the additivity to true although I'm not very happy about this and now I can explore the third party logs.

Configuring commons logging in Glassfish

I am using commons logging for my application running on Glassfish V3.1(I am new to glassfish). I have different applications running on Glassfish under ../domain1 folder(Developers machine). I am using an XML to configure Logging.Following is the my xml config
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration>
<appender name="file"
class="org.apache.log4j.RollingFileAppender">
<param name="maxFileSize" value="100KB" />
<param name="maxBackupIndex" value="5" />
<param name="File" value="/home/phanikumar/Desktop/debug.log" />
<param name="threshold" value="debug"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{DATE} %5p %c{1}:%L - %m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="warn" />
<param name="LevelMax" value="fatal" />
</filter>
</appender>
<logger name="com">
<level value="DEBUG" />
<appender-ref ref="file"/>
</logger>
<root>
<appender-ref ref="file" />
</root>
</log4j:configuration>
In this config file I have explicitly mentioned the file to be in a specific location but it never did.Is there any problem with the logger file?Am I missing some thing?
or
Is there any way that I can configure my logs to be in a specific location? I have seen the server.log file and it is unsuitable for my requirement as the logs of all applications are logged in a same file.
Please kindly help me.
SOLUTION
Add a Properties file named commons-logging.properties in the class path.
And add the following property
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
This initializes Logging to Log4j Logger
Then it works perfectly.
EDIT:
Usually, by default commons logging searches for loggers like log4j. If the above solution doesnt work, one needs to check if the commons-logging jar file is corrupted i.e, check if the class files like org.apache.commons.logging.impl.Log4jLogger is present.

.NET Web Deployment Tool with log4Net: Not overwriting logs

I'm using the Web Deployment Tool to build and release an MVC site from VS 2010 to a server running IIS. I also have log4net logging to a subdirectory off of the root of the web application I'm deploying to. I already figured out how to keep write permissions intact when deploying with this tool on that directory, but now I'm running into the problem that I'd rather not lose the logs when deploying, and also, the deploy is failing because the log file that log4net is using is "used by another process" (presumably w3wp) and won't let the deploy continue.
So, I'd like to preserve the log files and not delete or overwrite them, for auditing purposes. Is there a way to do that within the confines of the Web Deployment Tool?
EDIT: Here's the applicable bits of the log4net configuration, in Web.Config.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net" />
</configSections>
<log4net>
<appender name="RollingLog" type="log4net.Appender.RollingFileAppender">
<param name="File" value="Logs\Log.txt" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Composite" />
<maxSizeRollBackups value="20" />
<maximumFileSize value="10MB" />
<datePattern value="yyyyMMdd" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="{%level}%date{MM/dd HH:mm:ss} - %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingLog" />
</root>
</log4net>
</configuration>
Found it by hunting around: there is a "skip" parameter you can tack on to the command when you call the pre-packaged deploy script. You HAVE to use a regular old CMD prompt for this; Powershell's crazy escaping of quotes makes it near-impossible to get right, so I gave up. Anyway, here's the end result I came up with:
.\MyProject.deploy.cmd /Y /M:MyServerName "-skip:skipAction=Delete,objectName=filePath,absolutePath=Logs"
"MyProject.deploy.cmd" being the name of the prepackaged deploy command, "MyServerName" being the name of the server I was deploying to, and "Logs" being the name of the folder I wanted to skip. This command seems to leave alone that Logs directory and deploy anything else that matters.
Source where I started to hone in on things: http://blogs.iis.net/msdeploy/archive/2009/04/23/what-has-changed-about-skip-replace-rules-in-rc.aspx
Set locking model of your appender to minimal lock and everything will be fine:
<appender name="RollingLog" type="log4net.Appender.RollingFileAppender">
...
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
...
</appender>
log4net.Appender.FileAppender (see remarks)

Resources