Why Log4Net is not writing the error logs? - asp.net-mvc-3

I have tried several way to tweak but Log4Net file logger is not logging anything in my MVC3 web app.
What I am missing? I am not getting any error either.
The log4net dll is added to the application and it points to a local copy.
1 main web.config:
<appSettings>
<add key="Log4NetConfigFilename" value="log4net.config" />
<add key="Log4NetConfigFilePath" value="C:\DEV\App\source\App.Web\log4net.config" />
</appSettings>
2 Global.asax.cs
protected void Application_Start()
{
log4net.Config.XmlConfigurator.Configure();
}
3 Log4net.config file:
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<logger name="MyLogger">
<level value="ALL" />
<appender-ref ref="MyRollingLogFileAppender" />
</logger>
<appender name="MyRollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="C:\\Support\Logs\\logs.log" />
<param name="AppendToFile" value="true" />
<param name="RollingStyle" value="Size" />
<param name="MaxSizeRollBackups" value="10" />
<param name="MaximumFileSize" value="1024KB" />
<param name="StaticLogFileName" value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout, log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821">
<param name="ConversionPattern" value="%date{MM-dd-yyyy HH:mm:ss} [%-5level] [%identity] - %message %newline" />
</layout>
</appender>
</log4net>
#4 I have a folder created C:\Support\Logs
#5 The log4net.config file is located in C:\DEV\App\source\App.Web\log4net.config
6) controller where I am trying to log a string
These 2 values getting in the controller correctly
using log4net;
using log4net.Config;
using System.Configuration;
namespace My.Controllers
{
public class TestController : MyBaseController
{
private static readonly ILog _log = LogManager.GetLogger("MyLogger");
private static readonly string _log4netConfigFilename = ConfigurationManager.AppSettings["Log4NetConfigFilename"];
private static readonly string _log4netConfigFilePath = ConfigurationManager.AppSettings["Log4NetConfigFilePath"];
[HttpGet]
public ActionResult Index()
{
if (_log.IsDebugEnabled) <-- ALWAYS FALSE
_log.DebugFormat("Processing Index() view"); <-- NEVER GETS WRITTEN
var model = new MyModel();
return View(model);
}
}
}

It's acting like it isn't seeing your configuration file. Try explicitly setting it to look at the configuration file by updating your App_Start code to the following:
log4net.Config.XmlConfigurator.Configure(ConfigurationManager.AppSettings["Log4NetConfigFilePath"]);
I'm not where I can test it at the moment but see if that gets it.

You need to make sure that you are using the custom log4net.config by specifying the path when calling Configure:
log4net.Config.XmlConfigurator.Configure(new FileInfo(ConfigurationManager.AppSettings["Log4NetConfigFilePath"]));
And as far as I know, you don't need the additional assembly info on the <layout> section of the config (was causing me errors):
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%date{MM-dd-yyyy HH:mm:ss} [%-5level] [%identity] - %message %newline" />
</layout>

Related

Log4j2 plugin not loaded in Spring 4

