public async Task CaptureAutoInstrumentedSpans(string targetFramework)
        {
            if (!TestEnvironment.IsWindows)
            {
                return;
            }

            var apmLogger = new InMemoryBlockingLogger(Elastic.Apm.Logging.LogLevel.Error);
            var apmServer = new MockApmServer(apmLogger, nameof(CaptureAutoInstrumentedSpans));
            var port      = apmServer.FindAvailablePortToListen();

            apmServer.RunInBackground(port);

            using (var profiledApplication = new ProfiledApplication("OracleManagedDataAccessSample"))
            {
                IDictionary <string, string> environmentVariables = new Dictionary <string, string>
                {
                    ["ELASTIC_APM_SERVER_URL"]      = $"http://localhost:{port}",
                    ["ORACLE_CONNECTION_STRING"]    = _fixture.ConnectionString,
                    ["ELASTIC_APM_DISABLE_METRICS"] = "*",
                    // to fix ORA-01882 Timezone region not found on CI.
                    ["TZ"] = "GMT",
                    ["ELASTIC_APM_EXIT_SPAN_MIN_DURATION"]   = "0",
                    ["ELASTIC_APM_SPAN_COMPRESSION_ENABLED"] = "false"
                };

                profiledApplication.Start(
                    targetFramework,
                    TimeSpan.FromMinutes(2),
                    environmentVariables,
                    null,
                    line => _output.WriteLine(line.Line),
                    exception => _output.WriteLine($"{exception}"));
            }

            apmServer.ReceivedData.Transactions.Should().HaveCount(2);
            apmServer.ReceivedData.Spans.Should().HaveCount(AdoNetTestData.DbRunnerExpectedTotalSpans + AdoNetTestData.OracleProviderExpectedSpans);

            var testSpans = apmServer.ReceivedData.Spans
                            .Where(s => !s.Name.StartsWith(AdoNetTestData.OracleProviderSpanNameStart))
                            .ToList();

            var genericTransaction = apmServer.ReceivedData.Transactions.FirstOrDefault(t => t.Name == "RunAllAsync<TDbCommand>");

            genericTransaction.Should().NotBeNull();

            var genericSpans = testSpans.Where(s => s.TransactionId == genericTransaction.Id).ToList();

            genericSpans.Should().HaveCount(AdoNetTestData.DbRunnerExpectedRunAllAsyncSpans);

            var baseTransaction = apmServer.ReceivedData.Transactions.FirstOrDefault(t => t.Name == "RunBaseTypesAsync");

            baseTransaction.Should().NotBeNull();

            var baseSpans = testSpans.Where(s => s.TransactionId == baseTransaction.Id).ToList();

            baseSpans.Should().HaveCount(AdoNetTestData.DbRunnerExpectedRunBaseTypesAsyncSpans);

            await apmServer.StopAsync();
        }
