Go_Splunk_HTTP

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 29, 2022 License: MIT Imports: 14 Imported by: 0

README

Go-Splunk-HTTP

A simple and lightweight HTTP Splunk logging package for Go. Instantiates a logging connection object to your Splunk server and allows you to submit log events as desired. Uses HTTP event collection on a Splunk server.

GoDoc Build Status Coverage Status Go Report Card

Table of Contents

Installation

go get "github.com/cynalytica/go-splunk"

Usage

Construct a new Splunk HTTP client, then send log events as desired.

For example:

package main

import "github.com/cynalytica/go-splunk"

func main() {

	// Create new Splunk client
	splunk := splunk.NewClient(
		nil,
		"https://{your-splunk-URL}:8088/services/collector",
		"{your-token}",
		"{your-source}",
		"{your-sourcetype}",
		"{your-index}"
	)
		
	// Use the client to send a log with the go host's current time
	err := splunk.Log(
		interface{"msg": "send key/val pairs or json objects here", "msg2": "anything that is useful to you in the log event"}
	)
	if err != nil {
        	return err
        }
	
	// Use the client to send a log with a provided timestamp
	err = splunk.LogWithTime(
		time.Now(),
		interface{"msg": "send key/val pairs or json objects here", "msg2": "anything that is useful to you in the log event"}
	)
	if err != nil {
		return err
	}
	
	// Use the client to send a batch of log events
	var events []splunk.Event
	events = append(
		events,
		splunk.NewEvent(
			interface{"msg": "event1"},
			"{desired-source}",
			"{desired-sourcetype}",
			"{desired-index}"
		)
	)
	events = append(
		events,
		splunk.NewEvent(
			interface{"msg": "event2"},
			"{desired-source}",
			"{desired-sourcetype}",
			"{desired-index}"
		)
	)
	err = splunk.LogEvents(events)
	if err != nil {
		return err
	}
}

Splunk Writer

To support logging libraries, and other output, we've added an asynchronous Writer. It supports retries, and different intervals for flushing messages & max log messages in its buffer

The easiest way to get access to the writer with an existing client is to do:

writer := splunkClient.Writer()

This will give you an io.Writer you can use to direct output to splunk. However, since the io.Writer() is asynchronous, it will never return an error from its Write() function. To access errors generated from the Client, Instantiate your Writer this way:

splunk.Writer{
  Client: splunkClient
}

Since the type will now be splunk.Writer(), you can access the Errors() function, which returns a channel of errors. You can then spin up a goroutine to listen on this channel and report errors, or you can handle however you like.

Optionally, you can add more configuration to the writer.

splunk.Writer {
  Client: splunkClient,
  FlushInterval: 10 *time.Second, // How often we'll flush our buffer
  FlushThreshold: 25, // Max messages we'll keep in our buffer, regardless of FlushInterval
  MaxRetries: 2, // Number of times we'll retry a failed send
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	HTTPClient    *http.Client // HTTP client used to communicate with the API
	URL           string
	Hostname      string
	Token         string
	UseIndexerAck bool   //Used for Channel Auth
	Source        string //Default source
	SourceType    string //Default source type
	Index         string //Default index
}

Client manages communication with Splunk's HTTP Event Collector. New client objects should be created using the NewClient function.