While Spring 4 Rest application loading , i am getting the logger information ( log file name / path / archival days) from database and passing this value to Logj plugin , so that i can retrieve the value from log4j.xml.
My application log file not created and plugin not called ! not getting any error in console as well.
What should i do , for Logj plugin load and log file creation ?
Spring:4.3.15.RELEASE
log4j:2.4.1
java:1.8
SpringWebInitializer.java
public class SpringWebInitializer implements WebApplicationInitializer{
#Override
public void onStartup(ServletContext ctx) throws ServletException {
AnnotationConfigWebApplicationContext webCtx = new AnnotationConfigWebApplicationContext();
webCtx.register(WebConfiguration.class);
webCtx.setServletContext(ctx);
ServletRegistration.Dynamic servlet = ctx.addServlet("dispatcher", new DispatcherServlet(webCtx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
//Add Listener.
ctx.addListener(new MyAppContextListner());
}
}
WebConfiguration.java
#EnableWebMvc
#Configuration
#ComponentScan(basePackages ="org.vasa.ws.myapp")
public class WebConfiguration {
}
MyAppContextListner.java
public class MyAppContextListner implements ServletContextListener{
private static final Logger LOGGER = LogManager.getLogger(BenefitsCompositeContextListner.class);
private WebApplicationContext webApplicationContext = null;
#Override
public void contextInitialized(ServletContextEvent event) {
// Database connectivity and get the logger information from db.
}
#Override
public void contextDestroyed(ServletContextEvent event) {
// TODO Auto-generated method stub
}
}
Given below Log4j Plugin i am using
MyLog4JConfigDatabaseLookup.java
#Plugin(name = "MyAppdbLookup", category = StrLookup.CATEGORY)
public class MyLog4JConfigDatabaseLookup extends AbstractLookup {
public String lookup(final LogEvent event, final String key) {
System.out.println("Lookup......");
}
}
log4j2.xml
<Configuration packages="org.vasa.ws.myapp">
<Properties>
<Property name="app-name">MyAppdbLookup</Property>
<Property name="file-level">${MyAppdbLookup:logLevel}</Property>
<Property name="log-file">${MyAppdbLookup:logFile}</Property>
<Property name="log-file-level">${MyAppdbLookup:logLevel}</Property>
<Property name="log-path">${MyAppdbLookup:logPath}</Property>
<Property name="archive-days">${MyAppdbLookup:archive-days}</Property>
</Properties>
<Appenders>
<Routing name="route-log">
<Routes pattern="framework">
<Route key="benefitCompositeWS">
<RollingFile name="message-log" fileName="${log-path}/myapp.log"
filePattern="${log-path}/$${date:yyyy-MM}/myapp.%d{MM-dd-yyyy}-%i.log.gz" append="true">
<PatternLayout
pattern="%d{MM/dd/yyyy HH:mm:ss.SSS z} [%t] %-5level %logger{36} - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="150 MB" />
</Policies>
<DefaultRolloverStrategy max="1000">
<Delete basePath="${log-path}" maxDepth="2">
<IfFileName glob="*/myapp*.log.gz" />
<IfLastModified age="${archive-days}" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile >
</Route>
</Routes>
</Routing>
<Loggers>
<Root level="${file-level}" additivity="false">
<AppenderRef ref="route-log" />
<AppenderRef ref="STDOUT" />
</Root>
</Loggers>
</Configuration>
I have changed my plugin name as lower case and now it's working fine as expected:
#Plugin(name="myappdblookup")

How to load application.properties into Log4j2 LogEventPatternConverter class?

I am working on a task that I want to mask sensitive data using Log4j2 LogEventPatternConverter Class.
#Plugin(name="SensitiveDataLog", category = "Converter")
#ConverterKeys({"sense"})
public class SensitiveDataLog extends LogEventPatternConverter {
#Value("${ssn}")
private String ssn;
public SensitiveDataLog(String name, String style) {
super(name, style);
}
public static SensitiveDataLog newInstance(String[] options) {
return new SensitiveDataLog("sense","sense");
}
#Override
public void format(LogEvent logEvent, StringBuilder outputMsg) {
String message = logEvent.getMessage().getFormattedMessage();
Matcher matcher = SSN_PATTERN.matcher(message);
if (matcher.find()) {
String maskedMessage = matcher.replaceAll("***-**-****");
outputMsg.append(maskedMessage);
} else {
outputMsg.append(message);
}
}
}
Suppose I want to keep pattern in application.properties, But problem here is we cannot load property value ssn. Always its null.
Here is my log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info" monitorInterval="30"
packages="com.virtusa.xlab.fw.logging.component"
xmlns="http://logging.apache.org/log4j/2.0/config">
<Properties>
<Property name="basePath">logs/log4j2</Property>
</Properties>
<Appenders>
<!-- File Appender -->
<RollingFile name="FILE"
fileName="${basePath}/logfile.log" filePattern="${basePath}/logfile.%d{yyyy-MM-dd}-%i.log" append="true">
<PatternLayout
pattern="%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C{2} (%F:%L) - %sense%n" />
<Policies>
<SizeBasedTriggeringPolicy size="1 KB" />
</Policies>
<DefaultRolloverStrategy max="4" />
</RollingFile>
<!-- Console Appender -->
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout
pattern="%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C{2} (%F:%L) - %sense%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="com.virtusa.xlab.fw" level="info" />
<Root level="info">
<AppenderRef ref="STDOUT" />
<AppenderRef ref="FILE" />
</Root>
</Loggers>
</Configuration>
Can anyone help me out here?
Thanks.
The problem is that SensitiveDataLog is created via static method newInstance(). Obviously, field ssn is not initialized at that moment. What you can do is to init the field later, e.g. when refreshing Spring context.
Here is my snippet:
private static XmlMaskPatternConverter INSTANCE = new XmlMaskPatternConverter();
public XmlMaskPatternConverter() {
super(NAME, NAME);
}
public static XmlMaskPatternConverter newInstance() {
return INSTANCE;
}
Now you can call static method getInstance() somewhere in your Spring Configuration (I do it in #Bean method) and set the ssn value there. Ofc, you need to create a setter for this field.
P.S. Hope it helps. I faced this problem too, so decided to leave my solution here. My first post on SO btw)

logback-spring.xml log to file while using org/springframework/boot/logging/logback/base.xml

I have created a test project with Spring Boot to learn about about using the logback-spring.xml file. I want to use Spring's default setting for writing to console so I am using the following line
<include resource="org/springframework/boot/logging/logback/base.xml" />
And I also want to log to a file on a rolling basis and keep a maximum number of log files on the system. Writing to console is working as expected. However no logs are written to the log file. The folder named "logs" gets created and the file "logfile.log" also gets created. But nothing gets logged to it.
Below is the fill logback-spring.xml file
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<property name="LOG_PATH" value="logs" />
<property name="LOG_ARCHIVE" value="${LOG_PATH}/archive" />
<appender name="File-Appender" class="ch.qos.logback.core.FileAppender">
<file>${LOG_PATH}/logfile.log</file>
<encoder>
<pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} %magenta([%thread]) %highlight(%-5level) %logger{36}.%M - %msg%n</pattern>
<outputPatternAsHeader>false</outputPatternAsHeader>
</encoder>
</appender>
<logger name="test" level="DEBUG" />
</configuration>
and below is the TestApplication.java file which is part of the test package
#SpringBootApplication
public class TestApplication {
private static final Logger logger = LoggerFactory.getLogger(TestApplication.class);
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
logger.trace("Trace Message!");
logger.debug("Debug Message!");
logger.info("Info Message!");
logger.warn("Warn Message!");
logger.error("Error Message!");
}
}
Why is nothing being logged to the file?
I think there are a few issues.
First, remove the line <logger name="test" level="DEBUG" /> . This sets up a logger for classes under the package test but defines no appender, so nothing is logged.
Once that's gone, add
<root level="DEBUG">
<appender-ref ref="File-Appender"/>
</root>
This will configure the root logger (which all loggers inherit) on debug level and to output all the logs to the File-Appender.
Also, I cannot recall if logback creates missing directories, so you might need to ensure the logs directory does exist before starting the application.

