public async Task MetricsWithRealAgent()
        {
            // Note: If XunitOutputLogger is used with MetricsCollector it might cause issues because
            // MetricsCollector's Dispose is currently broken - it doesn't guarantee that MetricsCollector's behaves correctly (i.e., ignores)
            // timer callbacks after Dispose completed.
            // This bug in turn causes MetricsCollector to possibly use XunitOutputLogger even after the current test has exited
            // and ITestOutputHelper on which XunitOutputLogger is based became invalid.
            //
            // After https://github.com/elastic/apm-agent-dotnet/issues/494 is fixed the line below can be uncommented.
            //
            // var logger = _logger;
            //
            var logger = new NoopLogger();
            //

            var payloadSender = new MockPayloadSender();
            var configReader  = new MockConfigSnapshot(logger, metricsInterval: "1s", logLevel: "Debug");

            using var agentComponents = new AgentComponents(payloadSender: payloadSender, logger: logger, configurationReader: configReader);
            using (var agent = new ApmAgent(agentComponents))
            {
                await Task.Delay(10000);                 //make sure we wait enough to collect 1 set of metrics

                agent.ConfigurationReader.MetricsIntervalInMilliseconds.Should().Be(1000);
            }

            payloadSender.Metrics.Should().NotBeEmpty();
            payloadSender.Metrics.First().Samples.Should().NotBeEmpty();
        }
示例#2
0
        public void LimitedAmountOfSpansShouldBeSent_WhenSpansAreCapturedConcurrently()
        {
            // Arrange
            const int spansCount        = 10;
            const int maxSpansCount     = 2;
            var       mockPayloadSender = new MockPayloadSender();
            var       mockConfig        = new MockConfigSnapshot(transactionMaxSpans: maxSpansCount.ToString());

            // Act
            using (var agent = new ApmAgent(new TestAgentComponents(config: mockConfig, payloadSender: mockPayloadSender)))
            {
                agent.Tracer.CaptureTransaction("test transaction name", "test transaction type",
                                                transaction =>
                {
                    MultiThreadsTestUtils.TestOnThreads(spansCount, threadIndex =>
                    {
                        transaction.CaptureSpan($"test span name #{threadIndex}", "test span type", span => { });
                        return(1);
                    });
                });
            }

            // Assert
            mockPayloadSender.WaitForTransactions();
            mockPayloadSender.Transactions.Count.Should().Be(1);
            mockPayloadSender.WaitForSpans();
            mockPayloadSender.Spans.Count.Should().Be(maxSpansCount);
            mockPayloadSender.FirstTransaction.SpanCount.Dropped.Should().Be(spansCount - maxSpansCount);
        }
示例#3
0
        public async Task SecretToken_test()
        {
            var isRequestFinished = new TaskCompletionSource <object>();

            AuthenticationHeaderValue authHeader = null;
            var handler = new MockHttpMessageHandler((r, c) =>
            {
                authHeader = r.Headers.Authorization;
                isRequestFinished.SetResult(null);
                return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)));
            });

            const string secretToken   = "SecretToken";
            var          noopLogger    = new NoopLogger();
            var          mockConfig    = new MockConfigSnapshot(_logger, secretToken: secretToken, maxBatchEventCount: "1");
            var          payloadSender = new PayloadSenderV2(_logger, mockConfig,
                                                             Service.GetDefaultService(mockConfig, noopLogger), new Api.System(), handler, /* dbgName: */ TestDisplayName);

            using (var agent = new ApmAgent(new TestAgentComponents(LoggerBase, mockConfig, payloadSender)))
            {
                agent.PayloadSender.QueueTransaction(new Transaction(agent, "TestName", "TestType"));
                await isRequestFinished.Task;
            }

            authHeader.Should().NotBeNull();
            authHeader.Scheme.Should().Be("Bearer");
            authHeader.Parameter.Should().Be(secretToken);
        }
        public async Task ToggleRecordingAndCaptureMetrics()
        {
            var logger = new NoopLogger();

            var payloadSender = new MockPayloadSender();
            var configReader  = new MockConfigSnapshot(logger, metricsInterval: "1s", logLevel: "Debug", recording: "false");

            using var agentComponents = new AgentComponents(payloadSender: payloadSender, logger: logger, configurationReader: configReader);
            using var agent           = new ApmAgent(agentComponents);

            await Task.Delay(10000);             //make sure we wait enough to collect 1 set of metrics

            agent.ConfigurationReader.MetricsIntervalInMilliseconds.Should().Be(1000);
            payloadSender.Metrics.Should().BeEmpty();

            //start recording
            agent.ConfigStore.CurrentSnapshot = new MockConfigSnapshot(logger, metricsInterval: "1s", logLevel: "Debug", recording: "true");

            await Task.Delay(10000);             //make sure we wait enough to collect 1 set of metrics

            //stop recording
            agent.ConfigStore.CurrentSnapshot = new MockConfigSnapshot(logger, metricsInterval: "1s", logLevel: "Debug", recording: "false");
            payloadSender.Metrics.Should().NotBeEmpty();

            await Task.Delay(500);             //make sure collection on the MetricCollector is finished

            var numberOfEvents = payloadSender.Metrics.Count;

            await Task.Delay(10000);             //make sure we wait enough to collect 1 set of metrics

            payloadSender.Metrics.Count.Should().Be(numberOfEvents);
        }
