Why does log4net stop logging after a while on .NET WCF but not a usual website? - wcf

I've search many sites and tried several different opinions. But I still could not solve it. Here are the things I did right now:
In Global.asax at Application_Startup I give the file path and startup the Log4Net.
Right after I start log4net, I write a log that says "Application has
stared'"
Currently, there is only 1 worker in IIS for the WCF application The
IIS user has access to WRITE, MODIFY and READ privileges
The problem:
When I invoke a method of service directly (without doing the 2.
step below), No Logs is written
On a browser, I write te WCF url and hit ENTER, Log4Net creates the
folder and the files (files are EMPTY at this point).
If I make requests and invoke the methods (doing the 1st step), now
Log4Net writes the logs.
The actual problem:
After the 3rd step, (lets say we waited without any invokes of the
WCF methods around 10 minutes or more), the invoking DOES NOT CREATE
Log4Net Text logs ANYMORE.
Sometimes, if I repeat the 2nd step, it begins writing the logs
again. But there is no coherent results.
Here is the Config.xml:
<?xml version="1.0" encoding="utf-8"?>
<log4net>
<appender name="ProcessInfo_FileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="L:\LOGs\ProcessInfo\ProcessInfo_[%processid].txt" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<maxSizeRollBackups value="200" />
<maximumFileSize value="30MB" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] - %message%newline" />
</layout>
</appender>
<logger name="ProcessInfo">
<levelMin value="ERROR" />
<levelMax value="INFO" />
<appender-ref ref="ProcessInfo_FileAppender" />
</logger>
<root></root>
</log4net>
I have other WCF projects which have no problem even with multiple Workers. (I used the exact same IIS and Log4Net xml configuration with them). Also, as I mentioned on the title, I have a WebSite who has exact same logging codes (they both using a common 3rd party dll which I wrote) and has NO PROBLEM of writing Log4Net text logging at all.
Please help.
Thanks.

The problem is not in your logging configuration, you should try to enable log4net internal debugging. This will tell you why the logging stops. I guess there is some code that reconfigures your logging to load configuration from your web.config which is not there.
<configuration>
...
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
...
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\tmp\log4net.txt" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
Log4net FAQ

Related

Why does this web api need a local web api call to log?

I have two almost identical web api services programmed in C# and installed on the same Windows 2008 Server on IIS 6.1. When I do web api calls to them, they both work just fine. I am using log4net for logging purposes. One of them, however, does not always log. They both have the same exact log4net configuration, which is:
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingLogFileAppender" />
</root>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:\LOGS\SomeFolder\" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<preserveLogFileNameExtension value="true" />
<rollingStyle value="Date" />
<datePattern value="'WebApi.One.'yyyy-MM-dd'.log'" />
<staticLogFileName value="false" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level [%thread][%date{dd-MM-yy HH:mm:ss,fff}] %logger - %message%newline" />
</layout>
</appender>
</log4net>
The only difference in the configuration is the datePattern which has a slightly different name so that they do not log to the same exact file.
For the web api where logging works as expected a new log file is created each day as soon as a web api call comes in. For the web api where logging does not seem to work the new log file is not created. However, if I make a web api call from a browser on the same server as it is installed on, then logging starts. After the logging has started for that day it continues fine (even with web api calls coming from other machines). But the next day no new file is created.
I am unable to see what the difference is. Surely there must be something I am not thinking of that makes these two web apis behave differently when it comes to logging. Remember, both of the services work fine, it is just the logging that is not working for one of them.
Any suggestions?
Edit 1:
After adding diagnostics as suggested by Peter I can see that the access to the path is denied:
log4net:ERROR Could not create Appender [RollingLogFileAppender] of type [log4net.Appender.RollingFileAppender]. Reported error follows.
System.UnauthorizedAccessException: Access to the path 'C__LOGS_WebApi.One_' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.Threading.Mutex.MutexTryCodeHelper.MutexTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.Mutex.CreateMutexWithGuaranteedCleanup(Boolean initiallyOwned, String name, Boolean& createdNew, SECURITY_ATTRIBUTES secAttrs)
at System.Threading.Mutex..ctor(Boolean initiallyOwned, String name, Boolean& createdNew, MutexSecurity mutexSecurity)
at System.Threading.Mutex..ctor(Boolean initiallyOwned, String name)
at log4net.Appender.RollingFileAppender.ActivateOptions()
at log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseAppender(XmlElement appenderElement)
log4net:ERROR Appender named [RollingLogFileAppender] not found.
I don't know why though.
Edit 2:
I checked solutions in these StackOverflow answers:
What am I doing wrong with thie log4net implementation?
log4net: Error on loading custom appender
But still no progress.
This looked very similar, but I could see no solution there (although maybe there is one).
Edit 3:
Folder permissions:
According to the exception message, the process does not have enough rights to write to the location of the log file.
In my experience with dealing with IIS, changing the security permissions on the folder where the log file is stored so that the application/process has the rights to modify the log file(s) usually works.
To confirm/troubleshoot start by giving everyone full control on the folder and testing that the file can be modified.
If that works then you can confirm it is a permission issue.
I usually give IIS_IUSRS the following permission on the Log folder where I store my logs and archive.
Read
Write
Modify
To limit possible attack vectors I try to give the process as few permission as needed to perform its function. Adding and removing permissions and then testing that it still functions as desired.
It looks like a security issue, to debug this you should enable debugging for log4net:
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
And
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\tmp\log4net.txt" />
</listeners>
</trace>
</system.diagnostics>
in your configuration.
This way you are able to see why the creation of the file fails.
log4net faq

