2.1.3 ā€¢ Published 4 months ago

chartjs-plugin-datasource-prometheus v2.1.3

Weekly downloads
5
License
MIT
Repository
github
Last release
4 months ago

Welcome to chartjs-plugin-datasource-prometheus šŸ‘‹

NPM version License: MIT

A Prometheus datasource for ChartJS.

screenshot

Dependencies:

Demonstration:

https://samber.github.io/chartjs-plugin-datasource-prometheus/example/

I would be happy to add links to charts using this library. Feel free to reach me by creating an issue ;)

āœØ Features

  • Loads time-series from Prometheus into Chart.js.
  • Similar to Grafana, but ported to Chart.js for public-facing web applications.
  • UMD compatible, you can use it with any module loader
  • Have been tested with line chart and (stacked) bar chart. The library should be compatible with more chart types.
  • Graph auto-refresh
  • Date interval can be absolute or relative to now
  • Multiple Prometheus queries into the same chart
  • Stacked series
  • Custom backend requests (useful for multitenant apps)
  • Hooks available (styling, labeling, data presentation...)
  • Custom chart messages for errors or empty Prometheus responses
  • Break or continuous lines when gap in data
  • Line styling
  • Send queries with your own Prometheus driver

āš ļø This project is not intented to replace Grafana. For monitoring purpose or internal company graph showing, Grafana will definitely be better and more secure.

šŸš€ Installation

Via npm:

npm install momentjs chart.js --save

npm install chartjs-plugin-datasource-prometheus --save

Via CDN:

Add inside of <head> the following:

<script src="https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3/dist/chartjs-adapter-date-fns.bundle.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datasource-prometheus@2/dist/chartjs-plugin-datasource-prometheus.umd.min.js" crossorigin="anonymous"></script>

šŸ’” Note that chartjs-plugin-datasource-prometheus must be loaded after Chart.js and the date-fns adapter.

Here is used the jsDelivr CDN with specifying only a major version so any minor and patch updates will be applied automatically. If you need to use a specific version or ESM the copy link from https://www.jsdelivr.com/package/npm/chartjs-plugin-datasource-prometheus

šŸ’” Quick start

chartjs-plugin-datasource-prometheus can be used with ES6 modules, plain JavaScript and module loaders.

<canvas id="myChart"></canvas>

Then, you need to register the plugin to enable it for all charts in the page.

Chart.registry.plugins.register(ChartDatasourcePrometheusPlugin);

Or, you can enable the plugin only for specific charts.

var chart = new Chart(ctx, {
    plugins: [ChartDatasourcePrometheusPlugin],
    options: {
        // ...
    }
});

In the example below, we display Go duration of garbage collection, for the last 12 hours:

var myChart = new Chart(ctx, {
  type: 'line',
  plugins: [ChartDatasourcePrometheusPlugin],
  options: {
    plugins: {
      'datasource-prometheus': {
        prometheus: {
          endpoint: "https://prometheus.demo.do.prometheus.io",
          baseURL: "/api/v1",   // default value
        },
        query: 'sum by (job) (go_gc_duration_seconds)',
        timeRange: {
          type: 'relative',

          // from 12 hours ago to now
          start: -12 * 60 * 60 * 1000,
          end: 0,
        },
      },
    },
  },
});

šŸ’¬ Spec

Options

PropertyRequiredDescriptionDefault
prometheus.endpointyesPrometheus hostname
prometheus.baseURLnoPrometheus metric path"/api/v1"
prometheus.headersnoHeaders to add to Prometheus request
prometheus.auth.usernamenoBasic auth username
prometheus.auth.passwordnoBasic auth password
prometheus.proxy.hostnoProxy hostname
prometheus.proxy.portnoProxy port
prometheus.withCredentialsnoSend cookies in cross-site requestsfalse
prometheus.timeoutnoPrometheus request timeout in milliseconds10000
queryyesPrometheus query: string or function (see below). Supports multiple queries, using an array.
timeRange.typenoTime range type: absolute or relative"absolute"
timeRange.startyesTime range start: Date object (absolute) or integer (relative)
timeRange.endyesTime range end: Date object (absolute) or integer (relative)
timeRange.stepnoTime between 2 data pointscomputed
timeRange.minStepnoMin time between 2 data pointsnull
timeRange.msUpdateIntervalnoUpdate interval in millisecondnull
fillGapsnoInsert NaN values when values are missing in time rangefalse
tensionnoBezier curve tension of the line. Set to 0 to draw straightlines. This option is ignored if monotone cubic interpolation is used0.4
cubicInterpolationModeno"default" or "monotone""default"
steppednofalse, true, "before", "middle" or "after"false
stackednoWhether values are stacked or notfalse
fillnoFills the area under the linefalse
borderWidthnoShould I explain this field?3
backgroundColornoShould I explain this field?See library source code
borderColornoShould I explain this field?See library source code
errorMsg.messagenoOverrides error messagesnull
errorMsg.fontnoFont of error messages"16px normal 'Helvetica Nueue'"
noDataMsg.messagenoEmpty chart message"No data to display"
noDataMsg.fontnoFont of empty chart message"16px normal 'Helvetica Nueue'"

Hooks

Some hooks have been inserted into the library. It may help you to rewrite label names dynamically, set colors...