示例#5
0
        public async Task CheckAuthorizationHeader(string authorizationHeader)
        {
            var isRequestFinished = new TaskCompletionSource <object>();

            AuthenticationHeaderValue authHeader = null;
            var handler = new MockHttpMessageHandler((r, c) =>
            {
                authHeader = r.Headers.Authorization;
                isRequestFinished.SetResult(null);
                return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)));
            });

            var logger        = new NoopLogger();
            var mockConfig    = new MockConfigSnapshot(logger, secretToken: _secretToken, apiKey: _apiKey, flushInterval: "1s");
            var payloadSender = new PayloadSenderV2(logger, mockConfig,
                                                    Api.Service.GetDefaultService(mockConfig, logger), new Api.System(), handler, /* dbgName: */ nameof(ApiKeyFeatureContext));

            using (var agent = new ApmAgent(new TestAgentComponents(logger, mockConfig, payloadSender)))
            {
                agent.PayloadSender.QueueTransaction(new Transaction(agent, "TestName", "TestType"));
                await isRequestFinished.Task;
            }

            authHeader.Should().NotBeNull();
            authHeader.ToString().Should().Be(authorizationHeader);
        }
示例#6
0
        public void LimitedAmountOfSpansShouldBeSent_WhenTransactionMaxSpansIsPositiveNumber()
        {
            // Arrange
            const int spansCount        = 10;
            const int maxSpansCount     = 5;
            var       mockPayloadSender = new MockPayloadSender();
            var       mockConfig        = new MockConfigSnapshot(transactionMaxSpans: maxSpansCount.ToString());

            // Act
            using (var agent = new ApmAgent(new TestAgentComponents(config: mockConfig, payloadSender: mockPayloadSender)))
            {
                agent.Tracer.CaptureTransaction("test transaction name", "test transaction type",
                                                transaction =>
                {
                    foreach (var iteration in Enumerable.Range(1, spansCount))
                    {
                        transaction.CaptureSpan($"test span name #{iteration}", "test span type", span => { });
                    }
                });
            }

            // Assert
            mockPayloadSender.WaitForTransactions();
            mockPayloadSender.Transactions.Count.Should().Be(1);
            mockPayloadSender.Spans.Count.Should().Be(maxSpansCount);
            mockPayloadSender.FirstTransaction.SpanCount.Dropped.Should().Be(spansCount - maxSpansCount);
        }
