When building I got some errors & warnings. One of these warnings was:
Could not resolve assembly "System.Web". The assembly is not in the currently targeted framework ".NETFramework,Version=v4.0,Profile=Client". Please remove references to assemblies not in the targeted framework or consider retargeting your project.
I went googling about the different target frameworks and I found a page explaining the this: http://msdn.microsoft.com/en-us/library/cc656912.aspx. Basicly there are some parts "missing" by default if the target is ".NET Framework 4 Client Profile".
OK, fair enough, I changed the target framework to ".NET Framework 4" instead of ".NET Framework 4 Client Profile" on the log4net project.
Finally, I can build my solution! I was dissapointed again when I tried to run it. Now I get the following error in log4net.Core.DefaultRepositorySelector.CreateRepository():
Exception has been thrown by the target of an invocation.
The inner exception was more detailed:
Inheritance security rules violated while overriding member: 'log4net.Util.ReadOnlyPropertiesDictionary.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)'. Security accessibility of the overriding method must match the security accessibility of the method being overriden.
It states that something is wrong with the overriden method GetObjectData() in the ReadOnlyPropertiesDictionary class. ReadOnlyPropertiesDictionary implements ISerializable which makes you have to implement GetObjectData(). When you look at the definition of ISerializable.GetObjectData() you'll see there is an SecurityCritical attribute specified on it. With the inner exception in mind, I added the SecurityCritical attribute to the method GetObjectData() in ReadOnlyPropertiesDictionary. To be honest, the people in this thread pointed me in the good direction: http://stackoverflow.com/questions/2903669/log4net-and-net-framework-4-0.
Having changed that I ran it again. Now other errors arised, however Visual Studio did not break on it, it was written to the VS output window and my console app. One of the errors was the same as above, but then for log4net.Core.LoggingEvent.GetObjectData(). So I added the attribute SecurityCritical there too.
Still no luck with that, because now this error was thrown:
System.MethodAccessException: Attempt by security transparent method 'log4net.Util.SystemInfo.get_CurrentThreadId()' to call native code through method 'System.AppDomain.GetCurrentThreadId()' failed. Methods must be security critical or security safe-critical to call native code.
The property CurrentThreadId of the class log4net.Util.SystemInfo calls System.AppDomain.GetCurrentThreadId(). However, it seems that this is obsolete and need to be changed to System.Threading.Thread.CurrentThread.ManagedThreadId. See http://msdn.microsoft.com/en-us/library/system.appdomain.getcurrentthreadid.aspx.
Changed the property, run it, get an error. Do you have the impression we are in a vicious circle? Don't worry, so do I, but we are getting out of it!
This time the error is:
System.MethodAccessException: Attempt by security transparent method 'log4net.Appender.ColoredConsoleAppender.ActivateOptions()' to call native code through method 'log4net.Appender.ColoredConsoleAppender.GetConsoleOutputCP()' failed. Methods must be security critical or security safe-critical to call native code.
Some security changes were made in the .NET 4.0 framework. In the AssemblyInfo.cs file of the log4net project, you'll find the following line:
[assembly: System.Security.AllowPartiallyTrustedCallers]
This is affected by the security changes. Take a look at this page for more details: http://msdn.microsoft.com/en-us/library/system.security.allowpartiallytrustedcallersattribute.aspx.
I commented that line and now I can succesfully run my application with the logging capabilities of log4net! Isn't that great?
Because the AllowPartiallyTrustedCallers is in comment, the SecurityCritical attributes we added can be removed again.
As a summary, this is what you'll need to do to make log4net run on .NET framework 4:
- Include the source as a project
- Change log4net.Util.SystemInfo.CurrentThreadId to return System.Threading.Thread.CurrentThread.ManagedThreadId instead of System.AppDomain.GetCurrentThreadId().
- Put [assembly: System.Security.AllowPartiallyTrustedCallers] in comment in the AssemblyInfo.cs file.
I made those changes, howether I still had log4net crashing, so I had to remove %thread and %ndc properties from config , and it started to work..
ReplyDeleteI have both of the paremeters in my config, but I cannot reproduce the crash. Which exception do you get exactly?
ReplyDeleteVersion 1.2.10 already uses System.Threading.Thread.CurrentThread.ManagedThreadId, so no need to do first action now.
ReplyDeleteI Added NET_4_0 along with NET_2_0 and did the following:
ReplyDelete-Used #if (!NETCF && !NET_4_0) for [assembly: System.Security.AllowPartiallyTrustedCallers] section.
- In XmlConfigurator: replaced settings.ProhibitDtd = false; with
#if NET_4_0
settings.DtdProcessing = DtdProcessing.Parse;
#else
settings.ProhibitDtd = false;
#endif
@a soldier: I don't think I'm allowed to distribute modified code... sorry!
ReplyDeletea simpliest answer here
ReplyDeletehttp://mocella.blogspot.com/2010/01/using-log4net-with-net-40-wpf.html
Putting
ReplyDelete[assembly:SecurityRules(SecurityRuleSet.Level1)]
solved issue for me
I tried log4net in framework4.0 , i decided to do log files manually creating StreamWriter , finailly i goggled i got this blog , really i feel happy, thanks to Tseo
ReplyDeleteI also thank you for the solution you have provided us with. As the solution is not obvious at all, I have saved a lot of time because of this blog post.
ReplyDeleteGreat! Thanks a lot, you saved my day.
ReplyDeleteYou're all welcome!
ReplyDeleteIt's been a long time since the last post, time to post a new one...
Adding [SecurityCritical] is a better solution.
ReplyDeletesee http://stackoverflow.com/questions/3055792/inheritance-security-rules-violated-while-overriding-member-securityruleset-lev
Brilliant, thank you so much. I used this in conjunction with http://www.codeproject.com/KB/dotnet/Log4NetWithClient.aspx to make a Client Profile friendly log4net assembly which seems to work a treat!
ReplyDeleteHi Tseo,
ReplyDeleteApparently you did a great job for all the guys above. Unfortunately it doesn't work for me... I'm trying to get it to work in .net framework 4.0. I did follow all your steps, even in combination with the instructions from the link in previous comment.
What I notice is that it works well when the layout is set to SimpleLayout, but it fails when I put it to PatternLayout with the following pattern "%date [%thread] %-5level - %message%newline". Also tried it with when I removed "%thread"... I only get blank spaces. My assumption is that Log4Net wants to log but can't do the translation/mapping of the pattern with the exact values.
Any help is more than welcome.
Kind regards,
JDB
Hi JDB749,
ReplyDeleteIn my config file I have the following sections in the log4net section:
<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value="ERROR" />
<foreColor value="Red" />
</mapping>
<mapping>
<level value="DEBUG" />
<foreColor value="Yellow" />
</mapping>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level - %message%newline"/>
</layout>
</appender>
<logger name="MyLogger">
<level value="ALL"></level>
<appender-ref ref="ColoredConsoleAppender"/>
</logger>
As you can see this is a patternlayout with the use of the %thread parameter.
Do you get any kind of exception?
Put the config part here & click the button: http://accessify.com/tools-and-wizards/developer-tools/quick-escape/
ReplyDeleteCopy/paste the result in your comment.
I received a mail saying you responded, but I don't see your comment here. Can you please post it again?
ReplyDeleteHi Tseo,
ReplyDeleteIt is even hard to post something on a blog :)
Anyhow... What I was saying...
It works great when I just use the ColoredConsoleAppender and when I change your tag <logger> with <root>. But no luck with the RollingFileAppender.
My app.config section looks something like below:
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" >
<converter>
<name value="folder" />
<type value="Log4Net.Test.SpecialFolderPatternConverter,Log4Net.Test" />
</converter>
<conversionPattern value="%folder{CommonApplicationData}\\Log\\test.log" />
</file>
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1MB" />
<staticLogFileName value="true" />
<!--<layout type="log4net.Layout.SimpleLayout" />-->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level -> %message%newline" />
</layout>
</appender>
The creation of the file succeeds and when I want to log then I see only blank spaces (noticable when I open the file and do a CTRL+A).
I even stepped through the Log4Net sources but no exception popped up.
Hopefully you could point me in the right direction.
@JDB749: Could you try with a "simple" RollingLogFileAppender?
ReplyDeleteHere is my complete log4net section with a console and a file appender:
<log4net>
<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value="ERROR" />
<foreColor value="Red" />
</mapping>
<mapping>
<level value="DEBUG" />
<foreColor value="Yellow" />
</mapping>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level - %message%newline"/>
</layout>
</appender>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="./Logs/logfile.log"/>
<appendToFile value="false"/>
<rollingStyle value="Date"/>
<datePattern value="yyyyMMdd"/>
<maxSizeRollBackups value="30"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level - %message%newline"/>
</layout>
</appender>
<logger name="MyLogger">
<level value="ALL"></level>
<appender-ref ref="ColoredConsoleAppender"/>
<appender-ref ref="RollingLogFileAppender"/>
</logger>
</log4net>
I hope this will help!
Thanks! It is working now strangely enough... must be a typo somewhere.
ReplyDeleteI can stop banging my head against my desk now.
You got my appreciation!
Kind regards,
JDB