def memory_usage(datasource):
    return G.Graph(
        title="Memory Usage",
        dataSource=datasource,

        xAxis=X_TIME,
        yAxes=[
            G.YAxis(
                # 2 ^ 30 bytes
                format="gbytes",
                label="Memory",
            ),
            G.YAxis(
                show=False,
            ),
        ],
        targets=[
            G.Target(
                expr="""
                sum(machine_memory_bytes) / 2 ^ 30
                """,
                legendFormat="Total Physical Memory",
                refId="A",
            ),
            G.Target(
                expr="""
                rss:container_memory:total / 2 ^ 30
                """,
                legendFormat="Total Container RSS",
                refId="B",
            ),
        ],
    )
示例#2
0
def test_auto_refids():
    """auto_ref_ids() provides refIds for all targets without refIds already set."""
    dashboard = G.Dashboard(
        title="Test dashboard",
        rows=[
            G.Row(panels=[
                G.Graph(
                    title="CPU Usage by Namespace (rate[5m])",
                    dataSource="My data source",
                    targets=[
                        G.Target(
                            expr='whatever #Q',
                            legendFormat='{{namespace}}',
                        ),
                        G.Target(
                            expr='hidden whatever',
                            legendFormat='{{namespace}}',
                            refId='Q',
                            hide=True
                        ),
                        G.Target(
                            expr='another target'
                        ),
                    ],
                    yAxes=[
                        G.YAxis(format=G.SHORT_FORMAT, label="CPU seconds"),
                        G.YAxis(format=G.SHORT_FORMAT),
                    ],
                ).auto_ref_ids()
            ]),
        ],
    )
    assert dashboard.rows[0].panels[0].targets[0].refId == 'A'
    assert dashboard.rows[0].panels[0].targets[1].refId == 'Q'
    assert dashboard.rows[0].panels[0].targets[2].refId == 'B'
示例#3
0
def test_auto_refids_preserves_provided_ids():
    """
    auto_ref_ids() provides refIds for all targets without refIds already
    set.
    """
    dashboard = G.Dashboard(
        title="Test dashboard",
        rows=[
            G.Row(panels=[
                G.Graph(
                    title="CPU Usage by Namespace (rate[5m])",
                    targets=[
                        G.Target(
                            expr='whatever #Q',
                            legendFormat='{{namespace}}',
                        ),
                        G.Target(
                            expr='hidden whatever',
                            legendFormat='{{namespace}}',
                            refId='Q',
                        ),
                        G.Target(
                            expr='another target'
                        ),
                    ],
                ).auto_ref_ids()
            ]),
        ],
    )
    assert dashboard.rows[0].panels[0].targets[0].refId == 'A'
    assert dashboard.rows[0].panels[0].targets[1].refId == 'Q'
    assert dashboard.rows[0].panels[0].targets[2].refId == 'B'
示例#4
0
def PromGraph(data_source, title, expressions, **kwargs):
    """Create a graph that renders Prometheus data.

    :param str data_source: The name of the data source that provides
        Prometheus data.
    :param title: The title of the graph.
    :param expressions: List of tuples of (legend, expr), where 'expr' is a
        Prometheus expression. Or a list of dict where keys are Target's args.
    :param kwargs: Passed on to Graph.
    """
    letters = string.ascii_uppercase
    expressions = list(expressions)
    if len(expressions) > len(letters):
        raise ValueError(
            'Too many expressions. Can support at most {}, but got {}'.format(
                len(letters), len(expressions)))

    if all(isinstance(expr, dict) for expr in expressions):
        targets = [
            G.Target(refId=refId, **args)
            for (args, refId) in zip(expressions, letters)
        ]
    else:
        targets = [
            G.Target(expr, legend, refId=refId)
            for ((legend, expr), refId) in zip(expressions, letters)
        ]
    return G.Graph(title=title,
                   dataSource=data_source,
                   targets=targets,
                   **kwargs)