示例#7
0
        public void AllSpansShouldBeSent_WhenTransactionMaxSpansIsEqualToMinusOne()
        {
            // Arrange
            var mockPayloadSender = new MockPayloadSender();
            var mockConfig        = new MockConfigSnapshot(transactionMaxSpans: "-1");
            var spansCount        = 1000;

            // Act
            using (var agent = new ApmAgent(new TestAgentComponents(config: mockConfig, payloadSender: mockPayloadSender)))
            {
                agent.Tracer.CaptureTransaction("test transaction name", "test transaction type",
                                                transaction =>
                {
                    foreach (var iteration in Enumerable.Range(1, spansCount))
                    {
                        transaction.CaptureSpan($"test span name #{iteration}", "test span type", span => { });
                    }
                });
            }

            // Assert
            mockPayloadSender.WaitForTransactions();
            mockPayloadSender.Transactions.Count.Should().Be(1);
            mockPayloadSender.WaitForSpans();
            mockPayloadSender.Spans.Count.Should().Be(spansCount);
            mockPayloadSender.FirstTransaction.SpanCount.Dropped.Should().Be(0);
        }
        public void AgentDisabledBasicTransactionWithSpans()
        {
            var payloadSender = new MockPayloadSender();
            var configReader  = new MockConfigSnapshot(enabled: "false");

            using var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender, config: configReader));
            var transaction = agent.Tracer.StartTransaction("TestTransaction", "Test");

            transaction.Should().NotBeOfType <Transaction>();
            transaction.Should().BeOfType <NoopTransaction>();

            var span1 = transaction.StartSpan("test", "test");

            span1.Should().NotBeOfType <Span>();
            span1.Should().BeOfType <NoopSpan>();
            agent.Tracer.CurrentSpan.Should().Be(span1);
            span1.End();

            agent.Tracer.CurrentSpan.Should().BeNull();

            var span2 = span1.StartSpan("test2", "test");

            span2.Should().NotBeOfType <Span>();
            span2.Should().BeOfType <NoopSpan>();
            span2.End();

            transaction.End();
            payloadSender.Transactions.Should().BeNullOrEmpty();
            payloadSender.Spans.Should().BeNullOrEmpty();
        }
示例#9
0
        public void ServerCert_Should_Allow_Https_To_Apm_Server()
        {
            using var tempFile = new TempFile();
            var certPath   = Path.Combine(SolutionPaths.Root, "test", "Elastic.Apm.Tests.MockApmServer", "cert.pfx");
            var serverCert = new X509Certificate2(certPath, "password");

            File.WriteAllBytes(tempFile.Path, serverCert.Export(X509ContentType.Cert));

            var configuration = new MockConfigSnapshot(
                serverUrl: $"https://localhost:{_port}",
                serverCert: tempFile.Path,
                disableMetrics: "*",
                cloudProvider: "none");

            using var agent = new ApmAgent(new AgentComponents(_logger, configuration));
            agent.Tracer.CaptureTransaction("TestTransaction", "TestType", t =>
            {
                t.SetLabel("self_signed_cert", true);
            });

            var signalled = _waitHandle.WaitOne(TimeSpan.FromMinutes(2));

            signalled.Should().BeTrue("timed out waiting to receive transaction");

            _server.ReceivedData.Transactions.Should().HaveCount(1);
            var transaction = _server.ReceivedData.Transactions.First();

            transaction.Context.Labels.MergedDictionary.Should().ContainKey("self_signed_cert");
        }
示例#10
0
        public void SpansSentOnlyForSampledTransaction(bool isSampled)
        {
            var mockPayloadSender = new MockPayloadSender();
            var mockConfig        = new MockConfigSnapshot(transactionSampleRate: isSampled ? "1" : "0");

            using (var agent = new ApmAgent(new TestAgentComponents(config: mockConfig, payloadSender: mockPayloadSender)))
            {
                agent.Tracer.CaptureTransaction("test transaction name", "test transaction type",
                                                transaction =>
                                                transaction.CaptureSpan("test span name", "test span type", span => { })
                                                );
            }

            mockPayloadSender.WaitForTransactions();
            mockPayloadSender.Transactions.Count.Should().Be(1);
            mockPayloadSender.FirstTransaction.SpanCount.Dropped.Should().Be(0);
            if (isSampled)
            {
                mockPayloadSender.FirstTransaction.SampleRate.Should().Be(1);
                mockPayloadSender.FirstTransaction.SpanCount.Started.Should().Be(1);
                mockPayloadSender.Spans.Count.Should().Be(1);
            }
            else
            {
                mockPayloadSender.FirstTransaction.SampleRate.Should().Be(0);
                mockPayloadSender.FirstTransaction.SpanCount.Started.Should().Be(0);
                mockPayloadSender.Spans.Should().BeEmpty();
            }
        }