Spring boot logbcak to file is not working on tomcat

I am running spring boot as War on tomcat with logback to console and file.
as long as i run as Java application it is fine i can see logs in console and file.
but i dont see logs printed to file when run on server.
I tried setting logger manager also, didnt work. was wondering to know if some one has faced similar issue.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<property name="LOG_FILE"
value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}app.log}"/>
<property name="LOG_FILE_MAX_SIZE" value="10MB" />
<property name="LOG_TOTAL_SIZE_CAP" value="100MB" />
<property name="LOG_FILE_MAX_HISTORY" value="20" />
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
Verify that you have the following dependency :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
or even if you have spring-boot-starter-web dependency added, logging should work.
and have the following in yml or properties file :
logging.path=logs
logging.file=${logging.path}/log.log
logging.pattern.file=%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M - %msg%n
and you can also have a logback.xml and use the spring default base.xml in that so that all default spring configurations apply for your logging as well :
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<logger name="org.springframework.web" level="DEBUG"/>
</configuration>
Here is my logback-spring.xml which i have
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<property name="LOG_FILE"
value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}app.log}"/>
<property name="LOG_FILE_MAX_SIZE" value="10MB" />
<property name="LOG_TOTAL_SIZE_CAP" value="100MB" />
<property name="LOG_FILE_MAX_HISTORY" value="20" />
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
I could fix it by writing the logs to a different folder looks application doesn't have write access the path, however i need to make some changes to springboot main class for loading application props based profile, please find the class below. not sure if others had to the same.
anyway i am glad it is working finally:)
public class Application extends SpringBootServletInitializer{
public String PROFILE = null;
private static String CONFIG_LOCATION = null;
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
//Grab the active profile from the servlet conext
PROFILE = servletContext.getInitParameter("spring.profiles.active");
CONFIG_LOCATION = servletContext.getInitParameter("spring.config.path");
super.onStartup(servletContext);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
//...and pass it to the boot application
application.application().setAdditionalProfiles(PROFILE);
return application.sources(Application.class).properties(getProperties());
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
//For Loading config from server
static Properties getProperties() {
Properties props = new Properties();
props.put("spring.config.location", CONFIG_LOCATION);
return props;
}
}
web.xml
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>dev</param-value>
</context-param>
<context-param>
<param-name>spring.config.path</param-name>
<param-value>classpath:app.config/</param-value>
</context-param>

