Skip to content

pgillich/grafana-tree-panel

Repository files navigation

Grafana Tree Panel Plugin

Build

This panel plugin shows a tree from records, provided by a datasource. The plugin is optized and tested with JSON API datasource.

This plugin presents JSON API responses, for example Kubernetes resources received from Kubernetes API. A possible production environment is described at https://github.com/pgillich/grafana-kubernetes.

Example screenshot about a Kubernetes Namespace:

2 panels

Screenshot about a panel editor:

simple-editor

Datasource

All values from datasource are converted to string. The object type is converted to JSON string. The best datasource is JSON API, but other datasources may also be used, for example TestData Logs:

TestData, Logs

The number of values in fields must be same, so missing values must be substituted. JSON API supports JSONata, so it's possible.

Example JSONata expression for Kubernetes API, which substitutes the missing values (appName, containerState) and generates string about lists (containerImage, containerState):

$map(items, function($v) {{"namespace": $v.metadata.namespace, "name": $v.metadata.name, "appName": $v.metadata.labels."app.kubernetes.io/name" ? $v.metadata.labels."app.kubernetes.io/name" : ($v.metadata.labels."app" ? $v.metadata.labels."app" : "-"), "statusPhase": $v.status.phase, "containerCount": $count($v.spec.containers), "containerImage": $join($v.spec.containers[*].image, " "), "containerState": $v.status.containerStatuses[*].state ? $string($v.status.containerStatuses[*].state) : "-"}})

If Grafana runs outside of the Kubernetes cluster, a kubectl proxy command can create API endpoint for JSON API in order to access the cluster:

kubectl proxy --address 0.0.0.0 --accept-hosts='.*' --reject-methods=POST,PUT,PATCH -v5

It's highly recommended to use same JSONata expression in field definition, only the selected field should be different, for example:

Query editor 1

Query editor 2

Panel Options

Option descriptions can be read on the panel option editor:

Panel options

The default template engine is a simple and fast ${field}-style expression processor, for example:

${statusPhase}
${namespace}
${appName} ${name}
${containerImage}

If a more complex template engine is needed, Handlebars can be used, which is a {{field}}-style engine, for example:

handlebars-options

Screenshot about a panel editor, with Handlebars engine:

handlebars-editor

Handlebars extensions

Pod info

An additional function is added to Handlebars, for having better information about Kubernetes Pods. It's complex to evaluate the STATUS and other kubectl get pod -o wide columns from Kubernetes API responses, so the printPod() function was ported to TypeScript. The syntax is: {{printPodColumn <whole_pod> "<column>"}}, where <whole_pod> the field, which contains the whole pod, <column> is the kubectl get pod -o wide column name, for example:

  • NAME
  • READY
  • STATUS
  • RESTARTS
  • AGE
  • IP
  • NODE
  • NOMINATED_NODE
  • READINESS_GATES
  • MESSAGE

The AGE behaves a little bit different: it's a little bit more precise. The MESSAGE column contains additional info (reason) about the STATUS. Example for printPodColumn:

{{printPodColumn rawPod "STATUS"}}
{{namespace}}
{{appName}} {{name}}
{{containerImage}} {{printPodColumn rawPod "MESSAGE"}}

Example JSONata datasource expression for above template:

$map(items, function($v) {{"rawPod": $v, "namespace": $v.metadata.namespace, "name": $v.metadata.name, "appName": $v.metadata.labels."app.kubernetes.io/name" ? $v.metadata.labels."app.kubernetes.io/name" : ($v.metadata.labels."app" ? $v.metadata.labels."app" : "-"), "statusPhase": $v.status.phase, "containerCount": $count($v.spec.containers), "containerImage": $join($v.spec.containers[*].image, " "), "containerState": $v.status.containerStatuses[*].state ? $string($v.status.containerStatuses[*].state) : "-"}})

Example screenshot for comparing Pod status info form raw Kubernetes API and from printPodColumn function:

simple-handlebars

Example Dashboards

Example dashboards can be found in examples.

  • Namespace Pods.json Pods of a selected Namespace, Simple template engine
  • All Pods.json Pods of all Namespaces, Handlebars template engine with kubectl columns.

Creating Issues

Please attach sample json file(s) to the new Issue.

Contributing

See more details in CONTRIBUTING.md.