public void TestApplicationTags()
        {
            var customTags = new Dictionary <string, string>
            {
                { "customTag1", "customValue1" },
                { "customTag2", "customValue2" }
            };
            var applicationTags =
                new ApplicationTags.Builder("myApplication", "myServDefaultSource")
                .Cluster("myCluster")
                .Shard("myShard")
                .CustomTags(customTags)
                .Build();
            var tracer = new WavefrontTracer
                         .Builder(new ConsoleReporter(DefaultSource), applicationTags)
                         .Build();
            var span = (WavefrontSpan)tracer.BuildSpan("testOp").Start();

            Assert.NotNull(span);
            var spanTags = span.GetTagsAsMap();

            Assert.NotNull(spanTags);
            Assert.Equal(6, spanTags.Count);
            Assert.Contains(applicationTags.Application, spanTags[ApplicationTagKey]);
            Assert.Contains(applicationTags.Service, spanTags[ServiceTagKey]);
            Assert.Contains(applicationTags.Cluster, spanTags[ClusterTagKey]);
            Assert.Contains(applicationTags.Shard, spanTags[ShardTagKey]);
            Assert.Contains("customValue1", spanTags["customTag1"]);
            Assert.Contains("customValue2", spanTags["customTag2"]);
        }
Example #2
0
        public static IServiceCollection AddWavefrontProxy(this IServiceCollection services, IConfiguration configuration)
        {
            var waveFrontProxyConfiguration =
                configuration.GetSection(WavefrontProxyOptions.WavefrontProxy).Get <WavefrontProxyOptions>();

            var wfProxyClientBuilder = new WavefrontProxyClient.Builder(waveFrontProxyConfiguration.Hostname);

            wfProxyClientBuilder.MetricsPort(waveFrontProxyConfiguration.Port);
            wfProxyClientBuilder.DistributionPort(waveFrontProxyConfiguration.DistributionPort);
            wfProxyClientBuilder.TracingPort(waveFrontProxyConfiguration.TracingPort);
            wfProxyClientBuilder.FlushIntervalSeconds(waveFrontProxyConfiguration.TracingPort);
            var wavefrontSender = wfProxyClientBuilder.Build();

            var applicationTags = new ApplicationTags.Builder(waveFrontProxyConfiguration.Application, waveFrontProxyConfiguration.Service)
                                  .Cluster(waveFrontProxyConfiguration.Cluster)
                                  .Shard(waveFrontProxyConfiguration.Shard)
                                  .Build();

            var wfAspNetCoreReporter = new WavefrontAspNetCoreReporter.Builder(applicationTags)
                                       .WithSource(waveFrontProxyConfiguration.Source)
                                       .ReportingIntervalSeconds(waveFrontProxyConfiguration.ReportingIntervalSeconds)
                                       .Build(wavefrontSender);

            System.Console.WriteLine(wfAspNetCoreReporter);

            var wavefrontSpanReporter = new WavefrontSpanReporter.Builder()
                                        .Build(wavefrontSender);

            ITracer tracer = new WavefrontTracer.Builder(wavefrontSpanReporter, applicationTags).Build();

            services.AddWavefrontForMvc(wfAspNetCoreReporter, tracer);

            return(services);
        }
Example #3
0
        public static IServiceCollection AddWavefrontDirectIngestion(this IServiceCollection services, IConfiguration configuration)
        {
            var waveFrontDirectIngestionConfiguration =
                configuration.GetSection(WavefrontDirectIngestionOptions.WavefrontDirectIngestion)
                .Get <WavefrontDirectIngestionOptions>();

            var applicationTags =
                new ApplicationTags.Builder(waveFrontDirectIngestionConfiguration.Application, waveFrontDirectIngestionConfiguration.Service)
                .Cluster(waveFrontDirectIngestionConfiguration.Cluster)
                .Shard(waveFrontDirectIngestionConfiguration.Shard)
                .Build();

            var wfDirectIngestionClientBuilder = new WavefrontDirectIngestionClient.Builder(waveFrontDirectIngestionConfiguration.Hostname, waveFrontDirectIngestionConfiguration.Token);

            wfDirectIngestionClientBuilder.MaxQueueSize(waveFrontDirectIngestionConfiguration.MaxQueueSize);
            wfDirectIngestionClientBuilder.BatchSize(waveFrontDirectIngestionConfiguration.BatchSize);
            wfDirectIngestionClientBuilder.FlushIntervalSeconds(waveFrontDirectIngestionConfiguration.FlushIntervalSeconds);
            var wavefrontSender = wfDirectIngestionClientBuilder.Build();

            var wfAspNetCoreReporter = new WavefrontAspNetCoreReporter.Builder(applicationTags)
                                       .WithSource(waveFrontDirectIngestionConfiguration.Source)
                                       .ReportingIntervalSeconds(waveFrontDirectIngestionConfiguration.ReportingIntervalSeconds)
                                       .Build(wavefrontSender);

            var wavefrontSpanReporter = new WavefrontSpanReporter.Builder()
                                        .Build(wavefrontSender);

            ITracer tracer = new WavefrontTracer.Builder(wavefrontSpanReporter, applicationTags).Build();

            services.AddWavefrontForMvc(wfAspNetCoreReporter, tracer);

            return(services);
        }
        public void TestTagFromEnv()
        {
            SetEnvVar();
            var pointTags = new ApplicationTags.Builder("app1", "service1")
                            .CustomTags(new Dictionary <string, string>
            {
                { "env", "production" },
                { "location", "SF" }
            })
                            .tagFromEnv("VERSION", "ver")
                            .Build()
                            .ToPointTags();

            Assert.Contains(new KeyValuePair <string, string>("env", "production"), pointTags);
            Assert.Contains(new KeyValuePair <string, string>("location", "SF"), pointTags);
            Assert.Contains(new KeyValuePair <string, string>("ver", "1.0"), pointTags);
        }
Example #5
0
        private ApplicationTags ConstructApplicationTags(IConfiguration appTagsConfig)
        {
            var appTagsBuilder = new ApplicationTags
                                 .Builder(appTagsConfig["application"], appTagsConfig["service"])
                                 .Cluster(appTagsConfig["cluster"])
                                 .Shard(appTagsConfig["shard"]);

            var customTagsConfig = appTagsConfig.GetSection("CustomTags");
            var customTagsDict   = new Dictionary <string, string>();

            foreach (var tag in customTagsConfig.GetChildren())
            {
                customTagsDict.Add(tag.Key, tag.Value);
            }
            appTagsBuilder.CustomTags(customTagsDict);

            return(appTagsBuilder.Build());
        }
        public void TestTagsFromEnv()
        {
            SetEnvVar();
            var pointTags = new ApplicationTags.Builder("app1", "service1")
                            .CustomTags(new Dictionary <string, string>
            {
                { "env", "production" },
                { "location", "SF" }
            })
                            .tagsFromEnv("^MY.*$")
                            .Build()
                            .ToPointTags();

            Assert.Contains(new KeyValuePair <string, string>("env", "production"), pointTags);
            Assert.Contains(new KeyValuePair <string, string>("location", "SF"), pointTags);
            Assert.Contains(new KeyValuePair <string, string>("my_var1", "var_value1"), pointTags);
            Assert.Contains(new KeyValuePair <string, string>("my_var2", "var_value2"), pointTags);
            Assert.DoesNotContain(new KeyValuePair <string, string>("not_my_var3", "var_value3"), pointTags);
            Assert.DoesNotContain(new KeyValuePair <string, string>("VERSION", "1.0"), pointTags);
        }
Example #7
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));
        }