diff --git a/CHANGELOG.md b/CHANGELOG.md index 86d8a0ed46c..df617ee0609 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ or `/query` HTTP endpoints. 1. [20861](https://github.com/influxdata/influxdb/pull/20861): Update Telegraf plugins in UI to include additions and changes in 1.18 release. 1. [20894](https://github.com/influxdata/influxdb/pull/20894): Display task IDs in the UI. 1. [21046](https://github.com/influxdata/influxdb/pull/21046): Write to standard out when `--output-path -` is passed to `influxd inspect export-lp`. +1. [21006](https://github.com/influxdata/influxdb/pull/21006): Add `-p, --profilers` flag to `influx query` command. ### Bug Fixes diff --git a/cmd/influx/query.go b/cmd/influx/query.go index 5a25e383041..44ee72791ce 100644 --- a/cmd/influx/query.go +++ b/cmd/influx/query.go @@ -21,9 +21,10 @@ import ( ) var queryFlags struct { - org organization - file string - raw bool + org organization + file string + raw bool + profilers []string } func cmdQuery(f *globalFlags, opts genericCLIOpts) *cobra.Command { @@ -36,6 +37,7 @@ func cmdQuery(f *globalFlags, opts genericCLIOpts) *cobra.Command { queryFlags.org.register(opts.viper, cmd, true) cmd.Flags().StringVarP(&queryFlags.file, "file", "f", "", "Path to Flux query file") cmd.Flags().BoolVarP(&queryFlags.raw, "raw", "r", false, "Display raw query results") + cmd.Flags().StringSliceVarP(&queryFlags.profilers, "profilers", "p", nil, "Names of Flux profilers to enable. Profiler information will be appended to query results") return cmd } @@ -101,7 +103,7 @@ func fluxQueryF(cmd *cobra.Command, args []string) error { } u.RawQuery = params.Encode() - body, _ := json.Marshal(map[string]interface{}{ + var body_map = map[string]interface{}{ "query": q, "type": "flux", "dialect": map[string]interface{}{ @@ -109,7 +111,13 @@ func fluxQueryF(cmd *cobra.Command, args []string) error { "delimiter": ",", "header": true, }, - }) + } + + if len(queryFlags.profilers) > 0 { + body_map["extern"] = buildProfilersExtern(queryFlags.profilers) + } + + body, _ := json.Marshal(body_map) req, _ := http.NewRequest("POST", u.String(), bytes.NewReader(body)) req.Header.Set("Authorization", "Token "+flags.config().Token) @@ -155,6 +163,56 @@ func fluxQueryF(cmd *cobra.Command, args []string) error { return results.Err() } +// buildProfilersExtern constructs the AST representation of a Flux statement enabling +// the specified profilers in the query options. +// +// See the docs for more info: https://docs.influxdata.com/influxdb/cloud/reference/flux/stdlib/profiler/ +func buildProfilersExtern(profilersToEnable []string) (profilersExtern map[string]interface{}) { + elements := make([]interface{}, len(profilersToEnable)) + for i, profiler := range profilersToEnable { + elements[i] = map[string]interface{}{ + "type": "StringLiteral", + "value": profiler, + } + } + profilersExtern = map[string]interface{}{ + "type": "File", + "imports": []interface{}{ + map[string]interface{}{ + "type": "ImportDeclaration", + "path": map[string]interface{}{ + "type": "StringLiteral", + "value": "profiler", + }, + }, + }, + "body": []interface{}{ + map[string]interface{}{ + "assignment": map[string]interface{}{ + "member": map[string]interface{}{ + "object": map[string]interface{}{ + "name": "profiler", + "type": "Identifier", + }, + "property": map[string]interface{}{ + "name": "enabledProfilers", + "type": "Identifier", + }, + "type": "MemberExpression", + }, + "init": map[string]interface{}{ + "type": "ArrayExpression", + "elements": elements, + }, + "type": "MemberAssignment", + }, + "type": "OptionStatement", + }, + }, + } + return profilersExtern +} + // Below is a copy and trimmed version of the execute/format.go file from flux. // It is copied here to avoid requiring a dependency on the execute package which // may pull in the flux runtime as a dependency.