SmtpAppender
The SmtpAppender sends log events via email using the Simple Mail Transfer Protocol (SMTP).
This appender is useful for sending email notifications when certain events occur, such as errors or critical failures in your application.
There are two implementations to choose from:
| Type | Assembly | SMTP client |
|---|---|---|
|
|
|
|
|
|
|
The built-in It sends mail through System.Net.Mail.SmtpClient, which Microsoft no longer recommends for new development because it does not support many modern protocols. In practice this shows up as connection failures against modern mail servers, most often around SSL/TLS negotiation. Use the MailKit based |
MailKit based SmtpAppender (recommended)
This appender lives in the separate log4net.Ext.Mail package, so that log4net itself does not take on a mail dependency.
Add it to your project:
dotnet add package log4net.Ext.Mail
Because the appender is not part of the log4net assembly, the type attribute must be assembly-qualified:
type="log4net.Ext.Mail.Appender.SmtpAppender, log4net.Ext.Mail"
The following example shows how to configure the SmtpAppender to deliver log events via SMTP email.
The To, From, Subject and SmtpHost are required parameters.
This example shows how to deliver only significant events.
A LevelEvaluator is specified with a threshold of WARN. This means that an email will be sent for each WARN or higher level message that is logged. Each email will also contain up to 512 (BufferSize) previous messages of any level to provide context.
Messages not sent will be discarded.
<appender name="SmtpAppender" type="log4net.Ext.Mail.Appender.SmtpAppender, log4net.Ext.Mail">
<to value="to@example.com" />
<from value="from@example.com" />
<subject value="test logging message" />
<smtpHost value="smtp.example.com" />
<bufferSize value="512" />
<lossy value="true" />
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="WARN"/>
</evaluator>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%newline%date [%thread] %-5level %logger - %message%newline%newline%newline" />
</layout>
</appender>
This example shows how to configure the SmtpAppender to deliver all messages in emails with 512 bufferSize messages per email.
<appender name="SmtpAppender" type="log4net.Ext.Mail.Appender.SmtpAppender, log4net.Ext.Mail">
<to value="to@example.com" />
<from value="from@example.com" />
<subject value="test logging message" />
<smtpHost value="smtp.example.com" />
<bufferSize value="512" />
<lossy value="false" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%newline%date [%thread] %-5level %logger - %message%newline%newline%newline" />
</layout>
</appender>
This example shows a more verbose formatting layout for the mail messages.
<appender name="SmtpAppender" type="log4net.Ext.Mail.Appender.SmtpAppender, log4net.Ext.Mail">
<to value="to@example.com" />
<from value="from@example.com" />
<subject value="test logging message" />
<smtpHost value="smtp.example.com" />
<bufferSize value="512" />
<lossy value="false" />
<evaluator type="log4net.Core.LevelEvaluator,log4net">
<threshold value="WARN" />
</evaluator>
<layout type="log4net.Layout.PatternLayout,log4net">
<conversionPattern value="%property{log4net:HostName} :: %level :: %message %newlineLogger: %logger%newlineThread: %thread%newlineDate: %date%newline%newline" />
</layout>
</appender>
This example authenticates against a mail server that requires an encrypted connection on the submission port.
<appender name="SmtpAppender" type="log4net.Ext.Mail.Appender.SmtpAppender, log4net.Ext.Mail">
<to value="ops@example.com,oncall@example.com" />
<cc value="team@example.com" />
<from value="log4net@example.com" />
<replyTo value="noreply@example.com" />
<subject value="Errors from the payment service" />
<smtpHost value="smtp.example.com" />
<port value="587" />
<enableSsl value="true" />
<authentication value="Basic" />
<username value="log4net@example.com" />
<password value="secret" />
<priority value="High" />
<bufferSize value="512" />
<lossy value="true" />
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="ERROR"/>
</evaluator>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%newline%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
Options
| Option | Description |
|---|---|
|
Required. Comma-delimited list of recipient email addresses. |
|
Required. The sender’s email address. |
|
Required. The subject line of the email. |
|
Required. The name or address of the SMTP relay server. |
|
Comma-delimited list of addresses to carbon copy. |
|
Comma-delimited list of addresses to blind carbon copy. |
|
The reply-to address. |
|
The port the SMTP server listens on. Defaults to |
|
Whether to require transport security. Defaults to |
|
How the connection is secured. One of |
|
One of |
|
The user name to authenticate with. Ignored when |
|
The password to authenticate with. Ignored when |
|
One of |
|
The encoding of the subject line, for example |
|
The encoding of the message body, for example |
|
How many log events to buffer into one email. See Appenders. |
|
Whether buffered events may be discarded rather than sent. |
|
An |
to, cc and bcc also accept semicolons as separators, and quoted display names such as "Doe, John" <john@example.com>.
Transport security
enableSsl covers the usual cases and behaves as it does in the legacy appender: true requires
transport security, so connecting fails when the server does not offer it rather than continuing
unencrypted.
transportSecurity is the same setting expressed precisely, for servers that need something else.
The two properties cannot disagree: whichever is assigned last wins.
| Value | Description |
|---|---|
|
The connection is not encrypted. Equivalent to |
|
Transport security is required and the mechanism follows the port: implicit TLS on port 465,
|
|
The session is encrypted before the SMTP greeting, whatever the port.
Use this for a server expecting implicit TLS on a port other than 465, which |
|
|
|
|
|
|
Differences from the legacy appender
The options above are named exactly as in the legacy appender, but a few behave differently:
-
smtpHostis required. MailKit has no notion of a machine-wide default SMTP server, so there is nothing to fall back on when the option is omitted. -
authenticationset toNtlmrequiresusernameandpassword. MailKit cannot reuse the Windows logon session of the current thread or process, which the legacy appender did. -
Semicolon-delimited recipient lists in
to,ccandbccare parsed correctly. -
transportSecurityhas no counterpart in the legacy appender, which offers onlyenableSsl.
enableSsl keeps its meaning, so a migrated configuration secures the connection exactly as before.
If the legacy appender reached your server with enableSsl set to true, so does this one.
The new transportSecurity option is only needed for a server that the legacy appender could not
reach either, such as one expecting implicit TLS on a port other than 465.
Built-in SmtpAppender (deprecated)
|
This appender is still shipped and still works, but it is marked |
The built-in appender is configured with the same options, except for the differences listed in Differences from the legacy appender.
It needs no assembly-qualified type name, because it is part of the log4net assembly.
<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="to@example.com" />
<from value="from@example.com" />
<subject value="test logging message" />
<smtpHost value="smtp.example.com" />
<bufferSize value="512" />
<lossy value="true" />
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="WARN"/>
</evaluator>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%newline%date [%thread] %-5level %logger - %message%newline%newline%newline" />
</layout>
</appender>
If you cannot take on the MailKit dependency, SmtpPickupDirAppender is an alternative that avoids an SMTP client altogether by writing the emails to a pickup directory.