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(); } }
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."); } } }
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."); } } }
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."); } } }
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."); } }
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}"); }
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}"""); } } }
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"); } } }
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."); } } }
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."); } } }
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]); } } }
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); } }
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}"); } }
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."); } }
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); } }
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); } }
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."); } } }
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]); } } }
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]); } } }
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); } }