How to force camel case in C# .NET structured logging?

1.1k Views Asked by At

Does anyone know how to change the behavior/format of the structured logging in .NET Core C# to be camel case (ex: camelCase)? I'm trying to leverage structured logging like as follows:

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

Let's say some class looks like as follows:

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

For the sake of brevity, I'll receive some output like follows:

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

But what I want is for all the fields to be camel case like all the parent fields in the log are. The following is the desired outcome:

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

I've tried setting up my JsonConvert.DefaultSettings with a new JsonSerializerSettings object to force camel casing, but I'm assuming this only works if I'm actually serializing to string (got this from StackOverflow question). To which I'm guessing the logger does not use under the hood.

If it helps I'm using I am using .NET Core 2.2 and v4.8.1.

1

There are 1 best solutions below

0
On BEST ANSWER

1) Create your custom serializer with CamelCaseNamingStrategy as NamingStrategy config.

    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) Change default for the new custom

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

Use it, send your Json to NLog log.Info("Metadata: {@source}", metadata);