Skip to content

Commit

Permalink
feat: support k8s labels for dashboards
Browse files Browse the repository at this point in the history
Signed-off-by: arkbriar <[email protected]>
  • Loading branch information
arkbriar committed Nov 2, 2023
1 parent 41d82d2 commit 651396d
Show file tree
Hide file tree
Showing 5 changed files with 1,010 additions and 877 deletions.
2 changes: 1 addition & 1 deletion docker/dashboards/risingwave-dev-dashboard.json

Large diffs are not rendered by default.

185 changes: 74 additions & 111 deletions grafana/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,40 @@
# We use DASHBOARD_VERSION env variable to indicate whether to use a variable as the datasource
DASHBOARD_DYNAMIC_SOURCE = "DASHBOARD_DYNAMIC_SOURCE"

namespace_filter_enabled = os.environ.get(
NAMESPACE_FILTER_ENABLED, "") == "true"
namespace_filter_enabled = os.environ.get(NAMESPACE_FILTER_ENABLED, "") == "true"
if namespace_filter_enabled:
print("Enable filter for namespace field in the generated prometheus query")
risingwave_name_filter_enabled = os.environ.get(
RISINGWAVE_NAME_FILTER_ENABLED, "") == "true"
risingwave_name_filter_enabled = (
os.environ.get(RISINGWAVE_NAME_FILTER_ENABLED, "") == "true"
)
if risingwave_name_filter_enabled:
print("Enable filter for namespace_filter field in the generated prometheus query")
dynamic_source_enabled = os.environ.get(
DASHBOARD_DYNAMIC_SOURCE, "") == "true"
dynamic_source_enabled = os.environ.get(DASHBOARD_DYNAMIC_SOURCE, "") == "true"
if dynamic_source_enabled:
print("Enable use the datasource variable as the dashboard datasource")

COMPONENT_LABEL = "job"
COMPONENT_VARIABLE_LABEL = "Job"
COMPONENT_VARIABLE = "job"
NODE_LABEL = "instance"
NODE_VARIABLE_LABEL = "Node"
NODE_VARIABLE = "node"

# Use different labels for role and instance when namespace filter enabled. (Kubernetes)
if namespace_filter_enabled:
COMPONENT_LABEL = "risingwave_component"
COMPONENT_VARIABLE_LABEL = "Component"
COMPONENT_VARIABLE = "component"
NODE_LABEL = "pod"
NODE_VARIABLE_LABEL = "Pod"
NODE_VARIABLE = "pod"

templating = Templating()
if namespace_filter_enabled:
templating = Templating(
list=[
{
"definition": "label_values(up{risingwave_name=~\".+\"}, namespace)",
"definition": 'label_values(up{risingwave_name=~".+"}, namespace)',
"description": "Kubernetes namespace.",
"hide": 0,
"includeAll": False,
Expand All @@ -44,21 +59,20 @@
"name": "namespace",
"options": [],
"query": {
"query": "label_values(up{risingwave_name=~\".+\"}, namespace)",
"refId": "StandardVariableQuery"
"query": 'label_values(up{risingwave_name=~".+"}, namespace)',
"refId": "StandardVariableQuery",
},
"refresh": 2,
"regex": "",
"skipUrlSync": False,
"sort": 0,
"type": "query"
"type": "query",
}
]
)


class Layout:

def __init__(self):
self.x = 0
self.y = 0
Expand Down Expand Up @@ -110,31 +124,29 @@ def __init__(self, datasource):
self.datasource = datasource

def row(
self,
title,
self,
title,
):
gridPos = self.layout.next_row()
return RowPanel(title=title, gridPos=gridPos)

def row_collapsed(self, title, panels):
gridPos = self.layout.next_row()
return RowPanel(title=title,
gridPos=gridPos,
collapsed=True,
panels=panels)
return RowPanel(title=title, gridPos=gridPos, collapsed=True, panels=panels)

def target(self, expr, legendFormat, hide=False):
return Target(expr=expr,
legendFormat=legendFormat,
datasource=self.datasource,
hide=hide)
return Target(
expr=expr, legendFormat=legendFormat, datasource=self.datasource, hide=hide
)

