【问题标题】:.net Core and Serilog Email sink - json config.net Core 和 Serilog 电子邮件接收器 - json 配置
【发布时间】:2018-10-27 11:41:40
【问题描述】:

我正在使用 .net Core 2.0 和 Serilog 电子邮件接收器。我在使用appsettings.json 配置电子邮件接收器时遇到问题。来自program.cs 的相同配置有效,而来自appsetting.json 的配置无效。

【问题讨论】:

  • app.settings 周围是否有父元素?例如"WriteTo": [ { "Name": "Email", ... ]?
  • 是的,这只是代码的一部分。 "Serilog": { "WriteTo": ...}

标签: json email asp.net-core .net-core serilog


【解决方案1】:

设置系统 (ReadFrom.Configuration()) 实际上只尝试调用方法和扩展方法,它可以发现并传递配置文件提供的参数

不幸的是,它暂时只支持 basic 类型(可转换为string 和一些更具体的情况),因此无法提供EmailConnectionInfo 类型的参数。

不过,作为一种解决方法,如果您只需要传入几个参数,您可以创建自己的扩展方法来接受您需要的参数并从配置系统中调用它。

在您的情况下,您需要执行以下操作:

首先,定义一个extension methodEmailCustom(...),可以插入WriteTo(类型为Serilog.Configuration.LoggerSinkConfiguration)并返回一个LoggerConfiguration

这看起来像(未经测试,没有使用等:P):

namespace Serilog{
    public static class MyCustomExtensions
    {
        public static LoggerConfiguration EmailCustom(this LoggerSinkConfiguration sinkConfiguration, string param1, int param2, LogEventLevel restrictedToMinimumLevel){
            // the actual call to configure the Email sink, passing in complex parameters
            return sinkConfiguration.Email(... ... , restrictedToMinimumLevel , EmailConnectionInfo(){
            Foo = "bar",
            Baz = param1,
            Qux = param2,
            }
            );
        }
    }
}

从那时起,您应该能够编写如下 C# 代码:

new LoggerConfiguration()
    .WriteTo.EmailCustom(param1: "my param1", param2: 42)
   // ...
    .CreateLogger();

一旦你完成了这项工作,你实际上可以在 json 中定义该方法调用,这要归功于 Serilog.Settings.Configuration 在这种情况下,看起来像

{
"Serilog": {
    "Using" : ["TheNameOfTheAssemblyThatContainsEmailCustom"],
    "MinimumLevel": "Debug",
    "WriteTo": [
      {
        "Name": "EmailCustom",
        "Args": {
          "param1": "my param1",
          "param2": 42,
          "restrictedToMinimumLevel": "Verbose"
        }
      }]
    }
}

此策略也可以应用于 Serilog 的其他接收器和其他配置部分。


你可以在这里找到更多关于配置系统的信息:

【讨论】:

  • 现在是一年后,在您提供的链接中,它指出现在可以通过配置传递复杂类型:github.com/tsimbalar/serilog-settings-comparison/blob/master/… - 事实上,您自己把它放在那里: D 那么您能否更新您的答案以反映新的现实?
  • 很好的答案!我在这个问题上把头从墙上撞了下来,答案就在眼前!
【解决方案2】:

对于像我这样难以在字里行间拼凑事物的其他人,这里是使用 tsimbalar 提供的框架的完整答案,用于使用 SendGrid 发送电子邮件的解决方案。

我将以下类添加到我的项目(“MyApp”)的根目录中。这会从 ReadFrom.Configuration(configuration).CreateLogger(); 中自动调用。由于 appsettings 中的 WriteTo EmailCustom。

using System;
using System.Net;
using Serilog;
using Serilog.Configuration;
using Serilog.Events;
using Serilog.Sinks.Email;

namespace TrackumApi
{
    public static class SerilogEmailExtension
    {
        public static LoggerConfiguration EmailCustom(this LoggerSinkConfiguration sinkConfiguration,
            string fromEmail,
            string toEmail,
            string enableSsl,
            string mailSubject,
            string isBodyHtml,
            string mailServer,
            string networkCredentialuserName,
            string networkCredentialpassword,
            string smtpPort,
            string outputTemplate,
            string batchPostingLimit,
            string periodMinutes,
            string restrictedToMinimumLevel)
        {
            return sinkConfiguration.Email(new EmailConnectionInfo
            {
                FromEmail = fromEmail,
                ToEmail = toEmail,
                EnableSsl = GetBoolean(enableSsl),
                EmailSubject = mailSubject,
                IsBodyHtml = GetBoolean(isBodyHtml),
                MailServer = mailServer,
                NetworkCredentials = new NetworkCredential(networkCredentialuserName, networkCredentialpassword),
                Port = GetInt(smtpPort)
            }, outputTemplate, GetLevel(restrictedToMinimumLevel), 
                GetInt(batchPostingLimit), TimeSpan.FromMinutes(GetInt(periodMinutes))
            );
        }

      //The system hated converting the string inputs inline so I added the conversion methods:

        private static int GetInt(string instring)
        {
            return int.TryParse(instring, out var result) ? result : 0;
        }

        private static bool GetBoolean(string instring)
        {
            return bool.TryParse(instring, out var result) && result;
        }

        private static LogEventLevel GetLevel(string restrictedtominimumlevel)
        {
            return Enum.TryParse(restrictedtominimumlevel, true,
                out LogEventLevel level) ? level : LogEventLevel.Warning;
        }
    }
}

在我的原始帖子中,我修改了我的 Program.cs,但事实证明这不是必需的。然而,在任何其他代码之前添加 Serilog.Debugging.SelfLog 仍然是无价的:

        Serilog.Debugging.SelfLog.Enable(Console.Out);
        var configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", true, true)
            .Build();

        Log.Logger = new LoggerConfiguration()
            .ReadFrom.Configuration(configuration)
            .CreateLogger();

最后我修改了 appsettings.json 如下(原谅额外的,但我认为这也可能对某人有所帮助):

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",

  "Serilog": {
    "Using": [ "Serilog", "Serilog.Sinks.Console", "Serilog.Sinks.File", "MyApp" ],
    "MinimumLevel": {
      "Default": "Verbose",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning",
        "Microsoft.AspNetCore.Authentication": "Information"
      }
    },
    "WriteTo": [
      {
        "Name": "Console",
        "Args": {
          "outputTemplate": "[{Timestamp:HH:mm:ss.fff} [{Level}] {SourceContext} {Message}{NewLine}{Exception}",
          "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console"
        }
      },
      {
        "Name": "File",
        "Args": {
          "path": "C:\\Temp\\Logs\\MyApp.log",
          "fileSizeLimitBytes": 1000000,
          "rollOnFileSizeLimit": "true",
          "shared": "true",
          "flushToDiskInterval": 3,
          "outputTemplate": "[{Timestamp:MM/dd/yy HH:mm:ss} [{Level}] {SourceContext} {Message}{NewLine}{Exception}",
          "restrictedToMinimumLevel": "Verbose"
        }
      },
      {
        "Name": "EmailCustom",
        "Args": {
          "fromEmail": "no-reply@mydomain.com",
          "toEmail": "me@mydomain.com",
          "enableSsl": false,
          "mailSubject": "MyApp Message",
          "isBodyHtml": true,
          "mailServer": "smtp.sendgrid.net",
          "networkCredentialuserName": "mysendgridusername",
          "networkCredentialpassword": "mysendgridpassword",
          "smtpPort": 587,
          "outputTemplate": "[{Timestamp:HH:mm:ss.fff} {Level:u3}] {Message:lj} <s:{SourceContext}>{NewLine}{Exception}",
          "batchPostingLimit": 10,
          "periodMinutes": 5,
          "restrictedToMinimumLevel": "Verbose"
        }
      }
    ],
    "Enrich": [ "FromLogContext" ],
    "Properties": {
      "Application": "MyApp"
    }
  }

}

HTH!

【讨论】:

    猜你喜欢
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多