Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions source/Graphite/ChannelFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Graphite
/// </summary>
public class ChannelFactory : IDisposable
{
private static readonly Func<string, string, string> buildKey = (prefix, key) =>
private static readonly Func<string, string, string> buildKey = (prefix, key) =>
!string.IsNullOrEmpty(prefix) ? prefix + "." + key : key;

private readonly FormatterFactory formatters;
Expand Down Expand Up @@ -55,8 +55,8 @@ public IMonitoringChannel CreateChannel(string type, string target)
throw new InvalidOperationException("graphite pipe is not configured.");

return new MonitoringChannel(
k => buildKey(this.graphitePrefix, k),
formatter,
k => buildKey(this.graphitePrefix, k),
formatter,
this.graphitePipe);
}
else if (string.Equals(target, "statsd", StringComparison.OrdinalIgnoreCase))
Expand All @@ -65,8 +65,8 @@ public IMonitoringChannel CreateChannel(string type, string target)
throw new InvalidOperationException("statsd pipe is not configured.");

return new MonitoringChannel(
k => buildKey(this.statsdPrefix, k),
formatter,
k => buildKey(this.statsdPrefix, k),
formatter,
this.statsdPipe);
}

Expand All @@ -92,9 +92,9 @@ public IMonitoringChannel CreateChannel(string type, string target, float sampli
throw new InvalidOperationException("statsd pipe is not configured.");

return new SamplingMonitoringChannel(
k => buildKey(this.statsdPrefix, k),
formatter,
this.statsdPipe,
k => buildKey(this.statsdPrefix, k),
formatter,
this.statsdPipe,
sampling);
}
else if (string.Equals(target, "graphite", StringComparison.OrdinalIgnoreCase))
Expand Down Expand Up @@ -155,13 +155,12 @@ private void SetupPipes(IGraphiteConfiguration graphite, IStatsDConfiguration st
}
}

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Objekte verwerfen, bevor Bereich verloren geht", Justification="Ownership transferred to outer pipe.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Objekte verwerfen, bevor Bereich verloren geht", Justification = "Ownership transferred to outer pipe.")]
private void SetupStatsD(IStatsDConfiguration configuration)
{
IPAddress address = Helpers.ParseAddress(configuration.Address);
Func<IPipe> pipeFactory = () => new UdpPipe(configuration.Address, configuration.Port);

// Initialize with ip address.
IPipe inner = new UdpPipe(address, configuration.Port);
var inner = new AutoRefreshPipe(pipeFactory, configuration.Lifetime);

this.statsdPipe = new SamplingPipe(inner);
}
Expand All @@ -178,8 +177,9 @@ private void SetupGraphite(IGraphiteConfiguration configuration)
}
else if (configuration.Transport == TransportType.Udp)
{
// Initialize with ip address.
this.graphitePipe = new UdpPipe(address, configuration.Port);
Func<IPipe> pipeFactory = () => new UdpPipe(configuration.Address, configuration.Port);

this.graphitePipe = new AutoRefreshPipe(pipeFactory, configuration.Lifetime);
}
else
{
Expand Down
20 changes: 18 additions & 2 deletions source/Graphite/Configuration/ConnectionStringConfigurationBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Graphite.Configuration
Expand All @@ -23,6 +24,11 @@ public abstract class ConnectionStringConfigurationBase
/// </summary>
public string PrefixKey { get; private set; }

/// <summary>
/// Gets the time before renewing the socket, when using UDP protocol.
/// </summary>
public TimeSpan Lifetime { get; private set; }

/// <summary>
/// Parses connection string to properties.
/// </summary>
Expand All @@ -37,7 +43,7 @@ protected virtual IDictionary<string, string> Parse(string connectionString)
.Split(';')
.Select(x => x.Split(new[] { '=' }, 2))
.ToDictionary(
x => x.First().ToLowerInvariant(),
x => x.First().ToLowerInvariant(),
x => x.Skip(1).FirstOrDefault());

string value;
Expand All @@ -59,6 +65,16 @@ protected virtual IDictionary<string, string> Parse(string connectionString)
{
this.PrefixKey = value;
}

if (values.TryGetValue("lifetime", out value))
{
TimeSpan temp;

if (TimeSpan.TryParse(value, out temp))
{
this.Lifetime = temp;
}
}
}

return values;
Expand Down
18 changes: 17 additions & 1 deletion source/Graphite/Configuration/GraphiteElement.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Configuration;
using System;
using System.Configuration;
using System.Net;

namespace Graphite.Configuration
Expand Down Expand Up @@ -28,6 +29,11 @@ public class GraphiteElement : ConfigurationElement, IGraphiteConfiguration
/// </summary>
internal const string PrefixKeyPropertyName = "prefixKey";

/// <summary>
/// The XML name of the <see cref="Lifetime"/> property
/// </summary>
internal const string LifetimePropertyName = "lifetime";

/// <summary>
/// Gets or sets the port number.
/// </summary>
Expand Down Expand Up @@ -67,5 +73,15 @@ public string PrefixKey
get { return (string)base[PrefixKeyPropertyName]; }
set { base[PrefixKeyPropertyName] = value; }
}

/// <summary>
/// When using UDP protocol, the time before renewing the socket
/// </summary>
[ConfigurationProperty(LifetimePropertyName, IsRequired = false)]
public TimeSpan Lifetime
{
get { return (TimeSpan)base[LifetimePropertyName]; }
set { base[LifetimePropertyName] = value; }
}
}
}
6 changes: 6 additions & 0 deletions source/Graphite/Configuration/IGraphiteConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Net;

namespace Graphite.Configuration
Expand Down Expand Up @@ -26,5 +27,10 @@ public interface IGraphiteConfiguration
/// Gets the common prefix key.
/// </summary>
string PrefixKey { get; }

