public async Task Can_format_payload_with_multiple_fields_correctly() { // Arrange await using var ms = new MemoryStream(); await using var jsonWriter = new Utf8JsonWriter(ms); var fields = new Dictionary <string, object> { { "field1key", "field1value" }, { "field2key", 2 }, { "field3key", false } }; var timestamp = new DateTime(2017, 1, 1, 1, 1, 1, DateTimeKind.Utc); var point = new HostedMetricsPoint(null, "measurement", fields, MetricTags.Empty, new DefaultHostedMetricsPointTextWriter(), FlushInterval, timestamp); // Act jsonWriter.WriteStartArray(); point.Write(jsonWriter); jsonWriter.WriteEndArray(); await jsonWriter.FlushAsync(); var result = Encoding.UTF8.GetString(ms.ToArray()); // Assert result.Should().Be("[{\"name\":\"measurement.field1key\",\"metric\":\"measurement.field1key\",\"value\":0,\"interval\":10,\"mtype\":\"gauge\",\"unit\":\"\",\"time\":1483232461,\"tags\":[]},{\"name\":\"measurement.field2key\",\"metric\":\"measurement.field2key\",\"value\":2,\"interval\":10,\"mtype\":\"gauge\",\"unit\":\"\",\"time\":1483232461,\"tags\":[]},{\"name\":\"measurement.field3key\",\"metric\":\"measurement.field3key\",\"value\":0,\"interval\":10,\"mtype\":\"gauge\",\"unit\":\"\",\"time\":1483232461,\"tags\":[]}]"); }
public void At_least_one_field_is_required() { // Arrange var fields = new Dictionary <string, object>(); Action action = () => { // Act var point = new HostedMetricsPoint(null, "measurement", fields, MetricTags.Empty, new DefaultHostedMetricsPointTextWriter(), FlushInterval); }; // Assert action.Should().Throw <ArgumentException>(); }
public void Field_key_cannot_be_empty() { // Arrange var fields = new Dictionary <string, object> { { string.Empty, "value" } }; Action action = () => { // Act var point = new HostedMetricsPoint(null, "measurement", fields, MetricTags.Empty, new DefaultHostedMetricsPointTextWriter(), FlushInterval); }; // Assert action.Should().Throw <ArgumentException>(); }
public void Measurement_is_required() { // Arrange var fields = new Dictionary <string, object> { { "key", "value" } }; Action action = () => { // Act var point = new HostedMetricsPoint(null, string.Empty, fields, MetricTags.Empty, new DefaultHostedMetricsPointTextWriter()); }; // Assert action.Should().Throw <ArgumentException>(); }
public void Can_format_payload_correctly() { // Arrange var sb = new StringBuilder(); var textWriter = new JsonTextWriter(new StringWriter(sb)); var fields = new Dictionary <string, object> { { "key", "value" } }; var timestamp = new DateTime(2017, 1, 1, 1, 1, 1, DateTimeKind.Utc); var point = new HostedMetricsPoint(null, "measurement", fields, MetricTags.Empty, new DefaultHostedMetricsPointTextWriter(), FlushInterval, timestamp); // Act point.Write(textWriter); var result = sb.ToString(); // Assert result.Should().Be("{\"name\":\"measurement.key\",\"metric\":\"measurement.key\",\"value\":0.0,\"interval\":10,\"mtype\":\"gauge\",\"unit\":\"\",\"time\":1483232461,\"tags\":[]}"); }
public void Should_add_context_when_provided() { // Arrange var sb = new StringBuilder(); var textWriter = new JsonTextWriter(new StringWriter(sb)); var fields = new Dictionary <string, object> { { "key", "value" } }; var tags = new MetricTags("tagkey", "tagvalue"); var timestamp = new DateTime(2017, 1, 1, 1, 1, 1, DateTimeKind.Utc); var point = new HostedMetricsPoint("context", "measurement", fields, tags, new DefaultHostedMetricsPointTextWriter(), FlushInterval, timestamp); // Act point.Write(textWriter); var result = sb.ToString(); // Assert result.Should().Be("{\"name\":\"context.measurement.tagkey.tagvalue.key\",\"metric\":\"context.measurement.tagkey.tagvalue.key\",\"value\":0.0,\"interval\":10,\"mtype\":\"gauge\",\"unit\":\"\",\"time\":1483232461,\"tags\":[]}", "Hosted Metrics request at the moment allow tags array but its not yet used."); }
public void Can_format_payload_with_tags_correctly() { // Arrange var sb = new StringBuilder(); var textWriter = new JsonTextWriter(new StringWriter(sb)); var fields = new Dictionary <string, object> { { "key", "value" } }; var tags = new MetricTags("tagkey", "tagvalue"); var timestamp = new DateTime(2017, 1, 1, 1, 1, 1, DateTimeKind.Utc); var point = new HostedMetricsPoint(null, "measurement", fields, tags, new DefaultHostedMetricsPointTextWriter(), timestamp); // Act point.Write(textWriter); var result = sb.ToString(); // Assert result.Should() .Be("[{\"name\":\"measurement.tagkey.tagvalue.key\",\"metric\":\"measurement.tagkey.tagvalue.key\",\"value\":\"value\",\"interval\":1,\"unit\":\"\",\"time\":\"1483232461\",\"tags\":[]}]", "Hosted Metrics request at the moment allow tags array but its not yet used."); }
public void Can_format_payload_with_multiple_fields_correctly() { // Arrange var sb = new StringBuilder(); var textWriter = new JsonTextWriter(new StringWriter(sb)); var fields = new Dictionary <string, object> { { "field1key", "field1value" }, { "field2key", 2 }, { "field3key", false } }; var timestamp = new DateTime(2017, 1, 1, 1, 1, 1, DateTimeKind.Utc); var point = new HostedMetricsPoint(null, "measurement", fields, MetricTags.Empty, new DefaultHostedMetricsPointTextWriter(), timestamp); // Act point.Write(textWriter); var result = sb.ToString(); // Assert result.Should().Be("[{\"name\":\"measurement.field1key\",\"metric\":\"measurement.field1key\",\"value\":\"field1value\",\"interval\":1,\"unit\":\"\",\"time\":\"1483232461\",\"tags\":[]},{\"name\":\"measurement.field2key\",\"metric\":\"measurement.field2key\",\"value\":\"2\",\"interval\":1,\"unit\":\"\",\"time\":\"1483232461\",\"tags\":[]},{\"name\":\"measurement.field3key\",\"metric\":\"measurement.field3key\",\"value\":\"f\",\"interval\":1,\"unit\":\"\",\"time\":\"1483232461\",\"tags\":[]}]"); }
public async Task Should_add_context_when_provided() { // Arrange await using var ms = new MemoryStream(); await using var jsonWriter = new Utf8JsonWriter(ms); var fields = new Dictionary <string, object> { { "key", "value" } }; var tags = new MetricTags("tagkey", "tagvalue"); var timestamp = new DateTime(2017, 1, 1, 1, 1, 1, DateTimeKind.Utc); var point = new HostedMetricsPoint("context", "measurement", fields, tags, new DefaultHostedMetricsPointTextWriter(), FlushInterval, timestamp); // Act point.Write(jsonWriter); await jsonWriter.FlushAsync(); var result = Encoding.UTF8.GetString(ms.ToArray()); // Assert result.Should().Be("{\"name\":\"context.measurement.tagkey.tagvalue.key\",\"metric\":\"context.measurement.tagkey.tagvalue.key\",\"value\":0,\"interval\":10,\"mtype\":\"gauge\",\"unit\":\"\",\"time\":1483232461,\"tags\":[]}", "Hosted Metrics request at the moment allow tags array but its not yet used."); }
public void Time_stamp_should_be_utc(DateTimeKind dateTimeKind, bool expected) { // Arrange var fields = new Dictionary <string, object> { { "key", "value" } }; var timestamp = new DateTime(2017, 1, 1, 1, 1, 1, dateTimeKind); Action action = () => { // Act var point = new HostedMetricsPoint(null, "measurement", fields, MetricTags.Empty, new DefaultHostedMetricsPointTextWriter(), FlushInterval, timestamp); }; // Assert if (!expected) { action.Should().Throw <ArgumentException>(); } else { action.Should().NotThrow(); } }
/// <inheritdoc /> public void Write(JsonWriter textWriter, HostedMetricsPoint point, bool writeTimestamp = true) { if (textWriter == null) { throw new ArgumentNullException(nameof(textWriter)); } var hasPrevious = false; var measurementWriter = new StringWriter(); var tagsDictionary = point.Tags.ToDictionary(GraphiteSyntax.EscapeName); if (tagsDictionary.TryGetValue("app", out var appValue)) { measurementWriter.Write("app."); measurementWriter.Write(appValue); hasPrevious = true; } if (tagsDictionary.TryGetValue("env", out var envValue)) { if (hasPrevious) { measurementWriter.Write("."); } measurementWriter.Write("env."); measurementWriter.Write(envValue); hasPrevious = true; } if (tagsDictionary.TryGetValue("server", out var serverValue)) { if (hasPrevious) { measurementWriter.Write("."); } measurementWriter.Write("server."); measurementWriter.Write(serverValue); hasPrevious = true; } if (tagsDictionary.TryGetValue("mtype", out var metricType) && !string.IsNullOrWhiteSpace(metricType)) { if (hasPrevious) { measurementWriter.Write("."); } measurementWriter.Write(metricType); hasPrevious = true; } if (!string.IsNullOrWhiteSpace(point.Context)) { if (hasPrevious) { measurementWriter.Write("."); } measurementWriter.Write(GraphiteSyntax.EscapeName(point.Context, true)); hasPrevious = true; } if (hasPrevious) { measurementWriter.Write("."); } measurementWriter.Write(GraphiteSyntax.EscapeName(point.Measurement, true)); var tags = tagsDictionary.Where(tag => !ExcludeTags.Contains(tag.Key)); foreach (var tag in tags) { measurementWriter.Write('.'); measurementWriter.Write(GraphiteSyntax.EscapeName(tag.Key)); measurementWriter.Write('.'); measurementWriter.Write(tag.Value); } measurementWriter.Write('.'); var prefix = measurementWriter.ToString(); var utcTimestamp = point.UtcTimestamp ?? DateTime.UtcNow; foreach (var f in point.Fields) { textWriter.WriteStartObject(); var metric = $"{prefix}{GraphiteSyntax.EscapeName(f.Key)}"; textWriter.WritePropertyName("name"); // in graphite style format. should be same as Metric field below (used for partitioning, schema matching, indexing) textWriter.WriteValue(metric); textWriter.WritePropertyName("metric"); // in graphite style format. should be same as Name field above (used to generate Id) textWriter.WriteValue(metric); textWriter.WritePropertyName("value"); textWriter.WriteValue(HostedMetricsSyntax.FormatValue(f.Value, metric)); textWriter.WritePropertyName("interval"); textWriter.WriteValue(point.FlushInterval.Seconds); textWriter.WritePropertyName("mtype"); // not used yet. but should be one of gauge rate count counter timestamp textWriter.WriteValue("gauge"); textWriter.WritePropertyName("unit"); // not needed or used yet textWriter.WriteValue(string.Empty); textWriter.WritePropertyName("time"); // unix timestamp in seconds textWriter.WriteValue(HostedMetricsSyntax.FormatTimestamp(utcTimestamp)); textWriter.WritePropertyName("tags"); textWriter.WriteStartArray(); // TODO: Hosted Metrics requests take tags but not yet used, provided in metric tag for now. textWriter.WriteEndArray(); textWriter.WriteEndObject(); } }