private WavefrontAspNetCoreReporter(IMetricsRoot metrics, IWavefrontSender wavefrontSender,
                                     ApplicationTags applicationTags, string source)
 {
     Metrics         = metrics;
     WavefrontSender = wavefrontSender;
     ApplicationTags = applicationTags;
     Source          = source;
 }
 private WavefrontSpanReporter(IWavefrontSender wavefrontSender, string source,
                               int maxQueueSize, double logPercent, bool reportSpanLogs, ILoggerFactory loggerFactory)
 {
     WavefrontSender     = wavefrontSender;
     Source              = source;
     spanBuffer          = new BlockingCollection <WavefrontSpan>(maxQueueSize);
     random              = new Random();
     this.logPercent     = logPercent;
     logger              = loggerFactory.CreateLogger <WavefrontSpanReporter>();
     sendTask            = Task.Factory.StartNew(SendLoop, TaskCreationOptions.LongRunning);
     this.reportSpanLogs = reportSpanLogs;
 }
Exemple #3
0
        private void ConfigureWavefront(IServiceCollection services)
        {
            var appTagsConfig = new ConfigurationBuilder()
                                .AddYamlFile(Path.Combine(env.ContentRootPath, Configuration["applicationTagsYamlFile"]))
                                .Build();
            ApplicationTags applicationTags = ConstructApplicationTags(appTagsConfig);

            var wfReportingConfig = new ConfigurationBuilder()
                                    .AddYamlFile(Path.Combine(env.ContentRootPath, Configuration["wfReportingConfigYamlFile"]))
                                    .Build();

            string source = wfReportingConfig["source"];

            if (string.IsNullOrWhiteSpace(source))
            {
                source = Dns.GetHostName();
            }

            IWavefrontSender wavefrontSender = ConstructWavefrontSender(wfReportingConfig);

            WavefrontAspNetCoreReporter wfAspNetCoreReporter = new WavefrontAspNetCoreReporter
                                                               .Builder(applicationTags)
                                                               .WithSource(source)
                                                               .Build(wavefrontSender);

            ITracer tracer;

            if (wfReportingConfig.GetValue <bool>("reportTraces"))
            {
                WavefrontSpanReporter wavefrontSpanReporter = new WavefrontSpanReporter
                                                              .Builder()
                                                              .WithSource(source)
                                                              .Build(wavefrontSender);
                var consoleReporter   = new ConsoleReporter(source);
                var compositeReporter = new CompositeReporter(wavefrontSpanReporter, consoleReporter);
                tracer = new WavefrontTracer
                         .Builder(compositeReporter, applicationTags)
                         .Build();
            }
            else
            {
                tracer = null;
            }

            services.AddWavefrontForMvc(wfAspNetCoreReporter, tracer);
        }
        private WavefrontAspNetCoreReporter(IMetricsRoot metrics, IWavefrontSender wavefrontSender,
                                            ApplicationTags applicationTags, string source)
        {
            Metrics            = metrics;
            WavefrontSender    = wavefrontSender;
            ApplicationTags    = applicationTags;
            Source             = source;
            sdkMetricsRegistry = new WavefrontSdkMetricsRegistry
                                 .Builder(wavefrontSender)
                                 .Prefix(SdkMetricPrefix + ".aspnetcore")
                                 .Source(source)
                                 .Tags(applicationTags.ToPointTags())
                                 .Build();
            double sdkVersion = Utils.GetSemVer(Assembly.GetExecutingAssembly());

            sdkMetricsRegistry.Gauge("version", () => sdkVersion);
        }
        /// <summary>
        ///     Add the <see cref="WavefrontReporter" /> allowing metrics to be reported to
        ///     Wavefront.
        /// </summary>
        /// <param name="metricReporterProviderBuilder">
        ///     The <see cref="IMetricsReportingBuilder" /> used to configure metrics reporters.
        /// </param>
        /// <param name="wavefrontSender">
        ///     The <see cref="IWavefrontSender" /> that handles the formatting and flushing of
        ///     metrics to Wavefront, either via direct ingestion or the Wavefront Proxy Agent.
        /// </param>
        /// <returns>
        ///     An <see cref="IMetricsBuilder" /> that can be used to further configure App Metrics.
        /// </returns>
        public static IMetricsBuilder ToWavefront(
            this IMetricsReportingBuilder metricReporterProviderBuilder,
            IWavefrontSender wavefrontSender)
        {
            if (metricReporterProviderBuilder == null)
            {
                throw new ArgumentNullException(nameof(metricReporterProviderBuilder));
            }

            var options = new MetricsReportingWavefrontOptions
            {
                WavefrontSender = wavefrontSender
            };

            var provider = new WavefrontReporter(options);

            return(metricReporterProviderBuilder.Using(provider));
        }
            /// <summary>
            ///     Builds a <see cref="WavefrontAspNetCoreReporter"/>.
            /// </summary>
            /// <returns>The <see cref="WavefrontAspNetCoreReporter"/> instance.</returns>
            /// <param name="wavefrontSender">
            ///     The Wavefront sender instance that handles the sending of data to Wavefront,
            ///     via either Wavefront proxy or direct ingestion.
            /// </param>
            public WavefrontAspNetCoreReporter Build(IWavefrontSender wavefrontSender)
            {
                source = string.IsNullOrWhiteSpace(source) ? Utils.GetDefaultSource() : source;

                var globalTags = new Dictionary <string, string>
                {
                    { ApplicationTagKey, applicationTags.Application }
                };

                if (applicationTags.CustomTags != null)
                {
                    foreach (var customTag in applicationTags.CustomTags)
                    {
                        if (!globalTags.ContainsKey(customTag.Key))
                        {
                            globalTags.Add(customTag.Key, customTag.Value);
                        }
                    }
                }

                var metrics = new MetricsBuilder()
                              .Configuration.Configure(
                    options =>
                {
                    options.DefaultContextLabel = AspNetCoreContext;
                    options.GlobalTags          = new GlobalMetricTags(globalTags);
                })
                              .Report.ToWavefront(
                    options =>
                {
                    options.WavefrontSender = wavefrontSender;
                    options.Source          = source;
                    options.WavefrontHistogram.ReportMinuteDistribution = true;
                    options.FlushInterval = TimeSpan.FromSeconds(reportingIntervalSeconds);
                })
                              .Build();

                return(new WavefrontAspNetCoreReporter(
                           metrics, wavefrontSender, applicationTags, source));
            }
