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 void InjectsLogs(bool enableLogShipping) { // One of the traces starts by manual opening a span when the background service starts, // and then it sends a HTTP request to the server. // On .NET Framework, we do not yet automatically instrument AspNetCore so instead of // having one distributed trace, the result is two separate traces. So expect one more trace // when running on .NET Framework // We also log inside of the web server handling, so in .NET Core expect one more log line #if NETFRAMEWORK var expectedCorrelatedTraceCount = 3; var expectedCorrelatedSpanCount = 3; #else var expectedCorrelatedTraceCount = 2; var expectedCorrelatedSpanCount = 4; #endif using var logsIntake = new MockLogsIntake(); if (enableLogShipping) { EnableDirectLogSubmission(logsIntake.Port, nameof(IntegrationId.ILogger), nameof(InjectsLogs)); } using (var agent = EnvironmentHelper.GetMockAgent()) using (RunSampleAndWaitForExit(agent, aspNetCorePort: 0)) { var spans = agent.WaitForSpans(1, 2500); spans.Should().HaveCountGreaterOrEqualTo(1); ValidateLogCorrelation(spans, _logFiles, expectedCorrelatedTraceCount, expectedCorrelatedSpanCount); } }
public void InjectsLogsWhenEnabled(string packageVersion, bool enableLogShipping) { SetEnvironmentVariable("DD_LOGS_INJECTION", "true"); using var logsIntake = new MockLogsIntake(); if (enableLogShipping) { EnableDirectLogSubmission(logsIntake.Port, nameof(IntegrationId.Log4Net), nameof(InjectsLogsWhenEnabled)); } var expectedCorrelatedTraceCount = 1; var expectedCorrelatedSpanCount = 1; using (var agent = EnvironmentHelper.GetMockAgent()) using (RunSampleAndWaitForExit(agent, packageVersion: packageVersion)) { var spans = agent.WaitForSpans(1, 2500); Assert.True(spans.Count >= 1, $"Expecting at least 1 span, only received {spans.Count}"); #if NETFRAMEWORK if (!string.IsNullOrWhiteSpace(packageVersion) && new Version(packageVersion) >= new Version("2.0.5")) { ValidateLogCorrelation(spans, _nlog205LogFileTests, expectedCorrelatedTraceCount, expectedCorrelatedSpanCount, packageVersion); } else { ValidateLogCorrelation(spans, _nlogPre205LogFileTests, expectedCorrelatedTraceCount, expectedCorrelatedSpanCount, packageVersion); } #else // Regardless of package version, for .NET Core just assert against raw log lines ValidateLogCorrelation(spans, _nlogPre205LogFileTests, expectedCorrelatedTraceCount, expectedCorrelatedSpanCount, packageVersion); #endif } }
public void DirectlyShipsLogs(string packageVersion) { var hostName = "integration_log4net_tests"; using var logsIntake = new MockLogsIntake(); SetEnvironmentVariable("DD_LOGS_INJECTION", "true"); EnableDirectLogSubmission(logsIntake.Port, nameof(IntegrationId.Log4Net), hostName); var agentPort = TcpPortProvider.GetOpenPort(); using var agent = new MockTracerAgent(agentPort); using var processResult = RunSampleAndWaitForExit(agent, packageVersion: packageVersion); 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(3); logs.Should() .OnlyContain(x => x.Service == "LogsInjection.Log4Net") .And.OnlyContain(x => x.Env == "integration_tests") .And.OnlyContain(x => x.Version == "1.0.0") .And.OnlyContain(x => x.Host == hostName) .And.OnlyContain(x => x.Source == "csharp") .And.OnlyContain(x => x.Exception == null) .And.OnlyContain(x => x.LogLevel == DirectSubmissionLogLevel.Information); if (PackageSupportsLogsInjection(packageVersion)) { logs .Where(x => !x.Message.Contains(ExcludeMessagePrefix)) .Should() .NotBeEmpty() .And.OnlyContain(x => !string.IsNullOrEmpty(x.TraceId)) .And.OnlyContain(x => !string.IsNullOrEmpty(x.SpanId)); } }
public void DoesNotInjectLogsWhenDisabled(string packageVersion, bool enableLogShipping) { SetEnvironmentVariable("DD_LOGS_INJECTION", "false"); using var logsIntake = new MockLogsIntake(); if (enableLogShipping) { EnableDirectLogSubmission(logsIntake.Port, nameof(IntegrationId.Serilog), nameof(InjectsLogsWhenEnabled)); } var expectedCorrelatedTraceCount = 0; var expectedCorrelatedSpanCount = 0; using (var agent = EnvironmentHelper.GetMockAgent()) using (RunSampleAndWaitForExit(agent, packageVersion: packageVersion)) { var spans = agent.WaitForSpans(1, 2500); Assert.True(spans.Count >= 1, $"Expecting at least 1 span, only received {spans.Count}"); var logFiles = GetLogFiles(packageVersion, logsInjectionEnabled: false); ValidateLogCorrelation(spans, logFiles, expectedCorrelatedTraceCount, expectedCorrelatedSpanCount, packageVersion, disableLogCorrelation: true); } }
public void SubmitTraces(string packageVersion) { List <MockSpan> spans = null; string[] messages = null; try { SetEnvironmentVariable("DD_CIVISIBILITY_ENABLED", "1"); SetEnvironmentVariable("DD_TRACE_DEBUG", "1"); SetEnvironmentVariable("DD_DUMP_ILREWRITE_ENABLED", "1"); using var logsIntake = new MockLogsIntake(); EnableDirectLogSubmission(logsIntake.Port, nameof(IntegrationId.XUnit), nameof(XUnitTests)); SetEnvironmentVariable(ConfigurationKeys.CIVisibility.Logs, "1"); using (var agent = EnvironmentHelper.GetMockAgent()) using (ProcessResult processResult = RunDotnetTestSampleAndWaitForExit(agent, packageVersion: packageVersion)) { spans = agent.WaitForSpans(ExpectedSpanCount) .Where(s => !(s.Tags.TryGetValue(Tags.InstrumentationName, out var sValue) && sValue == "HttpMessageHandler")) .ToList(); // Check the span count Assert.Equal(ExpectedSpanCount, spans.Count); // *************************************************************************** foreach (var targetSpan in spans) { // check the name Assert.Equal("xunit.test", targetSpan.Name); // check the CIEnvironmentValues decoration. CheckCIEnvironmentValuesDecoration(targetSpan); // check the runtime values CheckRuntimeValues(targetSpan); // check the bundle name AssertTargetSpanEqual(targetSpan, TestTags.Bundle, TestBundleName); // check the suite name AssertTargetSpanEqual(targetSpan, TestTags.Suite, TestSuiteName); // check the test type AssertTargetSpanEqual(targetSpan, TestTags.Type, TestTags.TypeTest); // check the test framework AssertTargetSpanContains(targetSpan, TestTags.Framework, "xUnit"); Assert.True(targetSpan.Tags.Remove(TestTags.FrameworkVersion)); // check the version AssertTargetSpanEqual(targetSpan, "version", "1.0.0"); // checks the origin tag CheckOriginTag(targetSpan); // checks the runtime id tag AssertTargetSpanExists(targetSpan, Tags.RuntimeId); // Check the Environment AssertTargetSpanEqual(targetSpan, Tags.Env, "integration_tests"); // Language AssertTargetSpanEqual(targetSpan, Tags.Language, TracerConstants.Language); // CI Library Language AssertTargetSpanEqual(targetSpan, CommonTags.LibraryVersion, TracerConstants.AssemblyVersion); // check specific test span switch (targetSpan.Tags[TestTags.Name]) { case "SimplePassTest": CheckSimpleTestSpan(targetSpan); break; case "SimpleSkipFromAttributeTest": CheckSimpleSkipFromAttributeTest(targetSpan); break; case "SimpleErrorTest": CheckSimpleErrorTest(targetSpan); break; case "TraitPassTest": CheckSimpleTestSpan(targetSpan); CheckTraitsValues(targetSpan); break; case "TraitSkipFromAttributeTest": CheckSimpleSkipFromAttributeTest(targetSpan); CheckTraitsValues(targetSpan); break; case "TraitErrorTest": CheckSimpleErrorTest(targetSpan); CheckTraitsValues(targetSpan); break; case "SimpleParameterizedTest": CheckSimpleTestSpan(targetSpan); AssertTargetSpanAnyOf( targetSpan, TestTags.Parameters, "{\"metadata\":{\"test_name\":\"Samples.XUnitTests.TestSuite.SimpleParameterizedTest(xValue: 1, yValue: 1, expectedResult: 2)\"},\"arguments\":{\"xValue\":\"1\",\"yValue\":\"1\",\"expectedResult\":\"2\"}}", "{\"metadata\":{\"test_name\":\"Samples.XUnitTests.TestSuite.SimpleParameterizedTest(xValue: 2, yValue: 2, expectedResult: 4)\"},\"arguments\":{\"xValue\":\"2\",\"yValue\":\"2\",\"expectedResult\":\"4\"}}", "{\"metadata\":{\"test_name\":\"Samples.XUnitTests.TestSuite.SimpleParameterizedTest(xValue: 3, yValue: 3, expectedResult: 6)\"},\"arguments\":{\"xValue\":\"3\",\"yValue\":\"3\",\"expectedResult\":\"6\"}}", "{\"metadata\":{\"test_name\":\"SimpleParameterizedTest(xValue: 1, yValue: 1, expectedResult: 2)\"},\"arguments\":{\"xValue\":\"1\",\"yValue\":\"1\",\"expectedResult\":\"2\"}}", "{\"metadata\":{\"test_name\":\"SimpleParameterizedTest(xValue: 2, yValue: 2, expectedResult: 4)\"},\"arguments\":{\"xValue\":\"2\",\"yValue\":\"2\",\"expectedResult\":\"4\"}}", "{\"metadata\":{\"test_name\":\"SimpleParameterizedTest(xValue: 3, yValue: 3, expectedResult: 6)\"},\"arguments\":{\"xValue\":\"3\",\"yValue\":\"3\",\"expectedResult\":\"6\"}}"); break; case "SimpleSkipParameterizedTest": CheckSimpleSkipFromAttributeTest(targetSpan); break; case "SimpleErrorParameterizedTest": CheckSimpleErrorTest(targetSpan); AssertTargetSpanAnyOf( targetSpan, TestTags.Parameters, "{\"metadata\":{\"test_name\":\"Samples.XUnitTests.TestSuite.SimpleErrorParameterizedTest(xValue: 1, yValue: 0, expectedResult: 2)\"},\"arguments\":{\"xValue\":\"1\",\"yValue\":\"0\",\"expectedResult\":\"2\"}}", "{\"metadata\":{\"test_name\":\"Samples.XUnitTests.TestSuite.SimpleErrorParameterizedTest(xValue: 2, yValue: 0, expectedResult: 4)\"},\"arguments\":{\"xValue\":\"2\",\"yValue\":\"0\",\"expectedResult\":\"4\"}}", "{\"metadata\":{\"test_name\":\"Samples.XUnitTests.TestSuite.SimpleErrorParameterizedTest(xValue: 3, yValue: 0, expectedResult: 6)\"},\"arguments\":{\"xValue\":\"3\",\"yValue\":\"0\",\"expectedResult\":\"6\"}}", "{\"metadata\":{\"test_name\":\"SimpleErrorParameterizedTest(xValue: 1, yValue: 0, expectedResult: 2)\"},\"arguments\":{\"xValue\":\"1\",\"yValue\":\"0\",\"expectedResult\":\"2\"}}", "{\"metadata\":{\"test_name\":\"SimpleErrorParameterizedTest(xValue: 2, yValue: 0, expectedResult: 4)\"},\"arguments\":{\"xValue\":\"2\",\"yValue\":\"0\",\"expectedResult\":\"4\"}}", "{\"metadata\":{\"test_name\":\"SimpleErrorParameterizedTest(xValue: 3, yValue: 0, expectedResult: 6)\"},\"arguments\":{\"xValue\":\"3\",\"yValue\":\"0\",\"expectedResult\":\"6\"}}"); break; } // check remaining tag (only the name) Assert.Single(targetSpan.Tags); } // *************************************************************************** // Check logs messages = logsIntake.Logs.Select(i => i.Message).Where(m => m.StartsWith("Test:")).ToArray(); Assert.Contains(messages, m => m.StartsWith("Test:SimplePassTest")); Assert.Contains(messages, m => m.StartsWith("Test:SimpleErrorTest")); Assert.Contains(messages, m => m.StartsWith("Test:TraitPassTest")); Assert.Contains(messages, m => m.StartsWith("Test:TraitErrorTest")); Assert.Contains(messages, m => m.StartsWith("Test:SimpleParameterizedTest")); Assert.Contains(messages, m => m.StartsWith("Test:SimpleErrorParameterizedTest")); } } catch { WriteSpans(spans); throw; } }