/// <summary>
/// Gets the time before renewing the socket, when using UDP protocol
/// </summary>
TimeSpan Lifetime { get; }
}
}
7 changes: 7 additions & 0 deletions source/Graphite/Configuration/IStatsDConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System;

namespace Graphite.Configuration
{
/// <summary>
Expand All @@ -19,5 +21,10 @@ public interface IStatsDConfiguration
/// Gets the common prefix key.
/// </summary>
string PrefixKey { get; }

/// <summary>
/// Gets the time before renewing the socket, when using UDP protocol
/// </summary>
TimeSpan Lifetime { get; }
}
}
18 changes: 17 additions & 1 deletion source/Graphite/Configuration/StatsDElement.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Configuration;
using System;
using System.Configuration;

namespace Graphite.Configuration
{
Expand All @@ -22,6 +23,11 @@ public class StatsDElement : ConfigurationElement, IStatsDConfiguration
/// </summary>
internal const string PrefixKeyPropertyName = "prefixKey";

/// <summary>
/// The XML name of the <see cref="Lifetime"/> property
/// </summary>
internal const string LifetimePropertyName = "lifetime";

/// <summary>
/// Gets or sets the port number.
/// </summary>
Expand Down Expand Up @@ -51,5 +57,15 @@ public string PrefixKey
get { return (string)base[PrefixKeyPropertyName]; }
set { base[PrefixKeyPropertyName] = value; }
}

/// <summary>
/// The time before renewing the socket
/// </summary>
[ConfigurationProperty(LifetimePropertyName, IsRequired = false)]
public TimeSpan Lifetime
{
get { return (TimeSpan)base[LifetimePropertyName]; }
set { base[LifetimePropertyName] = value; }
}
}
}
1 change: 1 addition & 0 deletions source/Graphite/Graphite.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
<Compile Include="Formatters\StatsDSetFormatter.cs" />
<Compile Include="Formatters\StatsDGaugeFormatter.cs" />
<Compile Include="Formatters\StatsDTimingFormatter.cs" />
<Compile Include="Infrastructure\AutoRefreshPipe.cs" />
<Compile Include="Infrastructure\IMonitoringChannel.cs" />
<Compile Include="Infrastructure\ISamplingPipe.cs" />
<Compile Include="IMetricsPipeProvider.cs" />
Expand Down
58 changes: 58 additions & 0 deletions source/Graphite/Infrastructure/AutoRefreshPipe.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using System.Threading;

namespace Graphite.Infrastructure
{
internal class AutoRefreshPipe : IPipe, IDisposable
{
private readonly Func<IPipe> pipeFactory;
private readonly TimeSpan delay;

private DateTime lastUpdate;
private IPipe innerPipe;

public AutoRefreshPipe(Func<IPipe> pipeFactory, TimeSpan delay)
{
this.pipeFactory = pipeFactory;
this.innerPipe = pipeFactory();
this.delay = delay;
this.lastUpdate = DateTime.UtcNow;
}

public bool Send(string message)
{
this.RefreshPipeIfNeeded();

return this.innerPipe.Send(message);
}

public bool Send(string[] messages)
{
this.RefreshPipeIfNeeded();

return this.innerPipe.Send(messages);
}

public void Dispose()
{
this.DisposePipe(this.innerPipe);
}

private void RefreshPipeIfNeeded()
{
if (this.delay > TimeSpan.Zero && DateTime.UtcNow - this.lastUpdate >= this.delay)
{
var oldPipe = Interlocked.Exchange(ref this.innerPipe, this.pipeFactory());
this.lastUpdate = DateTime.UtcNow;
this.DisposePipe(oldPipe);
}
}

private void DisposePipe(IPipe pipe)
{
var disposablePipe = pipe as IDisposable;

disposablePipe?.Dispose();
}
}
}
7 changes: 3 additions & 4 deletions source/Graphite/Infrastructure/UdpPipe.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;

Expand All @@ -12,11 +11,11 @@ internal class UdpPipe : IPipe, IDisposable

private bool disposed;

public UdpPipe(IPAddress address, int port)
public UdpPipe(string address, int port)
{
this.udpClient = new UdpClient();

this.udpClient.Connect(new IPEndPoint(address, port));
this.udpClient.Connect(address, port);
}

public bool Send(string message)
Expand All @@ -36,7 +35,7 @@ public bool Send(string[] messages)

return this.CoreSend(data);
}

private bool CoreSend(byte[] data)
{
try
Expand Down
12 changes: 7 additions & 5 deletions source/MSBuild.Graphite/Tasks/Graphite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ public Graphite()
public int Port { get; set; }

[Required]
public string Transport
public string Transport
{
get { return this.transport.ToString(); }
set { this.transport = (TransportType)Enum.Parse(typeof(TransportType), value); }
}

TransportType IGraphiteConfiguration.Transport
{
get { return this.transport; }
TransportType IGraphiteConfiguration.Transport
{
get { return this.transport; }
}

public string PrefixKey { get; set; }
Expand All @@ -42,12 +42,14 @@ TransportType IGraphiteConfiguration.Transport

public int Value { get; set; }

public TimeSpan Lifetime { get; set; }

public override bool Execute()
{
using (var channelFactory = new ChannelFactory(this, null))
{
IMonitoringChannel channel = channelFactory.CreateChannel(
"gauge",
"gauge",
"graphite");

channel.Report(this.Key, this.Value);
Expand Down
2 changes: 2 additions & 0 deletions source/MSBuild.Graphite/Tasks/StatsD.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public StatsD()
[Required]
public MetricType Type { get; set; }

public TimeSpan Lifetime { get; set; }

public override bool Execute()
{
using (var channelFactory = new ChannelFactory(null, this))
Expand Down