log4net - 设置XML配置以使用FileAppender的运行时指定路径

时间:2015-07-29 10:40:40

标签: xml log4net

我们正在构建一个Unity游戏客户端,它将在(至少)Windows,OS X和iOS上运行。我使用log4net来处理日志记录,我想使用FileAppender将错误记录到文件中以协助错误报告。我想把这个文件放在UnityEngine.Application.persistentDataPath所指向的目录中,这样无论操作系统如何,该文件都会显示在某个地方,并且我很难找到将其插入到XML配置中的方法。 ; m传递给log4net' XMLConfigurator

我可以设置一个虚拟路径并在运行时更改它,但是(除了笨重)这有一个缺点,当我可以改变FileAppender的设置时,它已经创建了我放入XML配置的任何位置都有一个空的日志文件,这意味着我之后需要清理空文件。

那么,是否可以将FileAppender指向UnityEngine.Application.persistentDataPath的XML配置文件?

2 个答案:

答案 0 :(得分:0)

您可以创建自定义PatternConverter以允许您执行此操作

XMLConfigurator在运行时解析%someString个变量,因此您可以设置自定义PatternConverter以返回UnityEngine.Application.persistentDataPath的值,并设置XML以便配置程序将使用它来解决您的一个变量。

所以,你需要一个这样的课程:

public class PersistentDataStoreConverter : PatternConverter {
    protected override void Convert(TextWriter writer, object state) {
        writer.Write(UnityEngine.Application.persistentDataPath);
    }
}

然后您可以在XML配置中使用该转换器,如下所示:

<appender name="Logfile" type="log4net.Appender.FileAppender">
    <file type="log4net.Util.PatternString">
        <converter>
            <!-- Tell the configurator that this is the converter for "%persistentDataStore" below -->
            <name value="persistentDataStore" />
            <!-- Tell the converter what to call to do the conversion -->
            <type value="Namespace.PersistentDataStoreConverter, AssemblyName" />
        </converter>
        <conversionPattern value="%persistentDataStore/logfile-%date{yyyy-MM-dd-HH-mm-ss}.log" />
    </file>
    <!-- Also specify layout etc... -->
</appender>

答案 1 :(得分:0)

执行此操作的常用方法是设置在配置期间评估的属性:请注意,必须将file属性设置为键入PatternString才能评估变量:

[TestMethod]
public void Set_Log_Path_At_Runtime()
{
    log4net.GlobalContext.Properties["logpath"] =
    Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Test.log");

     // Use stream as is convenient for a unit test, in normal usage
     // would probably want to use the overload that takes a fileinfo.
     using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(config)))
            XmlConfigurator.Configure(ms);

    var appender = log4net.LogManager.GetRepository()
                .GetAppenders()
                .OfType<RollingFileAppender>()
                .First();

    Console.WriteLine(appender.File);
}

private const string config = @"<?xml version=""1.0"" encoding=""utf-8"" ?>

        <log4net debug=""false"">

          <appender name=""RollingFileAppender"" type=""log4net.Appender.RollingFileAppender"">
        <file type=""log4net.Util.PatternString"" value=""%property{logpath}"" />
        <lockingModel type=""log4net.Appender.FileAppender+MinimalLock"" />
        <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>";

由于这是使用the overload of Configure that takes a Stream,将XML加载到变量,将文件位置从占位符更改为实际,并将其作为要配置的流传递一样容易。