Skip to content

Commit 032f366

Browse files
authored
Splunk 9.1 + .NET 6 (#166)
* Sample: Target net6.0. Added additional logging statements. * Docker: Splunk 9.1. * Tests: Target net6.0 and updated nuget packages. * Added constant for services/collector. Event request trims / from uri. Updated collector URL for Splunk 9.1
1 parent 82e9aae commit 032f366

File tree

11 files changed

+153
-95
lines changed

11 files changed

+153
-95
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ To start using the Splunk Event Collector (Splunk 6.3 and above), logging can be
3232

3333
```csharp
3434
var log = new LoggerConfiguration()
35-
.WriteTo.EventCollector("https://mysplunk:8088/services/collector", "myeventcollectortoken")
35+
.WriteTo.EventCollector("https://mysplunk:8088/services/collector/event", "myeventcollectortoken")
3636
.CreateLogger();
3737
```
3838

@@ -50,6 +50,7 @@ If using `appsettings.json` for configuration the following example illustrates
5050
"Name": "EventCollector",
5151
"Args": {
5252
"splunkHost": "http://splunk:8088",
53+
"uriPath": "services/collector/event",
5354
"eventCollectorToken": "00112233-4455-6677-8899-AABBCCDDEEFF"
5455
}
5556
}

sample/Sample/Program.cs

