Log4net RollingFileAppender not writing when application runs as a service - log4net

I have an C# application that can run on Windows 10 either as a console app or as a service, depending on a configuration parameter. I am writing log messages using a log4net RollingFileAppender. I'm using log4net version 4.5. When the application runs as a console app, the rolling file gets written as expected. When it is run as a service the file does not get written. What can I do to get my log file?
Here's the configuration file:
<?xml version="1.0" encoding="utf-8"?>
<log4net>
<appender name="TimedFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="c:/misc/HotspotControlService.log" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd.lo\g" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date - %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="TimedFileAppender" />
</root>
</log4net>

As usual, my own idiocy is the problem. I specified the configuration file in my program by the bare file name, with no folder given. The file exists in the same folder as my executable file. But when running as a service, the working folder is not the folder in which the executable folder lives. I used an absolute path for the configuration file name, and it worked.

Related

SQL Jobs or Task Scheduler call log4net, does not write log file

I write a console application with log4net, my log4net config below
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender" >
<file value="Process_Log\" />
<appendToFile value="true" />
<datePattern value="yyyy-MM-dd.TXT" />
<maxSizeRollBackups value="10" />
<rollingStyle value="Date" />
<maximumFileSize value="10MB" />
<staticLogFileName value="false" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %p %message [%logger] %n" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="RollingLogFileAppender" />
</root>
</log4net>
Run the console application, It has output log files.
But use SQL Server Agent Jobs or Windows Task Scheduler call it,
It didn't write log file.
I figured out the problem. When you run the solution from Visual Studio, log4net finds out the configuration file from the "bin" folder. So, it gets required information to run. But when you run the application by Windows Task Scheduler, the situation is different. This time, the Windows Task Scheduler tries to find out the Configuration file from this location "C:\Windows\System32". Because, when you run Windows Task Scheduler, it treats the default application folder location "C:\Windows\System32".
You can write following codes to navigate the application to load the log4net configuration file. Here, the config file name is "LogConfiguration.config".
var log4NetConfigDirectory =
AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
var log4NetConfigFilePath = Path.Combine(log4NetConfigDirectory, "LogConfiguration.config");
log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(log4NetConfigFilePath));
The accepted answer by user3626918 is correct about the problem (wrong working directory). As an alternative to the proposed code change solution you can instead:
Configure the "Start in" directory of your scheduled task (Properties->Actions->Edit...)
Confirm that the account running the scheduled task has permissions to write to the log file destination.

Create multiple logfiles during application run using log4net

I'm using log4net in a c# windows service, so the main application runs every time. I configured log4net to log into a date specific directory. Inside this directory log4net creates a logfile with a timestamp in the filename. This works fine. The probem is, that it only creates a new logfile, when the windows service restarts. This causes the logfile to get very big, expecially if the service runs over several days.
The question is:
Is there a possibility to force log4net to start with a new logfile throughout my code.
This is my log4net config:
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file type="log4net.Util.PatternString" value="${ProgramData}\Sirona\Log\AcqSrv\%date{yyMMdd}\AcqSrvAll-%date{HHmmss}.log" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%2thread] [%-5level] [%logger] - %message%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="FileAppender" />
</root> <!-- Do not want NHibernate log -->
</log4net>
Best regards
Emu
I think your problem is solved by the RollingFileAppender: http://logging.apache.org/log4net/release/config-examples.html
http://logging.apache.org/log4net/release/sdk/log4net.Appender.RollingFileAppender.html
It works exactly as a FileAppender but once it reach a maximum size (configurable) it creates another log file.
You can also instruct it to keep only the latest X log files.
Hope it helps.

Log4Net - Output not showing up at file

I have an Log4Net configuration that produces output as expected in a console application.
I have the exact same config, and invokation code (all done at the earliest point possible in the execution flow), but in the context of NUnit tests.
I know the configuration is loaded correctly. Additionally, I have turned the system diagnostics for Log4Net, and the debug prints are the exact same in both cases.
In the console application the text gets written. Otherwise, the file is empty.
The configuration code:
<log4net>
<!--APPENDERS-->
<!--Endpoint File Appender-->
<appender name="EndpointFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:\Temp\Endpoint.log" />
<appendToFile value="true" />
<maximumFileSize value="100KB" />
<maxSizeRollBackups value="10" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</appender>
<!--LOGGERS-->
<logger name="EndpointLog">
<level value="ALL" />
<appender-ref ref="EndpointFileAppender" />
</logger>
The Invocation code (first thing at application boot):
log4net.Config.XmlConfigurator.Configure();
ILog log = LogManager.GetLogger("EndpointLog");
log.Info("Hello World.");
Any ideas? Thanks
Is it that you need a root section? Try adding this:
<root>
<level value="All" />
<appender-ref ref="EndpointFileAppender" />
</root>
When you are running in an unittest context, you need to copy the log4net config into the bin folder with your unittest dlls. You can do this by setting copy tot output folder on the log4net config.

log4net not logging from Autocad Plugin on deployment

