【问题标题】:Set Serilog minimum level from environment variable从环境变量中设置 Serilog 最低级别
【发布时间】:2020-10-19 11:57:04
【问题描述】:

是否可以从环境变量设置 Serilog 最低日志级别?

如果我尝试这样配置它

  "Serilog": {
    "MinimumLevel": "%LOG_LEVEL%",
    "WriteTo": [
      {
        "Name": "RollingFile",
        "Args": {
          "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [v{SourceSystemInformationalVersion}] {Message}{NewLine}{Exception}",
          "pathFormat": "%LOG_FOLDER%/sds-osdr-domain-saga-host-{Date}.log",
          "retainedFileCountLimit": 5
        }
      }
    ]
  }

返回错误

值 %LOG_LEVEL% 不是有效的 Serilog 级别。

是否可以以某种方式从环境变量传播日志级别?

【问题讨论】:

    标签: .net-core serilog


    【解决方案1】:

    我想你是在问configuration by environment 这不是特定于 serilog 的。

    如果LOG_LEVEL是固定的特定环境(开发、登台或生产),您可以设置appsettings.<EnvironmentName>.json中的每个LOG_LEVEL,并设置如下配置:

    var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
        .Build();
    

    如果您需要在 docker-compose 文件或 kubernetes 部署文件中配置环境变量中的LOG_LEVEL,则可以通过调用AddEnvironmentVariables从环境变量中读取值:

    var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false)
        .AddEnvironmentVariables()
        .Build();
    

    并在 windows 中设置环境 Serilog:MinimumLevel 或在 linux 和 mac 中设置 ``Serilog__MinimumLevel`。

    【讨论】:

    • 这与 Serilog 有什么关系?
    • @jmdon 您可以使用按环境配置中的方法为Serilog设置不同的配置,例如日志级别
    • 你答案的最后一行是我的关键解决方案!
    【解决方案2】:

    经过一番思考,我最终得到了下面的小班

    public class EnvironmentVariableLoggingLevelSwitch : LoggingLevelSwitch
    {
        public EnvironmentVariableLoggingLevelSwitch(string environmentVariable)
        {
            LogEventLevel level = LogEventLevel.Information;
            if (Enum.TryParse<LogEventLevel>(Environment.ExpandEnvironmentVariables(environmentVariable), true, out level))
            {
                MinimumLevel = level;
            }
        }
    }
    

    并在配置记录器时使用它

    Log.Logger = new LoggerConfiguration()
        .ReadFrom.Configuration(Configuration)
        .MinimumLevel.ControlledBy(new EnvironmentVariableLoggingLevelSwitch("%LOG_LEVEL%"))
        .CreateLogger();
    

    所以,如果你不声明环境变量,你仍然可以从配置文件中配置日志级别,或者用环境变量覆盖它。

    【讨论】:

      【解决方案3】:

      不确定在配置文件中使用环境变量,但从代码中很容易做到。这是一个动态设置日志记录级别的类。您可以读取您的环境变量并传递给:SetLoggingLevel

      internal static class SerilogConfig
      {
          private const int OneDayInMilliseconds = 24 * 60 * 60 * 1000;
          private static Timer ResetLogLevelTimer = null;
      
          public static LoggingLevelSwitch LoggingLevel { get; set; }
      
          static SerilogConfig()
          {
              LoggingLevel = new LoggingLevelSwitch();
      
              LogEventLevel defaultLevel = LogEventLevel.Information;
              bool res = Enum.TryParse<LogEventLevel>(Program.Configuration["DefaultLoggingLevel"], true, out defaultLevel);
              LoggingLevel.MinimumLevel = res ? defaultLevel : LogEventLevel.Information;
          }
      
          public static void Initialize(string serviceName)
          {
              var logConfig = new LoggerConfiguration();
      
              logConfig.MinimumLevel.ControlledBy(LoggingLevel);
              logConfig.MinimumLevel.Override("Microsoft", LogEventLevel.Warning);
              logConfig.MinimumLevel.Override("System", LogEventLevel.Error);
      
              if (Debugger.IsAttached)
              {
                  Serilog.Debugging.SelfLog.Enable(msg => Console.WriteLine(msg));
      
                  logConfig.WriteTo.Console();
              }
      
              Log.Logger = logConfig.CreateLogger();
          }
      
          public static void SetLoggingLevel(LogEventLevel minimumLevel)
          {
              if (minimumLevel == LoggingLevel.MinimumLevel)
              {
                  Log.Verbose("Requested log verbosity level change to the same level. No action taken.");
                  return;
              }
      
              Log.Warning("Changing log verbosity level from {originalLevel} to {newLevel}", LoggingLevel.MinimumLevel.ToString(), minimumLevel.ToString());
      
              LoggingLevel.MinimumLevel = minimumLevel;
      
              if (minimumLevel != LogEventLevel.Information)
              {
                  int resetLogLevelTimeout = Int32.Parse(Program.Configuration["DetailedLoggingTimeDays"]) * OneDayInMilliseconds;
                  ResetLogLevelTimer = new Timer(resetLogLevelTimerCallback, null, resetLogLevelTimeout, Timeout.Infinite);
              }
              else
              {
                  if (ResetLogLevelTimer != null)
                  {
                      ResetLogLevelTimer.Dispose();
                      ResetLogLevelTimer = null;
                  }
              }
          }
          private static void resetLogLevelTimerCallback(object value)
          {
              if (LoggingLevel.MinimumLevel != LogEventLevel.Information)
              {
                  Log.Warning("AUTO RESET: Changing log verbosity level from {0} back to Information", LoggingLevel.MinimumLevel);
      
                  LoggingLevel.MinimumLevel = LogEventLevel.Information;
                  ResetLogLevelTimer.Dispose();
                  ResetLogLevelTimer = null;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2014-12-17
        • 2019-02-02
        • 1970-01-01
        • 2020-07-11
        • 2021-04-06
        • 2016-01-26
        • 2012-02-06
        • 1970-01-01
        • 2021-06-09
        相关资源
        最近更新 更多