def api_call_latency(title, verb, scope, threshold):
    return d.Graph(
        title=title,
        targets=[
            g.Target(expr=str(threshold), legendFormat="threshold"),
            g.Target(
                expr='apiserver:apiserver_request_latency_1m:histogram_quantile{quantile="0.99", verb=~"%(verb)s", scope=~"%(scope)s"}'
                % {"verb": verb, "scope": scope},
                legendFormat="{{verb}} {{scope}}/{{resource}}",
            ),
        ],
        yAxes=g.single_y_axis(format=g.SECONDS_FORMAT),
    )
def s4_customer_deployments(datasource):
    return G.Graph(
        title="Customer Deployments",
        dataSource=datasource,

        xAxis=X_TIME,
        yAxes=[
            G.YAxis(
                format="none",
                label="Total Customer Deployments",
                min=0,
                max=100,
            ),
            G.YAxis(
                show=False,
            ),
        ],

        targets=[
            G.Target(
                # Each replicaset and pod end up with their own series.  Label
                # these more succinctly.  Leave them distinct in case it is
                # interesting to see where restarts have happened.
                expr="""
                label_replace(
                    s4_deployment_gauge{pod=~"subscription-converger-.*"},
                    "shortpod",
                    "# Deploys ($1)",
                    "pod",
                    "subscription-converger-(.*)"
                )
                """,
                refId="A",
                legendFormat="{{shortpod}}",
            ),
            G.Target(
                # As above.
                expr="""
                label_replace(
                    s4_running_pod_gauge{pod=~"subscription-converger-.*"},
                    "shortpod",
                    "# Running ($1)",
                    "pod",
                    "subscription-converger-(.*)"
                )
                """,
                refId="B",
                legendFormat="{{shortpod}}",
            ),
        ],
    )
def process_open_fds(datasource):
    return G.Graph(
        title="Open File Descriptors",
        dataSource=datasource,

        xAxis=X_TIME,
        yAxes=[
            G.YAxis(
                format="none",
                label="Count",
            ),
            G.YAxis(
                show=False,
            ),
        ],

        targets=[
            G.Target(
                expr="""
                process_open_fds{pod=~".+"}
                """,
                refId="A",
                legendFormat="{{pod}}",
            ),
        ],
    )
def unhandled_errors(datasource):
    return G.Graph(
        title="Unhandled Errors",
        dataSource=datasource,

        xAxis=X_TIME,
        yAxes=[
            G.YAxis(
                format="none",
                label="Count",
            ),
            G.YAxis(
                show=False,
            ),
        ],

        targets=[
            G.Target(
                expr="""
                sum(s4_unhandled_error_counter)
                """,
                refId="A",
                legendFormat="Total Unhandled Errors",
            ),
        ],
    )
def last_convergence(datasource):
    return G.Graph(
        title="Since Last Convergence",
        dataSource=datasource,

        xAxis=X_TIME,
        yAxes=[
            G.YAxis(
                format="none",
                label="Period",
            ),
            G.YAxis(
                show=False,
            ),
        ],

        targets=[
            G.Target(
                expr="""
                time()
                - max(
                    s4_last_convergence_succeeded{
                        pod=~"subscription-converger-.*"
                    }
                )
                """,
                refId="A",
                legendFormat="Time Since Last Convergence Success",
            ),
        ],
    )
def filesystem_usage(datasource):
    return G.Graph(
        title="Filesystem Usage",
        dataSource=datasource,

        xAxis=X_TIME,
        yAxes=[
            G.YAxis(
                format="percent",
            ),
            G.YAxis(
                show=False,
            ),
        ],
        targets=[
            G.Target(
                # Get the proportion used of each filesystem on a volume from
                # a PersistentVolumeClaim on each node of the cluster.  It's
                # hard to figure out the role each filesystem serves from this
                # graph (since all we get is the PVC name).  Better than
                # nothing, though.  Hopefully later we can do better.
                expr="""
                100
                * filesystem_used_bytes{volume=~"pvc-.*"}
                / filesystem_size_bytes{volume=~"pvc-.*"}
                """,
                legendFormat="{{volume}}",
                refId="A",
            ),
        ],
    )
