You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android平台下基于MvvmCross和Serilog运行时修改日志配置

解决MvvmCross运行时更新Serilog日志级别不生效的问题

问题根源

MvvmCross的InitializeLoggingServices()仅在应用启动时初始化日志服务,并且会将ILoggerFactory和ILoggerProvider以单例模式注册到IoC容器中。后续调用该方法不会覆盖已注册的实例,所以直接调用无法生效。

两种解决方案

方案一:动态级别控制(推荐)

使用Serilog自带的LoggingLevelSwitch,无需重新创建Logger或修改IoC注册,直接动态调整级别:

  1. 在Setup类中定义全局级别开关:
private readonly LoggingLevelSwitch _logLevelSwitch = new LoggingLevelSwitch(LogEventLevel.Information); // 默认级别
  1. 初始化日志工厂时绑定开关:
protected override ILoggerFactory CreateLogFactory()
{
    Serilog.Log.Logger = new LoggerConfiguration()
        .MinimumLevel.ControlledBy(_logLevelSwitch)
        .CreateLogger();

    return new SerilogLoggerFactory();
}
  1. 运行时更新级别只需修改开关:
public void UpdateLogLevel(LogEventLevel newLevel)
{
    _logLevelSwitch.MinimumLevel = newLevel;
}

这种方式无需操作IoC容器,所有已创建的ILogger实例会自动使用新级别,是最简洁的方案。

方案二:重新注册IoC日志服务

如果必须重新创建LoggerConfiguration,需要手动注销并重新注册IoC中的日志服务:

public void UpdateLogLevel(LogEventLevel newLogLevel)
{
    // 更新全局级别变量
    _logEventLevel = newLogLevel;

    // 重新创建Serilog全局Logger
    Serilog.Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Is(_logEventLevel)
        .CreateLogger();

    // 获取MvvmCross IoC容器
    var ioc = Mvx.IoCProvider;

    // 注销并重新注册日志服务
    ioc.Unregister<ILoggerFactory>();
    ioc.RegisterSingleton<ILoggerFactory>(() => new SerilogLoggerFactory());

    ioc.Unregister<ILoggerProvider>();
    ioc.RegisterSingleton<ILoggerProvider>(() => new SerilogLoggerProvider());

    // 注意:已注入到ViewModel/服务中的旧ILogger实例不会自动更新
    // 如果需要这些实例生效,需从IoC重新获取(比如在ViewModel中调用Mvx.IoCProvider.Resolve<ILogger>())
}

注意事项

  • 方案二中,已创建的ILogger实例(比如ViewModel构造函数中注入的)是基于旧级别生成的,不会自动更新,需要手动重新获取。
  • 优先使用方案一,因为它更高效且无需修改IoC容器状态。

内容的提问来源于stack exchange,提问作者Remo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 22:05:52