diff --git a/Dockerfile b/Dockerfile index c42262e..ac43bb8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ -FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build -COPY . / +FROM microsoft/dotnet:8.0-sdk AS build +ADD . / WORKDIR /sample/Sample RUN dotnet restore -RUN dotnet publish -c Release -o out -f net6.0 +RUN dotnet publish -c Release -o out -f net8.0 -FROM mcr.microsoft.com/dotnet/runtime:6.0 AS runtime +FROM microsoft/dotnet:8.0-runtime AS runtime WORKDIR /sample/Sample COPY --from=build /sample/Sample/out ./ ENTRYPOINT ["dotnet", "Sample.dll"] \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index f9926d6..65bbf22 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,7 @@ version: '{build}' skip_tags: true image: - - Visual Studio 2019 + - Visual Studio 2022 - Ubuntu2004 configuration: - Release diff --git a/build.sh b/build.sh index f3c086a..b039722 100755 --- a/build.sh +++ b/build.sh @@ -7,11 +7,10 @@ dotnet restore for path in src/**/Serilog.Sinks.Splunk.csproj; do dotnet build -f netstandard2.0 -c Release ${path} dotnet build -f netstandard2.1 -c Release ${path} - dotnet build -f net6.0 -c Release ${path} done for path in test/*.Tests/*.csproj; do - dotnet test -f net6.0 -c Release ${path} + dotnet test -f net8.0 -c Release ${path} done -dotnet build -f net6.0 -c Release sample/Sample/Sample.csproj \ No newline at end of file +dotnet build -f net8.0 -c Release sample/Sample/Sample.csproj \ No newline at end of file diff --git a/sample/Sample/Program.cs b/sample/Sample/Program.cs index a77ee35..1f1dfd9 100644 --- a/sample/Sample/Program.cs +++ b/sample/Sample/Program.cs @@ -1,10 +1,10 @@ -using System.Collections.Generic; -using System.Linq; -using System.IO; +using Microsoft.Extensions.Configuration; using Serilog; using Serilog.Sinks.Splunk; -using Microsoft.Extensions.Configuration; using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; namespace Sample { @@ -18,7 +18,7 @@ public class Program public static void Main(string[] args) { // Bootstrap a simple logger. - var logger = new LoggerConfiguration() + var logger = new LoggerConfiguration() .WriteTo.Console() .CreateLogger(); @@ -94,7 +94,6 @@ public static void UsingAppSettingsJson(int eventsToCreate) var configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") - .AddUserSecrets() .Build(); Log.Logger = new LoggerConfiguration() diff --git a/sample/Sample/Sample.csproj b/sample/Sample/Sample.csproj index 35010d3..0521562 100644 --- a/sample/Sample/Sample.csproj +++ b/sample/Sample/Sample.csproj @@ -2,14 +2,14 @@ Exe - net6.0 + net8.0 - - + + diff --git a/src/Serilog.Sinks.Splunk/Serilog.Sinks.Splunk.csproj b/src/Serilog.Sinks.Splunk/Serilog.Sinks.Splunk.csproj index 98a67f0..48871b5 100644 --- a/src/Serilog.Sinks.Splunk/Serilog.Sinks.Splunk.csproj +++ b/src/Serilog.Sinks.Splunk/Serilog.Sinks.Splunk.csproj @@ -4,7 +4,7 @@ The Splunk Sink for Serilog 4.0.0 Matthew Erbs, Serilog Contributors - netstandard2.1;netstandard2.0;net6.0 + netstandard2.1;netstandard2.0;net6.0;net8.0 true Serilog.Sinks.Splunk Serilog.Sinks.Splunk @@ -24,7 +24,7 @@ - + diff --git a/src/Serilog.Sinks.Splunk/Sinks/Splunk/EventCollectorSink.cs b/src/Serilog.Sinks.Splunk/Sinks/Splunk/EventCollectorSink.cs index 8e2be66..1754dd2 100644 --- a/src/Serilog.Sinks.Splunk/Sinks/Splunk/EventCollectorSink.cs +++ b/src/Serilog.Sinks.Splunk/Sinks/Splunk/EventCollectorSink.cs @@ -164,8 +164,11 @@ public EventCollectorSink( : new EventCollectorClient(eventCollectorToken); } - /// - public async Task EmitBatchAsync(IEnumerable events) + /// + /// Emit a batch of log events, running asynchronously. + /// + /// The events to emit. + public virtual async Task EmitBatchAsync(IEnumerable events) { var allEvents = new StringWriter(); diff --git a/src/Serilog.Sinks.Splunk/SplunkLoggingConfigurationExtensions.cs b/src/Serilog.Sinks.Splunk/SplunkLoggingConfigurationExtensions.cs index 2fefae6..6baad8e 100644 --- a/src/Serilog.Sinks.Splunk/SplunkLoggingConfigurationExtensions.cs +++ b/src/Serilog.Sinks.Splunk/SplunkLoggingConfigurationExtensions.cs @@ -13,14 +13,15 @@ // limitations under the License. -using System; -using System.Net.Http; using Serilog.Configuration; using Serilog.Core; using Serilog.Events; using Serilog.Formatting; +using Serilog.Formatting.Json; using Serilog.Sinks.PeriodicBatching; using Serilog.Sinks.Splunk; +using System; +using System.Net.Http; namespace Serilog { @@ -64,25 +65,33 @@ public static LoggerConfiguration EventCollector( int batchIntervalInSeconds = 2, int batchSizeLimit = 100, int? queueLimit = null, - HttpMessageHandler messageHandler = null, + HttpMessageHandler messageHandler = null, LoggingLevelSwitch levelSwitch = null) { if (configuration == null) throw new ArgumentNullException(nameof(configuration)); + var batchingOptions = new PeriodicBatchingSinkOptions + { + BatchSizeLimit = batchSizeLimit, + Period = TimeSpan.FromSeconds(batchIntervalInSeconds), + EagerlyEmitFirstEvent = true, + QueueLimit = queueLimit + }; + var eventCollectorSink = new EventCollectorSink( splunkHost, - eventCollectorToken, + eventCollectorToken, uriPath, - source, - sourceType, - host, + source, + sourceType, + host, index, formatProvider, renderTemplate, messageHandler); + var batchingSink = new PeriodicBatchingSink(eventCollectorSink, batchingOptions); - return configuration.BuildPeriodicBatchingSink(eventCollectorSink, restrictedToMinimumLevel, levelSwitch, - batchIntervalInSeconds, batchSizeLimit, queueLimit); + return configuration.Sink(batchingSink, restrictedToMinimumLevel, levelSwitch); } /// @@ -117,16 +126,25 @@ public static LoggerConfiguration EventCollector( if (configuration == null) throw new ArgumentNullException(nameof(configuration)); if (jsonFormatter == null) throw new ArgumentNullException(nameof(jsonFormatter)); + + var batchingOptions = new PeriodicBatchingSinkOptions + { + BatchSizeLimit = batchSizeLimit, + Period = TimeSpan.FromSeconds(batchIntervalInSeconds), + EagerlyEmitFirstEvent = true, + QueueLimit = queueLimit + }; + var eventCollectorSink = new EventCollectorSink( splunkHost, eventCollectorToken, uriPath, - jsonFormatter, messageHandler); - return configuration.BuildPeriodicBatchingSink(eventCollectorSink, restrictedToMinimumLevel, levelSwitch, - batchIntervalInSeconds, batchSizeLimit, queueLimit); + var batchingSink = new PeriodicBatchingSink(eventCollectorSink, batchingOptions); + + return configuration.Sink(batchingSink, restrictedToMinimumLevel, levelSwitch); } @@ -172,7 +190,76 @@ public static LoggerConfiguration EventCollector( { if (configuration == null) throw new ArgumentNullException(nameof(configuration)); + var batchingOptions = new PeriodicBatchingSinkOptions + { + BatchSizeLimit = batchSizeLimit, + Period = TimeSpan.FromSeconds(batchIntervalInSeconds), + EagerlyEmitFirstEvent = true, + QueueLimit = queueLimit + }; + var eventCollectorSink = new EventCollectorSink( + splunkHost, + eventCollectorToken, + uriPath, + source, + sourceType, + host, + index, + fields, + formatProvider, + renderTemplate, + messageHandler); + + var batchingSink = new PeriodicBatchingSink(eventCollectorSink, batchingOptions); + + return configuration.Sink(batchingSink, restrictedToMinimumLevel, levelSwitch); + } + + /// + /// Adds a sink that writes log events as to a Splunk instance via the HTTP Event Collector. + /// + /// The logger config + /// The Splunk host that is configured with an Event Collector + /// The token provided to authenticate to the Splunk Event Collector + /// Change the default endpoint of the Event Collector e.g. services/collector/event + /// The Splunk index to log to + /// The source of the event + /// The source type of the event + /// The host of the event + /// The minimum log event level required in order to write an event to the sink. + /// Supplies culture-specific formatting information, or null. + /// If ture, the message template will be rendered + /// The handler used to send HTTP requests + /// A switch allowing the pass-through minimum level to be changed at runtime. + /// + public static LoggerConfiguration EventCollector( + this LoggerAuditSinkConfiguration configuration, + string splunkHost, + string eventCollectorToken, + string uriPath = "services/collector", + 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, + HttpMessageHandler messageHandler = null, + LoggingLevelSwitch levelSwitch = null) + { + if (configuration == null) throw new ArgumentNullException(nameof(configuration)); + + + var batchingOptions = new PeriodicBatchingSinkOptions + { + BatchSizeLimit = 100, + Period = TimeSpan.FromSeconds(2), + EagerlyEmitFirstEvent = true, + QueueLimit = 10000 + }; + + var eventCollectorSink = new EventCollectorAuditSink( splunkHost, eventCollectorToken, uriPath, @@ -180,31 +267,14 @@ public static LoggerConfiguration EventCollector( sourceType, host, index, - fields, formatProvider, renderTemplate, messageHandler ); - return configuration.BuildPeriodicBatchingSink(eventCollectorSink, restrictedToMinimumLevel, levelSwitch, - batchIntervalInSeconds, batchSizeLimit, queueLimit); - } - - private static LoggerConfiguration BuildPeriodicBatchingSink(this LoggerSinkConfiguration configuration, - EventCollectorSink eventCollectorSink, - LogEventLevel restrictedToMinimumLevel, - LoggingLevelSwitch levelSwitch = null, - int batchIntervalInSeconds = 2, - int batchSizeLimit = 100, - int? queueLimit = EventCollectorSink.DefaultQueueLimit) - { - var periodicBatchingOptions = new PeriodicBatchingSinkOptions - { - Period = TimeSpan.FromSeconds(batchIntervalInSeconds), QueueLimit = queueLimit, BatchSizeLimit = batchSizeLimit - }; - var periodicBatchSink = new PeriodicBatchingSink(eventCollectorSink, periodicBatchingOptions); + var batchingSink = new PeriodicBatchingSink(eventCollectorSink, batchingOptions); - return configuration.Sink(periodicBatchSink, restrictedToMinimumLevel, levelSwitch); + return configuration.Sink(batchingSink, restrictedToMinimumLevel, levelSwitch); } } } \ No newline at end of file diff --git a/src/Serilog.Sinks.TCP/Serilog.Sinks.Splunk.TCP.csproj b/src/Serilog.Sinks.TCP/Serilog.Sinks.Splunk.TCP.csproj index d41cd8a..e3a6ae6 100644 --- a/src/Serilog.Sinks.TCP/Serilog.Sinks.Splunk.TCP.csproj +++ b/src/Serilog.Sinks.TCP/Serilog.Sinks.Splunk.TCP.csproj @@ -20,7 +20,7 @@ - + diff --git a/src/Serilog.Sinks.UDP/Serilog.Sinks.Splunk.UDP.csproj b/src/Serilog.Sinks.UDP/Serilog.Sinks.Splunk.UDP.csproj index 95daf56..ab2c2db 100644 --- a/src/Serilog.Sinks.UDP/Serilog.Sinks.Splunk.UDP.csproj +++ b/src/Serilog.Sinks.UDP/Serilog.Sinks.Splunk.UDP.csproj @@ -20,6 +20,6 @@ - + diff --git a/test/Serilog.Sinks.Splunk.Tests/Serilog.Sinks.Splunk.Tests.csproj b/test/Serilog.Sinks.Splunk.Tests/Serilog.Sinks.Splunk.Tests.csproj index d8f0579..7f73a20 100644 --- a/test/Serilog.Sinks.Splunk.Tests/Serilog.Sinks.Splunk.Tests.csproj +++ b/test/Serilog.Sinks.Splunk.Tests/Serilog.Sinks.Splunk.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 Serilog.Sinks.Splunk.Tests Serilog.Sinks.Splunk.Tests true @@ -15,14 +15,14 @@ - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive +