.net Log4Net可以';当我在appender中命名文件时,找不到%username属性

.net Log4Net可以';当我在appender中命名文件时,找不到%username属性,.net,log4net,.net,Log4net,log4net没有对我的登录名进行正确的PatternString替换。我希望我的日志是 Logs\YYYYMMDD\MSMQcore\uuu[username]。日志 当我使用%username属性时,我会在路径中获取域,从而在路径中添加另一个间接文件夹。我只想要用户名 Logs\yyyyymmdd\MSMQcore\uu[domain]\[username]。日志 有没有人举过在附加者的文件名中插入“用户名”的例子?我已经试过很多东西了,我还在挠头 <appender name="co

log4net没有对我的登录名进行正确的
PatternString
替换。我希望我的日志是

Logs\YYYYMMDD\MSMQcore\uuu[username]。日志

当我使用
%username
属性时,我会在路径中获取域,从而在路径中添加另一个间接文件夹。我只想要用户名

Logs\yyyyymmdd\MSMQcore\uu[domain]\[username]。日志

有没有人举过在附加者的文件名中插入“用户名”的例子?我已经试过很多东西了,我还在挠头

<appender name="core_Appender" type="log4net.Appender.RollingFileAppender" >
<!-- <file type="log4net.Util.PatternString"  value="Logs/%date{yyyyMMdd}/MSMQcore_%identity.log" /> -->
<!-- <file type="log4net.Util.PatternString"  value="Logs/%date{yyyyMMdd}/MSMQcore_%property{user}.log" /> -->
<file type="log4net.Util.PatternString"  value="Logs/%date{yyyyMMdd}/MSMQcore_%username.log" />
</appender>

使用环境变量模式对我有效:

<file type="log4net.Util.PatternString" value="Logs\\%env{USERNAME}.txt" />
新设置将如下所示:

<file type="MyPatternString" value="Logs\\%usernameonly.txt" />


更新2:要回答%identity和%property{user}不起作用的原因:

%标识模式在当前线程上拾取标识属性。此属性在我的测试中为null,并且在为正在运行的线程分配特定的Windows标识之前可能为null。这在appender的上下文中不起作用,因为您不知道哪个线程将执行实际的追加

%属性模式从GlobalContext和ThreadContext类中提取属性。默认情况下,只有log4net:HostName(LoggingEvent.HostNameProperty)在GlobalContext中注册。因此,除非您在这些上下文中主动注册属性,否则无法将它们与%property模式一起使用。同样,ThreadContext在appender的上下文中是无用的,因为您无法知道哪个线程将进行追加

这就是说,在GlobalContext.Properties集合中注册一个名为username的属性,也许在应用程序启动例程的某个地方,将使%property{username}按预期工作。

Peter的回答几乎对我有效;这无疑让我走上了正确的道路,因为我需要一个类似的解决方案。我必须做的是子类
PatternConverter

public class ConfigurationSettingsConverter : PatternConverter
{
    protected override void Convert(TextWriter writer, object state)
    {
        // use Option as a key to get a configuration value...
        if (Option != null)
            writer.Write(ConfigUtils.Setting[Option]);
    }
}
并将此转换器添加到
模式字符串的子类的
激活选项
覆盖中:

public class ConfigurationSettingsPatternString : PatternString
{
    public ConfigurationSettingsPatternString()
    {}

    public ConfigurationSettingsPatternString(string pattern): base(pattern)
    {}

    public override void ActivateOptions()
    {
        AddConverter("cs", typeof(ConfigurationSettingsConverter));
        base.ActivateOptions();
    }
}
正如Peter回答的那样,我最初尝试在构造函数中执行此操作,但是模式字符串的底层调用没有返回转换器来解析源字符串。在配置log4net之前,我还必须在代码路径的任何位置注册一个类型转换器(不要与
模式转换器混淆):

ConverterRegistry.AddConverter(
    // type we want to convert to (from string)...
    typeof(ConfigurationSettingsPatternString),
    // the type of the type converter that will do the conversion...
    typeof(ConfigurationSettingsPatternStringConverter));
不这样做会阻止log4net
FileAppender
文件节点(即字符串)中的属性转换为
配置设置spatterString
。例如,在这个配置片段中

<file
  type="Some.Name.Space.ConfigurationSettingsPatternString, Some.Assembly"
  value="some\path\MyLog.%cs{SomeKey}.log" />
这对于托管在同一可执行文件中的Windows多个服务来说非常有效(例如,您可以添加一个%serviceName模式作为文件名来分隔服务的日志。

使用“%username”对我来说很有效

<parameter>
    <parameterName value="@identity" />
    <dbType value="String" />
    <size value="255" />
    <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%username" />
    </layout>
</parameter>


但是,我还是在一个标准WinForms应用程序的环境中,而不是ASP.NET应用程序。不确定这是否是您想要的。

对工具包的解决方案只有一个改进: 使用属性

[TypeConverter("namespace.ConfigurationSettingsPatternStringConverter")]
public class ConfigurationSettingsPatternString : PatternString
{
以及对

ConverterRegistry.AddConverter(
// type we want to convert to (from string)...
typeof(ConfigurationSettingsPatternString),
// the type of the type converter that will do the conversion...
typeof(ConfigurationSettingsPatternStringConverter));
不再需要。


<layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="Running on ${COMPUTERNAME} / ${USERNAME} %newline %logger %date%newline Thread ID=[%thread]%newline %-5level - %message%newline" />
</layout>

这对我来说效果很好。

Peter,谢谢……这对我来说也很好。幸运的是设置了环境变量。我仍然不确定其他版本为什么不起作用。也许PatternString只在一次过程中解析字符串??tvm,CraigThanks。这太棒了。Craig,我认为在代码中过早调用AddConverter可能是错误的问题的答案。请参阅下面我的答案,了解对我有用的内容。@Peter,
ThreadContext
是在日志语句生成时设置的,而不是在附加消息时设置的。因此,调用
Log.Info(“废话废话废话”)的是线程
@Anthony,是的,这是正确的。我的观点是,在appender生成文件名时,没有ThreadContext,因为它不一定作为日志语句的一部分来完成。您可以通过Log4Net版本1.2.11中的appender模式来获得它。请参阅stackoverflow.com/a/26277219/203371
ConverterRegistry.AddConverter(
// type we want to convert to (from string)...
typeof(ConfigurationSettingsPatternString),
// the type of the type converter that will do the conversion...
typeof(ConfigurationSettingsPatternStringConverter));
<layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="Running on ${COMPUTERNAME} / ${USERNAME} %newline %logger %date%newline Thread ID=[%thread]%newline %-5level - %message%newline" />
</layout>