-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
* Create unit tests for TCP collector. * Signing assembly breaks Splunk TCP collector. Switch to ProjectReference * Alternative solution Embedding sources from Splunk.Loggin.Common * Add target for net6.0 & net8.0
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,20 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<Import Project="../common.props"/> | ||
<Import Project="../common.props" /> | ||
|
||
<PropertyGroup> | ||
<Description>The Splunk TCP Sink for Serilog</Description> | ||
<TargetFrameworks>netstandard2.1;netstandard2.0</TargetFrameworks> | ||
<TargetFrameworks>netstandard2.1;netstandard2.0;net6.0;net8.0</TargetFrameworks> | ||
<AssemblyName>Serilog.Sinks.Splunk.TCP</AssemblyName> | ||
<PackageId>Serilog.Sinks.Splunk.TCP</PackageId> | ||
<PackageTags>serilog;splunk;logging;tcp</PackageTags> | ||
<AssemblyOriginatorKeyFile>../../assets/Serilog.snk</AssemblyOriginatorKeyFile> | ||
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign> | ||
<PublicSign Condition=" '$(Configuration)' == 'Debug' ">true</PublicSign> | ||
<SignAssembly>true</SignAssembly> | ||
<IsPackable>true</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Serilog.Sinks.Splunk" Version="4.0.0" /> | ||
<PackageReference Include="Splunk.Logging.Common.Core" Version="1.0.0" /> | ||
<ProjectReference Include="..\Serilog.Sinks.Splunk\Serilog.Sinks.Splunk.csproj" /> | ||
</ItemGroup> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* Copyright 2014 Splunk, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"): you may | ||
* not use this file except in compliance with the License. You may obtain | ||
* a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
using System; | ||
using System.Net; | ||
using System.Net.Sockets; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace Splunk.Logging | ||
{ | ||
/// <summary> | ||
/// TcpConnectionPolicy implementation that tries to reconnect after | ||
/// increasingly long intervals. | ||
/// </summary> | ||
/// <remarks> | ||
/// The intervals double every time, starting from 0s, 1s, 2s, 4s, ... | ||
/// until 10 minutes between connections, when it plateaus and does | ||
/// not increase the interval length any further. | ||
/// </remarks> | ||
public class ExponentialBackoffTcpReconnectionPolicy : ITcpReconnectionPolicy | ||
{ | ||
private int ceiling = 10 * 60; // 10 minutes in seconds | ||
|
||
public Socket Connect(Func<IPAddress, int, Socket> connect, IPAddress host, int port, CancellationToken cancellationToken) | ||
Check warning on line 37 in src/Serilog.Sinks.TCP/Splunk.Logging/ExponentialBackoffTcpReconnectionPolicy.cs GitHub Actions / build
Check warning on line 37 in src/Serilog.Sinks.TCP/Splunk.Logging/ExponentialBackoffTcpReconnectionPolicy.cs GitHub Actions / build
|
||
{ | ||
int delay = 1; // in seconds | ||
while (!cancellationToken.IsCancellationRequested) | ||
{ | ||
try | ||
{ | ||
return connect(host, port); | ||
} | ||
catch (SocketException) { } | ||
|
||
// If this is cancelled via the cancellationToken instead of | ||
// completing its delay, the next while-loop test will fail, | ||
// the loop will terminate, and the method will return null | ||
// with no additional connection attempts. | ||
Task.Delay(delay * 1000, cancellationToken).Wait(); | ||
// The nth delay is min(10 minutes, 2^n - 1 seconds). | ||
delay = Math.Min((delay + 1) * 2 - 1, ceiling); | ||
} | ||
|
||
// cancellationToken has been cancelled. | ||
return null; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
* Copyright 2014 Splunk, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"): you may | ||
* not use this file except in compliance with the License. You may obtain | ||
* a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
using System; | ||
using System.Collections.Concurrent; | ||
using System.Threading; | ||
|
||
namespace Splunk.Logging | ||
{ | ||
/// <summary> | ||
/// A queue with a maximum size. When the queue is at its maximum size | ||
/// and a new item is queued, the oldest item in the queue is dropped. | ||
/// </summary> | ||
/// <typeparam name="T"></typeparam> | ||
internal class FixedSizeQueue<T> | ||
{ | ||
public int Size { get; private set; } | ||
public IProgress<bool> Progress = new Progress<bool>(); | ||
public bool IsCompleted { get; private set; } | ||
|
||
private readonly BlockingCollection<T> _collection = new BlockingCollection<T>(); | ||
|
||
public FixedSizeQueue(int size) | ||
: base() | ||
{ | ||
Size = size; | ||
IsCompleted = false; | ||
} | ||
|
||
public void Enqueue(T obj) | ||
{ | ||
lock (this) | ||
{ | ||
if (IsCompleted) | ||
{ | ||
throw new InvalidOperationException("Tried to add an item to a completed queue."); | ||
} | ||
|
||
_collection.Add(obj); | ||
|
||
while (_collection.Count > Size) | ||
{ | ||
_collection.Take(); | ||
} | ||
Progress.Report(true); | ||
} | ||
} | ||
|
||
public void CompleteAdding() | ||
{ | ||
lock (this) | ||
{ | ||
IsCompleted = true; | ||
} | ||
} | ||
|
||
public T Dequeue(CancellationToken cancellationToken) | ||
{ | ||
return _collection.Take(cancellationToken); | ||
} | ||
|
||
public T Dequeue() | ||
{ | ||
return _collection.Take(); | ||
} | ||
|
||
|
||
public decimal Count { get { return _collection.Count; } } | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* Copyright 2014 Splunk, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"): you may | ||
* not use this file except in compliance with the License. You may obtain | ||
* a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
using System; | ||
using System.Net; | ||
using System.Net.Sockets; | ||
using System.Threading; | ||
|
||
namespace Splunk.Logging | ||
{ | ||
/// <summary> | ||
/// TcpConnectionPolicy encapsulates a policy for what logging via TCP should | ||
/// do when there is a socket error. | ||
/// </summary> | ||
/// <remarks> | ||
/// TCP loggers in this library (TcpTraceListener and TcpEventSink) take a | ||
/// TcpConnectionPolicy as an argument to their constructor. When the TCP | ||
/// session the logger uses has an error, the logger suspends logging and calls | ||
/// the Reconnect method of an implementation of TcpConnectionPolicy to get a | ||
/// new socket. | ||
/// </remarks> | ||
public interface ITcpReconnectionPolicy | ||
{ | ||
// A blocking method that should eventually return a Socket when it finally | ||
// manages to get a connection, or throw a TcpReconnectFailure if the policy | ||
// says to give up trying to connect. | ||
/// <summary> | ||
/// Try to reestablish a TCP connection. | ||
/// </summary> | ||
/// <remarks> | ||
/// The method should block until it either | ||
/// | ||
/// 1. succeeds and returns a connected TCP socket, or | ||
/// 2. fails and throws a TcpReconnectFailure exception, or | ||
/// 3. the cancellationToken is cancelled, in which case the method should | ||
/// return null. | ||
/// | ||
/// The method takes a zero-parameter function that encapsulates trying to | ||
/// make a single connection and a cancellation token to stop the method | ||
/// if the logging system that invoked it is disposed. | ||
/// | ||
/// For example, the default ExponentialBackoffTcpConnectionPolicy invokes | ||
/// connect after increasingly long intervals until it makes a successful | ||
/// connnection, or is cancelled by the cancellationToken, at which point | ||
/// it returns null. | ||
/// </remarks> | ||
/// <param name="connect">A zero-parameter function that tries once to | ||
/// establish a connection.</param> | ||
/// <param name="cancellationToken">A token used to cancel the reconnect | ||
/// attempt when the invoking logger is disposed.</param> | ||
/// <returns>A connected TCP socket.</returns> | ||
Socket Connect(Func<IPAddress, int, Socket> connect, IPAddress host, int port, CancellationToken cancellationToken); | ||
Check warning on line 64 in src/Serilog.Sinks.TCP/Splunk.Logging/ITcpReconnectionPolicy.cs GitHub Actions / build
Check warning on line 64 in src/Serilog.Sinks.TCP/Splunk.Logging/ITcpReconnectionPolicy.cs GitHub Actions / build
Check warning on line 64 in src/Serilog.Sinks.TCP/Splunk.Logging/ITcpReconnectionPolicy.cs GitHub Actions / build
Check warning on line 64 in src/Serilog.Sinks.TCP/Splunk.Logging/ITcpReconnectionPolicy.cs GitHub Actions / build
|
||
} | ||
} |