log4net getting ? instead of method name randomly - log4net

I have .net 4.5.2 applications where i am using log4net 1.2.15.0 version (even in 2.0.8)
I have random behavior that in method name i am getting ? in my text file
I have tried both %M or %method and this behavior reoccur randomly
My Appender setting is
<appender name="MyApp" type="log4net.Appender.RollingFileAppender" >
<file value="..\\Logs\\MyApp.txt" />
<appendToFile value="true" />
<datePattern value="yyyyMMdd" />
<rollingStyle value="Date" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1MB" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<filter type="log4net.Filter.LevelRangeFilter">
<acceptOnMatch value="true" />
<levelMin value="INFO" />
<levelMax value="FATAL" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d{yyyy-MM-dd HH:mm:ss.fff} %10p [%2t] %5c{1}.%method - %m%n" />
<!-- <conversionPattern value="%d{yyyy-MM-dd HH:mm:ss.fff} %10p [%2t] %5c{1}.%M - %m%n" /> -->
</layout>
</appender>
Sample output text in log file is
2017-08-22 07:13:08.668 INFO [ 4] ServicesManager.? - Socket connectivity Reply from aaa, is True at socket connectivity attempt 1
Please help me in finding what's the problem

This is documented behaviour:
The following patterns %type %file %line %method %location %class %C %F %L %l %M all generate caller location information. Location information uses the System.Diagnostics.StackTrace class to generate a call stack. The caller's information is then extracted from this stack.
StackTrace information will be most informative with Debug build configurations. By default, Debug builds include debug symbols, while Release builds do not. The debug symbols contain most of the file, method name, line number, and column information used in constructing StackFrame and StackTrace objects. StackTrace might not report as many method calls as expected, due to code transformations that occur during optimization.
This means that in a Release build the caller information may be incomplete or may not exist at all! Therefore caller location information cannot be relied upon in a Release build.
The documentation also says:
Generating caller location information is extremely slow. Its use should be avoided unless execution speed is not an issue.

Related

Log4net file rollingFile not deleting old files

I have log4Net set up with the following config settings in a web service web.config file:
<log4net>
<!-- RollingFile is set to be a File Appender -->
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="c:\temp\Sync.log" />
<appendToFile value="true" />
<maximumFileSize value="50MB" />
<maxSizeRollBackups value="10" />
<datePattern value="yyyyMMdd" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level %-50logger - %message%newline%newline" />
</layout>
</appender>
<!-- Set root logger level to DEBUG to have all log -->
<root>
<level value="INFO" />
<appender-ref ref="RollingFile" />
</root>
The issue I am having is when I look in temp I see 17 files
Sync.Log
Sync.log20180424.log
(other sync files with dates)
...
the last one being
Sync.log20180405
I am confused as to why it is not removing the ones beyond 10 days as stated by the maxSizeRollBackups.
I know that by default the is rollingStyle = composite.
With my current config, how would it behave if I let it go?
And as a second - what am I missing in my current settings.
Thanks. I know there are similar questions out there but in reading them I feel like I am still missing something.
It turns out that what I was trying to do is not possible.
As stated in other places:
A maximum number of backup files when rolling on date/time boundaries is not supported.
Because of this, I took the date portion out so that the backups roll by size only. After doing that I did not have the same issues. I don't like the file name as much but it is still easy enough to track them based on their file properties having the date last edited.

How should I configure log4net to write to %LOCALAPPDATA% on Windows XP and 7?

I've got an internal app which is using log4net for logging. I'd like the logs to be generated at %LOCALAPPDATA%\Vendor\App\application.log. Unfortunately, log4net is creating the log file at %APPDATA% instead. It's not a huge problem, because we really don't use roaming profiled here, but I don't like leaving little idiosyncrasies in my code if I can avoid it.
Any thoughts on how to get the file written to the location I specified without configuring log4net programattically and using pinvoke to get the path for XP?
Here's the appender section of my config file if it's any help:
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="${LOCALAPPDATA}\Vendor\App\application.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="100KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger%newline%message%newline" />
</layout>
</appender>
VERY late to the party here but I just came across this and the found the answer.
Seems you can use log4net.Util.PatternString to insert environment variables into the file path. So the OP's example becomes:
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="%env{LOCALAPPDATA}\Vendor\App\application.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="100KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger%newline%message%newline" />
</layout>
</appender>
Add type="log4net.Util.PatternString" to the file element and then specify the %env pattern specifier followed by the environment variable name in curly brackets.
If this isn't working, it would imply your environment variable is wrong.
Log4net does not have anything special in it to handle either appdata or localappdata. All it does is call System.Environment.GetEnvironmentVariables() to return a hashtable and performs substitution based on whatever values that returns.
And for everybody, that had the same problems as me:
doesnt get this to work even when using different cases: (e.g. LocalAppData, LOCALAPPDATA, localappdata)
can not use "util.PatternString" because config is done in code and not the log4net.config file
This can give you local app data or whatever enviroment variable path you want. Use lower case, e.g. "localappdata"!! Returns empty.string when it could not find it.
private static string GetLocalAppDataPath()
{
foreach (DictionaryEntry environmentVariable in Environment.GetEnvironmentVariables())
{
var environmentVariableString = environmentVariable.Key as string;
if (environmentVariableString?.ToLower() == "localappdata")
return (string) environmentVariable.Value;
}
return string.Empty;
}

