Repository: microsoft/onefuzz
File: src/ApiService/ApiService/onefuzzlib/Metrics.cs (C#)

Code before:
        private readonly ILogTracer _log;
        private readonly IOnefuzzContext _context;
        private readonly JsonSerializerOptions _options;

        public Metrics(ILogTracer log, IOnefuzzContext context) {
            _context = context;
            _log = log;
            _options = new JsonSerializerOptions(EntityConverter.GetJsonSerializerOptions()) {
                DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
            };
            _options.Converters.Add(new RemoveUserInfo());
        }

        public void SendMetric(int metricValue, BaseEvent customDimensions) {
            var metricType = customDimensions.GetEventType();

            _ = _options.PropertyNamingPolicy ?? throw new ArgumentException("Serializer _options not available.");

            var metricTypeSnakeCase = _options.PropertyNamingPolicy.ConvertName($"{metricType}");

            var dimensionString = JsonSerializer.Serialize(customDimensions, customDimensions.GetType(), _options);
            var dimensionDict = JsonSerializer.Deserialize<Dictionary<string, string>>(dimensionString);

            _log.Metric($"{metricTypeSnakeCase}", metricValue, dimensionDict);
            LogMetric(customDimensions);
        }

        public void LogMetric(BaseEvent metric) {
            var serializedMetric = JsonSerializer.Serialize(metric, metric.GetType(), _options);
            _log.Info($"sending metric: {metric.GetEventType():Tag:MetricType} - {serializedMetric}");
        }
    }
}


Review comment (suggestion):
try this instead. It should save you the round trip of serialize deserialize
```C#
var dimensionDict = JsonSerializer.SerializeToNode(customDimensions, customDimensions.GetType(), _options ).AsObject().ToDictionary(kvp => kvp.Key, kvp =>  kvp.Value.ToString());
```

Code after:
        private readonly ILogTracer _log;
        private readonly IOnefuzzContext _context;
        private readonly JsonSerializerOptions _options;

        public Metrics(ILogTracer log, IOnefuzzContext context) {
            _context = context;
            _log = log;
            _options = new JsonSerializerOptions(EntityConverter.GetJsonSerializerOptions()) {
                DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
            };
            _options.Converters.Add(new RemoveUserInfo());
        }

        public void SendMetric(int metricValue, BaseEvent customDimensions) {
            var metricType = customDimensions.GetEventType();

            _ = _options.PropertyNamingPolicy ?? throw new ArgumentException("Serializer _options not available.");

            var metricTypeSnakeCase = _options.PropertyNamingPolicy.ConvertName($"{metricType}");

            var dimensionNode = JsonSerializer.SerializeToNode(customDimensions, customDimensions.GetType(), _options);
            _ = dimensionNode ?? throw new JsonException("Was not able to properly serialize the custom dimensions.");
            var dimensionDict = dimensionNode.AsObject().ToDictionary(kvp => kvp.Key.ToString(), kvp => kvp.Value is not null ? kvp.Value.ToString() : "");

            _log.Metric($"{metricTypeSnakeCase}", metricValue, dimensionDict);
            LogMetric(customDimensions);
        }

        public void LogMetric(BaseEvent metric) {
            var serializedMetric = JsonSerializer.Serialize(metric, metric.GetType(), _options);
            _log.Info($"sending metric: {metric.GetEventType():Tag:MetricType} - {serializedMetric}");
        }
    }
}