Cannot add duplicate collection entry of type 'add' with unique key attribute 'name' set to 'aspNetCore

I have recently published my ASP.NET Core application to my host. I am hitting a HTTP Error 500.19.
IIS 8.5 says the issue is:-
"Cannot add duplicate collection entry of type 'add' with unique key attribute 'name' set to 'aspNetCore'"
It also highlights this key add line in my system.webServer config:-
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule"
</handlers>
I'm not really sure what to do on this. It looks as though there is a duplicate instance of this, so I have tried renaming this but it still asks to add this again?
Here is my web.config:-
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--
Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380
-->
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
</system.webServer>
<system.net>
<defaultProxy useDefaultCredentials="true" >
</defaultProxy>
</system.net>
</configuration>
The answer above didn't work for me, however DavidG's comment did solve my problem, so going to post as an answer in case it helps someone else.
For me, I was not running it as a sub-application, and a project that had been working for me no issue for over a year suddenly stopped working with this issue. Still not sure what changed. When I commented out or removed the <add name="aspNetCore".../> the error persisted, and then that line got automatically re-added.
To solve the problem, I added <remove name="aspNetCore" /> to the config file, right above the <add name="aspNetCore"... /> entry, and things started working again.
To continue running on IIS EXPRESS, go on root folder where the .sln file stays.
go to delete file from .vs\config\applicationhost.config or save
it in a temporary place if you have something there.
Close/Re Open VS Studio, run again, will work.
If you need to add something back from save applicationhost.config, just compare those two, but I don't see what you could have there.
None of the suggested solutions worked for me unfortunately. By some miracle I learned that my applicationhost.config file had been modified in an unfortunate matter, making that "Cannot add duplicate collection entry" error appear when I navigated to a specific page in my .NET Core website application.
Under the <sites> tag in applicationhost.config, I had the following:
<site name="MyWebsite" id="2">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\Users\___\solutionname\MyWebsite" />
</application>
<application path="/SomePage" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\Users\___\solutionname\MyWebsite" />
</application>
<bindings>
<binding protocol="https" bindingInformation="*:12345:localhost" />
</bindings>
</site>
The 500.19 HTTP error was shown to me when I navigated to the page "/SomePage". As you can see, for some reason there was a separate <application> tag for this specific page. I have no idea why.
I removed that entire <application> tag for the "/SomePage" path, and everything started working again.
I faced this issue with vs 2017 on a project that was working fine without changing the web.config. Looking at this posts I realized that it might be an IIS express issue and I solved simply deleting .vs folder and restarting vs.
I had the same problem and in my case commenting the line
<add name="aspNetCore"...
solved the issue and brought up the question "why is it working without AspNetCoreModule".
The problem in my case was that I was adding the site as a sub-application in defaultwebsite and it was located in the wwwrootfolder. I think the config was automatically picked up by the defaultwebsite and applied for all sub-application sites.
This link helped
So the solution was to move it as a separate site on another port.
In my case, the issue was caused by putting a path in the Debug Tab of my web project so that the app would open at a particular page. This causes two silent additions to the file .vs\config\applicationhost.config, similar to the one observed by eightx2.
In :
<add name="api AppPool" managedRuntimeVersion="" />
In :
<application path="/blah" applicationPool="api AppPool">
<virtualDirectory path="/" physicalPath="your-path\src\your-proj" />
</application>
where a similar entry already exists. This is the root of the problem.
The error message, unfortunately, is completely misleading.
Solution is to rename applicationhost.config, restart VS, and let it rebuild the file. This is why Ricardo's solution of deleting the entire .vs folder also works.
That error is because there is a root file in ASP.NET Core that is called ".vs\config\applicationhost.config"
Initially it has 67 keys. You can see it for yourself here, in the Configuration Editor.
This file called ".vs\config\applicationhost.config" has the default settings carried by the Web.config to be able to work, and one of them is that handler.
You can also see it here.
The problem is that that file has that handler and what you publish is going to inherit that handler.
You have two solutions, comment on the line of your published web.config or delete that handler from the ".vs\config\applicationhost.config"
I just had this one, it turns out I had changed the App Url in Debug settings for the website Properties, in order to load a specific page (wrong but happened).
In IIS it automatically created a new application under the test domain called About (in this case).
Removing the rogue IIS application under the domain solves the issue as it doesn't attempt to reload the same web.config when navigating to the page.
I commented the below statement
<verbs allowUnlisted="true">
And its works
If you're running your site in IIS, check if your Application Pool has a "duplicate" Application attached.
I had this same problem debugging my site in IIS. While troubleshooting I found that the Application Pool for my site showed 2 applications connected to it. I checked each of my sites to make sure I hadn't accidentally assigned one of them to the same app pool but they were all correct. So I deleted my site in IIS and checked the app pool which then showed 0 applications. I recreated the site in IIS, attached it to the application pool which then showed only the 1 application. Restarted the site and it worked correctly.
Not sure how that phantom application got attached to my app pool but that's what was causing the duplicate aspNetCore key in my case.
I have a parent web application with multiple child applications.
This is what worked for me:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments="<pathToDll>" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="InProcess" />
</system.webServer>
</location>
</configuration>
Basically, wrap the system.webServer element of the parent website with the location element and set inheritInChildApplications: <location path="." inheritInChildApplications="false">.
Then the child websites can stay the same and you do not need to add <remove name="aspNetCore" /> to each child website's web.config.
Note that this is in the project file:
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="InProcess" />
And it gets changed to this during publish:
<aspNetCore processPath="dotnet" arguments="<pathToDll>" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="InProcess" />

