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 tag 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 tag. 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. handles both timeserie & table responses
- 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.QueryArgs) (response *simplejson.QueryResponse, err error) { // build response return }
Queries ¶
SimpleJSON supports two types of query responses: timeseries responses and table responses.
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, _ query.QueryArgs) (response *simplejson.TimeSeriesResponse, err error) { response = &query.TimeSeriesResponse{ Name: "A", DataPoints: []simplejson.DataPoint{ {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, 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, _ query.QueryArgs) (response *simplejson.TableResponse, err error) { response = &simplejson.TableResponse{ Columns: []simplejson.Column{ { Text: "Time", Data: query.TimeColumn{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: query.StringColumn{"foo", "bar"}}, { Text: "Series A", Data: query.NumberColumn{42, 43}}, { Text: "Series B", Data: query.NumberColumn{64.5, 100.0}}, }, } return }
Annotations ¶
The /annotations endpoint returns Annotations:
func (h *handler) Annotations(_ simplejson.QueryRequest) (annotations []simplejson.Annotation, err error) { annotations = []simplejson.Annotation{ { Time: time.Now().Add(-5 * time.Minute), Title: "foo", Text: "bar", Tags: []string{"A", "B"}, }, } return }
NOTE: this is only called when using the SimpleJSON datasource. simPod / GrafanaJsonDatasource does not use the /annotations endpoint. Instead, it will call a regular /query and allows to configure its response as annotations instead.
Tags ¶
The /tag-keys and /tag-values endpoints return supported keys and key values respectively for your data source. A Grafana dashboard can then be confirmed to show those keys and its possible values as a filter.
The following sets up a key & key value handler:
func (h *handler) TagKeys(_ context.Context) (keys []string) { return []string{"some-key"} } func (h *handler) TagValues(_ context.Context, key string) (values []string, err error) { if key != "some-key" { return nil, fmt.Errorf("invalid key: %s", key) } return []string{"A", "B", "C"}, nil }
When the dashboard performs a query with a tag selected, that tag & value will be added in the request's AdHocFilters.
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 and tags, refer to the documentation for those data structures.
Index ¶
- type AdHocFilter
- type Annotation
- type AnnotationRequest
- type AnnotationsFunc
- type Args
- type Column
- type DataPoint
- type Endpoints
- type Handler
- type NumberColumn
- type QueryArgs
- type QueryFunc
- type QueryMetrics
- type QueryRequest
- type Range
- type RequestDetails
- type Response
- type Server
- func (s *Server) Annotations(w http.ResponseWriter, req *http.Request)
- func (s *Server) Query(w http.ResponseWriter, req *http.Request)
- func (s *Server) Run() error
- func (s *Server) Search(w http.ResponseWriter, _ *http.Request)
- func (s *Server) Shutdown(timeout time.Duration) (err error)
- func (s *Server) TagKeys(w http.ResponseWriter, req *http.Request)
- func (s *Server) TagValues(w http.ResponseWriter, req *http.Request)
- func (s *Server) Targets() (targets []string)
- type StringColumn
- type TableResponse
- type TagKeysFunc
- type TagValuesFunc
- type Target
- type TimeColumn
- 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 TimeEnd time.Time Title string Text string Tags []string Request RequestDetails }
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 ¶
type AnnotationRequest struct { Annotation RequestDetails `json:"annotation"` Args }
AnnotationRequest is a query for annotation.
func (*AnnotationRequest) UnmarshalJSON ¶
func (r *AnnotationRequest) UnmarshalJSON(b []byte) (err error)
UnmarshalJSON unmarshalls a AnnotationRequest from JSON
type AnnotationsFunc ¶
type AnnotationsFunc func(req AnnotationRequest) ([]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 Column ¶
type Column struct { Text string Data interface{} }
Column is a column returned by a TableQuery. Text holds the column's header, Data holds the slice of values and should be a TimeColumn, a StringColumn or a NumberColumn.
func (Column) MarshalEasyJSON ¶
MarshalEasyJSON supports easyjson.Marshaler interface
func (Column) MarshalJSON ¶
MarshalJSON supports json.Marshaler interface
func (*Column) UnmarshalEasyJSON ¶
UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (*Column) UnmarshalJSON ¶
UnmarshalJSON supports json.Unmarshaler interface
type DataPoint ¶
DataPoint contains one entry returned by a Query.
func (DataPoint) MarshalJSON ¶
MarshalJSON converts a DataPoint to JSON.
type Endpoints ¶
type Endpoints struct { Query QueryFunc // /query endpoint: handles 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, annotation, etc.) that it needs.
type NumberColumn ¶
type NumberColumn []float64
NumberColumn holds a slice of number values (one per row).
type QueryFunc ¶
type QueryFunc func(ctx context.Context, req QueryRequest) (Response, error)
QueryFunc handles queries
type QueryMetrics ¶
type QueryMetrics struct { Duration *prometheus.HistogramVec Errors *prometheus.CounterVec }
func NewQueryMetrics ¶
func NewQueryMetrics(name string) QueryMetrics
func (QueryMetrics) Register ¶
func (qm QueryMetrics) Register(r prometheus.Registerer)
type QueryRequest ¶
QueryRequest is a Query request. For each specified Target, the server will call the appropriate handler's Query or TableQuery function with the provided QueryArgs.
func (*QueryRequest) UnmarshalJSON ¶
func (r *QueryRequest) UnmarshalJSON(b []byte) (err error)
UnmarshalJSON unmarshalls a QueryRequest from JSON
type RequestDetails ¶
type RequestDetails struct { Name string `json:"name"` Datasource string `json:"datasource"` Enable bool `json:"enable"` Query string `json:"query"` }
RequestDetails specifies which annotation should be returned.
type Server ¶
Server receives SimpleJSON requests from Grafana and dispatches them to the handler that serves the specified target.
func NewWithRegisterer ¶
func NewWithRegisterer(name string, handlers map[string]Handler, r prometheus.Registerer, options ...httpserver.Option) (s *Server, err error)
func (*Server) Annotations ¶
func (s *Server) Annotations(w http.ResponseWriter, req *http.Request)
type StringColumn ¶
type StringColumn []string
StringColumn holds a slice of string values (one per row).
type TableResponse ¶
type TableResponse struct {
Columns []Column
}
TableResponse is returned by a TableQuery, i.e. a slice of Column structures.
func (TableResponse) MarshalJSON ¶
func (t TableResponse) MarshalJSON() (output []byte, err error)
MarshalJSON converts a TableResponse to JSON.
type TagKeysFunc ¶
TagKeysFunc returns supported tag names
type TagValuesFunc ¶
TagValuesFunc returns supported values for the specified tag name
type Target ¶
type Target struct { Name string `json:"target"` // name of the target. Type string `json:"type"` // "timeserie" or "" for timeseries. "table" for table queries. }
Target specifies the requested target name and type.
type TimeColumn ¶
TimeColumn holds a slice of time.Time values (one per row).
type TimeSeriesResponse ¶
type TimeSeriesResponse struct { Target string `json:"target"` DataPoints []DataPoint `json:"datapoints"` }
TimeSeriesResponse is the response from a timeseries Query.
func (TimeSeriesResponse) MarshalEasyJSON ¶
func (v TimeSeriesResponse) MarshalEasyJSON(w *jwriter.Writer)
MarshalEasyJSON supports easyjson.Marshaler interface
func (TimeSeriesResponse) MarshalJSON ¶
func (v TimeSeriesResponse) MarshalJSON() ([]byte, error)
MarshalJSON supports json.Marshaler interface
func (*TimeSeriesResponse) UnmarshalEasyJSON ¶
func (v *TimeSeriesResponse) UnmarshalEasyJSON(l *jlexer.Lexer)
UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (*TimeSeriesResponse) UnmarshalJSON ¶
func (v *TimeSeriesResponse) UnmarshalJSON(data []byte) error
UnmarshalJSON supports json.Unmarshaler interface