예제 #1
0
        public void DirectlyShipsLogs()
        {
            var hostName = "integration_ilogger_tests";

            using var logsIntake = new MockLogsIntake();

            EnableDirectLogSubmission(logsIntake.Port, nameof(IntegrationId.ILogger), hostName);

            var agentPort = TcpPortProvider.GetOpenPort();

            using var agent         = new MockTracerAgent(agentPort);
            using var processResult = RunSampleAndWaitForExit(agent, aspNetCorePort: 0);

            Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode} and exception: {processResult.StandardError}");

            var logs = logsIntake.Logs;

            using var scope = new AssertionScope();
            logs.Should().NotBeNull();
            logs.Should().HaveCountGreaterOrEqualTo(12); // have an unknown number of "Waiting for app started handling requests"
            logs.Should()
            .OnlyContain(x => x.Service == "LogsInjection.ILogger")
            .And.OnlyContain(x => x.Host == hostName)
            .And.OnlyContain(x => x.Source == "csharp")
            .And.OnlyContain(x => x.Env == "integration_tests")
            .And.OnlyContain(x => x.Version == "1.0.0")
            .And.OnlyContain(x => x.Exception == null)
            .And.OnlyContain(x => x.LogLevel == DirectSubmissionLogLevel.Information);
        }
        public static HttpListener StartHttpListenerWithPortResilience(string port, int retries = 5)
        {
            // try up to 5 consecutive ports before giving up
            while (true)
            {
                Url = $"http://localhost:{port}/Samples.WebRequest/";

                // seems like we can't reuse a listener if it fails to start,
                // so create a new listener each time we retry
                var listener = new HttpListener();
                listener.Prefixes.Add(Url);

                try
                {
                    listener.Start();

                    listenerThread = new Thread(HandleHttpRequests);
                    listenerThread.Start(listener);

                    return(listener);
                }
                catch (HttpListenerException) when(retries > 0)
                {
                    // only catch the exception if there are retries left
                    port = TcpPortProvider.GetOpenPort().ToString();
                    retries--;
                }

                // always close listener if exception is thrown,
                // whether it was caught or not
                listener.Close();
            }
        }
예제 #3
0
        public void SubmitsTraces()
        {
            var expectedSpanCount = 21; // 7 queries * 3 groups (The group of generic constraint calls is not currently supported)

            const string dbType = "sql-server";
            const string expectedOperationName = dbType + ".query";
            const string expectedServiceName   = "Samples.SqlServer.NetFramework20-" + dbType;

            int agentPort = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(expectedSpanCount, operationName: expectedOperationName);
                    Assert.Equal(expectedSpanCount, spans.Count);

                    foreach (var span in spans)
                    {
                        Assert.Equal(expectedOperationName, span.Name);
                        Assert.Equal(expectedServiceName, span.Service);
                        Assert.Equal(SpanTypes.Sql, span.Type);
                        Assert.Equal(dbType, span.Tags[Tags.DbType]);
                        Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag.");
                    }
                }
        }
예제 #4
0
        public void SubmitsTraces(string packageVersion)
        {
#if NET452
            var expectedSpanCount = 49; // 7 queries * 7 groups
#else
            var expectedSpanCount = 77; // 7 queries * 11 groups
#endif

            const string dbType = "sql-server";
            const string expectedOperationName = dbType + ".query";
            const string expectedServiceName   = "Samples.SqlServer-" + dbType;

            int agentPort = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port, packageVersion: packageVersion))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(expectedSpanCount, operationName: expectedOperationName);
                    Assert.Equal(expectedSpanCount, spans.Count);

                    foreach (var span in spans)
                    {
                        Assert.Equal(expectedOperationName, span.Name);
                        Assert.Equal(expectedServiceName, span.Service);
                        Assert.Equal(SpanTypes.Sql, span.Type);
                        Assert.Equal(dbType, span.Tags[Tags.DbType]);
                        Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag.");
                    }
                }
        }
