Skip to content

Commit 590d961

Browse files
committed
Update build and test infrastructure; move to standalone JSON formatter.
1 parent 74bbc9e commit 590d961

File tree

12 files changed

+260
-40
lines changed

12 files changed

+260
-40
lines changed

Build.ps1

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,51 @@
1+
echo "build: Build started"
2+
13
Push-Location $PSScriptRoot
24

3-
if(Test-Path .\artifacts) { Remove-Item .\artifacts -Force -Recurse }
5+
if(Test-Path .\artifacts) {
6+
echo "build: Cleaning .\artifacts"
7+
Remove-Item .\artifacts -Force -Recurse
8+
}
49

5-
& dotnet restore
10+
& dotnet restore --no-cache
611

7-
$revision = @{ $true = $env:APPVEYOR_BUILD_NUMBER; $false = 1 }[$env:APPVEYOR_BUILD_NUMBER -ne $NULL];
12+
$branch = @{ $true = $env:APPVEYOR_REPO_BRANCH; $false = $(git symbolic-ref --short -q HEAD) }[$env:APPVEYOR_REPO_BRANCH -ne $NULL];
13+
$revision = @{ $true = "{0:00000}" -f [convert]::ToInt32("0" + $env:APPVEYOR_BUILD_NUMBER, 10); $false = "local" }[$env:APPVEYOR_BUILD_NUMBER -ne $NULL];
14+
$suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)))-$revision"}[$branch -eq "master" -and $revision -ne "local"]
815

9-
Push-Location src/Serilog.Sinks.Splunk
16+
echo "build: Version suffix is $suffix"
1017

