Nlog泛型方法

Kvl*_*ive 1 .net c# logging nlog

NLog具有logger.Fatal("Message",T object)等方法.

我脑子里有两个问题 -

除了类型安全记录器之外,这些方法的目的是什么?

我们可以使用此方法在运行时根据对象属性构造动态消息字符串吗?

我们希望在运行时基于对象属性构造消息,以便Nlog可以反映该类型.这可能吗 ?

wag*_*ghe 6

通用日志记录签名允许进行类型安全日志记录.所以,你可以有这样的日志语句(假设logger你的日志记录变量):

int a;
string b;
SomeOtherTypeOfObject c;

logger.Info(a);
logger.Info(b);
logger.Info(c);

logger.Info("a = {0}", a);
logger.Info("b = {0}", b);
logger.Info("c = {0}", c);
Run Code Online (Sandbox Code Playgroud)

在内部,NLog使用string.Format将传入的格式和对象转换为字符串.对于只接受对象而不是格式的通用日志记录签名,内部NLog使用这样的格式"{0}",因此NLog中较长的消息格式化代码不需要知道是否传入了格式字符串或不.

NLog最终调用ToString传递给NLog日志记录函数的对象,无论是上面的前3行中的对象,还是上面的seconde 3行中的格式和对象.

这样做的一个含义是,您可以在类型上实现ToString,以提供您希望用于记录的字符串.

所以,假设你有一个类型如下:

public class Person
{
  public Person(string name, DateTime birthday)
  {
    Name = name;
    Birthday = birthday;
  }

  public string Name { get; set; }
  public DateTime Birthday { get; set; }
  public int AgeInYears { get { return (DateTime.Now.Year - Birthday.Year); } }

  public override string ToString()
  {
    return string.Format("Person [{0}] Age [{1}]", Name, AgeInYears);
  }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样记录一个人:

Person p = new Person("Bob", new DateTime(1970, 1, 1));
logger.Info(p);
Run Code Online (Sandbox Code Playgroud)

或者像这样:

Person p = GetPersonFromDatabase("Bob");
logger.Info("Person from database is {0}", p);
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,当最终由NLog评估Person时,使用ToString方法,因此您将得到类似的东西来表示Person:

Person [Bob] Age [41]
Run Code Online (Sandbox Code Playgroud)

或者,您应该能够根据某种计算制作一个对象,其唯一目的是生成一条消息:

public class MyLoggingParameters
{
  public string override ToString()
  {
    var x = GetSomeInformationFromSomewhere();

    return string.Format("MyLoggingParameters: [{0}], [{1}], [{2}]", x.Foo, x.Bar, x.Baz);
  }
}

var x = new MyLoggingParameters();

logger.Info(x);
Run Code Online (Sandbox Code Playgroud)

此外,不要忘记您可以使用各种上下文对象为您的日志消息提供更多上下文:

NLog.GlobalDiagnosticContext["WhenDidMyApplicationStart"] = DateTime.Now;
NLog.ThreadDiagnosticContext["SomeThreadLocalValue"] = 1234;
Run Code Online (Sandbox Code Playgroud)

请注意,上下文字典属于类型Dictionary<string, string>,因此您无法在字典中存储对象,并希望NLog在对象上调用ToString时需要进行日志记录.如果要将对象存储在上下文字典中,则可以有效地存储对象的快照.

最后,如果您想要做一些专门的事情,那么编写自己的LayoutRenderer对象非常容易.LayoutRenderer接收LogEventData结构作为输入,因此您可以将输出基于该结构的内容,或者您​​可以将其基于您知道如何访问的任何其他数据.

有关使用NLog的更多信息,请参阅此问题,包括自定义LayoutRenderer的示例:

最有用的NLog配置