예제 #5
0
        public void SubmitsTraces()
        {
            // In .NET Framework, the MySQL client injects
            // a few extra queries the first time it connects to a database
#if NET452
            var expectedSpanCount = 50; // 7 queries * 7 groups + 1 internal query
#else
            var expectedSpanCount = 78; // 7 queries * 11 groups + 1 internal query
#endif

            const string dbType = "mysql";
            const string expectedOperationName = dbType + ".query";
            const string expectedServiceName   = "Samples.MySql-" + dbType;

            int agentPort = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(expectedSpanCount, operationName: expectedOperationName);
                    Assert.Equal(expectedSpanCount, spans.Count);

                    foreach (var span in spans)
                    {
                        Assert.Equal(expectedOperationName, span.Name);
                        Assert.Equal(expectedServiceName, span.Service);
                        Assert.Equal(SpanTypes.Sql, span.Type);
                        Assert.Equal(dbType, span.Tags[Tags.DbType]);
                        Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag.");
                    }
                }
        }
예제 #6
0
        public void TracingDisabled_DoesNotSubmitsTraces(InstrumentationOptions instrumentation, bool enableSocketsHandler)
        {
            ConfigureInstrumentation(instrumentation, enableSocketsHandler);

            const string expectedOperationName = "http.request";

            using var telemetry = this.ConfigureTelemetry();
            int httpPort = TcpPortProvider.GetOpenPort();

            using (var agent = EnvironmentHelper.GetMockAgent())
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent, arguments: $"TracingDisabled Port={httpPort}"))
                {
                    var spans = agent.WaitForSpans(1, 2000, operationName: expectedOperationName);
                    Assert.Equal(0, spans.Count);

                    var traceId        = StringUtil.GetHeader(processResult.StandardOutput, HttpHeaderNames.TraceId);
                    var parentSpanId   = StringUtil.GetHeader(processResult.StandardOutput, HttpHeaderNames.ParentId);
                    var tracingEnabled = StringUtil.GetHeader(processResult.StandardOutput, HttpHeaderNames.TracingEnabled);

                    Assert.Null(traceId);
                    Assert.Null(parentSpanId);
                    Assert.Equal("false", tracingEnabled);

                    using var scope = new AssertionScope();
                    // ignore auto enabled for simplicity
                    telemetry.AssertIntegrationDisabled(IntegrationId.HttpMessageHandler);
                    telemetry.AssertIntegration(IntegrationId.HttpSocketsHandler, enabled: false, autoEnabled: null);
                    telemetry.AssertIntegration(IntegrationId.WinHttpHandler, enabled: false, autoEnabled: null);
                    telemetry.AssertIntegration(IntegrationId.CurlHandler, enabled: false, autoEnabled: null);
                }
        }
        public void WebClient()
        {
            int agentPort = TcpPortProvider.GetOpenPort();
            int httpPort  = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port, arguments: $"WebClient Port={httpPort}"))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(1);
                    Assert.True(spans.Count > 0, "expected at least one span." + System.Environment.NewLine + "IMPORTANT: Make sure Datadog.Trace.ClrProfiler.Managed.dll and its dependencies are in the GAC.");

                    var traceId      = GetHeader(processResult.StandardOutput, HttpHeaderNames.TraceId);
                    var parentSpanId = GetHeader(processResult.StandardOutput, HttpHeaderNames.ParentId);

                    // inspect the top-level span, underlying spans can be HttpMessageHandler in .NET Core
                    var firstSpan = spans.First();
                    Assert.Equal("http.request", firstSpan.Name);
                    Assert.Equal("Samples.HttpMessageHandler-http-client", firstSpan.Service);
                    Assert.Equal(SpanTypes.Http, firstSpan.Type);
                    Assert.Equal(nameof(WebRequest), firstSpan.Tags?[Tags.InstrumentationName]);
                    Assert.False(firstSpan.Tags?.ContainsKey(Tags.Version), "Http client span should not have service version tag.");

                    var lastSpan = spans.Last();
                    Assert.Equal(lastSpan.TraceId.ToString(CultureInfo.InvariantCulture), traceId);
                    Assert.Equal(lastSpan.SpanId.ToString(CultureInfo.InvariantCulture), parentSpanId);
                    Assert.False(lastSpan.Tags?.ContainsKey(Tags.Version), "Http client span should not have service version tag.");
                }
        }