示例#11
0
 def api_call_latency(title, verb, scope, threshold):
     return d.Graph(
         title=title,
         targets=[
             g.Target(expr=str(threshold), legendFormat="threshold"),
             g.Target(
                 expr=d.one_line(expression % {
                     "verb": verb,
                     "scope": scope
                 }),
                 # TODO(github.com/grafana/grafana/issues/19410): uncomment once fixed
                 # legendFormat="{{verb}} {{scope}}/{{resource}}",
             ),
         ],
         yAxes=g.single_y_axis(format=g.SECONDS_FORMAT),
     )
示例#12
0
def test_auto_id():
    """auto_panel_ids() provides IDs for all panels without IDs already set."""
    dashboard = G.Dashboard(
        title="Test dashboard",
        rows=[
            G.Row(panels=[
                G.Graph(
                    title="CPU Usage by Namespace (rate[5m])",
                    dataSource="My data source",
                    targets=[
                        G.Target(
                            expr='whatever',
                            legendFormat='{{namespace}}',
                            refId='A',
                        ),
                    ],
                    yAxes=[
                        G.YAxis(format=G.SHORT_FORMAT, label="CPU seconds"),
                        G.YAxis(format=G.SHORT_FORMAT),
                    ],
                )
            ]),
        ],
    ).auto_panel_ids()
    assert dashboard.rows[0].panels[0].id == 1
示例#13
0
def api_call_latency(title, metric, verb, scope, limit):
    return d.Graph(
        title=title,
        targets=[
            g.Target(expr=str(limit), legendFormat="limit"),
            g.Target(
                expr=
                'quantile_over_time(0.99, %(metric)s{quantile="0.99", verb=~"%(verb)s", scope=~"%(scope)s"}[12h])'
                % {
                    "metric": metric,
                    "verb": verb,
                    "scope": scope
                }),
        ],
        yAxes=g.single_y_axis(format=g.SECONDS_FORMAT),
    )
示例#14
0
def test_table():
    t = G.Table(
        dataSource='some data source',
        targets=[
            G.Target(expr='some expr'),
        ],
        title='table title',
        transformations=[
            {
                "id": "seriesToRows",
                "options": {}
            },
            {
                "id": "organize",
                "options": {
                    "excludeByName": {
                        "Time": True
                    },
                    "indexByName": {},
                    "renameByName": {
                        "Value": "Dummy"
                    }
                }
            }
        ]
    )
    assert len(t.to_json_data()['transformations']) == 2
    assert t.to_json_data()['transformations'][0]["id"] == "seriesToRows"
示例#15
0
def dummy_alert_condition() -> G.AlertCondition:
    return G.AlertCondition(
        target=G.Target(),
        evaluator=G.Evaluator(type=G.EVAL_GT, params=42),
        timeRange=G.TimeRange(from_time='5m', to_time='now'),
        operator=G.OP_AND,
        reducerType=G.RTYPE_AVG,
    )
示例#16
0
def show_quantiles(queryTemplate, quantiles=None, legend=""):
    quantiles = quantiles or QUANTILES
    targets = []
    for quantile in quantiles:
        q = "{:.2f}".format(quantile)
        l = legend or q
        targets.append(g.Target(expr=queryTemplate.format(quantile=q), legendFormat=l))
    return targets
示例#17
0
def test_stat_no_repeat():
    t = G.Stat(title='dummy',
               dataSource='data source',
               targets=[G.Target(expr='some expr')])

    assert t.to_json_data()['repeat'] is None
    assert t.to_json_data()['repeatDirection'] is None
    assert t.to_json_data()['maxPerRow'] is None
示例#18
0
def min_max_avg(base, by, legend=""):
    return [
        g.Target(
            expr="{func}({query}) by ({by})".format(func=f,
                                                    query=base,
                                                    by=", ".join(by)),
            legendFormat="{func} {legend}".format(func=f, legend=legend),
        ) for f in ("min", "avg", "max")
    ]
示例#19
0
def test_stat_with_repeat():
    t = G.Stat(title='dummy',
               dataSource='data source',
               targets=[G.Target(expr='some expr')],
               repeat=G.Repeat(variable="repetitionVariable",
                               direction='h',
                               maxPerRow=10))

    assert t.to_json_data()['repeat'] == 'repetitionVariable'
    assert t.to_json_data()['repeatDirection'] == 'h'
    assert t.to_json_data()['maxPerRow'] == 10
