ASP.NET Core中的日志配置更改 [英] Log configuration changes in ASP.NET Core

查看:67
本文介绍了ASP.NET Core中的日志配置更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要在更改配置时记录日志.

I want to log when configuration is changed.

我在 code> Program.cs 或 Startup.cs :

I do this in Program.cs or Startup.cs:

ChangeToken.OnChange(
  () => configuration.GetReloadToken(),
  state => logger.Information("Configuration reloaded"),
  (object)null
);

但是我收到了两次变更报告,因此需要将其删除.建议是这样做:

But I get double change reports, so it needs to be debounced. The advice is to do this:

ChangeToken.OnChange(
  () => configuration.GetReloadToken(),
  state => { Thread.Sleep(2000); logger.Information("Configuration reloaded"); },
  (object)null
);

我在这里使用 2000 ,因为我不确定什么是合理的值.

I'm using 2000 here as I'm not sure what's a reasonable value.

我发现有时候我仍然可以检测到多个变更,相隔2000毫秒.因此,反跳对我不起作用,只会导致报告的更改之间出现延迟.如果我设置一个很高的值,那么我只会得到一份报告,但这并不理想(并且掩盖了问题).

I've found that sometimes I still get multiple change detections, separated by 2000 milliseconds. So the debounce doesn't work for me, just causes a delay between reported changes. If I set a high value then I only get one report, but that isn't ideal (and conceals the problem).

所以我想知道:

  • 这真的是在反跳,还是只是对已报告的更改进行排队?
  • 我使用1000到5000的值来获得不同的成功.别人在用什么?
  • 睡眠是否已发布到服务器的主线程?我希望不会!

推荐答案

讨论了多项更改检测问题此处(以及多个存储库中的至少十二个其他问题)是他们拒绝使用内置机制解决的问题.

The multiple change detection issue discussed here (and at least a dozen other issues in multiple repos) is something they refuse to address using a built-in mechanism.

MS文档使用文件散列方法,但我认为反跳效果更好.

The MS docs use a file hashing approach, but I think that debouncing is better.

我的解决方案使用异步(避免异步同步,这可能会意外炸毁某些东西)和

My solution uses async (avoids async-in-sync which could blow up something accidentally) and a hosted service that debounces change detections.

Debouncer.cs :

public sealed class Debouncer : IDisposable {

  public Debouncer(TimeSpan? delay) => _delay = delay ?? TimeSpan.FromSeconds(2);

  private readonly TimeSpan _delay;
  private CancellationTokenSource? previousCancellationToken = null;

  public async Task Debounce(Action action) {
    _ = action ?? throw new ArgumentNullException(nameof(action));
    Cancel();
    previousCancellationToken = new CancellationTokenSource();
    try {
      await Task.Delay(_delay, previousCancellationToken.Token);
      await Task.Run(action, previousCancellationToken.Token);
    }
    catch (TaskCanceledException) { }    // can swallow exception as nothing more to do if task cancelled
  }

  public void Cancel() {
    if (previousCancellationToken != null) {
      previousCancellationToken.Cancel();
      previousCancellationToken.Dispose();
    }
  }

  public void Dispose() => Cancel();

}

ConfigWatcher.cs :

public sealed class ConfigWatcher : IHostedService, IDisposable {

  public ConfigWatcher(IServiceScopeFactory scopeFactory, ILogger<ConfigWatcher> logger) {
    _scopeFactory = scopeFactory;
    _logger = logger;
  }

  private readonly IServiceScopeFactory _scopeFactory;
  private readonly ILogger<ConfigWatcher> _logger;

  private readonly Debouncer _debouncer = new(TimeSpan.FromSeconds(2));

  private void OnConfigurationReloaded() {
    _logger.LogInformation("Configuration reloaded");
    // ... can do more stuff here, e.g. validate config
  }

  public Task StartAsync(CancellationToken cancellationToken) {
    ChangeToken.OnChange(
      () => {                                                 // resolve config from scope rather than ctor injection, in case it changes (this hosted service is a singleton)
        using var scope = _scopeFactory.CreateScope();
        var configuration = scope.ServiceProvider.GetRequiredService<IConfiguration>();
        return configuration.GetReloadToken();
      },
      async () => await _debouncer.Debounce(OnConfigurationReloaded)
    );
    return Task.CompletedTask;
  }

  public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;

  public void Dispose() => _debouncer.Dispose();

}

Startup.cs :

services.AddHostedService<ConfigWatcher>();        // registered as singleton

这篇关于ASP.NET Core中的日志配置更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