Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add variable query to be able to fetch Pixie variables. #46

Merged
merged 12 commits into from
Jun 10, 2022

Conversation

TarasPriadka
Copy link
Contributor

@TarasPriadka TarasPriadka commented Jun 8, 2022

Adding ability to query Pixie Grafana go backend to fetch and display Pixie clusters. This PR doesn't add the functionality to switch clusters for the whole dashboard, as in dashboard variables are not going to function yet. Dashboard cluster change will be introduced in the next PR.

Structural changes:

  • Restructured Go query schema. Now looks like:
{
  queryType: str
  queryBody? {
    pxlScript?: str
  }
}
  • New query structure allows switching on different types of requests that we may add in the future

Go backend:

  • Refactored code into query type processor and query processor. Query type processor switches on different types of queries. Query processor actually sends a proper request using Pixie API based on the query type.
  • Query processing module now supports queries to run the pxl script, or queries vizier clusters.
  • Added function to query vizier clusters to support Cluster dashboard variable.

Front-end:

  • Add functionality to Datasource which sends a query to plugin backend.
  • Add VariableQueryEditor which adds a dropdown menu to Variables page in the dashboard settings and allows to create a dashboard variable. For now there's only a single item to get clusters.
  • Update PixieDataQuery interface to reflect the schema changes.

Signed-off-by: Taras Priadka tpriadka@pixielabs.ai