示例#2
0
        public async Task CaptureAutoInstrumentedSpans(string targetFramework)
        {
            var apmLogger = new InMemoryBlockingLogger(Elastic.Apm.Logging.LogLevel.Error);
            var apmServer = new MockApmServer(apmLogger, nameof(CaptureAutoInstrumentedSpans));
            var port      = apmServer.FindAvailablePortToListen();

            apmServer.RunInBackground(port);

            using (var profiledApplication = new ProfiledApplication("MySqlDataSample"))
            {
                IDictionary <string, string> environmentVariables = new Dictionary <string, string>
                {
                    ["ELASTIC_APM_SERVER_URL"]               = $"http://localhost:{port}",
                    ["MYSQL_CONNECTION_STRING"]              = _fixture.ConnectionString,
                    ["ELASTIC_APM_DISABLE_METRICS"]          = "*",
                    ["ELASTIC_APM_EXIT_SPAN_MIN_DURATION"]   = "0",
                    ["ELASTIC_APM_SPAN_COMPRESSION_ENABLED"] = "false"
                };

                profiledApplication.Start(
                    targetFramework,
                    TimeSpan.FromMinutes(2),
                    environmentVariables,
                    null,
                    line => _output.WriteLine(line.Line),
                    exception => _output.WriteLine($"{exception}"));
            }

            // RunAllAsync<TDbCommand> transaction
            // RunBaseTypesAsync transaction
            apmServer.ReceivedData.Transactions.Should().HaveCount(2);

            // The first MySqlCommand on an opened MySqlConnection executes an additional
            // command that the profiler instrumentation will create a span for. Since there
            // are two connections opened, 1 for RunAllAsync<TDbCommand> and 1 for RunBaseTypesAsync,
            // expect 2 additional spans
            apmServer.ReceivedData.Spans.Should().HaveCount(AdoNetTestData.DbRunnerExpectedTotalSpans + 2);

            var genericTransaction = apmServer.ReceivedData.Transactions.FirstOrDefault(t => t.Name == "RunAllAsync<TDbCommand>");

            genericTransaction.Should().NotBeNull();

            var genericSpans = apmServer.ReceivedData.Spans.Where(s => s.TransactionId == genericTransaction.Id).ToList();

            genericSpans.Should().HaveCount(AdoNetTestData.DbRunnerExpectedRunAllAsyncSpans + 1);

            var baseTransaction = apmServer.ReceivedData.Transactions.FirstOrDefault(t => t.Name == "RunBaseTypesAsync");

            baseTransaction.Should().NotBeNull();

            var baseSpans = apmServer.ReceivedData.Spans.Where(s => s.TransactionId == baseTransaction.Id).ToList();

            baseSpans.Should().HaveCount(AdoNetTestData.DbRunnerExpectedRunBaseTypesAsyncSpans + 1);

            await apmServer.StopAsync();
        }
        public async Task CaptureAutoInstrumentedSpans(string targetFramework, string npgsqlVersion)
        {
            var apmLogger = new InMemoryBlockingLogger(Elastic.Apm.Logging.LogLevel.Error);
            var apmServer = new MockApmServer(apmLogger, nameof(CaptureAutoInstrumentedSpans));
            var port      = apmServer.FindAvailablePortToListen();

            apmServer.RunInBackground(port);

            using (var profiledApplication = new ProfiledApplication("NpgsqlSample"))
            {
                var environmentVariables = new Dictionary <string, string>
                {
                    ["ELASTIC_APM_SERVER_URL"]               = $"http://localhost:{port}",
                    ["POSTGRES_CONNECTION_STRING"]           = _fixture.ConnectionString,
                    ["ELASTIC_APM_DISABLE_METRICS"]          = "*",
                    ["ELASTIC_APM_EXIT_SPAN_MIN_DURATION"]   = "0",
                    ["ELASTIC_APM_SPAN_COMPRESSION_ENABLED"] = "false"
                };

                var msBuildProperties = npgsqlVersion is null
                                        ? null
                                        : new Dictionary <string, string> {
                    ["NpgsqlVersion"] = npgsqlVersion
                };

                profiledApplication.Start(
                    targetFramework,
                    TimeSpan.FromMinutes(2),
                    environmentVariables,
                    msBuildProperties,
                    line => _output.WriteLine(line.Line),
                    exception => _output.WriteLine($"{exception}"));
            }

            apmServer.ReceivedData.Transactions.Should().HaveCount(2);
            apmServer.ReceivedData.Spans.Should().HaveCount(AdoNetTestData.DbRunnerExpectedTotalSpans);

            var genericTransaction = apmServer.ReceivedData.Transactions.FirstOrDefault(t => t.Name == "RunAllAsync<TDbCommand>");

            genericTransaction.Should().NotBeNull();

            var genericSpans = apmServer.ReceivedData.Spans.Where(s => s.TransactionId == genericTransaction.Id).ToList();

            genericSpans.Should().HaveCount(AdoNetTestData.DbRunnerExpectedRunAllAsyncSpans);

            var baseTransaction = apmServer.ReceivedData.Transactions.FirstOrDefault(t => t.Name == "RunBaseTypesAsync");

            baseTransaction.Should().NotBeNull();

            var baseSpans = apmServer.ReceivedData.Spans.Where(s => s.TransactionId == baseTransaction.Id).ToList();

            baseSpans.Should().HaveCount(AdoNetTestData.DbRunnerExpectedRunBaseTypesAsyncSpans);

            await apmServer.StopAsync();
        }