I am developing an AutoCAD 2012 plugin using .net API"s of autocad. The Autocad plugin's are dll which are loaded into the Autocad runtime when the Autocad is started. I have been able to successfully log from log4net using Visual Studio developement environment. However, when I run the plugin outside of Visual Studio, that is when I deploy my plugin, the log4net does not log any messages or even create a log file. Here is the logging related code and the configuration file.
log4net_autocad.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false"/>
</configSections>
<log4net>
<appender name="AutocadRollingFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="${NIRVANA_SOFTWARE_INSTALL_PATH}Relay_Manager_Autocad.log"/>
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="0" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p [%C.%M] %m%n"/>
</layout>
</appender>
<logger name="AutocadFile">
<level value="All"/>
<appender-ref ref="AutocadRollingFileAppender"/>
</logger>
</log4net>
</configuration>
myPlugin.cs: Code to congifure logging
public class MyPlugin : IExtensionApplication {
private static log4net.ILog log;
void IExtensionApplication.Initialize() {
...
log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo("log4net_autocad.config"));
log = log4net.LogManager.GetLogger("AutocadFile");
}
void IExtensionApplication.Initialize() will execute when the Autocad is started. Couple of things that I have checked:
Checked that the Autocad Plugin is properly loaded in Autocad, which
means that log4net initialization code has run.
Checked that log4net config file (log4net_autocad.config) is copied
in the bin directory of the deployed application
The strange thing is that when I load the plugin in developement environment(VS 2010), the plugin logs properly. So why is the log4net not logging (or even creating a log file) in deployment.
EDIT:
I checked some additional stuff
In the plugin just before I log, I checked following through alert dialogs.
The log.Logger.Name properly returns the name of the logger that I am using.
log.Logger.IsEnabledFor(log4net.Core.Level.All) returns false, even though I have configured Level Value=All in the config file.
EDIT-2
I tried to define config file as explained in the referring url of the answer. I am quoting the approach as outlined in the document.
2.] Application Configuration File: [AppName].exe.config, [AppName].dll.config
The application-level configuration, [AppName].exe.config or [AppName].dll.config, is where
most of this document will spend its time. This configuration file will contain all applicationlevel settings and can even be used to define the use of and default values for settings
associated with the Roaming-User and Local-User configuration files. These files are
typically stored in the same directory as the application executable, but can be placed
elsewhere if necessary. There will be much more discussion on this to come.
The above approach suits my application, but I still can't get the logger to log anything at all.I defined a log4net config file with name RelayAnalysis_Autocad.dll.config and supplied it to the log4net for configuration. I think there is something else to it that I am not able to understand. I have started doubting whether we can log using log4net from autocad plugin?
I also removed the environment path and hardcoded it so as to eliminate any issues regarding the reading of environment variable. Still no luck.
On deploy, you should store the plugin configuration in one of the default config files:
User.config
acad.exe.config
machine.config
Probably, the User.config is the best file to carefully change during setup. Moreover you should design and code the changes so that they can be reverted on uninstall.
Doublecheck that you have properly replaced the ${NIRVANA_SOFTWARE_INSTALL_PATH} during setup and that the folder has proper permissions.
Furthermore, I would try to either add to the AssemblyInfo.cs the following line
[assembly: log4net.Config.XmlConfigurator(ConfigFile="AbsolutePathToTheConfig")]
(in which case you shouldn't call XmlConfigurator.Configure) or use an absolute path in the call to
log4net.Config.XmlConfigurator.Configure(new FileInfo("AbsolutePathToTheConfig"));
Finally, note that the log4net documentation about XmlConfigurator.Configure states that the configuration file used can be a XML not matching the .NET config rules.
The configuration file must be valid XML. It must contain at least one element called log4net that holds the log4net configuration data.
Thus, in the log4net_autocad.config file you can skip the <configuration> element:
<log4net>
<appender name="AutocadRollingFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="Absolute\Path\To\Relay_Manager_Autocad.log"/>
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="0" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p [%C.%M] %m%n"/>
</layout>
</appender>
<logger name="AutocadFile">
<level value="All"/>
<appender-ref ref="AutocadRollingFileAppender"/>
</logger>
</log4net>

log4net does not log when my web app is packaged deployed

I have a web app that uses log4net to log errors to a log file.
It works well when I publish my website via xcopy but when I build a package installer, log4net does not appear to work when remote users access my site.
I use impersonate=true in my web.config and log4net only logs errors when I am the logged user.
I have another app that works fine in all cases but was not package deployed.
Does anyone have any thoughts?
After all it was a permission issue
setting the write permission to everyone log4net started logging well as it uses the
current logged user account
regards
i don't think so because same config is used in a working app
but here it is
what user does log4net uses when writing to disk?!
Is there any need to add permissions to write to log folders? Because i use impersonate=true the user logged to the site is the one that log4net is using to write
to file system right?!
<!-- log4net -->
<log4net debug="false">
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="D:\\WSBank\\Solution\\Logs\\Solution.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1024KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>

Resources