From 1e5029830e860101be56dcd08a6bc8e48824097a Mon Sep 17 00:00:00 2001 From: Andrew Lock Date: Mon, 24 Oct 2022 19:05:12 +0100 Subject: [PATCH] Add better fallback for Lambda service name (#3378) * minor refactor: extract handler name variable immediately when running in Lambda * Use provided handler assembly name as default fallback service name in AWS Lambda * Remove explicit DD_SERVICE from handler containers To verify that the fallback is used correctly * Fix snapshot capitalisation --- docker-compose.serverless.yml | 29 ----- .../LambdaHandler.cs | 5 +- .../ServerlessInstrumentation/Serverless.cs | 94 +++++++++----- .../src/Datadog.Trace/TracerManagerFactory.cs | 6 + .../Datadog.Trace.Tests/ServerlessTests.cs | 69 +++++++++-- .../snapshots/AwsLambdaTests.verified.txt | 116 +++++++++--------- 6 files changed, 188 insertions(+), 131 deletions(-) diff --git a/docker-compose.serverless.yml b/docker-compose.serverless.yml index 17b894b154af..1633daea8745 100644 --- a/docker-compose.serverless.yml +++ b/docker-compose.serverless.yml @@ -149,7 +149,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -173,7 +172,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -197,7 +195,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -221,7 +218,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -245,7 +241,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -269,7 +264,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -293,7 +287,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -317,7 +310,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -341,7 +333,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -365,7 +356,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -389,7 +379,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -413,7 +402,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -437,7 +425,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -461,7 +448,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -485,7 +471,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -509,7 +494,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -533,7 +517,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -557,7 +540,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -581,7 +563,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -605,7 +586,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -629,7 +609,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -653,7 +632,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -677,7 +655,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -701,7 +678,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -725,7 +701,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -749,7 +724,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -773,7 +747,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -797,7 +770,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: @@ -821,7 +793,6 @@ services: - DUMMY_API_HOST=http://serverless-dummy-api:9005 - DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 - DD_TRACE_DEBUG=1 - - DD_SERVICE=Samples.Aws.Lambda ports: - "8080" volumes: diff --git a/tracer/src/Datadog.Trace/ClrProfiler/ServerlessInstrumentation/LambdaHandler.cs b/tracer/src/Datadog.Trace/ClrProfiler/ServerlessInstrumentation/LambdaHandler.cs index e8ea6ff482a2..07ab18571289 100644 --- a/tracer/src/Datadog.Trace/ClrProfiler/ServerlessInstrumentation/LambdaHandler.cs +++ b/tracer/src/Datadog.Trace/ClrProfiler/ServerlessInstrumentation/LambdaHandler.cs @@ -13,7 +13,8 @@ namespace Datadog.Trace.ClrProfiler.ServerlessInstrumentation; internal class LambdaHandler { - private static readonly string[] Separator = { "::" }; + internal const string Separator = "::"; + private static readonly string[] Separators = { "::" }; internal LambdaHandler(string? handlerName) { @@ -22,7 +23,7 @@ internal LambdaHandler(string? handlerName) ThrowHelper.ThrowArgumentNullException(nameof(handlerName)); } - var handlerTokens = handlerName.Split(Separator, StringSplitOptions.None); + var handlerTokens = handlerName.Split(Separators, StringSplitOptions.None); if (handlerTokens.Length != 3) { ThrowHelper.ThrowArgumentException($"The handler name {handlerName} did not have the expected format A::B::C"); diff --git a/tracer/src/Datadog.Trace/ClrProfiler/ServerlessInstrumentation/Serverless.cs b/tracer/src/Datadog.Trace/ClrProfiler/ServerlessInstrumentation/Serverless.cs index f6ac5c70d963..938a58d36c9c 100644 --- a/tracer/src/Datadog.Trace/ClrProfiler/ServerlessInstrumentation/Serverless.cs +++ b/tracer/src/Datadog.Trace/ClrProfiler/ServerlessInstrumentation/Serverless.cs @@ -13,7 +13,6 @@ namespace Datadog.Trace.ClrProfiler.ServerlessInstrumentation internal static class Serverless { private const string DefinitionsId = "68224F20D001430F9400668DD25245BA"; - private const string HandlerEnvName = "_HANDLER"; private const string LogLevelEnvName = "DD_LOG_LEVEL"; private static NativeCallTargetDefinition[] callTargetDefinitions = null; @@ -22,44 +21,22 @@ internal static class Serverless internal static void InitIfNeeded() { - if (Metadata.IsRunningInLambda) + if (Metadata is { IsRunningInLambda: true, HandlerName: var handlerName }) { + if (string.IsNullOrEmpty(handlerName)) + { + Error("Error initializing serverless integration: handler name not found"); + return; + } + Debug("Sending CallTarget serverless integration definitions to native library."); - var serverlessDefinitions = GetServerlessDefinitions(); + var serverlessDefinitions = GetServerlessDefinitions(handlerName); NativeMethods.InitializeProfiler(DefinitionsId, serverlessDefinitions); Debug("The profiler has been initialized with serverless definitions, count = " + serverlessDefinitions.Length); } } - internal static NativeCallTargetDefinition[] GetServerlessDefinitions() - { - try - { - if (callTargetDefinitions == null) - { - LambdaHandler handler = new LambdaHandler(EnvironmentHelpers.GetEnvironmentVariable(HandlerEnvName)); - var assemblyName = typeof(InstrumentationDefinitions).Assembly.FullName; - var paramCount = handler.ParamTypeArray.Length; - - var integrationType = GetIntegrationType(handler.ParamTypeArray[0], paramCount); - callTargetDefinitions = new NativeCallTargetDefinition[] - { - new(handler.Assembly, handler.FullType, handler.MethodName, handler.ParamTypeArray, 0, 0, 0, 65535, 65535, 65535, assemblyName, integrationType) - }; - - LifetimeManager.Instance.AddShutdownTask(RunShutdown); - } - - return callTargetDefinitions; - } - catch (Exception ex) - { - Error("Impossible to get Serverless Definitions", ex); - return Array.Empty(); - } - } - internal static string GetIntegrationType(string returnType, int paramCount) { var inputParamCount = paramCount - 1; // since the return type is in the array @@ -144,22 +121,57 @@ private static void RunShutdown() callTargetDefinitions = null; } + private static NativeCallTargetDefinition[] GetServerlessDefinitions(string handlerName) + { + try + { + if (callTargetDefinitions == null) + { + LambdaHandler handler = new LambdaHandler(handlerName); + var assemblyName = typeof(InstrumentationDefinitions).Assembly.FullName; + var paramCount = handler.ParamTypeArray.Length; + + var integrationType = GetIntegrationType(handler.ParamTypeArray[0], paramCount); + callTargetDefinitions = new NativeCallTargetDefinition[] + { + new(handler.Assembly, handler.FullType, handler.MethodName, handler.ParamTypeArray, 0, 0, 0, 65535, 65535, 65535, assemblyName, integrationType) + }; + + LifetimeManager.Instance.AddShutdownTask(RunShutdown); + } + + return callTargetDefinitions; + } + catch (Exception ex) + { + Error("Impossible to get Serverless Definitions", ex); + return Array.Empty(); + } + } + internal class LambdaMetadata { private const string ExtensionEnvName = "_DD_EXTENSION_PATH"; private const string ExtensionFullPath = "/opt/extensions/datadog-agent"; private const string FunctionEnvame = "AWS_LAMBDA_FUNCTION_NAME"; + private const string HandlerEnvName = "_HANDLER"; - public LambdaMetadata(bool isRunningInLambda, string functionName) + private LambdaMetadata(bool isRunningInLambda, string functionName, string handlerName, string serviceName) { IsRunningInLambda = isRunningInLambda; FunctionName = functionName; + HandlerName = handlerName; + ServiceName = serviceName; } public bool IsRunningInLambda { get; } public string FunctionName { get; } + public string HandlerName { get; } + + public string ServiceName { get; } + /// /// Gets the paths we don't want to trace when running in Lambda /// @@ -173,7 +185,23 @@ public static LambdaMetadata Create(string extensionPath = ExtensionFullPath) && File.Exists( EnvironmentHelpers.GetEnvironmentVariable(ExtensionEnvName) ?? extensionPath); - return new LambdaMetadata(isRunningInLambda, functionName); + + if (!isRunningInLambda) + { + // the other values are irrelevant, so don't bother setting them + return new LambdaMetadata(isRunningInLambda: false, functionName, handlerName: null, serviceName: null); + } + + var handlerName = EnvironmentHelpers.GetEnvironmentVariable(HandlerEnvName); + var serviceName = handlerName?.IndexOf(LambdaHandler.Separator, StringComparison.Ordinal) switch + { + null => null, // not provided + 0 => null, // invalid handler name (no assembly) + -1 => handlerName, // top level function style + { } i => handlerName.Substring(0, i), // three part function style + }; + + return new LambdaMetadata(isRunningInLambda: true, functionName, handlerName, serviceName); } } } diff --git a/tracer/src/Datadog.Trace/TracerManagerFactory.cs b/tracer/src/Datadog.Trace/TracerManagerFactory.cs index 6aeb432f88d4..f44643782ae6 100644 --- a/tracer/src/Datadog.Trace/TracerManagerFactory.cs +++ b/tracer/src/Datadog.Trace/TracerManagerFactory.cs @@ -12,6 +12,7 @@ using Datadog.Trace.Agent.DiscoveryService; using Datadog.Trace.AppSec; using Datadog.Trace.ClrProfiler; +using Datadog.Trace.ClrProfiler.ServerlessInstrumentation; using Datadog.Trace.Configuration; using Datadog.Trace.ContinuousProfiler; using Datadog.Trace.DataStreamsMonitoring; @@ -286,6 +287,11 @@ private static string GetApplicationName() return AzureAppServices.Metadata.SiteName; } + if (Serverless.Metadata is { IsRunningInLambda: true, ServiceName: var serviceName }) + { + return serviceName; + } + try { if (TryLoadAspNetSiteName(out var siteName)) diff --git a/tracer/test/Datadog.Trace.Tests/ServerlessTests.cs b/tracer/test/Datadog.Trace.Tests/ServerlessTests.cs index f359e12b8448..50539c79f21c 100644 --- a/tracer/test/Datadog.Trace.Tests/ServerlessTests.cs +++ b/tracer/test/Datadog.Trace.Tests/ServerlessTests.cs @@ -4,6 +4,7 @@ // using System; +using System.Collections.Generic; using System.IO; using Datadog.Trace.ClrProfiler.ServerlessInstrumentation; @@ -12,57 +13,107 @@ namespace Datadog.Trace.Tests { - public class ServerlessTests + public class ServerlessTests : IDisposable { private const string FunctionNameEnvVar = "AWS_LAMBDA_FUNCTION_NAME"; + private const string HandlerEnvVar = "_HANDLER"; + private readonly Dictionary _originalEnvVars; + + public ServerlessTests() + { + _originalEnvVars = new() + { + { FunctionNameEnvVar, Environment.GetEnvironmentVariable(FunctionNameEnvVar) }, + { HandlerEnvVar, Environment.GetEnvironmentVariable(HandlerEnvVar) }, + }; + } + + public void Dispose() + { + foreach (var originalEnvVar in _originalEnvVars) + { + Environment.SetEnvironmentVariable(originalEnvVar.Key, originalEnvVar.Value); + } + } [Fact] public void IsRunningInLambdaFalseNoFileAndNoEnvironmentVariable() { - var originalValue = Environment.GetEnvironmentVariable(FunctionNameEnvVar); Environment.SetEnvironmentVariable(FunctionNameEnvVar, string.Empty); string path = Directory.GetCurrentDirectory() + "/invalid"; var res = Serverless.LambdaMetadata.Create(path); - Environment.SetEnvironmentVariable(FunctionNameEnvVar, originalValue); res.IsRunningInLambda.Should().BeFalse(); } [Fact] public void IsRunningInLambdaFalseNoFileAndEnvironmentVariable() { - var originalValue = Environment.GetEnvironmentVariable(FunctionNameEnvVar); Environment.SetEnvironmentVariable(FunctionNameEnvVar, "my-test-function"); string path = Directory.GetCurrentDirectory() + "/invalid"; var res = Serverless.LambdaMetadata.Create(path); - Environment.SetEnvironmentVariable(FunctionNameEnvVar, originalValue); res.IsRunningInLambda.Should().BeFalse(); } [Fact] public void IsRunningInLambdaFalseFileAndNoEnvironmentVariable() { - var originalValue = Environment.GetEnvironmentVariable(FunctionNameEnvVar); Environment.SetEnvironmentVariable(FunctionNameEnvVar, string.Empty); string currentDirectory = Directory.GetCurrentDirectory(); string existingFile = Directory.GetFiles(currentDirectory)[0]; var res = Serverless.LambdaMetadata.Create(existingFile); - Environment.SetEnvironmentVariable(FunctionNameEnvVar, originalValue); res.IsRunningInLambda.Should().BeFalse(); } [Fact] public void IsRunningInLambdaTrue() { - var originalValue = Environment.GetEnvironmentVariable(FunctionNameEnvVar); Environment.SetEnvironmentVariable(FunctionNameEnvVar, "my-test-function"); string currentDirectory = Directory.GetCurrentDirectory(); string existingFile = Directory.GetFiles(currentDirectory)[0]; var res = Serverless.LambdaMetadata.Create(existingFile); - Environment.SetEnvironmentVariable(FunctionNameEnvVar, originalValue); res.IsRunningInLambda.Should().BeTrue(); res.FunctionName.Should().Be("my-test-function"); } + [Theory] + [InlineData(null, null)] + [InlineData("", null)] + [InlineData("SomeValue", "SomeValue")] + public void Extracts_Handler(string handler, string expectedHandler) + { + Environment.SetEnvironmentVariable(FunctionNameEnvVar, "my-test-function"); + Environment.SetEnvironmentVariable(HandlerEnvVar, handler); + string currentDirectory = Directory.GetCurrentDirectory(); + string existingFile = Directory.GetFiles(currentDirectory)[0]; + + var res = Serverless.LambdaMetadata.Create(existingFile); + + res.IsRunningInLambda.Should().BeTrue(); + res.FunctionName.Should().Be("my-test-function"); + res.HandlerName.Should().Be(expectedHandler); + } + + [Theory] + [InlineData(null, null)] + [InlineData("", null)] + [InlineData("SomeValue", "SomeValue")] + [InlineData("::Invalid::Name", null)] + [InlineData("AssemblyName::Some::Value", "AssemblyName")] + [InlineData("AssemblyNameNotValidButOk::", "AssemblyNameNotValidButOk")] + public void Extracts_ServiceFromHandler(string handler, string expectedService) + { + Environment.SetEnvironmentVariable(FunctionNameEnvVar, "my-test-function"); + Environment.SetEnvironmentVariable(HandlerEnvVar, handler); + string currentDirectory = Directory.GetCurrentDirectory(); + string existingFile = Directory.GetFiles(currentDirectory)[0]; + + var res = Serverless.LambdaMetadata.Create(existingFile); + + res.IsRunningInLambda.Should().BeTrue(); + res.FunctionName.Should().Be("my-test-function"); + res.ServiceName.Should().Be(expectedService); + } + [Fact] public void GetSyncIntegrationTypeFromParamCountZero() { diff --git a/tracer/test/snapshots/AwsLambdaTests.verified.txt b/tracer/test/snapshots/AwsLambdaTests.verified.txt index 651160b6d8a2..0561c417765b 100644 --- a/tracer/test/snapshots/AwsLambdaTests.verified.txt +++ b/tracer/test/snapshots/AwsLambdaTests.verified.txt @@ -300,7 +300,7 @@ SpanId: Id_59, Name: manual.HandlerNoParamSync, Resource: manual.HandlerNoParamSync, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_2, Tags: { language: dotnet, @@ -319,7 +319,7 @@ SpanId: Id_60, Name: manual.HandlerOneParamSync, Resource: manual.HandlerOneParamSync, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_4, Tags: { language: dotnet, @@ -338,7 +338,7 @@ SpanId: Id_61, Name: manual.HandlerTwoParamsSync, Resource: manual.HandlerTwoParamsSync, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_6, Tags: { language: dotnet, @@ -357,7 +357,7 @@ SpanId: Id_62, Name: manual.HandlerNoParamAsync, Resource: manual.HandlerNoParamAsync, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_8, Tags: { language: dotnet, @@ -376,7 +376,7 @@ SpanId: Id_63, Name: manual.HandlerOneParamAsync, Resource: manual.HandlerOneParamAsync, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_10, Tags: { language: dotnet, @@ -395,7 +395,7 @@ SpanId: Id_64, Name: manual.HandlerTwoParamsAsync, Resource: manual.HandlerTwoParamsAsync, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_12, Tags: { language: dotnet, @@ -414,7 +414,7 @@ SpanId: Id_65, Name: manual.HandlerNoParamVoid, Resource: manual.HandlerNoParamVoid, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_14, Tags: { language: dotnet, @@ -433,7 +433,7 @@ SpanId: Id_66, Name: manual.HandlerOneParamVoid, Resource: manual.HandlerOneParamVoid, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_16, Tags: { language: dotnet, @@ -452,7 +452,7 @@ SpanId: Id_67, Name: manual.HandlerTwoParamsVoid, Resource: manual.HandlerTwoParamsVoid, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_18, Tags: { language: dotnet, @@ -471,7 +471,7 @@ SpanId: Id_68, Name: manual.HandlerNoParamSyncWithContext, Resource: manual.HandlerNoParamSyncWithContext, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_20, Tags: { language: dotnet, @@ -489,7 +489,7 @@ SpanId: Id_69, Name: manual.HandlerOneParamSyncWithContext, Resource: manual.HandlerOneParamSyncWithContext, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_22, Tags: { language: dotnet, @@ -507,7 +507,7 @@ SpanId: Id_70, Name: manual.HandlerTwoParamsSyncWithContext, Resource: manual.HandlerTwoParamsSyncWithContext, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_24, Tags: { language: dotnet, @@ -525,7 +525,7 @@ SpanId: Id_71, Name: manual.BaseHandlerNoParamSync, Resource: manual.BaseHandlerNoParamSync, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_26, Tags: { language: dotnet, @@ -544,7 +544,7 @@ SpanId: Id_72, Name: manual.BaseHandlerTwoParamsSync, Resource: manual.BaseHandlerTwoParamsSync, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_28, Tags: { language: dotnet, @@ -563,7 +563,7 @@ SpanId: Id_73, Name: manual.BaseHandlerOneParamSyncWithContext, Resource: manual.BaseHandlerOneParamSyncWithContext, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_30, Tags: { language: dotnet, @@ -581,7 +581,7 @@ SpanId: Id_74, Name: manual.BaseHandlerOneParamAsync, Resource: manual.BaseHandlerOneParamAsync, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_32, Tags: { language: dotnet, @@ -600,7 +600,7 @@ SpanId: Id_75, Name: manual.BaseHandlerTwoParamsVoid, Resource: manual.BaseHandlerTwoParamsVoid, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_34, Tags: { language: dotnet, @@ -619,7 +619,7 @@ SpanId: Id_76, Name: manual.HandlerStructParam, Resource: manual.HandlerStructParam, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_36, Tags: { language: dotnet, @@ -638,7 +638,7 @@ SpanId: Id_77, Name: manual.HandlerNestedClassParam, Resource: manual.HandlerNestedClassParam, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_38, Tags: { language: dotnet, @@ -657,7 +657,7 @@ SpanId: Id_78, Name: manual.HandlerNestedStructParam, Resource: manual.HandlerNestedStructParam, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_40, Tags: { language: dotnet, @@ -676,7 +676,7 @@ SpanId: Id_79, Name: manual.HandlerGenericDictionaryParam, Resource: manual.HandlerGenericDictionaryParam, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_42, Tags: { language: dotnet, @@ -695,7 +695,7 @@ SpanId: Id_80, Name: manual.HandlerNestedGenericDictionaryParam, Resource: manual.HandlerNestedGenericDictionaryParam, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_44, Tags: { language: dotnet, @@ -714,7 +714,7 @@ SpanId: Id_81, Name: manual.HandlerDoublyNestedGenericDictionaryParam, Resource: manual.HandlerDoublyNestedGenericDictionaryParam, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_46, Tags: { language: dotnet, @@ -733,7 +733,7 @@ SpanId: Id_82, Name: manual.ThrowingHandler, Resource: manual.ThrowingHandler, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_48, Tags: { language: dotnet, @@ -752,7 +752,7 @@ SpanId: Id_83, Name: manual.ThrowingHandlerAsync, Resource: manual.ThrowingHandlerAsync, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_50, Tags: { language: dotnet, @@ -771,7 +771,7 @@ SpanId: Id_84, Name: manual.ThrowingHandlerAsyncTask, Resource: manual.ThrowingHandlerAsyncTask, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_52, Tags: { language: dotnet, @@ -790,7 +790,7 @@ SpanId: Id_85, Name: manual.ThrowingHandler, Resource: manual.ThrowingHandler, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_54, Tags: { language: dotnet, @@ -808,7 +808,7 @@ SpanId: Id_86, Name: manual.ThrowingHandlerAsync, Resource: manual.ThrowingHandlerAsync, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_56, Tags: { language: dotnet, @@ -826,7 +826,7 @@ SpanId: Id_87, Name: manual.ThrowingHandlerAsyncTask, Resource: manual.ThrowingHandlerAsyncTask, - Service: Samples.Aws.Lambda, + Service: Samples.AWS.Lambda, ParentId: Id_58, Tags: { language: dotnet, @@ -844,7 +844,7 @@ SpanId: Id_88, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerNoParamSync, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_59, Tags: { @@ -864,7 +864,7 @@ SpanId: Id_89, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerOneParamSync, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_60, Tags: { @@ -884,7 +884,7 @@ SpanId: Id_90, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerTwoParamsSync, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_61, Tags: { @@ -904,7 +904,7 @@ SpanId: Id_91, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerNoParamAsync, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_62, Tags: { @@ -924,7 +924,7 @@ SpanId: Id_92, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerOneParamAsync, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_63, Tags: { @@ -944,7 +944,7 @@ SpanId: Id_93, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerTwoParamsAsync, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_64, Tags: { @@ -964,7 +964,7 @@ SpanId: Id_94, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerNoParamVoid, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_65, Tags: { @@ -984,7 +984,7 @@ SpanId: Id_95, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerOneParamVoid, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_66, Tags: { @@ -1004,7 +1004,7 @@ SpanId: Id_96, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerTwoParamsVoid, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_67, Tags: { @@ -1024,7 +1024,7 @@ SpanId: Id_97, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerNoParamSyncWithContext, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_68, Tags: { @@ -1044,7 +1044,7 @@ SpanId: Id_98, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerOneParamSyncWithContext, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_69, Tags: { @@ -1064,7 +1064,7 @@ SpanId: Id_99, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerTwoParamsSyncWithContext, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_70, Tags: { @@ -1084,7 +1084,7 @@ SpanId: Id_100, Name: http.request, Resource: GET serverless-dummy-api:9005/function/BaseHandlerNoParamSync, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_71, Tags: { @@ -1104,7 +1104,7 @@ SpanId: Id_101, Name: http.request, Resource: GET serverless-dummy-api:9005/function/BaseHandlerTwoParamsSync, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_72, Tags: { @@ -1124,7 +1124,7 @@ SpanId: Id_102, Name: http.request, Resource: GET serverless-dummy-api:9005/function/BaseHandlerOneParamSyncWithContext, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_73, Tags: { @@ -1144,7 +1144,7 @@ SpanId: Id_103, Name: http.request, Resource: GET serverless-dummy-api:9005/function/BaseHandlerOneParamAsync, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_74, Tags: { @@ -1164,7 +1164,7 @@ SpanId: Id_104, Name: http.request, Resource: GET serverless-dummy-api:9005/function/BaseHandlerTwoParamsVoid, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_75, Tags: { @@ -1184,7 +1184,7 @@ SpanId: Id_105, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerStructParam, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_76, Tags: { @@ -1204,7 +1204,7 @@ SpanId: Id_106, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerNestedClassParam, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_77, Tags: { @@ -1224,7 +1224,7 @@ SpanId: Id_107, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerNestedStructParam, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_78, Tags: { @@ -1244,7 +1244,7 @@ SpanId: Id_108, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerGenericDictionaryParam, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_79, Tags: { @@ -1264,7 +1264,7 @@ SpanId: Id_109, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerNestedGenericDictionaryParam, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_80, Tags: { @@ -1284,7 +1284,7 @@ SpanId: Id_110, Name: http.request, Resource: GET serverless-dummy-api:9005/function/HandlerDoublyNestedGenericDictionaryParam, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_81, Tags: { @@ -1304,7 +1304,7 @@ SpanId: Id_111, Name: http.request, Resource: GET localhost/function/ThrowingHandler, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_82, Error: 1, @@ -1327,7 +1327,7 @@ SpanId: Id_112, Name: http.request, Resource: GET localhost/function/ThrowingHandlerAsync, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_83, Error: 1, @@ -1350,7 +1350,7 @@ SpanId: Id_113, Name: http.request, Resource: GET localhost/function/ThrowingHandlerAsyncTask, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_84, Error: 1, @@ -1373,7 +1373,7 @@ SpanId: Id_114, Name: http.request, Resource: GET localhost/function/ThrowingHandler, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_85, Error: 1, @@ -1396,7 +1396,7 @@ SpanId: Id_115, Name: http.request, Resource: GET localhost/function/ThrowingHandlerAsync, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_86, Error: 1, @@ -1419,7 +1419,7 @@ SpanId: Id_116, Name: http.request, Resource: GET localhost/function/ThrowingHandlerAsyncTask, - Service: Samples.Aws.Lambda-http-client, + Service: Samples.AWS.Lambda-http-client, Type: http, ParentId: Id_87, Error: 1,