示例#4
0
        public async Task CaptureAutoInstrumentedSpans(string targetFramework)
        {
            var apmLogger = new InMemoryBlockingLogger(Logging.LogLevel.Error);
            var apmServer = new MockApmServer(apmLogger, nameof(CaptureAutoInstrumentedSpans));
            var port      = apmServer.FindAvailablePortToListen();

            apmServer.RunInBackground(port);

            using (var profiledApplication = new ProfiledApplication("RabbitMqSample"))
            {
                IDictionary <string, string> environmentVariables = new Dictionary <string, string>
                {
                    ["RABBITMQ_HOST"]                     = _fixture.ConnectionString,
                    ["ELASTIC_APM_SERVER_URL"]            = $"http://localhost:{port}",
                    ["ELASTIC_APM_DISABLE_METRICS"]       = "*",
                    ["ELASTIC_APM_IGNORE_MESSAGE_QUEUES"] = "test-ignore-exchange-name,test-ignore-queue-name"
                };

                profiledApplication.Start(
                    targetFramework,
                    TimeSpan.FromMinutes(2),
                    environmentVariables,
                    null,
                    line => _output.WriteLine(line.Line),
                    exception => _output.WriteLine($"{exception}"));
            }

            var transactions = apmServer.ReceivedData.Transactions;
            var spans        = apmServer.ReceivedData.Spans;

            transactions.Should().HaveCount(9);

            var ignoreTransaction = transactions.Single(t => t.Name == "PublishAndGetIgnore");

            // don't capture any spans for ignored queues and messages
            spans.Where(s => s.TransactionId == ignoreTransaction.Id).Should().BeEmpty();

            var publishAndGetTransaction = transactions.Single(t => t.Name == "PublishAndGet");

            spans.Where(s => s.TransactionId == publishAndGetTransaction.Id).Should().HaveCount(3, "PublishAndGet");

            var publishAndGetDefaultTransaction = transactions.Single(t => t.Name == "PublishAndGetDefault");

            spans.Where(s => s.TransactionId == publishAndGetDefaultTransaction.Id).Should().HaveCount(3, "PublishAndGetDefault");

            var senderTransactions = transactions.Where(t => t.Name == "PublishToConsumer").ToList();

            senderTransactions.Should().HaveCount(3, "PublishToConsumer");

            var consumeTransactions = transactions.Where(t => t.Name.StartsWith("RabbitMQ RECEIVE from")).ToList();

            consumeTransactions.Should().HaveCount(3, "RabbitMQ RECEIVE from");

            foreach (var senderTransaction in senderTransactions)
            {
                var senderSpan = spans.FirstOrDefault(s => s.TransactionId == senderTransaction.Id);
                senderSpan.Should().NotBeNull();

                var tracingTransaction = consumeTransactions.FirstOrDefault(t => t.TraceId == senderTransaction.TraceId);
                tracingTransaction.Should().NotBeNull();
                tracingTransaction.ParentId.Should().Be(senderSpan.Id);
            }

            foreach (var consumeTransaction in consumeTransactions)
            {
                spans.Where(s => s.TransactionId == consumeTransaction.Id).Should().HaveCount(1);
            }

            await apmServer.StopAsync();
        }
示例#5
0
        public async Task CaptureAutoInstrumentedSpans(string targetFramework)
        {
            var apmLogger = new InMemoryBlockingLogger(Elastic.Apm.Logging.LogLevel.Error);
            var apmServer = new MockApmServer(apmLogger, nameof(CaptureAutoInstrumentedSpans));
            var port      = apmServer.FindAvailablePortToListen();

            apmServer.RunInBackground(port);

            var ignoreTopic = "ignore-topic";

            using (var profiledApplication = new ProfiledApplication("KafkaSample"))
            {
                IDictionary <string, string> environmentVariables = new Dictionary <string, string>
                {
                    ["KAFKA_HOST"]                        = _fixture.BootstrapServers,
                    ["ELASTIC_APM_SERVER_URL"]            = $"http://localhost:{port}",
                    ["ELASTIC_APM_DISABLE_METRICS"]       = "*",
                    ["ELASTIC_APM_IGNORE_MESSAGE_QUEUES"] = ignoreTopic
                };

                profiledApplication.Start(
                    targetFramework,
                    TimeSpan.FromMinutes(2),
                    environmentVariables,
                    line => _output.WriteLine(line.Line),
                    exception => _output.WriteLine($"{exception}"));
            }

            // 6 * 10 consume transactions, 14 produce transactions
            var transactions = apmServer.ReceivedData.Transactions;

            transactions.Should().HaveCount(74);

            var consumeTransactions = transactions.Where(t => t.Name.StartsWith("Kafka RECEIVE")).ToList();

            consumeTransactions.Should().HaveCount(60);

            foreach (var consumeTransaction in consumeTransactions)
            {
                var spans = apmServer.ReceivedData.Spans.Where(s => s.TransactionId == consumeTransaction.Id);
                spans.Should().HaveCount(1);
                consumeTransaction.Context.Message.Queue.Should().NotBeNull();
                consumeTransaction.Context.Message.Queue.Name.Should().NotBeNullOrEmpty();
                consumeTransaction.ParentId.Should().NotBeNull();
            }

            var produceTransactions = transactions.Where(t => !t.Name.StartsWith("Kafka RECEIVE")).ToList();

            produceTransactions.Should().HaveCount(14);

            foreach (var produceTransaction in produceTransactions)
            {
                var spans = apmServer.ReceivedData.Spans.Where(s => s.TransactionId == produceTransaction.Id).ToList();

                if (produceTransaction.Name.Contains("INVALID-TOPIC"))
                {
                    spans.Should().HaveCount(1);
                }
                // the produce transaction shouldn't have an auto instrumented publish span as topic is ignored
                else if (produceTransaction.Name.Contains(ignoreTopic))
                {
                    spans.Should().BeEmpty();
                }
                else
                {
                    spans.Should().HaveCount(10);
                }

                foreach (var span in spans)
                {
                    span.Context.Message.Should().NotBeNull();
                    span.Context.Message.Queue.Should().NotBeNull();
                    span.Context.Message.Queue.Name.Should().NotBeNullOrEmpty();
                }
            }

            await apmServer.StopAsync();
        }