11-
& dotnet pack -c Release -o ..\..\.\artifacts --version-suffix=$revision
12-
if($LASTEXITCODE -ne 0) { exit 1 }
18+
foreach ($src in ls src/*) {
19+
Push-Location $src
1320

21+
echo "build: Packaging project in $src"
22+
23+
& dotnet pack -c Release -o ..\..\artifacts --version-suffix=$suffix
24+
if($LASTEXITCODE -ne 0) { exit 1 }
25+
26+
Pop-Location
27+
}
28+
29+
foreach ($test in ls test/*.PerformanceTests) {
30+
Push-Location $test
31+
32+
echo "build: Building performance test project in $test"
33+
34+
& dotnet build -c Release
35+
if($LASTEXITCODE -ne 0) { exit 2 }
36+
37+
Pop-Location
38+
}
39+
40+
foreach ($test in ls test/*.Tests) {
41+
Push-Location $test
42+
43+
echo "build: Testing project in $test"
44+
45+
& dotnet test -c Release
46+
if($LASTEXITCODE -ne 0) { exit 3 }
47+
48+
Pop-Location
49+
}
1450

15-
Pop-Location
1651
Pop-Location

appveyor.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ deploy:
1919
secure: nvZ/z+pMS91b3kG4DgfES5AcmwwGoBYQxr9kp4XiJHj25SAlgdIxFx++1N0lFH2x
2020
skip_symbols: true
2121
on:
22-
branch: master
22+
branch: /^(master|dev)$/
2323
- provider: GitHub
2424
auth_token:
25-
secure: ggZTqqV1z0xecDoQbeoy3A7xikShCt9FWZIGp95dG9Fo0p5RAT9oGU0ZekHfUIwk
25+
secure: p4LpVhBKxGS5WqucHxFQ5c7C8cP74kbNB0Z8k9Oxx/PMaDQ1+ibmoexNqVU5ZlmX
2626
artifact: /Serilog.*\.nupkg/
2727
tag: v$(appveyor_build_version)
2828
on:

global.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
{
1+
{
22
"projects": [ "src", "test" ],
33
"sdk": {
4-
"version": "1.0.0-preview1-002702"
4+
"version": "1.0.0-preview2-003121"
55
}
66
}

serilog-sinks-splunk.sln

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 14
4-
VisualStudioVersion = 14.0.24720.0
4+
VisualStudioVersion = 14.0.25420.1
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{7A774CBB-A6E9-4854-B4DB-4CF860B0C1C5}"
77
EndProject
@@ -25,6 +25,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sample", "sample", "{1C75E4
2525
EndProject
2626
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Sample", "src\sample\Sample.xproj", "{17497155-5D94-45DF-81D9-BD960E8CF217}"
2727
EndProject
28+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{B9451AD8-09B9-4C09-A152-FBAE24806614}"
29+
EndProject
30+
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Serilog.Sinks.Splunk.Tests", "test\Serilog.Sinks.Splunk.Tests\Serilog.Sinks.Splunk.Tests.xproj", "{3C2D8E01-5580-426A-BDD9-EC59CD98E618}"
31+
EndProject
2832
Global
2933
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3034
Debug|Any CPU = Debug|Any CPU
@@ -39,12 +43,17 @@ Global
3943
{17497155-5D94-45DF-81D9-BD960E8CF217}.Debug|Any CPU.Build.0 = Debug|Any CPU
4044
{17497155-5D94-45DF-81D9-BD960E8CF217}.Release|Any CPU.ActiveCfg = Release|Any CPU
4145
{17497155-5D94-45DF-81D9-BD960E8CF217}.Release|Any CPU.Build.0 = Release|Any CPU
46+
{3C2D8E01-5580-426A-BDD9-EC59CD98E618}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
47+
{3C2D8E01-5580-426A-BDD9-EC59CD98E618}.Debug|Any CPU.Build.0 = Debug|Any CPU
48+
{3C2D8E01-5580-426A-BDD9-EC59CD98E618}.Release|Any CPU.ActiveCfg = Release|Any CPU
49+
{3C2D8E01-5580-426A-BDD9-EC59CD98E618}.Release|Any CPU.Build.0 = Release|Any CPU
4250
EndGlobalSection
4351
GlobalSection(SolutionProperties) = preSolution
4452
HideSolutionNode = FALSE
4553
EndGlobalSection
4654
GlobalSection(NestedProjects) = preSolution
4755
{32CF915C-3ECD-496C-8FDB-1214581274A6} = {7A774CBB-A6E9-4854-B4DB-4CF860B0C1C5}
4856
{17497155-5D94-45DF-81D9-BD960E8CF217} = {1C75E4A9-4CB1-497C-AD17-B438882051A1}
57+
{3C2D8E01-5580-426A-BDD9-EC59CD98E618} = {B9451AD8-09B9-4C09-A152-FBAE24806614}
4958
EndGlobalSection
5059
EndGlobal

src/Serilog.Sinks.Splunk/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
using System.Runtime.CompilerServices;
33

44
[assembly: AssemblyVersion("2.0.0.0")]
5+
6+
[assembly: InternalsVisibleTo("Serilog.Sinks.Splunk.Tests")]
Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2014 Serilog Contriutors
1+
// Copyright 2016 Serilog Contributors
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -10,56 +10,96 @@
1010
// distributed under the License is distributed on an "AS IS" BASIS,
1111
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
// See the License for the specific language governing permissions and
13-
// limitations under the License.using System;
13+
// limitations under the License.
1414

1515
using System;
16+
using System.Collections.Generic;
1617
using System.IO;
18+
using Serilog.Events;
19+
using Serilog.Formatting;
1720
using Serilog.Formatting.Json;
1821

1922
namespace Serilog.Sinks.Splunk
2023
{
2124
/// <summary>
22-
/// A json formatter to allow conditional rendering of properties
25+
/// Renders log events into a default JSON format for consumption by Splunk.
2326
/// </summary>
24-
public class SplunkJsonFormatter : JsonFormatter
27+
class SplunkJsonFormatter : ITextFormatter
2528
{
26-
private readonly bool _renderTemplate;
29+
static readonly JsonValueFormatter ValueFormatter = new JsonValueFormatter();
30+
31+
readonly bool _renderTemplate;
32+
readonly bool _renderMessage;
33+
readonly IFormatProvider _formatProvider;
2734

2835
/// <summary>
29-
/// Construct a <see cref="JsonFormatter"/>.
36+
/// Construct a <see cref="SplunkJsonFormatter"/>.
3037
/// </summary>
31-
/// <param name="omitEnclosingObject">If true, the properties of the event will be written to
32-
/// the output without enclosing braces. Otherwise, if false, each event will be written as a well-formed
33-
/// JSON object.</param>
34-
/// <param name="closingDelimiter">A string that will be written after each log event is formatted.
35-
/// If null, <see cref="Environment.NewLine"/> will be used. Ignored if <paramref name="omitEnclosingObject"/>
36-
/// is true.</param>
3738
/// <param name="renderMessage">If true, the message will be rendered and written to the output as a
3839
/// property named RenderedMessage.</param>
3940
/// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
4041
/// <param name="renderTemplate">If true, the template used will be rendered and written to the output as a property named MessageTemplate</param>
4142
public SplunkJsonFormatter(
42-
bool omitEnclosingObject = false,
43-
string closingDelimiter = null,
43+
bool renderTemplate = true,
4444
bool renderMessage = false,
45-
IFormatProvider formatProvider = null,
46-
bool renderTemplate = true)
47-
:base(omitEnclosingObject,closingDelimiter,renderMessage,formatProvider)
45+
IFormatProvider formatProvider = null)
4846
{
4947
_renderTemplate = renderTemplate;
48+
_renderMessage = renderMessage;
49+
_formatProvider = formatProvider;
5050
}
5151

52+
public void Format(LogEvent logEvent, TextWriter output)
53+
{
54+
if (logEvent == null) throw new ArgumentNullException(nameof(logEvent));
55+
if (output == null) throw new ArgumentNullException(nameof(output));
5256

53-
/// <summary>
54-
/// Writes the message with or without the message template
55-
/// </summary>
56-
/// <param name="template"></param>
57-
/// <param name="delim"></param>
58-
/// <param name="output"></param>
59-
protected override void WriteMessageTemplate(string template, ref string delim, TextWriter output)
57+
output.Write("{\"Timestamp\":\"");
58+
output.Write(logEvent.Timestamp.ToString("o"));
59+
output.Write("\",\"Level\":\"");
60+
output.Write(logEvent.Level);
61+
62+
if (_renderTemplate)
63+
{
64+
output.Write("\",\"MessageTemplate\":");
65+
JsonValueFormatter.WriteQuotedJsonString(logEvent.MessageTemplate.Text, output);
66+
}
67+
68+
if (_renderMessage)
69+
{
70+
output.Write("\",\"RenderedMessage\":");
71+
JsonValueFormatter.WriteQuotedJsonString(logEvent.RenderMessage(_formatProvider), output);
72+
}
73+
74+
if (logEvent.Exception != null)
75+
{
76+
output.Write(",\"Exception\":");
77+
JsonValueFormatter.WriteQuotedJsonString(logEvent.Exception.ToString(), output);
78+
}
79+
80+
if (logEvent.Properties.Count != 0)
81+
WriteProperties(logEvent.Properties, output);
82+
83+
output.Write('}');
84+
output.WriteLine();
85+
}
86+
87+
static void WriteProperties(IReadOnlyDictionary<string, LogEventPropertyValue> properties, TextWriter output)
6088
{
61-
if(_renderTemplate)
62-
base.WriteMessageTemplate(template, ref delim, output);
89+
output.Write(",\"Properties\":{");
90+
91+
var precedingDelimiter = "";
92+
foreach (var property in properties)
93+
{
94+
output.Write(precedingDelimiter);
95+
precedingDelimiter = ",";
96+
97+
JsonValueFormatter.WriteQuotedJsonString(property.Key, output);
98+
output.Write(':');
99+
ValueFormatter.Format(property.Value, output);
100+
}
101+
102+
output.Write('}');
63103
}
64104
}
65-
}
105+
}

src/Serilog.Sinks.Splunk/project.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "2.0.1",
2+
"version": "2.1.0-*",
33
"description": "The Splunk Sink for Serilog",
44
"authors": [
55
"Matthew Erbs, Serilog Contributors"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"profiles": {
3+
"test": {
4+
"commandName": "test"
5+
},
6+
"test-dnxcore50": {
7+
"commandName": "test",
8+
"sdkVersion": "dnx-coreclr-win-x86.1.0.0-rc1-final"
9+
}
10+
}
11+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
5+
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
6+
</PropertyGroup>
7+
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
8+
<PropertyGroup Label="Globals">
9+
<ProjectGuid>3c2d8e01-5580-426a-bdd9-ec59cd98e618</ProjectGuid>
10+
<RootNamespace>Serilog.Sinks.Splunk.Tests</RootNamespace>
11+
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
12+
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
13+
</PropertyGroup>
14+
<PropertyGroup>
15+
<SchemaVersion>2.0</SchemaVersion>
16+
</PropertyGroup>
17+
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
18+
</Project>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using System;
2+
using System.IO;
3+
using Newtonsoft.Json.Linq;
4+
using Xunit;
5+
using Serilog.Sinks.Splunk.Tests.Support;
6+
7+
namespace Serilog.Sinks.Splunk.Tests
8+
{
9+
public class SplunkJsonFormatterTests
10+
{
11+
void AssertValidJson(Action<ILogger> act)
12+
{
13+
var output = new StringWriter();
14+
var formatter = new SplunkJsonFormatter();
15+
var log = new LoggerConfiguration()
16+
.WriteTo.Sink(new TextWriterSink(output, formatter))
17+
.CreateLogger();
18+
19+
act(log);
20+
21+
var json = output.ToString();
22+
23+
// Unfortunately this will not detect all JSON formatting issues; better than nothing however.
24+
JObject.Parse(json);
25+
}
26+
27+
[Fact]
28+
public void AnEmptyEventIsValidJson()
29+
{
30+
AssertValidJson(log => log.Information("No properties"));
31+
}
32+
33+
[Fact]
34+
public void AMinimalEventIsValidJson()
35+
{
36+
AssertValidJson(log => log.Information("One {Property}", 42));
37+
}
38+
39+
[Fact]
40+
public void MultiplePropertiesAreDelimited()
41+
{
42+
AssertValidJson(log => log.Information("Property {First} and {Second}", "One", "Two"));
43+
}
44+
45+
[Fact]
46+
public void ExceptionsAreFormattedToValidJson()
47+
{
48+
AssertValidJson(log => log.Information(new DivideByZeroException(), "With exception"));
49+
}
50+
51+
[Fact]
52+
public void ExceptionAndPropertiesAreValidJson()
53+
{
54+
AssertValidJson(log => log.Information(new DivideByZeroException(), "With exception and {Property}", 42));
55+
}
56+
}
57+
}

0 commit comments

Comments
 (0)