Skip to content

Commit

Permalink
Splunk 9.1 + .NET 6 (#166)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Havagan authored Mar 16, 2024
1 parent 82e9aae commit 032f366
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 95 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ To start using the Splunk Event Collector (Splunk 6.3 and above), logging can be

```csharp
var log = new LoggerConfiguration()
.WriteTo.EventCollector("https://mysplunk:8088/services/collector", "myeventcollectortoken")
.WriteTo.EventCollector("https://mysplunk:8088/services/collector/event", "myeventcollectortoken")
.CreateLogger();
```

Expand All @@ -50,6 +50,7 @@ If using `appsettings.json` for configuration the following example illustrates
"Name": "EventCollector",
"Args": {
"splunkHost": "http://splunk:8088",
"uriPath": "services/collector/event",
"eventCollectorToken": "00112233-4455-6677-8899-AABBCCDDEEFF"
}
}
Expand Down
115 changes: 77 additions & 38 deletions sample/Sample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,58 +4,97 @@
using Serilog;
using Serilog.Sinks.Splunk;
using Microsoft.Extensions.Configuration;
using System;

namespace Sample
{
public class Program
{
const string SPLUNK_FULL_ENDPOINT = "http://splunk:8088/services/collector"; // Full splunk url
const string SPLUNK_ENDPOINT = "http://splunk:8088"; // Your splunk url
const string SPLUNK_FULL_ENDPOINT = "http://splunk:8088/services/collector/event"; // Full splunk url
const string SPLUNK_ENDPOINT = "http://splunk:8088"; // Your splunk url
const string SPLUNK_HEC_TOKEN = "00112233-4455-6677-8899-AABBCCDDEEFF"; // Your HEC token. See http://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector
public static string EventCollectorToken = SPLUNK_HEC_TOKEN;
public static string EventCollectorToken = SPLUNK_HEC_TOKEN;

public static void Main(string[] args)
{
var eventsToCreate = 100;
var runSSL = false;
var millisecsToWait = 60000;

if (args.Length > 0)
eventsToCreate = int.Parse(args[0]);

if (args.Length == 2)
runSSL = bool.Parse(args[1]);

if (args.Length == 3)
millisecsToWait = int.Parse(args[2]);

Serilog.Debugging.SelfLog.Enable(System.Console.Out);
Log.Information("Sample app starting up...");
Log.Information("Waiting {} millisecs...", millisecsToWait);
System.Threading.Thread.Sleep(millisecsToWait);

UsingAppSettingsJson(eventsToCreate);
UsingHostOnly(eventsToCreate);
UsingHostOnly(eventsToCreate);
UsingFullUri(eventsToCreate);
OverridingSource(eventsToCreate);
OverridingSourceType(eventsToCreate);
OverridingHost(eventsToCreate);
WithNoTemplate(eventsToCreate);
WithCompactSplunkFormatter(eventsToCreate);

if (runSSL)
// Bootstrap a simple logger.
var logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();

try
{
UsingSSL(eventsToCreate);
}
AddCustomFields(eventsToCreate);
logger.Information("Sample app starting up...");
logger.Information("Startup arguments \"{Arguments}\".", args);

var eventsToCreate = 100;
var runSSL = false;
var millisecsToWait = 60000;

if (args.Length > 0)
eventsToCreate = int.Parse(args[0]);

if (args.Length == 2)
runSSL = bool.Parse(args[1]);

if (args.Length == 3)
millisecsToWait = int.Parse(args[2]);

Serilog.Debugging.SelfLog.Enable(msg =>
{
Console.WriteLine(msg);
throw new Exception("Failed to write to Serilog.", new Exception(msg));
});

logger.Information("Waiting {MillisecondsToWait} millisecs...", millisecsToWait);
System.Threading.Thread.Sleep(millisecsToWait);

logger.Information("Creating logger {MethodName}.", nameof(UsingAppSettingsJson));
UsingAppSettingsJson(eventsToCreate);

logger.Information("Creating logger {MethodName}.", nameof(UsingHostOnly));
UsingHostOnly(eventsToCreate);

logger.Information("Creating logger {MethodName}.", nameof(UsingFullUri));
UsingFullUri(eventsToCreate);

Log.Information("Done....");
logger.Information("Creating logger {MethodName}.", nameof(OverridingSource));
OverridingSource(eventsToCreate);

logger.Information("Creating logger {MethodName}.", nameof(OverridingSourceType));
OverridingSourceType(eventsToCreate);

logger.Information("Creating logger {MethodName}.", nameof(OverridingHost));
OverridingHost(eventsToCreate);

logger.Information("Creating logger {MethodName}.", nameof(WithNoTemplate));
WithNoTemplate(eventsToCreate);

logger.Information("Creating logger {MethodName}.", nameof(WithCompactSplunkFormatter));
WithCompactSplunkFormatter(eventsToCreate);

if (runSSL)
{
logger.Information("Creating logger {MethodName}.", nameof(UsingSSL));
UsingSSL(eventsToCreate);
}

logger.Information("Creating logger {MethodName}.", nameof(AddCustomFields));
AddCustomFields(eventsToCreate);
}
finally
{
logger.Information("Done...");
Log.CloseAndFlush();
}
}

public static void UsingAppSettingsJson(int eventsToCreate)
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddUserSecrets<Program>()
.Build();

Log.Logger = new LoggerConfiguration()
Expand Down Expand Up @@ -263,7 +302,7 @@ public static void AddCustomFields(int eventsToCreate)
, host: System.Environment.MachineName
, source: "BackPackTestServerChannel"
, sourceType: "_json"
,fields: metaData)
, fields: metaData)
.Enrich.WithProperty("Serilog.Sinks.Splunk.Sample", "ViaEventCollector")
.Enrich.WithProperty("Serilog.Sinks.Splunk.Sample.TestType", "AddCustomFields")
.CreateLogger();
Expand All @@ -277,5 +316,5 @@ public static void AddCustomFields(int eventsToCreate)
}
}


}
12 changes: 7 additions & 5 deletions sample/Sample/Sample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<UserSecretsId>7e06bf41-4a1d-4a41-bcf3-cacd41388d5f</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.3.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.1" />
<PackageReference Include="Serilog" Version="3.0.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="7.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
38 changes: 20 additions & 18 deletions sample/Sample/appsettings.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
{
"Serilog": {
"Using": ["Serilog.Sinks.Console", "Serilog.Sinks.Splunk"],
"MinimumLevel": "Information",
"WriteTo": [{
"Name": "Console"
},
{
"Name": "EventCollector",
"Args": {
"splunkHost": "http://splunk:8088",
"eventCollectorToken": "00112233-4455-6677-8899-AABBCCDDEEFF"
}
}
],
"Properties": {
"Application": "Serilog Splunk Console Sample",
"Serilog.Sinks.Splunk.Sample": "ViaEventCollector",
"Serilog.Sinks.Splunk.Sample.TestType": "AppSettings.json"
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.Splunk" ],
"MinimumLevel": "Information",
"WriteTo": [
{
"Name": "Console"
},
{
"Name": "EventCollector",
"Args": {
"splunkHost": "http://splunk:8088/",
"uriPath": "services/collector/event",
"eventCollectorToken": "00112233-4455-6677-8899-AABBCCDDEEFF"
}
}
],
"Properties": {
"Application": "Serilog Splunk Console Sample",
"Serilog.Sinks.Splunk.Sample": "ViaEventCollector",
"Serilog.Sinks.Splunk.Sample.TestType": "AppSettings.json"
}
}
}
2 changes: 1 addition & 1 deletion sample/splunk/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
FROM splunk/splunk:7.2
FROM splunk/splunk:9.1
ADD etc ${SPLUNK_HOME}/etc
18 changes: 18 additions & 0 deletions src/Serilog.Sinks.Splunk/ConfigurationDefaults.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Serilog
{
internal static class ConfigurationDefaults
{
internal const string DefaultSource = "";
internal const string DefaultSourceType = "";
internal const string DefaultHost = "";
internal const string DefaultIndex = "";

/// <summary>
/// The default HTTP Event Collector path when not set via configuration.
/// </summary>
/// <remarks>
/// https://docs.splunk.com/Documentation/Splunk/9.1.0/Data/UsetheHTTPEventCollector#Send_data_to_HTTP_Event_Collector_on_Splunk_Enterprise
/// </remarks>
internal const string DefaultEventCollectorPath = "services/collector/event";
}
}
1 change: 1 addition & 0 deletions src/Serilog.Sinks.Splunk/Serilog.Sinks.Splunk.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<SignAssembly>true</SignAssembly>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ public EventCollectorClient(string eventCollectorToken, HttpMessageHandler messa

private void SetHeaders(string eventCollectorToken)
{
DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(AUTH_SCHEME, eventCollectorToken);
// Reminder: If the event collector url is redirected, all authentication headers will be removed.
// See: https://github.com/dotnet/runtime/blob/ccfe21882e4a2206ce49cd5b32d3eb3cab3e530f/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RedirectHandler.cs#L53

DefaultRequestHeaders.Authorization ??= new AuthenticationHeaderValue(AUTH_SCHEME, eventCollectorToken);

if (!this.DefaultRequestHeaders.Contains(SPLUNK_REQUEST_CHANNEL))
{
this.DefaultRequestHeaders.Add(SPLUNK_REQUEST_CHANNEL, Guid.NewGuid().ToString());
Expand Down
16 changes: 6 additions & 10 deletions src/Serilog.Sinks.Splunk/Sinks/Splunk/EventCollectorRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,14 @@ namespace Serilog.Sinks.Splunk
{
internal class EventCollectorRequest : HttpRequestMessage
{
internal EventCollectorRequest(string splunkHost, string jsonPayLoad, string uri ="services/collector")
internal EventCollectorRequest(string splunkHost, string jsonPayLoad, string uri = ConfigurationDefaults.DefaultEventCollectorPath)
{
var hostUrl = $@"{splunkHost}/{uri}";

if(splunkHost.Contains("services/collector"))
{
hostUrl = $@"{splunkHost}";
}

var stringContent = new StringContent(jsonPayLoad, Encoding.UTF8, "application/json");
var hostUrl = splunkHost.Contains(ConfigurationDefaults.DefaultEventCollectorPath)
? splunkHost
: $"{splunkHost.TrimEnd('/')}/{uri.TrimStart('/').TrimEnd('/')}";

RequestUri = new Uri(hostUrl);
Content = stringContent;
Content = new StringContent(jsonPayLoad, Encoding.UTF8, "application/json");
Method = HttpMethod.Post;
}
}
Expand Down
27 changes: 11 additions & 16 deletions src/Serilog.Sinks.Splunk/SplunkLoggingConfigurationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ namespace Serilog
/// </summary>
public static class SplunkLoggingConfigurationExtensions
{
internal const string DefaultSource = "";
internal const string DefaultSourceType = "";
internal const string DefaultHost = "";
internal const string DefaultIndex = "";

/// <summary>
/// Adds a sink that writes log events as to a Splunk instance via the HTTP Event Collector.
/// </summary>
Expand All @@ -57,11 +52,11 @@ public static LoggerConfiguration EventCollector(
this LoggerSinkConfiguration configuration,
string splunkHost,
string eventCollectorToken,
string uriPath = "services/collector",
string source = DefaultSource,
string sourceType = DefaultSourceType,
string host = DefaultHost,
string index = DefaultIndex,
string uriPath = ConfigurationDefaults.DefaultEventCollectorPath,
string source = ConfigurationDefaults.DefaultSource,
string sourceType = ConfigurationDefaults.DefaultSourceType,
string host = ConfigurationDefaults.DefaultHost,
string index = ConfigurationDefaults.DefaultIndex,
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
IFormatProvider formatProvider = null,
bool renderTemplate = true,
Expand Down Expand Up @@ -112,7 +107,7 @@ public static LoggerConfiguration EventCollector(
string splunkHost,
string eventCollectorToken,
ITextFormatter jsonFormatter,
string uriPath = "services/collector",
string uriPath = ConfigurationDefaults.DefaultEventCollectorPath,
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
int batchIntervalInSeconds = 2,
int batchSizeLimit = 100,
Expand Down Expand Up @@ -163,11 +158,11 @@ public static LoggerConfiguration EventCollector(
string splunkHost,
string eventCollectorToken,
CustomFields fields,
string uriPath = "services/collector",
string source = DefaultSource,
string sourceType = DefaultSourceType,
string host = DefaultHost,
string index = DefaultIndex,
string uriPath = ConfigurationDefaults.DefaultEventCollectorPath,
string source = ConfigurationDefaults.DefaultSource,
string sourceType = ConfigurationDefaults.DefaultSourceType,
string host = ConfigurationDefaults.DefaultHost,
string index = ConfigurationDefaults.DefaultIndex,
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
IFormatProvider formatProvider = null,
bool renderTemplate = true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<AssemblyName>Serilog.Sinks.Splunk.Tests</AssemblyName>
<PackageId>Serilog.Sinks.Splunk.Tests</PackageId>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
Expand All @@ -15,11 +15,11 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.1" />
<PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down

0 comments on commit 032f366

Please sign in to comment.