NLog具有logger.Fatal(“Message”,T object)等方法。
我脑子里有两个问题 -
除了类型安全记录器之外,这些方法的目的是什么?
我们可以使用此方法根据对象属性在运行时构造动态消息字符串吗?
我们希望在运行时根据对象属性构造一条消息,以便Nlog可以反映该类型。这可能吗?
答案 0 :(得分: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);
在内部,NLog使用string.Format将传入的格式和对象转换为字符串。对于只接受对象而不是格式的通用日志记录签名,内部NLog使用类似"{0}"
的格式,因此NLog中的消息格式化代码不需要知道格式是否格式化字符串是否传入。
NLog最终调用ToString
传递给NLog记录函数的对象,无论是上面第3行中的对象,还是上面第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);
}
}
然后你可以记录这样一个人:
Person p = new Person("Bob", new DateTime(1970, 1, 1));
logger.Info(p);
或者像这样:
Person p = GetPersonFromDatabase("Bob");
logger.Info("Person from database is {0}", p);
在这两种情况下,当最终由NLog评估Person时,会使用ToString方法,因此您将得到类似的内容来表示Person:
Person [Bob] Age [41]
或者,您应该能够创建一个对象,其唯一目的是根据某种计算生成消息:
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);
此外,不要忘记您可以使用各种上下文对象为您的日志消息提供更多上下文:
NLog.GlobalDiagnosticContext["WhenDidMyApplicationStart"] = DateTime.Now;
NLog.ThreadDiagnosticContext["SomeThreadLocalValue"] = 1234;
请注意,上下文字典的类型为Dictionary<string, string>
,因此您无法在字典中存储对象,并希望NLog在对象上调用ToString时需要进行日志记录。如果要将对象存储在上下文字典中,则可以有效地存储对象的快照。
最后,如果您想要做一些专门的事情,那么编写自己的LayoutRenderer对象非常容易。 LayoutRenderer接收LogEventData结构作为输入,因此您可以将输出基于该结构的内容,或者您可以将其基于您知道如何访问的任何其他数据。
有关使用NLog的更多信息,请参阅此问题,包括自定义LayoutRenderer的示例: