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:
- .NET Framework 4.5 or later: Splunk logging for .NET requires the .NET Framework version 4.5 or later.
- Splunk Enterprise or Splunk Cloud: If you haven't already installed Splunk Enterprise, download it at http://www.splunk.com/download. Otherwise, you should have at least a trial subscription to Splunk Cloud.
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: Splunk logging for .NET supports development in Microsoft Visual Studio 2017 or later.
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:
- 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.
[email protected] | |
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.
- You can find help through our community on Splunk Answers (use the
logging-library-dotnet
tag to identify your questions). - File issues on GitHub.
Splunk logging for .NET is licensed under the Apache License 2.0. Details can be found in the LICENSE file.