示例#11
0
        public void ErrorShouldContainTransactionData(bool isSampled, bool captureOnSpan, bool captureAsError)
        {
            var payloadSender        = new MockPayloadSender();
            var expectedErrorContext = new Context();

            expectedErrorContext.Labels["one"]        = "1";
            expectedErrorContext.Labels["twenty two"] = "22";

            ITransaction      capturedTransaction            = null;
            IExecutionSegment errorCapturingExecutionSegment = null;
            var mockConfig = new MockConfigSnapshot(transactionSampleRate: isSampled ? "1" : "0");

            using (var agent = new ApmAgent(new TestAgentComponents(config: mockConfig, payloadSender: payloadSender)))
            {
                agent.Tracer.CaptureTransaction(TestTransaction, CustomTransactionTypeForTests, transaction =>
                {
                    capturedTransaction = transaction;

                    foreach (var keyValue in expectedErrorContext.Labels)
                    {
                        transaction.Context.Labels[keyValue.Key] = keyValue.Value;
                    }
                    ISpan span = null;
                    if (captureOnSpan)
                    {
                        span = transaction.StartSpan(TestSpan1, ApiConstants.TypeExternal);
                        errorCapturingExecutionSegment = span;
                    }
                    else
                    {
                        errorCapturingExecutionSegment = transaction;
                    }

                    if (captureAsError)
                    {
                        errorCapturingExecutionSegment.CaptureError("Test error message", "Test error culprit", new StackTrace(true).GetFrames());
                    }
                    else
                    {
                        errorCapturingExecutionSegment.CaptureException(new TestException("test exception"));
                    }

                    // Immutable snapshot of the context should be captured instead of reference to a mutable object
                    // transaction.Context.Labels["three hundred thirty three"] = "333";

                    span?.End();
                });
            }

            payloadSender.Errors.Count.Should().Be(1);
            payloadSender.FirstError.Transaction.IsSampled.Should().Be(isSampled);
            payloadSender.FirstError.Transaction.Type.Should().Be(CustomTransactionTypeForTests);
            payloadSender.FirstError.TransactionId.Should().Be(capturedTransaction.Id);
            payloadSender.FirstError.TraceId.Should().Be(capturedTransaction.TraceId);
            payloadSender.FirstError.ParentId.Should().Be(errorCapturingExecutionSegment.Id);
            payloadSender.FirstError.Context.Should().BeEquivalentTo(expectedErrorContext);
        }
示例#12
0
        public void Subscribers_Not_Subscribed_When_Agent_Disabled()
        {
            var payloadSender = new NoopPayloadSender();
            var configReader  = new MockConfigSnapshot(enabled: "false");

            using var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender, config: configReader));

            var subscriber = new Mock <IDiagnosticsSubscriber>();

            agent.Subscribe(subscriber.Object);
            subscriber.Verify(s => s.Subscribe(It.IsAny <IApmAgent>()), Times.Never);
        }
        public void CaptureTransactionAndSpansWithRecordingOnFalse()
        {
            var mockPayloadSender  = new MockPayloadSender();
            var mockConfigSnapshot = new MockConfigSnapshot(recording: "false");

            using var agent = new ApmAgent(new AgentComponents(payloadSender: mockPayloadSender, configurationReader: mockConfigSnapshot));

            CreateTransactionsAndSpans(agent);

            mockPayloadSender.Transactions.Should().BeEmpty();
            mockPayloadSender.Spans.Should().BeEmpty();
            mockPayloadSender.Errors.Should().BeEmpty();
        }
示例#14
0
        public async Task ChangeTransactionIgnoreUrlsAfterStart(bool useDiagnosticSourceOnly)
        {
            // Start with default config
            var startConfigSnapshot = new MockConfigSnapshot(new NoopLogger());

            _capturedPayload = new MockPayloadSender();

            var agentComponents = new TestAgentComponents(
                _logger,
                startConfigSnapshot, _capturedPayload,
                new CurrentExecutionSegmentsContainer());

            _agent  = new ApmAgent(agentComponents);
            _client = Helper.GetClient(_agent, _factory, useDiagnosticSourceOnly);

            _client.DefaultRequestHeaders.Add("foo", "bar");
            await _client.GetAsync("/Home/SimplePage");

            _capturedPayload.WaitForTransactions();
            _capturedPayload.Transactions.Should().ContainSingle();
            _capturedPayload.FirstTransaction.Context.Request.Url.Full.ToLower().Should().Contain("simplepage");

            //change config to ignore urls with SimplePage
            var updateConfigSnapshot = new MockConfigSnapshot(
                new NoopLogger()
                , transactionIgnoreUrls: "*SimplePage*"
                );

            _agent.ConfigStore.CurrentSnapshot = updateConfigSnapshot;

            await _client.GetAsync("/Home/SimplePage");

            _capturedPayload.WaitForTransactions(TimeSpan.FromSeconds(5));

            //assert that no more transaction is captured - so still 1 captured transaction
            _capturedPayload.Transactions.Should().ContainSingle();

            //update config again
            updateConfigSnapshot = new MockConfigSnapshot(
                new NoopLogger()
                , transactionIgnoreUrls: "FooBar"
                );
            _agent.ConfigStore.CurrentSnapshot = updateConfigSnapshot;

            await _client.GetAsync("/Home/SimplePage");

            _capturedPayload.WaitForTransactions();

            //assert that the number of captured transaction increased
            _capturedPayload.Transactions.Count.Should().Be(2);
        }