How to ignore Liferay user removed from LDAP errors?

I have a Liferay 6.1 instance that is connected to LDAP. New users get imported nicely, but when I remove a user from the LDAP directory, Liferay starts throwing exceptions when it tries to sync users from LDAP.
These seem to be safe to ignore, but they produce several megabytes of log and it makes log parsing highly annoying. Also I think it might affect performance. If a deleted user logs in, they see nothing.
16:13:54,422 ERROR [liferay/scheduler_dispatch-790][PortalLDAPImporterImpl:995] LDAP user not found with fullUserDN cn=foobar,ou=people,o=foo,dc=bar,dc=baz
javax.naming.NameNotFoundException: [LDAP: error code 32 - No Such Object]; remaining name 'cn=foobar,ou=people,o=foo,dc=bar,dc=baz'
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3057)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2978)
... etc
How could I convince Liferay that this is really OK? Or is there something else I should do?
Until missing users in LDAP are supported by Liferay you can turn off the logging for this particular message. Just create the file ROOT.war/WEB-INF/classes/META-INF/portal-log4j-ext.xml with the following content:
<?xml version="1.0">
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Copy all appenders from
ROOT.war/WEB-INF/lib/portal-impl.jar/META-INF/portal-log4j.xml
and add the following filter: -->
<appender ...>
...
<filter class="org.apache.log4j.filter.StringMatchFilter">
<param name="StringToMatch" value="LDAP user not found with fullUserDN" />
<param name="AcceptOnMatch" value="false" />
</filter>
</appender>
<!-- Keep the root definition from portal-log4j.xml
to trigger the parsing of the appenders: -->
<root>
<priority value="INFO" />
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</log4j:configuration>
You can find more about logging in the Liferay Wiki.

Infinispan Initial State Transfer Hangs and times out