예제 #8
0
        public void EmptyCommand()
        {
            bool callbackInvoked = false;

            Program.CallbackForTests = (_, _, _) =>
            {
                callbackInvoked = true;
            };

            // CI visibility mode checks if there's a running agent
            using var agent = EnableCiVisibilityMode ? new MockTracerAgent(TcpPortProvider.GetOpenPort()) : null;

            var agentUrl = $"http://localhost:{agent?.Port ?? 1111}";

            // dd-env is an argument for the target application and therefore shouldn't set the DD_ENV variable
            var commandLine = $"{CommandPrefix} --tracer-home dummyFolder --agent-url {agentUrl}";

            using var console = ConsoleHelper.Redirect();

            var exitCode = Program.Main(commandLine.Split(' '));

            using var scope = new AssertionScope();

            scope.AddReportable("output", console.Output);

            exitCode.Should().Be(1);
            callbackInvoked.Should().BeFalse();
            console.Output.Should().Contain("Error: Missing command");
        }
        public void SubmitsMetrics()
        {
            int agentPort = TcpPortProvider.GetOpenPort();

            Output.WriteLine($"Assigning port {agentPort} for the agentPort.");

            SetEnvironmentVariable("DD_RUNTIME_METRICS_ENABLED", "1");

            using var agent = new MockTracerAgent(agentPort, useStatsd: true);
            Output.WriteLine($"Assigning port {agent.StatsdPort} for the statsdPort.");

            using var processResult = RunSampleAndWaitForExit(agent.Port, agent.StatsdPort);
            var requests = agent.StatsdRequests;

            // Check if we receive 2 kinds of metrics:
            // - exception count is gathered using common .NET APIs
            // - contention count is gathered using platform-specific APIs

            var exceptionRequestsCount = requests.Count(r => r.Contains("runtime.dotnet.exceptions.count"));

            Assert.True(exceptionRequestsCount > 0, "No exception metrics received. Metrics received: " + string.Join("\n", requests));

            // Check if .NET Framework or .NET Core 3.1+
            if (!EnvironmentHelper.IsCoreClr() ||
                (Environment.Version.Major == 3 && Environment.Version.Minor == 1) ||
                Environment.Version.Major >= 5)
            {
                var contentionRequestsCount = requests.Count(r => r.Contains("runtime.dotnet.threads.contention_count"));

                Assert.True(contentionRequestsCount > 0, "No contention metrics received. Metrics received: " + string.Join("\n", requests));
            }

            Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");
        }
예제 #10
0
        public void SubmitsTraces()
        {
            const int    expectedSpanCount     = 17;
            const string dbType                = "postgres";
            const string expectedOperationName = dbType + ".query";
            const string expectedServiceName   = "Samples.Dapper-" + dbType;

            int agentPort = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(expectedSpanCount, operationName: expectedOperationName);
                    Assert.Equal(expectedSpanCount, spans.Count);

                    foreach (var span in spans)
                    {
                        Assert.Equal(expectedOperationName, span.Name);
                        Assert.Equal(expectedServiceName, span.Service);
                        Assert.Equal(SpanTypes.Sql, span.Type);
                        Assert.Equal(dbType, span.Tags?[Tags.DbType]);
                        Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag.");
                    }
                }
        }
        public void SubmitsTraces(string packageVersion)
        {
            int agentPort = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
                using (var processResult = RunSampleAndWaitForExit(agent.Port, arguments: $"{TestPrefix}", packageVersion: packageVersion))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    // note: ignore the INFO command because it's timing is unpredictable (on Linux?)
                    var spans = agent.WaitForSpans(11)
                                .Where(s => s.Type == "redis" && s.Resource != "INFO")
                                .OrderBy(s => s.Start)
                                .ToList();

                    var host = Environment.GetEnvironmentVariable("SERVICESTACK_REDIS_HOST") ?? "localhost:6379";
                    var port = host.Substring(host.IndexOf(':') + 1);
                    host = host.Substring(0, host.IndexOf(':'));

                    foreach (var span in spans)
                    {
                        Assert.Equal("redis.command", span.Name);
                        Assert.Equal("Samples.ServiceStack.Redis-redis", span.Service);
                        Assert.Equal(SpanTypes.Redis, span.Type);
                        Assert.Equal(host, span.Tags.GetValueOrDefault("out.host"));
                        Assert.Equal(port, span.Tags.GetValueOrDefault("out.port"));
                        Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag.");
                    }

                    var expected = new TupleList <string, string>
                    {
                        { "ROLE", "ROLE" },
                        { "SET", $"SET {TestPrefix}ServiceStack.Redis.INCR 0" },
                        { "PING", "PING" },
                        { "DDCUSTOM", "DDCUSTOM COMMAND" },
                        { "ECHO", "ECHO Hello World" },
                        { "SLOWLOG", "SLOWLOG GET 5" },
                        { "INCR", $"INCR {TestPrefix}ServiceStack.Redis.INCR" },
                        { "INCRBYFLOAT", $"INCRBYFLOAT {TestPrefix}ServiceStack.Redis.INCR 1.25" },
                        { "TIME", "TIME" },
                        { "SELECT", "SELECT 0" },
                    };

                    for (int i = 0; i < expected.Count; i++)
                    {
                        var e1 = expected[i].Item1;
                        var e2 = expected[i].Item2;

                        var a1 = i < spans.Count
                                 ? spans[i].Resource
                                 : string.Empty;
                        var a2 = i < spans.Count
                                 ? spans[i].Tags.GetValueOrDefault("redis.raw_command")
                                 : string.Empty;

                        Assert.True(e1 == a1, $@"invalid resource name for span #{i}, expected ""{e1}"", actual ""{a1}""");
                        Assert.True(e2 == a2, $@"invalid raw command for span #{i}, expected ""{e2}"" != ""{a2}""");
                    }
                }
        }
