Add epoch to influx query

pull/10616/head
Chris Goller 2018-01-11 23:05:23 -06:00
parent 8073d3f090
commit 1629f6c56b
5 changed files with 81 additions and 4 deletions

View File

@ -166,6 +166,7 @@ type Query struct {
Command string `json:"query"` // Command is the query itself
DB string `json:"db,omitempty"` // DB is optional and if empty will not be used.
RP string `json:"rp,omitempty"` // RP is a retention policy and optional; if empty will not be used.
Epoch string `json:"epoch,omitempty"` // Epoch is the time format for the return results
TemplateVars []TemplateVar `json:"tempVars,omitempty"` // TemplateVars are template variables to replace within an InfluxQL query
Wheres []string `json:"wheres,omitempty"` // Wheres restricts the query to certain attributes
GroupBys []string `json:"groupbys,omitempty"` // GroupBys collate the query by these tags

View File

@ -137,7 +137,8 @@ func (r *annotationResults) Annotations() (res []chronograf.Annotation, err erro
func (c *Client) queryAnnotations(ctx context.Context, query string) ([]chronograf.Annotation, error) {
res, err := c.Query(ctx, chronograf.Query{
Command: query,
DB: `chronograf`,
DB: DefaultDB,
Epoch: "ns",
})
if err != nil {
return nil, err

View File

@ -74,7 +74,10 @@ func (c *Client) query(u *url.URL, q chronograf.Query) (chronograf.Response, err
params.Set("q", command)
params.Set("db", q.DB)
params.Set("rp", q.RP)
params.Set("epoch", "ms") // TODO(timraymond): set this based on analysis
params.Set("epoch", "ms")
if q.Epoch != "" {
params.Set("epoch", q.Epoch)
}
req.URL.RawQuery = params.Encode()
if c.Authorizer != nil {

66
influx/lineprotocol.go Normal file
View File

@ -0,0 +1,66 @@
package influx
import (
"fmt"
"sort"
"strings"
"github.com/influxdata/chronograf"
)
var (
escapeMeasurement = strings.NewReplacer(
`,` /* to */, `\,`,
` ` /* to */, `\ `,
)
escapeKeys = strings.NewReplacer(
`,` /* to */, `\,`,
`"` /* to */, `\"`,
` ` /* to */, `\ `,
`=` /* to */, `\=`,
)
escapeTagValues = strings.NewReplacer(
`,` /* to */, `\,`,
`"` /* to */, `\"`,
` ` /* to */, `\ `,
`=` /* to */, `\=`,
)
escapeFieldStrings = strings.NewReplacer(
`"` /* to */, `\"`,
`\` /* to */, `\\`,
)
)
func toLineProtocol(point *chronograf.Point) string {
measurement := escapeMeasurement.Replace(point.Measurement)
tags := []string{}
for tag, value := range point.Tags {
t := fmt.Sprintf("%s=%s", escapeKeys.Replace(tag), escapeTagValues.Replace(value))
tags = append(tags, t)
}
// it is faster to insert data into influx db if the tags are sorted
sort.Strings(tags)
fields := []string{}
for field, value := range point.Fields {
var format string
switch v := value.(type) {
case int64, int32, int16, int8, int:
format = fmt.Sprintf("%s=%di", escapeKeys.Replace(field), v)
case uint64, uint32, uint16, uint8, uint:
format = fmt.Sprintf("%s=%du", escapeKeys.Replace(field), v)
case float64, float32:
format = fmt.Sprintf("%s=%f", escapeKeys.Replace(field), v)
case string:
format = fmt.Sprintf("%s=%s", escapeKeys.Replace(field), escapeFieldStrings.Replace(v))
case bool:
format = fmt.Sprintf("%s=%t", escapeKeys.Replace(field), v)
}
fields = append(fields, format)
}
return fmt.Sprintf("%s,%s %s %d\n",
measurement,
strings.Join(tags, ","),
strings.Join(fields, ","),
point.Time)
}

View File

@ -550,7 +550,8 @@
"patch": {
"tags": ["sources", "users"],
"summary": "Update user configuration",
"description": "Update one parameter at a time (one of password, permissions or roles)",
"description":
"Update one parameter at a time (one of password, permissions or roles)",
"parameters": [
{
"name": "id",
@ -3139,7 +3140,7 @@
"rp": "autogen",
"tempVars": [
{
"tempVar": "$myfield",
"tempVar": ":myfield:",
"values": [
{
"type": "fieldKey",
@ -3160,6 +3161,11 @@
"rp": {
"type": "string"
},
"epoch": {
"description": "timestamp return format",
"type": "string",
"enum": ["h", "m", "s", "ms", "u", "ns"]
},
"tempVars": {
"type": "array",
"description":