def table_target(self, expr, hide=False):
return Target(expr=expr,
datasource=self.datasource,
hide=hide,
instant=True,
format='table')
return Target(
expr=expr,
datasource=self.datasource,
hide=hide,
instant=True,
format="table",
)

def timeseries(self, title, description, targets):
gridPos = self.layout.next_half_width_graph()
Expand All @@ -147,11 +159,7 @@ def timeseries(self, title, description, targets):
**self.common_options,
)

def timeseries_count(self,
title,
description,
targets,
legendCols=["mean"]):
def timeseries_count(self, title, description, targets, legendCols=["mean"]):
gridPos = self.layout.next_half_width_graph()
return TimeSeries(
title=title,
Expand All @@ -163,11 +171,7 @@ def timeseries_count(self,
**self.common_options,
)

def timeseries_percentage(self,
title,
description,
targets,
legendCols=["mean"]):
def timeseries_percentage(self, title, description, targets, legendCols=["mean"]):
# Percentage should fall into 0.0-1.0
gridPos = self.layout.next_half_width_graph()
return TimeSeries(
Expand All @@ -181,11 +185,7 @@ def timeseries_percentage(self,
**self.common_options,
)

def timeseries_latency(self,
title,
description,
targets,
legendCols=["mean"]):
def timeseries_latency(self, title, description, targets, legendCols=["mean"]):
gridPos = self.layout.next_half_width_graph()
return TimeSeries(
title=title,
Expand All @@ -198,11 +198,7 @@ def timeseries_latency(self,
**self.common_options,
)

def timeseries_latency_ms(self,
title,
description,
targets,
legendCols=["mean"]):
def timeseries_latency_ms(self, title, description, targets, legendCols=["mean"]):
gridPos = self.layout.next_half_width_graph()
return TimeSeries(
title=title,
Expand All @@ -215,11 +211,9 @@ def timeseries_latency_ms(self,
**self.common_options,
)

def timeseries_actor_latency(self,
title,
description,
targets,
legendCols=["mean"]):
def timeseries_actor_latency(
self, title, description, targets, legendCols=["mean"]
):
gridPos = self.layout.next_half_width_graph()
return TimeSeries(
title=title,
Expand All @@ -232,11 +226,9 @@ def timeseries_actor_latency(self,
**self.common_options,
)

def timeseries_actor_latency_small(self,
title,
description,
targets,
legendCols=["mean"]):
def timeseries_actor_latency_small(
self, title, description, targets, legendCols=["mean"]
):
gridPos = self.layout.next_one_third_width_graph()
return TimeSeries(
title=title,
Expand All @@ -249,11 +241,9 @@ def timeseries_actor_latency_small(self,
**self.common_options,
)

def timeseries_query_per_sec(self,
title,
description,
targets,
legendCols=["mean"]):
def timeseries_query_per_sec(
self, title, description, targets, legendCols=["mean"]
):
gridPos = self.layout.next_half_width_graph()
return TimeSeries(
title=title,
Expand All @@ -266,11 +256,9 @@ def timeseries_query_per_sec(self,
**self.common_options,
)

def timeseries_bytes_per_sec(self,
title,
description,
targets,
legendCols=["mean"]):
def timeseries_bytes_per_sec(
self, title, description, targets, legendCols=["mean"]
):
gridPos = self.layout.next_half_width_graph()
return TimeSeries(
title=title,
Expand All @@ -283,11 +271,7 @@ def timeseries_bytes_per_sec(self,
**self.common_options,
)

def timeseries_bytes(self,
title,
description,
targets,
legendCols=["mean"]):
def timeseries_bytes(self, title, description, targets, legendCols=["mean"]):
gridPos = self.layout.next_half_width_graph()
return TimeSeries(
title=title,
Expand Down Expand Up @@ -325,11 +309,7 @@ def timeseries_ms(self, title, description, targets, legendCols=["mean"]):
**self.common_options,
)

def timeseries_kilobytes(self,
title,
description,
targets,
legendCols=["mean"]):
def timeseries_kilobytes(self, title, description, targets, legendCols=["mean"]):
gridPos = self.layout.next_half_width_graph()
return TimeSeries(
title=title,
Expand All @@ -342,11 +322,7 @@ def timeseries_kilobytes(self,
**self.common_options,
)

def timeseries_dollar(self,
title,
description,
targets,
legendCols=["mean"]):
def timeseries_dollar(self, title, description, targets, legendCols=["mean"]):
gridPos = self.layout.next_half_width_graph()
return TimeSeries(
title=title,
Expand All @@ -372,11 +348,7 @@ def timeseries_ops(self, title, description, targets, legendCols=["mean"]):
**self.common_options,
)

def timeseries_actor_ops(self,
title,
description,
targets,
legendCols=["mean"]):
def timeseries_actor_ops(self, title, description, targets, legendCols=["mean"]):
gridPos = self.layout.next_half_width_graph()
return TimeSeries(
title=title,
Expand All @@ -389,11 +361,9 @@ def timeseries_actor_ops(self,
**self.common_options,
)

def timeseries_actor_ops_small(self,
title,
description,
targets,
legendCols=["mean"]):
def timeseries_actor_ops_small(
self, title, description, targets, legendCols=["mean"]
):
gridPos = self.layout.next_one_third_width_graph()
return TimeSeries(
title=title,
Expand All @@ -406,11 +376,7 @@ def timeseries_actor_ops_small(self,
**self.common_options,
)

def timeseries_rowsps(self,
title,
description,
targets,
legendCols=["mean"]):
def timeseries_rowsps(self, title, description, targets, legendCols=["mean"]):
gridPos = self.layout.next_half_width_graph()
return TimeSeries(
title=title,
Expand All @@ -423,11 +389,7 @@ def timeseries_rowsps(self,
**self.common_options,
)

def timeseries_bytesps(self,
title,
description,
targets,
legendCols=["mean"]):
def timeseries_bytesps(self, title, description, targets, legendCols=["mean"]):
gridPos = self.layout.next_half_width_graph()
return TimeSeries(
title=title,
Expand Down Expand Up @@ -502,8 +464,9 @@ def timeseries_id(self, title, description, targets):
def table_info(self, title, description, targets, excluded_columns):
gridPos = self.layout.next_half_width_graph()
excludedByName = dict.fromkeys(excluded_columns, True)
transformations = [{"id": "organize", "options": {
"excludeByName": excludedByName}}]
transformations = [
{"id": "organize", "options": {"excludeByName": excludedByName}}
]
return Table(
title=title,
dataSource=self.datasource,
Expand All @@ -512,7 +475,7 @@ def table_info(self, title, description, targets, excluded_columns):
gridPos=gridPos,
showHeader=True,
filterable=True,
transformations=transformations
transformations=transformations,
)

def sub_panel(self):
Expand All @@ -522,15 +485,15 @@ def sub_panel(self):
def metric(name, filter=None, node_filter_enabled=True, table_id_filter_enabled=False):
filters = [filter] if filter else []
if namespace_filter_enabled:
filters.append("namespace=~\"$namespace\"")
filters.append('namespace=~"$namespace"')
if risingwave_name_filter_enabled:
filters.append("risingwave_name=~\"$instance\"")
filters.append('risingwave_name=~"$instance"')
if table_id_filter_enabled:
# We use "%table|" instead of "%table" here to match empty string for the table_id filter
filters.append("table_id=~\"$table|\"")
filters.append('table_id=~"$table|"')
if node_filter_enabled:
filters.append("job=~\"$job\"")
filters.append("instance=~\"$node\"")
filters.append(f'{COMPONENT_LABEL}=~"${COMPONENT_VARIABLE}"')
filters.append(f'{NODE_LABEL}=~"${NODE_VARIABLE}"')
if filters:
return f"{name}{{{','.join(filters)}}}"
else:
Expand All @@ -551,5 +514,5 @@ def quantile(f, percentiles):
"max": ["1.0", "max"],
}
return list(
map(lambda p: f(quantile_map[str(p)][0], quantile_map[str(p)][1]),
percentiles))
map(lambda p: f(quantile_map[str(p)][0], quantile_map[str(p)][1]), percentiles)
)
Loading

0 comments on commit 651396d

Please sign in to comment.