public static void RecordMetricsForever(MetricsCollector collector) { var rand = new Random(); // basic counter (no extra tags) var myCounter = collector.CreateMetric <Counter>("my_counter", "units", "desc"); // counter with tags // var successCounter = collector.CreateMetric("results", "units", "desc", new ResultCounter(ResultType.Success)); // metric group var group = collector.GetMetricGroup <ResultType, ResultCounter>("results", "u", "d"); group.PopulateFromEnum(); // multi-aggregate gauge var gauge = collector.CreateMetric <RandomGauge>("random", "stuff", "no desc"); // record on them while (true) { myCounter.Increment(); var x = rand.NextDouble(); if (x < .1) { group[ResultType.Error].Increment(); } else if (x < .3) { group[ResultType.Timeout].Increment(); } else { group[ResultType.Success].Increment(); } gauge.Record(rand.NextDouble()); // slow down the infinite loop Thread.Sleep(20); } }
static void Main(string[] args) { _collector = new MetricsCollector(new BosunOptions(ex => Handle(ex)) { MetricsNamePrefix = "TestApp.", BosunUrl = new System.Uri("http://192.168.1.5:8070"), PropertyToTagName = NameTransformers.CamelToLowerSnakeCase, ThrowOnPostFail = true, DefaultTags = new Dictionary <string, string> { { "host", NameTransformers.Sanitize(Environment.MachineName.ToLower()) }, { "client", "home" }, } }); _timer = _collector.CreateMetric <EventGauge>("GetWeather", "time taken", "measures time taken to get weather from api"); var dispatcherTimer = new Timer(); dispatcherTimer.Interval = 5000; dispatcherTimer.Start(); dispatcherTimer.Elapsed += new ElapsedEventHandler(timer_Elapsed); Console.ReadLine(); }
static async Task Main(string[] args) { //BenchmarkRunner.Run<Benchmark>(); //var x = 1; //if (x == 1) //{ // return; //} s_cancellationTokenSource = new CancellationTokenSource(); Debug.AutoFlush = true; const string LocalEndpointKey = "Local"; var localHandler = new LocalMetricHandler(); var options = new MetricsCollectorOptions(exception => { Console.WriteLine("Hey, there was an exception."); Console.WriteLine(exception); foreach (var key in exception.Data.Keys) { Console.WriteLine($"{key}={exception.Data[key]}"); } }) { Endpoints = new MetricEndpoint[] { //new MetricEndpoint(LocalEndpointKey, localHandler), //new MetricEndpoint("Test UDP", new TestUdpMetricHandler(s_cancellationTokenSource.Token) { MaxPayloadSize = 320 }), //new MetricEndpoint("Bosun (no URL)", new BosunMetricHandler(null)), //new MetricEndpoint("Bosun", new BosunMetricHandler(new Uri("http://devbosun.ds.stackexchange.com/"))), //new MetricEndpoint("SignalFx Agent", new SignalFxMetricHandler(new Uri("http://sfxgateway.signalfx.svc.ny-intkube.k8s.ds.stackexchange.com:18080"))), new MetricEndpoint("SignalFx StatsD Agent", new SignalFxMetricHandler(new Uri("udp://[::1]:8125")) { }), //new MetricEndpoint("SignalFx Cloud", new SignalFxMetricHandler(new Uri("https://ingest.us1.signalfx.com/"), "{API_KEY}")), //new MetricEndpoint("SignalFx Cloud (no URL)", new SignalFxMetricHandler(null, "{API_KEY}")), }, MetricsNamePrefix = "bosun.reporter.", ThrowOnPostFail = true, ThrowOnQueueFull = false, SnapshotInterval = TimeSpan.FromSeconds(10), PropertyToTagName = NameTransformers.CamelToLowerSnakeCase, TagValueConverter = (name, value) => name == "converted" ? value.ToLowerInvariant() : value, DefaultTags = new Dictionary <string, string> { { "host", NameTransformers.Sanitize(Environment.MachineName.ToLower()) } } }; var collector = new MetricsCollector(options); foreach (var endpoint in collector.Endpoints) { switch (endpoint.Handler) { case BosunMetricHandler bosunHandler: Console.WriteLine($"{endpoint.Name}: {bosunHandler.BaseUri?.AbsoluteUri ?? "null"}"); break; case SignalFxMetricHandler signalFxHandler: Console.WriteLine($"{endpoint.Name}: {signalFxHandler.BaseUri?.AbsoluteUri ?? "null"}"); break; } } collector.BeforeSerialization += () => Console.WriteLine("BosunReporter: Running metrics snapshot."); collector.AfterSerialization += info => Console.WriteLine($"BosunReporter: Metric Snapshot wrote {info.Count} metrics ({info.BytesWritten} bytes) to {info.Endpoint} in {info.Duration.TotalMilliseconds.ToString("0.##")}ms"); collector.AfterSend += info => { if (info.Endpoint == LocalEndpointKey) { foreach (var reading in localHandler.GetReadings()) { Console.WriteLine($"{reading.Name}{reading.Suffix}@{reading.Timestamp:s} {reading.Value}"); } } Console.WriteLine($"BosunReporter: Payload {info.PayloadType} - {info.BytesWritten} bytes posted to endpoint {info.Endpoint} in {info.Duration.TotalMilliseconds.ToString("0.##")}ms ({(info.Successful ? "SUCCESS" : "FAILED")})"); }; collector.BindMetric("my_counter", "increments", typeof(TestCounter)); var counter = collector.GetMetric <TestCounter>("my_counter", "increments", "This is meaningless."); counter.Increment(); counter.Increment(); var gauge = collector.CreateMetric("gauge", "watts", "Some description of a gauge.", new TestAggregateGauge("1")); if (gauge != collector.GetMetric("gauge", "watts", null, new TestAggregateGauge("1"))) { throw new Exception("WAT?"); } try { collector.CreateMetric("gauge", "watts", "Some description of a gauge.", new TestAggregateGauge("1")); } catch (Exception) { goto SKIP_EXCEPTION; } throw new Exception("CreateMetric should have failed for duplicate metric."); SKIP_EXCEPTION: var gauge2 = collector.GetMetric <CountGauge>("gauge2", "newtons", "Number of newtons currently applied."); for (var i = 0; i < 6; i++) { new Thread(Run).Start(new Tuple <AggregateGauge, AggregateGauge, int>(gauge, gauge2, i)); } var enumCounter = collector.GetMetricGroup <SomeEnum, EnumCounter>("some_enum", "things", "Some of something"); enumCounter.PopulateFromEnum(); Type t; string u; if (collector.TryGetMetricInfo("gauge2", out t, out u)) { Console.WriteLine(t); Console.WriteLine(u); } else { Console.WriteLine("NOOOOO!!!!!"); } var si = 0; var snapshot = collector.GetMetric("my_snapshot", "snappys", "Snap snap snap.", new SnapshotGauge(() => ++ si % 5)); var group = collector.GetMetricGroup <string, TestGroupGauge>("test_group", "tests", "These gauges are for testing."); group.Add("low").Description = "Low testing."; group.Add("medium").Description = "Medium testing."; group.Add("high").Description = "High testing."; var sampler = collector.GetMetric("sampler", "french fries", "Collect them all.", new SamplingGauge()); var eventGauge = collector.GetMetric("event", "count", "How many last time.", new EventGauge()); var converted = collector.CreateMetric("convert_test", "units", "Checking to see if the tag value converter works.", new ConvertedTagsTestCounter("ThingsAndStuff")); var noHost = collector.CreateMetric <ExcludeHostCounter>("no_host", "units", "Shouldn't have a host tag."); var externalCounter = collector.GetMetricGroup <SomeEnum, TestExternalCounter>("external.test", "units", "Should aggregate externally."); externalCounter.PopulateFromEnum(); // var externalNoTags = collector.CreateMetric<ExternalNoTagsCounter>("external.no_tags", "units", "Shouldn't have any tags except relay."); var lotsOfCounters = new List <Counter>(); for (var i = 0; i < 400; i++) { lotsOfCounters.Add(collector.GetMetric("counter_" + i, "counts", "Testing lots of counters", new Counter())); } var sai = 0; var random = new Random(); s_samplerTask = Task.Run(async() => { while (true) { await Task.Delay(100); sampler.Record(++sai % 35); eventGauge.Record(sai % 35); group["low"].Record(random.Next(0, 10)); group["medium"].Record(random.Next(10, 20)); group["high"].Record(random.Next(20, 30)); enumCounter[SomeEnum.One].Increment(); enumCounter[SomeEnum.Two].Increment(2); enumCounter[SomeEnum.Three].Increment(3); enumCounter[SomeEnum.Four].Increment(4); externalCounter[SomeEnum.One].Increment(); if (sai % 2 == 0) { externalCounter[SomeEnum.Two].Increment(); } if (sai % 3 == 0) { externalCounter[SomeEnum.Three].Increment(); } if (sai % 4 == 0) { externalCounter[SomeEnum.Four].Increment(); } foreach (var lotsOfCounter in lotsOfCounters) { lotsOfCounter.Increment(random.Next(0, 5)); } // externalNoTags.Increment(); converted.Increment(); noHost.Increment(); if (sai == 1000 || s_cancellationTokenSource.IsCancellationRequested) { collector.Shutdown(); break; } } }); Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) => { s_cancellationTokenSource.Cancel(); }; try { await s_samplerTask; } catch (TaskCanceledException) { // meh, ignore } }
static void Main(string[] args) { Debug.Listeners.Add(new TextWriterTraceListener(Console.Out)); Debug.AutoFlush = true; Func <Uri> getUrl = () => { return(new Uri("http://192.168.99.100:8070/")); // return new Uri("http://127.0.0.1:1337/"); }; // for testing minimum event threshold // AggregateGauge.GetDefaultMinimumEvents = () => 1306000; var options = new BosunOptions() { MetricsNamePrefix = "bret.", GetBosunUrl = getUrl, ThrowOnPostFail = true, ReportingInterval = 5, PropertyToTagName = NameTransformers.CamelToLowerSnakeCase, TagValueConverter = (name, value) => name == "converted" ? value.ToLowerInvariant() : value, DefaultTags = new Dictionary <string, string> { { "host", NameTransformers.Sanitize(Environment.MachineName.ToLower()) } } }; var collector = new MetricsCollector(options); collector.OnBackgroundException += exception => { Console.WriteLine("Hey, there was an exception."); Console.WriteLine(exception); }; collector.BeforeSerialization += () => Console.WriteLine("BosunReporter: Running metrics snapshot."); collector.AfterSerialization += info => Console.WriteLine($"BosunReporter: Metric Snapshot took {info.MillisecondsDuration.ToString("0.##")}ms"); collector.AfterPost += info => Console.WriteLine($"BosunReporter: {info.Count} metrics posted to Bosun in {info.MillisecondsDuration.ToString("0.##")}ms ({(info.Successful ? "SUCCESS" : "FAILED")})"); collector.BindMetric("my_counter", "increments", typeof(TestCounter)); var counter = collector.GetMetric <TestCounter>("my_counter", "increments", "This is meaningless."); counter.Increment(); counter.Increment(); var gauge = collector.CreateMetric("gauge", "watts", "Some description of a gauge.", new TestAggregateGauge("1")); if (gauge != collector.GetMetric("gauge", "watts", null, new TestAggregateGauge("1"))) { throw new Exception("WAT?"); } try { collector.CreateMetric("gauge", "watts", "Some description of a gauge.", new TestAggregateGauge("1")); } catch (Exception) { goto SKIP_EXCEPTION; } throw new Exception("CreateMetric should have failed for duplicate metric."); SKIP_EXCEPTION: var gauge2 = collector.GetMetric <AggregateGauge>("gauge2", "newtons", "Number of newtons currently applied."); for (var i = 0; i < 6; i++) { new Thread(Run).Start(new Tuple <AggregateGauge, AggregateGauge, int>(gauge, gauge2, i)); } var enumCounter = collector.GetMetricGroup <SomeEnum, EnumCounter>("some_enum", "things", "Some of something"); enumCounter.PopulateFromEnum(); Type t; string u; if (collector.TryGetMetricInfo("gauge2", out t, out u)) { Console.WriteLine(t); Console.WriteLine(u); } else { Console.WriteLine("NOOOOO!!!!!"); } var si = 0; var snapshot = collector.GetMetric("my_snapshot", "snappys", "Snap snap snap.", new SnapshotGauge(() => ++ si % 5)); var group = collector.GetMetricGroup <string, TestGroupGauge>("test_group", "tests", "These gauges are for testing."); group.Add("low").Description = "Low testing."; group.Add("medium").Description = "Medium testing."; group.Add("high").Description = "High testing."; var sampler = collector.GetMetric("sampler", "french fries", "Collect them all.", new SamplingGauge()); var eventGauge = collector.GetMetric("event", "count", "How many last time.", new EventGauge()); var converted = collector.CreateMetric("convert_test", "units", "Checking to see if the tag value converter works.", new ConvertedTagsTestCounter("ThingsAndStuff")); var noHost = collector.CreateMetric <ExcludeHostCounter>("no_host", "units", "Shouldn't have a host tag."); var externalCounter = collector.GetMetricGroup <SomeEnum, TestExternalCounter>("external.test", "units", "Should aggregate externally."); externalCounter.PopulateFromEnum(); // var externalNoTags = collector.CreateMetric<ExternalNoTagsCounter>("external.no_tags", "units", "Shouldn't have any tags except relay."); var sai = 0; var random = new Random(); _samplerTimer = new Timer(o => { sampler.Record(++sai % 35); eventGauge.Record(sai % 35); group["low"].Record(random.Next(0, 10)); group["medium"].Record(random.Next(10, 20)); group["high"].Record(random.Next(20, 30)); enumCounter[SomeEnum.One].Increment(); enumCounter[SomeEnum.Two].Increment(2); enumCounter[SomeEnum.Three].Increment(3); enumCounter[SomeEnum.Four].Increment(4); externalCounter[SomeEnum.One].Increment(); if (sai % 2 == 0) { externalCounter[SomeEnum.Two].Increment(); } if (sai % 3 == 0) { externalCounter[SomeEnum.Three].Increment(); } if (sai % 4 == 0) { externalCounter[SomeEnum.Four].Increment(); } // externalNoTags.Increment(); converted.Increment(); noHost.Increment(); if (sai == 40) { collector.Shutdown(); Environment.Exit(0); } }, null, 1000, 1000); Thread.Sleep(4000); collector.UpdateDefaultTags(new Dictionary <string, string> { { "host", NameTransformers.Sanitize(Environment.MachineName.ToLower()) } }); // Thread.Sleep(4000); // collector.UpdateDefaultTags(new Dictionary<string, string>() { { "host", "test_env" } }); }
static void Main(string[] args) { Debug.Listeners.Add(new TextWriterTraceListener(Console.Out)); Debug.AutoFlush = true; Func<Uri> getUrl = () => { return new Uri("http://192.168.99.100:8070/"); }; // for testing minimum event threshold // AggregateGauge.GetDefaultMinimumEvents = () => 306000; var options = new BosunOptions() { MetricsNamePrefix = "bret.", GetBosunUrl = getUrl, ThrowOnPostFail = true, ReportingInterval = 5, PropertyToTagName = NameTransformers.CamelToLowerSnakeCase, TagValueConverter = (name, value) => name == "converted" ? value.ToLowerInvariant() : value, DefaultTags = new Dictionary<string, string> { {"host", NameTransformers.Sanitize(Environment.MachineName.ToLower())} } }; var collector = new MetricsCollector(options); collector.OnBackgroundException += exception => { Console.WriteLine("Hey, there was an exception."); Console.WriteLine(exception); }; collector.BeforeSerialization += () => Debug.WriteLine("BosunReporter: Running metrics snapshot."); collector.AfterSerialization += info => Debug.WriteLine($"BosunReporter: Metric Snapshot took {info.MillisecondsDuration.ToString("0.##")}ms"); collector.AfterPost += info => Debug.WriteLine($"BosunReporter: {info.Count} metrics posted to Bosun in {info.MillisecondsDuration.ToString("0.##")}ms ({(info.Successful ? "SUCCESS" : "FAILED")})"); collector.BindMetric("my_counter", "increments", typeof(TestCounter)); var counter = collector.GetMetric<TestCounter>("my_counter", "increments", "This is meaningless."); counter.Increment(); counter.Increment(); var gauge = collector.CreateMetric("gauge", "watts", "Some description of a gauge.", new TestAggregateGauge("1")); if (gauge != collector.GetMetric("gauge", "watts", null, new TestAggregateGauge("1"))) throw new Exception("WAT?"); try { collector.CreateMetric("gauge", "watts", "Some description of a gauge.", new TestAggregateGauge("1")); } catch(Exception) { goto SKIP_EXCEPTION; } throw new Exception("CreateMetric should have failed for duplicate metric."); SKIP_EXCEPTION: var gauge2 = collector.GetMetric<AggregateGauge>("gauge2", "newtons", "Number of newtons currently applied."); for (var i = 0; i < 6; i++) { new Thread(Run).Start(new Tuple<AggregateGauge, AggregateGauge, int>(gauge, gauge2, i)); } var enumCounter = collector.GetMetricGroup<SomeEnum, EnumCounter>("some_enum", "things", "Some of something"); enumCounter.PopulateFromEnum(); Type t; string u; if (collector.TryGetMetricInfo("gauge2", out t, out u)) { Console.WriteLine(t); Console.WriteLine(u); } else { Console.WriteLine("NOOOOO!!!!!"); } var si = 0; var snapshot = collector.GetMetric("my_snapshot", "snappys", "Snap snap snap.", new SnapshotGauge(() => ++si % 5)); var group = collector.GetMetricGroup<string, TestGroupGauge>("test_group", "tests", "These gauges are for testing."); group.Add("low").Description = "Low testing."; group.Add("medium").Description = "Medium testing."; group.Add("high").Description = "High testing."; var sampler = collector.GetMetric("sampler", "french fries", "Collect them all.", new SamplingGauge()); var eventGauge = collector.GetMetric("event", "count", "How many last time.", new EventGauge()); var converted = collector.CreateMetric("convert_test", "units", "Checking to see if the tag value converter works.", new ConvertedTagsTestCounter("ThingsAndStuff")); var sai = 0; var random = new Random(); _samplerTimer = new Timer(o => { sampler.Record(++sai%35); eventGauge.Record(sai%35); group["low"].Record(random.Next(0, 10)); group["medium"].Record(random.Next(10, 20)); group["high"].Record(random.Next(20, 30)); enumCounter[SomeEnum.One].Increment(); enumCounter[SomeEnum.Two].Increment(2); enumCounter[SomeEnum.Three].Increment(3); enumCounter[SomeEnum.Four].Increment(4); converted.Increment(); if (sai == 40) { collector.Shutdown(); Environment.Exit(0); } }, null, 1000, 1000); Thread.Sleep(4000); collector.UpdateDefaultTags(new Dictionary<string, string> { { "host", NameTransformers.Sanitize(Environment.MachineName.ToLower()) } }); // Thread.Sleep(4000); // collector.UpdateDefaultTags(new Dictionary<string, string>() { { "host", "test_env" } }); }
public async Task FailedSend_OnlyAffectsFailedHandler() { var completionEvent = new ManualResetEventSlim(false); var failHandler = new TestMetricHandler( (_, __, ___) => throw new MetricPostException(new Exception("Boom!")) ) { MaxPayloadCount = 10 }; var successHandler = new TestMetricHandler( async(handler, type, sequence) => { if (type != PayloadType.Counter) { return; } Assert.Equal(PayloadType.Counter, type); using (var memoryStream = new MemoryStream()) { await memoryStream.WriteAsync(sequence); // verify that the bytes written to the stream match what we received var actualBytes = memoryStream.ToArray(); var expectedBytes = handler.GetNextWrittenChunk(PayloadType.Counter); while (expectedBytes.Length < actualBytes.Length) { // collect bytes until we have no more to get expectedBytes = expectedBytes.Concat(handler.GetNextWrittenChunk(PayloadType.Counter)).ToArray(); } Assert.Equal(expectedBytes, actualBytes); } if (!handler.HasPendingChunks(PayloadType.Counter)) { completionEvent.Set(); } } ) { MaxPayloadCount = 1000 }; var collector = new MetricsCollector( new MetricsCollectorOptions(_ => { }) { DefaultTags = new Dictionary <string, string> { ["host"] = Environment.MachineName }, Endpoints = new[] { new MetricEndpoint("Failed", failHandler), new MetricEndpoint("Success", successHandler) }, SnapshotInterval = TimeSpan.FromMilliseconds(20), RetryInterval = TimeSpan.Zero } ); var metrics = new Counter[10]; for (var i = 0; i < metrics.Length; i++) { metrics[i] = collector.CreateMetric <Counter>("metric_" + i, "requests", string.Empty); } // report some metrics foreach (var metric in metrics) { metric.Increment(); // waiting for the snapshot interval before we send out next batch of data await Task.Delay(20); } // give some time for everything to complete var completed = completionEvent.Wait(TimeSpan.FromMilliseconds(2000)); var pendingEvents = successHandler.GetPendingChunks(PayloadType.Counter); collector.Shutdown(); Assert.True(completed, $"Success handler did not complete successfully. {pendingEvents} pending"); } }