Skip to content

Commit 6808bce

Browse files
committed
Stop serialization if queue is full
Fixes the excessive number of exceptions from being thrown when Bosun is down
1 parent e09106c commit 6808bce

File tree

3 files changed

+43
-37
lines changed

3 files changed

+43
-37
lines changed

BosunReporter/Exceptions.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
using System;
22
using System.Net;
3+
using BosunReporter.Infrastructure;
34

45
namespace BosunReporter
56
{
67
public class BosunPostException : Exception
78
{
8-
public BosunPostException(HttpStatusCode statusCode, string responseBody, Exception innerException)
9+
internal BosunPostException(HttpStatusCode statusCode, string responseBody, Exception innerException)
910
: base("Posting to the Bosun API failed with status code " + statusCode, innerException)
1011
{
1112
Data["ResponseBody"] = responseBody;
1213
}
1314

14-
public BosunPostException(Exception innerException)
15+
internal BosunPostException(Exception innerException)
1516
: base("Posting to the Bosun API failed. Bosun did not respond.", innerException)
1617
{
1718
}
@@ -22,8 +23,8 @@ public class BosunQueueFullException : Exception
2223
public int MetricsCount { get; }
2324
public int Bytes { get; }
2425

25-
public BosunQueueFullException(int metricsCount, int bytes)
26-
: base("Bosun metric queue is full. Metric data is likely being lost due to repeated failures in posting to the Bosun API.")
26+
internal BosunQueueFullException(QueueType queueType, int metricsCount, int bytes)
27+
: base($"Bosun {queueType} metric queue is full. Metric data is likely being lost due to repeated failures in posting to the Bosun API.")
2728
{
2829
MetricsCount = metricsCount;
2930
Bytes = bytes;

BosunReporter/Infrastructure/PayloadQueue.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.IO;
4-
using System.Threading;
53

64
namespace BosunReporter.Infrastructure
75
{
6+
internal enum QueueType
7+
{
8+
Local,
9+
ExternalCounters,
10+
}
11+
812
internal class PayloadQueue
913
{
1014
private int _cacheLimit = 1;
@@ -17,12 +21,18 @@ internal class PayloadQueue
1721
internal int MaxPendingPayloads { get; set; }
1822
internal int LastBatchPayloadCount { get; private set; }
1923
internal int DroppedPayloads { get; private set; }
24+
internal QueueType Type { get; }
2025

2126
internal int PendingPayloadsCount => _pendingPayloads.Count;
2227
internal bool IsFull => PendingPayloadsCount >= MaxPendingPayloads;
2328

2429
internal event Action<BosunQueueFullException> PayloadDropped;
2530

31+
internal PayloadQueue(QueueType type)
32+
{
33+
Type = type;
34+
}
35+
2636
internal MetricWriter GetWriter()
2737
{
2838
// sure, we could keep a cache of writers, but seriously, it's one object per serialization interval
@@ -64,7 +74,7 @@ internal void AddPendingPayload(Payload payload)
6474
}
6575
else
6676
{
67-
ex = new BosunQueueFullException(payload.MetricsCount, payload.Used);
77+
ex = new BosunQueueFullException(Type, payload.MetricsCount, payload.Used);
6878
DroppedPayloads++;
6979
ReleasePayload(payload);
7080
}

BosunReporter/MetricsCollector.cs

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ public int MaxPayloadSize
122122

123123
public MetricsCollector(BosunOptions options)
124124
{
125-
_localMetricsQueue = new PayloadQueue();
126-
_externalCounterQueue = new PayloadQueue();
125+
_localMetricsQueue = new PayloadQueue(QueueType.Local);
126+
_externalCounterQueue = new PayloadQueue(QueueType.ExternalCounters);
127127

128128
_localMetricsQueue.PayloadDropped += OnPayloadDropped;
129129
_externalCounterQueue.PayloadDropped += OnPayloadDropped;
@@ -729,39 +729,34 @@ private void SerializeMetrics(out int metricsCount, out int bytesWritten)
729729

730730
metricsCount = 0;
731731
bytesWritten = 0;
732-
MetricWriter localWriter = null;
733-
MetricWriter externalCounterWriter = null;
734-
try
735-
{
736-
if (_localMetrics.Count > 0)
737-
{
738-
localWriter = _localMetricsQueue.GetWriter();
739-
SerializeMetricListToWriter(localWriter, _localMetrics, timestamp);
740-
metricsCount += localWriter.MetricsCount;
741-
bytesWritten += localWriter.TotalBytesWritten;
742-
}
743-
744-
if (_externalCounterMetrics.Count > 0)
745-
{
746-
externalCounterWriter = _externalCounterQueue.GetWriter();
747-
SerializeMetricListToWriter(externalCounterWriter, _externalCounterMetrics, timestamp);
748-
metricsCount += externalCounterWriter.MetricsCount;
749-
bytesWritten += externalCounterWriter.TotalBytesWritten;
750-
}
751-
}
752-
finally
753-
{
754-
localWriter?.EndBatch();
755-
externalCounterWriter?.EndBatch();
756-
}
732+
SerializeMetricListToWriter(_localMetricsQueue, _localMetrics, timestamp, ref metricsCount, ref bytesWritten);
733+
SerializeMetricListToWriter(_externalCounterQueue, _externalCounterMetrics, timestamp, ref metricsCount, ref bytesWritten);
757734
}
758735
}
759736

760-
private static void SerializeMetricListToWriter(MetricWriter writer, List<BosunMetric> metrics, DateTime timestamp)
737+
private static void SerializeMetricListToWriter(PayloadQueue queue, List<BosunMetric> metrics, DateTime timestamp, ref int metricsCount, ref int bytesWritten)
761738
{
762-
foreach (var m in metrics)
739+
if (metrics.Count == 0)
740+
return;
741+
742+
var writer = queue.GetWriter();
743+
744+
try
745+
{
746+
foreach (var m in metrics)
747+
{
748+
m.SerializeInternal(writer, timestamp);
749+
750+
if (queue.IsFull)
751+
break;
752+
}
753+
754+
metricsCount += writer.MetricsCount;
755+
bytesWritten += writer.TotalBytesWritten;
756+
}
757+
finally
763758
{
764-
m.SerializeInternal(writer, timestamp);
759+
writer.EndBatch();
765760
}
766761
}
767762

0 commit comments

Comments
 (0)