Skip to content

Commit

Permalink
Merge branch 'release/3.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Jericho committed Feb 13, 2018
2 parents 7ab0db8 + c164b67 commit 32820d6
Show file tree
Hide file tree
Showing 19 changed files with 791 additions and 367 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ public ColoredConsoleLogProvider(LogLevel minLevel = LogLevel.Trace)
_minLevel = minLevel;
}


/// <summary>
/// Gets the specified named logger.
/// </summary>
/// <param name="name">Name of the logger.</param>
/// <returns>The logger reference.</returns>
public Logger GetLogger(string name)
{
return (logLevel, messageFunc, exception, formatParameters) =>
Expand All @@ -36,8 +42,7 @@ public Logger GetLogger(string name)
{
if (logLevel >= _minLevel)
{
ConsoleColor consoleColor;
if (Colors.TryGetValue(logLevel, out consoleColor))
if (Colors.TryGetValue(logLevel, out ConsoleColor consoleColor))
{
var originalForground = Console.ForegroundColor;
try
Expand Down Expand Up @@ -76,12 +81,25 @@ private static void WriteMessage(
Console.WriteLine("{0} | {1} | {2} | {3}", DateTime.UtcNow, logLevel, name, message);
}


/// <summary>
/// Opens a nested diagnostics context. Not supported in EntLib logging.
/// </summary>
/// <param name="message">The message to add to the diagnostics context.</param>
/// <returns>A disposable that when disposed removes the message from the context.</returns>
public IDisposable OpenNestedContext(string message)
{
return NullDisposable.Instance;
}

public IDisposable OpenMappedContext(string key, string value)

/// <summary>
/// Opens a mapped diagnostics context. Not supported in EntLib logging.
/// </summary>
/// <param name="key">A key.</param>
/// <param name="value">A value.</param>
/// <returns>A disposable that when disposed removes the map from the context.</returns>
public IDisposable OpenMappedContext(string key, object value, bool destructure = false)
{
return NullDisposable.Instance;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using App.Metrics;
using App.Metrics.Formatters;
using App.Metrics.Serialization;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace Picton.Messaging.IntegrationTests.Datadog
{
/// <summary>
/// Formatter for encoding Metrics in Datadog JSON
/// </summary>
public class DatadogFormatter : IMetricsOutputFormatter
{
private readonly DatadogFormatterOptions _options;

/// <summary>
/// Constructor
/// </summary>
public DatadogFormatter(DatadogFormatterOptions options)
{
_options = options;
}

/// <inheritdoc />
public Task WriteAsync(Stream output, MetricsDataValueSource metricsData, CancellationToken cancellationToken = new CancellationToken())
{
var serializer = new MetricSnapshotSerializer();
using (var streamWriter = new StreamWriter(output))
{
using (var writer = new MetricSnapshotDatadogWriter(streamWriter, _options))
serializer.Serialize(writer, metricsData);
}

return Task.CompletedTask;
}

/// <inheritdoc />
public MetricsMediaTypeValue MediaType => new MetricsMediaTypeValue("application", "com.datadoghq.metrics", "v1", "json");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

namespace Picton.Messaging.IntegrationTests.Datadog
{
/// <summary>
/// Options for data reported to Datadog
/// </summary>
public class DatadogFormatterOptions
{
/// <summary>
/// The Hostname that is reported. Usually Environment.MachineName
/// </summary>
public string Hostname { get; set; }
}
}
13 changes: 13 additions & 0 deletions Source/Picton.Messaging.IntegrationTests/Datadog/MetricJson.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Picton.Messaging.IntegrationTests.Datadog
{
/// <summary>
/// For serializing http://docs.datadoghq.com/api/?lang=console#metrics
/// </summary>
class MetricJson
{
public string Metric { get; set; }
public object[][] Points { get; set; }
public string Host { get; set; }
public string[] Tags { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
using App.Metrics;
using App.Metrics.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Picton.Messaging.IntegrationTests.Datadog
{
class MetricSnapshotDatadogWriter : IMetricSnapshotWriter
{
private StreamWriter _streamWriter;
private readonly DatadogFormatterOptions _options;
private readonly List<MetricJson> _metrics = new List<MetricJson>();

static readonly JsonSerializerSettings JsonSettings = new JsonSerializerSettings
{
ContractResolver = new LowercaseContractResolver()
};

private class LowercaseContractResolver : DefaultContractResolver
{
protected override string ResolvePropertyName(string propertyName)
{
return propertyName.ToLower();
}
}

public MetricSnapshotDatadogWriter(StreamWriter streamWriter, DatadogFormatterOptions options)
{
_streamWriter = streamWriter;
_options = options;
}

public void Dispose()
{
if (_streamWriter != null)
{
Flush();

_streamWriter?.Dispose();
_streamWriter = null;
}
}

/// <inheritdoc />
public void Write(string context, string name, object value, MetricTags tags, DateTime timestamp)
{
Write(context, name, new[] { "value" }, new[] { value }, tags, timestamp);
}

/// <inheritdoc />
public void Write(string context, string name, IEnumerable<string> columns, IEnumerable<object> values, MetricTags tags, DateTime timestamp)
{
var posixTimestamp = (timestamp - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)).TotalSeconds; //TODO: Check this

var dict = columns.Zip(values, (column, value) => new { column, value }).ToDictionary(p => p.column, p => p.value);

switch (tags.Values[Array.IndexOf(tags.Keys, "mtype")])
{
case "apdex":
Write(posixTimestamp, context, name, "count", dict["samples"]);
Write(posixTimestamp, context, name, "score", dict["score"]);
Write(posixTimestamp, context, name, "satisfied", dict["satisfied"]);
Write(posixTimestamp, context, name, "tolerating", dict["tolerating"]);
Write(posixTimestamp, context, name, "frustrating", dict["frustrating"]);
break;
case "gauge":
Write(posixTimestamp, context, name, dict["value"]);
break;
case "counter":
if (dict.ContainsKey("value"))
Write(posixTimestamp, context, name, dict["value"]);
break;
case "meter":
Write(posixTimestamp, context, name, "count", dict["count.meter"]);
Write(posixTimestamp, context, name, "15m", dict["rate15m"]);
Write(posixTimestamp, context, name, "5m", dict["rate5m"]);
Write(posixTimestamp, context, name, "1m", dict["rate1m"]);
Write(posixTimestamp, context, name, "avg", dict["rate.mean"]);
break;
case "timer":
Write(posixTimestamp, context, name, "1mrate", dict["rate1m"]);
Write(posixTimestamp, context, name, "5mrate", dict["rate5m"]);
Write(posixTimestamp, context, name, "15mrate", dict["rate15m"]);
WriteHistogram(posixTimestamp, context, name, dict);
break;
case "histogram":
WriteHistogram(posixTimestamp, context, name, dict);
break;
}
}

private void WriteHistogram(double posixTimestamp, string context, string name, Dictionary<string, object> dict)
{
Write(posixTimestamp, context, name, "count", dict["count.hist"]);

Write(posixTimestamp, context, name, "max", dict["max"]);
Write(posixTimestamp, context, name, "avg", dict["mean"]);
Write(posixTimestamp, context, name, "median", dict["median"]);
Write(posixTimestamp, context, name, "min", dict["min"]);
Write(posixTimestamp, context, name, "stdDev", dict["stddev"]);

Write(posixTimestamp, context, name, "75percentile", dict["p75"]);
Write(posixTimestamp, context, name, "95percentile", dict["p95"]);
Write(posixTimestamp, context, name, "98percentile", dict["p98"]);
Write(posixTimestamp, context, name, "99percentile", dict["p99"]);
Write(posixTimestamp, context, name, "999percentile", dict["p999"]);
}

private void Write(double timestamp, string context, string name, string subname, object value)
{
Write(timestamp, context, name + "." + subname, value);
}

private void Write(double timestamp, string context, string name, object value)
{
_metrics.Add(new MetricJson
{
Host = _options.Hostname,
Metric = context + "." + name,
//Tags = tags.Values,
Points = new[]
{
new[] { timestamp, value }
}
});
}

private void Flush()
{
_streamWriter.Write(JsonConvert.SerializeObject(new SeriesJson { Series = _metrics.ToArray() }, JsonSettings));
}

public GeneratedMetricNameMapping MetricNameMapping { get; } = new GeneratedMetricNameMapping();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Picton.Messaging.IntegrationTests.Datadog
{
class SeriesJson
{
public MetricJson[] Series { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
<AssemblyName>Picton.Mesaging.IntegrationTests</AssemblyName>
<RootNamespace>Picton.Mesaging.IntegrationTests</RootNamespace>
<AssemblyName>Picton.Messaging.IntegrationTests</AssemblyName>
<RootNamespace>Picton.Messaging.IntegrationTests</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="App.Metrics.Reporting.Http" Version="2.0.0-preview1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Picton.Messaging\Picton.Messaging.csproj" />
</ItemGroup>
Expand Down
Loading

0 comments on commit 32820d6

Please sign in to comment.