从环境变量设置 Serilog 最低级别

Mr.*_*kin 5 serilog .net-core

是否可以从环境变量设置 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
        }
      }
    ]
  }
Run Code Online (Sandbox Code Playgroud)

它返回错误

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

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

Fei*_*hou 7

我认为您询问的是并非特定于 serilog 的环境配置。

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

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

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

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

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


Mr.*_*kin 6

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

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

并在配置记录器时使用它

Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(Configuration)
    .MinimumLevel.ControlledBy(new EnvironmentVariableLoggingLevelSwitch("%LOG_LEVEL%"))
    .CreateLogger();
Run Code Online (Sandbox Code Playgroud)

因此,如果您没有声明环境变量,您仍然可以从配置文件配置日志记录级别,或使用环境变量覆盖它。


pro*_*erj 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)