Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tagging and gauge operations #229

Closed
wants to merge 18 commits into from
Closed
17 changes: 11 additions & 6 deletions src/JustEat.StatsD/Buffered/BufferBasedStatsDPublisher.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;

namespace JustEat.StatsD.Buffered
{
Expand Down Expand Up @@ -31,19 +32,23 @@ internal BufferBasedStatsDPublisher(StatsDConfiguration configuration, IStatsDTr
_formatter = new StatsDUtf8Formatter(configuration.Prefix);
}

public void Increment(long value, double sampleRate, string bucket)
public void Increment(long value, double sampleRate, string bucket, IDictionary<string, string>? tags = null)
{
SendMessage(sampleRate, StatsDMessage.Counter(value, bucket));
SendMessage(sampleRate, StatsDMessage.Counter(value, bucket, tags));
}

public void Gauge(double value, string bucket)
public void Gauge(
double value,
string bucket,
Operation operation = Operation.Set,
IDictionary<string, string>? tags = null)
{
SendMessage(DefaultSampleRate, StatsDMessage.Gauge(value, bucket));
SendMessage(DefaultSampleRate, StatsDMessage.Gauge(value, bucket, tags, operation));
}

public void Timing(long duration, double sampleRate, string bucket)
public void Timing(long duration, double sampleRate, string bucket, IDictionary<string, string>? tags = null)
{
SendMessage(sampleRate, StatsDMessage.Timing(duration, bucket));
SendMessage(sampleRate, StatsDMessage.Timing(duration, bucket, tags));
}

private void SendMessage(double sampleRate, in StatsDMessage msg)
Expand Down
35 changes: 28 additions & 7 deletions src/JustEat.StatsD/Buffered/StatsDMessage.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,52 @@
using System.Collections.Generic;

namespace JustEat.StatsD.Buffered
{
internal readonly struct StatsDMessage
{
public readonly string StatBucket;
public readonly double Magnitude;
public readonly StatsDMessageKind MessageKind;
public readonly Operation Operation;
public readonly IDictionary<string, string>? Tags;

private StatsDMessage(string statBucket, double magnitude, StatsDMessageKind messageKind)
private StatsDMessage(
string statBucket,
double magnitude,
StatsDMessageKind messageKind,
IDictionary<string, string>? tags,
Operation operation = default)
{
StatBucket = statBucket;
Magnitude = magnitude;
MessageKind = messageKind;
Operation = operation;
Tags = tags;
}

public static StatsDMessage Timing(long milliseconds, string statBucket)
public static StatsDMessage Timing(
long milliseconds,
string statBucket,
IDictionary<string, string>? tags)
{
return new StatsDMessage(statBucket, milliseconds, StatsDMessageKind.Timing);
return new StatsDMessage(statBucket, milliseconds, StatsDMessageKind.Timing, tags);
}

public static StatsDMessage Counter(long magnitude, string statBucket)
public static StatsDMessage Counter(
long magnitude,
string statBucket,
IDictionary<string, string>? tags)
{
return new StatsDMessage(statBucket, magnitude, StatsDMessageKind.Counter);
return new StatsDMessage(statBucket, magnitude, StatsDMessageKind.Counter, tags);
}

public static StatsDMessage Gauge(double magnitude, string statBucket)
public static StatsDMessage Gauge(
double magnitude,
string statBucket,
IDictionary<string, string>? tags,
Operation operation = Operation.Set)
{
return new StatsDMessage(statBucket, magnitude, StatsDMessageKind.Gauge);
return new StatsDMessage(statBucket, magnitude, StatsDMessageKind.Gauge, tags, operation);
}
}
}
38 changes: 33 additions & 5 deletions src/JustEat.StatsD/Buffered/StatsDUtf8Formatter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Text;

Expand Down Expand Up @@ -37,7 +39,7 @@ public bool TryFormat(in StatsDMessage msg, double sampleRate, Span<byte> destin
var buffer = new Buffer(destination);

bool isFormattingSuccessful =
TryWriteBucketNameWithColon(ref buffer, msg.StatBucket)
TryWriteBucketNameWithColon(ref buffer, msg)
&& TryWritePayloadWithMessageKindSuffix(ref buffer, msg)
&& TryWriteSampleRateIfNeeded(ref buffer, sampleRate);

Expand All @@ -46,15 +48,33 @@ public bool TryFormat(in StatsDMessage msg, double sampleRate, Span<byte> destin
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool TryWriteBucketNameWithColon(ref Buffer buffer, string statBucket)
private bool TryWriteBucketNameWithColon(ref Buffer buffer, StatsDMessage msg)
{
// prefix + msg.Bucket + ":"
// prefix + msg.Bucket + tags + ":"

return buffer.TryWriteBytes(_utf8Prefix)
&& buffer.TryWriteUtf8String(statBucket)
&& buffer.TryWriteUtf8String(msg.StatBucket)
&& TryWriteTags(ref buffer, msg.Tags)
&& buffer.TryWriteByte((byte)':');
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryWriteTags(ref Buffer buffer, IDictionary<string, string>? tags)
{
// key=value,key=value

if (tags == null || tags.Count == 0)
return true;
gandarez marked this conversation as resolved.
Show resolved Hide resolved

StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> tag in tags)
gandarez marked this conversation as resolved.
Show resolved Hide resolved
{
sb.AppendFormat(CultureInfo.InvariantCulture, ";{0}={1}", tag.Key, tag.Value);
}

return buffer.TryWriteUtf8String(sb.ToString());
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryWritePayloadWithMessageKindSuffix(ref Buffer buffer, in StatsDMessage msg)
{
Expand All @@ -79,7 +99,15 @@ private static bool TryWritePayloadWithMessageKindSuffix(ref Buffer buffer, in S
// check if magnitude is integral, integers are written significantly faster
bool isMagnitudeIntegral = msg.Magnitude == integralMagnitude;

var successSoFar = isMagnitudeIntegral ?
bool successSoFar;
gandarez marked this conversation as resolved.
Show resolved Hide resolved

if (msg.Operation == Operation.Increment)
successSoFar = buffer.TryWriteByte((byte)'+');
gandarez marked this conversation as resolved.
Show resolved Hide resolved

if (msg.Operation == Operation.Decrement)
successSoFar = buffer.TryWriteByte((byte)'-');
gandarez marked this conversation as resolved.
Show resolved Hide resolved

successSoFar = isMagnitudeIntegral ?
gandarez marked this conversation as resolved.
Show resolved Hide resolved
buffer.TryWriteInt64(integralMagnitude) :
buffer.TryWriteDouble(msg.Magnitude);

Expand Down
12 changes: 9 additions & 3 deletions src/JustEat.StatsD/IStatsDPublisher.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Collections.Generic;

namespace JustEat.StatsD
{
/// <summary>
Expand All @@ -11,21 +13,25 @@ public interface IStatsDPublisher
/// <param name="value">The value to increment the counter by.</param>
/// <param name="sampleRate">The sample rate for the counter.</param>
/// <param name="bucket">The bucket to increment the counter for.</param>
void Increment(long value, double sampleRate, string bucket);
/// <param name="tags">The key value pair collection of tags.</param>
gandarez marked this conversation as resolved.
Show resolved Hide resolved
void Increment(long value, double sampleRate, string bucket, IDictionary<string, string>? tags);

/// <summary>
/// Publishes a gauge for the specified bucket and value.
/// </summary>
/// <param name="value">The value to publish for the gauge.</param>
/// <param name="bucket">The bucket to publish the gauge for.</param>
void Gauge(double value, string bucket);
/// <param name="operation">The gauge operation.</param>
/// <param name="tags">The key value pair collection of tags.</param>
gandarez marked this conversation as resolved.
Show resolved Hide resolved
void Gauge(double value, string bucket, Operation operation, IDictionary<string, string>? tags);

/// <summary>
/// Publishes a timer for the specified bucket and value.
/// </summary>
/// <param name="duration">The value to publish for the timer.</param>
/// <param name="sampleRate">The sample rate for the timer.</param>
/// <param name="bucket">The bucket to publish the timer for.</param>
void Timing(long duration, double sampleRate, string bucket);
/// <param name="tags">The key value pair collection of tags.</param>
gandarez marked this conversation as resolved.
Show resolved Hide resolved
void Timing(long duration, double sampleRate, string bucket, IDictionary<string, string>? tags);
}
}
60 changes: 36 additions & 24 deletions src/JustEat.StatsD/IStatsDPublisherExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ public static class IStatsDPublisherExtensions
/// </summary>
/// <param name="publisher">The <see cref="IStatsDPublisher"/> to publish with.</param>
/// <param name="bucket">The bucket to increment the counter for.</param>
public static void Increment(this IStatsDPublisher publisher, string bucket)
/// <param name="tags">The key value pair collection of tags.</param>
gandarez marked this conversation as resolved.
Show resolved Hide resolved
public static void Increment(this IStatsDPublisher publisher, string bucket, IDictionary<string, string>? tags = null)
{
publisher.Increment(1, DefaultSampleRate, bucket);
publisher.Increment(1, DefaultSampleRate, bucket, tags);
}

/// <summary>
Expand All @@ -28,9 +29,10 @@ public static void Increment(this IStatsDPublisher publisher, string bucket)
/// <param name="publisher">The <see cref="IStatsDPublisher"/> to publish with.</param>
/// <param name="value">The value to increment the counter by.</param>
/// <param name="bucket">The bucket to increment the counter for.</param>
public static void Increment(this IStatsDPublisher publisher, long value, string bucket)
/// <param name="tags">The key value pair collection of tags.</param>
gandarez marked this conversation as resolved.
Show resolved Hide resolved
public static void Increment(this IStatsDPublisher publisher, long value, string bucket, IDictionary<string, string>? tags = null)
{
publisher.Increment(value, DefaultSampleRate, bucket);
publisher.Increment(value, DefaultSampleRate, bucket, tags);
}

/// <summary>
Expand All @@ -40,7 +42,8 @@ public static void Increment(this IStatsDPublisher publisher, long value, string
/// <param name="value">The value to increment the counter(s) by.</param>
/// <param name="sampleRate">The sample rate for the counter(s).</param>
/// <param name="buckets">The bucket(s) to increment the counter(s) for.</param>
public static void Increment(this IStatsDPublisher publisher, long value, double sampleRate, IEnumerable<string> buckets)
/// <param name="tags">The key value pair collection of tags.</param>
gandarez marked this conversation as resolved.
Show resolved Hide resolved
public static void Increment(this IStatsDPublisher publisher, long value, double sampleRate, IEnumerable<string> buckets, IDictionary<string, string>? tags = null)
{
if (buckets == null)
{
Expand All @@ -49,7 +52,7 @@ public static void Increment(this IStatsDPublisher publisher, long value, double

foreach (string bucket in buckets)
{
publisher.Increment(value, sampleRate, bucket);
publisher.Increment(value, sampleRate, bucket, tags);
}
}

Expand All @@ -60,7 +63,8 @@ public static void Increment(this IStatsDPublisher publisher, long value, double
/// <param name="value">The value to increment the counter(s) by.</param>
/// <param name="sampleRate">The sample rate for the counter(s).</param>
/// <param name="buckets">The bucket(s) to increment the counter(s) for.</param>
public static void Increment(this IStatsDPublisher publisher, long value, double sampleRate, params string[] buckets)
/// <param name="tags">The key value pair collection of tags.</param>
gandarez marked this conversation as resolved.
Show resolved Hide resolved
public static void Increment(this IStatsDPublisher publisher, long value, double sampleRate, IDictionary<string, string>? tags = null, params string[] buckets)
{
if (buckets == null || buckets.Length == 0)
{
Expand All @@ -69,7 +73,7 @@ public static void Increment(this IStatsDPublisher publisher, long value, double

foreach (string bucket in buckets)
{
publisher.Increment(value, sampleRate, bucket);
publisher.Increment(value, sampleRate, bucket, tags);
}
}

Expand All @@ -78,9 +82,10 @@ public static void Increment(this IStatsDPublisher publisher, long value, double
/// </summary>
/// <param name="publisher">The <see cref="IStatsDPublisher"/> to publish with.</param>
/// <param name="bucket">The bucket to decrement the counter for.</param>
public static void Decrement(this IStatsDPublisher publisher, string bucket)
/// <param name="tags">The key value pair collection of tags.</param>
gandarez marked this conversation as resolved.
Show resolved Hide resolved
public static void Decrement(this IStatsDPublisher publisher, string bucket, IDictionary<string, string>? tags = null)
{
publisher.Increment(-1, DefaultSampleRate, bucket);
publisher.Increment(-1, DefaultSampleRate, bucket, tags);
}

/// <summary>
Expand All @@ -89,9 +94,10 @@ public static void Decrement(this IStatsDPublisher publisher, string bucket)
/// <param name="publisher">The <see cref="IStatsDPublisher"/> to publish with.</param>
/// <param name="value">The value to decrement the counter by.</param>
/// <param name="bucket">The bucket to decrement the counter for.</param>
public static void Decrement(this IStatsDPublisher publisher, long value, string bucket)
/// <param name="tags">The key value pair collection of tags.</param>
gandarez marked this conversation as resolved.
Show resolved Hide resolved
public static void Decrement(this IStatsDPublisher publisher, long value, string bucket, IDictionary<string, string>? tags = null)
{
publisher.Increment(value > 0 ? -value : value, DefaultSampleRate, bucket);
publisher.Increment(value > 0 ? -value : value, DefaultSampleRate, bucket, tags);
}

/// <summary>
Expand All @@ -101,9 +107,10 @@ public static void Decrement(this IStatsDPublisher publisher, long value, string
/// <param name="value">The value to decrement the counter by.</param>
/// <param name="sampleRate">The sample rate for the counter.</param>
/// <param name="bucket">The bucket to decrement the counter for.</param>
public static void Decrement(this IStatsDPublisher publisher, long value, double sampleRate, string bucket)
/// <param name="tags">The key value pair collection of tags.</param>
gandarez marked this conversation as resolved.
Show resolved Hide resolved
public static void Decrement(this IStatsDPublisher publisher, long value, double sampleRate, string bucket, IDictionary<string, string>? tags = null)
{
publisher.Increment(value > 0 ? -value : value, sampleRate, bucket);
publisher.Increment(value > 0 ? -value : value, sampleRate, bucket, tags);
}

/// <summary>
Expand All @@ -113,7 +120,8 @@ public static void Decrement(this IStatsDPublisher publisher, long value, double
/// <param name="value">The value to decrement the counter(s) by.</param>
/// <param name="sampleRate">The sample rate for the counter(s).</param>
/// <param name="buckets">The bucket(s) to decrement the counter(s) for.</param>
public static void Decrement(this IStatsDPublisher publisher, long value, double sampleRate, IEnumerable<string> buckets)
/// <param name="tags">The key value pair collection of tags.</param>
gandarez marked this conversation as resolved.
Show resolved Hide resolved
public static void Decrement(this IStatsDPublisher publisher, long value, double sampleRate, IEnumerable<string> buckets, IDictionary<string, string>? tags = null)
{
if (buckets == null)
{
Expand All @@ -124,7 +132,7 @@ public static void Decrement(this IStatsDPublisher publisher, long value, double

foreach (string bucket in buckets)
{
publisher.Increment(adjusted, sampleRate, bucket);
publisher.Increment(adjusted, sampleRate, bucket, tags);
}
}

Expand All @@ -135,7 +143,8 @@ public static void Decrement(this IStatsDPublisher publisher, long value, double
/// <param name="value">The value to decrement the counter(s) by.</param>
/// <param name="sampleRate">The sample rate for the counter(s).</param>
/// <param name="buckets">The bucket(s) to decrement the counter(s) for.</param>
public static void Decrement(this IStatsDPublisher publisher, long value, double sampleRate, params string[] buckets)
/// <param name="tags">The key value pair collection of tags.</param>
gandarez marked this conversation as resolved.
Show resolved Hide resolved
public static void Decrement(this IStatsDPublisher publisher, long value, double sampleRate, IDictionary<string, string>? tags = null, params string[] buckets)
{
if (buckets == null || buckets.Length == 0)
{
Expand All @@ -146,7 +155,7 @@ public static void Decrement(this IStatsDPublisher publisher, long value, double

foreach (string bucket in buckets)
{
publisher.Increment(adjusted, sampleRate, bucket);
publisher.Increment(adjusted, sampleRate, bucket, tags);
}
}

Expand All @@ -156,9 +165,10 @@ public static void Decrement(this IStatsDPublisher publisher, long value, double
/// <param name="publisher">The <see cref="IStatsDPublisher"/> to publish with.</param>
/// <param name="duration">The value to publish for the timer.</param>
/// <param name="bucket">The bucket to publish the timer for.</param>
public static void Timing(this IStatsDPublisher publisher, TimeSpan duration, string bucket)
/// <param name="tags">The key value pair collection of tags.</param>
gandarez marked this conversation as resolved.
Show resolved Hide resolved
public static void Timing(this IStatsDPublisher publisher, TimeSpan duration, string bucket, IDictionary<string, string>? tags = null)
{
publisher.Timing((long)duration.TotalMilliseconds, DefaultSampleRate, bucket);
publisher.Timing((long)duration.TotalMilliseconds, DefaultSampleRate, bucket, tags);
}

/// <summary>
Expand All @@ -168,9 +178,10 @@ public static void Timing(this IStatsDPublisher publisher, TimeSpan duration, st
/// <param name="duration">The value to publish for the timer.</param>
/// <param name="sampleRate">The sample rate for the timer.</param>
/// <param name="bucket">The bucket to publish the timer for.</param>
public static void Timing(this IStatsDPublisher publisher, TimeSpan duration, double sampleRate, string bucket)
/// <param name="tags">The key value pair collection of tags.</param>
gandarez marked this conversation as resolved.
Show resolved Hide resolved
public static void Timing(this IStatsDPublisher publisher, TimeSpan duration, double sampleRate, string bucket, IDictionary<string, string>? tags = null)
{
publisher.Timing((long)duration.TotalMilliseconds, sampleRate, bucket);
publisher.Timing((long)duration.TotalMilliseconds, sampleRate, bucket, tags);
}

/// <summary>
Expand All @@ -179,9 +190,10 @@ public static void Timing(this IStatsDPublisher publisher, TimeSpan duration, do
/// <param name="publisher">The <see cref="IStatsDPublisher"/> to publish with.</param>
/// <param name="duration">The value to publish for the timer.</param>
/// <param name="bucket">The bucket to publish the timer for.</param>
public static void Timing(this IStatsDPublisher publisher, long duration, string bucket)
/// <param name="tags">The key value pair collection of tags.</param>
gandarez marked this conversation as resolved.
Show resolved Hide resolved
public static void Timing(this IStatsDPublisher publisher, long duration, string bucket, IDictionary<string, string>? tags = null)
gandarez marked this conversation as resolved.
Show resolved Hide resolved
{
publisher.Timing(duration, DefaultSampleRate, bucket);
publisher.Timing(duration, DefaultSampleRate, bucket, tags);
}
}
}
Loading