The Splunk logging libraries for .NET enable you to configure UDP or TCP logging of events to a Splunk Enterprise instance from within your .NET applications, via a .NET TraceListener or a Semantic Logging Application Block (SLAB) event sink.
Each library consists of several extensions for existing .NET logging frameworks. Specifically, there are two libraries available, along with a third common library that is required by both main libraries:
- Splunk.Logging.TraceListener
- Splunk.Logging.SLAB
- Splunk.Logging.Common
If you can, it is better to log to files and monitor them with a Splunk Universal Forwarder. This provides you with the features of the Universal Forwarder, and added robustness from having persistent files. However, there are situations where using a Universal Forwarder is not a possibility. In these cases, writing directly to a UDP input is a reasonable approach.
You can use data cloning by providing multiple instances of your UDP handler in your logging configuration, each instance pointing to different indexers.
Rather than trying to reinvent load balancing across your indexers in your log configuration, set up a Splunk Universal Forwarder with a UDP input. Have all your logging sources write to that UDP input, and use the Universal Forwarder's load balancing features to distribute the data from there to a set of indexers.
The information in this Readme provides steps to get going quickly, but for more in-depth information be sure to visit the Splunk logging libraries for .NET page on Splunk Developer Portal.
Here's what you need to use the Splunk logging libraries for .NET:
- .NET Framework 4.0 or later: The Splunk logging libraries for .NET require at least .NET 4.0.
- Splunk Enterprise: If you haven't already installed Splunk Enterprise, download it at http://www.splunk.com/download. For more information about installing and running Splunk Enterprise and system requirements, see the Splunk Installation Manual.
If you want to build the libraries and run the test suite, you will also need:
- xUnit runner: If you use ReSharper, install its xUnit.net Test Support. Otherwise, install the xUnit.net runner for Visual Studio 2012 and 2013.
- Visual Studio: The Splunk logging libraries for .NET supports development in Microsoft Visual Studio 2012 or later.
You have several options for installing the Splunk logging libraries for .NET. The most common method is through NuGet. Add the package you want after searching for "splunk" in the Manage NuGet Packages window in Visual Studio.
For more information, and for information about other ways to install the Splunk logging libraries for .NET, see Install the Splunk logging libraries for .NET
The solution is organized into src and test directories. The src directory contains three libraries: Splunk.Logging.TraceListener (which contains .NET trace listeners that log events to Splunk Enterprise over UDP or TCP), Splunk.Logging.SLAB (which contains Semantic Logging Application Block (SLAB) event sinks that log ETW events to Splunk Enterprise over UDP or TCP), and Splunk.Logging.Common (a common library that contains resources required by both logging libraries). The test directory contains a single project, unit-tests.
The Splunk logging libraries for .NET include full unit tests which run using xunit.
Below is a snippet showing creating a TraceSource and then attaching a UdpTraceListener (or TcpTraceListener) configured to talk to localhost on port 10000. Next an event is generated which is sent to Splunk.
//setup
var traceSource = new TraceSource("TestLogger");
traceSource.Listeners.Remove("Default");
traceSource.Switch.Level = SourceLevels.All;
traceSource.Listeners.Add(new UdpTraceListener(IPAddress.Loopback, 10000));
// or, for TCP:
// traceSource.Listeners.Add(new TcpTraceListener(IPAddress.Loopback, 10000, new ExponentialBackoffTcpReconnectionPolicy()));
//log an event
traceSource.TraceEvent(TraceEventType.Information, 1, "Test event");
Below is a snippet showing how to create an ObservableEventListener and then subscribe to events with a UdpEventSink (or TcpEventSink) configured to talk to localhost on port 10000. Next a SimpleEventSource is instantiated and a test event is generated.
//setup
var listener = new ObservableEventListener();
listener.Subscribe(new UdpEventSink(IPAddress.Loopback, 10000));
// or, for TCP:
// listener.Subscribe(new TcpEventSink(IPAddress.Loopback, 10000, new ExponentialBackoffReconnectionPolicy()));
var eventSource = new SimpleEventSource();
listener.EnableEvents(eventSource, EventLevel.LogAlways, Keywords.All);
//log an event
eventSource.Message("Test event");
[EventSource(Name = "TestEventSource")]
public class SimpleEventSource : EventSource
{
public class Keywords { }
public class Tasks { }
[Event(1, Message = "{0}", Level = EventLevel.Error)]
internal void Message(string message)
{
this.WriteEvent(1, message);
}
}
In both the example above, the TCP listeners took an extra argument, which specifies how they should handle dropped TCP sessions. You can specify a custom reconnection policy by defining an implementation of Splunk.Logging.ITcpReconnectionPolicy and passing it to the constructors of the TcpTraceListener or TcpEventSink classes. If you have no particular policy in mind, use the ExponentialBackoffReconnectionPolicy provided by the library, which retries after increasingly long intervals, starting from a delay of one second and going to a plateau of ten minutes.
TcpConnectionPolicy has a single method, Connect, which tries to establish a connection or throws a TcpReconnectFailure if it cannot do so acceptably. Here is annotated source code of the default, exponential backoff policy:
public class ExponentialBackoffTcpReconnectionPolicy : ITcpReconnectionPolicy
{
private int ceiling = 10 * 60; // 10 minutes in seconds
// The arguments are:
//
// connect - a function that attempts a TCP connection given a host, port number.
// host - the host to connect to
// port - the port to connect on
// cancellationToken - used by TcpTraceListener and TcpEventSink to cancel this method
// when they are disposed.
public Socket Connect(Func<IPAddress, int, Socket> connect, IPAddress host, int port, CancellationToken cancellationToken)
{
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;
}
}
Another, simpler policy, would be trying to reconnect once, and then failing:
class TryOnceTcpConnectionPolicy : ITcpReconnectionPolicy
{
public Socket Connect(Func<System.Net.IPAddress, int, Socket> connect,
System.Net.IPAddress host, int port,
System.Threading.CancellationToken cancellationToken)
{
try
{
if (cancellationToken.IsCancellationRequested)
return null;
return connect(host, port);
}
catch (SocketException e)
{
throw new TcpReconnectFailureException("Reconnect failed: " + e.Message);
}
}
}
It can be difficult to diagnose connection problems in TCP logging without seeing the exceptions that are actually thrown. The exceptions thrown during connection attempts and by the reconnection policy are available by adding a handler to TcpEventSink or TcpTraceListener.
Both TcpEventSink and TcpTraceListener have a method that takes an action to be executed on each exception thrown in the logging system:
public void AddLoggingFailureHandler(Action<Exception> handler)
For example, to write them to a local console, you would write:
TcpTraceListener listener = ...;
listener.AddLoggingFailureHandler((ex) => {
Console.WriteLine("{0}", ex);
});
The CHANGELOG.md file in the root of the repository contains a description of changes for each version of the Splunk logging libraries for .NET. You can also find it online at
https://github.com/splunk/splunk-library-dotnetlogging/blob/master/CHANGELOG.md
The master branch always represents a stable and released version of the Splunk Library for .NET Logging. You can read more about our branching model on our Wiki at
https://github.com/splunk/splunk-sdk-python/wiki/Branching-Model
If you need to know more:
- For all things developer with Splunk, your main resource is the Splunk Developer Portal.
- For more about the Splunk REST API, see the REST API Reference.
- For more about about Splunk in general, see Splunk>Docs.
Stay connected with other developers building on Splunk.
If you want to make a code contribution, go to the Open Source page for more information.
This product is currently in development and officially unsupported. We will be triaging any issues filed by the community however and addressing them as appropriate. Please file issues for any problems that you encounter.
You can reach the Dev Platform team at [email protected].
The Splunk Logging Libraries for .NET are licensed under the Apache License 2.0. Details can be found in the LICENSE file.