· Apr 19, 2021 2m read

Grafana support for InterSystems IRIS

Hello everyone, let me introduce, one of my latest projects. It is a DataSource plugin for Grafana, which can connect directly to InterSystems IRIS and gather any data (in the future). 


  • Can show SAM metrics with periodic update, with a history, the metrics gathered by Grafana directly and only when requested while displayed
  • Display messages.log and alerts.log 
  • Application errors from ^ERRORS global

Features that can be added later

  • Any SQL SELECT query for tables with or without DateTime fields
  • View some data directly from any Global
  • Call for any custom SQL Query on the IRIS side
  • Even probably MDX Queries

So, if you have some custom logic for logging within your application, it would be possible to connect Grafana to these logs and display it there.


To test it by yourself, you can clone the repo, and start the environment with docker-compose. The docker-compose environment is configured on using ports 3000, 3081, 3082; if those ports already in use in your system, just change them in the docker-compose.yml file.

git clone
cd grafana-intersystems-datasource
docker-compose up -d

After pulling images, it will start Grafana and IRIS in two containers.

Open Grafana by link http://localhost:3000/

Go to DataSources, it will have InterSystems IRIS connection, added by autoprovision.

Diving inside will give a simple form with basic settings, and the Test button, to check the connection. When IRIS will start it should show green OK.

Let's create some Dashboard and Panel

Select Query Type: Metrics 

Let's select iris_db_latency for instance

By default update interval is depends on a selected time interval, but can be changed in Query options, field Min Interval

Log Files and Application Errors can be shown with Logs Vizualization and as a Table


Please vote for the project 

You can contact me if you would like to get more functionality in the plugin.

Discussion (2)2
Log in or sign up to continue

Some example of code in Go

package main

import (


func main() {
  var addr = "localhost:1972"
  var namespace = "%SYS"
  var login = "_SYSTEM"
  var password = "SYS"

  connection, err := connection.Connect(addr, namespace, login, password)
  if err != nil {
    println("Connection failed:", err.Error())
  defer connection.Disconnect()

  // Kill ^A
  // Set ^A(1) = 1
  connection.GlobalSet("A", 1, 1)
  // Set ^A(1, 2) = "test"
  connection.GlobalSet("A", "test", 1, 1)
  // Set ^A(1, "2", 3) = "123"
  connection.GlobalSet("A", 123, 1, "a", 3)
  // Set ^A(2, 1) = "21test"
  connection.GlobalSet("A", "21test", 2, 1)
  // Set ^A(3, 1) = "test31"
  connection.GlobalSet("A", "test31", 3, 1)

  var globalFull = func(global string, subs ...interface{}) string {
    return fmt.Sprintf("^A(%v)", strings.Trim(strings.Join(strings.Split(fmt.Sprintf("%+v", subs), " "), ", "), "[]"))
  var queryGlobal func(global string, subs ...interface{})
  queryGlobal = func(global string, subs ...interface{}) {
    for i := ""; ; {
      if hasNext, _ := connection.GlobalNext("A", &i, subs...); !hasNext {
      var allSubs = []interface{}{i}
      allSubs = append(subs, allSubs...)
      hasValue, hasSubNode := connection.GlobalIsDefined("A", allSubs...)
      if hasValue {
        var value string
        connection.GlobalGet("A", &value, allSubs...)
        fmt.Printf("%v = %#v\n", globalFull("A", allSubs...), value)
      if hasSubNode {
        queryGlobal("A", allSubs...)