Switched to use Nuget component for StatsD instead of including the code.

This commit is contained in:
Eric Fontana
2015-05-15 10:41:09 -04:00
parent 4dbb926698
commit 5692d2ec42
10 changed files with 35 additions and 242 deletions

View File

@@ -42,6 +42,13 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\RapidRegex.Core.1.0.0.4\lib\net40\RapidRegex.Core.dll</HintPath>
</Reference>
<Reference Include="StatsdClient, Version=1.0.0.19, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\StatsdClient.1.0.0.19\lib\net35\StatsdClient.dll</HintPath>
</Reference>
<Reference Include="StatsdClient.Configuration">
<HintPath>..\packages\StatsdClient.1.0.0.19\lib\net35\StatsdClient.Configuration.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration.Install" />
<Reference Include="System.Core" />

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="RapidRegex.Core" version="1.0.0.4" targetFramework="net40" />
<package id="StatsdClient" version="1.0.0.19" targetFramework="net40" />
<package id="Topshelf" version="3.1.4" targetFramework="net40" />
</packages>

View File

@@ -25,6 +25,7 @@
"StatsD": [
{
"type": "Win32-TailLog",
"namespace": "timberwinrtest",
"port": 8125,
"host": "devlexicesnu003.mycompany.svc",
"increment": ["apache.response.%{response}"],

View File

@@ -1,178 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net.Sockets;
using System.Threading;
namespace NStatsD
{
public sealed class Client
{
private static UdpClient _client;
public static string Host { get; set; }
public static int Port { get; set; }
Client()
{
if (Config != null)
{
var host = Config.Server.Host;
var port = Config.Server.Port;
_client = new UdpClient(host, port);
}
else
{
Config = new StatsDConfigurationSection();
Config.Server.Host = Host;;
Config.Server.Port = Port;
_client = new UdpClient(Host, Port);
}
}
public static Client Current
{
get { return CurrentClient.Instance; }
}
class CurrentClient
{
static CurrentClient() { }
internal static readonly Client Instance = new Client();
}
private StatsDConfigurationSection _config;
public StatsDConfigurationSection Config
{
get
{
if (_config == null)
{
_config = (StatsDConfigurationSection)ConfigurationManager.GetSection("statsD");
}
if(_config != null)
_config.Prefix = ValidatePrefix(_config.Prefix);
return _config;
}
set
{
_config = value;
_config.Prefix = ValidatePrefix(_config.Prefix);
}
}
private string ValidatePrefix(string prefix)
{
if (string.IsNullOrWhiteSpace(prefix))
return prefix;
if (prefix.EndsWith("."))
return prefix;
return string.Format("{0}.", prefix);
}
/// <summary>
/// Sends timing statistics.
/// </summary>
/// <param name="stat">Name of statistic being updated.</param>
/// <param name="time">The timing it took to complete.</param>
/// <param name="sampleRate">Tells StatsD how often to sample this value. Defaults to 1 (send all values).</param>
/// <param name="callback">A callback for when the send is complete. Defaults to null.</param>
public void Timing(string stat, long time, double sampleRate = 1, AsyncCallback callback = null)
{
var data = new Dictionary<string, string> { { stat, string.Format("{0}|ms", time) } };
Send(data, sampleRate, callback);
}
/// <summary>
/// Increments a counter
/// </summary>
/// <param name="stat">Name of statistic being updated.</param>
/// <param name="sampleRate">Tells StatsD how often to sample this value. Defaults to 1 (send all values).</param>
/// <param name="callback">A callback for when the send is complete. Defaults to null.</param>
public void Increment(string stat, double sampleRate = 1, AsyncCallback callback = null)
{
UpdateStats(stat, 1, sampleRate, callback);
}
/// <summary>
/// Decrements a counter
/// </summary>
/// <param name="stat">Name of statistic being updated.</param>
/// <param name="sampleRate">Tells StatsD how often to sample this value. Defaults to 1 (send all values).</param>
/// <param name="callback">A callback for when the send is complete. Defaults to null.</param>
public void Decrement(string stat, double sampleRate = 1, AsyncCallback callback = null)
{
UpdateStats(stat, -1, sampleRate, callback);
}
/// <summary>
/// Updates a counter by an arbitrary amount
/// </summary>
/// <param name="stat">Name of statistic being updated.</param>
/// <param name="value">The value of the metric.</param>
/// <param name="sampleRate">Tells StatsD how often to sample this value. Defaults to 1 (send all values).</param>
/// <param name="callback">A callback for when the send is complete. Defaults to null.</param>
public void Gauge(string stat, int value, double sampleRate = 1, AsyncCallback callback = null)
{
var data = new Dictionary<string, string> { { stat, string.Format("{0}|g", value) } };
Send(data, sampleRate, callback);
}
/// <summary>
/// Updates a counter by an arbitrary amount
/// </summary>
/// <param name="stat">Name of statistic(s) being updated.</param>
/// <param name="delta">The amount to adjust the counter</param>
/// <param name="sampleRate">Tells StatsD how often to sample this value. Defaults to 1 (send all values).</param>
/// <param name="callback">A callback for when the send is complete. Defaults to null.</param>
public void UpdateStats(string stat, int delta = 1, double sampleRate = 1, AsyncCallback callback = null)
{
var dictionary = new Dictionary<string, string> { { stat, string.Format("{0}|c", delta) } };
Send(dictionary, sampleRate, callback);
}
private static int _seed = Environment.TickCount;
private static readonly ThreadLocal<Random> random = new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref _seed)));
private void Send(Dictionary<string, string> data, double sampleRate, AsyncCallback callback)
{
if (!Config.Enabled)
return;
if (sampleRate < 1)
{
var nextRand = random.Value.NextDouble();
if (nextRand <= sampleRate)
{
var sampledData = data.Keys.ToDictionary(stat => stat,
stat => string.Format("{0}|@{1}", data[stat], sampleRate));
SendToStatsD(sampledData, callback);
}
}
else
{
SendToStatsD(data, callback);
}
}
private void SendToStatsD(Dictionary<string, string> sampledData, AsyncCallback callback)
{
var prefix = Config.Prefix;
var encoding = new System.Text.ASCIIEncoding();
foreach (var stat in sampledData.Keys)
{
var stringToSend = string.Format("{0}{1}:{2}", prefix, stat, sampledData[stat]);
var sendData = encoding.GetBytes(stringToSend);
_client.BeginSend(sendData, sendData.Length, callback, null);
}
}
}
}