示例#15
0
        private void CreateSutEnvAndTest(Action <ApmAgent, PayloadSenderV2> doAction)
        {
            var configReader           = new MockConfigSnapshot(_logger);
            var mockHttpMessageHandler = new MockHttpMessageHandler((r, c) => Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)));
            var service       = Service.GetDefaultService(configReader, _logger);
            var payloadSender = new PayloadSenderV2(_logger, configReader, service, new Api.System(), mockHttpMessageHandler
                                                    , /* dbgName: */ TestDisplayName);

            payloadSender.IsRunning.Should().BeTrue();

            using (var agent = new ApmAgent(new TestAgentComponents(LoggerBase, payloadSender: payloadSender))) doAction(agent, payloadSender);

            payloadSender.IsRunning.Should().BeFalse();
        }
示例#16
0
        public void CaptureTransactionAndSpansWithEnabledOnFalse()
        {
            var mockPayloadSender  = new MockPayloadSender();
            var mockConfigSnapshot = new MockConfigSnapshot(enabled: "false");

            using var agent = new ApmAgent(new AgentComponents(payloadSender: mockPayloadSender, configurationReader: mockConfigSnapshot));

            CreateTransactionsAndSpans(agent);

            mockPayloadSender.WaitForAny(TimeSpan.FromSeconds(5));
            mockPayloadSender.Transactions.Should().BeEmpty();
            mockPayloadSender.Spans.Should().BeEmpty();
            mockPayloadSender.Errors.Should().BeEmpty();
            mockPayloadSender.Metrics.Should().BeEmpty();
        }
        public async Task ChangeSanitizeFieldNamesAfterStart(bool useDiagnosticSourceOnly)
        {
            var startConfigSnapshot = new MockConfigSnapshot(new NoopLogger());

            _capturedPayload = new MockPayloadSender();

            var agentComponents = new TestAgentComponents(
                _logger,
                startConfigSnapshot, _capturedPayload,
                new CurrentExecutionSegmentsContainer());

            _agent  = new ApmAgent(agentComponents);
            _client = Helper.GetClient(_agent, _factory, useDiagnosticSourceOnly);

            _client.DefaultRequestHeaders.Add("foo", "bar");
            await _client.GetAsync("/Home/SimplePage");

            _capturedPayload.WaitForTransactions();
            _capturedPayload.Transactions.Should().ContainSingle();
            _capturedPayload.FirstTransaction.Context.Should().NotBeNull();
            _capturedPayload.FirstTransaction.Context.Request.Should().NotBeNull();
            _capturedPayload.FirstTransaction.Context.Request.Headers.Should().NotBeNull();

            _capturedPayload.FirstTransaction.Context.Request.Headers["foo"].Should().Be("bar");

            _capturedPayload.Clear();

            //change config to sanitize headers with "foo"
            var updateConfigSnapshot = new MockConfigSnapshot(
                new NoopLogger()
                , sanitizeFieldNames: "foo"
                );

            _agent.ConfigStore.CurrentSnapshot = updateConfigSnapshot;

            await _client.GetAsync("/Home/SimplePage");

            _capturedPayload.WaitForTransactions();
            _capturedPayload.Transactions.Should().ContainSingle();
            _capturedPayload.FirstTransaction.Context.Should().NotBeNull();
            _capturedPayload.FirstTransaction.Context.Request.Should().NotBeNull();
            _capturedPayload.FirstTransaction.Context.Request.Headers.Should().NotBeNull();

            _capturedPayload.FirstTransaction.Context.Request.Headers["foo"].Should().Be("[REDACTED]");
        }
        public void Should_Update_Logger_That_Is_ILogLevelSwitchable()
        {
            var logLevel   = LogLevel.Trace;
            var testLogger = new ConsoleLogger(logLevel);

            var configSnapshotFromReader = new MockConfigSnapshot(testLogger, logLevel: "Trace");
            var configStore = new ConfigStore(configSnapshotFromReader, testLogger);
            var service     = Service.GetDefaultService(configSnapshotFromReader, testLogger);

            var waitHandle = new ManualResetEvent(false);
            var handler    = new MockHttpMessageHandler();
            var configUrl  = BackendCommUtils.ApmServerEndpoints
                             .BuildGetConfigAbsoluteUrl(configSnapshotFromReader.ServerUrl, service);

            handler.When(configUrl.AbsoluteUri)
            .Respond(_ =>
            {
                waitHandle.Set();
                return(new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Headers = { ETag = new EntityTagHeaderValue("\"etag\"") },
                    Content = new StringContent("{ \"log_level\": \"error\" }", Encoding.UTF8)
                });
            });

            var centralConfigFetcher = new CentralConfigFetcher(testLogger, configStore, service, handler);

            using var agent = new ApmAgent(new TestAgentComponents(testLogger,
                                                                   centralConfigFetcher: centralConfigFetcher,
                                                                   payloadSender: new NoopPayloadSender()));

            centralConfigFetcher.IsRunning.Should().BeTrue();
            waitHandle.WaitOne();

            // wait up to 60 seconds for the log level to change. Change can often be slower in CI
            var count = 0;

            while (count < 60 && testLogger.LogLevelSwitch.Level == logLevel)
            {
                count++;
                Thread.Sleep(TimeSpan.FromSeconds(1));
            }

            testLogger.LogLevelSwitch.Level.Should().Be(LogLevel.Error);
        }
