In my application, I am using logback as a logging framework. The application isn't making progress. To troubleshoot, I took thread dumps (for approx 60 sec), and see the application thread remains in the WAITING stage forever, at the point where the LOG statement happens.
The below is the snippet of the AsynAppender:
"AsyncAppender-Worker-ASYNC-FILE" #209937 daemon prio=5 os_prio=0 tid=0x00007f0150108800 nid=0x799b waiting on condition [0x00007f01a8b13000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000006d9216d20> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.ArrayBlockingQueue.take(ArrayBlockingQueue.java:403)
at ch.qos.logback.core.AsyncAppenderBase$Worker.run(AsyncAppenderBase.java:289)
The below is the snippet of the logback thread:
"logback-6" #807 daemon prio=5 os_prio=0 tid=0x00007f018000b800 nid=0x6b7 waiting on condition [0x00007f0141acd000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x0000000640949190> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
The below is the snippet of the application thread:
"application-thread-005-5def0e44-fff5-4184-96dc-ee77349c31de-StreamThread-13" #66 prio=5 os_prio=0 tid=0x00007f01f5e9c000 nid=0x56 waiting on condition [0x00007f01468ea000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000006d9216fa0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
The below are snippets of logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds">
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/coldStorage.log</file>
<append>false</append>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/application.log.%d{yyyy-MM-dd_HH}
</fileNamePattern>
<maxHistory>240</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %thread %-5level - %msg
%n</pattern>
</encoder>
</appender>
<appender name="ASYNC-FILE"
class="ch.qos.logback.classic.AsyncAppender">
<queueSize>10000</queueSize>
<discardingThreshold>20</discardingThreshold>
<neverBlock>true</neverBlock>
<appender-ref ref="FILE" />
</appender>
<logger name="com.example.appl" level="ERROR" additivity="false">
<appender-ref ref="ASYNC-FILE" />
<appender-ref ref="ASYNC-STDOUT" />
</logger>
<root level="INFO">
<appender-ref ref="ASYNC-FILE" />
</root>
The application isn't making any progress because the thread remains in the WAITING state forever.
Any inputs what's possible is causing this. I tried to disable FILE altogether, still the same issues.
Related
As per documentation [https://azure.microsoft.com/en-us/documentation/articles/web-sites-java-custom-upload/], we can run a custom java app. With following setup, Wildfly runs fine but keeps getting restarted and hence I cannot access the website from [http://app-service.azurewebsites.net/].
Publishing source as "Local Git Repository"
1. git clone https://user#<app-service>.scm.azurewebsites.net:443/<app-service>.git
2. Copy Wildfly under bin folder
3. Create web.config under root folder
4. git add .
5. git commit -m "initial"
6. git push origin master
web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
</handlers>
<httpPlatform processPath="%HOME%\site\wwwroot\bin\wildfly\bin\standalone.bat"
arguments="">
<environmentVariables>
<environmentVariable name="SERVER_OPTS" value="-Djboss.http.port=%HTTP_PLATFORM_PORT%" />
<environmentVariable name="JBOSS_HOME" value="%HOME%\site\wwwroot\bin\wildfly" />
<environmentVariable name="JAVA_OPTS" value="-Djava.net.preferIPv4Stack=true" />
</environmentVariables>
</httpPlatform>
</system.webServer>
</configuration>
Log Files
1. Connect to ftp://<app-service>\user#waws-prod-sn1-033.ftp.azurewebsites.windows.net
2. Check Wildfly log at path: /site/wwwroot/bin/wildfly/standalon/log
Log snippet
2016-05-18 18:17:16,539 INFO [org.jboss.as] (MSC service thread 1-1) WFLYSRV0049: Keycloak 1.9.1.Final (WildFly Core 2.0.10.Final) starting
2016-05-18 18:17:16,539 DEBUG [org.jboss.as.config] (MSC service thread 1-1) Configured system properties:
awt.toolkit = sun.awt.windows.WToolkit
file.encoding = Cp1252
file.encoding.pkg = sun.io
...
2016-05-18 18:17:16,549 DEBUG [org.jboss.as.config] (MSC service thread 1-1) VM Arguments: -Dprogram.name=standalone.bat -Djava.net.preferIPv4Stack=true -Dorg.jboss.boot.log.file=D:\home\site\wwwroot\bin\keycloak\standalone\log\server.log -Dlogging.configuration=file:D:\home\site\wwwroot\bin\keycloak\standalone\configuration/logging.properties
2016-05-18 18:17:22,976 INFO [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0039: Creating http management service using socket-binding (management-http)
2016-05-18 18:17:23,095 INFO [org.xnio] (MSC service thread 1-2) XNIO version 3.3.4.Final
2016-05-18 18:17:23,193 INFO [org.xnio.nio] (MSC service thread 1-2) XNIO NIO Implementation Version 3.3.4.Final
2016-05-18 18:17:23,347 INFO [org.jboss.remoting] (MSC service thread 1-2) JBoss Remoting version 4.0.18.Final
...
2016-05-18 18:18:07,318 INFO [org.wildfly.extension.undertow] (ServerService Thread Pool -- 48) WFLYUT0021: Registered web context: /auth
2016-05-18 18:18:07,457 INFO [org.jboss.as.server] (ServerService Thread Pool -- 45) WFLYSRV0010: Deployed "keycloak-server.war" (runtime-name : "keycloak-server.war")
2016-05-18 18:18:07,799 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management
2016-05-18 18:18:07,799 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:9990
2016-05-18 18:18:07,799 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: Keycloak 1.9.1.Final (WildFly Core 2.0.10.Final) started in 53968ms - Started 416 of 782 services (526 services are lazy, passive or on-demand)
The issue was with dynamic port (not 8080). The correct configuration to work with dynamic port assignment is as follows. Please notice the change in arguments="-Djboss.http.port=%HTTP_PLATFORM_PORT%".
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
</handlers>
<httpPlatform processPath="%HOME%\site\wwwroot\bin\wildfly\bin\standalone.bat"
arguments="-Djboss.http.port=%HTTP_PLATFORM_PORT%" startupTimeLimit="120" startupRetryCount="2" requestTimeout="00:10:00" stdoutLogEnabled="true">
<environmentVariables>
<environmentVariable name="JBOSS_HOME" value="%HOME%\site\wwwroot\bin\wildfly" />
</environmentVariables>
</httpPlatform>
</system.webServer>
</configuration>
Following configuration logs to Eventlog and it works for SmtpSender. But the filelogger does not log, it creates the log file in the path, but does not do any debug logs.
<root>
<level value="DEBUG" />
<appender-ref ref="EventLogAppender" />
</root>
<logger additivity="false" name="SmtpLogger">
<level value="FATAL"/>
<appender-ref ref="SmtpAppender" />
</logger>
<logger name="RollingFileAppender">
<level value="DEBUG"/>
<appender-ref ref="RollingFileAppender"/>
</logger>
But when I change the root logger to RollingFileAppender it logs to file,
<root>
<level value="DEBUG" />
<appender-ref ref="RollingFileAppender" />
</root>
<logger additivity="false" name="SmtpLogger">
<level value="FATAL"/>
<appender-ref ref="SmtpAppender" />
</logger>
<logger name="RollingFileAppender">
<level value="DEBUG"/>
<appender-ref ref="RollingFileAppender"/>
</logger>
Any idea why this happens? How can I get file logger working in this scenario.
You did not post the appender confuriguration, however the easiest way to figure out what goes wrong is enable internal debugging. This will tell you what goes wrong in the rolling file appender:
There are 2 different ways to enable internal debugging in log4net.
These are listed below. The preferred method is to specify the
log4net.Internal.Debug option in the application's config file.
• Internal debugging can also be enabled by setting a value in the
application's configuration file (not the log4net configuration file,
unless the log4net config data is embedded in the application's config
file). The log4net.Internal.Debug application setting must be set to
the value true. For example:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
</configuration>
This setting is read immediately on startup an will cause all internal
debugging messages to be emitted.
• To enable log4net's internal debug programmatically you need to set
the log4net.Util.LogLog.InternalDebugging property to true. Obviously
the sooner this is set the more debug will be produced.
Internal debugging messages are written to the console and to the
System.Diagnostics.Trace system. If the application does not have a
console the messages logged there will be lost. Note that an
application can redirect the console stream by setting the
System.Console.Out. The Trace system will by default send the message
to an attached debugger (where the messages will appear in the output
window). If the process does not have a debugger attached then the
messages are sent to the system debugger. A utility like DebugView
from http://www.sysinternals.com may be used to capture these
messages.
As log4net internal debug messages are written to the
System.Diagnostics.Trace system it is possible to redirect those
messages to a local file. You can define a trace listener by adding
the following to your application's .config file:
<configuration>
...
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\tmp\log4net.txt" />
</listeners>
</trace>
</system.diagnostics>
...
</configuration>
Make sure that the process running your application has permission to write to this file.
log4net faq
I managed to get the logging work, in fact I did this as an experiment and it worked.
Added RollingFileAppender to the root element,
<root>
<level value="DEBUG" />
<appender-ref ref="EventLogAppender" />
<appender-ref ref="RollingFileAppender"/>
</root>
<logger additivity="false" name="SmtpLogger">
<level value="FATAL"/>
<appender-ref ref="SmtpAppender" />
</logger>
<logger name="RollingFileAppender">
<level value="DEBUG"/>
<appender-ref ref="RollingFileAppender"/>
</logger>
We use log4j2 for message logging in our applications. Currently, our log4j2 configurations use an Async Appender which then reference a Socket Appender (protocol="tcp") to write logs to a remote Logstash Server:
<Socket name="logstash" host="logging" port="4560" protocol="tcp" >
<LogStashJSONLayout>
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
<KeyValuePair key="tomcat.host" value="${env:HOSTNAME}"/>
<KeyValuePair key="tomcat.port" value="${env:CONNECTOR_PORT}"/>
<KeyValuePair key="tomcat.service" value="${web:contextPath}"/>
</LogStashJSONLayout>
</Socket>
<Async name="async">
<AppenderRef ref="logstash"/>
</Async>
What we would now like to do is to, modify our log4j2 configuration to include a fallback RollingFile Appender for cases where the Logstash Server is not available and, to accomplish this, we are thinking that we would modify the Async Appender by:
Setting 'blocking=false'.
Setting 'ignoreExceptions="false"'
Setting an 'errorRef' to point to our fallback RollingFile Appender.
Is this a sensible way of accomplishing this? And, if so, how would the Async Appender's XML look like? We tried the following:
<RollingFile name="fallbackFile"
fileName="${sys:catalina.base}/logs/${web:contextPath}-fallback.log"
filePattern="${sys:catalina.base}/logs/${web:contextPath}-%d{dd-MMM-yyyy}-%i.log"
append="true">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
<Policies>
<SizeBasedTriggeringPolicy size="1 GB" />
</Policies>
</RollingFile>
<Socket name="logstash" host="logging" port="4560" protocol="tcp" >
<LogStashJSONLayout>
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
<KeyValuePair key="tomcat.host" value="${env:HOSTNAME}"/>
<KeyValuePair key="tomcat.port" value="${env:CONNECTOR_PORT}"/>
<KeyValuePair key="tomcat.service" value="${web:contextPath}"/>
</LogStashJSONLayout>
</Socket>
<Async name="async" blocking="false" ignoreExceptions="false" errorRef="fallbackFile">
<AppenderRef ref="logstash"/>
</Async>
But we get an error when deploying the application in an environment where the Logstash Server node is purposely unavailable:
2015-04-24 09:55:43,688 ERROR Unable to invoke factory method in class class org.apache.logging.log4j.core.appender.SocketAppender for element Socket. 2015-04-24 09:55:43,702 ERROR Null object returned for Socket in Appenders. 2015-04-24 09:55:43,707 ERROR No appender named logstash was configured Apr 24, 2015 9:55:43 AM org.apache.catalina.core.StandardContext startInternal SEVERE: Error during ServletContainerInitializer processing javax.servlet.ServletException: Failed to instantiate WebApplicationInitializer class at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:160) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5481) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1081) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:553) at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1668) at sun.reflect.GeneratedMethodAccessor532.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(Unknown Source) at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(Unknown Source) at org.apache.catalina.manager.ManagerServlet.check(ManagerServlet.java:1480) at org.apache.catalina.manager.ManagerServlet.deploy(ManagerServlet.java:709) at org.apache.catalina.manager.ManagerServlet.doPut(ManagerServlet.java:450) at javax.servlet.http.HttpServlet.service(HttpServlet.java:649) at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:612) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Unknown Source) Caused by: java.lang.ExceptionInInitializerError at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at java.lang.Class.newInstance(Unknown Source) at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:157) ... 42 more Caused by: java.lang.NullPointerException at org.apache.logging.log4j.core.appender.AsyncAppender.start(AsyncAppender.java:108) at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:157) at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:364) at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:422) at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:146) at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:75) at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:37) at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:468) at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:403) at com.company.service.config.WebInitialiser.(WebInitialiser.java:21)
What are we doing wrong? Should we be using a Failover Appender instead maybe?
--------- UPDATE ---------
After further testing, I can say that the above setup works in cases where the Socket Appender's host is available but NOT the port (e.g. service unavailable). But it does NOT work in cases where the Socket Appender's host is NOT available (e.g. unknown host).
Now, in order to have the fallbackFile Appender work in both cases (service unavailable and unknown host), I have included a Failover Appender over our SocketAppender:
<RollingFile name="fallbackFile"
fileName="${sys:catalina.base}/logs/${web:contextPath}-fallback.log"
filePattern="${sys:catalina.base}/logs/${web:contextPath}-%d{dd-MMM-yyyy}-%i.log"
append="true">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
<Policies>
<SizeBasedTriggeringPolicy size="1 GB" />
</Policies>
</RollingFile>
<Socket name="logstash" host="logging" port="4560" protocol="tcp" >
<LogStashJSONLayout>
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
<KeyValuePair key="tomcat.host" value="${env:HOSTNAME}"/>
<KeyValuePair key="tomcat.port" value="${env:CONNECTOR_PORT}"/>
<KeyValuePair key="tomcat.service" value="${web:contextPath}"/>
</LogStashJSONLayout>
</Socket>
<Failover name="failover" primary="logstash">
<Failovers>
<AppenderRef ref="fallbackFile"/>
</Failovers>
</Failover>
<Async name="async" bufferSize="10" blocking="false" ignoreExceptions="false" errorRef="fallbackFile">
<AppenderRef ref="failover"/>
</Async>
This configuration seems to be giving us the behaviour we wanted.
Any cleaner/neater solutions or even comments on this configuration would be most welcome.
Cheers,
PM
logstash-gelf is much more resilient than log4j2's SocketAppender. AsyncAppenders can protect applications up to a certain degree, still you can run into issues with TCP, such as service not available, slow or the connection/reconnection eats up time.
GELF works over UDP, so if the service is down/not reachable, it does not affect your application performance in any way. The only thing that might happen is that you might lose log events, but you've got the file fallback for that case.
A full example of logstash-gelf's config looks like:
<Configuration>
<Appenders>
<Gelf name="gelf" host="udp:localhost" port="12201" version="1.1" extractStackTrace="true"
filterStackTrace="true" mdcProfiling="true" includeFullMdc="true" maximumMessageSize="8192"
originHost="%host{fqdn}">
<Field name="timestamp" pattern="%d{dd MMM yyyy HH:mm:ss,SSS}" />
<Field name="level" pattern="%level" />
<Field name="simpleClassName" pattern="%C{1}" />
<Field name="className" pattern="%C" />
<Field name="server" pattern="%host" />
<Field name="server.fqdn" pattern="%host{fqdn}" />
<!-- This is a static field -->
<Field name="fieldName2" literal="fieldValue2" />
<!-- This is a field using MDC -->
<Field name="mdcField2" mdc="mdcField2" />
<DynamicMdcFields regex="mdc.*" />
<DynamicMdcFields regex="(mdc|MDC)fields" />
</Gelf>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="gelf" />
</Root>
</Loggers>
</Configuration>
Full documentation is available here: http://logging.paluch.biz/
The updated solution is 99% good.
As specified in log4j async appender, ignoreExceptions must be set to false on the socket appender to make it work with the failover appender.
You must set this to false when wrapping this Appender in a FailoverAppender.
I am working on .NET Framework 4.0 using C# in Windows 7, and trying to log from a class library but it's not working. I'm running my application without errors, but also nothing happens to my log file, neither to my console.
So, here is my code:
This is my App.config file:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<add key="log4net.config" value="config.log4net"/>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{ABSOLUTE} [%thread] %level %logger - %message%newlineExtra Info: %property{testProperty}%newline%exception"/>
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG"/>
<levelMax value="FATAL"/>
</filter>
</appender>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="MyLogFile.txt"/>
<appendToFile value="true"/>
<rollingStyle value="Size"/>
<maxSizeRollBackups value="5"/>
<maximumFileSize value="10MB"/>
<staticLogFileName value="true"/>
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="debug"/>
</filter>
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="error"/>
</filter>
<filter type="log4net.Filter.DenyAllFilter"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level %logger - %message%newline%exception"/>
</layout>
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="ConsoleAppender"/>
<appender-ref ref="RollingFileAppender"/>
</root>
<logger name="MyApplication">
<level value="DEBUG"/>
<appender-ref ref="ConsoleAppender"/>
<appender-ref ref="RollingFileAppender"/>
</logger>
</log4net>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
This is what I put into my AssemblyInfo.cs:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
This what is at the file i'm trying to log:
private static readonly ILog log = LogManager.GetLogger(
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
log.Debug("Testing");
When i run my program nothing happens. Someone knows why?
Similar to this answer, both the app.config, log4net configuration and the AssemblyInfo.cs configurator needs to be placed in the host application.
Lets say I have project Console as a console project that I will run, and Library as a Library project. Console will need to have an app.config file with the above log4net configuration, and the AssemblyInfo.cs will need the XmlConfigurator code inside of it. Library does not need either of these, and will work by using the LogManager call.
Console > This is the project that you will run.
Properties
AssemblyInfo.cs > Place [assembly: log4net.Config.XmlConfigurator(Watch = true)] here.
app.config > Place log4net XML configuration here.
Program.cs > Start of application.
Library
Properties
AssemblyInfo.cs > Leave this file alone.
Foo.cs > Create the private readonly property.
SomeMethod() > log.Debug("Test");
Incase anyone is still looking at this and to add to the previous answers, you need to have instantiated a logger in your host application before you can log from the class library.
If you look at the log4net documentation for assembly attributes it says this:
"Therefore if you use configuration attributes you must invoke log4net
to allow it to read the attributes. A simple call to LogManager.GetLogger will cause the attributes on the calling assembly
to be read and processed. Therefore it is imperative to make a logging call as early as possible during the application start-up, and
certainly before any external assemblies have been loaded and invoked."
When the assembly attributes are defined in a class library - i.e. an external assembly - it gets tricky. Can you use log4net.Config.XmlConfigurator.Configure(path) instead?
I am getting following errors on my console repeatedly
log4j:ERROR Attempted to append to closed appender named [ConsoleAppender].
log4j:ERROR Attempted to append to closed appender named [FixedWindowRollingFile].
used log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
<appender class="org.apache.log4j.rolling.RollingFileAppender" name="FixedWindowRollingFile">
<param name="Append" value="true"/>
<param name="ImmediateFlush" value="true"/>
<rollingPolicy class="org.apache.log4j.rolling.FixedWindowRollingPolicy">
<param name="fileNamePattern" value="logs/StandardizeAccountService.%i.log"/>
<param name="minIndex" value="1"/>
<param name="maxIndex" value="10"/>
</rollingPolicy>
<triggeringPolicy class="org.apache.log4j.rolling.SizeBasedTriggeringPolicy">
<param name="MaxFileSize" value="1002400"/>
</triggeringPolicy>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %p %c{1}:%L - %m%n"/>
</layout>
</appender>
<appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.SimpleLayout"/>
</appender>
<logger name="com.arosys" additivity="false" >
<level value="INFO" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="FixedWindowRollingFile"/>
</logger>
<root>
<priority value="INFO"/>
<appender-ref ref="ConsoleAppender"/>
<appender-ref ref="FixedWindowRollingFile"/>
</root>
</log4j:configuration>
please help me where the problem.
I got the same error:
log4j:ERROR Attempted to append to closed appender named [rollingFileAppender].
In my log4j.xml
I have two loggers with the same name like below
<logger name="java.sql.PreparedStatement" additivity="false">
<level value="INFO"/>
<appender-ref ref="rollingFileAppender"/>
</logger>
<logger name="java.sql.PreparedStatement">
<level value="INFO"/>
<appender-ref ref="rollingFileAppender"/>
</logger>
I removed the duplicate, it worked.
I've answered similar question here: https://stackoverflow.com/a/9973283/340290
In my case, I've two log4j.properties available to the Log4J: one via placing it in classpath and other being loaded programmatically (using PropertyConfigurator.configure(..)).
And in the two files, I've ConsoleAppender registered with same name stdout and used for same category twice (one per each properties file). Removing config or the properties file solved my issue.
One could overwrite the configuration using:
BasicConfigurator.resetConfiguration();
PropertyConfigurator.configure(props);
Just to clarify because I was mislead by MaDa answer, additivity=false redirects the output to another place than the default (root logger) and NOT to the default.
See http://logging.apache.org/log4j/1.2/manual.html chapter "Appenders and Layouts"
This may also mean that you already have your server running, and you're trying to run it again. The second instance can't write to the log file because it's already open in your server.
solution: check to see if your server is already running, and restart it if neccessary.
In my case, I added by mistake 2 "root" elements.
I'm not saying this is the cause of the behaviour you describe (but it might), but this part:
<logger name="com.arosys" additivity="false" >
<level value="INFO" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="FixedWindowRollingFile"/>
</logger>
is pointless. Normally, you'd set a non-additive logger to redirect it somewhere else than the default place (your root logger), but you still send the output to the default place. You might as well delete this fragment.