Log4j 1.2 is not logging into RollingFileAppender

I have a problem with Log4J (version 1.2.17) configuration .properties file in my Spring (3.2.5) standalone application.
This is my configuration file, logging to a consoles works fine but RollingFileAppender doesn't append messages into logs/application_log.file. I have tried to change almost everything - file name, ConversionPattern, create the file manually and set filesystem rights (OS X Mavericks) for writing to all but nothing works.
log4j.rootLogger=INFO,CA,FA
#Console Appender
log4j.appender.CA=org.apache.log4j.ConsoleAppender
log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern=%d{ISO8601} %-5p [%c:%L] - %m%n
#Rolling File Appender
log4j.appender.FA=org.apache.log4j.RollingFileAppender
log4j.appender.FA.File=logs/application_log.log
log4j.appender.FA.MaxFileSize=50MB
log4j.appender.FA.layout.ConversionPattern=%d{ISO8601} %-5p [%c:%L] - %m%n
log4j.appender.FA.Append=true
log4j.appender.FA.MaxBackupIndex=10
log4j.appender.FA.layout=org.apache.log4j.PatternLayout
What am I doing wrong? Do you see something wrong what I don't see?
It looks like you're using wrong class for your appender. You should use org.apache.log4j.DailyRollingFileAppender (you're missing word Daily).
But personally I prefer using log4j.xml instead of log4j.properties. For example:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="true" xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="log-app" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="C:/Temp/my-log.log"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n"/>
</layout>
</appender>
<root>
<level value="debug"/>
<appender-ref ref="log-app"/>
</root>
</log4j:configuration>
jUnit test:
import org.apache.log4j.Logger;
import org.junit.Test;
public class FakeTest {
private final static Logger log = Logger.getLogger(FakeTest.class);
#Test
public void testTestMe() throws Exception {
log.debug("Debug message");
log.error("Error message");
}
}
Result in my-app.log:
2013-12-20 09:40:40,589 [main] DEBUG my.package.FakeTest - Debug message
2013-12-20 09:40:40,589 [main] ERROR my.package.FakeTest - Error message

Resources