예제 #12
0
        public void HttpClient()
        {
            int agentPort = TcpPortProvider.GetOpenPort();
            int httpPort  = TcpPortProvider.GetOpenPort();

            Output.WriteLine($"Assigning port {agentPort} for the agentPort.");
            Output.WriteLine($"Assigning port {httpPort} for the httpPort.");

            using (var agent = new MockTracerAgent(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port, arguments: $"HttpClient Port={httpPort}"))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(1);
                    Assert.True(spans.Count > 0, "expected at least one span");

                    var traceId      = GetHeader(processResult.StandardOutput, HttpHeaderNames.TraceId);
                    var parentSpanId = GetHeader(processResult.StandardOutput, HttpHeaderNames.ParentId);

                    var firstSpan = spans.First();
                    Assert.Equal("http.request", firstSpan.Name);
                    Assert.Equal("Samples.HttpMessageHandler-http-client", firstSpan.Service);
                    Assert.Equal(SpanTypes.Http, firstSpan.Type);
                    Assert.Equal(nameof(HttpMessageHandler), firstSpan.Tags[Tags.InstrumentationName]);

                    var lastSpan = spans.Last();
                    Assert.Equal(lastSpan.TraceId.ToString(CultureInfo.InvariantCulture), traceId);
                    Assert.Equal(lastSpan.SpanId.ToString(CultureInfo.InvariantCulture), parentSpanId);
                }
        }
        public void SubmitTraces()
        {
            var agentPort = TcpPortProvider.GetOpenPort();

            using var agent = new MockZipkinCollector(Output, agentPort);

            const int expectedSpanCount = 8;

            using var processResult = RunTestApplicationAndWaitForExit(agent.Port, arguments: $"{_sqlClientFixture.Password} {_sqlClientFixture.Port}", enableStartupHook: true);
            Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode} and exception: {processResult.StandardError}");
            var spans = agent.WaitForSpans(expectedSpanCount, TimeSpan.FromSeconds(5));

            using (new AssertionScope())
            {
                spans.Count.Should().Be(expectedSpanCount);

                foreach (var span in spans)
                {
                    span.Service.Should().Be(ServiceName);
                    span.Name.Should().Be("master");
                    span.Tags["db.system"].Should().Be("mssql");
                    span.Tags["db.name"].Should().Be("master");
                    span.Tags["peer.service"].Should().Contain($"{_sqlClientFixture.Port}");
                    span.Tags["db.statement_type"].Should().Be("Text");
                    span.Tags["span.kind"].Should().Be("client");
                }
            }
        }
예제 #14
0
        public void SubmitsTraces()
        {
            const int    expectedSpanCount     = 2;
            const string expectedOperationName = "http.request";
            const string expectedServiceName   = "Samples.NetFramework.DomainNeutralInstrumentationWithoutGac-http-client";

            Assert.False(typeof(Instrumentation).Assembly.GlobalAssemblyCache, "Datadog.Trace.ClrProfiler.Managed was loaded from the GAC. Ensure that the assembly and its dependencies are not installed in the GAC when running this test.");

            int agentPort = TcpPortProvider.GetOpenPort();
            int httpPort  = TcpPortProvider.GetOpenPort();

            Output.WriteLine($"Assigning port {agentPort} for the agentPort.");
            Output.WriteLine($"Assigning port {httpPort} for the httpPort.");

            using (var agent = new MockTracerAgent(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port, arguments: $"HttpClient Port={httpPort}"))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(expectedSpanCount);
                    Assert.True(spans.Count >= expectedSpanCount, $"Expected at least {expectedSpanCount} span, only received {spans.Count}");

                    foreach (var span in spans)
                    {
                        Assert.Equal(expectedOperationName, span.Name);
                        Assert.Equal(expectedServiceName, span.Service);
                        Assert.Equal(SpanTypes.Http, span.Type);
                        Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag.");
                    }
                }
        }
