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) }
Output:
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.