Set up image rendering

Grafana supports automatic rendering of panels as PNG images. This allows Grafana to automatically generate images of your panels to include in alert notifications, PDF export, and Reporting. PDF Export and Reporting are available only in Grafana Enterprise.

Note: Image rendering of dashboards is not supported at this time.

While an image is being rendered, the PNG image is temporarily written to the file system. When the image is rendered, the PNG image is temporarily written to the png folder in the Grafana data folder.

A background job runs every 10 minutes and removes temporary images. You can configure how long an image should be stored before being removed by configuring the temp_data_lifetime setting.

You can also render a PNG by clicking the dropdown arrow next to a panel title, then clicking Share > Direct link rendered image.

Alerting and render limits

Alert notifications can include images, but rendering many images at the same time can overload the server where the renderer is running. For instructions of how to configure this, see concurrent_render_limit.

Install Grafana Image Renderer plugin

Note: Starting from Grafana v7.0.0, all PhantomJS support has been removed. Please use the Grafana Image Renderer plugin or remote rendering service.

To install the plugin, refer to the Grafana Image Renderer Installation instructions.

Configuration

The Grafana Image Renderer plugin has a number of configuration options that are used in plugin or remote rendering modes.

In plugin mode, you can specify them directly in the Grafana configuration file.

In remote rendering mode, you can specify them in a .json configuration file or, for some of them, you can override the configuration defaults using environment variables.

Configuration file

You can update your settings by using a configuration file, see default.json for defaults. Note that any configured environment variable takes precedence over configuration file settings.

You can volume mount your custom configuration file when starting the docker container:

  1. docker run -d --name=renderer --network=host -v /some/path/config.json:/usr/src/app/config.json grafana/grafana-image-renderer:latest

You can see a docker-compose example using a custom configuration file here.

Rendering mode

You can instruct how headless browser instances are created by configuring a rendering mode. Default is default, other supported values are clustered and reusable.

Default

Default mode will create a new browser instance on each request. When handling multiple concurrent requests, this mode increases memory usage as it will launch multiple browsers at the same time. If you want to set a maximum number of browser to open, you’ll need to use the clustered mode.

Note: When using the default mode, it’s recommended to not remove the default Chromium flag --disable-gpu. When receiving a lot of concurrent requests, not using this flag can cause Puppeteer newPage function to freeze, causing request timeouts and leaving browsers open.

  1. RENDERING_MODE=default
  1. {
  2. "rendering": {
  3. "mode": "default"
  4. }
  5. }

Clustered

With the clustered mode, you can configure how many browser instances or incognito pages can execute concurrently. Default is browser and will ensure a maximum amount of browser instances can execute concurrently. Mode context will ensure a maximum amount of incognito pages can execute concurrently. You can also configure the maximum concurrency allowed, which per default is 5, and the maximum duration of a rendering request, which per default is 30 seconds.

Using a cluster of incognito pages is more performant and consumes less CPU and memory than a cluster of browsers. However, if one page crashes it can bring down the entire browser with it (making all the rendering requests happening at the same time fail). Also, each page isn’t guaranteed to be totally clean (cookies and storage might bleed-through as seen here).

  1. RENDERING_MODE=clustered
  2. RENDERING_CLUSTERING_MODE=browser
  3. RENDERING_CLUSTERING_MAX_CONCURRENCY=5
  4. RENDERING_CLUSTERING_TIMEOUT=30
  1. {
  2. "rendering": {
  3. "mode": "clustered",
  4. "clustering": {
  5. "mode": "browser",
  6. "maxConcurrency": 5,
  7. "timeout": 30
  8. }
  9. }
  10. }
Cluster mode contextPerRenderKey (experimental)

Note: This feature is available in Image Renderer v3.4.0 and later versions.

In contextPerRenderKey mode, the plugin will reuse the same browser context for all rendering requests sharing the same renderKey auth cookie and target domain within a short time window. Each new request will open a new page within the existing context. Contexts are closed automatically after 5s of inactivity.

In the case of contextPerRenderKey mode, the clustering.max_concurrency option refers to the number of open contexts rather than the number of open pages. There is no way to limit the number of open pages in a context.

contextPerRenderKey was designed to improve the performance of the dashboard previews crawler.

  1. {
  2. "rendering": {
  3. "mode": "clustered",
  4. "clustering": {
  5. "mode": "contextPerRenderKey",
  6. "maxConcurrency": 5,
  7. "timeout": 30
  8. }
  9. }
  10. }

Reusable (experimental)

When using the rendering mode reusable, one browser instance will be created and reused. A new incognito page will be opened for each request. This mode is experimental since, if the browser instance crashes, it will not automatically be restarted. You can achieve a similar behavior using clustered mode with a high maxConcurrency setting.

  1. RENDERING_MODE=reusable
  1. {
  2. "rendering": {
  3. "mode": "reusable"
  4. }
  5. }

Optimize the performance, CPU and memory usage of the image renderer

The performance and resources consumption of the different modes depend a lot on the number of concurrent requests your service is handling. To understand how many concurrent requests your service is handling, monitor your image renderer service.

With no concurrent requests, the different modes show very similar performance and CPU / memory usage.

When handling concurrent requests, we see the following trends:

  • To improve performance and reduce CPU and memory consumption, use clustered mode with RENDERING_CLUSTERING_MODE set as context. This parallelizes incognito pages instead of browsers.
  • If you use the clustered mode with a maxConcurrency setting below your average number of concurrent requests, performance will drop as the rendering requests will need to wait for the other to finish before getting access to an incognito page / browser.

To achieve better performance, monitor the machine on which your service is running. If you don’t have enough memory and / or CPU, every rendering step will be slower than usual, increasing the duration of every rendering request.

Other available settings