View File

@@ -1,51 +0,0 @@
using System.Configuration;
namespace NStatsD
{
public class StatsDConfigurationSection : ConfigurationSection
{
[ConfigurationProperty("enabled", DefaultValue = "true", IsRequired = false)]
public bool Enabled
{
get { return (bool)this["enabled"]; }
set { this["enabled"] = value; }
}
[ConfigurationProperty("server")]
public ServerElement Server
{
get { return (ServerElement)this["server"]; }
set { this["server"] = value; }
}
[ConfigurationProperty("prefix", DefaultValue = "", IsRequired = false)]
public string Prefix
{
get { return (string)this["prefix"]; }
set { this["prefix"] = value; }
}
public override bool IsReadOnly()
{
return false;
}
}
public class ServerElement : ConfigurationElement
{
[ConfigurationProperty("host", DefaultValue = "localhost", IsRequired = true)]
public string Host
{
get { return (string)this["host"]; }
set { this["host"] = value; }
}
[ConfigurationProperty("port", DefaultValue = "8125", IsRequired = false)]
public int Port
{
get { return (int)this["port"]; }
set { this["port"] = value; }
}
}
}

View File

@@ -15,6 +15,7 @@ using System.Threading.Tasks;
using RapidRegex.Core;
using System.Text.RegularExpressions;
using System.Globalization;
using StatsdClient;
using TimberWinR.Parser;
namespace TimberWinR.Outputs
@@ -86,8 +87,13 @@ namespace TimberWinR.Outputs
_numThreads = parameters.NumThreads;
_jsonQueue = new List<JObject>();
NStatsD.Client.Host = _host;
NStatsD.Client.Port = _port;
var metricsConfig = new MetricsConfig
{
StatsdServerName = _host,
Prefix = parameters.Namespace,
};
StatsdClient.Metrics.Configure(metricsConfig);
for (int i = 0; i < _numThreads; i++)
{
@@ -249,7 +255,7 @@ namespace TimberWinR.Outputs
private string BuildMetricPath(string metric, JObject json)
{
return string.Format("{0}.{1}.{2}", ExpandField(_params.Namespace, json), ExpandField(_params.Sender, json), ExpandField(metric, json));
return string.Format("{0}.{1}", ExpandField(_params.Sender, json), ExpandField(metric, json));
}
private void TransmitStats(List<JObject> messages)
@@ -305,7 +311,7 @@ namespace TimberWinR.Outputs
int value;
if (int.TryParse(gaugeName, out value))
{
NStatsD.Client.Current.Gauge(metricPath, value, _params.SampleRate);
Metrics.Gauge(metricPath, value);
}
}
}
@@ -317,10 +323,10 @@ namespace TimberWinR.Outputs
{
string metricPath = BuildMetricPath(_params.Timings[i], json);
string timingName = ExpandField(_params.Timings[i + 1], json);
long value;
if (long.TryParse(timingName, out value))
int value;
if (int.TryParse(timingName, out value))
{
NStatsD.Client.Current.Timing(metricPath, value, _params.SampleRate);
Metrics.Timer(metricPath, value, _params.SampleRate);
}
}
}
@@ -335,7 +341,7 @@ namespace TimberWinR.Outputs
int value;
if (int.TryParse(countName, out value))
{
NStatsD.Client.Current.UpdateStats(metricPath, value, _params.SampleRate);
Metrics.Counter(metricPath, value, _params.SampleRate);
}
}
}
@@ -345,7 +351,7 @@ namespace TimberWinR.Outputs
foreach (var metric in _params.Increments)
{
string metricPath = BuildMetricPath(metric, json);
NStatsD.Client.Current.Increment(metricPath, _params.SampleRate);
Metrics.Counter(metricPath, 1,_params.SampleRate);
}
}
@@ -355,7 +361,7 @@ namespace TimberWinR.Outputs
foreach (var metric in _params.Increments)
{
string metricPath = BuildMetricPath(metric, json);
NStatsD.Client.Current.Decrement(metricPath, _params.SampleRate);
Metrics.Counter(metricPath, -1, _params.SampleRate);
}
}
}