Lines changed: 77 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,58 +4,97 @@
44
using Serilog;
55
using Serilog.Sinks.Splunk;
66
using Microsoft.Extensions.Configuration;
7+
using System;
8+
79
namespace Sample
810
{
911
public class Program
1012
{
11-
const string SPLUNK_FULL_ENDPOINT = "http://splunk:8088/services/collector"; // Full splunk url
12-
const string SPLUNK_ENDPOINT = "http://splunk:8088"; // Your splunk url
13+
const string SPLUNK_FULL_ENDPOINT = "http://splunk:8088/services/collector/event"; // Full splunk url
14+
const string SPLUNK_ENDPOINT = "http://splunk:8088"; // Your splunk url
1315
const string SPLUNK_HEC_TOKEN = "00112233-4455-6677-8899-AABBCCDDEEFF"; // Your HEC token. See http://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector
14-
public static string EventCollectorToken = SPLUNK_HEC_TOKEN;
16+
public static string EventCollectorToken = SPLUNK_HEC_TOKEN;
1517

1618
public static void Main(string[] args)
1719
{
18-
var eventsToCreate = 100;
19-
var runSSL = false;
20-
var millisecsToWait = 60000;
21-
22-
if (args.Length > 0)
23-
eventsToCreate = int.Parse(args[0]);
24-
25-
if (args.Length == 2)
26-
runSSL = bool.Parse(args[1]);
27-
28-
if (args.Length == 3)
29-
millisecsToWait = int.Parse(args[2]);
30-
31-
Serilog.Debugging.SelfLog.Enable(System.Console.Out);
32-
Log.Information("Sample app starting up...");
33-
Log.Information("Waiting {} millisecs...", millisecsToWait);
34-
System.Threading.Thread.Sleep(millisecsToWait);
35-
36-
UsingAppSettingsJson(eventsToCreate);
37-
UsingHostOnly(eventsToCreate);
38-
UsingHostOnly(eventsToCreate);
39-
UsingFullUri(eventsToCreate);
40-
OverridingSource(eventsToCreate);
41-
OverridingSourceType(eventsToCreate);
42-
OverridingHost(eventsToCreate);
43-
WithNoTemplate(eventsToCreate);
44-
WithCompactSplunkFormatter(eventsToCreate);
45-
46-
if (runSSL)
20+
// Bootstrap a simple logger.
21+
var logger = new LoggerConfiguration()
22+
.WriteTo.Console()
23+
.CreateLogger();
24+
25+
try
4726
{
48-
UsingSSL(eventsToCreate);
49-
}
50-
AddCustomFields(eventsToCreate);
27+
logger.Information("Sample app starting up...");
28+
logger.Information("Startup arguments \"{Arguments}\".", args);
29+
30+
var eventsToCreate = 100;
31+
var runSSL = false;
32+
var millisecsToWait = 60000;
33+
34+
if (args.Length > 0)
35+
eventsToCreate = int.Parse(args[0]);
36+
37+
if (args.Length == 2)
38+
runSSL = bool.Parse(args[1]);
39+
40+
if (args.Length == 3)
41+
millisecsToWait = int.Parse(args[2]);
42+
43+
Serilog.Debugging.SelfLog.Enable(msg =>
44+
{
45+
Console.WriteLine(msg);
46+
throw new Exception("Failed to write to Serilog.", new Exception(msg));
47+
});
48+
49+
logger.Information("Waiting {MillisecondsToWait} millisecs...", millisecsToWait);
50+
System.Threading.Thread.Sleep(millisecsToWait);
51+
52+
logger.Information("Creating logger {MethodName}.", nameof(UsingAppSettingsJson));
53+
UsingAppSettingsJson(eventsToCreate);
54+
55+
logger.Information("Creating logger {MethodName}.", nameof(UsingHostOnly));
56+
UsingHostOnly(eventsToCreate);
57+
58+
logger.Information("Creating logger {MethodName}.", nameof(UsingFullUri));
59+
UsingFullUri(eventsToCreate);
5160

52-
Log.Information("Done....");
61+
logger.Information("Creating logger {MethodName}.", nameof(OverridingSource));
62+
OverridingSource(eventsToCreate);
63+
64+
logger.Information("Creating logger {MethodName}.", nameof(OverridingSourceType));
65+
OverridingSourceType(eventsToCreate);
66+
67+
logger.Information("Creating logger {MethodName}.", nameof(OverridingHost));
68+
OverridingHost(eventsToCreate);
69+
70+
logger.Information("Creating logger {MethodName}.", nameof(WithNoTemplate));
71+
WithNoTemplate(eventsToCreate);
72+
73+
logger.Information("Creating logger {MethodName}.", nameof(WithCompactSplunkFormatter));
74+
WithCompactSplunkFormatter(eventsToCreate);
75+
76+
if (runSSL)
77+
{
78+
logger.Information("Creating logger {MethodName}.", nameof(UsingSSL));
79+
UsingSSL(eventsToCreate);
80+
}
81+
82+
logger.Information("Creating logger {MethodName}.", nameof(AddCustomFields));
83+
AddCustomFields(eventsToCreate);
84+
}
85+
finally
86+
{
87+
logger.Information("Done...");
88+
Log.CloseAndFlush();
89+
}
5390
}
91+
5492
public static void UsingAppSettingsJson(int eventsToCreate)
5593
{
5694
var configuration = new ConfigurationBuilder()
5795
.SetBasePath(Directory.GetCurrentDirectory())
5896
.AddJsonFile("appsettings.json")
97+
.AddUserSecrets<Program>()
5998
.Build();
6099

61100
Log.Logger = new LoggerConfiguration()
@@ -263,7 +302,7 @@ public static void AddCustomFields(int eventsToCreate)
263302
, host: System.Environment.MachineName
264303
, source: "BackPackTestServerChannel"
265304
, sourceType: "_json"
266-
,fields: metaData)
305+
, fields: metaData)
267306
.Enrich.WithProperty("Serilog.Sinks.Splunk.Sample", "ViaEventCollector")
268307
.Enrich.WithProperty("Serilog.Sinks.Splunk.Sample.TestType", "AddCustomFields")
269308
.CreateLogger();
@@ -277,5 +316,5 @@ public static void AddCustomFields(int eventsToCreate)
277316
}
278317
}
279318

280-
319+
281320
}

sample/Sample/Sample.csproj

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net5.0</TargetFramework>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<UserSecretsId>7e06bf41-4a1d-4a41-bcf3-cacd41388d5f</UserSecretsId>
67
</PropertyGroup>
78

