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' dashboard = G.Dashboard( title="Test dashboard", 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', ), G.Target(expr='another target'), ], yAxes=G.YAxes( G.YAxis(format=G.SHORT_FORMAT, label="CPU seconds"), G.YAxis(format=G.SHORT_FORMAT), ), gridPos=G.GridPos(h=1, w=24, x=0, y=8)).auto_ref_ids() ], ).auto_panel_ids() assert dashboard.panels[0].targets[0].refId == 'A' assert dashboard.panels[0].targets[1].refId == 'Q' assert dashboard.panels[0].targets[2].refId == 'B'
def Dashboard( title, version, time, rows, graphTooltip=0, templating=None, ): optional_args = {} if templating is not None: optional_args['templating'] = templating return core.Dashboard( title=title, refresh=None, schemaVersion=14, version=version, time=time, timezone='browser', inputs=[ { 'name': 'DS_PROMETHEUS', 'label': 'prometheus', 'description': '', 'type': 'datasource', 'pluginId': 'prometheus', 'pluginName': 'Prometheus' }, ], rows=rows, graphTooltip=graphTooltip, **optional_args, )
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'
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
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())
def GenerateDashboard(self): return core.Dashboard(title=self.title, refresh='1s', time=core.Time('now-5m', 'now'), timePicker=core.TimePicker(refreshIntervals=[ '1s', '3s', '10s', '30s', ], timeOptions=[ '5m', '15m', '1h', '6h', '12h', '24h', '2d', ]), panels=self.panels).auto_panel_ids()
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])", targets=[G.Target(expr="metric %d" % i) for i in range(53)], ).auto_ref_ids() ]), ], ) assert dashboard.rows[0].panels[0].targets[0].refId == 'A' assert dashboard.rows[0].panels[0].targets[25].refId == 'Z' assert dashboard.rows[0].panels[0].targets[26].refId == 'AA' assert dashboard.rows[0].panels[0].targets[51].refId == 'AZ' assert dashboard.rows[0].panels[0].targets[52].refId == 'BA'
def Dashboard(**kwargs): """Standard Weave Cloud dashboard. Automatically sets panel ids and applies events from Weave Cloud as annotations. """ defaultTemplates = [G.Template( label="Datasource", name="datasource", type="datasource", query="prometheus", )] if "templating" in kwargs: extraTemplates = kwargs["templating"].list else: extraTemplates = [] kwargs["templating"] = G.Templating(list=defaultTemplates + extraTemplates) return G.Dashboard( refresh='1m', # Override the default of 10s **kwargs ).auto_panel_ids()
import grafanalib.core as G dashboard = G.Dashboard( title='Test dashboard', panels=[ G.Graph(title='CPU Usage by Namespace', dataSource='metricbeat', 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), ], gridPos=G.GridPos(h=8, w=12, x=0, y=0)) ], ).auto_panel_ids()
dashboard = g.Dashboard( title="Master dashboard", time=g.Time("now-30d", "now"), templating=g.Templating(list=[ # Make it possible to use $source as a source. g.Template(name="source", type="datasource", query="prometheus") ]), rows=[ g.Row( title="Clusterloader", height=DEFAULT_PANEL_HEIGHT, panels=CLUSTERLOADER_PANELS, ), g.Row( title="Overall cluster health", height=DEFAULT_PANEL_HEIGHT, panels=HEALTH_PANELS, ), g.Row(title="etcd", height=DEFAULT_PANEL_HEIGHT, panels=ETCD_PANELS), g.Row(title="kube-apiserver", height=DEFAULT_PANEL_HEIGHT, panels=APISERVER_PANELS), g.Row( title="kube-controller-manager", height=DEFAULT_PANEL_HEIGHT, panels=[ simple_graph( "Workqueue depths", 'workqueue_depth{endpoint="kube-controller-manager"}', legend="{{name}}", ) ], ), g.Row(title="Master VM", height=DEFAULT_PANEL_HEIGHT, panels=VM_PANELS), g.Row( title="Addons", height=DEFAULT_PANEL_HEIGHT, panels=[ g.Graph( title="Coredns memory", dataSource="$source", targets=[ g.Target( expr= 'quantile(1, sum(process_resident_memory_bytes{job="kube-dns"}) by (pod))', legendFormat="coredns-mem-100pctl", ), g.Target( expr= 'quantile(0.99, sum(process_resident_memory_bytes{job="kube-dns"}) by (pod))', legendFormat="coredns-mem-99ctl", ), g.Target( expr= 'quantile(0.90, sum(process_resident_memory_bytes{job="kube-dns"}) by (pod))', legendFormat="coredns-mem-90ctl", ), g.Target( expr= 'quantile(0.50, sum(process_resident_memory_bytes{job="kube-dns"}) by (pod))', legendFormat="coredns-mem-50ctl", ), ], yAxes=g.single_y_axis(format=g.BYTES_FORMAT), ) ], ), ], ).auto_panel_ids()
"hide": True, "iconColor": "rgba(0, 211, 255, 1)", "name": name, "type": "dashboard" }]) 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), ]) ]) dashboard = core.Dashboard( title='hogehoge', uid="XK5tCdAWk", annotations=_annotations('Annotations & Alerts'), rows=[_row('title')], ).auto_panel_ids()
def dashboard(): PROMETHEUS = "prometheus" return G.Dashboard( title="S4", rows=[ G.Row(panels=[ G.Graph( title="Signups", dataSource=PROMETHEUS, xAxis=X_TIME, yAxes=[ G.YAxis( format="none", label="Count", ), G.YAxis( format="none", label="Count", ), ], targets=[ G.Target( # Filter down to just the signup pod since that's # the only one where this metric value is # meaningful. Some other pods report a 0 value # for this metric because they happen to import # the Python code that defines the object # representing it. # # Also, sum over the selected series to account # for pod replacement. expr='sum(wormhole_signup_started{pod=~"s4-signup.*"})', legendFormat="Wormhole Signups Started", refId="A", ), G.Target( expr='sum(wormhole_signup_success{pod=~"s4-signup.*"})', legendFormat="Wormhole Signups Completed", refId="B", ), G.Target( expr='sum(wormhole_signup_failure{pod=~"s4-signup.*"})', legendFormat="Wormhole Signups Failed", refId="C", ), ], ), G.Graph( title="Usage", dataSource=PROMETHEUS, # Stack the connection graphs on each other, revealing # both a total and a distribution across different grid # router instances. stack=True, tooltip=G.Tooltip( valueType=G.INDIVIDUAL, ), xAxis=X_TIME, yAxes=[ G.YAxis( format="none", label="Count", ), G.YAxis( format="none", label="Count", ), ], targets=[ G.Target( expr="grid_router_connections", legendFormat="Tahoe-LAFS Connections", refId="D", ), ], ), last_convergence(PROMETHEUS), ]), G.Row( title="Cluster", panels=[ cpu_usage(PROMETHEUS, ["1m", "5m", "10m"]), memory_usage(PROMETHEUS), network_usage(PROMETHEUS), filesystem_usage(PROMETHEUS), ], ), G.Row( title="Cluster2", panels=[ process_open_fds(PROMETHEUS), ], ), G.Row(panels=[ tahoe_lafs_transfer_rate(PROMETHEUS), s4_customer_deployments(PROMETHEUS), unhandled_errors(PROMETHEUS), ]), ], ).auto_panel_ids()
def dashboard(): PROMETHEUS = "prometheus" return G.Dashboard( title="S4", rows=[ G.Row(panels=[ G.Graph( title="Signups", dataSource=PROMETHEUS, xAxis=X_TIME, yAxes=[ G.YAxis( format="none", label="Count", ), G.YAxis( format="none", label="Count", ), ], targets=[ G.Target( expr='wormhole_signup_started{pod=~"s4-signup.*"}', legendFormat="Wormhole Signups Started", refId="A", ), G.Target( expr='wormhole_signup_success{pod=~"s4-signup.*"}', legendFormat="Wormhole Signups Completed", refId="B", ), G.Target( expr='wormhole_signup_failure{pod=~"s4-signup.*"}', legendFormat="Wormhole Signups Failed", refId="C", ), ], ), G.Graph( title="Usage", dataSource=PROMETHEUS, # Stack the connection graphs on each other, revealing # both a total and a distribution across different grid # router instances. stack=True, tooltip=G.Tooltip( valueType=G.INDIVIDUAL, ), xAxis=X_TIME, yAxes=[ G.YAxis( format="none", label="Count", ), G.YAxis( format="none", label="Count", ), ], targets=[ G.Target( expr="grid_router_connections", legendFormat="Tahoe-LAFS Connections", refId="D", ), ], ), ]), G.Row( title="Cluster", panels=[ cpu_usage(PROMETHEUS, ["1m", "5m", "10m"]), memory_usage(PROMETHEUS), network_usage(PROMETHEUS), filesystem_usage(PROMETHEUS), ], ), G.Row(panels=[ G.SingleStat( title='Current Customer Deployments', dataSource='prometheus', valueName='current', sparkline=G.SparkLine(show=True), targets=[ G.Target( expr='s4_deployment_gauge', refId="E", ), ], ), G.SingleStat( title='Unhandled Errors', dataSource='prometheus', valueName='current', sparkline=G.SparkLine(show=True), targets=[ G.Target( expr='s4_unhandled_error_counter', refId="F", ), ], ), ]), ], ).auto_panel_ids()
dashboard = G.Dashboard( title="System health", rows=[ G.Row(title="Service status", panels=[ G.SingleStat( editable=True, colorBackground=True, colorValue=False, colors=[G.ORANGE, G.GREEN, G.RED], dataSource="Prometheus", gauge=G.Gauge( maxValue=100, minValue=0, show=False, thresholdLabels=False, thresholdMarkers=True, ), title=app["name"], targets=[ G.Target( expr='up{{instance="{hostname}:{port}"}}'.format( hostname=app["hostname"], port=app["port"]), intervalFactor=2, legendFormat="", step=4, ) ], span=2, thresholds="0.1", transparent=True, valueMaps=[ G.ValueMap(op="=", text="N/A", value="null"), G.ValueMap(op="=", text="Down", value="0"), G.ValueMap(op="=", text="Up", value="1"), ], sparkline=G.SparkLine( fillColor=G.RGBA(31, 118, 109, 0.18), full=False, lineColor=G.RGB(31, 120, 193), show=False, ), rangeMaps=[G.RangeMap(start=None, text="N/A", end=None)], valueName="current", ) for app in APPS ]) ], ).auto_panel_ids()
dashboard = G.Dashboard( title='UCDAPI', rows=[ G.Row(panels=[ G.SingleStat( title='Pods Up', dataSource='prometheus', valueName='current', sparkline=G.SparkLine(show=True), targets=[ G.Target( expr='count by(service) (up{service="ucdapi"} == 1)', ) ]), ]), G.Row(panels=[ G.Graph( title='HTTP RPS', dataSource='prometheus', targets=[ G.Target( expr= 'service_status:http_request_duration_seconds_count:irate{service="ucdapi",status_code=~"1.."}', legendFormat='1xx', refId='A'), G.Target( expr= 'service_status:http_request_duration_seconds_count:irate{service="ucdapi",status_code=~"2.."}', legendFormat='2xx', refId='B'), G.Target( expr= 'service_status:http_request_duration_seconds_count:irate{service="ucdapi",status_code=~"3.."}', legendFormat='3xx', refId='C'), G.Target( expr= 'service_status:http_request_duration_seconds_count:irate{service="ucdapi",status_code=~"4.."}', legendFormat='4xx', refId='D'), G.Target( expr= 'service_status:http_request_duration_seconds_count:irate{service="ucdapi",status_code=~"5.."}', legendFormat='5xx', refId='E'), ], aliasColors=ALIAS_COLORS, yAxes=[ G.YAxis(format=G.OPS_FORMAT), G.YAxis(format=G.SHORT_FORMAT, show=False) ], nullPointMode=G.NULL_AS_ZERO, stack=True, lineWidth=0, fill=10, tooltip=G.Tooltip(valueType=G.INDIVIDUAL)), G.Graph( title='RPS', dataSource='prometheus', targets=[ G.Target( expr= 'sum(irate(http_request_duration_seconds_count{service="ucdapi"}[1m])) by (status_code, method)', ), ], yAxes=[ G.YAxis(format=G.OPS_FORMAT), G.YAxis(format=G.SHORT_FORMAT), ]), ]), G.Row(panels=[ G.Graph( title='Latency 0.9q', dataSource='prometheus', targets=[ G.Target( expr= 'http_request_duration_seconds{quantile="0.9",status_code="200",service="ucdapi"}*1000', legendFormat='{{pod}}', refId='A', ), ], yAxes=[ G.YAxis(format=G.MILLISECONDS_FORMAT), G.YAxis(format=G.SHORT_FORMAT, show=False), ]), G.Graph( title='Latency 0.99q', dataSource='prometheus', targets=[ G.Target( expr= 'http_request_duration_seconds{quantile="0.99",status_code="200",service="ucdapi"}*1000', legendFormat='{{pod}}', refId='A', ), ], yAxes=[ G.YAxis(format=G.MILLISECONDS_FORMAT), G.YAxis(format=G.SHORT_FORMAT, show=False), ]), ]), ]).auto_panel_ids()
def make(prefix, title): def target(expr, **kw): return G.Target(expr=expr.format(prefix), **kw) return G.Dashboard( title=title, rows=[ G.Row(panels=[ G.SingleStat( title='Pods up (web)', dataSource='prometheus', valueName='current', sparkline=G.SparkLine(show=True), targets=[ target( expr= 'count by(service) (up{{service="{}-isaacranks-web"}} == 1)' ) ]), G.SingleStat( title='Pods up (rebuild)', dataSource='prometheus', valueName='current', sparkline=G.SparkLine(show=True), targets=[ target( expr= 'count by(service) (up{{service="{}-isaacranks-rebuild"}} == 1)' ) ]), ]), G.Row(panels=[ G.Graph( title='HTTP RPS', dataSource='prometheus', targets=[ target( expr= 'service_status:http_request_duration_seconds_count:irate{{service="{}-isaacranks-web",status_code=~"1.."}}', legendFormat='1xx', refId='A'), target( expr= 'service_status:http_request_duration_seconds_count:irate{{service="{}-isaacranks-web",status_code=~"2.."}}', legendFormat='2xx', refId='B'), target( expr= 'service_status:http_request_duration_seconds_count:irate{{service="{}-isaacranks-web",status_code=~"3.."}}', legendFormat='3xx', refId='C'), target( expr= 'service_status:http_request_duration_seconds_count:irate{{service="{}-isaacranks-web",status_code=~"4.."}}', legendFormat='4xx', refId='D'), target( expr= 'service_status:http_request_duration_seconds_count:irate{{service="{}-isaacranks-web",status_code=~"5.."}}', legendFormat='5xx', refId='E'), ], aliasColors=ALIAS_COLORS, yAxes=[ G.YAxis(format=G.OPS_FORMAT), G.YAxis(format=G.SHORT_FORMAT, show=False) ], nullPointMode=G.NULL_AS_ZERO, stack=True, lineWidth=0, fill=10, tooltip=G.Tooltip(valueType=G.INDIVIDUAL)), G.Graph( title='HTTP latency', dataSource='prometheus', targets=[ target( expr= 'service:http_request_duration_seconds:50p{{service="{}-isaacranks-web"}} * 1000', legendFormat='0.5q', refId='A'), target( expr= 'service:http_request_duration_seconds:90p{{service="{}-isaacranks-web"}} * 1000', legendFormat='0.9q', refId='B'), target( expr= 'service:http_request_duration_seconds:99p{{service="{}-isaacranks-web"}} * 1000', legendFormat='0.99q', refId='C'), ], aliasColors=ALIAS_COLORS, yAxes=[ G.YAxis(format=G.MILLISECONDS_FORMAT), G.YAxis(format=G.SHORT_FORMAT, show=False) ]), ]), G.Row(panels=[ G.Graph( title='Ballots', dataSource='prometheus', targets=[ target( expr= 'service_version:isaacranks_ballot_generation_seconds_count:irate{{service="{}-isaacranks-web"}}', legendFormat='{{version}}', refId='A') ], yAxes=[ G.YAxis(format=G.OPS_FORMAT), G.YAxis(format=G.SHORT_FORMAT, show=False), ], nullPointMode=G.NULL_AS_ZERO, stack=True, lineWidth=0, fill=10, tooltip=G.Tooltip(valueType=G.INDIVIDUAL)), G.Graph( title='Ballot latency', dataSource='prometheus', targets=[ target( expr= 'service:isaacranks_ballot_generation_seconds:50p{{service="{}-isaacranks-web"}} * 1000', legendFormat='0.5q', refId='A'), target( expr= 'service:isaacranks_ballot_generation_seconds:90p{{service="{}-isaacranks-web"}} * 1000', legendFormat='0.9q', refId='B'), target( expr= 'service:isaacranks_ballot_generation_seconds:99p{{service="{}-isaacranks-web"}} * 1000', legendFormat='0.99q', refId='C'), ], yAxes=[ G.YAxis(format=G.MILLISECONDS_FORMAT), G.YAxis(format=G.SHORT_FORMAT, show=False) ]), ]), G.Row(panels=[ G.Graph( title='Votes', dataSource='prometheus', targets=[ target( expr= 'service_version:isaacranks_vote_casting_seconds_count:irate{{service="{}-isaacranks-web"}}', legendFormat='{{version}}', refId='A') ], yAxes=[ G.YAxis(format=G.OPS_FORMAT), G.YAxis(format=G.SHORT_FORMAT, show=False) ], nullPointMode=G.NULL_AS_ZERO, stack=True, lineWidth=0, fill=10, tooltip=G.Tooltip(valueType=G.INDIVIDUAL)), G.Graph( title='Vote latency', dataSource='prometheus', targets=[ target( expr= 'service:isaacranks_vote_casting_seconds:50p{{service="{}-isaacranks-web"}} * 1000', legendFormat='0.5q', refId='A'), target( expr= 'service:isaacranks_vote_casting_seconds:90p{{service="{}-isaacranks-web"}} * 1000', legendFormat='0.9q', refId='B'), target( expr= 'service:isaacranks_vote_casting_seconds:99p{{service="{}-isaacranks-web"}} * 1000', legendFormat='0.99q', refId='C'), ], yAxes=[ G.YAxis(format=G.MILLISECONDS_FORMAT), G.YAxis(format=G.SHORT_FORMAT, show=False) ]), ]), G.Row(panels=[ G.Graph( title='Time since last rebuild', dataSource='prometheus', targets=[ target( expr= 'time() - (isaacranks_last_rebuild_timestamp{{service="{}-isaacranks-rebuild"}} != 0)', legendFormat='Age') ], legend=G.Legend(current=True), yAxes=[ G.YAxis(format=G.SECONDS_FORMAT), G.YAxis(format=G.SHORT_FORMAT, show=False) ]), G.Graph( title='Rebuild duration', dataSource='prometheus', targets=[ target( expr= 'isaacranks_last_rebuild_duration_seconds{{service="{}-isaacranks-rebuild"}} != 0', legendFormat='Duration') ], legend=G.Legend(current=True), yAxes=[ G.YAxis(format=G.SECONDS_FORMAT), G.YAxis(format=G.SHORT_FORMAT, show=False) ]), ]) ]).auto_panel_ids()
def run(self): templateList = [] if self.options.use_sdp: templateList.append( G.Template(default="1", dataSource="default", name="sdpinst", label="SDPInstance", query="label_values(sdpinst)")) if self.options.customer: templateList.append( G.Template(default="1", dataSource="default", name="customer", label="Customer", query="label_values(customer)")) templateList.append( 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)) 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 if 'type' in metric and metric['type'] == 'gauge': pass # text = G.Text(title=metric['title'], # dataSource='default') # dashboard.rows[-1].panels.append(G.Text) else: yAxis = G.single_y_axis(format="short") if 'yformat' in metric: yAxis = G.single_y_axis(format=metric['yformat']) 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=yAxis) refId = 'A' for targ in metric['target']: texp = targ['expr'] legend = "instance {{instance}}, serverid {{serverid}}" if 'legend' in targ: legend += ' %s' % targ['legend'] # Remove SDP if not self.options.use_sdp: texp = texp.replace('sdpinst="$sdpinst",', '') if self.options.customer: texp = texp.replace('{', '{customer="$customer",') graph.targets.append( G.Target(expr=texp, legendFormat=legend, refId=refId)) refId = chr(ord(refId) + 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())