开发者

How to use fully qualified class name as logger name with NLog?

I have a generic class:

public class GenericClass<开发者_JAVA百科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?


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.


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