89
<ItemGroup>
9-
<PackageReference Include="Serilog" Version="2.10.0" />
10-
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.0" />
11-
<PackageReference Include="Serilog.Settings.Configuration" Version="3.3.0" />
12-
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
10+
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
11+
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.1" />
12+
<PackageReference Include="Serilog" Version="3.0.1" />
13+
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
14+
<PackageReference Include="Serilog.Settings.Configuration" Version="7.0.0" />
1315
</ItemGroup>
1416

1517
<ItemGroup>

sample/Sample/appsettings.json

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
{
2-
"Serilog": {
3-
"Using": ["Serilog.Sinks.Console", "Serilog.Sinks.Splunk"],
4-
"MinimumLevel": "Information",
5-
"WriteTo": [{
6-
"Name": "Console"
7-
},
8-
{
9-
"Name": "EventCollector",
10-
"Args": {
11-
"splunkHost": "http://splunk:8088",
12-
"eventCollectorToken": "00112233-4455-6677-8899-AABBCCDDEEFF"
13-
}
14-
}
15-
],
16-
"Properties": {
17-
"Application": "Serilog Splunk Console Sample",
18-
"Serilog.Sinks.Splunk.Sample": "ViaEventCollector",
19-
"Serilog.Sinks.Splunk.Sample.TestType": "AppSettings.json"
2+
"Serilog": {
3+
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.Splunk" ],
4+
"MinimumLevel": "Information",
5+
"WriteTo": [
6+
{
7+
"Name": "Console"
8+
},
9+
{
10+
"Name": "EventCollector",
11+
"Args": {
12+
"splunkHost": "http://splunk:8088/",
13+
"uriPath": "services/collector/event",
14+
"eventCollectorToken": "00112233-4455-6677-8899-AABBCCDDEEFF"
2015
}
16+
}
17+
],
18+
"Properties": {
19+
"Application": "Serilog Splunk Console Sample",
20+
"Serilog.Sinks.Splunk.Sample": "ViaEventCollector",
21+
"Serilog.Sinks.Splunk.Sample.TestType": "AppSettings.json"
2122
}
23+
}
2224
}

sample/splunk/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
FROM splunk/splunk:7.2
1+
FROM splunk/splunk:9.1
22
ADD etc ${SPLUNK_HOME}/etc
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace Serilog
2+
{
3+
internal static class ConfigurationDefaults
4+
{
5+
internal const string DefaultSource = "";
6+
internal const string DefaultSourceType = "";
7+
internal const string DefaultHost = "";
8+
internal const string DefaultIndex = "";
9+
10+
/// <summary>
11+
/// The default HTTP Event Collector path when not set via configuration.
12+
/// </summary>
13+
/// <remarks>
14+
/// https://docs.splunk.com/Documentation/Splunk/9.1.0/Data/UsetheHTTPEventCollector#Send_data_to_HTTP_Event_Collector_on_Splunk_Enterprise
15+
/// </remarks>
16+
internal const string DefaultEventCollectorPath = "services/collector/event";
17+
}
18+
}

src/Serilog.Sinks.Splunk/Serilog.Sinks.Splunk.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
1919
<SignAssembly>true</SignAssembly>
2020
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
21+
<LangVersion>latest</LangVersion>
2122
</PropertyGroup>
2223

2324
<ItemGroup>

src/Serilog.Sinks.Splunk/Sinks/Splunk/EventCollectorClient.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ public EventCollectorClient(string eventCollectorToken, HttpMessageHandler messa
3636

3737
private void SetHeaders(string eventCollectorToken)
3838
{
39-
DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(AUTH_SCHEME, eventCollectorToken);
39+
// Reminder: If the event collector url is redirected, all authentication headers will be removed.
40+
// See: https://github.com/dotnet/runtime/blob/ccfe21882e4a2206ce49cd5b32d3eb3cab3e530f/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RedirectHandler.cs#L53
41+
42+
DefaultRequestHeaders.Authorization ??= new AuthenticationHeaderValue(AUTH_SCHEME, eventCollectorToken);
43+
4044
if (!this.DefaultRequestHeaders.Contains(SPLUNK_REQUEST_CHANNEL))
4145
{
4246
this.DefaultRequestHeaders.Add(SPLUNK_REQUEST_CHANNEL, Guid.NewGuid().ToString());

src/Serilog.Sinks.Splunk/Sinks/Splunk/EventCollectorRequest.cs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,14 @@ namespace Serilog.Sinks.Splunk
2121
{
2222
internal class EventCollectorRequest : HttpRequestMessage
2323
{
24-
internal EventCollectorRequest(string splunkHost, string jsonPayLoad, string uri ="services/collector")
24+
internal EventCollectorRequest(string splunkHost, string jsonPayLoad, string uri = ConfigurationDefaults.DefaultEventCollectorPath)
2525
{
26-
var hostUrl = $@"{splunkHost}/{uri}";
27-
28-
if(splunkHost.Contains("services/collector"))
29-
{
30-
hostUrl = $@"{splunkHost}";
31-
}
32-
33-
var stringContent = new StringContent(jsonPayLoad, Encoding.UTF8, "application/json");
26+
var hostUrl = splunkHost.Contains(ConfigurationDefaults.DefaultEventCollectorPath)
27+
? splunkHost
28+
: $"{splunkHost.TrimEnd('/')}/{uri.TrimStart('/').TrimEnd('/')}";
29+
3430
RequestUri = new Uri(hostUrl);
35-
Content = stringContent;
31+
Content = new StringContent(jsonPayLoad, Encoding.UTF8, "application/json");
3632
Method = HttpMethod.Post;
3733
}
3834
}

src/Serilog.Sinks.Splunk/SplunkLoggingConfigurationExtensions.cs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@ namespace Serilog
2828
/// </summary>
2929
public static class SplunkLoggingConfigurationExtensions
3030
{
31-
internal const string DefaultSource = "";
32-
internal const string DefaultSourceType = "";
33-
internal const string DefaultHost = "";
34-
internal const string DefaultIndex = "";
35-
3631
/// <summary>
3732
/// Adds a sink that writes log events as to a Splunk instance via the HTTP Event Collector.
3833
/// </summary>
@@ -57,11 +52,11 @@ public static LoggerConfiguration EventCollector(
5752
this LoggerSinkConfiguration configuration,
5853
string splunkHost,
5954
string eventCollectorToken,
60-
string uriPath = "services/collector",
61-
string source = DefaultSource,
62-
string sourceType = DefaultSourceType,
63-
string host = DefaultHost,
64-
string index = DefaultIndex,
55+
string uriPath = ConfigurationDefaults.DefaultEventCollectorPath,
56+
string source = ConfigurationDefaults.DefaultSource,
57+
string sourceType = ConfigurationDefaults.DefaultSourceType,
58+
string host = ConfigurationDefaults.DefaultHost,
59+
string index = ConfigurationDefaults.DefaultIndex,
6560
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
6661
IFormatProvider formatProvider = null,
6762
bool renderTemplate = true,
@@ -112,7 +107,7 @@ public static LoggerConfiguration EventCollector(
112107
string splunkHost,
113108
string eventCollectorToken,
114109
ITextFormatter jsonFormatter,
115-
string uriPath = "services/collector",
110+
string uriPath = ConfigurationDefaults.DefaultEventCollectorPath,
116111
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
117112
int batchIntervalInSeconds = 2,
118113
int batchSizeLimit = 100,
@@ -163,11 +158,11 @@ public static LoggerConfiguration EventCollector(
163158
string splunkHost,
164159
string eventCollectorToken,
165160
CustomFields fields,
166-
string uriPath = "services/collector",
167-
string source = DefaultSource,
168-
string sourceType = DefaultSourceType,
169-
string host = DefaultHost,
170-
string index = DefaultIndex,
161+
string uriPath = ConfigurationDefaults.DefaultEventCollectorPath,
162+
string source = ConfigurationDefaults.DefaultSource,
163+
string sourceType = ConfigurationDefaults.DefaultSourceType,
164+
string host = ConfigurationDefaults.DefaultHost,
165+
string index = ConfigurationDefaults.DefaultIndex,
171166
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
172167
IFormatProvider formatProvider = null,
173168
bool renderTemplate = true,

0 commit comments

Comments
 (0)