github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/production/loki-mixin/dashboards/dashboard-utils.libsonnet (about)

     1  local utils = import 'mixin-utils/utils.libsonnet';
     2  
     3  (import 'grafana-builder/grafana.libsonnet') {
     4    // Override the dashboard constructor to add:
     5    // - default tags,
     6    // - some links that propagate the selected cluster.
     7    dashboard(title, uid='')::
     8      super.dashboard(title, uid) + {
     9        addRowIf(condition, row)::
    10          if condition
    11          then self.addRow(row)
    12          else self,
    13        addLog(name='logs'):: self {
    14          templating+: {
    15            list+: [
    16              {
    17                hide: 0,
    18                label: null,
    19                name: name,
    20                options: [],
    21                query: 'loki',
    22                refresh: 1,
    23                regex: '',
    24                type: 'datasource',
    25              },
    26            ],
    27          },
    28        },
    29  
    30        addCluster(multi=false)::
    31          if multi then
    32            self.addMultiTemplate('cluster', 'loki_build_info', $._config.per_cluster_label)
    33          else
    34            self.addTemplate('cluster', 'loki_build_info', $._config.per_cluster_label),
    35  
    36        addNamespace(multi=false)::
    37          if multi then
    38            self.addMultiTemplate('namespace', 'loki_build_info{' + $._config.per_cluster_label + '=~"$cluster"}', 'namespace')
    39          else
    40            self.addTemplate('namespace', 'loki_build_info{' + $._config.per_cluster_label + '=~"$cluster"}', 'namespace'),
    41  
    42        addTag()::
    43          self + {
    44            tags+: $._config.tags,
    45            links+: [
    46              {
    47                asDropdown: true,
    48                icon: 'external link',
    49                includeVars: true,
    50                keepTime: true,
    51                tags: $._config.tags,
    52                targetBlank: false,
    53                title: 'Loki Dashboards',
    54                type: 'dashboards',
    55              },
    56            ],
    57          },
    58  
    59        addClusterSelectorTemplates(multi=true)::
    60          local d = self {
    61            tags: $._config.tags,
    62            links: [
    63              {
    64                asDropdown: true,
    65                icon: 'external link',
    66                includeVars: true,
    67                keepTime: true,
    68                tags: $._config.tags,
    69                targetBlank: false,
    70                title: 'Loki Dashboards',
    71                type: 'dashboards',
    72              },
    73            ],
    74          };
    75  
    76          if multi then
    77            d.addMultiTemplate('cluster', 'loki_build_info', $._config.per_cluster_label)
    78            .addMultiTemplate('namespace', 'loki_build_info{' + $._config.per_cluster_label + '=~"$cluster"}', 'namespace')
    79          else
    80            d.addTemplate('cluster', 'loki_build_info', $._config.per_cluster_label)
    81            .addTemplate('namespace', 'loki_build_info{' + $._config.per_cluster_label + '=~"$cluster"}', 'namespace'),
    82      },
    83  
    84    jobMatcher(job)::
    85      $._config.per_cluster_label + '=~"$cluster", job=~"($namespace)/%s"' % job,
    86  
    87    namespaceMatcher()::
    88      $._config.per_cluster_label + '=~"$cluster", namespace=~"$namespace"',
    89  
    90    containerLabelMatcher(containerName)::
    91      'label_name=~"%s.*"' % containerName,
    92  
    93    logPanel(title, selector, datasource='$logs'):: {
    94      title: title,
    95      type: 'logs',
    96      datasource: datasource,
    97      targets: [
    98        {
    99          refId: 'A',
   100          expr: selector,
   101        },
   102      ],
   103    },
   104    fromNowPanel(title, metric_name)::
   105      $.panel(title) +
   106      {
   107        type: 'stat',
   108        title: title,
   109        fieldConfig: {
   110          defaults: {
   111            custom: {},
   112            thresholds: {
   113              mode: 'absolute',
   114              steps: [
   115                {
   116                  color: 'green',
   117                  value: null,
   118                },
   119              ],
   120            },
   121            color: {
   122              mode: 'fixed',
   123              fixedColor: 'blue',
   124            },
   125            unit: 'dateTimeFromNow',
   126          },
   127        },
   128        targets: [
   129          {
   130            expr: '%s{%s} * 1e3' % [metric_name, $.namespaceMatcher()],
   131            refId: 'A',
   132            instant: true,
   133            format: 'time_series',
   134          },
   135        ],
   136        options: {
   137          reduceOptions: {
   138            values: false,
   139            calcs: [
   140              'lastNotNull',
   141            ],
   142            fields: '',
   143          },
   144          orientation: 'auto',
   145          text: {},
   146          textMode: 'auto',
   147          colorMode: 'value',
   148          graphMode: 'area',
   149          justifyMode: 'auto',
   150        },
   151        datasource: '$datasource',
   152      },
   153    CPUUsagePanel(title, matcher)::
   154      $.panel(title) +
   155      $.queryPanel([
   156        'sum by(pod) (rate(container_cpu_usage_seconds_total{%s, %s}[$__rate_interval]))' % [$.namespaceMatcher(), matcher],
   157        'min(container_spec_cpu_quota{%s, %s} / container_spec_cpu_period{%s, %s})' % [$.namespaceMatcher(), matcher, $.namespaceMatcher(), matcher],
   158      ], ['{{pod}}', 'limit']) +
   159      {
   160        seriesOverrides: [
   161          {
   162            alias: 'limit',
   163            color: '#E02F44',
   164            fill: 0,
   165          },
   166        ],
   167        tooltip: { sort: 2 },  // Sort descending.
   168      },
   169    containerCPUUsagePanel(title, containerName)::
   170      self.CPUUsagePanel(title, 'container="%s"' % containerName),
   171  
   172    memoryWorkingSetPanel(title, matcher)::
   173      $.panel(title) +
   174      $.queryPanel([
   175        // We use "max" instead of "sum" otherwise during a rolling update of a statefulset we will end up
   176        // summing the memory of the old pod (whose metric will be stale for 5m) to the new pod.
   177        'max by(pod) (container_memory_working_set_bytes{%s, %s})' % [$.namespaceMatcher(), matcher],
   178        'min(container_spec_memory_limit_bytes{%s, %s} > 0)' % [$.namespaceMatcher(), matcher],
   179      ], ['{{pod}}', 'limit']) +
   180      {
   181        seriesOverrides: [
   182          {
   183            alias: 'limit',
   184            color: '#E02F44',
   185            fill: 0,
   186          },
   187        ],
   188        yaxes: $.yaxes('bytes'),
   189        tooltip: { sort: 2 },  // Sort descending.
   190      },
   191    containerMemoryWorkingSetPanel(title, containerName)::
   192      self.memoryWorkingSetPanel(title, 'container="%s"' % containerName),
   193  
   194    goHeapInUsePanel(title, jobName)::
   195      $.panel(title) +
   196      $.queryPanel(
   197        'sum by(%s) (go_memstats_heap_inuse_bytes{%s})' % [$._config.per_instance_label, $.jobMatcher(jobName)],
   198        '{{%s}}' % $._config.per_instance_label
   199      ) +
   200      {
   201        yaxes: $.yaxes('bytes'),
   202        tooltip: { sort: 2 },  // Sort descending.
   203      },
   204  
   205    filterNodeDisk(matcher)::
   206      |||
   207        ignoring(%s) group_right() (label_replace(count by(%s, %s, device) (container_fs_writes_bytes_total{%s, %s, device!~".*sda.*"}), "device", "$1", "device", "/dev/(.*)") * 0)
   208      ||| % [$._config.per_instance_label, $._config.per_node_label, $._config.per_instance_label, $.namespaceMatcher(), matcher],
   209    filterNodeDiskContainer(containerName)::
   210      self.filterNodeDisk('container="%s"' % containerName),
   211  
   212    newStatPanel(queries, legends='', unit='percentunit', decimals=1, thresholds=[], instant=false, novalue='')::
   213      super.queryPanel(queries, legends) + {
   214        type: 'stat',
   215        targets: [
   216          target {
   217            instant: instant,
   218            interval: '',
   219  
   220            // Reset defaults from queryPanel().
   221            format: null,
   222            intervalFactor: null,
   223            step: null,
   224          }
   225          for target in super.targets
   226        ],
   227        fieldConfig: {
   228          defaults: {
   229            decimals: decimals,
   230            noValue: novalue,
   231            unit: unit,
   232          },
   233          overrides: [],
   234        },
   235      },
   236  
   237    containerDiskSpaceUtilizationPanel(title, containerName)::
   238      $.panel(title) +
   239      $.queryPanel('max by(persistentvolumeclaim) (kubelet_volume_stats_used_bytes{%s} / kubelet_volume_stats_capacity_bytes{%s}) and count by(persistentvolumeclaim) (kube_persistentvolumeclaim_labels{%s,%s})' % [$.namespaceMatcher(), $.namespaceMatcher(), $.namespaceMatcher(), $.containerLabelMatcher(containerName)], '{{persistentvolumeclaim}}') +
   240      { yaxes: $.yaxes('percentunit') },
   241  }