示例#19
0
        public void CentralConfigNoUserNamePwPrinted()
        {
            var userName = "******";
            var pw       = "def";

            var inMemoryLogger = new InMemoryBlockingLogger(LogLevel.Error);
            var configReader   = new MockConfigSnapshot(serverUrls: $"http://{userName}:{pw}@localhost:8123", maxBatchEventCount: "0",
                                                        flushInterval: "0");

            var configStore = new ConfigStore(configReader, inMemoryLogger);

            using var centralConfigFetcher =
                      new CentralConfigFetcher(inMemoryLogger, configStore, Service.GetDefaultService(configReader, inMemoryLogger));

            inMemoryLogger.Lines.Should().HaveCount(1);
            inMemoryLogger.Lines.Should().NotContain(n => n.Contains($"{userName}:{pw}"));
            inMemoryLogger.Lines.Should().Contain(n => n.Contains("http://[REDACTED]:[REDACTED]@localhost:8123"));
        }
示例#20
0
        public void PayloadSenderNoUserNamePwPrintedForServerUrl()
        {
            var userName       = "******";
            var pw             = "def";
            var inMemoryLogger = new InMemoryBlockingLogger(LogLevel.Warning);
            var configReader   = new MockConfigSnapshot(serverUrls: $"http://{userName}:{pw}@localhost:8234", maxBatchEventCount: "0",
                                                        flushInterval: "0");

            using var payloadSender = new PayloadSenderV2(inMemoryLogger, configReader,
                                                          Service.GetDefaultService(configReader, inMemoryLogger), new Api.System());

            using var agent = new ApmAgent(new AgentComponents(payloadSender: payloadSender));

            agent.Tracer.CaptureTransaction("Test", "TestTransaction", () => { });

            inMemoryLogger.Lines.Should().HaveCount(1);
            inMemoryLogger.Lines.Should().NotContain(n => n.Contains($"{userName}:{pw}"));
            inMemoryLogger.Lines.Should().Contain(n => n.Contains("http://[REDACTED]:[REDACTED]@localhost:8234"));
        }