// šŸ’” For better serie labels, we are looking for a templating solution => please contribute ;)

PropertyRequiredDescriptionPrototype
findInLabelMapnoCustom serie label(serie: Metric) => string
findInBorderColorMapnoCustom serie line color(serie: Metric) => string
findInBackgroundColorMapnoCustom serie background color(serie: Metric) => string
dataSetHooknoModify data on the fly, right before display(datasets: ChartDataSet[]) => ChartDataSet[]

Examples

Multiple queries in one chart

The query field can be an array of queries. Returned series are aggregated in a single chart.

In case you want to show those queries on different axes, you can define a custom options.scales.yAxes field.

var myChart = new Chart(ctx, {
    type: 'line',
    plugins: [ChartDatasourcePrometheusPlugin],
    options: {
        scales: {
            yAxes: [
                {position: 'left'},
                {position: 'left'},
                {position: 'right'},
            ]
        },
        plugins: {
            'datasource-prometheus': {
                prometheus: {
                    endpoint: "https://prometheus.demo.do.prometheus.io",
                },
                query: ['node_load1', 'node_load5', 'node_load15'],
                timeRange: {
                    type: 'relative',

                    // from 12 hours ago to now
                    start: -12 * 60 * 60 * 1000,
                    end: 0,
                },
            },
        },
    },
});

screenshot

Auto refresh

Animations should be disabled when chart refresh itself.

var myChart = new Chart(ctx, {
    type: 'line',
    plugins: [ChartDatasourcePrometheusPlugin],
    options: {
        animation: {
            duration: 0,
        },
        plugins: {
            'datasource-prometheus': {
                prometheus: {
                    endpoint: "https://prometheus.demo.do.prometheus.io",
                },
                query: 'node_load1',
                timeRange: {
                    type: 'relative',

                    // from 10 minutes ago to now
                    start: -1 * 10 * 60 * 1000,
                    end: 0,
                    msUpdateInterval: 5000,
                },
            },
        },
    },
});

Update

Query update:

chart.options.plugins['datasource-prometheus'].query = "new query";
chart.update({});

Start/end range update:

chart.options.plugins['datasource-prometheus'].timeRange.start = startTime;
chart.update({});

Custom queries

In the context of a multitenant application, it is not a good idea to write a query on the browser side. In that scenario, you may need to send a custom request to your backend, which is responsible for doing the final Prometheus query.

In that case, the prometheus field can be ommited. Just pass a function with the following prototype: (start: Date, end: Date, step: number) => Promise<any>.

It can be combined with traditional string queries: query: ['node_load1', customReq].

// Here, we call a fictive API that gonna query Prometheus to get the list
// of comments, wrote by the current user during the past hour.
// This endpoint will return a Prometheus-like response.
function customReq(start, end, step) {
    const startTimestamp = start.getTime() / 1000;
    const endTimestamp = end.getTime() / 1000;

    const url = `https://api.example.com/user/activity?event_type=comment.write&range_start=${startTimestamp}&end=${endTimestamp}&range_step=${step}`;
    const headers = {'Authorization': 'Bearer Ainae1Ahchiew6UhseeCh7el'};

    return fetch(url, { headers })
        .then(response => response.json())
        .then(response => response['data']);
}

const myChart = new Chart(ctx, {
    type: 'line',
    plugins: [ChartDatasourcePrometheusPlugin],
    options: {
        plugins: {
            'datasource-prometheus': {
                query: customReq,
                timeRange: {
                    type: 'relative',
                    start: -1 * 60 * 60 * 1000, // 1h ago
                    end: 0,   // now
                },
            },
        },
    },
});

šŸ¤Æ Troubleshooting

CORS

Start your Prometheus instance with --web.cors.origin="www.example.com" flag or even --web.cors.origin=".*" if you like living dangerously. šŸ˜…

šŸ” Security advisory

Please read the security advisory of prometheus-query library.

In the context of a multitenant application, it is not a good idea to write a query on the browser side. In that scenario, you may need to use the "custom request" feature.

šŸ¤ Contributing

The Prometheus Datasource is open source and contributions from community (you!) are welcome.

There are many ways to contribute: writing code, documentation, reporting issues...

How-to

Author

šŸ‘¤ Samuel Berthe

šŸ‘¤ Frantisek Svoboda

šŸ’« Show your support

Give a ā­ļø if this project helped you!

support us

šŸ“ License

Copyright Ā© 2020 Samuel Berthe.

This project is MIT licensed.

2.1.3

4 months ago

2.1.2

6 months ago

2.1.1

1 year ago

1.1.0

1 year ago

2.1.0

1 year ago

2.0.0

1 year ago

1.0.13

1 year ago

1.0.12

2 years ago

1.0.11

2 years ago

1.0.9

2 years ago

1.0.8

2 years ago

1.0.10

2 years ago

1.0.7

2 years ago

1.0.6

3 years ago

1.0.5

3 years ago

1.0.2

3 years ago

1.0.4

3 years ago

1.0.3

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago

1.0.0-beta.2

3 years ago

1.0.0-beta.1

3 years ago

0.4.0

3 years ago

0.3.7

3 years ago

0.3.6

3 years ago

0.3.5

3 years ago

0.2.0

4 years ago

0.1.0

4 years ago