View File

@@ -67,6 +67,12 @@
<Reference Include="RestSharp">
<HintPath>..\packages\RestSharp.105.0.0\lib\net4\RestSharp.dll</HintPath>
</Reference>
<Reference Include="StatsdClient">
<HintPath>..\packages\StatsdClient.1.0.0.19\lib\net35\StatsdClient.dll</HintPath>
</Reference>
<Reference Include="StatsdClient.Configuration">
<HintPath>..\packages\StatsdClient.1.0.0.19\lib\net35\StatsdClient.Configuration.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.configuration" />
<Reference Include="System.Core" />
@@ -114,8 +120,6 @@
<Compile Include="Inputs\WindowsEvtInputListener.cs" />
<Compile Include="LogErrors.cs" />
<Compile Include="Manager.cs" />
<Compile Include="NStatsD\Client.cs" />
<Compile Include="NStatsD\StatsDConfigurationSection.cs" />
<Compile Include="Outputs\Elasticsearch.cs" />
<Compile Include="Outputs\OutputSender.cs" />
<Compile Include="Outputs\StatsD.cs" />

View File

@@ -9,6 +9,7 @@
<package id="NLog" version="3.2.0.0" targetFramework="net40" />
<package id="RapidRegex.Core" version="1.0.0.4" targetFramework="net40" />
<package id="RestSharp" version="105.0.0" targetFramework="net40" />
<package id="StatsdClient" version="1.0.0.19" targetFramework="net40" />
<package id="System.Linq.Dynamic" version="1.0.4" targetFramework="net40" />
<package id="Topshelf" version="3.1.4" targetFramework="net40" />
</packages>

View File

@@ -54,6 +54,8 @@
<File Id="default.json" Source="$(var.TimberWinR.ServiceHost.TargetDir)\default.json" />
<File Id="Newtonsoft.Json.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\Newtonsoft.Json.dll" />
<File Id="Nlog.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\Nlog.dll" />
<File Id="StatsdClient.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\StatsdClient.dll" />
<File Id="StatsdClient.Configuration.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\StatsdClient.Configuration.dll" />
<File Id="RestSharp.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\RestSharp.dll" />
<File Id="RapidRegex.Core.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\RapidRegex.Core.dll" />
<File Id="TimberWinR.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\TimberWinR.dll" />

View File

@@ -2,6 +2,6 @@ $packageName = 'TimberWinR-${version}' # arbitrary name for the package, used in
$installerType = 'msi' #only one of these: exe, msi, msu
$scriptPath = $(Split-Path $MyInvocation.MyCommand.Path)
$fileFullPath = Join-Path $scriptPath 'TimberWinR-${version}.0.msi'
$silentArgs = '{54D22382-5BDE-4CD7-90D4-91AEC0D9B447} /quiet'
$silentArgs = '{E001D138-669B-4604-88C5-02C756461C15} /quiet'
$validExitCodes = @(0) #please insert other valid exit codes here, exit codes for ms http://msdn.microsoft.com/en-us/library/aa368542(VS.85).aspx
UnInstall-ChocolateyPackage "$packageName" "$installerType" "$silentArgs" "fileFullPath" -validExitCodes $validExitCodes