【问题标题】:Serilog with .NET Core AWS Serverless Web API projectSerilog 与 .NET Core AWS 无服务器 Web API 项目
【发布时间】:2018-11-20 17:16:55
【问题描述】:

我有一个使用 .NET Core (2.1) 构建的 AWS 无服务器 API 应用程序。我已经使用 Serilog 日志记录进行了设置,该日志记录使用 AWS Cloudwatch 接收器作为其日志记录目标。该项目依赖于核心逻辑所在的共享类库。

我注意到并非我的所有日​​志消息都进入 Cloudwatch。我的 API 控制器中的消息确实会成功记录,但来自共享类库的消息仅在我在本地运行时才会记录,而不是在使用实时 API 时记录。

这是我在 Startup 中的日志记录设置。

var awsCredentials = new BasicAWSCredentials(config["AWS:AccessKey"], config["AWS:SecretKey"]);
if (env.IsProduction())
{
    var options = new CloudWatchSinkOptions
    {
        LogGroupName = config["AWS:Cloudwatch:LogGroup"],
        LogStreamNameProvider = new LogStreamNameProvider(),
        TextFormatter = new Serilog.Formatting.Json.JsonFormatter()
    };

    var client = new AmazonCloudWatchLogsClient(awsCredentials, RegionEndpoint.EUWest2);
    Log.Logger = new LoggerConfiguration()
        .Enrich.WithExceptionDetails()
        .WriteTo
        .AmazonCloudWatch(options, client)
        .CreateLogger();
}

services.AddSingleton(Log.Logger);

我也尝试过添加services.AddLogging(builder => builder.AddSerilog());,但这并没有帮助。

我是这样使用的:

public class TestService
{
    private readonly ILogger logger;

    public TestService(ILogger logger)
    {
        this.logger = logger;
    }

    public void TestMethod()
    {
        this.logger.Information("Test Message");
    }
}

【问题讨论】:

  • 你试过services.AddLogging(configuration => configuration.AddSerilog()).AddSingleton(Log.Logger);吗?
  • 刚试过。没有运气:(
  • 您如何将ILogger 传递给您的服务?默认的依赖注入容器不会像在控制器中那样自动映射依赖。您必须调用 ServiceProvider.GetService 来检索要手动传递的依赖项,除非您自己编写该映射。
  • 嗯,我没有为此设置任何东西。我认为 ILogger 会像其他任何服务一样被注入?我不想每次我想使用记录器时都必须做ServiceProvider.GetService。当然,这违背了依赖注入的观点。没有ServiceProvider.GetService,有没有办法做到这一点?
  • 另外,我没有收到任何异常说 DI 顺便说一句失败了。就是拒绝登录直播环境。

标签: c# amazon-web-services logging asp.net-core amazon-cloudwatch


【解决方案1】:

默认的依赖注入框架有几个限制。在控制器内部,依赖项将通过构造函数中的放置自动加载。但是,在嵌套类中,您必须传递依赖项本身,否则框架将不会自动解析。该框架在组合根的假设下工作。本质上:

// Auto Resolved:
public class SampleController : Controller
{
     private readonly ILogger logger;

     public SampleController(ILogger logger) => this.logger = logger;

     public IActionResult Index()
     {
         logger.Information("...");
         ..
     }
}

// Will not auto resolve
public class SampleService
{
     private readonly ILogger logger;

     public SampleService(ILogger logger) => this.logger = logger;

     public void SampleAction()
     {
         logger.Information("...");
         ..
     }
}

为了在SampleService 中正确实现记录器,您需要按照以下方式进行操作:

// Logger as property
Logger = serviceProvider.GetService<ILogger>();
var sampleService = new SampleService(Logger);

// Called directly passed
var sampleService = new SampleService(serviceProvider.GetService<ILogger>());

这是我的经验,否则将无法使用您传递的定义实现。可能有一些我没有的信息也可能会影响您的代码。

【讨论】:

  • 这是ILogger 特有的吗?我问是因为我的类库中有许多其他依赖项的服务,这些依赖项都是用 DI 设置的,它们工作得很好。我唯一有问题的是ILogger,没有别的。
  • 老实说,我相信这可能源于他们的 DI 框架而不是 ILogger 实现,但我可能弄错了。我只是注意到,如果在根级别没有传递具体实例,则依赖关系不会在管道中进一步解析。
猜你喜欢
  • 2022-09-26
  • 2018-06-24
  • 2020-06-29
  • 2018-11-20
  • 1970-01-01
  • 2019-02-18
  • 1970-01-01
  • 2021-03-22
  • 1970-01-01
相关资源
最近更新 更多