Signed-off-by: Taras Priadka <tpriadka@pixielabs.ai>
Signed-off-by: Taras Priadka <tpriadka@pixielabs.ai>
Signed-off-by: Taras Priadka <tpriadka@pixielabs.ai>
@@ -99,7 +99,8 @@ func (td *PixieDatasource) QueryData(ctx context.Context, req *backend.QueryData

type queryModel struct {
// The PxL script passed in by the user.
PxlScript string `json:"pxlScript"`
PxlScript string `json:"pxlScript"`
ClusterFlag bool `json:bool`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably want json:"clusterFlag"

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should think about the design of this API a bit more - we can support autocomplete in the future for things like pod name, service name, node name, etc. This could be pretty powerful when adding filters to dashboard variables. Today, we wouldn't be able to do that without running a query across the entire cluster, but in theory we could do so. The Pixie API doesn't currently expose autocomplete, but maybe it could eventually (cc @aimichelle on that thought).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do already expose the autocomplete API via gRPC, since the CLI used it for the cmd-K.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, never mind! then, i think we should consider adding in support for autocompleting service name, pod name, node name, etc to the grafana plugin as well. along with cluster ID

Copy link
Contributor Author

@TarasPriadka TarasPriadka Jun 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should think about the design of this API a bit more - we can support autocomplete in the future for things like pod name, service name, node name, etc. This could be pretty powerful when adding filters to dashboard variables. Today, we wouldn't be able to do that without running a query across the entire cluster, but in theory we could do so. The Pixie API doesn't currently expose autocomplete, but maybe it could eventually (cc @aimichelle on that thought).

I am still working on the PR. Basically trying to get things to work bruteforce style since it is quite hard to do things which are slightly more different from their tutorials. I will refactor code a bit after everything works end-to-end to be more robust.

Not sure how to implement autocomplete yet, so I think it would be best to get some variable fetching to work first before doing anything with autocompletion.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we don't have to support autocomplete or pod/etc suggestions in this PR. Let's just make sure the API changes we are adding are scalable to those being added in the future, so that the API doesn't churn.

Signed-off-by: Taras Priadka <tpriadka@pixielabs.ai>
Signed-off-by: Taras Priadka <tpriadka@pixielabs.ai>
Signed-off-by: Taras Priadka <tpriadka@pixielabs.ai>
Signed-off-by: Taras Priadka <tpriadka@pixielabs.ai>
Signed-off-by: Taras Priadka <tpriadka@pixielabs.ai>
Signed-off-by: Taras Priadka <tpriadka@pixielabs.ai>
@TarasPriadka TarasPriadka marked this pull request as ready for review June 9, 2022 21:32
Signed-off-by: Taras Priadka <tpriadka@pixielabs.ai>
}

type queryModel struct {
// The PxL script passed in by the user.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is now incorrect right? This should probably be a comment above PxlScript in the queryBody struct.


type queryModel struct {
// The PxL script passed in by the user.
QueryType string `json:"queryType"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can make QueryType an enum just for some extra space efficiency (also prevents bugs from typos). See https://yourbasic.org/golang/iota/ Complete enum type with strings [best practice] section.


response.Frames = append(response.Frames, vizierFrame)

backend.Logger.Debug(fmt.Sprintf("number of viziers: $d", len(viziers)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rm these debug logs.

export class DataSource extends DataSourceWithBackend<PixieDataQuery, PixieDataSourceOptions> {
backendServ?: BackendSrv;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: slightly different spellings of BackendSrv and backendServ we should just go with backendSrv for the variable name as well.

Copy link
Member

@NickLanam NickLanam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks sensible overall from the frontend side, just a few nits

src/types.ts Outdated
@@ -22,11 +22,17 @@ import { scriptOptions } from 'pxl_scripts';
// PixieDataQuery is the interface representing a query in Pixie.
// Pixie queries use PxL, Pixie's query language.
export interface PixieDataQuery extends DataQuery {
pxlScript: string;
queryType: string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Likely, this should be a literal string type instead of a general one. Right now, the only value it can take is 'run-script'.

So if we do this instead, consumers can get type-checking to tell them if they make a typo or try to use a type of query that doesn't exist:

export type PixieDataQueryType = 'run-script' | 'foo' | 'bar';

export interface PixieDataQuery extends DataQuery {
  queryType: PixieDataQueryType;
  // ...
}

export const someQuery: Partial<PixieDataQuery> = {
  // The `as const` part lets TypeScript know to treat it as both a type and a value
  // rather than as an arbitrary string that could violate the constraint.
  queryType: 'run-script' as const,
  // ...
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it a better practice to do this through a literal string as you have described, or with a string enum?

import React from 'react';

interface VariableQueryProps {
query: string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably have a comment describing what it actually means (for instance, is it a PxL script or something else?). It also seems to be currently unused below, so there's no context to make it obvious yet.

@@ -46,21 +46,21 @@ const editorStyle = {
export class QueryEditor extends PureComponent<Props> {
onPxlScriptChange(event: string) {
const { onChange, query, onRunQuery } = this.props;
onChange({ ...query, pxlScript: event });
onChange({ ...query, queryType: 'run-script', queryBody: { pxlScript: event } });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit (same in onScriptSelect): even though this still fits on one line, it has a mix of things going on that could stand to live on multiple lines.

@@ -71,7 +71,7 @@ export class QueryEditor extends PureComponent<Props> {
defaultValue={scriptOptions[0]}
/>
<Editor
value={pxlScript}
value={pxlScript === undefined ? '' : pxlScript}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this can be simplified to pxlScript ?? '' (null coalesce)

}

async fetchMetricNames(options: any): Promise<FetchResponse | void> {
let refId = 'tempvar';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let refId = 'tempvar';
const refId = options?.variable?.name ?? 'tempvar';


const range = options?.range as TimeRange;
const interpolatedQuery = {
refId: refId,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
refId: refId,
refId,

Object shorthand syntax is nice for stuff like this

Comment on lines 95 to 108
const zippedData = new Array(df.length);

for (let i = 0; i < df.length; i++) {
zippedData[i] = {};
}

df.fields.forEach((field) => {
field.values.toArray().forEach((elem, i) => {
zippedData[i][field.name] = elem;
});
});

console.log(zippedData);
return zippedData;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover log, and you don't need to call so many functions:

Suggested change
const zippedData = new Array(df.length);
for (let i = 0; i < df.length; i++) {
zippedData[i] = {};
}
df.fields.forEach((field) => {
field.values.toArray().forEach((elem, i) => {
zippedData[i][field.name] = elem;
});
});
console.log(zippedData);
return zippedData;
const zipped = Array(df.length).fill(null);
for (const field of df.fields) {
for (let i = 0; i < field.values.length; i++) {
zipped[i] ??= {};
zipped[i][field.name] = field.values.get(i);
}
}
return zipped;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is definitely a more readable function implementation.

Signed-off-by: Taras Priadka <tpriadka@pixielabs.ai>
@TarasPriadka TarasPriadka requested a review from aimichelle June 10, 2022 20:46
return client, nil
}

//Specifies available query types
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My remaining major nit is that we usually like to add a space after //. So: // Specifies available query types.

There are a few other places in the PR where we can clean this up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh oops. Not sure why linter didn't take care of this

Signed-off-by: Taras Priadka <tpriadka@pixielabs.ai>
@TarasPriadka TarasPriadka requested a review from aimichelle June 10, 2022 20:54
@aimichelle aimichelle merged commit 305bc00 into pixie-io:main Jun 10, 2022
@TarasPriadka TarasPriadka deleted the variable-queries branch June 10, 2022 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants