How to set credentials on log4net RollingFileAppender to impersonate?
-
30-05-2021 - |
Pregunta
Case
Currently I'm in the process of deploying a WPF-application with log4net logging. In development I had no issues with the RollingFileAppender. However when deployed and started in a Citrix environment, the current user obviously has no permissions to write log files in the application directory.
Questions
- Is it somehow possible to provide credentials to log4net and/or the RollingFileAppender itself to log with a service account?
- If not possible, any ideas for a workaround (except for giving all users permissions on the directory)?
Thanks in advance!
Solución
After two years I encountered the same problem again and found a decent and built-in solution. No need for a custom appender anymore!
This solution comes as a configuration property, which log4net calles securityContext
and is applyable to each appender. See example below.
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO" />
</filter>
<file type="log4net.Util.PatternString" value="LogFiles\%date{yyyyMMdd}\%property{log4net:HostName}_%env{username}" />
<datePattern value=".yyyyMMdd'.log'" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<maxSizeRollBackups value="10" />
<staticLogFileName value="false" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%3thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
<securityContext type="log4net.Util.WindowsSecurityContext">
<domainName value="**myDomain**"/>
<userName value="**myUser**" />
<password value="**mySecretPassword**" />
</securityContext>
</appender>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="ERROR" />
</filter>
<logName value="Application" />
<applicationName value="**MyAppName**" />
<Layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger{1} - %message%newline" />
</Layout>
<securityContext type="log4net.Util.WindowsSecurityContext">
<domainName value="**myDomain**"/>
<userName value="**myUser**" />
<password value="**mySecretPassword**" />
</securityContext>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="RollingFileAppender" />
<appender-ref ref="EventLogAppender" />
</root>
</log4net>
Otros consejos
Im not familiar with Citrix environment, but you can create custom appender, derived from RollingFileAppender:
public class CitrixRollingFileAppender : RollingFileAppender
{
public string Login { get; set; }
public string Password { get; set; }
protected override void Append(LoggingEvent loggingEvent)
{
// use Login and Password here, or authenticate only once when appender created
base.Append(loggingEvent);
}
}
And configuration:
<appender name="citrix" type="YourNamespace.CitrixRollingFileAppender, YourAssembly">
<file value="citrixlog.txt"/>
<appendToFile value="true"/>
<rollingStyle value="Size"/>
<login value="Foo"/>
<password value="Bar"/>
<layout type="log4net.Layout.SimpleLayout"/>
</appender>
UPDATE: You can override such methods like ActivateOptions
or OnClose
to execute some code after appender was configured, or when it about to close.