Example #1
0
        public MetricsCollector(BosunOptions options)
        {
            MetricsNamePrefix = options.MetricsNamePrefix ?? "";
            if (MetricsNamePrefix != "" && !BosunValidation.IsValidMetricName(MetricsNamePrefix))
            {
                throw new Exception("\"" + MetricsNamePrefix + "\" is not a valid metric name prefix.");
            }

            GetBosunUrl       = options.GetBosunUrl;
            BosunUrl          = GetBosunUrl == null ? options.BosunUrl : GetBosunUrl();
            MaxQueueLength    = options.MaxQueueLength;
            BatchSize         = options.BatchSize;
            ThrowOnPostFail   = options.ThrowOnPostFail;
            ThrowOnQueueFull  = options.ThrowOnQueueFull;
            ReportingInterval = options.ReportingInterval;
            PropertyToTagName = options.PropertyToTagName;
            TagValueConverter = options.TagValueConverter;
            DefaultTags       = ValidateDefaultTags(options.DefaultTags);

            // start continuous queue-flushing
            _flushTimer = new Timer(Flush, true, 1000, 1000);

            // start reporting timer
            var interval = TimeSpan.FromSeconds(ReportingInterval);

            _reportingTimer = new Timer(Snapshot, true, interval, interval);

            // metadata timer - wait 30 seconds to start (so there is some time for metrics to be delcared)
            if (options.MetaDataReportingInterval > 0)
            {
                _metaDataTimer = new Timer(PostMetaData, true, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(options.MetaDataReportingInterval));
            }
        }
        /// <summary>
        /// Instantiates a new collector (the primary class of BosunReporter). You should typically only instantiate one collector for the lifetime of your
        /// application. It will manage the serialization of metrics and sending data to Bosun.
        /// </summary>
        /// <param name="options"></param>
        /// <param name="exceptionHandler"></param>
        public MetricsCollector(BosunOptions options, Action <Exception> exceptionHandler)
        {
            if (exceptionHandler == null)
            {
                throw new ArgumentNullException(nameof(exceptionHandler));
            }

            ExceptionHandler = exceptionHandler;

            _localMetricsQueue    = new PayloadQueue(QueueType.Local);
            _externalCounterQueue = new PayloadQueue(QueueType.ExternalCounters);

            _localMetricsQueue.PayloadDropped    += OnPayloadDropped;
            _externalCounterQueue.PayloadDropped += OnPayloadDropped;

            // these two setters actually update the queues themselves
            MaxPayloadSize     = options.MaxPayloadSize;
            MaxPendingPayloads = options.MaxPendingPayloads;

            MetricsNamePrefix = options.MetricsNamePrefix ?? "";
            if (MetricsNamePrefix != "" && !BosunValidation.IsValidMetricName(MetricsNamePrefix))
            {
                throw new Exception("\"" + MetricsNamePrefix + "\" is not a valid metric name prefix.");
            }

            GetBosunUrl = options.GetBosunUrl;
            BosunUrl    = GetBosunUrl == null ? options.BosunUrl : GetBosunUrl();

            _accessToken    = options.AccessToken;
            _getAccessToken = options.GetAccessToken;

            ThrowOnPostFail        = options.ThrowOnPostFail;
            ThrowOnQueueFull       = options.ThrowOnQueueFull;
            ReportingInterval      = options.ReportingInterval;
            EnableExternalCounters = options.EnableExternalCounters;
            PropertyToTagName      = options.PropertyToTagName;
            TagValueConverter      = options.TagValueConverter;
            DefaultTags            = ValidateDefaultTags(options.DefaultTags);

            // start continuous queue-flushing
            _flushTimer = new Timer(Flush, true, 1000, 1000);

            // start reporting timer
            var interval = TimeSpan.FromSeconds(ReportingInterval);

            _reportingTimer = new Timer(Snapshot, true, interval, interval);

            // metadata timer - wait 30 seconds to start (so there is some time for metrics to be delcared)
            if (options.MetaDataReportingInterval > 0)
            {
                _metaDataTimer = new Timer(PostMetaData, true, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(options.MetaDataReportingInterval));
            }
        }
Example #3
0
        /// <summary>
        /// Instantiates a new collector (the primary class of BosunReporter). You should typically only instantiate one collector for the lifetime of your
        /// application. It will manage the serialization of metrics and sending data to Bosun.
        /// </summary>
        /// <param name="options"></param>
        public MetricsCollector(BosunOptions options)
        {
            ExceptionHandler = options.ExceptionHandler;

            if (options.SnapshotInterval < TimeSpan.FromSeconds(1))
            {
                throw new InvalidOperationException("options.SnapshotInterval cannot be less than one second");
            }

            _localMetricsQueue    = new PayloadQueue(QueueType.Local);
            _externalCounterQueue = new PayloadQueue(QueueType.ExternalCounters);

            _localMetricsQueue.PayloadDropped    += OnPayloadDropped;
            _externalCounterQueue.PayloadDropped += OnPayloadDropped;

            // these two setters actually update the queues themselves
            MaxPayloadSize     = options.MaxPayloadSize;
            MaxPendingPayloads = options.MaxPendingPayloads;

            MetricsNamePrefix = options.MetricsNamePrefix ?? "";
            if (MetricsNamePrefix != "" && !BosunValidation.IsValidMetricName(MetricsNamePrefix))
            {
                throw new Exception("\"" + MetricsNamePrefix + "\" is not a valid metric name prefix.");
            }

            _getUrlDynamic = options.GetBosunUrl;
            _fixedUrl      = options.BosunUrl;

            _accessToken    = options.AccessToken;
            _getAccessToken = options.GetAccessToken;

            ThrowOnPostFail        = options.ThrowOnPostFail;
            ThrowOnQueueFull       = options.ThrowOnQueueFull;
            ReportingInterval      = options.SnapshotInterval;
            EnableExternalCounters = options.EnableExternalCounters;
            PropertyToTagName      = options.PropertyToTagName;
            TagValueConverter      = options.TagValueConverter;
            DefaultTags            = ValidateDefaultTags(options.DefaultTags);

            // start continuous queue-flushing
            _flushTimer = new Timer(Flush, true, 1000, 1000);

            // start reporting timer
            _reportingTimer = new Timer(Snapshot, true, ReportingInterval, ReportingInterval);
        }
Example #4
0
        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" } });
        }