Splunk logging for .NET enables you to configure HTTP Event Collector, 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
The information in this Readme provides steps to get going quickly, but for more in-depth information be sure to visit Splunk logging for .NET page on Splunk Developer Portal.
Here's what you need to use Splunk logging for .NET:
If you want to build the libraries and run the test suite, you will also need:
You have several options for installing Splunk logging 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 Splunk logging for .NET, see Install Splunk logging 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
.
Splunk logging 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);
});
This feature requires Splunk 6.3.0 and later.
After enabling HTTP Event Collector and creating an application token sending events is very simple:
// TraceListener
var trace = new TraceSource("demo-logger");
trace.Listeners.Add(new HttpEventCollectorTraceListener(
uri: new Uri("https://splunk-server:8088"),
token: "<token-guid>"));
trace.TraceEvent(TraceEventType.Information, 0, "hello world");
// SLAB
var listener = new ObservableEventListener();
var sink = new HttpEventCollectorEventSink(
uri: new Uri("https://splunk-server:8088"),
token: "token-guid",
formatter: new AppEventFormatter());
listener.Subscribe(sink);
var eventSource = new AppEventSource();
listener.EnableEvents(eventSource, EventLevel.LogAlways, Keywords.All);
eventSource.Message("hello world");
A user application code can register an error handler that is invoked when HTTP Event Collector isn't able to send data.
listener.AddLoggingFailureHandler((sender, HttpEventCollectorException e) =>
{
// handle the error
});
The CHANGELOG.md
file in the root of the repository contains a description
of changes for each version of Splunk logging 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 logging for .NET. 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:
Stay connected with other developers building on Splunk.
devinfo@splunk.com | |
Issues | https://github.com/splunk/splunk-library-dotnetlogging |
Answers | http://splunk-base.splunk.com/tags/csharp/ |
Blog | http://blogs.splunk.com/dev/ |
@splunkdev |
If you want to make a code contribution, go to the Open Source page for more information.
The Splunk logging library for .NET is community-supported.
logging-library-dotnet
tag to identify your questions).Splunk logging for .NET is licensed under the Apache License 2.0. Details can be found in the LICENSE file.