I'm trying to cluster a pair of servers with a shared Infinispan cache (Replicated Asynchronously). One always starts successfully, and registers itself properly with the JDBC database. When the other starts, it registers properly with the database, and I see a bunch of chatter between them, then, while waiting on a response from the second server, I get
`org.infinispan.commons.CacheException: Initial statue transfer timed out`
I think it's just an issue of configuration, but I'm not sure how to debug my configuration issues. I've spent several days configuring and re-configuring my Infinispan XML, and my JGroups.xml:
Infinispan:
<?xml version="1.0" encoding="UTF-8"?>
<infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:infinispan:config:6.0"
xsi:schemaLocation="urn:infinispan:config:6.0 http://www.infinispan.org/schemas/infinispan-config-6.0.xsd
urn:infinispan:config:remote:6.0 http://www.infinispan.org/schemas/infinispan-cachestore-remote-config-6.0.xsd"
xmlns:remote="urn:infinispan:config:remote:6.0"
>
<!-- *************************** -->
<!-- System-wide global settings -->
<!-- *************************** -->
<global>
<shutdown hookBehavior="DEFAULT"/>
<transport clusterName="DSLObjectCache">
<properties>
<property name="configurationFile" value="jgroups.xml"/>
</properties>
</transport>
<globalJmxStatistics enabled="false" cacheManagerName="Complex.com"/>
</global>
<namedCache name="ObjectCache">
<transaction transactionMode="TRANSACTIONAL" />
<locking
useLockStriping="false"
/>
<invocationBatching enabled="true"/>
<clustering mode="replication">
<async asyncMarshalling="true" useReplQueue="true" replQueueInterval="100" replQueueMaxElements="100"/>
<stateTransfer fetchInMemoryState="true" />
</clustering>
<eviction strategy="LIRS" maxEntries="500000"/>
<expiration lifespan="86400000" wakeUpInterval="1000" />
</namedCache>
<default>
<!-- Configure a synchronous replication cache -->
<locking
useLockStriping="false"
/>
<clustering mode="replication">
<async asyncMarshalling="true" useReplQueue="true" replQueueInterval="100" replQueueMaxElements="100"/>
<stateTransfer fetchInMemoryState="true" />
</clustering>
<eviction strategy="LIRS" maxEntries="500000"/>
<expiration lifespan="86400000" wakeUpInterval="1000" />
<persistence>
<cluster remoteCallTimeout="60000" />
</persistence>
</default>
</infinispan>
Jboss.xml:
<config xmlns="urn:org:jgroups"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/JGroups-3.0.xsd">
<!-- Default the external_addr to #DEADBEEF so we can see errors coming through
on the backend -->
<TCP
external_addr="${injected.external.address:222.173.190.239}"
receive_on_all_interfaces="true"
bind_addr="0.0.0.0"
bind_port="${injected.bind.port:12345}"
conn_expire_time="0"
reaper_interval="0"
sock_conn_timeout="20000"
tcp_nodelay="true"
/>
<JDBC_PING
datasource_jndi_name="java:jboss/datasources/dsl/control"
/>
<MERGE2 max_interval="30000" min_interval="10000"/>
<FD_SOCK
external_addr="${injected.external.address:222.173.190.239}"
bind_addr="0.0.0.0"
/>
<FD timeout="10000" max_tries="5"/>
<VERIFY_SUSPECT timeout="1500"
bind_addr="0.0.0.0"
/>
<pbcast.NAKACK use_mcast_xmit="false"
retransmit_timeouts="300,600,1200,2400,4800"
discard_delivered_msgs="true"/>
<UNICAST3 ack_batches_immediately="true"
/>
<RSVP ack_on_delivery="true"
throw_exception_on_timeout="true"
timeout="1000"
/>
<pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
max_bytes="400000"/>
<pbcast.GMS print_local_addr="true" join_timeout="5000"
view_bundling="true" view_ack_collection_timeout="5000"/>
<FRAG2 frag_size="60000"/>
<pbcast.STATE_SOCK
bind_port="54321"
external_addr="${injected.external.address:222.173.190.239}"
bind_addr="0.0.0.0"
/>
<pbcast.FLUSH timeout="1000"/>
</config>
I've tried, frankly, every configuration option I can think of, and I'm not sure why the replication keeps timing out. All communication between these servers is wide open. Sorry to just dump so much XML, but I'm not even sure how to collect more information.
Continued exploration indicated that Infinispan was pushing logs to the server.log, but - due to my configuration, this was not duplicated on the console. Further inspection revealed that I left a single element in my cache objects unserializable - making it impossible for it to be written to the wire and transferred. The logs are very specific, making this actually a very easy problem to track down once I realized where the logs were being written.
If you come here from the future, my advice is to just tail every single log you can on the working server, and see what comes up.

ASP.NET MVC - Castle ActiveRecord - Show SQL queries

I'm using ASP.NET MVC with Castle ActiveRecord as my persistance layer.
I want to know if it's possible to show the SQL queries being executed on my MySQL server.
I know it's possible in a Web application using the "show_sql" property in the Castle XML configuration file, but I don't know how to do it using a Web application, since I don't have access to the Console.
I think I can use log4net to do it, but after some research using Google, I haven't been able to come up with a solution.
In your Application_Start:
XmlConfigurator.Configure(new FileInfo(Server.MapPath("/log4net.config")));
Then you need a log4net.config in your root, something like this:
<?xml version="1.0" encoding="utf-8" ?>
<log4net debug="true">
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender, log4net" >
<param name="File" value="log.txt" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd" />
<maxSizeRollBackups value="7" />
<layout type="log4net.Layout.PatternLayout, log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
</layout>
</appender>
<root>
<priority value="DEBUG" />
<appender-ref ref="LogFileAppender"/>
</root>
</log4net>
Here's a sample app you can use as reference.
Here is a tutorial on how to configure log4net for ASP.NET, it's all the same for MVC:
http://www.codeproject.com/KB/aspnet/Log4Net_Configuration.aspx
And here is how to configure NHibernate to output SQL to log4net
http://www.davesquared.net/2008/01/viewing-sql-generated-by-nhibernate.html