예제 #15
0
        public void SubmitsTracesWithNetStandard(string packageVersion)
        {
            SetCallTargetSettings(enableCallTarget: true);

            var expectedSpanCount = 91;

            const string dbType = "sqlite";
            const string expectedOperationName = dbType + ".query";
            const string expectedServiceName   = "Samples.Microsoft.Data.Sqlite-" + dbType;

            // NOTE: opt into the additional instrumentation of calls into netstandard.dll
            SetEnvironmentVariable("DD_TRACE_NETSTANDARD_ENABLED", "true");

            int agentPort = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port, packageVersion: packageVersion))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(expectedSpanCount, operationName: expectedOperationName);
                    Assert.Equal(expectedSpanCount, spans.Count);

                    foreach (var span in spans)
                    {
                        Assert.Equal(expectedOperationName, span.Name);
                        Assert.Equal(expectedServiceName, span.Service);
                        Assert.Equal(SpanTypes.Sql, span.Type);
                        Assert.Equal(dbType, span.Tags[Tags.DbType]);
                        Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag.");
                    }
                }
        }
예제 #16
0
        public void SubmitsTraces(string packageVersion)
        {
            const int    expectedSpanCount     = 35;
            const string dbType                = "sql-server";
            const string expectedOperationName = dbType + ".query";
            const string expectedServiceName   = "Samples.SqlServer";

            int agentPort = TcpPortProvider.GetOpenPort();

            using (var agent = new MockZipkinCollector(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port, packageVersion: packageVersion, envVars: ZipkinEnvVars))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(expectedSpanCount, operationName: expectedOperationName);
                    Assert.Equal(expectedSpanCount, spans.Count);

                    foreach (var span in spans)
                    {
                        Assert.Equal(expectedOperationName, span.Name);
                        Assert.Equal(expectedServiceName, span.Service);
                        Assert.Null(span.Type);
                        Assert.Equal(dbType, span.Tags[Tags.DbType]);
                        Assert.NotNull(span.Tags[Tags.DbStatement]);
                    }
                }
        }
예제 #17
0
        public void TracingDisabled_DoesNotSubmitsTraces(bool enableCallTarget)
        {
            SetCallTargetSettings(enableCallTarget);

            const string expectedOperationName = "http.request";

            int agentPort = TcpPortProvider.GetOpenPort();
            int httpPort  = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port, arguments: $"TracingDisabled Port={httpPort}"))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(1, 3000, operationName: expectedOperationName);
                    Assert.Equal(0, spans.Count);

                    var traceId        = StringUtil.GetHeader(processResult.StandardOutput, HttpHeaderNames.TraceId);
                    var parentSpanId   = StringUtil.GetHeader(processResult.StandardOutput, HttpHeaderNames.ParentId);
                    var tracingEnabled = StringUtil.GetHeader(processResult.StandardOutput, HttpHeaderNames.TracingEnabled);

                    Assert.Null(traceId);
                    Assert.Null(parentSpanId);
                    Assert.Equal("false", tracingEnabled);
                }
        }
예제 #18
0
    public async Task SubmitsTraces()
    {
        var agentPort = TcpPortProvider.GetOpenPort();
        var webPort   = TcpPortProvider.GetOpenPort();

        using (var fwPort = FirewallHelper.OpenWinPort(agentPort, Output))
            using (var agent = new MockZipkinCollector(Output, agentPort))
                using (var container = await StartContainerAsync(agentPort, webPort))
                {
                    var client = new HttpClient();

                    var response = await client.GetAsync($"http://localhost:{webPort}");

                    var content = await response.Content.ReadAsStringAsync();

                    Output.WriteLine("Sample response:");
                    Output.WriteLine(content);

                    agent.SpanFilters.Add(x => x.Name != "healthz");

                    var spans = agent.WaitForSpans(1);

                    Assert.True(spans.Count >= 1, $"Expecting at least 1 span, only received {spans.Count}");
                }
    }
