如何指定log4net的公共应用程序数据文件夹?

35

我想让log4net将日志文件(使用RollingFileAppender)写入公共应用程序数据文件夹的子文件夹中(例如C:\ Documents and Settings \ All Users \ Application Data \ Company \ Product \ Logs)。
然而,在Win XP上,没有指定此文件夹的环境变量。我们有%ALLUSERSPROFILE%,我们有%APPDATA%,但是没有像%ALLUSERSAPPDATA%这样的东西。
通过编程,我可以使用Environment.SpecialFolder.CommonApplicationData,但我需要将其放入log4net配置中,就像这样:

<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
   <file value="%ALLUSERSAPPDATA%\Company\Product\Logs\error.log" />
</appender>

好的,我们可以在设置中定义这个,但也许有人会想出更好的想法呢?


请纠正问题标题的拼写错误"specifiy" - Jader Dias
根据@codeulike答案中的链接,在1.2.11版本中,您可以简单地使用PatternString表达式,例如%envFolderPath{CommonApplicationData} - Asherah
6个回答

34
我们只是使用这个:
<param name="File" value="${ALLUSERSPROFILE}/Company/Product/Logs/error.log"/>

它运行得非常好。


这行代码可以直接插入到您当前的appender配置中:

<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
   <param name="File" value="${ALLUSERSPROFILE}/Company/Product/Logs/error.log"/>
</appender>

这个解决方案在Win Xp上不起作用,因为${ALLUSERSPROFILE}没有有效的解析。 适用于所有系统(Win Xp及其后续版本)的解决方案在此处的已接受答案中https://dev59.com/0nI_5IYBdhLWcg3wEe1u#1535998。 - user2126375
2
在Windows XP中,ALLUSERSPROFILE存在并默认为C:\ Documents and Settings \ All Users,因此这应该有效,除非您有权限问题。 - pduncan

12

以下是从log4net邮件列表中链接到的pilif分享的完整代码:

基本上,方法是在log4net配置文件中实现自定义模式转换器。

首先将此类添加到您的项目中:

public class SpecialFolderPatternConverter : log4net.Util.PatternConverter
{
    override protected void Convert(System.IO.TextWriter writer, object state)
    {
        Environment.SpecialFolder specialFolder = (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), base.Option, true);
        writer.Write(Environment.GetFolderPath(specialFolder));
    }
}

接着将FileAppender的File参数设置如下:

<file type="log4net.Util.PatternString">
    <converter>
      <name value="folder" />
      <type value="MyAppName.SpecialFolderPatternConverter,MyAppName" />
    </converter>
    <conversionPattern value="%folder{CommonApplicationData}\\SomeOtherFolder\\log.txt" />
</file>

基本上,%folder 告诉它要查找名为 folder 的转换器,该转换器指向 SpecialFolderPatternConverter 类。然后它调用该类上的 Convert 方法,并传入 CommonApplicationData(或其他)枚举值。

显然,在下一个 log4net 版本(1.2.11)中将会有一种更简单的方法,如此处所述。


如何在 <param name="File" 部分(@pduncan提到的部分)中使用此转换器(我也在log4net官方网站上找到了但没有成功)。 - Lei Yang

12

这篇帖子在log4net邮件列表上解释了如何定义自己的路径替换变量。


谢谢,这给了我正确的想法。我将定义一个属性,并在配置文件中使用PatternString来表示文件夹。 - user57474
你可以使用这里接受的答案中的解决方案 https://dev59.com/0nI_5IYBdhLWcg3wEe1u#1535998。该解决方案适用于Win XP和所有后续系统。 - user2126375
1
你能否总结一下链接中的主要思想? - Ryan Gates
仅提供链接的答案一旦链接失效就无法使用。请总结所提供链接资源中的解决方案。 - O. R. Mapper

4
在当前的log4net版本(2.0.8.0)中,您可以简单地使用以下内容:
对于“C:\ ProgramData”,请使用<file value =“$ {ProgramData} \ myFolder \ LogFiles \”/>
对于“C:\ Users \ user \ AppData \ Local \”,请使用$ {LocalAppData} 对于“C:\ Users \ user \ AppData \ Roaming \”,请使用$ {AppData}

3

完整且可用的解决方案 - 我的Log4net.config文件内容。在实际版本的Log4Net中,不再需要编写自己的模式转换器。

<?xml version="1.0"?>
<log4net>
  <root>
    <level value="INFO" />
    <appender-ref ref="LogFileAppender" />
  </root>
  <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender" >
    <file type="log4net.Util.PatternString" value="%envFolderPath{CommonApplicationData}\\MyProject\\Logs\\log.txt" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="100MB" />
    <layout type="log4net.Layout.PatternLayout">
      <ConversionPattern type="log4net.Util.PatternString" value="%%-5p %%d{yyyy-MM-dd HH:mm:ss} - %%m%%n" />
    </layout>
  </appender>
</log4net>

1
尝试过这个,它只是在我的 Web 应用程序下创建了一个带百分号的荒唐文件夹。 - jpierson

1

现在(2018年2月)根据log4net版本2.0.8.0。

您可以按以下方式获取环境变量,无需任何转换器。

<file type="log4net.Util.PatternString" value="%envFolderPath{CommonApplicationData}\\mylogfile.txt" />

请参考log4net.Util.PatternString类的文档以获取更多详细信息。


1
%env{LOCALAPPDATA} 对我有效,而不是 %envFolderPath{LOCALAPPDATA}。 - dxk3355

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接