How should I configure log4net to write to %LOCALA

2020-08-27 06:50发布

问题:

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>

回答1:

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.



回答2:

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.



回答3:

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;
}