예제 #19
0
        public void WebClient()
        {
            int          expectedSpanCount     = 1;
            const string expectedOperationName = "http.request";
            const string expectedServiceName   = "Samples.HttpMessageHandler-http-client";

            int agentPort = TcpPortProvider.GetOpenPort();
            int httpPort  = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port, arguments: $"WebClient Port={httpPort}"))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(expectedSpanCount, operationName: expectedOperationName);
                    Assert.Equal(expectedSpanCount, spans.Count);

                    var traceId      = GetHeader(processResult.StandardOutput, HttpHeaderNames.TraceId);
                    var parentSpanId = GetHeader(processResult.StandardOutput, HttpHeaderNames.ParentId);

                    // inspect the top-level span, underlying spans can be HttpMessageHandler in .NET Core
                    var firstSpan = spans.First();
                    Assert.Equal("http.request", firstSpan.Name);
                    Assert.Equal(expectedServiceName, firstSpan.Service);
                    Assert.Equal(SpanTypes.Http, firstSpan.Type);
                    Assert.Equal(nameof(WebRequest), firstSpan.Tags?[Tags.InstrumentationName]);
                    Assert.False(firstSpan.Tags?.ContainsKey(Tags.Version), "Http client span should not have service version tag.");

                    var lastSpan = spans.Last();
                    Assert.Equal(lastSpan.TraceId.ToString(CultureInfo.InvariantCulture), traceId);
                    Assert.Equal(lastSpan.SpanId.ToString(CultureInfo.InvariantCulture), parentSpanId);
                    Assert.False(lastSpan.Tags?.ContainsKey(Tags.Version), "Http client span should not have service version tag.");
                }
        }
예제 #20
0
        private static IImmutableList <MockTracerAgent.Span> SendSpan(bool tracerMetricsEnabled, Mock <IStatsd> statsd)
        {
            IImmutableList <MockTracerAgent.Span> spans;
            var agentPort = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
            {
                var settings = new TracerSettings
                {
                    AgentUri             = new Uri($"http://localhost:{agent.Port}"),
                    TracerMetricsEnabled = tracerMetricsEnabled
                };

                var tracer = new Tracer(settings, agentWriter: null, sampler: null, scopeManager: null, statsd.Object);

                using (var scope = tracer.StartActive("root"))
                {
                    scope.Span.ResourceName = "resource";
                    Thread.Sleep(5);
                }

                spans = agent.WaitForSpans(1);
            }

            return(spans);
        }
        public void RenamesService()
        {
            var expectedSpanCount = 76;

            const string expectedOperationName = "http.request";
            const string expectedServiceName   = "my-custom-client";

            int httpPort = TcpPortProvider.GetOpenPort();

            Output.WriteLine($"Assigning port {httpPort} for the httpPort.");

            using (var agent = EnvironmentHelper.GetMockAgent())
                using (RunSampleAndWaitForExit(agent, arguments: $"Port={httpPort}"))
                {
                    var spans = agent.WaitForSpans(expectedSpanCount, operationName: expectedOperationName);
                    Assert.Equal(expectedSpanCount, spans.Count);

                    foreach (var span in spans)
                    {
                        Assert.Equal(expectedOperationName, span.Name);
                        Assert.Equal(expectedServiceName, span.Service);
                        Assert.Equal(SpanTypes.Http, span.Type);
                        Assert.Matches("WebRequest|HttpMessageHandler", span.Tags[Tags.InstrumentationName]);
                        Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag.");
                    }
                }
        }
        public void WebClient()
        {
            int agentPort = TcpPortProvider.GetOpenPort();
            int httpPort  = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port, $"WebClient Port={httpPort}"))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(1);
                    Assert.True(spans.Count > 0, "expected at least one span");

                    var traceId      = GetHeader(processResult.StandardOutput, HttpHeaderNames.TraceId);
                    var parentSpanId = GetHeader(processResult.StandardOutput, HttpHeaderNames.ParentId);

                    // inspect the top-level span, underlying spans can be HttpMessageHandler in .NET Core
                    var firstSpan = spans.First();
                    Assert.Equal("http.request", firstSpan.Name);
                    Assert.Equal("Samples.HttpMessageHandler-http-client", firstSpan.Service);
                    Assert.Equal(SpanTypes.Http, firstSpan.Type);
                    Assert.Equal(nameof(WebRequest), firstSpan.Tags[Tags.InstrumentationName]);

                    var lastSpan = spans.Last();
                    Assert.Equal(lastSpan.TraceId.ToString(CultureInfo.InvariantCulture), traceId);
                    Assert.Equal(lastSpan.SpanId.ToString(CultureInfo.InvariantCulture), parentSpanId);
                }
        }
