【发布时间】:2020-04-17 22:02:17
【问题描述】:
我有 2 个 NLog 实例,其中一个需要特殊的 ValueFormatter 来序列化参数。 ValueFormatter 使用以下代码设置:
NLog.Config.ConfigurationItemFactory.Default.ValueFormatter = new NLogValueFormatter();
如您所见,它将应用于所有记录器。我在 NLogger 本身上找不到任何可能采用 ValueFormatter 的属性。
有没有办法将此 ValueFormatter 绑定到其中一个记录器?
编辑1:
private CommunicationFormatProvider provider = new CommunicationFormatProvider();
public void LogCommunication(string message, params object[] args)
{
_comLogger.Log(LogLevel.Info, provider, message, args);
}
public class CommunicationFormatProvider : IFormatProvider, ICustomFormatter
{
public string Format(string format, object arg, IFormatProvider formatProvider)
{
StringBuilder strBuilder = new StringBuilder();
strBuilder.Append(format);
var myTarget = LogManager.Configuration.FindTargetByName("communicationTarget");
myTarget = ((myTarget as NLog.Targets.Wrappers.WrapperTargetBase)?.WrappedTarget) ?? myTarget;
var jsonLayout = (myTarget as NLog.Targets.TargetWithLayout)?.Layout as NLog.Layouts.JsonLayout;
if (jsonLayout?.MaxRecursionLimit > 0)
strBuilder.Append(JsonConvert.SerializeObject(arg, new JsonSerializerSettings() { MaxDepth = jsonLayout?.MaxRecursionLimit }));
return strBuilder.ToString();
}
object IFormatProvider.GetFormat(Type formatType)
{
return (formatType == typeof(ICustomFormatter)) ? this : null;
}
}
编辑 2:
public bool FormatValue(object value, string format, CaptureType captureType, IFormatProvider formatProvider, StringBuilder builder)
{
if (value.GetType() == typeof(LogData))
return false;
builder.Append(format);
try
{
var myTarget = LogManager.Configuration.FindTargetByName("communicationTarget");
myTarget = ((myTarget as NLog.Targets.Wrappers.WrapperTargetBase)?.WrappedTarget) ?? myTarget;
var jsonLayout = (myTarget as NLog.Targets.TargetWithLayout)?.Layout as NLog.Layouts.JsonLayout;
if (jsonLayout?.MaxRecursionLimit > 0)
{
var jsonSettings = new JsonSerializerSettings() { MaxDepth = jsonLayout?.MaxRecursionLimit };
using (var stringWriter = new StringWriter())
{
using (var jsonWriter = new JsonTextWriterMaxDepth(stringWriter, jsonSettings))
JsonSerializer.Create(jsonSettings).Serialize(jsonWriter, value);
builder.Append(stringWriter.ToString());
}
}
else
value = null;
}
catch(Exception ex)
{
builder.Append($"Failed to serlize {value.GetType()} : {ex.ToString()}");
}
return true;
}
来自这里的 JSON 序列化器:json.net limit maxdepth when serializing
【问题讨论】:
-
顺便说一句。
JsonSerializerSettings.MaxDepth在这里无效。它仅在“阅读”时使用,而不是在像您在这里所做的“写作”时使用。 (所以不需要在 NLog-config 中进行任何查找)