Note: Please note that not all settings are available using environment variables. If there is no example using environment variable below, it means that you need to update the configuration file.

HTTP host

Change the listening host of the HTTP server. Default is unset and will use the local host.

  1. HTTP_HOST=localhost
  1. {
  2. "service": {
  3. "host": "localhost"
  4. }
  5. }

HTTP port

Change the listening port of the HTTP server. Default is 8081. Setting 0 will automatically assign a port not in use.

  1. HTTP_PORT=0
  1. {
  2. "service": {
  3. "port": 0
  4. }
  5. }

Enable Prometheus metrics

You can enable Prometheus metrics endpoint /metrics using the environment variable ENABLE_METRICS. Node.js and render request duration metrics are included, see output example for details.

Default is false.

  1. ENABLE_METRICS=true
  1. {
  2. "service": {
  3. "metrics": {
  4. "enabled": true,
  5. "collectDefaultMetrics": true,
  6. "requestDurationBuckets": [1, 5, 7, 9, 11, 13, 15, 20, 30]
  7. }
  8. }
  9. }

Log level

Change the log level. Default is info and will include log messages with level error, warning and info.

  1. LOG_LEVEL=debug
  1. {
  2. "service": {
  3. "logging": {
  4. "level": "debug",
  5. "console": {
  6. "json": false,
  7. "colorize": true
  8. }
  9. }
  10. }
  11. }

Verbose logging

Instruct headless browser instance whether to capture and log verbose information when rendering an image. Default is false and will only capture and log error messages. When enabled (true) debug messages are captured and logged as well.

Note that you need to change log level to debug, see above, for the verbose information to be included in the logs.

  1. RENDERING_VERBOSE_LOGGING=true
  1. {
  2. "rendering": {
  3. "verboseLogging": true
  4. }
  5. }

Capture browser output

Instruct headless browser instance whether to output its debug and error messages into running process of remote rendering service. Default is false. This can be useful to enable (true) when troubleshooting.

  1. RENDERING_DUMPIO=true
  1. {
  2. "rendering": {
  3. "dumpio": true
  4. }
  5. }

Custom Chrome/Chromium

If you already have Chrome or Chromium installed on your system, then you can use this instead of the pre-packaged version of Chromium.

Note: Please note that this is not recommended, since you may encounter problems if the installed version of Chrome/Chromium is not compatible with the Grafana Image renderer plugin.

You need to make sure that the Chrome/Chromium executable is available for the Grafana/image rendering service process.

  1. CHROME_BIN="/usr/bin/chromium-browser"
  1. {
  2. "rendering": {
  3. "chromeBin": "/usr/bin/chromium-browser"
  4. }
  5. }

Start browser with additional arguments

Additional arguments to pass to the headless browser instance. Defaults are --no-sandbox,--disable-gpu. The list of Chromium flags can be found here and the list of flags used as defaults by Puppeteer can be found there. Multiple arguments is separated with comma-character.

  1. RENDERING_ARGS=--no-sandbox,--disable-setuid-sandbox,--disable-dev-shm-usage,--disable-accelerated-2d-canvas,--disable-gpu,--window-size=1280x758
  1. {
  2. "rendering": {
  3. "args": [
  4. "--no-sandbox",
  5. "--disable-setuid-sandbox",
  6. "--disable-dev-shm-usage",
  7. "--disable-accelerated-2d-canvas",
  8. "--disable-gpu",
  9. "--window-size=1280x758"
  10. ]
  11. }
  12. }

Ignore HTTPS errors

Instruct headless browser instance whether to ignore HTTPS errors during navigation. Per default HTTPS errors are not ignored. Due to the security risk it’s not recommended to ignore HTTPS errors.

  1. IGNORE_HTTPS_ERRORS=true
  1. {
  2. "rendering": {
  3. "ignoresHttpsErrors": true
  4. }
  5. }

Default timezone

Instruct headless browser instance to use a default timezone when not provided by Grafana, .e.g. when rendering panel image of alert. See ICU’s metaZones.txt for a list of supported timezone IDs. Fallbacks to TZ environment variable if not set.

  1. BROWSER_TZ=Europe/Stockholm
  1. {
  2. "rendering": {
  3. "timezone": "Europe/Stockholm"
  4. }
  5. }

Default language

Instruct headless browser instance to use a default language when not provided by Grafana, e.g. when rendering panel image of alert. Refer to the HTTP header Accept-Language to understand how to format this value.

  1. {
  2. "rendering": {
  3. "acceptLanguage": "fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5"
  4. }
  5. }

Viewport width

Default viewport width when width is not specified in the rendering request. Default is 1000.

  1. {
  2. "rendering": {
  3. "width": 1000
  4. }
  5. }

Viewport height

Default viewport height when height is not specified in the rendering request. Default is 500.

  1. {
  2. "rendering": {
  3. "height": 500
  4. }
  5. }

Viewport maximum width

Limit the maximum viewport width that can be requested. Default is 3000.

  1. {
  2. "rendering": {
  3. "maxWidth": 1000
  4. }
  5. }

Viewport maximum height

Limit the maximum viewport height that can be requested. Default is 3000.

  1. {
  2. "rendering": {
  3. "maxHeight": 500
  4. }
  5. }

Device scale factor

Specify default device scale factor for rendering images. 2 is enough for monitor resolutions, 4 would be better for printed material. Setting a higher value affects performance and memory. Default is 1. This can be overridden in the rendering request.

  1. {
  2. "rendering": {
  3. "deviceScaleFactor": 2
  4. }
  5. }

Maximum device scale factor

Limit the maximum device scale factor that can be requested. Default is 4.

  1. {
  2. "rendering": {
  3. "maxDeviceScaleFactor": 4
  4. }
  5. }