log4net doesn't watch my app.config

I configured my log4net to watch on changes made to the app.config file.
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
When I run my app and change things in the config file, these changes only take effect when I restart my app. Why could this be?
Is there also a way to tell log4net to watch on changes in the app.config? Like:
<appender name="FileAppender" type="log4net.Appender.FileAppender" >
<watch value="true" />
</appender>
------------- EDIT -------------
I tried now to use a separate config-file: log4net.config.
It looks like this:
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="c:\log.txt" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5p %c (line %L) -- %m%n" />
</layout>
</appender>
<root>
<appender-ref ref="FileAppender" />
</root>
</log4net>
In my assemblyInfo.cs I wrote the following:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
The class that logs to the file looks like this:
ILog myLogger = LogManager.GetLogger(typeof(Form1));
myLogger.Debug("test");
This works like the old version. logfile entries are made, but when I change my log4net.config during runtime, these changes are not applied.... "Watch=true" should enable that feature, right?
HA!, I was just encountering the same problem, running unit tests that require logging.
Adding this line fixed it:
log4net.Config.XmlConfigurator.Configure();
My App.config:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="100KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>
I also do have this:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
According to log4net documentation, the Watch feature does not work for application configuration files (app.config, web.config):
Because the System.Configuration API does not support reloading of the config file
the configuration settings cannot be watched using the
log4net.Config.XmlConfigurator.ConfigureAndWatch methods.
So if you need the log4net configuration to be re-configurable, you will need to place it in a separate XML file and your application needs to have sufficient permissions to read the file:
The file to read the configuration from can be specified using any of the log4net.Config.XmlConfigurator methods that accept a System.IO.FileInfo object. Because the file system can be monitored for file change notifications the ConfigureAndWatch methods can be used to monitor the configuration file for modifications and automatically reconfigure log4net.
Even though I'm terribly late to the party - here's, what helped me: a simple call to log4net.LogManager.GetLogger("DUMMY"); at the very beginning of my program. I put it in the very first line of program.cs's Main() method. No need to assign the logger to any object, merely a polite request to log4net to read the assembly's attributes as stated here.
Using attributes can be a clearer method for defining where the application's configuration will be loaded from. However it is worth noting that attributes are purely passive. They are information only. 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.

Log4Net - Process Lock on Files

We're using Log4Net with a FileAppender to log errors during a process. As the process is finishing, we want to email the log file but we can't do that as it Log4Net still has a lock on the file and we get a message that the file is in use by another process. Any ideas?
We're using a config like this:
<appender name="WarnFileAppender" type="log4net.Appender.FileAppender">
<file value="d:\for-review-log.txt" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %logger - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO" />
<levelMax value="WARN" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
<appendToFile value="false"></appendToFile>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
</appender>
I assume log is from some kind of service, so the log will be locked until service is running.
You probably want to use shared lock while reading the file for sending.
Or you can copy the file and send the copy.
ive got the same problem. Olso a flush doesn't work and when i try to use the SMTPmailAppender that olso doesn't seem to work somehow. but when i use my own created class to send email it works, only he doesn't add the attachment(logfile)

Log4Net section in Web.Config generates Error

So I am trying to set up Log4Net in my Web .NET 4.0 application. I have added the correct .dll to my project and have appended the following to my Web.Config file as starters:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingLogFileAppender" />
</root>
</configSections>
<log4net debug="true">
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:\\TestProj\\TestLog.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5p %d %5rms %-22.22c{1} %-18.18M - %m%n" />
</layout>
</appender>
However, if I append the "log4net" section to Web.Config, I will receive the error message
Unable to start debugging on the web server. See help for common
configuration problems.....
Make sure the server is running correctly. Verify there are no syntax
errors in the web.config........
NOTE
I can remove all the internals of this section and leave only the declaration:
<log4net></log4net>
and I will still get the same error.
Can someone give me some pointers on how to track down this error?
For developers who are not sure exactly how to get started following might be a help
ConfigSections in app.config
Remember to tell your application that a library is introducing a custom configuration section are you are intended to utilize, I am not perfectly sure if it is mandatory or not but I always use it as first section within root <configuration> tag.
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
log4net config in app.config
There are quite a variety of different appenders available in log4net but I usually use RollingFileAppender so I am using the same one in this sample, you can find rest of those here.
<log4net>
<!-- file appender -->
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:/logs/my_log_file.log"/>
<appendToFile value="true"/>
<rollingStyle value="Date"/>
<maxSizeRollBackups value="30"/>
<datePattern value=".yyyy-MM-dd"/>
<staticLogFileName value="true"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
</layout>
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="RollingFileAppender"/>
</root>
</log4net>
Update AssemblyInfo.cs file
I always miss this step whenever I have to create a new project. So remember you have to tell your application to watch for XMLConfigurator to perform configuration of log4net, so following line goes at the end of AssemblyInfo.cs file:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
Get Started
Remember to include the reference of log4net.dll then use following line of code to initialize logger within a class
private static ILog log = LogManager.GetLogger(typeof(MyClass));
And at the end lets use it like following
log.Info("Hello log4net");
Happy Logging :)
Take a look at a sample configurations at log4net documentation homepage.
Chances are you've misplaced required tags.

Resources