Как заставить верблюжий регистр в структурированном ведении журнала C# .NET?

Кто-нибудь знает, как изменить поведение / формат структурированного ведения журнала в.NET Core C# на случай верблюда (например, camelCase)? Я пытаюсь использовать структурированное ведение журнала следующим образом:

Logger.LogInformation("Some text here. My object: {@some_class}", someClass);

Допустим, некоторый класс выглядит так:

class SomeClass {
  [JsonProperty(PropertyName = "intField")] // this does NOT work for structured logging
  int IntField {get;set;}
  string StrField {get;set;}
}

Для краткости я получу следующий результат:

{
  ...
  "message": "Some text here. My object: {\"IntField\":5,\"StrField\":\"I'm here\"}",
  "some_class": {
    "IntField":5,
    "StrField":"I'm here"
  },
  ...
}

Но я хочу, чтобы все поля были верблюжьими, как и все родительские поля в журнале. Вот желаемый результат:

{
  ...
  "message": "Some text here. My object: {\"IntField\":5,\"StrField\":\"I'm here\"}",
  "some_class": {
    "intField":5,
    "strField":"I'm here"
  },
  ...
}

Я попытался настроить свой JsonConvert.DefaultSettings с новым объектом JsonSerializerSettings, чтобы принудительно использовать верблюжий корпус, но я предполагаю, что это работает, только если я действительно сериализую в строку ( получил это из вопроса Stackru). На что я предполагаю, что регистратор не использует под капотом.

Если это поможет, я использую.NET Core 2.2 и v4.8.1.

1 ответ

Решение

1) Создайте собственный сериализатор с помощьюCamelCaseNamingStrategy как конфигурация NamingStrategy.

    internal class JsonNetSerializer : NLog.IJsonConverter
    {
        private readonly DefaultContractResolver contractResolver;

        public JsonNetSerializer()
        {
            contractResolver = new DefaultContractResolver
            {
                // KEY CONFIG !!!
                NamingStrategy = new CamelCaseNamingStrategy()
            };
        }

        /// <summary>Serialization of an object into JSON format.</summary>
        /// <param name="value">The object to serialize to JSON.</param>
        /// <param name="builder">Output destination.</param>
        /// <returns>Serialize succeeded (true/false)</returns>
        public bool SerializeObject(object value, StringBuilder builder)
        {
            try
            {
                string json = JsonConvert.SerializeObject(value, new JsonSerializerSettings
                {
                    ContractResolver = contractResolver
                });

                builder.Append(json);
            }
            catch (Exception e)
            {
                NLog.Common.InternalLogger.Error(e, "Error when custom JSON serialization");
                return false;
            }
            return true;
        }
    }
}

2) Измените значение по умолчанию для нового обычай

var customConverter = new JsonNetSerializer();
ConfigurationItemFactory.Default.JsonConverter = customConverter;

Используйте его, отправьте свой Json в NLog log.Info("Metadata: {@source}", metadata);

Другие вопросы по тегам