Skip to content

Commit 0dd2898

Browse files
authored
Merge pull request #134 from serilog/dev
4.0.0 Release
2 parents 573cb51 + 5973f45 commit 0dd2898

File tree

7 files changed

+60
-46
lines changed

7 files changed

+60
-46
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
# Serilog.Sinks.Email
2-
3-
[![Build status](https://ci.appveyor.com/api/projects/status/sfvp7dw8u6aiodj1/branch/main?svg=true)](https://ci.appveyor.com/project/serilog/serilog-sinks-email/branch/main)
1+
# Serilog.Sinks.Email [![Build status](https://ci.appveyor.com/api/projects/status/sfvp7dw8u6aiodj1/branch/main?svg=true)](https://ci.appveyor.com/project/serilog/serilog-sinks-email/branch/main)
42

53
Sends log events by SMTP email.
64

5+
> ℹ️ Version 3.x of this package changes the name and structure of many configuration parameters from their 2.x names; see below for detailed information.
6+
77
**Package** - [Serilog.Sinks.Email](http://nuget.org/packages/serilog.sinks.email)
88

99
```csharp

appveyor.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
version: '{build}'
22
skip_tags: true
33
image: Visual Studio 2022
4-
test: off
54
build_script:
65
- pwsh: ./Build.ps1
6+
test: off
77
artifacts:
88
- path: artifacts/Serilog.*.nupkg
99
deploy:
1010
- provider: NuGet
1111
api_key:
12-
secure: sDnchSg4TZIOK7oIUI6BJwFPNENTOZrGNsroGO1hehLJSvlHpFmpTwiX8+bgPD+Q
12+
secure: ZpUO4ECx4c/V0Ecj04cfV1UGd+ZABeEG9DDW2fjG8vITjNYhmbiiJH0qNOnRy2G3
1313
skip_symbols: true
1414
on:
1515
branch: /^(main|dev)$/
@@ -20,4 +20,3 @@ deploy:
2020
tag: v$(appveyor_build_version)
2121
on:
2222
branch: main
23-

src/Serilog.Sinks.Email/LoggerConfigurationEmailExtensions.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
using Serilog.Events;
2222
using Serilog.Formatting.Display;
2323
using Serilog.Sinks.Email;
24-
using Serilog.Sinks.PeriodicBatching;
2524
// ReSharper disable MemberCanBePrivate.Global
2625

2726
namespace Serilog;
@@ -31,7 +30,7 @@ namespace Serilog;
3130
/// </summary>
3231
public static class LoggerConfigurationEmailExtensions
3332
{
34-
static readonly TimeSpan DefaultPeriod = TimeSpan.FromSeconds(30);
33+
static readonly TimeSpan DefaultBufferingTimeLimit = TimeSpan.FromSeconds(30);
3534
const int DefaultQueueLimit = 10000;
3635

3736
/// <summary>
@@ -108,7 +107,7 @@ public static LoggerConfiguration Email(
108107
/// </summary>
109108
/// <param name="loggerConfiguration">The logger configuration.</param>
110109
/// <param name="options">The connection info used for</param>
111-
/// <param name="batchingOptions">Optionally, a <see cref="PeriodicBatchingSinkOptions"/> to control background batching.</param>
110+
/// <param name="batchingOptions">Optionally, a <see cref="BatchingOptions"/> to control background batching.</param>
112111
/// <param name="restrictedToMinimumLevel">The minimum level for
113112
/// events passed through the sink. Ignored when <paramref name="levelSwitch"/> is specified.</param>
114113
/// <param name="levelSwitch">A switch allowing the pass-through minimum level
@@ -120,27 +119,25 @@ public static LoggerConfiguration Email(
120119
public static LoggerConfiguration Email(
121120
this LoggerSinkConfiguration loggerConfiguration,
122121
EmailSinkOptions options,
123-
PeriodicBatchingSinkOptions? batchingOptions = null,
122+
BatchingOptions? batchingOptions = null,
124123
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
125124
LoggingLevelSwitch? levelSwitch = null)
126125
{
127126
if (options == null) throw new ArgumentNullException(nameof(options));
128127

129-
batchingOptions ??= new PeriodicBatchingSinkOptions
128+
batchingOptions ??= new BatchingOptions
130129
{
131130
// Batching not used by default: fire off an email immediately upon receiving each event.
132131
BatchSizeLimit = 1,
133-
Period = DefaultPeriod,
132+
BufferingTimeLimit = DefaultBufferingTimeLimit,
134133
EagerlyEmitFirstEvent = true,
135134
QueueLimit = DefaultQueueLimit,
136135
};
137136

138137
var transport = new MailKitEmailTransport(options);
139138
var sink = new EmailSink(options, transport);
140139

141-
var batchingSink = new PeriodicBatchingSink(sink, batchingOptions);
142-
143-
return loggerConfiguration.Sink(batchingSink, restrictedToMinimumLevel, levelSwitch);
140+
return loggerConfiguration.Sink(sink, batchingOptions, restrictedToMinimumLevel, levelSwitch);
144141
}
145142

146143

src/Serilog.Sinks.Email/Serilog.Sinks.Email.csproj

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<Description>Send Serilog events as SMTP email using MailKit.</Description>
4-
<VersionPrefix>3.0.0</VersionPrefix>
4+
<VersionPrefix>4.0.0</VersionPrefix>
55
<Authors>Serilog Contributors</Authors>
6-
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net462</TargetFrameworks>
7-
<TargetFrameworks>$(TargetFrameworks);netstandard2.0;net6.0</TargetFrameworks>
6+
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net462;net471</TargetFrameworks>
7+
<TargetFrameworks>$(TargetFrameworks);netstandard2.0;net6.0;net8.0</TargetFrameworks>
88
<AssemblyOriginatorKeyFile>../../assets/Serilog.snk</AssemblyOriginatorKeyFile>
99
<SignAssembly>true</SignAssembly>
1010
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
@@ -30,9 +30,8 @@
3030
<None Include="../../README.md" Pack="true" Visible="false" PackagePath="/" />
3131
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
3232
<PackageReference Include="PolySharp" Version="1.14.1" PrivateAssets="All" />
33-
<PackageReference Include="Serilog" Version="3.1.1" />
34-
<PackageReference Include="Serilog.Sinks.PeriodicBatching" Version="4.0.0-*" />
35-
<PackageReference Include="MailKit" Version="4.3.0" />
33+
<PackageReference Include="Serilog" Version="4.0.0" />
34+
<PackageReference Include="MailKit" Version="4.6.0" />
3635
</ItemGroup>
3736

3837
</Project>

src/Serilog.Sinks.Email/Sinks/Email/EmailSink.cs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,17 @@
1616
using System.IO;
1717
using System.Threading.Tasks;
1818
using Serilog.Events;
19-
using Serilog.Sinks.PeriodicBatching;
2019
using System.Linq;
20+
using Serilog.Core;
21+
using Serilog.Formatting;
2122

2223
namespace Serilog.Sinks.Email;
2324

2425
class EmailSink : IBatchedLogEventSink, IDisposable
2526
{
2627
readonly EmailSinkOptions _sinkOptions;
2728
readonly IEmailTransport _emailTransport;
29+
2830
/// <summary>
2931
/// Construct a sink emailing with the specified details.
3032
/// </summary>
@@ -41,40 +43,45 @@ public EmailSink(EmailSinkOptions options, IEmailTransport emailTransport)
4143
/// Emit a batch of log events, running asynchronously.
4244
/// </summary>
4345
/// <param name="events">The events to emit.</param>
44-
public Task EmitBatchAsync(IEnumerable<LogEvent> events)
46+
public Task EmitBatchAsync(IReadOnlyCollection<LogEvent> events)
4547
{
46-
// ReSharper disable PossibleMultipleEnumeration
47-
4848
if (events == null)
4949
throw new ArgumentNullException(nameof(events));
5050

51-
var payload = new StringWriter();
51+
var body = new StringWriter();
5252

5353
if (_sinkOptions.Body is IBatchTextFormatter batchTextFormatter)
5454
{
55-
batchTextFormatter.FormatBatch(events, payload);
55+
batchTextFormatter.FormatBatch(events, body);
5656
}
5757
else
5858
{
5959
foreach (var logEvent in events)
6060
{
61-
_sinkOptions.Body.Format(logEvent, payload);
61+
_sinkOptions.Body.Format(logEvent, body);
6262
}
6363
}
6464

65-
var subject = new StringWriter();
66-
_sinkOptions.Subject.Format(events.OrderByDescending(e => e.Level).First(), subject);
65+
var subject = ComputeMailSubject(_sinkOptions.Subject, events);
6766

6867
var email = new EmailMessage(
6968
_sinkOptions.From,
7069
_sinkOptions.To,
71-
subject.ToString(),
72-
payload.ToString(),
70+
subject,
71+
body.ToString(),
7372
_sinkOptions.IsBodyHtml);
7473

7574
return _emailTransport.SendMailAsync(email);
75+
}
7676

77-
// ReSharper restore PossibleMultipleEnumeration
77+
internal static string ComputeMailSubject(ITextFormatter subjectLineFormatter, IEnumerable<LogEvent> events)
78+
{
79+
var subject = new StringWriter();
80+
subjectLineFormatter.Format(events.OrderByDescending(e => e.Level).First(), subject);
81+
var subjectAsText = subject.ToString();
82+
var firstLineOfSubject = subjectAsText.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
83+
.FirstOrDefault() ?? string.Empty;
84+
return firstLineOfSubject;
7885
}
7986

8087
public Task OnEmptyBatchAsync()

test/Serilog.Sinks.Email.Tests/EmailSinkTests.cs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
using System.Collections.Generic;
77
using System.Linq;
88
using System.Threading.Tasks;
9+
using Serilog.Configuration;
910
using Serilog.Sinks.Email.Tests.Support;
10-
using Serilog.Sinks.PeriodicBatching;
1111
using Xunit;
1212
using Xunit.Abstractions;
1313

@@ -84,7 +84,7 @@ public async Task SendEmailIsCorrectlyCalledWhenEventAreLogged()
8484
8585
8686
Body = new MessageTemplateTextFormatter("[{Level}] {Message}{NewLine}{Exception}"),
87-
Subject = new MessageTemplateTextFormatter("[{Level}] {Message}{NewLine}{Exception}")
87+
Subject = new MessageTemplateTextFormatter("[{Level}] A message")
8888
};
8989

9090
var transport = new TestEmailTransport();
@@ -101,8 +101,7 @@ await emailSink.EmitBatchAsync(new[]
101101
new MessageTemplate("Subject",
102102
new MessageTemplateToken[]
103103
{
104-
new PropertyToken("Message", "A multiline" + Environment.NewLine
105-
+ "Message")
104+
new PropertyToken("Message", "A multiline" + Environment.NewLine + "Message")
106105
})
107106
, Enumerable.Empty<LogEventProperty>())
108107
});
@@ -115,16 +114,29 @@ await emailSink.EmitBatchAsync(new[]
115114
+ "System.ArgumentOutOfRangeException: Message of the exception"
116115
+ " (Parameter 'parameter1')"
117116
+ Environment.NewLine + "", actual.Body);
118-
Assert.Equal("[Error] A multiline" + Environment.NewLine
119-
+ "Message" + Environment.NewLine
120-
+ "System.ArgumentOutOfRangeException: Message of the exception"
121-
+ " (Parameter 'parameter1')"
122-
+ Environment.NewLine + "", actual.Subject);
117+
Assert.Equal("[Error] A message", actual.Subject);
123118
Assert.Equal("[email protected]", actual.From);
124119
Assert.Equal(new[] { "[email protected]" }, actual.To);
125120
Assert.False(actual.IsBodyHtml);
126121
}
127122

123+
[Fact]
124+
public void MultilineMessageCreatesSubjectWithTheFirstLineOnly()
125+
{
126+
var subjectLineFormatter = new MessageTemplateTextFormatter("{Message}", null);
127+
128+
var logEvents = new[]
129+
{
130+
new LogEvent(DateTimeOffset.Now, LogEventLevel.Error, new Exception("An exception occured"),
131+
new MessageTemplate(@"Subject",
132+
new MessageTemplateToken[]{new PropertyToken("Message", "A multiline" + Environment.NewLine + "Message")})
133+
, Enumerable.Empty<LogEventProperty>())
134+
};
135+
var mailSubject = EmailSink.ComputeMailSubject(subjectLineFormatter, logEvents);
136+
137+
Assert.Equal("A multiline", mailSubject);
138+
}
139+
128140
[Fact]
129141
public void WorksWithIBatchTextFormatter()
130142
{
@@ -140,7 +152,7 @@ public void WorksWithIBatchTextFormatter()
140152
var sink = new EmailSink(emailConnectionInfo, emailTransport);
141153

142154
using (var emailLogger = new LoggerConfiguration()
143-
.WriteTo.Sink(new PeriodicBatchingSink(sink, new PeriodicBatchingSinkOptions()))
155+
.WriteTo.Sink(sink, new BatchingOptions())
144156
.CreateLogger())
145157
{
146158
emailLogger.Information("Information");

test/Serilog.Sinks.Email.Tests/Serilog.Sinks.Email.Tests.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
</ItemGroup>
1515

1616
<ItemGroup>
17-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
18-
<PackageReference Include="xunit" Version="2.6.4" />
19-
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
17+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
18+
<PackageReference Include="xunit" Version="2.8.1" />
19+
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
2020
<PrivateAssets>all</PrivateAssets>
2121
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
2222
</PackageReference>

0 commit comments

Comments
 (0)