simplejson

package module
v0.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 18, 2022 License: MIT Imports: 13 Imported by: 0

README

simplejson

GitHub tag (latest by date) Codecov Test Go Report Card GitHub

Basic Go implementation of a Grafana Simple JSON API server

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: []simplejson.Handler{myHandler},
}
err := s.Run(8080)

This starts a server, listening on port 8080, with one handler (myHandler).

Handler

A handler groups a set of targets and supports timeseries queries, table queues and/or annotation, possibly with tags. The Handler interface includes one function (Endpoints). This function returns the Grafana SimpleJSON endpoints that the handler supports. Those can be:

  • Search() implements the /search endpoint: it returns the list of supported targets
  • 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

Of these, Search() is mandatory. You will typically want to implement either Query or TableQuery.

Here's an example of a handler that supports timeseries queries:

type myHandler struct {
}

func (handler myHandler) Endpoints() simplejson.Endpoints {
	return simplejson.Endpoints{
		Search: handler.Search,
		Query:  handler.Query
	}
}

func (handler myHandler) Search() []string {
	return []string{"myTarget"}
}

func (handler *myHandler) Query(ctx context.Context, target string, target *simplejson.TimeSeriesQueryArgs) (response *simplejson.QueryResponse, err error) {
	// build response
	return
}

Timeseries Queries

Timeseries queries returns 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 & 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
}

Other topics

For information on query arguments, annotation and tags, refer to the documentation for those data structures.

Index

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 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 AnnotationsFunc

type AnnotationsFunc func(name, query string, args *RequestArgs) ([]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

type DataPoint struct {
	Timestamp time.Time
	Value     int64
}

DataPoint contains one entry returned by a Query.

func (*DataPoint) MarshalJSON

func (d *DataPoint) MarshalJSON() ([]byte, error)

MarshalJSON converts a DataPoint to JSON.

func (*DataPoint) UnmarshalJSON

func (d *DataPoint) UnmarshalJSON(input []byte) (err error)

UnmarshalJSON converts a JSON structure to a DataPoint.

type Endpoints

type Endpoints struct {
	Search      func() []string     // /search endpoint: it returns the list of supported targets
	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 Range

type Range struct {
	From time.Time `json:"from"`
	To   time.Time `json:"to"`
}

Range specified a start and end time for the data to be returned.

type Request

type Request struct {
	RequestArgs
	Annotation RequestDetails `json:"annotation"`
}

Request is a request for annotation.

type RequestArgs

type RequestArgs struct {
	Args
}

RequestArgs contains arguments for the Annotations endpoint.

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 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 []Handler
	// contains filtered or unexported fields
}

Server receives SimpleJSON requests from Grafana and dispatches them to the handler that serves the specified target. If multiple handlers serve the same target name, the first handler in the list will receive the request.

func (*Server) GetRouter

func (server *Server) GetRouter() (r *mux.Router)

GetRouter sets up an HTTP router. Useful if you want to hook other handlers to the HTTP Server.

func (*Server) Run

func (server *Server) Run(port int) error

Run starts the SimpleJSon Server.

func (*Server) Shutdown

func (server *Server) Shutdown(ctx context.Context, timeout time.Duration) error

Shutdown stops a running Server.

type TableQueryArgs

type TableQueryArgs struct {
	Args
}

TableQueryArgs contains the arguments for a TableQuery.

type TableQueryFunc

type TableQueryFunc func(ctx context.Context, target string, 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

type TableQueryResponseTimeColumn []time.Time

TableQueryResponseTimeColumn holds a slice of time.Time values (one per row).

type TagKeysFunc

type TagKeysFunc func(ctx context.Context) []string

TagKeysFunc returns supported tag names

type TagValuesFunc

type TagValuesFunc func(ctx context.Context, key string) ([]string, error)

TagValuesFunc returns supported values for the specified tag name

type TargetTable

type TargetTable map[string]struct {
	QueryFunc      TimeSeriesQueryFunc
	TableQueryFunc TableQueryFunc
}

TargetTable maps a target to a set of timeseries and table queries. This can be useful if a Handler supports multiple targets, and each target requires its own timeseries and/or table query function.

func (TargetTable) RunQuery

func (tt TargetTable) RunQuery(ctx context.Context, target string, args *TimeSeriesQueryArgs) (response *TimeSeriesResponse, err error)

RunQuery runs a timeseries query against a TargetTable. It looks up the target in the TargetTable and runs that timeseries query. If the target doesn't exist, or doesn't have a timeseries query, it returns an error.

func (TargetTable) RunTableQuery

func (tt TargetTable) RunTableQuery(ctx context.Context, target string, args *TableQueryArgs) (response *TableQueryResponse, err error)

RunTableQuery runs a table query against a TargetTable. It looks up the target in the TargetTable and runs that table query. If the target doesn't exist, or doesn't have a table query, it returns an error.

func (TargetTable) Targets

func (tt TargetTable) Targets() (targets []string)

Targets returns the targets mapped in this TargetTable.

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, target string, args *TimeSeriesQueryArgs) (*TimeSeriesResponse, error)

TimeSeriesQueryFunc handles timeseries queries

type TimeSeriesRequest

type TimeSeriesRequest struct {
	Targets []RequestTarget `json:"targets"`
	TimeSeriesQueryArgs
}

TimeSeriesRequest is a Query request. For each specified RequestTarget, the server will call the Query endpoint with the provided TimeSeriesQueryArgs.

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.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL