I'm attempting to send a log event from a piece of Go code, but am receiving a connection refused error. If I use curl to send test data, I get an OK status back, but I don't see the data show up in my Splunk instance.
My request data looks like this (formatted pretty)
POST /services/collector HTTP/1.1
Host: input-prd-p-zd5ktsgk9g47.cloud.splunk.com:8088
Authorization: Splunk {token}
Content-Type: application/json
{"time":1450588381,"host":"Golang","source":"HTTPSplunkEvent","sourcetype":"Test","index":"tweet_harvest","event":"This is a test"}
My error comes back as:
--- FAIL: TestSendEvent (0.51s)
event_test.go:22: Error sending event: "Post https://input-prd-p-zd5ktsgk9g47.cloud.splunk.com:8088/services/collector: remote error: handshake failure"
My code looks like this:
import (
"bytes"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/http/httputil"
"strconv"
)
//Event is a struct that holds all data to be sent to a Splunk HTTP logging
//endpoint
type Event struct {
Time int64 `json:"time"`
Host string `json:"host"`
Source string `json:"source"`
Sourcetype string `json:"sourcetype"`
Index string `json:"index"`
Event interface{} `json:"event"`
}
//Send the event to the specified Splunk Server
func (e Event) Send(destination string, token string, disableCertValidation bool) error {
//Ensure we have all of the values for the event
if e.Time == 0 || e.Host == "" || e.Source == "" || e.Sourcetype == "" || e.Index == "" || e.Event == nil {
return errors.New("All fields in Event must have a value")
}
//Create a byte array with the data
b, err := json.Marshal(e)
//Create client and request
client := &http.Client{}
request, err := http.NewRequest("POST", destination, bytes.NewBuffer(b))
if err != nil {
return err
}
//If we are working with a trial account the certificate will be self signed so we want to ignore certificate verification
if disableCertValidation {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client.Transport = tr
}
header := http.Header{}
header.Add("Authorization", "Splunk "+token)
header.Set("Content-Type", "application/json")
request.Header = header
resp, err := client.Do(request)
if err != nil {
dump, _ := httputil.DumpRequest(request, true)
fmt.Printf("Dumping request: %s\n", dump)
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
dump, err := httputil.DumpResponse(resp, true)
fmt.Printf("RESPONSE: %q\n", dump)
return err
}
//Any code other than 200 is an
var splunkResponse Response
decoder := json.NewDecoder(resp.Body)
err = decoder.Decode(&splunkResponse)
if err != nil {
fmt.Printf("Error decoding resposne\n")
return err
}
if splunkResponse.Code != SplunkResponseOK {
fmt.Printf("Splunk Response code not OK\n")
return errors.New(strconv.Itoa(splunkResponse.Code) + ": " + splunkResponse.Text)
}
//Everything is fine return nil error
return nil
}
And my test code:
import (
"testing"
"time"
)
func TestSendEvent(t *testing.T) {
event := &Event{
Time: time.Now().Unix(),
Index: "tweet_harvest",
Source: "HTTPSplunkEvent",
Sourcetype: "Test",
Event: "This is a test",
Host: "Golang",
}
err := event.Send("https://input-prd-p-zd5ktsgk9g47.cloud.splunk.com:8088/services/collector",
"8CEB3C52-47B9-451E-81A9-4E45A299D41C", true)
if err != nil {
t.Fatalf("Error sending event: %#v\n", err.Error())
}
}
... View more