示例#21
0
        public void SpansShouldNotBeSent_WhenTransactionMaxSpansIsEqualToZero()
        {
            // Arrange
            var mockPayloadSender = new MockPayloadSender();
            var mockConfig        = new MockConfigSnapshot(transactionMaxSpans: "0");

            // Act
            using (var agent = new ApmAgent(new TestAgentComponents(config: mockConfig, payloadSender: mockPayloadSender)))
            {
                agent.Tracer.CaptureTransaction("test transaction name", "test transaction type",
                                                transaction =>
                                                transaction.CaptureSpan("test span name", "test span type", span => { })
                                                );
            }

            // Assert
            mockPayloadSender.Transactions.Count.Should().Be(1);
            mockPayloadSender.Spans.Count.Should().Be(0);
            mockPayloadSender.FirstTransaction.SpanCount.Dropped.Should().Be(1);
        }
        public void CustomAndLabelDontThrowNullRef()
        {
            var mockPayloadSender  = new MockPayloadSender();
            var mockConfigSnapshot = new MockConfigSnapshot(enabled: "false");

            using var agent = new ApmAgent(new AgentComponents(payloadSender: mockPayloadSender, configurationReader: mockConfigSnapshot));

            var transaction = agent.Tracer.StartTransaction("foo", "bar");

            transaction.Should().BeOfType <NoopTransaction>();
            transaction.Custom["foo"] = "bar";
#pragma warning disable 618
            transaction.Labels["foo"] = "bar";
            var span = transaction.StartSpan("foo", "bar");
            span.Should().BeOfType <NoopSpan>();
            span.Labels["foo"] = "bar";
            span.End();
            transaction.End();
#pragma warning restore 618
        }
示例#23
0
        public void ShouldReturnIncludedNamespaces()
        {
            var payloadSender = new MockPayloadSender();
            var config        = new MockConfigSnapshot(applicationNamespaces: "MyApp1, Elastic.Apm.Tests., MyApp2");

            using (var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender, config: config)))
            {
                try
                {
                    // Throw the exception to generate a stacktrace
                    throw new Exception("TestMst");
                }
                catch (Exception e)
                {
                    agent.Tracer.CaptureTransaction("TestTransaction", "TestTransactionType",
                                                    t => { t.CaptureException(e); });
                }
            }

            payloadSender.FirstError.Culprit.Should().Be("Elastic.Apm.Tests.ApiTests.CulpritTests");
        }
示例#24
0
        public void GetCulpritWithLibraryFrames()
        {
            var payloadSender = new MockPayloadSender();
            var config        = new MockConfigSnapshot(excludedNamespaces: "LibraryNamespace");

            using (var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender, config: config)))
            {
                try
                {
                    // Throw the exception to generate a stacktrace
                    new ApplicationClass().Method1();
                }
                catch (Exception e)
                {
                    agent.Tracer.CaptureTransaction("TestTransaction", "TestTransactionType",
                                                    t => { t.CaptureException(e); });
                }
            }

            payloadSender.FirstError.Culprit.Should().Be("Test.Application.ApplicationClass");
        }
示例#25
0
        public void AgentDisabledBasicTransaction()
        {
            var payloadSender = new MockPayloadSender();
            var configReader  = new MockConfigSnapshot(enabled: "false");

            using var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender, config: configReader));
            agent.Tracer.CurrentTransaction.Should().BeNull();
            var transaction = agent.Tracer.StartTransaction("TestTransaction", "Test");

            transaction.Should().NotBeOfType <Transaction>();
            transaction.Should().BeOfType <NoopTransaction>();

            agent.Tracer.CurrentTransaction.Should().Be(transaction);

            transaction.End();

            payloadSender.SignalEndTransactions();
            agent.Tracer.CurrentTransaction.Should().BeNull();
            payloadSender.WaitForTransactions();
            payloadSender.Transactions.Should().BeNullOrEmpty();
        }
示例#26
0
        public void DistributionShouldBeUniform(double rate)
        {
            const int    total = 1_000_000;
            var          startCheckingAfter = Convert.ToInt32(total * 0.1);    // i.e., after 10%
            const double allowedDiffInRate  = 0.01;

            var sampledCount = 0;
            var noopLogger   = new NoopLogger();
            var currentExecutionSegmentsContainer = new NoopCurrentExecutionSegmentsContainer();
            var noopPayloadSender   = new NoopPayloadSender();
            var configurationReader = new MockConfigSnapshot(noopLogger);
            var sampler             = new Sampler(rate);

            total.Repeat(i =>
            {
                // reset current activity, otherwise all transactions share the same traceid which influences the sampling decision
                Activity.Current = null;

                var transaction = new Transaction(noopLogger, "test transaction name", "test transaction type", sampler,
                                                  /* distributedTracingData: */ null, noopPayloadSender, configurationReader, currentExecutionSegmentsContainer);
                if (transaction.IsSampled)
                {
                    ++sampledCount;
                }

                // ReSharper disable once InvertIf
                if (i + 1 >= startCheckingAfter)
                {
                    var actualRate = (double)sampledCount / (i + 1);
                    var diffInRate = actualRate - rate;
                    Assert.True(Math.Abs(diffInRate) <= allowedDiffInRate,
                                "Abs(diffInRate) should be <= allowedDiffInRate. " +
                                $"diffInRate: {diffInRate}, allowedDiffInRate: {allowedDiffInRate}, " +
                                $"i: {i}, " +
                                $"actual rate: {actualRate}, expected rate: {rate}, " +
                                $"actual sampled count: {sampledCount}, expected sampled count: {Convert.ToInt32((i + 1) * rate)}"
                                );
                }
            });
        }