예제 #23
0
        public void WebClient()
        {
            int agentPort = TcpPortProvider.GetOpenPort();
            int httpPort  = TcpPortProvider.GetOpenPort();

            using (var agent = new MockZipkinCollector(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port, arguments: $"WebClient Port={httpPort}", envVars: ZipkinEnvVars))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(1);
                    Assert.True(spans.Count > 0, "expected at least one span." + System.Environment.NewLine + "IMPORTANT: Make sure SignalFx.Tracing.ClrProfiler.Managed.dll and its dependencies are in the GAC.");

                    var traceId      = GetHeader(processResult.StandardOutput, HttpHeaderNames.B3TraceId);
                    var parentSpanId = GetHeader(processResult.StandardOutput, HttpHeaderNames.B3SpanId);

                    // inspect the top-level span, underlying spans can be HttpMessageHandler in .NET Core
                    var firstSpan = spans.First();
                    Assert.Equal("GET", firstSpan.Name);
                    Assert.Equal("Samples.HttpMessageHandler", firstSpan.Service);
                    Assert.Null(firstSpan.Type);
                    Assert.Equal(nameof(WebRequest), firstSpan.Tags[Tags.InstrumentationName]);

                    var lastSpan = spans.Last();
                    Assert.Equal(lastSpan.TraceId.ToString("x16", CultureInfo.InvariantCulture), traceId);
                    Assert.Equal(lastSpan.SpanId.ToString("x16", CultureInfo.InvariantCulture), parentSpanId);
                }
        }
예제 #24
0
        public void SubmitsTraces()
        {
            int agentPort = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
                using (var processResult = RunSampleAndWaitForExit(agent.Port))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(3, 500);
                    Assert.True(spans.Count >= 3, $"Expecting at least 3 spans, only received {spans.Count}");

                    var firstSpan = spans[0];

                    // Check for manual trace
                    Assert.Equal("Main()", firstSpan.Name);
                    Assert.Equal("Samples.MongoDB", firstSpan.Service);
                    Assert.Null(firstSpan.Type);

                    for (int i = 1; i < spans.Count; i++)
                    {
                        if (spans[i].Service == "Samples.MongoDB-mongodb")
                        {
                            Assert.Equal("mongodb.query", spans[i].Name);
                            Assert.Equal(SpanTypes.MongoDb, spans[i].Type);
                        }
                        else
                        {
                            // These are manual traces
                            Assert.Equal("Samples.MongoDB", spans[i].Service);
                        }
                    }
                }
        }
        public void RenamesService()
        {
            int expectedSpanCount = EnvironmentHelper.IsCoreClr() ? 71 : 27; // .NET Framework automatic instrumentation doesn't cover Async / TaskAsync operations

            var ignoreAsync = EnvironmentHelper.IsCoreClr() ? string.Empty : "IgnoreAsync ";

            const string expectedOperationName = "http.request";
            const string expectedServiceName   = "my-custom-client";

            int agentPort = TcpPortProvider.GetOpenPort();
            int httpPort  = TcpPortProvider.GetOpenPort();

            Output.WriteLine($"Assigning port {agentPort} for the agentPort.");
            Output.WriteLine($"Assigning port {httpPort} for the httpPort.");

            using (var agent = new MockTracerAgent(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port, arguments: $"{ignoreAsync}Port={httpPort}"))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(expectedSpanCount, operationName: expectedOperationName);
                    Assert.Equal(expectedSpanCount, spans.Count);

                    foreach (var span in spans)
                    {
                        Assert.Equal(expectedOperationName, span.Name);
                        Assert.Equal(expectedServiceName, span.Service);
                        Assert.Equal(SpanTypes.Http, span.Type);
                        Assert.Matches("WebRequest|HttpMessageHandler", span.Tags[Tags.InstrumentationName]);
                        Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag.");
                    }
                }
        }
