-
Notifications
You must be signed in to change notification settings - Fork 12
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
Adding support to filter columns for the Pod Metrics script #45
Conversation
src/column_filtering.tsx
Outdated
out = output[[` + | ||
podColumnQueries[0] + | ||
podColumnQueries[1] + | ||
podColumnQueries[2] + | ||
podColumnQueries[3] + | ||
podColumnQueries[4] + | ||
podColumnQueries[5] + | ||
podColumnQueries[6] + | ||
podColumnQueries[7] + | ||
`]] | ||
px.display(out)`; | ||
|
||
//array of json objects containing every column name with its corresponding index for an array containing the string format query | ||
export const podColumnOptions = [ | ||
{ label: 'pod', value: 0 }, | ||
{ label: 'cpu_usage', value: 1 }, | ||
{ label: 'total_disk_read_throughput', value: 2 }, | ||
{ label: 'total_disk_write_throughput', value: 3 }, | ||
{ label: 'container_count', value: 4 }, | ||
{ label: 'node', value: 5 }, | ||
{ label: 'start_time', value: 6 }, | ||
{ label: 'status', value: 7 }, | ||
]; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should put these pod column options as a property of the JSON for each script. that way, we don't hard code a particular script into the UI - it's all configurable via JSON
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I'll add them as a property of JSON for the script
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few stylistic and structural comments
src/column_filtering.tsx
Outdated
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
const podMetrics = require('pxl_scripts/pods-metrics.json'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to use the user script if it has the filtering line in it? I think it may be slightly annoying for users if filtering disregards all of the changes they made.
Also, a thought for the future, we can send columns which we want to filter and then remove them in the go backend instead of altering the script.
src/column_filtering.tsx
Outdated
px.display(out)`; | ||
|
||
//array of json objects containing every column name with its corresponding index for an array containing the string format query | ||
export const podColumnOptions = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can store podColumnQueries
in the value
field of podColumnOptions
instead of indicies. You'd need to change.
Also add type Array<SelectableValue<Type>>
for this variable where Type
is the type of the value. If you use store pod column options here, you'd use string
.
src/column_filtering.tsx
Outdated
{ label: 'status', value: 7 }, | ||
]; | ||
|
||
export const tabularScripts: string[] = ['Pod Metrics']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add an optional field in the JSONs tabular = true
so you don't have to hardcode the script names here in code.
src/column_filtering.tsx
Outdated
|
||
export const tabularScripts: string[] = ['Pod Metrics']; | ||
|
||
export function makeFilteringScript(obj: any[]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
obj
is not a descriptive name for a variable. Also any[]
is a very broad type, specify a tighter type instead. Specify a return type as well(ex.
function add(x: number, y: number): number {
return x + y;
}
)
src/column_filtering.tsx
Outdated
const podGetDataScript = podMetrics.script.substr(0, podMetrics.script.indexOf('px.display')); | ||
|
||
//Contains the part of the full script which contains all columns | ||
var filteredColumnScript = podAllColumnsScript; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use var
since it is not scoped properly in JS. Either use let
for mutable variables or const
. Specify a proper type.
src/pxl_scripts/pods-metrics.json
Outdated
{ | ||
"name": "Pod Metrics", | ||
"description": "", | ||
"script": "import px\n\ndef process_stats_by_entity(start_time: int, entity: str):\n ''' Gets the windowed process stats (CPU, memory, etc) per node or pod.\n Args:\n @start_time Starting time of the data to examine.\n @entity: Either pod or node_name.\n '''\n # Window size to use on time_ column for bucketing.\n ns_per_s = 1000 * 1000 * 1000\n window_ns = px.DurationNanos(10 * ns_per_s)\n\n df = px.DataFrame(table='process_stats', start_time=start_time)\n df[entity] = df.ctx[entity]\n df.timestamp = px.bin(df.time_, window_ns)\n # First calculate CPU usage by process (UPID) in each k8s_object\n # over all windows.\n df = df.groupby([entity, 'upid', 'timestamp']).agg(\n rss=('rss_bytes', px.mean),\n vsize=('vsize_bytes', px.mean),\n # The fields below are counters, so we take the min and the max to subtract them.\n cpu_utime_ns_max=('cpu_utime_ns', px.max),\n cpu_utime_ns_min=('cpu_utime_ns', px.min),\n cpu_ktime_ns_max=('cpu_ktime_ns', px.max),\n cpu_ktime_ns_min=('cpu_ktime_ns', px.min),\n read_bytes_max=('read_bytes', px.max),\n read_bytes_min=('read_bytes', px.min),\n write_bytes_max=('write_bytes', px.max),\n write_bytes_min=('write_bytes', px.min),\n rchar_bytes_max=('rchar_bytes', px.max),\n rchar_bytes_min=('rchar_bytes', px.min),\n wchar_bytes_max=('wchar_bytes', px.max),\n wchar_bytes_min=('wchar_bytes', px.min),\n )\n # Next calculate cpu usage and memory stats per window.\n df.cpu_utime_ns = df.cpu_utime_ns_max - df.cpu_utime_ns_min\n df.cpu_ktime_ns = df.cpu_ktime_ns_max - df.cpu_ktime_ns_min\n df.read_bytes = df.read_bytes_max - df.read_bytes_min\n df.write_bytes = df.write_bytes_max - df.write_bytes_min\n df.rchar_bytes = df.rchar_bytes_max - df.rchar_bytes_min\n df.wchar_bytes = df.wchar_bytes_max - df.wchar_bytes_min\n # Sum by UPID.\n df = df.groupby([entity, 'timestamp']).agg(\n cpu_ktime_ns=('cpu_ktime_ns', px.sum),\n cpu_utime_ns=('cpu_utime_ns', px.sum),\n read_bytes=('read_bytes', px.sum),\n write_bytes=('write_bytes', px.sum),\n rchar_bytes=('rchar_bytes', px.sum),\n wchar_bytes=('wchar_bytes', px.sum),\n rss=('rss', px.sum),\n vsize=('vsize', px.sum),\n )\n df.actual_disk_read_throughput = df.read_bytes / window_ns\n df.actual_disk_write_throughput = df.write_bytes / window_ns\n df.total_disk_read_throughput = df.rchar_bytes / window_ns\n df.total_disk_write_throughput = df.wchar_bytes / window_ns\n # Now take the mean value over the various timestamps.\n df = df.groupby(entity).agg(\n cpu_ktime_ns=('cpu_ktime_ns', px.mean),\n cpu_utime_ns=('cpu_utime_ns', px.mean),\n actual_disk_read_throughput=('actual_disk_read_throughput', px.mean),\n actual_disk_write_throughput=('actual_disk_write_throughput', px.mean),\n total_disk_read_throughput=('total_disk_read_throughput', px.mean),\n total_disk_write_throughput=('total_disk_write_throughput', px.mean),\n avg_rss=('rss', px.mean),\n avg_vsize=('vsize', px.mean),\n )\n # Finally, calculate total (kernel + user time) percentage used over window.\n df.cpu_usage = px.Percent((df.cpu_ktime_ns + df.cpu_utime_ns) / window_ns)\n return df.drop(['cpu_ktime_ns', 'cpu_utime_ns'])\n\n''' A list of pods in `namespace`.\nArgs:\n@start_time: The timestamp of data to start at.\n@namespace: The name of the namespace to filter on.\n'''\ndf = px.DataFrame(table='process_stats', start_time=$__from)\ndf.pod = df.ctx['pod_name']\ndf.node = df.ctx['node_name']\ndf.container = df.ctx['container_name']\ndf = df.groupby(['pod', 'node', 'container']).agg()\ndf = df.groupby(['pod', 'node']).agg(container_count=('container', px.count))\ndf.start_time = px.pod_name_to_start_time(df.pod)\ndf.status = px.pod_name_to_status(df.pod)\n\n\nprocess_stats = process_stats_by_entity($__from, 'pod')\noutput = process_stats.merge(df, how='inner', left_on='pod', right_on='pod',\n suffixes=['', '_x'])\n\n\npx.display(output[['pod', 'cpu_usage', 'total_disk_read_throughput',\n 'total_disk_write_throughput', 'container_count',\n 'node', 'start_time', 'status']])" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default scripts should have a short docstring documenting what the script does with a link to grafana documentation. Look at other default scripts for reference.
src/query_editor.tsx
Outdated
defaultValue={scriptOptions[0]} | ||
/> | ||
|
||
{tabularScripts.includes(query.scriptName) ? ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest adding a boolean field tabular
to the query object instead of tracking tabular script names in a list.
src/query_editor.tsx
Outdated
|
||
filterPodColumns(obj: any[]) { | ||
if (obj) { | ||
const constFilteredScript = makeFilteringScript(obj); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use variable name filteredScript
, its already clear that it is constant from the const
keyword
Signed-off-by: Kartik Pattaswamy <kpattaswamy@pixielabs.ai>
Signed-off-by: Kartik Pattaswamy <kpattaswamy@pixielabs.ai>
d1126ed
to
702c1d4
Compare
…milliseconds. 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: Kartik Pattaswamy <kpattaswamy@pixielabs.ai>
Signed-off-by: Kartik Pattaswamy <kpattaswamy@pixielabs.ai>
src/query_editor.tsx
Outdated
defaultValue={scriptOptions[0]} | ||
/> | ||
|
||
{query.isTabular === true ? ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: You can shorten this to query.isTabular ? ( ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the other path is just an empty fragment, you can even just do query.isTabular && (...)
and not have a ternary at all. React renders nothing at all if it's told to render a literal false
, so a && b
resolves to either rendering nothing or rendering b
.
src/query_editor.tsx
Outdated
options={query.columnOptions} | ||
onChange={this.filterColumns.bind(this)} | ||
width={32} | ||
inputId="multi-select-ops" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's rename the input ID to something more specific, like column-select
.
src/pxl_scripts.tsx
Outdated
value: scriptObject.script, | ||
value: scriptObject, | ||
isTabular: scriptObject.isTabular, | ||
columnOptions: scriptObject.columnNames, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the columnNames
field in the json files, it seems redundant to specify the value
since arrays are inherently ordered anyway.
I think restructuring the JSON file to just be:
"columnNames": ["timestamp", "remote_addr", ...]
Then here, we convert it to the values/label obj:
columnOptions: scriptObject.columnNames.map((name, index) => { 'label': name, 'value': index })
src/column_filtering.tsx
Outdated
|
||
//Splits the script into two parts: 1. Script up till display columns, 2. Script after displaying columns | ||
function splitScript(script: string): string[] { | ||
const beforeDisplayCol = script.slice(0, script.indexOf('[[')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My worry here is if there's a script that uses [[
and ]]
multiple times, and not just in the final output. For example, if you take a look at the px/cluster
script's conn_stats_by_service
function.
Luckily these scripts are written by ourselves, so we can make sure that doesn't happen. But we may to be a bit more robust and search for the last indexOf [[
and ]]
. You can use lastIndexOf
for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in agreement that scanning for this substring seems uncomfortably fragile. Template variables like you're already doing in datasource.tsx
(or some other format that is definitely not valid PxL) are a more robust choice here since you're controlling the preset scripts in this same repository. px/cluster
, as mentioned, has at least three [[something]]
s in it, how do you know for sure which one should be used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could try creating some macro which is easy to find without collisions with user code. #45 (comment)
Signed-off-by: Kartik Pattaswamy <kpattaswamy@pixielabs.ai>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Largely LGTM, just a couple of questions (see below)
src/query_editor.tsx
Outdated
defaultValue={scriptOptions[0]} | ||
/> | ||
|
||
{query.isTabular === true ? ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the other path is just an empty fragment, you can even just do query.isTabular && (...)
and not have a ternary at all. React renders nothing at all if it's told to render a literal false
, so a && b
resolves to either rendering nothing or rendering b
.
src/column_filtering.tsx
Outdated
|
||
//Splits the script into two parts: 1. Script up till display columns, 2. Script after displaying columns | ||
function splitScript(script: string): string[] { | ||
const beforeDisplayCol = script.slice(0, script.indexOf('[[')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in agreement that scanning for this substring seems uncomfortably fragile. Template variables like you're already doing in datasource.tsx
(or some other format that is definitely not valid PxL) are a more robust choice here since you're controlling the preset scripts in this same repository. px/cluster
, as mentioned, has at least three [[something]]
s in it, how do you know for sure which one should be used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall. Had some small nits
src/types.ts
Outdated
isTabular: boolean; | ||
columnOptions: Array<{ label: string; value: number }>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make these fields optional since not all scripts may have these fields.
isTabular: boolean; | |
columnOptions: Array<{ label: string; value: number }>; | |
isTabular?: boolean; | |
columnOptions?: Array<{ label: string; value: number }>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good suggestion.
src/pxl_scripts/example-query.json
Outdated
@@ -1,5 +1,6 @@ | |||
{ | |||
"name": "Example Query", | |||
"description": "Example query from Pixie documentation.", | |||
"script": "'''\nThis query graphs the request throughput from the nodes in your cluster which comes from Pixie docs tutorial(\\`https://docs.px.dev/tutorials/integrations/grafana/\\`)\nIf you are interested in learning more about how to write pxl scripts, go to https://docs.px.dev/tutorials/pxl-scripts/.\n\nThis query is for use with Grafana's Pixie Datasource Plugin only,\nas it uses Grafana macros for adding Grafana dashboard context.\n\n'''\n\n# Import Pixie's module for querying data.\nimport px\n\n# Load data from Pixie's \\`http_events\\` table into a Dataframe.\ndf = px.DataFrame(table='http_events', start_time=__time_from)\n\n# Add K8s metadata context.\ndf.service = df.ctx['service']\ndf.namespace = df.ctx['namespace']\n\n# Bin the 'time_' column using the interval provided by Grafana.\ndf.timestamp = px.bin(df.time_, __interval)\n\n# Group data by unique pairings of 'timestamp' and 'service'\n# and count the total number of requests per unique pairing.\nper_ns_df = df.groupby(['timestamp', 'service']).agg(\n throughput_total=('latency', px.count)\n)\n\n# Calculate throughput by dividing # of requests by the time interval.\nper_ns_df.request_throughput = per_ns_df.throughput_total / __interval\nper_ns_df.request_throughput = per_ns_df.request_throughput * 1e9\n\n# Rename 'timestamp' column to 'time_'. The Grafana plugin expects a 'time_'\n# column to display data in a Graph or Time series.\nper_ns_df.time_ = per_ns_df.timestamp\n\n# Output select columns of the DataFrame.\npx.display(per_ns_df['time_', 'service', 'request_throughput'])\n\n" | |||
"script": "'''\nThis query graphs the request throughput from the nodes in your cluster which comes from Pixie docs tutorial(\\`https://docs.px.dev/tutorials/integrations/grafana/\\`)\nIf you are interested in learning more about how to write pxl scripts, go to https://docs.px.dev/tutorials/pxl-scripts/.\n\nThis query is for use with Grafana's Pixie Datasource Plugin only,\nas it uses Grafana macros for adding Grafana dashboard context.\n\n'''\n\n# Import Pixie's module for querying data.\nimport px\n\n# Load data from Pixie's \\`http_events\\` table into a Dataframe.\ndf = px.DataFrame(table='http_events', start_time=__time_from)\n\n# Add K8s metadata context.\ndf.service = df.ctx['service']\ndf.namespace = df.ctx['namespace']\n\n# Bin the 'time_' column using the interval provided by Grafana.\ndf.timestamp = px.bin(df.time_, __interval)\n\n# Group data by unique pairings of 'timestamp' and 'service'\n# and count the total number of requests per unique pairing.\nper_ns_df = df.groupby(['timestamp', 'service']).agg(\n throughput_total=('latency', px.count)\n)\n\n# Calculate throughput by dividing # of requests by the time interval.\nper_ns_df.request_throughput = per_ns_df.throughput_total / __interval\nper_ns_df.request_throughput = per_ns_df.request_throughput * 1e9\n\n# Rename 'timestamp' column to 'time_'. The Grafana plugin expects a 'time_'\n# column to display data in a Graph or Time series.\nper_ns_df.time_ = per_ns_df.timestamp\n\n# Output select columns of the DataFrame.\npx.display(per_ns_df['time_', 'service', 'request_throughput'])\n\n", | |||
"isTabular": false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If isTabular
is optional in the query object, you don't have to add this field to every script. Same goes for all changed script files.
src/column_filtering.tsx
Outdated
|
||
//Splits the script into two parts: 1. Script up till display columns, 2. Script after displaying columns | ||
function splitScript(script: string): string[] { | ||
const beforeDisplayCol = script.slice(0, script.lastIndexOf('[[')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can introduce some sort of macro which users can use to specify the column names? We can find that macro then and process it in a predictable way.
Ex.
...
COLUMNS{all} // or COLUMNS{'pod', 'namespace', 'latency', ...}
...
Then later find this macro in code, process the columns that users want to display, and replace this macro with df.display
in query.pxlScript
before sending the code query.
src/column_filtering.tsx
Outdated
//Dynamically builds the script by concatenating each option that was chosen | ||
filteredColumnScript = `[[`; | ||
|
||
for (let i = 0; i < chosenOptions.length; i++) { | ||
filteredColumnScript += formatColumnName(chosenOptions[i].label); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You already have a method which does this.
//Dynamically builds the script by concatenating each option that was chosen | |
filteredColumnScript = `[[`; | |
for (let i = 0; i < chosenOptions.length; i++) { | |
filteredColumnScript += formatColumnName(chosenOptions[i].label); | |
//Dynamically builds the script by concatenating each option that was chosen | |
filteredColumnScript = getAllColumnScript(chosenOptions); |
src/column_filtering.tsx
Outdated
//Returns a script which can be used to display all columns | ||
function getAllColumnScript(columnNames: Array<{ label: string; value: number }>): string { | ||
let script = '[['; | ||
|
||
for (let i = 0; i < columnNames.length; i++) { | ||
script += formatColumnName(columnNames[i].label); | ||
} | ||
return script; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can join an array of values, and also should probably name this something general like getScriptFromColumns
:
//Returns a script which can be used to display all columns | |
function getAllColumnScript(columnNames: Array<{ label: string; value: number }>): string { | |
let script = '[['; | |
for (let i = 0; i < columnNames.length; i++) { | |
script += formatColumnName(columnNames[i].label); | |
} | |
return script; | |
} | |
function getScriptFromColumns(columnNames: Array<{ label: string; value: number }>): string { | |
return [ | |
'[[', | |
...columnNames.map(colName=>`'${colName.label}'`), | |
']]' | |
].join() | |
} |
This basically constructs your string where the mid part just formats colNames
the way you want.
src/datasource.ts
Outdated
timeVars.forEach((replace) => { | ||
query.pxlScript = query.pxlScript.replaceAll(replace[0], replace[1]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For readability, can do something like
timeVars.forEach((replace) => { | |
query.pxlScript = query.pxlScript.replaceAll(replace[0], replace[1]); | |
for (const [changeFrom, changeTo] of timeVars) { | |
query.pxlScript = query.pxlScript.replaceAll(replaceFrom, replaceTo); | |
} |
src/pxl_scripts.tsx
Outdated
isTabular: boolean; | ||
columnNames: string[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since these may be not present in some scripts, you can make these fields optional.
isTabular: boolean; | |
columnNames: string[]; | |
isTabular?: boolean; | |
columnNames?: string[]; |
src/pxl_scripts.tsx
Outdated
isTabular: scriptObject.isTabular, | ||
columnOptions: (scriptObject.columnNames || []).map((name, index) => ({ label: name, value: index })), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are already a part of scriptObject
, so you don't need to add these as fields. Also SelectableValue
doesn't have these fields, so its better to avoid adding them directly to the object.
src/query_editor.tsx
Outdated
const { onChange, query, onRunQuery } = this.props; | ||
onChange({ ...query, pxlScript: option.value }); | ||
const script = option.value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const script = option.value; | |
const script:Script = option.value; |
src/query_editor.tsx
Outdated
<MultiSelect | ||
placeholder="Select columns to filter" | ||
options={query.columnOptions} | ||
onChange={this.filterColumns.bind(this)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In React you want to call functions which get called on change or on click as on[name of action which is happening]
. So in this case you could call this method onFilterSelect
.
Signed-off-by: Kartik Pattaswamy <kpattaswamy@pixielabs.ai>
src/datasource.ts
Outdated
|
||
export class DataSource extends DataSourceWithBackend<PixieDataQuery, PixieDataSourceOptions> { | ||
constructor(instanceSettings: DataSourceInstanceSettings<PixieDataSourceOptions>) { | ||
super(instanceSettings); | ||
} | ||
|
||
applyTemplateVariables(query: PixieDataQuery, scopedVars: ScopedVars) { | ||
let timeVars = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Javascript has variables can be defined as let
or const
.
let
is usually used when you know the variable is going to be reassigned:
let a = 1;
a = 2;
However, const
should be used when you essentially have a constant.
const a = 1;
a = 2; // You shouldn't do this!
In the case of timeVars
, this can be a const. And columnVars
below as well.
You can actually pull them out of this function and move them to the top of the file (defined on the same level as functions). In general, we like to pull out constants to the top so that they're easy to find and change if needbe.
src/datasource.ts
Outdated
['$__interval', '__interval'], | ||
]; | ||
|
||
//Replace Grafana's time global variables from the script with Pixie's time macros |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: We like to make sure theres a space after the //
in our comments. So this should be: // Replace Grafana's...
This is usually enforced by a linter, so let me look into why that's not set up yet so that it's easier to keep in mind for your next PRs.
src/types.ts
Outdated
isTabular: boolean; | ||
columnOptions: Array<{ label: string; value: number }>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good suggestion.
Signed-off-by: Kartik Pattaswamy <kpattaswamy@pixielabs.ai>
…milliseconds. 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: Kartik Pattaswamy <kpattaswamy@pixielabs.ai>
Signed-off-by: Kartik Pattaswamy <kpattaswamy@pixielabs.ai>
Signed-off-by: Kartik Pattaswamy <kpattaswamy@pixielabs.ai>
Signed-off-by: Kartik Pattaswamy <kpattaswamy@pixielabs.ai>
Signed-off-by: Kartik Pattaswamy <kpattaswamy@pixielabs.ai>
Signed-off-by: Kartik Pattaswamy <kpattaswamy@pixielabs.ai>
Signed-off-by: Kartik Pattaswamy <kpattaswamy@pixielabs.ai>
Added a drop down select option for a user to choose what columns to filter in the Pods-Metrics table. Did this by adding support to dynamically replace part of the px script dealing with displaying all columns with only columns chosen by user.
Signed-off-by: Kartik Pattaswamy kpattaswamy@pixielabs.ai