示例#27
0
        public void AgentDisabledTransactionWithLambdaAndSpans()
        {
            var payloadSender = new MockPayloadSender();
            var configReader  = new MockConfigSnapshot(enabled: "false");

            using var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender, config: configReader));

            var block1Ran = false;
            var block2Ran = false;
            var block3Ran = false;

            agent.Tracer.CaptureTransaction("TestTransaction", "Test", transaction =>
            {
                block1Ran = true;
                transaction.Should().NotBeOfType <Transaction>();
                transaction.Should().BeOfType <NoopTransaction>();

                transaction.CaptureSpan("test", "test", span1 =>
                {
                    block2Ran = true;
                    span1.Should().NotBeOfType <Span>();
                    span1.Should().BeOfType <NoopSpan>();
                    span1.CaptureSpan("test2", "test", span2 =>
                    {
                        block3Ran = true;
                        span2.Should().NotBeOfType <Span>();
                        span2.Should().BeOfType <NoopSpan>();
                    });
                });
            });

            block1Ran.Should().BeTrue();
            block2Ran.Should().BeTrue();
            block3Ran.Should().BeTrue();

            payloadSender.SignalEndTransactions();
            payloadSender.WaitForAny();
            payloadSender.Transactions.Should().BeNullOrEmpty();
            payloadSender.Spans.Should().BeNullOrEmpty();
        }
        public void AgentDisabledTransactionWithLambda()
        {
            var payloadSender = new MockPayloadSender();
            var configReader  = new MockConfigSnapshot(enabled: "false");

            using var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender, config: configReader));
            var codeExecuted = false;

            agent.Tracer.CaptureTransaction("TestTransaction", "Test", transaction =>
            {
                codeExecuted = true;
                transaction.Should().NotBeOfType <Transaction>();
                transaction.Should().BeOfType <NoopTransaction>();

                // ReSharper disable AccessToDisposedClosure
                agent.Tracer.CurrentTransaction.Should().NotBeNull();
                agent.Tracer.CurrentTransaction.Should().Be(transaction);
            });

            codeExecuted.Should().BeTrue();
            payloadSender.Transactions.Should().BeNullOrEmpty();
        }
        public void AgentDisabledCaptureErrors()
        {
            var payloadSender = new MockPayloadSender();
            var configReader  = new MockConfigSnapshot(enabled: "false");

            using var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender, config: configReader));

            agent.Tracer.CaptureTransaction("foo", "bar", transaction =>
            {
                transaction.CaptureError("foo", "bar", new StackTrace().GetFrames());
                transaction.CaptureException(new Exception());

                transaction.CaptureSpan("foo", "bar", span =>
                {
                    span.CaptureError("foo", "bar", new StackTrace().GetFrames());
                    span.CaptureException(new Exception());
                });
            });

            payloadSender.Transactions.Should().BeNullOrEmpty();
            payloadSender.Spans.Should().BeNullOrEmpty();
        }
示例#30
0
        public void VerifyServerCert_Should_Allow_Https_To_Apm_Server()
        {
            var configuration = new MockConfigSnapshot(
                serverUrl: $"https://localhost:{_port}",
                verifyServerCert: "false",
                disableMetrics: "*",
                cloudProvider: "none");

            using var agent = new ApmAgent(new AgentComponents(_logger, configuration));
            agent.Tracer.CaptureTransaction("TestTransaction", "TestType", t =>
            {
                t.SetLabel("verify_server_cert", false);
            });

            var signalled = _waitHandle.WaitOne(TimeSpan.FromMinutes(2));

            signalled.Should().BeTrue("timed out waiting to receive transaction");

            _server.ReceivedData.Transactions.Should().HaveCount(1);
            var transaction = _server.ReceivedData.Transactions.First();

            transaction.Context.Labels.MergedDictionary.Should().ContainKey("verify_server_cert");
        }