Problem

How do you fetch metrics for a specific time period from SumoLogic programmatically in your go code using SumoLogic-Labs/sumologic-go-sdk?

Solution

If you are in a hurry, the code sits here. The SDK sits here.

1. Find the correct Sumo Logic API endpoint

If the Sumo Logic you are using is in us1 region, your Sumo Logic API endpoint is: https://api.sumologic.com/api
If it is not in us1 region your Sumo Logic API endpoint would be: https://api.<region-code>.sumologic.com/api
You need to find out the region code for your Sumo Logic end point. Check this on how to find it.

2. Create Access Key and Access Id to use in your client

Check this on how to create it.

3. Import sdk in your go code

1
2
3
4
import (
	"github.com/SumoLogic-Labs/sumologic-go-sdk/service/cip"
	"github.com/SumoLogic-Labs/sumologic-go-sdk/service/cip/types"
)

4. Initialize the client

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
	sumoEndPt := "https://api.sumologic.com/api" // I am in us1
	client := cip.APIClient{
		Cfg: &cip.Configuration{
			Authentication: cip.BasicAuth{
				AccessId:  strings.TrimSpace(os.Getenv("ACCESS_ID")),
				AccessKey: strings.TrimSpace(os.Getenv("ACCESS_KEY")),
			},
			BasePath:   sumoEndPt,
			HTTPClient: &http.Client{},
		},
	}

Export Access Key and Access Id as environment variables

1
2
export ACCESS_ID="<access-id-here>" ACCESS_KEY="<access-key-here>" 
go run main.go

5. Build the request

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
	query := "metric=container_memory_working_set_bytes container=fluentd pod=my-sumo-sumologic-fluentd-metrics-0"
	var from int64 = time.Now().Unix()

	// Sleep for some time
	// So that our `from` and `to` times
	// create a time range
	time.Sleep(time.Second * 30)
	
	var to int64 = time.Now().Unix()

	// Note: It takes some time until the metrics
	// start reflecting in the SumoLogic API results
	time.Sleep(time.Second * 30)

	req := types.MetricsQueryRequest{
		Queries: []types.MetricsQueryRow{
			types.MetricsQueryRow{
				Query:        query,
				RowId:        "A",
				// Sumo Logic doesn't support `quantize` operator
				// in the query when using API
				// You have to specify it explicitly like this:
				// Equivalent to: query | quantize to 30s using avg
				Quantization: time.Duration(time.Second * 30).Milliseconds(),
				Rollup:       "Avg",
			},
		},
		TimeRange: &types.ResolvableTimeRange{
			// BeginBoundedTimeRange: for <from-date> -> <to-date> type of time range
			// For other options, check https://api.sumologic.com/docs/#operation/runMetricsQueries
			Type_: "BeginBoundedTimeRange", 
			From: types.TimeRangeBoundary{
				// For other options, check https://api.sumologic.com/docs/#operation/runMetricsQueries
				Type:        "EpochTimeRangeBoundary",
				EpochMillis: from * 1000,
				RangeName:   "from",
			},
			To: types.TimeRangeBoundary{
				Type:        "EpochTimeRangeBoundary",
				EpochMillis: to * 1000,
				RangeName:   "to",
			},
		},

Most of the Metrics Operators are allowed in the query string except fillmissing, outlier, quantize and timeshift.

https://api.sumologic.com/docs/#operation/runMetricsQueries

6. Query the API endpoint for metrics

1
2
3
4
	mRes, hRes, err := client.RunMetricsQueries(req)
	if err != nil {
		panic(err) // you might want to use better error handling here
	}

6. Get the results

1
2
	fmt.Printf("Timestamp: %v\n", mRes.QueryResult[0].TimeSeriesList.TimeSeries[0].Points.Timestamps[0])
	fmt.Printf("Value: %v\n", mRes.QueryResult[0].TimeSeriesList.TimeSeries[0].Points.Values[0])

Result:

1
2
Timestamp: 1654756680000
Value: 1.691136e+08

Note

If you want to use quantize operator in your query, you will have to parse the query yourself and pass the correct value to the API. Check the code here for example.