Overview of the Splunk SDK for C#

Welcome to the Splunk® Software Development Kit (SDK) for C#!

This SDK is open source and uses the Apache v2.0 license. If you want to make a code contribution, go to the Open Source page for more information.

This overview tells you more about:

 

What you can do with the Splunk SDK for C#

This SDK contains library code and examples designed to enable developers to build applications using Splunk. With the Splunk SDK for C# you can write C# applications to programmatically interact with the Splunk engine. The SDK is built on top of the REST API, providing a wrapper over the REST API endpoints. So with fewer lines of code, you can write applications that:

  • Search your data, run saved searches, and work with search jobs
  • Manage Splunk configurations and objects
  • Integrate search results into your applications
  • Log directly to Splunk
  • Present a custom UI

The Splunk SDK for C# supports development in Microsoft Visual Studio 2012. The minimum supported version of the .NET Framework is version 3.5. Visual Studio downloads are available on the Visual Studio Downloads webpage.

 

The Splunk SDK for C# components

The Splunk developer platform consists of three primary components: Splunkd, the engine; Splunk Web, the app framework that sits on top of the engine; and the Splunk SDKs that interface with the REST API and extension points.

The Splunk SDK for C# lets you target Splunkd by making calls against the engine's REST API and accessing the various Splunkd extension points such as custom search commands, lookup functions, scripted inputs, and custom REST handlers.

Read more about:

 

Namespaces

To account for permissions to view apps, system files, and other entity resources by users throughout a Splunk installation, Splunk provides access to entity resources based on a namespace. This is similar to the app/user context that is used by the Splunk REST API when accessing resources using endpoints.

The namespace is defined by:

  • An owner, which is the Splunk username, such as "admin". A value of "nobody" means no specific user. The "-" wildcard means all users.
  • An app, which is the app context for this resource (such as "search"). The "-" wildcard means all apps.
  • A sharing mode, which indicates how the resource is shared. The sharing mode can be:
    • "user": The resource is private to a specific user, as specified by owner.
    • "app": The resource is shared through an app, as specified by app. The owner is "nobody", meaning no specific user.
    • "global": The resource is globally shared to all apps. The owner is "nobody", meaning no specific user.
    • "system": The resource is a system resource (owner is "nobody", app is "system").

In general, when you specify a namespace you can specify any combination of owner, app, and sharing the SDK library will reconcile the values, overriding them as appropriate. If a namespace is not explicitly specified, the current user is used for owner and the default app is used for app.

Here are some example combinations of owner, app, sharing:

  • List all of the saved searches for a specific user named Kramer: kramer, -, user
  • Create an index to be used within the Search app: nobody, search, app
 

The Service class

The Service class is the primary entry point for the client library. Construct an instance of the Service class and provide the login credentials that are required to connect to an available Splunk server. There are different ways to construct the instance and authenticate; here's one way:

// Define the context of the Splunk service
ServiceArgs svcArgs = new ServiceArgs();
svcArgs.Host = "localhost";
svcArgs.Port = 8089;

// Create a Service instance and log in 
Service service = new Service(svcArgs);
service.Login("admin", "changeme");

Once the Service instance is created and authenticated, you can use it to navigate, enumerate, and operate on a wide variety of Splunk resources.

 

Entities and collections

The Splunk REST API consists of over 160 endpoints that provide access to almost every feature of Splunk. The majority of the Splunk SDK for C# API follows a convention of exposing resources as collections of entities, where an entity is a resource that has properties, actions, and metadata that describes the entity. The entity/collection pattern provides a consistent approach to interacting with resources and collections of resources.

For example, the following code prints all Splunk users:

foreach (var user in service.GetUsers().Values) {
    System.Console.WriteLine(user.RealName);
}

Similarly, the following code prints all the Splunk apps:

foreach (var app in service.GetApplications().Values) {
    System.Console.WriteLine(app.Label);
}

Collections use a common mechanism to create and remove entities. Entities use a common mechanism to retrieve and update property values, and access entity metadata. Once you're familiar with this pattern, you'll have a reasonable understanding of how the SDK and underlying REST API work.

The SDK contains the base classes Entity and EntityCollection, both of which derive from the common base class Resource. Note that Service is not a Resource, but is a container that provides access to all features associated with a Splunk instance.

The class hierarchy for the core SDK library is as follows:

Service
Resource
    Entity
    ResourceCollection
        EntityCollection
 

Managing state between the client and server

When you create an object for an entity, the entity's properties are read and copied from the server, creating a local snapshot of those values. Any set operations on the object are only made to the local object. Your changes are not made on the server until you explictly call the object's Update method, which uploads all the changes you've made to that object. And, changes made on the server don't affect your local copy unless you call the object's Refresh method, which replaces any changes you have made with an updated snapshot from the server.

The SDK does not perform validation on values when you set them, but rather passes these values to the server for validation. Any error messages from the server are then sent back to you through the SDK.

There are two ways to set values for an entity:

  • Use the properties that are available for the entity, then call Update to upload all the changes you've made to this entity. For example:
    EventTypeCollection eventTypeCollection = service.GetEventTypes();
    EventType eventType = eventTypeCollection.Create("test", "index=_internal *");
    eventType.Description = "This is a test";
    eventType.Priority = 3;
    eventType.Update();
  • Create a dictionary of arguments, and then supply all of the specified arguments for this entity by calling the Create method to create the entity. For example:
    var eventTypeCollection = service.GetEventTypes();
    
    var args = new Args {
        { "description", "This is a test" }, 
        { "priority", 3 }, 
    };
    
    var eventType = eventTypeCollection.Create("test", "index=_internal *", args);

    A call to Update(args) also includes any changes you made to properties. For example:

    var eventTypeCollection = service.GetEventTypes();
    var eventType = eventTypeCollection.Create("test", "index=_internal *");
    var args = new Args();
    
    eventType.Priority = 3;
    eventType.Description = "This is a test";
    eventType.Update(args); // Updates both the description and priority
    

Argument dictionaries require a little more work because you must know which arguments are allowed for that entity, carefully specifying the case-sensitive argument name with a value in the expected format. However, using an argument dictionary also lets you set values for any argument that is allowed for a given entity—even if there isn't a corresponding property method for it. In addition, you must use an argument dictionary if you want to initialize an object with values, because object properties aren't available until after an object has been created.