示例#20
0
def simple_graph(title, exprs, yAxes=None, legend=""):
    if not isinstance(exprs, (list, tuple)):
        exprs = [exprs]
    if legend != "" and len(exprs) != 1:
        raise ValueError("legend can be specified only for a 1-element exprs")
    return Graph(
        title=title,
        # One graph per row.
        targets=[g.Target(expr=expr, legendFormat=legend) for expr in exprs],
        yAxes=yAxes or g.YAxes(),
    )
def simple_graph(title, exprs, yAxes=None):
    if not isinstance(exprs, (list, tuple)):
        exprs = [exprs]
    return g.Graph(
        title=title,
        dataSource="$source",
        # One graph per row.
        span=g.TOTAL_SPAN,
        targets=[g.Target(expr=expr) for expr in exprs],
        yAxes=yAxes or g.YAxes(),
        tooltip=DECREASING_ORDER_TOOLTIP,
    )
def api_call_latency(title, verb, scope, threshold):
    return d.Graph(
        title=title,
        targets=[
            g.Target(expr=str(threshold), legendFormat="threshold"),
            g.Target(
                expr=d.one_line("""
apiserver:apiserver_request_latency_1m:histogram_quantile{
  quantile="0.99",
  verb=~"%(verb)s",
  scope=~"%(scope)s",
  resource=~"${resource:regex}s*",
}""" % {
                    "verb": verb,
                    "scope": scope
                }),
                # TODO(github.com/grafana/grafana/issues/19410): uncomment once fixed
                # legendFormat="{{verb}} {{scope}}/{{resource}}",
            ),
        ],
        yAxes=g.single_y_axis(format=g.SECONDS_FORMAT),
    )
    def run(self):
        templateList = [
            G.Template(default="",
                       dataSource="default",
                       name="serverid",
                       label="ServerID",
                       query="label_values(serverid)")
        ]

        dashboard = G.Dashboard(title=self.options.title,
                                templating=G.Templating(list=templateList))

        # Simple table processing - could be enhanced to use GridPos etc.
        for metric in metrics:
            if 'section' in metric:
                dashboard.rows.append(
                    G.Row(title=metric['section'], showTitle=True))
                continue
            if 'row' in metric:
                dashboard.rows.append(G.Row(title='', showTitle=False))
                continue
            graph = G.Graph(title=metric['title'],
                            dataSource='default',
                            maxDataPoints=1000,
                            legend=G.Legend(show=True,
                                            alignAsTable=True,
                                            min=True,
                                            max=True,
                                            avg=True,
                                            current=True,
                                            total=True,
                                            sort='max',
                                            sortDesc=True),
                            yAxes=G.single_y_axis())
            ref_id = 'A'
            for texp in metric['expr']:
                graph.targets.append(G.Target(expr=texp, refId=ref_id))
                ref_id = chr(ord(ref_id) + 1)
            dashboard.rows[-1].panels.append(graph)

        # Auto-number panels - returns new dashboard
        dashboard = dashboard.auto_panel_ids()

        s = io.StringIO()
        write_dashboard(dashboard, s)
        print("""{
        "dashboard": %s
        }
        """ % s.getvalue())
示例#24
0
def simple_graph(title, exprs, legend="", interval="5s", **kwargs):
    if not isinstance(exprs, (list, tuple)):
        exprs = [exprs]
    if legend != "" and len(exprs) != 1:
        raise ValueError("legend can be specified only for a 1-element exprs")
    return Graph(
        title=title,
        # One graph per row.
        targets=[
            g.Target(expr=expr,
                     legendFormat=legend,
                     interval=interval,
                     intervalFactor=1) for expr in exprs
        ],
        **kwargs)
