如何使用 NLog 的完全限定类名作为记录器名称?

发布于 2024-11-25 00:21:30 字数 859 浏览 0 评论 0原文

我有一个通用类:

public class GenericClass<A>
{
    private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

    public void Blah(A a)
    {
        Logger.Info("Test log");
    }
}

与简单的 NLog 配置一起使用:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets>
    <target name="console" xsi:type="ColoredConsole" />
  </targets>

  <rules>
    <logger name="*" minlevel="Trace" writeTo="console" />
  </rules>
</nlog>

我希望我的日志输出看起来像:

...|INFO|NLogTests.GenericClass<System.String>|Test log

相反,我看到的是:

...|INFO|NLogTests.GenericClass`1|Test log

如何让记录器使用完全限定的类型名称而不是基本名称显示通用参数的数量?

I have a generic class:

public class GenericClass<A>
{
    private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

    public void Blah(A a)
    {
        Logger.Info("Test log");
    }
}

Used with a simple NLog configuration:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets>
    <target name="console" xsi:type="ColoredConsole" />
  </targets>

  <rules>
    <logger name="*" minlevel="Trace" writeTo="console" />
  </rules>
</nlog>

I would like my log output to look something like:

...|INFO|NLogTests.GenericClass<System.String>|Test log

Instead, what I see is:

...|INFO|NLogTests.GenericClass`1|Test log

How can I get logger to use the fully qualified type name instead of the basic name which only displays number of generic parameters?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无法回应 2024-12-02 00:21:30

您可以使用以下方法代替 GetCurrentClassLogger:

Logger log = LogManager.GetLogger(GenericToString(typeof(GenericClass<A>)));
…
string GenericToString(Type type) {
  var typeName = type.Namespace + "." + type.Name;
  var args = type.GetGenericArguments();
  if (args.Count() == 0) return typeName;

  typeName = typeName.Remove(typeName.LastIndexOf("`"));
  return typeName 
           + "<" 
           + string.Join(", ", args.Select(a=>GenericToString(a)))
           + ">";
}

GenericToString 放置在您保存随机实用函数/扩展方法的位置。

免责声明:该功能现已被黑客攻击,可能无法正常工作,导致您的计算机着火或导致秃顶。

Instead of GetCurrentClassLogger, you could use:

Logger log = LogManager.GetLogger(GenericToString(typeof(GenericClass<A>)));
…
string GenericToString(Type type) {
  var typeName = type.Namespace + "." + type.Name;
  var args = type.GetGenericArguments();
  if (args.Count() == 0) return typeName;

  typeName = typeName.Remove(typeName.LastIndexOf("`"));
  return typeName 
           + "<" 
           + string.Join(", ", args.Select(a=>GenericToString(a)))
           + ">";
}

Place GenericToString wherever you keep random utility functions / extension methods.

Disclaimer: the function was hacked up right now and might not work, make your computer catch fire, or induce baldness.

度的依靠╰つ 2024-12-02 00:21:30

如果您使用的是 C# 6 & .NET> 4.5,那么你可以做一个巧妙的技巧来使用 CSharpCodeProvider

public static class LogManager<T>
{
    public static Logger GetLogger()
    {
        return LogManager.GetLogger(typeof(T).GetFriendlyName());
    }
}

public static class TypeExtensions
{
    public static string GetFriendlyName(this Type t)
    {
        using (var provider = new CSharpCodeProvider())
        {
            var typeRef = new CodeTypeReference(t);
            return provider.GetTypeOutput(typeRef);
        }
    }
}

然后你可以像这样使用这个扩展:

var logger = LogManager<Dictionary<string, int>>.GetLogger();
logger.Info("logger name contains generic params");

输出将是:

2016-09-23 13:52:14.6342|INFO|System.Collections.Generic.Dictionary<string, int>|logger name contains generic params

If you're using C# 6 & .NET > 4.5, then you can do a neat trick to use CSharpCodeProvider:

public static class LogManager<T>
{
    public static Logger GetLogger()
    {
        return LogManager.GetLogger(typeof(T).GetFriendlyName());
    }
}

public static class TypeExtensions
{
    public static string GetFriendlyName(this Type t)
    {
        using (var provider = new CSharpCodeProvider())
        {
            var typeRef = new CodeTypeReference(t);
            return provider.GetTypeOutput(typeRef);
        }
    }
}

Then you can use this extension like this:

var logger = LogManager<Dictionary<string, int>>.GetLogger();
logger.Info("logger name contains generic params");

And output will be:

2016-09-23 13:52:14.6342|INFO|System.Collections.Generic.Dictionary<string, int>|logger name contains generic params
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文