The URL field must be defined and pointed at a Splunk servers Event Collector port (i.e. https://{your-splunk-URL}:8088/services/collector). The Token field must be defined with your access token to the Event Collector.

func NewClient

func NewClient(httpClient *http.Client, URL string, Token string, Source string, SourceType string, Index string, useAck bool) *Client

NewClient creates a new client to Splunk. This should be the primary way a Splunk client object is constructed.

If an httpClient object is specified it will be used instead of the default http.DefaultClient.

func (*Client) Log

func (c *Client) Log(event interface{}) error

Client.Log is used to construct a new log event and POST it to the Splunk server.

All that must be provided for a log event are the desired map[string]string key/val pairs. These can be anything that provide context or information for the situation you are trying to log (i.e. err messages, status codes, etc). The function auto-generates the event timestamp and hostname for you.

func (*Client) LogEvent

func (c *Client) LogEvent(e *Event) error

Client.LogEvent is used to POST a single event to the Splunk server.

func (*Client) LogEvents

func (c *Client) LogEvents(events []*Event) error

Client.LogEvents is used to POST multiple events with a single request to the Splunk server.

func (*Client) LogWithTime

func (c *Client) LogWithTime(t time.Time, event interface{}) error

Client.LogWithTime is used to construct a new log event with a specified timestamp and POST it to the Splunk server.

This is similar to Client.Log, just with the t parameter.

func (*Client) NewEvent

func (c *Client) NewEvent(event interface{}, source string, sourcetype string, index string) *Event

NewEvent creates a new log event to send to Splunk. This should be the primary way a Splunk log object is constructed, and is automatically called by the Log function attached to the client. This method takes the current timestamp for the event, meaning that the event is generated at runtime.

func (*Client) NewEventWithTime

func (c *Client) NewEventWithTime(t time.Time, event interface{}, source string, sourcetype string, index string) *Event

NewEventWithTime creates a new log event with a specified timetamp to send to Splunk. This is similar to NewEvent but if you want to log in a different time rather than time.Now this becomes handy. If that's the case, use this function to create the Event object and the the LogEvent function.

func (*Client) Writer

func (c *Client) Writer() io.Writer

Writer is a convience method for creating an io.Writer from a Writer with default values

type Event

type Event struct {
	Time       EventTime   `json:"time"`                 // when the event happened
	Host       string      `json:"host"`                 // hostname
	Source     string      `json:"source,omitempty"`     // optional description of the source of the event; typically the app's name
	SourceType string      `json:"sourcetype,omitempty"` // optional name of a Splunk parsing configuration; this is usually inferred by Splunk
	Index      string      `json:"index,omitempty"`      // optional name of the Splunk index to store the event in; not required if the token has a default index set in Splunk
	Event      interface{} `json:"event"`                // throw any useful key/val pairs here
}

Event represents the log event object that is sent to Splunk when Client.Log is called.

type EventCollectorResponse

type EventCollectorResponse struct {
	Text               string     `json:"text"`
	Code               StatusCode `json:"code"`
	InvalidEventNumber *int       `json:"invalid-event-number"`
	AckID              *int       `json:"ackId"`
}

EventCollectorResponse is the payload returned by the HTTP Event Collector in response to requests. https://docs.splunk.com/Documentation/Splunk/latest/RESTREF/RESTinput#services.2Fcollector

func (*EventCollectorResponse) Error

func (r *EventCollectorResponse) Error() string

Error implements the error interface.

type EventTime

type EventTime struct {
	time.Time
}

EventTime marshals timestamps using the Splunk HTTP Event Collector's default format.

func (EventTime) MarshalJSON

func (t EventTime) MarshalJSON() ([]byte, error)

type StatusCode

type StatusCode int8

StatusCode defines the meaning of responses returned by HTTP Event Collector endpoints.

const (
	Success StatusCode = iota
	TokenDisabled
	TokenRequired
	InvalidAuthz
	InvalidToken
	NoData
	InvalidDataFormat
	IncorrectIndex
	InternalServerError
	ServerBusy
	DataChannelMissing
	InvalidDataChannel
	EventFieldRequired
	EventFieldBlank
	ACKDisabled
	ErrorHandlingIndexedFields
	QueryStringAuthzNotEnabled
)

func (StatusCode) HTTPCode

func (c StatusCode) HTTPCode() (code int, err error)

HTTPCode returns the HTTP code corresponding to the given StatusCode. It returns -1 and an error in case the HTTP status code can not be determined.

type Writer

type Writer struct {
	Client *Client
	// How often the write buffer should be flushed to splunk
	FlushInterval time.Duration
	// How many Write()'s before buffer should be flushed to splunk
	FlushThreshold int
	// Max number of retries we should do when we flush the buffer
	MaxRetries int
	// contains filtered or unexported fields
}

Writer is a threadsafe, aysnchronous splunk writer. It implements io.Writer for usage in logging libraries, or whatever you want to send to splunk :) Writer.Client's configuration determines what source, sourcetype & index will be used for events Example for logrus:

splunkWriter := &splunk.Writer {Client: client}
logrus.SetOutput(io.MultiWriter(os.Stdout, splunkWriter))

func (*Writer) Errors

func (w *Writer) Errors() <-chan error

Errors returns a buffered channel of errors. Might be filled over time, might not Useful if you want to record any errors hit when sending data to splunk

func (*Writer) Write

func (w *Writer) Write(b []byte) (int, error)

Writer asynchronously writes to splunk in batches

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL