Documentation
¶
Overview ¶
Package simplejson provides a Go implementation for Grafana's SimpleJSON datasource: https://grafana.com/grafana/plugins/grafana-simple-json-datasource
Overview ¶
A simplejson server is an HTTP server that supports one or more handlers. Each handler can support multiple targets, each of which can be supported by a timeseries or table query. Optionally tags can be used to alter the behaviour of the query (e.g. filtering what data should be returned). Finally, a handler can support annotation, i.e. a set of timestamps with associated text.
Server ¶
To create a SimpleJSON server, create a Server and run it:
s := simplejson.Server{
Handlers: map[string]simplejson.Handler{
"my-target": myHandler,
},
}
err := s.Run(8080)
This starts a server, listening on port 8080, with one target "my-target", served by myHandler.
Handler ¶
A handler serves incoming requests from Grafana, e.g. queries, requests for annotations or tags. The Handler interface contains all functions a handler needs to implement. It contains only one function (Endpoints). This function returns the Grafana SimpleJSON endpoints that the handler supports. Those can be:
- Query() implements the /query endpoint for timeseries targets
- TableQuery() implements the /query endpoint for table targets
- Annotations() implements the /annotation endpoint
- TagKeys() implements the /tag-keys endpoint
- TagValues() implements the /tag-values endpoint
Here's an example of a handler that supports timeseries queries:
type myHandler struct {
}
func (handler myHandler) Endpoints() simplejson.Endpoints {
return simplejson.Endpoints{
Query: handler.Query
}
}
func (handler *myHandler) Query(ctx context.Context, target string, target *simplejson.TimeSeriesQueryArgs) (response *simplejson.QueryResponse, err error) {
// build response
return
}
Timeseries Queries ¶
Timeseries queries return values as a list of timestamp/value tuples. Here's an example of a timeseries query handler:
func (handler *myHandler) Query(_ context.Context, _ string, _ *simplejson.TimeSeriesQueryArgs) (response *simplejson.QueryResponse, err error) {
response = &simplejson.QueryResponse{
Target: "A",
DataPoints: []simplejson.QueryResponseDataPoint{
{Timestamp: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC), Value: 100},
{Timestamp: time.Date(2020, 1, 1, 0, 1, 0, 0, time.UTC), Value: 101},
{Timestamp: time.Date(2020, 1, 1, 0, 2, 0, 0, time.UTC), Value: 103},
},
}
return
}
Table Queries ¶
Table Queries, on the other hand, return data organized in columns and rows. Each column needs to have the same number of rows:
func (handler *myHandler) TableQuery(_ context.Context, _ string, _ *simplejson.TableQueryArgs) (response *simplejson.QueryResponse, err error) {
response = &simplejson.TableQueryResponse{
Columns: []simplejson.TableQueryResponseColumn{
{ Text: "Time", Data: simplejson.TableQueryResponseTimeColumn{time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC), time.Date(2020, 1, 1, 0, 1, 0, 0, time.UTC)} },
{ Text: "Label", Data: simplejson.TableQueryResponseStringColumn{"foo", "bar"}},
{ Text: "Series A", Data: simplejson.TableQueryResponseNumberColumn{42, 43}},
{ Text: "Series B", Data: simplejson.TableQueryResponseNumberColumn{64.5, 100.0}},
},
}
return
}
Metrics ¶
simplejson exports two Prometheus metrics for performance analytics:
simplejson_query_duration_seconds: duration of query requests by target, in seconds simplejson_query_failed_count: number of failed query requests
Other topics ¶
For information on query arguments, annotation and tags, refer to the documentation for those data structures.
Example ¶
package main
import (
"context"
"github.com/clambin/simplejson"
"time"
)
type handler struct{}
func (h handler) Endpoints() simplejson.Endpoints {
return simplejson.Endpoints{
Query: h.Query,
TableQuery: h.TableQuery,
}
}
func (h *handler) Query(_ context.Context, _ *simplejson.TimeSeriesQueryArgs) (response *simplejson.TimeSeriesResponse, err error) {
response = &simplejson.TimeSeriesResponse{
DataPoints: make([]simplejson.DataPoint, 60),
}
timestamp := time.Now().Add(-1 * time.Hour)
for i := 0; i < 60; i++ {
response.DataPoints[i] = simplejson.DataPoint{
Timestamp: timestamp,
Value: int64(i),
}
timestamp = timestamp.Add(1 * time.Minute)
}
return
}
func (h *handler) TableQuery(_ context.Context, _ *simplejson.TableQueryArgs) (response *simplejson.TableQueryResponse, err error) {
timestamps := make(simplejson.TableQueryResponseTimeColumn, 60)
seriesA := make(simplejson.TableQueryResponseNumberColumn, 60)
seriesB := make(simplejson.TableQueryResponseNumberColumn, 60)
timestamp := time.Now().Add(-1 * time.Hour)
for i := 0; i < 60; i++ {
timestamps[i] = timestamp
seriesA[i] = float64(i)
seriesB[i] = float64(-i)
timestamp = timestamp.Add(1 * time.Minute)
}
response = &simplejson.TableQueryResponse{
Columns: []simplejson.TableQueryResponseColumn{
{Text: "timestamp", Data: timestamps},
{Text: "series A", Data: seriesA},
{Text: "series B", Data: seriesB},
},
}
return
}
func main() {
s := simplejson.Server{
Handlers: map[string]simplejson.Handler{
"A": &handler{},
},
}
_ = s.Run(8088)
}
Index ¶
- type AdHocFilter
- type Annotation
- type AnnotationRequest
- type AnnotationRequestArgs
- type AnnotationRequestDetails
- type AnnotationsFunc
- type Args
- type DataPoint
- type Endpoints
- type Handler
- type QueryRequest
- type Range
- type RequestTarget
- type Server
- type TableQueryArgs
- type TableQueryFunc
- type TableQueryResponse
- type TableQueryResponseColumn
- type TableQueryResponseNumberColumn
- type TableQueryResponseStringColumn
- type TableQueryResponseTimeColumn
- type TagKeysFunc
- type TagValuesFunc
- type TimeSeriesQueryArgs
- type TimeSeriesQueryFunc
- type TimeSeriesResponse
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AdHocFilter ¶
type AdHocFilter struct {
Value string `json:"value"`
Operator string `json:"operator"`
Condition string `json:"condition"`
Key string `json:"key"`
}
AdHocFilter specifies the ad hoc filters, whose keys & values are returned by the /tag-key and /tag-values endpoints.
type Annotation ¶
type Annotation struct {
Time time.Time
Title string
Text string
Tags []string
Request AnnotationRequestDetails
}
Annotation response. The annotation endpoint returns a slice of these.
func (*Annotation) MarshalJSON ¶
func (annotation *Annotation) MarshalJSON() (output []byte, err error)
MarshalJSON converts an Annotation to JSON.
type AnnotationRequest ¶ added in v0.10.0
type AnnotationRequest struct {
AnnotationRequestArgs
Annotation AnnotationRequestDetails `json:"annotation"`
}
AnnotationRequest is a request for annotation.
type AnnotationRequestArgs ¶ added in v0.10.0
type AnnotationRequestArgs struct {
Args
}
AnnotationRequestArgs contains arguments for the Annotations endpoint.
type AnnotationRequestDetails ¶ added in v0.10.0
type AnnotationRequestDetails struct {
Name string `json:"name"`
Datasource string `json:"datasource"`
Enable bool `json:"enable"`
Query string `json:"query"`
}
AnnotationRequestDetails specifies which annotation should be returned.
type AnnotationsFunc ¶
type AnnotationsFunc func(name, query string, args *AnnotationRequestArgs) ([]Annotation, error)
AnnotationsFunc handles requests for annotation
type Args ¶
type Args struct {
Range Range `json:"range"`
AdHocFilters []AdHocFilter
}
Args contains common arguments used by endpoints.
type DataPoint ¶
DataPoint contains one entry returned by a Query.
func (*DataPoint) MarshalJSON ¶
MarshalJSON converts a DataPoint to JSON.
func (*DataPoint) UnmarshalJSON ¶
UnmarshalJSON converts a JSON structure to a DataPoint.
type Endpoints ¶
type Endpoints struct {
Query TimeSeriesQueryFunc // /query endpoint: handles timeSeries queries
TableQuery TableQueryFunc // /query endpoint: handles table queries
Annotations AnnotationsFunc // /annotation endpoint: handles requests for annotation
TagKeys TagKeysFunc // /tag-keys endpoint: returns all supported tag names
TagValues TagValuesFunc // /tag-values endpoint: returns all supported values for the specified tag name
}
Endpoints contains the functions that implement each of the SimpleJson endpoints
type Handler ¶
type Handler interface {
Endpoints() Endpoints
}
Handler implements the different Grafana SimpleJSON endpoints. The interface only contains a single Endpoints() function, so that a handler only has to implement the endpoint functions (query, tablequery, annotation, etc.) that it needs.
type QueryRequest ¶ added in v0.10.0
type QueryRequest struct {
Targets []RequestTarget `json:"targets"`
TimeSeriesQueryArgs
}
QueryRequest is a Query request. For each specified RequestTarget, the server will call the Query endpoint with the provided TimeSeriesQueryArgs.
type RequestTarget ¶
type RequestTarget struct {
Target string `json:"target"` // name of the target.
Type string `json:"type"` // "timeserie" or "" for timeseries. "table" for table queries.
}
RequestTarget specifies the requested target name and type.
type Server ¶
type Server struct {
Name string
Handlers map[string]Handler
// contains filtered or unexported fields
}
Server receives SimpleJSON requests from Grafana and dispatches them to the handler that serves the specified target.
func (*Server) GetRouter ¶
GetRouter sets up an HTTP router. Useful if you want to hook other handlers to the HTTP Server.
type TableQueryArgs ¶
type TableQueryArgs struct {
Args
}
TableQueryArgs contains the arguments for a TableQuery.
type TableQueryFunc ¶
type TableQueryFunc func(ctx context.Context, args *TableQueryArgs) (*TableQueryResponse, error)
TableQueryFunc handles for table queries
type TableQueryResponse ¶
type TableQueryResponse struct {
Columns []TableQueryResponseColumn
}
TableQueryResponse is returned by a TableQuery, i.e. a slice of TableQueryResponseColumn structures.
func (*TableQueryResponse) MarshalJSON ¶
func (table *TableQueryResponse) MarshalJSON() (output []byte, err error)
MarshalJSON converts a TableQueryResponse to JSON.
type TableQueryResponseColumn ¶
type TableQueryResponseColumn struct {
Text string
Data interface{}
}
TableQueryResponseColumn is a column returned by a TableQuery. Text holds the column's header, Data holds the slice of values and should be a TableQueryResponseTimeColumn, a TableQueryResponseStringColumn or a TableQueryResponseNumberColumn.
type TableQueryResponseNumberColumn ¶
type TableQueryResponseNumberColumn []float64
TableQueryResponseNumberColumn holds a slice of number values (one per row).
type TableQueryResponseStringColumn ¶
type TableQueryResponseStringColumn []string
TableQueryResponseStringColumn holds a slice of string values (one per row).
type TableQueryResponseTimeColumn ¶
TableQueryResponseTimeColumn holds a slice of time.Time values (one per row).
type TagKeysFunc ¶
TagKeysFunc returns supported tag names
type TagValuesFunc ¶
TagValuesFunc returns supported values for the specified tag name
type TimeSeriesQueryArgs ¶
type TimeSeriesQueryArgs struct {
Args
// Interval QueryRequestDuration `json:"interval"`
MaxDataPoints uint64 `json:"maxDataPoints"`
}
TimeSeriesQueryArgs contains the arguments for a Query.
type TimeSeriesQueryFunc ¶
type TimeSeriesQueryFunc func(ctx context.Context, args *TimeSeriesQueryArgs) (*TimeSeriesResponse, error)
TimeSeriesQueryFunc handles timeseries queries
type TimeSeriesResponse ¶
type TimeSeriesResponse struct {
Target string `json:"target"` // name of the target
DataPoints []DataPoint `json:"datapoints"` // values for the target
}
TimeSeriesResponse is returned by a Query.