22// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
33
44using System . Diagnostics . CodeAnalysis ;
5+ using Amazon . Lambda . Core ;
56using MartinCostello . LondonTravel . Skill . Extensions ;
67using MartinCostello . LondonTravel . Skill . Intents ;
78using MartinCostello . LondonTravel . Skill . Models ;
89using Microsoft . Extensions . Configuration ;
910using Microsoft . Extensions . DependencyInjection ;
1011using Microsoft . Extensions . Logging ;
1112using Microsoft . Extensions . Options ;
13+ using OpenTelemetry . Instrumentation . AWSLambda ;
14+ using OpenTelemetry . Metrics ;
15+ using OpenTelemetry . Resources ;
16+ using OpenTelemetry . Trace ;
1217
1318namespace MartinCostello . LondonTravel . Skill ;
1419
@@ -55,21 +60,15 @@ public async virtual ValueTask DisposeAsync()
5560 /// Handles a request to the skill as an asynchronous operation.
5661 /// </summary>
5762 /// <param name="request">The skill request.</param>
63+ /// <param name="context">The Lamda request context.</param>
5864 /// <returns>
5965 /// A <see cref="Task{TResult}"/> representing the asynchronous operation to get the skill's response.
6066 /// </returns>
61- public async Task < SkillResponse > HandlerAsync ( SkillRequest request )
67+ public async Task < SkillResponse > HandlerAsync ( SkillRequest request , ILambdaContext context )
6268 {
6369 EnsureInitialized ( ) ;
64-
65- var handler = _serviceProvider . GetRequiredService < FunctionHandler > ( ) ;
66- var logger = _serviceProvider . GetRequiredService < ILogger < AlexaFunction > > ( ) ;
67-
68- using var activity = SkillTelemetry . ActivitySource . StartActivity ( "Skill Request" ) ;
69-
70- Log . InvokingSkillRequest ( logger , request . Request . Type ) ;
71-
72- return await handler . HandleAsync ( request ) ;
70+ var tracerProvider = _serviceProvider . GetRequiredService < TracerProvider > ( ) ;
71+ return await AWSLambdaWrapper . TraceAsync ( tracerProvider , HandlerCoreAsync , request , context ) ;
7372 }
7473
7574 /// <summary>
@@ -132,6 +131,21 @@ protected virtual void ConfigureServices(IServiceCollection services)
132131 services . AddTransient < CommuteIntent > ( ) ;
133132 services . AddTransient < DisruptionIntent > ( ) ;
134133 services . AddTransient < StatusIntent > ( ) ;
134+
135+ services . AddSingleton ( ( _ ) => SkillTelemetry . ActivitySource ) ;
136+ services . AddOpenTelemetry ( )
137+ . ConfigureResource ( ( builder ) => builder . AddService ( SkillTelemetry . ServiceName , serviceVersion : SkillTelemetry . ServiceVersion ) )
138+ . WithTracing ( ( builder ) =>
139+ {
140+ builder . AddHttpClientInstrumentation ( ( p ) => p . RecordException = true )
141+ . AddSource ( SkillTelemetry . ServiceName ) ;
142+
143+ if ( IsRunningInAwsLambda ( ) )
144+ {
145+ builder . AddAWSLambdaConfigurations ( )
146+ . AddOtlpExporter ( ) ;
147+ }
148+ } ) ;
135149 }
136150
137151 protected virtual void Dispose ( bool disposing )
@@ -147,12 +161,22 @@ protected virtual void Dispose(bool disposing)
147161 }
148162 }
149163
150- /// <summary>
151- /// Creates the <see cref="ServiceProvider"/> to use.
152- /// </summary>
153- /// <returns>
154- /// The <see cref="ServiceProvider"/> to use.
155- /// </returns>
164+ private static bool IsRunningInAwsLambda ( )
165+ => Environment . GetEnvironmentVariable ( "AWS_LAMBDA_FUNCTION_NAME" ) is { Length : > 0 } &&
166+ Environment . GetEnvironmentVariable ( "AWS_REGION" ) is { Length : > 0 } ;
167+
168+ private async Task < SkillResponse > HandlerCoreAsync ( SkillRequest request , ILambdaContext context )
169+ {
170+ var handler = _serviceProvider ! . GetRequiredService < FunctionHandler > ( ) ;
171+ var logger = _serviceProvider ! . GetRequiredService < ILogger < AlexaFunction > > ( ) ;
172+
173+ using var activity = SkillTelemetry . ActivitySource . StartActivity ( "Skill Request" ) ;
174+
175+ Log . InvokingSkillRequest ( logger , request . Request . Type ) ;
176+
177+ return await handler . HandleAsync ( request ) ;
178+ }
179+
156180 private ServiceProvider CreateServiceProvider ( )
157181 {
158182 var services = new ServiceCollection ( ) ;
0 commit comments