serilog/serilog-sinks-email

Error during reading sink configuration from JSON file

Opened this issue · 1 comments

Hi,
I encountered error during reading sink configuration from JSON file.

System.InvalidOperationException
HResult=0x80131509
Message=Cannot create instance of type 'System.Net.ICredentialsByHost' because it is either abstract or an interface.
Source=Microsoft.Extensions.Configuration.Binder

{
  "Serilog": {
    "Using": [ "Serilog.Sinks.Email" ],
    "MinimumLevel": "Debug",
    "WriteTo": [
      {
        "Name": "Email",
        "Args": {
          "ConnectionInfo": {
            "NetworkCredentials": {
              "UserName": "username",
              "Password": "password"
            }
          }
        }
      }
    ]
  }
}

I wanted to use extension method with parameter connectionInfo.

public static LoggerConfiguration Email(
this LoggerSinkConfiguration loggerConfiguration,
EmailConnectionInfo connectionInfo,
string outputTemplate = DefaultOutputTemplate,
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
int batchPostingLimit = DefaultBatchPostingLimit,
TimeSpan? period = null,
IFormatProvider formatProvider = null,
string mailSubject = EmailConnectionInfo.DefaultSubject)

It wont work, because constructor for EmailConnectionInfo class doesn't initialize new object for NetworkCredentials property.
public EmailConnectionInfo()
{
Port = DefaultPort;
EmailSubject = DefaultSubject;
IsBodyHtml = false;
}
/// <summary>
/// Gets or sets the credentials used for authentication.
/// </summary>
public ICredentialsByHost NetworkCredentials { get; set; }

I ended up writing custom extension method, but this issue looks like easy to fix.

This is my workaround:

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

namespace MyConsoleApp
{
    public static class SerilogCustomEmailExtension
    {
        const string DefaultOutputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}";

        public static LoggerConfiguration CustomEmail(
            this LoggerSinkConfiguration loggerConfiguration,
            CustomEmailConnectionInfo connectionInfo,
            string outputTemplate = DefaultOutputTemplate,
            LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum
        )
        {
            return loggerConfiguration.Email(
                connectionInfo,
                outputTemplate,
                restrictedToMinimumLevel
            );
        }

        public class CustomEmailConnectionInfo : EmailConnectionInfo
        {
            public CustomEmailConnectionInfo()
            {
                NetworkCredentials = new NetworkCredential();
            }
        }
    }
}

appsettings.json

{
  "Serilog": {
    "Using": [ "Serilog.Sinks.Email", "MyConsoleApp" ],
    "MinimumLevel": "Information",
    "WriteTo": [
      {
        "Name": "CustomEmail",
        "Args": {
          "ConnectionInfo": {
            "NetworkCredentials": {
              "UserName": "example@email.com",
              "Password": "password"
            },
            "FromEmail": "EXAMPLE <example@email.com>",
            "MailServer": "smtp.email.com",
            "EmailSubject": "[{Level}] <{MachineName}> Log Email",
            "Port": "587",
            "IsBodyHtml": false,
            "EnableSsl": false,
            "ToEmail": "admin@email.com"
          },
          "RestrictedToMinimumLevel": "Error",
          "OutputTemplate": "{Timestamp:yyyy-MM-dd HH:mm} [{Level}] <{MachineName}> {Message}{NewLine}{Exception}"
        }
      }
    ],
    "Enrich": [ "WithMachineName" ]
  }
}