Open luddskunk opened 1 year ago
Here's my first attempt; MakeCamelCase
deals with runs of leading capitals but could still need a few more test cases to shake out bugs :-)
using System.Diagnostics.CodeAnalysis;
using Serilog.Events;
namespace Sample;
public static class CamelCaseFunctions
{
[return: NotNullIfNotNull("value")]
public static LogEventPropertyValue? ToCamelCase(LogEventPropertyValue? value)
{
return value switch
{
null => null,
DictionaryValue dictionaryValue => new DictionaryValue(dictionaryValue.Elements.Select(kvp => KeyValuePair.Create(kvp.Key, ToCamelCase(kvp.Value)))),
ScalarValue scalarValue => scalarValue,
SequenceValue sequenceValue => new SequenceValue(sequenceValue.Elements.Select(ToCamelCase)),
StructureValue structureValue => new StructureValue(
structureValue.Properties.Select(prop => new LogEventProperty(MakeCamelCase(prop.Name), ToCamelCase(prop.Value))),
structureValue.TypeTag),
_ => throw new ArgumentOutOfRangeException(nameof(value))
};
}
static string MakeCamelCase(string s)
{
if (s.Length == 0) return s;
var firstPreserved = s.Length + 1;
for (var i = 1; i < s.Length; ++i)
{
if (char.IsUpper(s[i])) continue;
firstPreserved = i;
break;
}
return s[..(firstPreserved - 1)].ToLowerInvariant() + (firstPreserved <= s.Length ? s[(firstPreserved - 1)..] : "");
}
}
Enable it with nameResolver: new StaticMemberNameResolver(typeof(CamelCaseFunctions))
and call it by wrapping toCamelCase()
around any object literal in the template:
.WriteTo.Console(new ExpressionTemplate(
"{ toCamelCase({@t: UtcDateTime(@t), @mt, @l: if @l = 'Information' then undefined() else @l, @x, UITest: 42, FUN: 8, IPhone: 13, ..@p}) }\n",
nameResolver: new StaticMemberNameResolver(typeof(CamelCaseFunctions))))
Would love to hear how you go!
Is your feature request related to a problem? Please describe. I'd like to format my JSON with camelcase properties, since I am using a backend for visualization of logs (Grafana Loki) which adheres to that standard. The possibility to do so is also mentioned in https://nblumhardt.com/2021/06/customize-serilog-json-output/
Describe the solution you'd like Use Serilog Expression to create CamelCase keys in JSON body.
Describe alternatives you've considered I tried creating my own custom resolver to do this, but I didn't manage to get it correctly.
I think this also quite quickly became too complex from maintainability standpoint.
What I want to achieve
should be
Additional context As discussed with @nblumhardt on Twitter, I open my thread here.
Hope to get any good insights for finding a smart solution I might've overlooked!