Giter VIP home page Giter VIP logo

grafonnet's Introduction

Grafonnet

Jsonnet library for generating Grafana dashboards.

Introduction

This library is generated from OpenAPI documents in grafana-foundation-sdk, these are generated from the Grafana repository to ensure Grafonnet can keep up with Grafana development.

Grafonnet is the spiritual successor of grafonnet-lib. As grafonnet-lib was manually written, it had a hard time to keep up with Grafana development, this resulted in it being under-maintained. Besides that, it also came with a performance penalty in jsonnet as it used the builder pattern, although visually appealing it becomes very slow for environments that need to manage many dashboards.

This library is experimental

The code in this repository should be considered experimental. Documentation is only available alongside the code. It comes without support, but we are keen to receive feedback on the product and suggestions on how to improve it, though we cannot commit to resolution of any particular issue. No SLAs are available. It is not meant to be used in production environments, and the risks are unknown/high.

Additional information can be found in Release life cycle for Grafana Labs.

Requirements

Grafonnet uses the Jsonnet programming language.

NOTE: There is a significant performance issue with the C implementation of Jsonnet. You are strongly recommended to use the newer go-jsonnet Jsonnet implementation. This is also the implementation recommended by the Jsonnet developers themselves.

The library can be installed with jsonnet-bundler.

Install

To add grafonnet to a jsonnet project:

jb install github.com/grafana/grafonnet/gen/grafonnet-latest@main

Usage

// dashboard.jsonnet
local grafonnet = import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet';

grafonnet.dashboard.new('My Dashboard')
jsonnet -J vendor dashboard.jsonnet

grafonnet's People

Contributors

breitreiter avatar consideratio avatar diebauer avatar duologic avatar isarns avatar jan-xyz avatar k-phoen avatar malcolmholmes avatar sebhoss avatar v-zhuravlev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

grafonnet's Issues

Support panels queries reuse (`-- Dashboard --` datasource)

We want to reduce load on the backend, for that we want to use share-query Grafana feature:
https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/share-query/
https://grafana.com/blog/2020/10/14/learn-grafana-share-query-results-between-panels-to-reduce-load-time/

Here is how i did before new grafonnet(hackish):
https://github.com/go-gitea/gitea/blob/main/contrib/gitea-monitoring-mixin/dashboards/overview.libsonnet#L275-L292
Unfortunately, can't assign static id to the panel, as it get overridden by
g.dashboard.withPanels().

Perhaps, when dashboard is created with grafonnet id can be kept if it is already present in the panel?

makeGrid with startY issues

I'm using the latest version

import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet'

and trying to make use of calling the new functionality of the grid.makeGrid function twice with the startY parameter but it does not appear to be working for me.

The first row and panels created are positioned correctly but the second call to makeGrid with the startY parameter leaves the
gridPos.y = 0 for the next row and the below panels are spaced correctly with a gridPos.y = 1

This causes all of the panels to exist under the second row.

Generating the dashboard is taking around 3-5 minutes.

Hello team, I am trying to migrate some template dashboards that I have but now with the new grafonet version.

Here are the instructions I am following to install:

jb init
jb install github.com/grafana/grafonnet/gen/grafonnet-latest@main

Here is the command to generate the dashboard.

jsonnet -J vendor dashboard.jsonnet >> mydashboard.json

dashboard.jsonnet

local grafonnet = import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet';

grafonnet.dashboard.new('My Dashboard')

This is a basic dashboard only for a POC.

My questions are:

1.- When I am generating the dashboard is taking around 3-5 minutes. Is it normal? Is there a way to run in debug/verbose mode?
2.- Are there examples that can I follow to migrate to the new grafonet version?

Adding Cloudwatch target in Grafonnet v9.4.0

Hello team!

I'm using the new Grafonnet version (9.4.0), and I identified that adding a new target in the panel is different compared with the old version. In the oldest Grafonnet version, the way that I followed to add a new target in the panel was by using the following function:

