2011-07-18 16 views
3

私はジェネリッククラスを持っている:NLogでロガー名として完全修飾クラス名を使用するにはどうすればよいですか?

シンプルNLog構成で使用さ
public class GenericClass<A> 
{ 
    private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); 

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

<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 

ロガーに、汎用パラメータの数だけを表示する基本名の代わりに完全修飾タイプ名を使用させるにはどうすればよいですか?代わりにGetCurrentClassLoggerの

答えて

3

、あなたが使用できます。

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あなたはランダムなユーティリティ機能/拡張メソッドを保存しているところ。

免責事項:この機能は現在ハッキングされており、機能しない可能性があります。コンピュータが火をつけたり、脱毛を引き起こしたりする可能性があります。

+0

はい私はもちろん行うことができますが、私は思い出す必要はありませんでしたそのメソッドを毎回呼び出す(そして、共通のutilsアセンブリに余分な依存関係がある)。もっと良いアプローチは、現在の出力がそれほど有用ではないとNLogがそれをした場合です。私はそこに余分な反射が少し必要であるかもしれないが、少なくともそれをオンにするオプションを持っているといいだろうと思っている。 – emertechie

+0

@Andrew:これを内蔵しているのはいいかもしれないが、 NLogの開発者に依頼してください。その間に、スタックトレースのスニッフィング(またはソースからのコピー貼り付け)を複製し、LogManagerで拡張メソッドを作成することができます。 – millimoose

+0

@AndrewSmithおそらくジェネリックスを取る拡張メソッドを書くことができ、GetLoggerと呼ぶこともできます。内部にInerdialのメソッドを使用して名前を作成します。あなたは何も覚えていない彼の方法:] – stijn

1

あなたが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 
関連する問題