Exemple #7
0
        public MetricSnapshotWavefrontWriter(
            IWavefrontSender wavefrontSender,
            string source,
            IDictionary <string, string> globalTags,
            ISet <HistogramGranularity> histogramGranularities,
            WavefrontSdkMetricsRegistry sdkMetricsRegistry,
            MetricFields fields)
        {
            this.wavefrontSender        = wavefrontSender;
            this.source                 = source;
            this.globalTags             = globalTags;
            this.histogramGranularities = histogramGranularities;
            this.fields                 = fields;

            gaugesReported        = sdkMetricsRegistry.Counter("gauges.reported");
            deltaCountersReported = sdkMetricsRegistry.Counter("delta_counters.reported");
            countersReported      = sdkMetricsRegistry.Counter("counters.reported");
            wfHistogramsReported  = sdkMetricsRegistry.Counter("wavefront_histograms.reported");
            histogramsReported    = sdkMetricsRegistry.Counter("histograms.reported");
            metersReported        = sdkMetricsRegistry.Counter("meters.reported");
            timersReported        = sdkMetricsRegistry.Counter("timers.reported");
            apdexesReported       = sdkMetricsRegistry.Counter("apdexes.reported");
            writerErrors          = sdkMetricsRegistry.Counter("writer.errors");
        }
 /// <summary>
 ///     Builds and returns a <see cref="WavefrontSpanReporter"/> for sending
 ///     OpenTracing spans to an <see cref="IWavefrontSender"/> that can send to
 ///     Wavefront via either proxy or direct ingestion.
 /// </summary>
 /// <returns>A <see cref="WavefrontSpanReporter"/>.</returns>
 /// <param name="wavefrontSender">The Wavefront sender.</param>
 public WavefrontSpanReporter Build(IWavefrontSender wavefrontSender)
 {
     return(new WavefrontSpanReporter(wavefrontSender, source, maxQueueSize, logPercent,
                                      reportSpanLogs, loggerFactory ?? Logging.LoggerFactory));
 }
        public WavefrontReporter(MetricsReportingWavefrontOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            if (options.WavefrontSender == null)
            {
                throw new ArgumentNullException(
                          nameof(MetricsReportingWavefrontOptions.WavefrontSender));
            }

            wavefrontSender = options.WavefrontSender;

            source = options.Source;

            if (options.ApplicationTags != null)
            {
                globalTags = new Dictionary <string, string>(options.ApplicationTags.ToPointTags());
            }
            else
            {
                globalTags = new Dictionary <string, string>();
            }

            histogramGranularities = new HashSet <HistogramGranularity>();
            if (options.WavefrontHistogram.ReportMinuteDistribution)
            {
                histogramGranularities.Add(HistogramGranularity.Minute);
            }
            if (options.WavefrontHistogram.ReportHourDistribution)
            {
                histogramGranularities.Add(HistogramGranularity.Hour);
            }
            if (options.WavefrontHistogram.ReportDayDistribution)
            {
                histogramGranularities.Add(HistogramGranularity.Day);
            }

            if (options.FlushInterval < TimeSpan.Zero)
            {
                throw new InvalidOperationException(
                          $"{nameof(MetricsReportingWavefrontOptions.FlushInterval)} " +
                          "must not be less than zero");
            }

            Filter = options.Filter;

            FlushInterval = options.FlushInterval > TimeSpan.Zero
                ? options.FlushInterval
                : AppMetricsConstants.Reporting.DefaultFlushInterval;

            // Formatting will be handled by the Wavefront sender.
            Formatter = null;

            metricFields = options.MetricFields ?? new MetricFields();

            var registryBuilder = new WavefrontSdkMetricsRegistry.Builder(wavefrontSender)
                                  .Prefix(Constants.SdkMetricPrefix + ".app_metrics")
                                  .Source(source)
                                  .Tags(globalTags);

            if (options.LoggerFactory != null)
            {
                registryBuilder.LoggerFactory(options.LoggerFactory);
            }
            sdkMetricsRegistry = registryBuilder.Build();

            reporterErrors = sdkMetricsRegistry.Counter("reporter.errors");

            double sdkVersion = Utils.GetSemVer(Assembly.GetExecutingAssembly());

            sdkMetricsRegistry.Gauge("version", () => sdkVersion);

            Logger.Info($"Using Wavefront Reporter {this}. FlushInterval: {FlushInterval}");
        }