.addTargets(
    [
      cloudwatch.target(
        region='$region',
        namespace='AWS/RDS',
        metric=metric_one,
        datasource='$datasource',
        statistic=statistic_one,
        dimensions={ DBInstanceIdentifier: '$dbName' }
      )
    ]

But in the new Grafonnet version (9.4.0), I found that it is necessary to use the grafonnet.query.cloudwatch subpackage to write a query. In the examples folder, I see a grafonnet.query.prometheus example:

prometheusQuery.new(
      '$' + variables.datasource.name,
      |||
        sum by (cluster, namespace, job) (
            rate(
                process_cpu_seconds_total{
                    cluster=~"$cluster",
                    namespace=~"$namespace",
                    job=~"$job"
                }
            [$__rate_interval])
        )
      |||
    ) 

Do you know if there is a way to "translate" the Builder configuration to a Code option to use the query subpackage?

image

Also, if you have an example using grafonnet.query.cloudwatch would be a great help.

Thanks in advance!

Non-collapsed row has no panels.

Not sure if it's a Grafonnet bug at all, but I faced it using Grafonnet:

  db.new(input.config.board_title)
  + db.withPanels([
    row.new('Row Name')
    + row.withCollapsed(false)
    + row.withPanels( ... )

If using + row.withCollapsed(false) rows are empty (no panels)
If using + row.withCollapsed(true) panels are in place

There is a workaround in not using rowWithPanels but flattening row and successive panels but it's not very comfortable to use especially with nested for cycles

Overrides matchers are created with another matcher inside

When trying to create overrides with the following jsonnet

local g = import 'github.com/grafana/grafonnet/gen/grafonnet-v9.4.0/main.libsonnet';

local overrides = g.panel.timeSeries.fieldConfig.overrides;

overrides.withMatcher(
    overrides.matcher.withId("id")
    + overrides.matcher.withOptions("options")
) + overrides.withProperties(
    overrides.properties.withId("otherId")
    + overrides.properties.withValue("value")
)

It creates the following json

{
   "matcher": {
      "matcher": {
         "id": "id",
         "options": "options"
      }
   },
   "properties": [
      {
         "id": "otherId",
         "value": "value"
      }
   ]
}

There you can see that the field matcher has a matcher inside of it, and this doesn't happen with properties (initialized in a similar way)

Language server support

The whole grafonnet library is generated by a function which means that language servers can't extract information about the object it returns. For a library of this size it would be great to have autocomplete in editors so that we don't have to tab over to a browser so often. One idea to accomplish this is to use the schema to generate a "documentation overlay" that wraps the generated api with matching function signatures and doc comments. For example:

// grafonnet/gen/grafonnet-vX.Y.Z/main.libsonnet

local grafonnet = import 'github.com/grafana/grafonnet/grafonnet-base/main.libsonnet';
local schemas = import './schemas.libsonnet';
local version = importstr './grafana-version';
local g = grafonnet.new(schemas, version);

{
  panel: {
    timeSeries: {
      // Creates a new timeSeries panel with a title.
      new(title): g.panel.timeSeries.new(title),
      // ..
    },
    // ...
  },
  // ...
}

Error for Unexpected String in dashboard.new title Field

Hiya, I'm not quite sure if this is a jsonnet issue or a grafonnet issue, so I'll start here.

Problem

I'm passing in a title to dashboard.new() like below:

# dashboard.jsonnet

local g = import '../../grafana.libsonnet';
local CONSTANTS = '../constants.libsonnet';
local uids = import '../uids.libsonnet';
local ec2 = import './panels/ec2_metrics.libsonnet';

local create_dashboard(region = "multi_staging_marketing") =
  local region_constants = CONSTANTS.regions[region];
  {
    folderUid: uids.regions[region].folder,
    overwrite: true,
    dashboard: g.dashboard.new(region_constants.name + " - EC2 Metrics")
    + g.dashboard.withTimezone("browser")
    + g.dashboard.graphTooltip.withSharedCrosshair()
    + g.dashboard.withPanels(
      ec2.cpu(region)
    )
  };

{
  "multi-staging-marketing-ec2.json": create_dashboard("multi_staging_marketing")
}

and I'm getting an error that I'm passing in an unexpected string and that it expects a number:
Screenshot 2023-09-26 at 2 19 56 PM

NOTE: The way in which I'm passing through the name of the region and env has been done in other dashboard.jsonnet files and they compile and run just fine. This seems to be an exception of some sort.

I have a constants.libsonnet file that holds all of the identifying information for each region and environment that gets passed through to our dashboard.jsonnet files. It looks like this (the ellipsis redacting sensitive info):

# constants.libsonnet

{
  regions: {
    prod_apac: {
      name: "Prod-APAC",
      ...
    },
    staging_apac: {
      name: "Staging-APAC",
      ...
    },
    staging_eu: {
      name: "Staging-EU",
      ...
    },
    multi_staging_marketing: {
      name: "Multi-Staging Marketing",
      ...
    }
  }
}

I can pass in the title explicitly like so g.dashboard.new("Multi-staging Marketing EC2 Metrics") and it works just fine. Has anyone ran into an issue like this: passing in a typed value to an object that is expecting that type but on runtime is expecting a different type?

Add detailed documentation

Is is possible to have a separate document with a basic documentation and list of all possible panels and what their syntax looks like in Jsonnet format?
Thank you!

Variable width using Grid Util

I've been trying to set a dashboard with panels with different sizes for some panels using the util.grid.makeGrid() function.

+ g.dashboard.withPanels(
  g.util.grid.makeGrid([
    row.new('Metrics')
    + row.withPanels([
      panels.time_series.base('Service Latency', queries.service_latency),
      panels.time_series.base('Endpoint Rate by Service', queries.endpoint_rate_by_service),
      panels.time_series.base('Error Rate', queries.error_rate),
      panels.bar_gauge.base('Top 5 Operations by Rate', queries.top_operations_by_rate),
    ]),
  ] panelWidth=12 )
  + g.util.gird.makeGrid([
    row.new('Node Graph')
    + row.withPanels([
      panels.node_graph.base('Node Graph',queries.node_graph),
    ]),
    row.new('Logs')
    + row.withPanels([
      panels.logs.base('Logs', queries.logs),
    ]),
    row.new('JVM'),
  ], panelWidth=24)
)

I thought that it would work doing something like that but that just scatters all of the panels rather changing the width. I also tried to add the width directly to the panels but seems like the makeGrid() function overrides the values.

I also tried adding them directly as an array like so

+ g.dashboard.withPanels([
    row.new('Metrics')
    + row.withPanels([
      panels.time_series.base('Service Latency', queries.service_latency),
      panels.time_series.base('Endpoint Rate by Service', queries.endpoint_rate_by_service),
      panels.time_series.base('Error Rate', queries.error_rate),
      panels.bar_gauge.base('Top 5 Operations by Rate', queries.top_operations_by_rate),
    ])
    + row.gridPos.withW(24)
    + row.gridPos.withH(8),
    row.new('Node Graph')
    + row.withPanels([
      panels.node_graph.base('Node Graph',queries.node_graph),
    ])
    + row.gridPos.withW(24)
    + row.gridPos.withH(8),
    row.new('Logs')
    + row.withPanels([
      panels.logs.base('Logs', queries.logs),
    ])
    + row.gridPos.withW(24)
    + row.gridPos.withH(8),
    row.new('JVM'),
  ]
)
  base(title, targets):
      nodeGraph.new(title)
      + nodeGraph.withTargets(targets)
      + nodeGraph.withDatasource('$' + variables.tempo_datasource.name)
      + nodeGraph.gridPos.withW(24)
      + nodeGraph.gridPos.withH(8)

But for some reason once they get imported to Grafana the panels get dropped and if I left the timeSeries panels in the definition the dashboard fails to initialize.

Is there a correct way of achieving that?

Field does not exist: multi

Hi! I get:

RUNTIME ERROR: Field does not exist: multi
        vendor/github.com/grafana/grafonnet/gen/grafonnet-v10.2.0/custom/dashboard/variable.libsonnet:100:18-28 function <anonymous>
        vendor/github.com/grafana/grafonnet/gen/grafonnet-v10.2.0/custom/dashboard/variable.libsonnet:106:21-31 object <anonymous>
        Field "text"    
        Field "current" 
        Array element 3 
        Field "list"    
        Field "templating"      
        During manifestation 

the self.multi seems fishy:

withCurrent(key, value=key): {
local multi(v) =
if self.multi
&& std.isArray(v)
then v
else [v],
current: {
selected: false,
text: multi(key),
value: multi(value),
},
},

fieldOverride byQuery renders not valid json

https://grafana.github.io/grafonnet/API/panel/timeSeries/standardOptions/override.html#obj-byquery
Snippet:

        + g.panel.timeSeries.standardOptions.withOverridesMixin(
          [
            // byQuery doesn't work
            g.panel.timeSeries.fieldOverride.byQuery.new('A')
            + g.panel.timeSeries.fieldOverride.byQuery.withPropertiesFromOptions(
              g.panel.timeSeries.standardOptions.withUnit(signal.units.simple),
            ),
          ],
        ),

Gives json:

    "overrides": [
      {
        "matcher": {
          "id": "byQuery",
          "options": "A"
        },
        "properties": [
          {
            "id": "unit",
            "value": "seconds"
          }
        ]
      }
    ]

That returns an error in Grafana:

An unexpected error happened
Error: "byQuery" not found in: byName,byRegexp,byType,byFrameRefID,byNames,byValue

ir@http://grafana.k3d.localhost:9999/public/build/DashboardPageProxy.c428143cac890308b384.js:83:5333
div
div
Or@http://grafana.k3d.localhost:9999/public/build/DashboardPageProxy.c428143cac890308b384.js:204:144
div
i@http://grafana.k3d.localhost:9999/public/build/8474.aca7493112eb29aea9e3.js:1:2302
div
i@http://grafana.k3d.localhost:9999/public/build/8474.aca7493112eb29aea9e3.js:1:4290
_@http://grafana.k3d.localhost:9999/public/build/8474.aca7493112eb29aea9e3.js:1:9613
div
div
div
W@http://grafana.k3d.localhost:9999/public/build/8291.6eb51b53410a9cd7be10.js:404:21371
Xs@http://grafana.k3d.localhost:9999/public/build/DashboardPageProxy.c428143cac890308b384.js:332:531
Connect(Xs)@http://grafana.k3d.localhost:9999/public/build/1663.190becda783f60342f79.js:183:66208
WithTheme(Connect(Xs))
vn@http://grafana.k3d.localhost:9999/public/build/DashboardPageProxy.c428143cac890308b384.js:407:479
DashboardPage
Connect(DashboardPage)@http://grafana.k3d.localhost:9999/public/build/1663.190becda783f60342f79.js:183:66208
To@http://grafana.k3d.localhost:9999/public/build/DashboardPageProxy.c428143cac890308b384.js:407:6445
Suspense
o@http://grafana.k3d.localhost:9999/public/build/8291.6eb51b53410a9cd7be10.js:192:118871
bo@http://grafana.k3d.localhost:9999/public/build/8291.6eb51b53410a9cd7be10.js:349:10002
be@http://grafana.k3d.localhost:9999/public/build/1663.190becda783f60342f79.js:228:23527
uo@http://grafana.k3d.localhost:9999/public/build/1663.190becda783f60342f79.js:209:4760
Jn@http://grafana.k3d.localhost:9999/public/build/1663.190becda783f60342f79.js:209:10242
el@http://grafana.k3d.localhost:9999/public/build/1663.190becda783f60342f79.js:228:11797
be@http://grafana.k3d.localhost:9999/public/build/1663.190becda783f60342f79.js:228:25722
div
div

This workaround works:

        + g.panel.timeSeries.standardOptions.withOverridesMixin(
          [
            // byQuery doesn't work
            {
              matcher: {
                id: 'byFrameRefID',
                options: 'A',
              },
            }
            + g.panel.timeSeries.fieldOverride.byQuery.withPropertiesFromOptions(
              g.panel.timeSeries.standardOptions.withUnit(signal.units.simple),
            ),
          ],
        ),

grafana version 10.3.1

Adding Alert Provisioning

Hi I was curious if the Grafonnet team was going to add Alert Provisioning/Alerting/Alert Rules to dashboards and relating the to panels in the near future?

Options and current missing in dashboard.templating.list

When trying to create a variable with a specific list of values (type=custom), there's no way to set the "current" or "options" field.

Currently I need to write:

    listVariable(label, variableName, values):
        var.new(variableName)
        + var.withLabel(label)
        + var.withMulti(false)
        + var.withIncludeAll(false)
        + var.withType("custom")
        + {
            current: {
                selected: false,
                text: _stringOrText(values[0]),
                value: _stringOrValue(values[0]),
            },
            options: std.makeArray(std.length(values), function(i)
                {
                    selected: i == 0,
                    text: _stringOrText(values[i]),
                    value: _stringOrValue(values[i]),
                },),
        },

Setting query doesn't populate these 2 fields as it should

You need to set both the fields in order for the variable to work correctly, not sure what the use of current is when you already have selected in options

Row panel error after refactor of determining panel type.

It appears that a few days ago when #43 was introduced, calling the panel.row.new function results in a missing argument error. I've included an example to reproduce this and the output below.

Code

local g = import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet';

g.panel.row.new('Test')

Result

RUNTIME ERROR: Missing argument: value
	vendor/github.com/grafana/grafonnet/grafonnet-base/veneer/panel.libsonnet:10:7-22	function <anonymous>
	dashboard.jsonnet:3:1-27	$
	During evaluation

Expected result

{
   "datasource": {
      "type": "datasource",
      "uid": "-- Mixed --"
   },
   "title": "Test",
   "type": "row"
}

I've found that the following patch addresses the issue, though I'm not quite up to speed on what's best for grafonnet or jsonnet in general, and it's my understanding that #43 intended to derive this information automatically:

diff --git a/grafonnet-base/main.libsonnet b/grafonnet-base/main.libsonnet
index d797051..7db400a 100644
--- a/grafonnet-base/main.libsonnet
+++ b/grafonnet-base/main.libsonnet
@@ -104,6 +104,11 @@ local veneer = import './veneer/main.libsonnet';
       panel+: {
         row:
           root.coreLib.new(rowPanel)
+          + {
+              withType(): {
+                type: 'row',
+              }
+            }
           + root.packageDocMixin(version, 'row', 'panel.')
           + veneer.panel('row'),
       },

I'm aware that this is an experimental library, and look forward to leveraging it and contributing where we can. Thanks for working on it!

Couldn't open import │ "github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet":

Starting to get the following error when using Terraform:

 RUNTIME ERROR: couldn't open import
│ "github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet": no
│ match locally or in the Jsonnet library paths
│ 	/app/jsonnet/g.libsonnet:2:1-74	$
│ 	/app/jsonnet/main.libsonnet:1:11-31	thunk <g> from <$>
│ 	/app/jsonnet/main.libsonnet:8:1-2	
│ 	During evaluation

Do you familiar with it ?

Grafana 8.x support

Grafana 8.x hasn't reached its end of life yet: https://endoflife.date/grafana. Our team policy doesn't allow us to drop 8.x support for dashboards since 8.x is still supported by Grafana team itself. But in that case we'll need to continue to use deprecated library with various workarounds.

Since new library is autogenerated, is it possible to make it compatible with 8.x code?

Integration with CUE

Hi,

I want to understand if there will be any Grafonnet integration with CUE going forward? Asking because we have seen a lot of reference to Grafonnet in grafana/grafana#39593.
We are currently investigating on methods to manage dashboards as code, it will be really helpful if you could provide some insight here.
Thank you.

`resolveCollapsedFlagOnRows` puts panel in wrong row

Hi! I ran into issue #145 and attempted to resolve it by calling util.panel.resolveCollapsedFlagOnRows on the final panel array. This resulted in one of my panels getting moved to the wrong row.

In the following example, I expect stats a and b to be next to each other on row 1; and c, d, and e, on row 2. However, Grafana puts stat b in row 2:

local g = import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet';
local row = g.panel.row;
local stat = g.panel.stat;

local panels = [
    row.new('row 1')
    + row.withPanels([
        stat.new('a')
        + stat.panelOptions.withGridPos(h=8, w=12),
        stat.new('b')
        + stat.panelOptions.withGridPos(h=8, w=12, x=12)
    ]),
    row.new('row 2')
    + row.withPanels([
        stat.new('c')
        + stat.panelOptions.withGridPos(h=4, w=4),
        stat.new('d')
        + stat.panelOptions.withGridPos(h=4, w=4, y=4),
        stat.new('e')
        + stat.panelOptions.withGridPos(h=8, w=20, x=4)
    ])
];

g.dashboard.new("bug report")
+ g.dashboard.withPanels(
    g.util.panel.resolveCollapsedFlagOnRows(panels)
)

Missing fields from alerting rule preventing it to be used with Grafana API

I'm trying to use grafonnet to define alert rules to be uploaded using this API https://grafana.com/docs/grafana/latest/developers/http_api/alerting_provisioning/#route-post-alert-rule.

My assumption is that I should use this grafonnet API
https://grafana.github.io/grafonnet/API/alerting/ruleGroup/rule/index.html

The problem is that several of the body parameters are missing (Even mandatory ones).
Full definition:
https://grafana.com/docs/grafana/latest/developers/http_api/alerting_provisioning/#provisioned-alert-rule

Can these please be added in?
https://github.com/grafana/grafonnet/blob/main/generator/alerting.libsonnet#L221

I'm not sure if I'm misunderstanding something?

RED example isn't building

I had to make the following change to the red dashboard to get it to build with jsonnet:

diff --git a/examples/redMethod/lib/redDashboard/main.libsonnet b/examples/redMethod/lib/redDashboard/main.libsonnet
index 965c8bd..4024cea 100644
--- a/examples/redMethod/lib/redDashboard/main.libsonnet
+++ b/examples/redMethod/lib/redDashboard/main.libsonnet
@@ -1,4 +1,4 @@
-local g = import 'g.libsonnet';
+local g = import '../g.libsonnet';
 
 local panels = import './panels.libsonnet';
 
diff --git a/examples/redMethod/lib/redDashboard/panels.libsonnet b/examples/redMethod/lib/redDashboard/panels.libsonnet
index 7445e2f..1cd15b4 100644
--- a/examples/redMethod/lib/redDashboard/panels.libsonnet
+++ b/examples/redMethod/lib/redDashboard/panels.libsonnet
@@ -1,4 +1,4 @@
-local g = import 'g.libsonnet';
+local g = import '../g.libsonnet';
 
 {
   new(applicationName, requestTargets, latencyTargets):
diff --git a/examples/redMethod/lib/redDashboard/queries/prometheus.libsonnet b/examples/redMethod/lib/redDashboard/queries/prometheus.libsonnet
index e300e6b..be063ad 100644
--- a/examples/redMethod/lib/redDashboard/queries/prometheus.libsonnet
+++ b/examples/redMethod/lib/redDashboard/queries/prometheus.libsonnet
@@ -1,4 +1,4 @@
-local g = import 'g.libsonnet';
+local g = import '../../g.libsonnet';
 
 {
   new(

Support for AWS CloudWatch Datasource in Grafana Variables

Expected Behavior

I would like to be able to define a Grafana variable with a CloudWatch datasource in my Jsonnet code. The expected JSON output for the variable should look like this:

{
  "current": {
    "selected": false,
    "text": "app/alb-name123123",
    "value": "app/alb-name123123"
  },
  "datasource": {
    "type": "cloudwatch",
    "uid": "cloudwatch-ds"
  },
  "definition": "",
  "hide": 0,
  "includeAll": false,
  "label": "alb_name",
  "multi": false,
  "name": "ALB",
  "options": [],
  "query": {
    "dimensionFilters": {},
    "dimensionKey": "LoadBalancer",
    "logGroupPrefix": "",
    "metricName": "RequestCount",
    "namespace": "AWS/ApplicationELB",
    "queryType": "dimensionValues",
    "refId": "CloudWatchVariableQueryEditor-VariableQuery",
    "region": "default",
    "resourceType": "",
    "tags": {}
  },
  "refresh": 1,
  "regex": "",
  "skipUrlSync": false,
  "sort": 1,
  "type": "query"
}

Current Behavior

Currently, I am unable to find a way to specify a CloudWatch datasource for a Grafana variable using Graffonet.

Environment

  • Graffonet version: v10.2.0
  • Grafana version: v10.2.0
  • Jsonnet version: v0.20.0

Possible Solution

Any suggestions for a possible solution or workaround.

Example of annotation ?

Hi,

I would like to add annotations to my dashboard and was wondering if you help me with an example for creating the annotation object and how it should be passed into dashboard ?

Also can I create a new annotation object using g.annotation.new ?

queryTypes required fileds

Hello! I use fn queryTypes.withLabelValues(label, metric), where requirement fields is label and metric. But as i i see in grafana documentation , filed metric is optional, and may not be used at queries, and this my case: in my queries, metric options is not needed, want to use only labels. Tried use regex, not succeeded .
My code is:

///
    + var.query.queryTypes.withLabelValues(
      'label',
      '',
///

after build via jsonnet become like this:
"query": "label_values(, label)",
and Grafana couldn't use it correctly, at variable interface i see this
изображение

Verbose dashboard construction syntax

g.dashboard.new('Faro dashboard')
+ g.dashboard.withDescription('Dashboard for Faro')
+ g.dashboard.graphTooltip.withSharedCrosshair()
+ g.dashboard.withPanels([

I've been following progress here and a major point of difference between this and the old grafonnet-lib is the syntax to build out dashboards. In the above example, would it be possible to drop the g.dashboard when calling .withDescription() .withPanels() etc? This way they would seem more like chained methods of a class instance rather than independent functions being called.

Populating and setting a variable's current value

Hi and thanks for the work on making grafonnet better aligned with the development of Grafana!

I have been playing around with the 10.2.0 API and Grafana 10.2.3 and now have the following variable definition:

{ 
  abc:
    var.custom.new('abc', values=['true', 'false', 'limited'])
    + var.custom.generalOptions.withLabel('Abc?')
    + var.custom.generalOptions.withCurrent('false')
    + var.custom.selectionOptions.withMulti(false)
    + var.custom.selectionOptions.withIncludeAll()
}

However, the variable's current value remains "true" despite the withCurrent('false'). How do I influence the variable's current (default) value?

Also, how do I make the default value "All"?

And finally, query type variables do not seem to populate as expected. After uploading a dashboard definition including the use of query variables, I need to manually go and click Run query in the Grafana variable editor UI to populate values.

Allow to set the default value to "All"

Reverse engineered this is how it looks like for a custom query:

{
        "current": {
          "selected": true,
          "text": [
            "All"
          ],
          "value": [
            "$__all"
          ]
        },
        "hide": 0,
        "includeAll": true,
        "multi": true,
        "name": "abc",
        "options": [
          {
            "selected": true,
            "text": "All",
            "value": "$__all"
          },
          {
            "selected": false,
            "text": "'true'",
            "value": "'true'"
          },
          {
            "selected": false,
            "text": "'false'",
            "value": "'false'"
          },
          {
            "selected": false,
            "text": "'limited'",
            "value": "'limited'"
          }
        ],
        "query": "'true', 'false', 'limited'",
        "queryValue": "",
        "skipUrlSync": false,
        "type": "custom"
      }

Terraform error with matcher

When using Terraform for my dashboard, I encountered the below error. Terraform works well when I comment out the lines containing "matcher", such as g.panel.table.fieldOverride.matcher.withId('id'), but otherwise:

terraform apply

│ Error: RUNTIME ERROR: Field does not exist: matcher
│ /tmp/jsonnet/main.libsonnet:6338:15-50
│ Array element 0
│ Field "overrides"
│ Field "fieldConfig"
│ Array element 0
│ Field "panels"
│ Array element 12
│ Field "panels"
│ During manifestation


│ with data.jsonnet_file.dashboard,
│ on dashboard.tf line 14, in data "jsonnet_file" "dashboard":
│ 14: data "jsonnet_file" "dashboard" {

Add filterable option in table panel

Previously table use to have a filterable:true option in grafonnet-lib library which used to provide us with a flexibility to filter rows based on the selected filters. For example

  "fieldConfig": {
    "defaults": {
      "custom": {
        "align": "auto",
        "cellOptions": {
          "type": "auto"
        },
        "inspect": false,
        "filterable": true
      },

This option is not present in the new grafonnet library. Requesting to add it.

Support PostgreSQL plugin

Hi! Please close this if I'm way off base, but I can't currently find any queries / targets for the core PostgreSQL plugin.

I'll try to use the same workaround that was mention in #147, but it would be great if this core plugin had its own library.

Automating the Extraction of dashboard.json in Terraform

The problem:

$ make > dashboard.json
Generate the following output:

data.jsonnet_file.dashboard: Reading...
data.jsonnet_file.dashboard: Read complete after 4s [id=fff343c4f694714716c088faa4aff66dbc2f1e763f80e149f87fdd85451cc933]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
dashboard = <<EOT
{
   "description": "Dashboard for Faro",
   ....
   "title": "Faro dashboard"
}

EOT

To obtain a clean dashboard JSON, we execute the following code:

with open(sys.argv[1], 'r') as f:
    match = re.search(r'dashboard = <<EOT(.*?)EOT', f.read(), re.DOTALL)
    if match:
        extracted_content = match.group(1).strip()

This method may not be optimal for extracting dashboard.json, as parsing could fail if the output contains 'EOT'.

Do you have a safer method to automate the extraction of dashboard.json in Terraform?

Simplify fixed-color overrides

Hi,

I have a code that looks like this to create a timeseries override.

...
+ standardOptions.withOverrides([
  fieldOverride.byName.new('latency_p99')
  + fieldOverride.byName.withPropertiesFromOptions(standardOptions.color.withFixedColor('green')),
...
])

I am using terraform to provision dashboards, and I got this rendered from the terraform plan:

...
properties = [
{
id    = "color.fixedColor"
value = "green"
},
...

The values for the id and the value keys do not look like valid override values and the override is not rendered at all, inspecting the json for the panel I am working on.

A properly working override looks like this:

"properties": [
          {
            "id": "color",
            "value": {
              "fixedColor": "green",
              "mode": "fixed"
            }

To correctly render the override, I have a workaround that looks like this, but it looks overly complicated just for overriding a color:

...
+ standardOptions.withOverrides([
  fieldOverride.byName.new('latency_p99')
  + fieldOverride.byName.withProperty('color', {
          fixedColor: 'green',
          mode: 'fixed',
        }),
...
])

I was wondering: is there a simpler way to do this? I expect a one liner such as + fieldOverride.byName.withPropertiesFromOptions(standardOptions.color.withFixedColor('green')), would render the override properly.

Stable replacement for granfonnet-lib

This library is experimental

Just wondering if there's are outstanding bugs/instabilities that prevent recommending migration from granfonnet-lib? My team and I would like to eventually port over from @rhowe 's fork.

Support Influxdb

Currently, there are no query target helpers/functions (not sure what the correct terminology is) for InfluxDB InfluxQL nor InfluxDB Flux.
It would be great to have them at least for InfluxQL, as this data source is quite popular.

The way it has to be done right now:

+ g.panel.timeSeries.queryOptions.withTargets([
        time.queryOptions.withDatasource('influxdb', influxFluxDataSource)
        + {
          alias: 'Frequency',
          groupBy: [
            {
              params: [
                '$__interval',
              ],
              type: 'time',
            },
            {
              params: [
                'none',
              ],
              type: 'fill',
            },
          ],
          measurement: 'telemetry_v2',
          orderByTime: 'ASC',
          policy: 'default',
          query: '',
          refId: 'A',
          resultFormat: 'time_series',
          select: [
            [
              {
                params: [
                  'system_frequency_freq_hz',
                ],
                type: 'field',
              },
              {
                params: [],
                type: 'mean',
              },
            ],
          ],
          tags: [
            {
              key: 'device_id',
              operator: '=~',
              value: '/^$device$/',
            },
          ],
        },
      ])

fixedColor overrides rendering two separate objects

Hi,

So I have a grafonnet code like this:

...
local timeSeries = g.panel.timeSeries,
local fieldConfig = timeSeries.fieldConfig,
local custom = fieldConfig.defaults.custom,
local options = timeSeries.options,
local standardOptions = timeSeries.standardOptions,
local override = standardOptions.override,
local step = standardOptions.threshold.step,
...
...
+ standardOptions.withOverrides([
        // Override 1
        override.byName.new('latency_median')
        + override.byName.withPropertiesFromOptions(standardOptions.color.withMode('fixed'))
        + override.byName.withPropertiesFromOptions(standardOptions.color.withFixedColor('red')),
...

I expect grafonnet to render an override like this panel json:

"properties": [
{
 "id": "color",
 "value": {
  "mode": "fixed"
  "fixedColor": "red"
  }
},
...

But instead it renders two objects with the same id "color" inside the properties array like this:

"properties": [
          {
            "id": "color",
            "value": {
              "mode": "fixed"
            }
          },
          {
            "id": "color",
            "value": {
              "fixedColor": "red"
            }
          }
        ]

I tried using only the withFixedColor() function without withMode('fixed') and vice versa but they only render one value at a time for "id" : "color": "fixedColor": "red" and "mode": "fixed", respectively (both do not work as expected).

Am I using the correct functions for color overrides?
I am using the latest grafonnet release v10.1.0 and on grafana v10.1.4.

This is related to #99 and #104.

Using grizzly

Can grafonnet be used with grizzly ?
I can an error when trying to use the grr preview command:
FATA[0000] recursion did not resolve in a valid Kubernetes object. In path '.' found key 'schemaVersion' of type 'float64' instead.

Any idea ?

Add Folder resource

If you look up the api documentation at here, you're not finding the folder resources.

I would expect it to show up at the overview.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.