C# .Net核心AWS Lambda函数不刷新日志

C# .Net核心AWS Lambda函数不刷新日志,c#,amazon-web-services,asp.net-core,logging,aws-lambda,C#,Amazon Web Services,Asp.net Core,Logging,Aws Lambda,我已经使用AWS工具包扩展的模板项目结构设置了一个.NET核心AWS Lambda函数。该函数按预期工作。我唯一的问题是,在应用程序关闭之前,我的日志并不总是被刷新。我通常会丢失一两行日志。我正在使用AWS Cloudwatch存储日志,并连接到内置的.NET核心日志框架中 我认为问题在于日志记录器批量推送日志,而不是立即发送它们。问题是,我的Lambda显然是在记录器发送最后一批之前完成的,所以有些会错过 我已尝试将批量推送间隔缩短为1秒,但仍然存在问题。我还尝试过处理我正在使用的服务提供商,

我已经使用AWS工具包扩展的模板项目结构设置了一个.NET核心AWS Lambda函数。该函数按预期工作。我唯一的问题是,在应用程序关闭之前,我的日志并不总是被刷新。我通常会丢失一两行日志。我正在使用AWS Cloudwatch存储日志,并连接到内置的.NET核心日志框架中

我认为问题在于日志记录器批量推送日志,而不是立即发送它们。问题是,我的Lambda显然是在记录器发送最后一批之前完成的,所以有些会错过

我已尝试将批量推送间隔缩短为1秒,但仍然存在问题。我还尝试过处理我正在使用的服务提供商,希望这会迫使日志记录器刷新它的日志,但这似乎也没有帮助

我一直无法找到一种从.NET Core logger手动刷新日志的方法

我真的不想在我的函数末尾添加像Thread.Sleep这样的东西——这很混乱,我真的不应该这样做

这是我的密码:

功能条目:


安迪,我不是.Net开发人员。我希望您了解AWS Lambda的限制

确保功能内存分配和功能超时在限制范围内


请确保您的AWS lambda具有在AWS Cloudwatch中写入日志的权限,该库不适合lambda,因为它在后台线程中上载日志。我们确实在回购协议的自述中提到了这一点


与使用内置在Lambda中的日志记录来CloudWatch日志相比,您希望使用这个库有什么原因吗?如果您喜欢.NET Core API和配置,可以使用Amazon.Lambda.Logging.AspNetCore,它会将日志发送到附加的日志流,如context.Logger.LogLine

谢谢。我可以确认该函数具有向Cloudwatch写入日志的权限。它只丢失了一两行日志,而不是全部。另外,我已经为Lambda函数分配了1GB的内存,这对于它的工作来说已经足够了。它通常只使用100-200MB。我的主要需求是因为我有各种基础库,它们依赖于ILogger.NET类。这些库用于各种应用程序,这些应用程序可能不一定是Lambda函数,因此我不想传递LambdaLogger实例,因为它没有实现ILogger,所以我不能在依赖项注入中使用它。我将看一看Amazon.Lambda.Logging.AspNetCore,因为听起来这可能会解决我的问题。谢谢您的推荐。Amazon.Lambda.Logging.AspNetCore是否应该与TestLambdaLogger一起使用?我有一个Lambda函数的集成测试,我正在使用Amazon.Lambda.TestUtilities.TestLambdaLogger类,但是在运行测试之后,Buffer属性为空。我遵循了这里概述的设置:谢谢Norm。这个包装非常好用。我还没有弄清楚是否有可能在我的测试中使用它,但我现在可以接受它。
public class Function
{
    private readonly Startup startup;

    private ServiceProvider serviceProvider;
    private ILogger<Function> logger;

    public Function()
    {
        startup = new Startup();
    }

    public async Task FunctionHandler(SendUnsentBrochuresRequest request, ILambdaContext context)
    {
        serviceProvider = startup.InitializeFunction();
        logger = this.serviceProvider.GetService<ILogger<Function>>();

        try
        {
            this.logger.LogInformation("Beginning function...");
            var service = this.serviceProvider.GetService<SendUnsentBrochuresService>();
            await service.Process(request);
        }
        catch (Exception ex)
        {
            this.logger.LogError(ex, ex.FullExceptionDetails());
        }
        finally
        {
            this.logger.LogInformation("Finished sending unsent brochure requests.");
            this.serviceProvider.Dispose();
        }
    }
}
public class Startup
{
    public ServiceProvider InitializeFunction()
    {
        var services = new ServiceCollection();
        var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

        // Config
        var configBuilder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables();

        var config = configBuilder.Build();
        services.AddSingleton<IConfiguration>(config);

        var awsCredentials = new BasicAWSCredentials(config["AWS:AccessKey"], config["AWS:SecretKey"]);

        // Logging
        services.AddLogging(builder =>
        {
            var options = new AWSLoggerConfig()
            {
                Credentials = awsCredentials,
                LogGroup = config["AWS:Cloudwatch:LogGroup"],
                Region = "eu-west-2",
                BatchPushInterval = TimeSpan.FromSeconds(1)
            };

            builder.AddFilter("Microsoft", LogLevel.Warning);

            builder.AddAWSProvider(options);
        });

        // Other stuff...

        // Function
        services.AddTransient<SendUnsentBrochuresService>();

        return services.BuildServiceProvider();
    }
}