【问题标题】:Why do I get FormatException with NLog?为什么我会使用 NLog 获得 FormatException?
【发布时间】:2020-05-10 14:52:49
【问题描述】:

我在内部 NLog 日志中得到以下信息:

2020-05-10 16:38:09.9251 Warn Error when formatting a message. Exception: System.FormatException: The input string had an incorrect format.
   vid System.Text.StringBuilder.FormatError()
   vid System.Text.StringBuilder.AppendFormatHelper(IFormatProvider provider, String format, ParamsArray args)
   vid System.String.FormatHelper(IFormatProvider provider, String format, ParamsArray args)
   vid System.String.Format(IFormatProvider provider, String format, Object[] args)
   vid NLog.LogEventInfo.CalcFormattedMessage()

如果像这样填写 LogEventInfo :

var logEvent = new LogEventInfo();
                    logEvent.Level = logData.LogLevel.ToLogLevel();
                    logEvent.Message = JsonConvert.SerializeObject(logData, Formatting.Indented);
                    logEvent.Properties.Add("logdata", logData);
                    logEvent.Parameters = new object[1] { logData };
                    _genLogger.Log(logEvent);

当我将 Message 设置为此时,警告似乎来自:

{
  "ComputerName": null,
  "LogLevel": 5,
  "LogId": null,
  "PersonId": null,
  "Text": "Communication Message",
  "TimeStamp": "2020-05-10T16:42:55.9456429+02:00",
  "ExceptionTyp": 7,
  "UserMessage": null,
  "RelatedObjectJsonString": "[\r\n  {\r\n    \"Address\": \"https://192.168.130.29:44476/MyApp5Service/Client\",\r\n    \"IsEmpty\": false,\r\n    \"IsFaulted\": false,\r\n    \"Action\": \"GetUserConfigurations\",\r\n    \"CallDirection\": 0,\r\n    \"EventTime\": \"2020-05-10T16:42:55.9406583+02:00\",\r\n    \"IsCallback\": false\r\n  }\r\n]",
  "SystemInformation": ""
}

我做错了什么?

问候

【问题讨论】:

  • 这里有什么想法?为什么消息,参数和属性中的logdata?我认为它最多应该是一个。

标签: c# nlog formatexception nlog-configuration


【解决方案1】:

消息是字符串格式或结构化格式的消息。这些参数用于格式化消息。

示例

字符串格式

当所有模板持有者都是数字时(在{} 之间),消息被用作字符串格式的消息。

logger.Info("Logon by user:{0} from ip_address:{1}", "Kenny", "127.0.0.1");

第一个参数是 message,其他参数是 parameters

结构化格式:

logger.Info("Logon by {user} from {ip_address}", "Kenny", "127.0.0.1"); // Logon by "Kenny" from "127.0.0.1"

当前问题

所以我们在这里做这样的事情:

string.Format("{
  "ComputerName": null,
  "LogLevel": 5,
  "LogId": null,
  "PersonId": null,
  "Text": "Communication Message",
  "TimeStamp": "2020-05-10T16:42:55.9456429+02:00",
  "ExceptionTyp": 7,
  "UserMessage": null,
  "RelatedObjectJsonString": "[\r\n  {\r\n    \"Address\": \"https://192.168.130.29:44476/MyApp5Service/Client\",\r\n    \"IsEmpty\": false,\r\n    \"IsFaulted\": false,\r\n    \"Action\": \"GetUserConfigurations\",\r\n    \"CallDirection\": 0,\r\n    \"EventTime\": \"2020-05-10T16:42:55.9406583+02:00\",\r\n    \"IsCallback\": false\r\n  }\r\n]",
  "SystemInformation": ""
}", logData);

不要认为那是你需要的;)

解决方案

我不确定您是否需要邮件中的数据。所以列出了这两个选项。

无需自己对数据进行 JSON 转换。这可以在配置中完成。

消息中的数据

我建议在这里使用结构化日志记录。

logger.Log(loglevel, "Message with {LogData}", logData);

您可以在配置中将 logData 呈现为 JSON,如下所示:

${event-properties:item=LogData:jsonEncode=true}

${json-encode}${event-properties}

注意:您可以控制如何呈现消息 (${message}),请参阅 How to use structured logging

消息中没有数据

使用.WithProperty,它是属性的语法糖。

logger.WithProperty("LogData", logData).Log(loglevel, "Message without LogData");

您还可以在此处使用${event-properties:item=LogData:jsonEncode=true} 将对象呈现为 JSON

【讨论】:

  • 谢谢,我有一个自定义 LogToServiceTarget,我从 LogEventInfo 中“解包”我的数据并将其发送到服务器,然后将其记录到数据库中。因此,在这种情况下,我只使用消息作为传输将发送到服务的数据对象的手段。避免这些警告的最佳解决方案是什么?
  • 您不能使用该消息。消息 will 被解析(根据请求),实际上并不是为此而设计的。请为此使用 LogEventInfo 属性,而不是消息。
猜你喜欢
  • 2019-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-09
相关资源
最近更新 更多