public void SubmitsMetrics() { int agentPort = TcpPortProvider.GetOpenPort(); Output.WriteLine($"Assigning port {agentPort} for the agentPort."); SetEnvironmentVariable("OTEL_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 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]); var lastSpan = spans.Last(); Assert.Equal(lastSpan.TraceId.ToString(CultureInfo.InvariantCulture), traceId); Assert.Equal(lastSpan.SpanId.ToString(CultureInfo.InvariantCulture), parentSpanId); } }
public void HttpClient() { int agentPort = TcpPortProvider.GetOpenPort(); int httpPort = TcpPortProvider.GetOpenPort(); 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 RenamesService(bool enableCallTarget, bool enableInlining) { SetCallTargetSettings(enableCallTarget, enableInlining); int expectedSpanCount = EnvironmentHelper.IsCoreClr() ? 36 : 32; 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: $"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.Equal("HttpMessageHandler", span.Tags[Tags.InstrumentationName]); Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag."); } } }
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 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 WhenDisabled_DoesntSendTelemetry() { const string expectedOperationName = "http.request"; const int expectedSpanCount = 1; const string serviceVersion = "1.0.0"; int agentPort = TcpPortProvider.GetOpenPort(); Output.WriteLine($"Assigning port {agentPort} for the agentPort."); using var agent = new MockTracerAgent(agentPort); SetServiceVersion(serviceVersion); int telemetryPort = TcpPortProvider.GetOpenPort(); using var telemetry = new MockTelemetryAgent <TelemetryData>(telemetryPort); SetEnvironmentVariable("DD_INSTRUMENTATION_TELEMETRY_ENABLED", "false"); SetEnvironmentVariable("DD_TRACE_TELEMETRY_URL", $"http://localhost:{telemetry.Port}"); SetEnvironmentVariable("DD_API_KEY", "INVALID_KEY_FOR_TESTS"); int httpPort = TcpPortProvider.GetOpenPort(); Output.WriteLine($"Assigning port {httpPort} for the httpPort."); using (ProcessResult processResult = RunSampleAndWaitForExit(agent, arguments: $"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); } // Shouldn't have any, but wait for 5s telemetry.WaitForLatestTelemetry(x => true); telemetry.Telemetry.Should().BeEmpty(); }
protected async Task AssertWebServerSpan( string path, MockTracerAgent agent, int httpPort, HttpStatusCode expectedHttpStatusCode, bool isError, string expectedErrorType, string expectedErrorMessage, string expectedSpanType, string expectedOperationName, string expectedResourceName, string expectedServiceVersion, IDictionary <string, string> expectedTags = null) { IImmutableList <MockTracerAgent.Span> spans; using (var httpClient = new HttpClient()) { // disable tracing for this HttpClient request httpClient.DefaultRequestHeaders.Add(HttpHeaderNames.TracingEnabled, "false"); var testStart = DateTime.UtcNow; var response = await httpClient.GetAsync($"http://localhost:{httpPort}" + path); var content = await response.Content.ReadAsStringAsync(); Output.WriteLine($"[http] {response.StatusCode} {content}"); Assert.Equal(expectedHttpStatusCode, response.StatusCode); spans = agent.WaitForSpans( count: 1, minDateTime: testStart, operationName: expectedOperationName); Assert.True(spans.Count == 1, "expected one span"); } MockTracerAgent.Span span = spans[0]; // base properties Assert.Equal(expectedSpanType, span.Type); Assert.Equal(expectedOperationName, span.Name); Assert.Equal(expectedResourceName, span.Resource); // errors Assert.Equal(isError, span.Error == 1); Assert.Equal(expectedErrorType, span.Tags.GetValueOrDefault(Tags.ErrorType)); Assert.Equal(expectedErrorMessage, span.Tags.GetValueOrDefault(Tags.ErrorMsg)); // other tags Assert.Equal(SpanKinds.Server, span.Tags.GetValueOrDefault(Tags.SpanKind)); Assert.Equal(expectedServiceVersion, span.Tags.GetValueOrDefault(Tags.Version)); if (expectedTags is not null) { foreach (var expectedTag in expectedTags) { Assert.Equal(expectedTag.Value, span.Tags.GetValueOrDefault(expectedTag.Key)); } } }
public void Telemetry_IsSentOnAppClose() { const string expectedOperationName = "http.request"; const int expectedSpanCount = 1; const string serviceVersion = "1.0.0"; int agentPort = TcpPortProvider.GetOpenPort(); Output.WriteLine($"Assigning port {agentPort} for the agentPort."); using var agent = new MockTracerAgent(agentPort); SetServiceVersion(serviceVersion); using var telemetry = this.ConfigureTelemetry(); int httpPort = TcpPortProvider.GetOpenPort(); Output.WriteLine($"Assigning port {httpPort} for the httpPort."); using (ProcessResult processResult = RunSampleAndWaitForExit(agent, arguments: $"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 data = telemetry.AssertIntegrationEnabled(IntegrationId.HttpMessageHandler); data.Application.ServiceVersion.Should().Be(serviceVersion); data.Application.ServiceName.Should().Be("Samples.Telemetry"); }
public void SubmitsTraces(bool enableCallTarget) { SetCallTargetSettings(enableCallTarget); int expectedSpanCount = 25; const string expectedOperationName = "http.request"; const string expectedServiceName = "Samples.WebRequest.NetFramework20-http-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: $"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.Equal("WebRequest", span.Tags[Tags.InstrumentationName]); Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag."); } PropagationTestHelpers.AssertPropagationEnabled(spans.First(), processResult); } }
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")); } 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 SubmitsTraces() { int agentPort = TcpPortProvider.GetOpenPort(); int aspNetCorePort = TcpPortProvider.GetOpenPort(); using (var agent = new MockTracerAgent(agentPort)) using (Process process = StartSample(agent.Port, arguments: null, packageVersion: string.Empty, aspNetCorePort: aspNetCorePort)) { var wh = new EventWaitHandle(false, EventResetMode.AutoReset); process.OutputDataReceived += (sender, args) => { if (args.Data != null) { if (args.Data.Contains("Now listening on:") || args.Data.Contains("Unable to start Kestrel")) { wh.Set(); } Output.WriteLine($"[webserver][stdout] {args.Data}"); } }; process.BeginOutputReadLine(); process.ErrorDataReceived += (sender, args) => { if (args.Data != null) { Output.WriteLine($"[webserver][stderr] {args.Data}"); } }; process.BeginErrorReadLine(); // wait for server to start wh.WaitOne(5000); SubmitRequests(aspNetCorePort); var graphQLValidateSpans = agent.WaitForSpans(_expectedGraphQLValidateSpanCount, operationName: _graphQLValidateOperationName, returnAllOperations: false) .GroupBy(s => s.SpanId) .Select(grp => grp.First()) .OrderBy(s => s.Start); var graphQLExecuteSpans = agent.WaitForSpans(_expectedGraphQLExecuteSpanCount, operationName: _graphQLExecuteOperationName, returnAllOperations: false) .GroupBy(s => s.SpanId) .Select(grp => grp.First()) .OrderBy(s => s.Start); if (!process.HasExited) { process.Kill(); } var spans = graphQLValidateSpans.Concat(graphQLExecuteSpans).ToList(); SpanTestHelpers.AssertExpectationsMet(_expectations, spans); } }
public void SubmitsTraces(string packageVersion, bool enableCallTarget) { SetCallTargetSettings(enableCallTarget); int agentPort = TcpPortProvider.GetOpenPort(); using (var agent = new MockTracerAgent(agentPort)) using (var processResult = RunSampleAndWaitForExit(agent.Port, packageVersion: packageVersion)) { Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode} and exception: {processResult.StandardError}"); var spans = agent.WaitForSpans(3, 500); Assert.True(spans.Count >= 3, $"Expecting at least 3 spans, only received {spans.Count}"); var rootSpan = spans.Single(s => s.ParentId == null); // Check for manual trace Assert.Equal("Main()", rootSpan.Name); Assert.Equal("Samples.MongoDB", rootSpan.Service); Assert.Null(rootSpan.Type); int spansWithResourceName = 0; foreach (var span in spans) { if (span == rootSpan) { continue; } if (span.Service == "Samples.MongoDB-mongodb") { Assert.Equal("mongodb.query", span.Name); Assert.Equal(SpanTypes.MongoDb, span.Type); Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag."); if (span.Resource != null && span.Resource != "mongodb.query") { spansWithResourceName++; Assert.True(span.Tags?.ContainsKey(Tags.MongoDbQuery), $"No query found on span {span}"); } } else { // These are manual traces Assert.Equal("Samples.MongoDB", span.Service); Assert.True("1.0.0" == span.Tags?.GetValueOrDefault(Tags.Version), span.ToString()); } } Assert.False(spansWithResourceName == 0, "Extraction of the command failed on all spans"); } }
public void MethodArgumentsInstrumentation(int numberOfArguments, bool fastPath) { SetCallTargetSettings(enableCallTarget: true); SetEnvironmentVariable("OTEL_INTEGRATIONS", Path.Combine(EnvironmentHelper.GetSampleProjectDirectory(), "integrations.json")); int agentPort = TcpPortProvider.GetOpenPort(); using (var agent = new MockTracerAgent(agentPort)) using (var processResult = RunSampleAndWaitForExit(agentPort, arguments: numberOfArguments.ToString())) { Assert.True(processResult.ExitCode == 0, $"Process exited with code {processResult.ExitCode}"); string beginMethodString = $"ProfilerOK: BeginMethod\\({numberOfArguments}\\)"; if (!fastPath) { beginMethodString = $"ProfilerOK: BeginMethod\\(Array\\)"; } int beginMethodCount = Regex.Matches(processResult.StandardOutput, beginMethodString).Count; int endMethodCount = Regex.Matches(processResult.StandardOutput, "ProfilerOK: EndMethod\\(").Count; int exceptionCount = Regex.Matches(processResult.StandardOutput, "Exception thrown.").Count; string[] typeNames = new string[] { ".VoidMethod", ".ReturnValueMethod", ".ReturnReferenceMethod", ".ReturnGenericMethod<string>", ".ReturnGenericMethod<int>", ".ReturnGenericMethod", }; if (numberOfArguments == 0) { // On number of arguments = 0 the throw exception on integrations async continuation runs. // So we have 1 more case with an exception being reported from the integration. Assert.Equal(43, beginMethodCount); Assert.Equal(43, endMethodCount); Assert.Equal(11, exceptionCount); } else { Assert.Equal(42, beginMethodCount); Assert.Equal(42, endMethodCount); Assert.Equal(10, exceptionCount); } foreach (var typeName in typeNames) { Assert.Contains(typeName, processResult.StandardOutput); } } }
protected async Task AssertAspNetSpanOnly( string path, MockTracerAgent agent, int httpPort, HttpStatusCode expectedHttpStatusCode, bool isError, string expectedErrorType, string expectedErrorMessage, string expectedSpanType, string expectedResourceName, string expectedServiceVersion) { IImmutableList <MockTracerAgent.Span> spans; using (var httpClient = new HttpClient()) { // disable tracing for this HttpClient request httpClient.DefaultRequestHeaders.Add(HttpHeaderNames.TracingEnabled, "false"); var testStart = DateTime.UtcNow; var response = await httpClient.GetAsync($"http://localhost:{httpPort}" + path); var content = await response.Content.ReadAsStringAsync(); Output.WriteLine($"[http] {response.StatusCode} {content}"); Assert.Equal(expectedHttpStatusCode, response.StatusCode); spans = agent.WaitForSpans( count: 1, minDateTime: testStart, operationName: "aspnet.request", returnAllOperations: true); Assert.True(spans.Count == 1, $"expected two span, saw {spans.Count}"); } MockTracerAgent.Span span = spans[0]; // base properties Assert.Equal(expectedResourceName, span.Resource); Assert.Equal(expectedSpanType, span.Type); // errors Assert.Equal(isError, span.Error == 1); Assert.Equal(expectedErrorType, span.Tags.GetValueOrDefault(Tags.ErrorType)); Assert.Equal(expectedErrorMessage, span.Tags.GetValueOrDefault(Tags.ErrorMsg)); // other tags Assert.Equal(SpanKinds.Server, span.Tags.GetValueOrDefault(Tags.SpanKind)); Assert.Equal(expectedServiceVersion, span.Tags.GetValueOrDefault(Tags.Version)); }
public void SubmitsTraces() { var prefix = $"{BuildParameters.Configuration}.{BuildParameters.TargetFramework}."; using (var agent = new MockTracerAgent(AgentPort)) using (var processResult = RunSampleAndWaitForExit(AgentPort, arguments: $"ServiceStack {prefix}")) { Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}"); var spans = agent.WaitForSpans(11).Where(s => s.Type == "redis").OrderBy(s => s.Start).ToList(); var host = Environment.GetEnvironmentVariable("REDIS_HOST") ?? "localhost"; foreach (var span in spans) { Assert.Equal(RedisHelper.OperationName, span.Name); Assert.Equal($"Samples.RedisCore-{RedisHelper.ServiceName}", span.Service); Assert.Equal(SpanTypes.Redis, span.Type); Assert.Equal(host, span.Tags.Get <string>("out.host")); Assert.Equal("6379", span.Tags.Get <string>("out.port")); } var expected = new TupleList <string, string> { { "INFO", "INFO" }, { "ROLE", "ROLE" }, { "SET", $"SET {prefix}ServiceStack.Redis.INCR 0" }, { "PING", "PING" }, { "DDCUSTOM", "DDCUSTOM COMMAND" }, { "ECHO", "ECHO Hello World" }, { "SLOWLOG", "SLOWLOG GET 5" }, { "INCR", $"INCR {prefix}ServiceStack.Redis.INCR" }, { "INCRBYFLOAT", $"INCRBYFLOAT {prefix}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.Get <string>("redis.raw_command") : string.Empty; Assert.True(e1 == a1, $"invalid resource name for span {i}, {e1} != {a1}"); Assert.True(e2 == a2, $"invalid raw command for span {i}, {e2} != {a2}"); } } }
public void TryStartIis(TestHelper helper) { lock (this) { if (_iisExpress == null) { var initialAgentPort = TcpPortProvider.GetOpenPort(); Agent = new MockTracerAgent(initialAgentPort); HttpPort = TcpPortProvider.GetOpenPort(); _iisExpress = helper.StartIISExpress(Agent.Port, HttpPort); } } }
public void SubmitsTraces(bool enableCallTarget) { SetCallTargetSettings(enableCallTarget); Output.WriteLine("Starting WcfTests.SubmitsTraces. Starting the Samples.Wcf requires ADMIN privileges"); var expectedSpanCount = 4; const string expectedOperationName = "wcf.request"; const string expectedServiceName = "Samples.Wcf"; HashSet <string> expectedResourceNames = new HashSet <string>() { "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue", "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue", "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT", "WcfSample/ICalculator/Add" }; int agentPort = TcpPortProvider.GetOpenPort(); int wcfPort = 8585; using (var agent = new MockTracerAgent(agentPort)) using (var processResult = RunSampleAndWaitForExit(agent.Port, arguments: $"WSHttpBinding Port={wcfPort}")) { Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode} and exception: {processResult.StandardError}"); var spans = agent.WaitForSpans(expectedSpanCount, operationName: expectedOperationName); Assert.True(spans.Count >= expectedSpanCount, $"Expecting at least {expectedSpanCount} spans, only received {spans.Count}"); foreach (var span in spans) { // Validate server fields Assert.Equal(expectedServiceName, span.Service); Assert.Equal(ServiceVersion, span.Tags[Tags.Version]); Assert.Equal(expectedOperationName, span.Name); Assert.Equal(SpanTypes.Web, span.Type); Assert.Equal(SpanKinds.Server, span.Tags[Tags.SpanKind]); // Validate resource name Assert.Contains(span.Resource, expectedResourceNames); // Test HTTP tags Assert.Equal("POST", span.Tags[Tags.HttpMethod]); Assert.Equal("http://localhost:8585/WcfSample/CalculatorService", span.Tags[Tags.HttpUrl]); Assert.Equal($"localhost:{wcfPort}", span.Tags[Tags.HttpRequestHeadersHost]); } } }
public void HttpClient_SubmitsTraces(bool enableCallTarget, InstrumentationOptions instrumentation, bool enableSocketsHandler) { ConfigureInstrumentation(enableCallTarget, instrumentation, enableSocketsHandler); var expectedAsyncCount = CalculateExpectedAsyncSpans(instrumentation, enableCallTarget); var expectedSyncCount = CalculateExpectedSyncSpans(instrumentation); var expectedSpanCount = expectedAsyncCount + expectedSyncCount; const string expectedOperationName = "http.request"; const string expectedServiceName = "Samples.HttpMessageHandler-http-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: $"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.Equal("HttpMessageHandler", span.Tags[Tags.InstrumentationName]); Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag."); if (span.Tags[Tags.HttpStatusCode] == "502") { Assert.Equal(1, span.Error); } } var firstSpan = spans.First(); var traceId = StringUtil.GetHeader(processResult.StandardOutput, HttpHeaderNames.TraceId); var parentSpanId = StringUtil.GetHeader(processResult.StandardOutput, HttpHeaderNames.ParentId); Assert.Equal(firstSpan.TraceId.ToString(CultureInfo.InvariantCulture), traceId); Assert.Equal(firstSpan.SpanId.ToString(CultureInfo.InvariantCulture), parentSpanId); } }
public void TryStartIis(TestHelper helper) { lock (this) { if (_iisExpress == null) { var initialAgentPort = TcpPortProvider.GetOpenPort(); Agent = new MockTracerAgent(initialAgentPort); HttpPort = TcpPortProvider.GetOpenPort(); // start IIS Express and give it a few seconds to boot up _iisExpress = helper.StartIISExpress(Agent.Port, HttpPort); Thread.Sleep(TimeSpan.FromSeconds(3)); } } }
public void DoesNotCrashInBadConfiguration(string targetFramework) { // Set bad configuration SetEnvironmentVariable("DD_DOTNET_TRACER_HOME", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); 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, framework: targetFramework)) { Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}"); } }
public void MetricsDisabled() { int agentPort = TcpPortProvider.GetOpenPort(); Output.WriteLine($"Assigning port {agentPort} for the agentPort."); SetEnvironmentVariable("DD_RUNTIME_METRICS_ENABLED", "0"); 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; Assert.True(requests.Count == 0, "Received metrics despite being disabled. Metrics received: " + string.Join("\n", requests)); Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}"); }
public void SubmitsTraces() { using (var agent = new MockTracerAgent(9002)) using (ProcessResult processResult = RunSampleAndWaitForExit(9002)) { 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"); foreach (var span in spans) { Assert.Equal("sql-server.query", span.Name); Assert.Equal($"Samples.SqlServer-sql-server", span.Service); Assert.Equal(SpanTypes.Sql, span.Type); } } }
public void SubmitsTraces() { if (Environment.OSVersion.Platform != PlatformID.Win32Windows) { return; } using (var agent = new MockTracerAgent(AgentPort)) { using (var iis = StartIISExpress(AgentPort, Port)) { try { var request = WebRequest.Create($"http://localhost:{Port}/"); using (var response = (HttpWebResponse)request.GetResponse()) using (var stream = response.GetResponseStream()) using (var reader = new StreamReader(stream)) { Output.WriteLine($"[http] {response.StatusCode} {reader.ReadToEnd()}"); } } catch (WebException wex) { Output.WriteLine($"[http] exception: {wex}"); if (wex.Response is HttpWebResponse response) { using (var stream = response.GetResponseStream()) using (var reader = new StreamReader(stream)) { Output.WriteLine($"[http] {response.StatusCode} {reader.ReadToEnd()}"); } } } } var spans = agent.WaitForSpans(1); Assert.True(spans.Count > 0, "expected at least one span"); foreach (var span in spans) { Assert.Equal("aspnet-mvc.request", span.Name); Assert.Equal(SpanTypes.Web, span.Type); Assert.Equal("GET home.index", span.Resource); } } }
public void SubmitsTraces() { 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(1); Assert.True(spans.Count > 0, "expected at least one span"); foreach (var span in spans) { Assert.Equal("postgres.query", span.Name); Assert.Equal("Samples.Npgsql-postgres", span.Service); Assert.Equal(SpanTypes.Sql, span.Type); } } }
public void SubmitsTraces() { using (var agent = new MockTracerAgent()) { using (var process = StartSample("SqlServer")) { process.WaitForExit(); } var spans = agent.GetSpans(); Assert.True(spans.Count > 1); foreach (var span in spans) { Assert.Equal("sqlserver.query", span.Name); Assert.Equal("Samples.SqlServer", span.Service); Assert.Equal("sql", span.Type); } } }
public void DoesNotCrashInBadConfiguration() { // Set bad configuration SetEnvironmentVariable("DD_DOTNET_TRACER_HOME", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); 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}"); } }
public void SubmitsTraces(bool enableCallTarget) { SetCallTargetSettings(enableCallTarget); 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 = "Samples.WebRequest-http-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.True(string.Equals(span.Tags[Tags.InstrumentationName], "WebRequest") || string.Equals(span.Tags[Tags.InstrumentationName], "HttpMessageHandler")); Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag."); } var firstSpan = spans.First(); var traceId = StringUtil.GetHeader(processResult.StandardOutput, HttpHeaderNames.TraceId); var parentSpanId = StringUtil.GetHeader(processResult.StandardOutput, HttpHeaderNames.ParentId); Assert.Equal(firstSpan.TraceId.ToString(CultureInfo.InvariantCulture), traceId); Assert.Equal(firstSpan.SpanId.ToString(CultureInfo.InvariantCulture), parentSpanId); } }
public void TracingDisabled_DoesNotSubmitsTraces(bool enableCallTarget, InstrumentationOptions instrumentation, bool enableSocketsHandler) { ConfigureInstrumentation(enableCallTarget, instrumentation, enableSocketsHandler); 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, 2000, operationName: expectedOperationName); Assert.Equal(0, spans.Count); PropagationTestHelpers.AssertPropagationDisabled(processResult); } }
public void SubmitsTraces() { using (var agent = new MockTracerAgent(AgentPort)) { using (var iis = StartIISExpress(AgentPort, Port)) { try { var request = WebRequest.Create($"http://localhost:{Port}/api/environment"); using (var response = (HttpWebResponse)request.GetResponse()) using (var stream = response.GetResponseStream()) using (var reader = new StreamReader(stream)) { Output.WriteLine($"[http] {response.StatusCode} {reader.ReadToEnd()}"); } } catch (WebException wex) { Output.WriteLine($"[http] exception: {wex}"); if (wex.Response is HttpWebResponse response) { using (var stream = response.GetResponseStream()) using (var reader = new StreamReader(stream)) { Output.WriteLine($"[http] {response.StatusCode} {reader.ReadToEnd()}"); } } } } var spans = agent.GetSpans(); Assert.True(spans.Count > 0, "expected at least one span"); foreach (var span in spans) { Assert.Equal("aspnet_web.query", span.Name); Assert.Equal("web", span.Type); Assert.Equal("GET api/environment", span.Resource); } } }