Exemple #10
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            //Begin code instrumentation - reference https://github.com/wavefrontHQ/wavefront-opentracing-sdk-csharp
            //The application, service, cluster, and shard variables are all metadata to be added to each span created.
            string application = "VMworld2020Demo";
            string service     = "GlobalDataAggregator";
            string cluster     = "Azure";
            string shard       = "networknerd4";

            //The URL and token are for direct ingestion of metrics, traces, and spans (no proxy in use here).
            //The API token can be found inside the Tanzu Observability (Wavefront) web UI and is unique to your environment.  Click the gear icon in the upper right, click your e-mail address, and then select API Access.
            string wfURL = "https://vmware.wavefront.com";
            string token = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";

            // Create ApplicationTags - for tracing purposes
            ApplicationTags applicationTags = new ApplicationTags.Builder(application, service).Cluster(cluster).Shard(shard).Build();

            //Configure a MetricsBuilder object - for custom metrics sent via the Metrics SDK
            var MyMetricsBuilder = new MetricsBuilder();

            //Initialize WavefrontDirectIngestionClient
            WavefrontDirectIngestionClient.Builder wfDirectIngestionClientBuilder = new WavefrontDirectIngestionClient.Builder(wfURL, token);

            // Create an IWavefrontSender instance for sending data via direct ingestion.
            IWavefrontSender wavefrontSender = wfDirectIngestionClientBuilder.Build();

            //Configure MeetricsBuilder to Report to Wavefront with proper sender object and source tag specified.  In this case my source is the function name.
            MyMetricsBuilder.Report.ToWavefront(
                options =>
            {
                options.WavefrontSender = wavefrontSender;
                options.Source          = "TruckGlobalDataAggregator";
            });

            //Build IMetrics instance
            var MyMetrics = MyMetricsBuilder.Build();

            //These are arrays for key value pairs to add as metric tags.  You can add some or many here as you instrument your code.
            string[] keys = new string[3] {
                "FunctionApp", "Cloud", "Region"
            };
            string[] values = new string[3] {
                "networknerd4", "Azure", "Central-US"
            };

            // Configure and instantiate a DeltaCounter using DeltaCounterOptions.Builder.  The metric name is azure.function.execution.deltacounter.
            var myDeltaCounter = new DeltaCounterOptions.Builder("azure.function.execution.deltacounter").MeasurementUnit(Unit.Calls).Tags(new MetricTags(keys, values)).Build();

            // Increment the counter by 1
            MyMetrics.Measure.Counter.Increment(myDeltaCounter);

            //Force reporting all custom metrics
            await Task.WhenAll(MyMetrics.ReportRunner.RunAllAsync());


            //Create a WavefrontSpanReporter for reporting trace data that originates on <sourceName>.  The source is the function name in this case.
            IReporter wfSpanReporter = new WavefrontSpanReporter.Builder()
                                       .WithSource("TruckGlobalDataAggregator").Build(wavefrontSender);

            //Create CompositeReporter and ConsoleReporter objects for more OpenTracing metrics
            IReporter consoleReporter   = new ConsoleReporter("TruckGlobalDataAggregator");
            IReporter compositeReporter = new CompositeReporter(wfSpanReporter, consoleReporter);

            //Create the WavefrontTracer.
            WavefrontTracer MyTracer = new WavefrontTracer.Builder(wfSpanReporter, applicationTags).Build();

            //The variable MyDictionary is needed to extract span context in case a call is made from another function / outside this function.
            IDictionary <string, string> MyDictionary = new Dictionary <string, string>();

            foreach (var entry in req.Headers)
            {
                MyDictionary.TryAdd(entry.Key, entry.Value);
            }

            //Attempt to pull span fontext from HTTP headers passed into this function to continue a span across environments.  The proper context will be loaded into the variable
            //ctx if so.  The second line of code loads all metadata from the span context.
            ITextMap carrier = new TextMapExtractAdapter(MyDictionary);

            OpenTracing.ISpanContext ctx            = MyTracer.Extract(BuiltinFormats.HttpHeaders, carrier);
            OpenTracing.IScope       receivingScope = MyTracer.BuildSpan("TruckGlobalDataAggregator.Execute").AsChildOf(ctx).StartActive(true);

            //Start building a new span called TruckGlobalDataAggregator.Execute if there was no context passed into headers.
            if (MyTracer.ActiveSpan != null)
            {
                MyTracer.BuildSpan("TruckGlobalDataAggregator.Execute").StartActive();
            }

            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string  requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data        = JsonConvert.DeserializeObject(requestBody);

            name = name ?? data?.name;

            //Add function execution delays based on input - for personal testing only.
            if (string.Equals(name, "0.5"))
            {
                await Task.Delay(500);
            }
            if (string.Equals(name, "1"))
            {
                await Task.Delay(1000);
            }
            if (string.Equals(name, "1.5"))
            {
                await Task.Delay(1500);
            }
            if (string.Equals(name, "2"))
            {
                await Task.Delay(2000);
            }

            string responseMessage = string.IsNullOrEmpty(name)
                ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                : $"Hello, {name}. This HTTP triggered function executed successfully.";

            //Finish the span
            MyTracer.ActiveSpan.Finish();

            //Close the tracer before application exit
            MyTracer.Close();

            return(new OkObjectResult(responseMessage));
        }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            //Begin code instrumentation - reference https://github.com/wavefrontHQ/wavefront-appmetrics-sdk-csharp
            //The URL and token are for direct ingestion of metrics (no proxy in use here).
            //The API token can be found inside the Tanzu Observability (Wavefront) web UI and is unique to your environment.  Click the gear icon in the upper right, click your e-mail address, and then select API Access.
            string wfURL = "https://vmware.wavefront.com";
            string token = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";

            //Configure a MetricsBuilder object
            var MyMetricsBuilder = new MetricsBuilder();

            //Initialize WavefrontDirectIngestionClient
            WavefrontDirectIngestionClient.Builder wfDirectIngestionClientBuilder = new WavefrontDirectIngestionClient.Builder(wfURL, token);

            // Create an IWavefrontSender instance for sending data via direct ingestion.
            IWavefrontSender wavefrontSender = wfDirectIngestionClientBuilder.Build();

            //Configure MeetricsBuilder to Report to Wavefront with proper sender object and source tag specified.  In this case my source is the function name.
            MyMetricsBuilder.Report.ToWavefront(
                options =>
            {
                options.WavefrontSender = wavefrontSender;
                options.Source          = "TruckWorkflowAnalytics";
            });

            //Build IMetrics instance
            var MyMetrics = MyMetricsBuilder.Build();

            //These are arrays for key value pairs to add as metric tags.  You can add some or many here as you instrument your code.
            string[] keys = new string[3] {
                "FunctionApp", "Cloud", "Region"
            };
            string[] values = new string[3] {
                "networknerd5", "Azure", "Central-US"
            };

            // Configure and instantiate a DeltaCounter using DeltaCounterOptions.Builder.  The metric name is azure.function.execution.deltacounter.
            var myDeltaCounter = new DeltaCounterOptions.Builder("azure.function.execution.deltacounter").MeasurementUnit(Unit.Calls).Tags(new MetricTags(keys, values)).Build();

            // Increment the delta counter by 1
            MyMetrics.Measure.Counter.Increment(myDeltaCounter);

            //Force reporting all metrics
            //end of code instrumentation for metrics
            await Task.WhenAll(MyMetrics.ReportRunner.RunAllAsync());

            //Begin default template code from the HTTP trigger function template as part of the Azure Functions Extension for C#.
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string  requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data        = JsonConvert.DeserializeObject(requestBody);

            name = name ?? data?.name;

            //Add function execution delays based on input (for my own testing only).
            if (string.Equals(name, "0.5"))
            {
                await Task.Delay(500);
            }
            if (string.Equals(name, "1"))
            {
                await Task.Delay(1000);
            }
            if (string.Equals(name, "1.5"))
            {
                await Task.Delay(1500);
            }
            if (string.Equals(name, "2"))
            {
                await Task.Delay(2000);
            }

            string responseMessage = string.IsNullOrEmpty(name)
                ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                : $"Hello, {name}. This HTTP triggered function executed successfully.";

            return(new OkObjectResult(responseMessage));
        }
 private WavefrontSpanReporter(IWavefrontSender wavefrontSender, string source)
 {
     this.wavefrontSender = wavefrontSender;
     this.source          = source;
 }
 /// <summary>
 ///     Builds and returns a <see cref="WavefrontSpanReporter"/> for sending
 ///     OpenTracing spans to an <see cref="IWavefrontSender"/> that can send to
 ///     Wavefront via either proxy or direct ingestion.
 /// </summary>
 /// <returns>A <see cref="WavefrontSpanReporter"/>.</returns>
 /// <param name="wavefrontSender">The Wavefront sender.</param>
 public WavefrontSpanReporter Build(IWavefrontSender wavefrontSender)
 {
     return(new WavefrontSpanReporter(wavefrontSender, source));
 }