def network_usage(datasource):
    return G.Graph(
        title="Network Usage",
        dataSource=datasource,

        xAxis=X_TIME,
        yAxes=[
            G.YAxis(
                # 2^20 bytes / second
                format="MBs",
                label="Transferred",
            ),
            G.YAxis(
                show=False,
            ),
        ],
        targets=[
            G.Target(
                # Get the rate of data received on the public interface (eth0)
                # for each entire node (id="/") over the last minute.
                expr="""
                receive:container_network_bytes:rate1m / 2 ^ 20
                """,
                legendFormat="receive",
                refId="A",
            ),
            G.Target(
                # And rate of data sent.
                expr="""
                transmit:container_network_bytes:rate1m / 2 ^ 20
                """,
                legendFormat="transmit",
                refId="B",
            ),
        ],
    )
示例#26
0
def _row(title):
    return core.Row(panels=[
        core.Graph(title=title,
                   dataSource='prometheus',
                   targets=[
                       core.Target(
                           expr=title,
                           legendFormat='{{namespace}}',
                       ),
                   ],
                   yAxes=[
                       core.YAxis(format=core.NO_FORMAT),
                       core.YAxis(format=core.SHORT_FORMAT),
                   ])
    ])
示例#27
0
def test_graph_panel_alert():
    data_source = 'dummy data source'
    targets = ['dummy_prom_query']
    title = 'dummy title'
    alert = [
        G.AlertCondition(G.Target(), G.Evaluator('a', 'b'), G.TimeRange('5', '6'), 'd', 'e')
    ]
    thresholds = [
        G.GraphThreshold(20.0),
        G.GraphThreshold(40.2, colorMode="ok")
    ]
    graph = G.Graph(data_source, targets, title, thresholds=thresholds, alert=alert)
    data = graph.to_json_data()
    assert data['targets'] == targets
    assert data['datasource'] == data_source
    assert data['title'] == title
    assert data['alert'] == alert
    assert data['thresholds'] == []
示例#28
0
def test_table_styled_columns():
    t = G.Table.with_styled_columns(
        columns=[
            (G.Column('Foo', 'foo'), G.ColumnStyle()),
            (G.Column('Bar', 'bar'), None),
        ],
        dataSource='some data source',
        targets=[
            G.Target(expr='some expr'),
        ],
        title='table title',
    )
    assert t.columns == [
        G.Column('Foo', 'foo'),
        G.Column('Bar', 'bar'),
    ]
    assert t.styles == [
        G.ColumnStyle(pattern='Foo'),
    ]
def cpu_usage(datasource, intervals):
    return G.Graph(
        title="CPU usage",
        dataSource=datasource,

        xAxis=X_TIME,
        yAxes=[
            G.YAxis(
                format="percent",
                label="Average",
                min=0,
                max=100,
            ),
            G.YAxis(
                format="percent",
                label="Average",
            ),
        ],
        targets=list(
            G.Target(
                # CPU usage (as a percentage of maximum possible) averaged
                # over a period is given as 100 times the sum (over all
                # containers) of the rate of increase (in seconds) divided by
                # the maximum possible increase (1 second per CPU).
                #
                # The sums are taken from recording rules because recomputing
                # them for every point on the graph for every graph request
                # becomes prohitively expensive.  Only a few specific rates
                # are "recorded" and the ``interval`` parameter must match one
                # of those. :(
                #
                # See prometheus.yaml for the recording rules.
                expr="""
                  100
                * cpu:container_usage_seconds:rate{}
                / cores:machine_cpu:total
                """.format(interval),
                legendFormat="CPU Usage ({} avg)".format(interval),
                refId=refId(n),
            )
            for n, interval in enumerate(intervals),
        ),
    )
示例#30
0
def test_serialization():
    """Serializing a graph doesn't explode."""
    graph = G.Graph(
        title="CPU Usage by Namespace (rate[5m])",
        dataSource="My data source",
        targets=[
            G.Target(
                expr='namespace:container_cpu_usage_seconds_total:sum_rate',
                legendFormat='{{namespace}}',
                refId='A',
            ),
        ],
        id=1,
        yAxes=[
            G.YAxis(format=G.SHORT_FORMAT, label="CPU seconds / second"),
            G.YAxis(format=G.SHORT_FORMAT),
        ],
    )
    stream = StringIO()
    _gen.write_dashboard(graph, stream)
    assert stream.getvalue() != ''