Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to setup DI to inject ILogger<T> within a lambda function app with single lambda FunctionHandler

I have an MRE lambda project with csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
    <AWSProjectType>Lambda</AWSProjectType>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Amazon.Lambda.Core" Version="1.1.0" />
    <PackageReference Include="Amazon.Lambda.Logging.AspNetCore" Version="3.0.1" />
    <PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.6" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.6" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.6" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.6" />
  </ItemGroup>
</Project>

And I have created a simple functionhandler which calls _svc.DoSomethingThatLogsUsingLogger();

as shown below

using Amazon.Lambda.Core;
using AWSLambda3.Services;
using Microsoft.Extensions.DependencyInjection;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace AWSLambda3
{
    public class Function
    {
        private IServiceName1 _svc { get; }

        public Function( IServiceName1 svc)
        {
            _svc = svc;
        }

        public Function()
        {
            var serviceCollection = new ServiceCollection();
            ConfigureServices(serviceCollection);
            serviceCollection.AddLogging();
            var serviceProvider = serviceCollection.BuildServiceProvider();

            _svc = serviceProvider.GetService<IServiceName1>();
        }

        private void ConfigureServices(IServiceCollection serviceCollection)
        {
            serviceCollection.AddTransient<IServiceName1, ServiceName1>();
        }


        public string FunctionHandler(string input, ILambdaContext context)
        {
            _svc.DoSomethingThatLogsUsingLogger();
            return input?.ToString();
        }
    }
}

That service code simply attempts to log using ILogger

using Microsoft.Extensions.Logging;
using System;

namespace AWSLambda3.Services
{
    public class ServiceName1 : IServiceName1
    {
        private readonly ILogger<ServiceName1> _logger;
        public ServiceName1(ILogger<ServiceName1> logger)
        {
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }
        public void DoSomethingThatLogsUsingLogger()
        {
            _logger.LogTrace("test LogTrace log string");
            _logger.LogDebug("test LogDebug log string");
            _logger.LogInformation("test LogInformation log string");
            _logger.LogWarning("test LogWarning log string");
            _logger.LogError("test LogError log string");
            _logger.LogCritical("test LogCritical log string");
        }
    }
}

However, upon deploying this lambda function handler to AWS Lambda, no logs are created in CloudWatch. What am I missing?

like image 394
jbooker Avatar asked Dec 31 '22 22:12

jbooker


1 Answers

Solution shown below in diff enter image description here

Also need to ensure this package is installed

<PackageReference Include="Amazon.Lambda.Logging.AspNetCore" Version="3.0.1" />
like image 107
jbooker Avatar answered Jan 08 '23 22:01

jbooker