예제 #26
0
        public void SubmitsTracesWithNetStandard()
        {
#if NET452
            var expectedSpanCount = 50; // 7 queries * 7 groups + 1 internal query
#else
            var expectedSpanCount = 78; // 7 queries * 11 groups + 1 internal query
#endif

            const string dbType = "mysql";
            const string expectedOperationName = dbType + ".query";
            const string expectedServiceName   = "Samples.MySql-" + dbType;

            // NOTE: opt into the additional instrumentation of calls into netstandard.dll
            SetEnvironmentVariable("DD_TRACE_NETSTANDARD_ENABLED", "true");

            int agentPort = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(expectedSpanCount, operationName: expectedOperationName);
                    Assert.Equal(expectedSpanCount, spans.Count);

                    foreach (var span in spans)
                    {
                        Assert.Equal(expectedOperationName, span.Name);
                        Assert.Equal(expectedServiceName, span.Service);
                        Assert.Equal(SpanTypes.Sql, span.Type);
                        Assert.Equal(dbType, span.Tags[Tags.DbType]);
                        Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag.");
                    }
                }
        }
        private static IImmutableList <MockSpan> SendSpan(bool tracerMetricsEnabled, IDogStatsd statsd)
        {
            IImmutableList <MockSpan> spans;
            var agentPort = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
            {
                var settings = new TracerSettings
                {
                    Exporter = new ExporterSettings()
                    {
                        AgentUri = new Uri($"http://127.0.0.1:{agent.Port}"),
                    },
                    TracerMetricsEnabled        = tracerMetricsEnabled,
                    StartupDiagnosticLogEnabled = false,
                };

                var tracer = new Tracer(settings, agentWriter: null, sampler: null, scopeManager: null, statsd);

                using (var scope = tracer.StartActive("root"))
                {
                    scope.Span.ResourceName = "resource";
                    Thread.Sleep(5);
                }

                spans = agent.WaitForSpans(1);
            }

            return(spans);
        }
        public void SubmitsTraces()
        {
            // In .NET Framework, the MySQL client injects
            // a few extra queries the first time it connects to a database
            int          expectedSpanCount     = EnvironmentHelper.IsCoreClr() ? 21 : 24;
            const string dbType                = "mysql";
            const string expectedOperationName = dbType + ".query";
            const string expectedServiceName   = "Samples.MySql-" + dbType;

            int agentPort = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(expectedSpanCount, operationName: expectedOperationName);
                    Assert.Equal(expectedSpanCount, spans.Count);

                    foreach (var span in spans)
                    {
                        Assert.Equal(expectedOperationName, span.Name);
                        Assert.Equal(expectedServiceName, span.Service);
                        Assert.Equal(SpanTypes.Sql, span.Type);
                        Assert.Equal(dbType, span.Tags[Tags.DbType]);
                    }
                }
        }
예제 #29
0
        public void SubmitsTraces()
        {
            var          expectedSpanCount     = 34;
            const string dbType                = "postgres";
            const string expectedOperationName = dbType + ".query";
            const string expectedServiceName   = "Samples.Npgsql-" + dbType;

            int agentPort = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
                using (ProcessResult processResult = RunSampleAndWaitForExit(agent.Port))
                {
                    Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}");

                    var spans = agent.WaitForSpans(expectedSpanCount, operationName: expectedOperationName);
                    Assert.Equal(expectedSpanCount, spans.Count);

                    foreach (var span in spans)
                    {
                        Assert.Equal(expectedOperationName, span.Name);
                        Assert.Equal(expectedServiceName, span.Service);
                        Assert.Equal(SpanTypes.Sql, span.Type);
                        Assert.Equal(dbType, span.Tags[Tags.DbType]);
                    }
                }
        }
예제 #30
0
        public async Task DatadogHttpClient_CanSendTracesToAgent()
        {
            var agentPort = TcpPortProvider.GetOpenPort();

            using (var agent = new MockTracerAgent(agentPort))
            {
                var settings = new TracerSettings
                {
                    Exporter = new ExporterSettings()
                    {
                        AgentUri        = new Uri($"http://localhost:{agent.Port}"),
                        TracesTransport = TracesTransportType.CustomTcpProvider,
                    }
                };
                var tracer = new Tracer(settings, agentWriter: null, sampler: null, scopeManager: null, statsd: null);

                using (var scope = tracer.StartActive("operationName"))
                {
                    scope.Span.ResourceName = "resourceName";
                }

                await tracer.FlushAsync();

                var spans = agent.WaitForSpans(1);
                Assert.Equal(1, spans.Count);
            }
        }