Grafana dashboard: 3 - APM Service Map
Description: This map shows all services sending traces and the interactions between them. Each arrow represents a service calling a specific operation in another service. The legend in the arrows includes the requests per second for that interaction.  If you are downsampling your traces before sending them to Promscale, then the number of requests per second will not be accurate but you'll be able to see how it compares to other operations.

APM Overview dashboard offered by Promscale on top of traces by leveraging SQL and TimescaleDB capabilities.

This dashboard contains service dependencies for the last 10 mins:

1. **Service Dependencies** describing Source, Target services, Operation, Number of Calls, Total Execution time, and  Average Execution time.
2. **Service Map** represents the nodes and edges here nodes are services and edges are connections between the services and the total number of calls between services. 


{
  "__inputs": [
    {
      "name": "DS_PROMSCALE-SQL",
      "label": "Promscale-SQL",
      "description": "TimescaleDB as PostgreSQL data source",
      "type": "datasource",
      "pluginId": "postgres",
      "pluginName": "PostgreSQL"
    }
  ],
  "__elements": [],
  "__requires": [
    {
      "type": "grafana",
      "id": "grafana",
      "name": "Grafana",
      "version": "8.5.2"
    },
    {
      "type": "panel",
      "id": "nodeGraph",
      "name": "Node Graph",
      "version": ""
    },
    {
      "type": "datasource",
      "id": "postgres",
      "name": "PostgreSQL",
      "version": "1.0.0"
    },
    {
      "type": "panel",
      "id": "table",
      "name": "Table",
      "version": ""
    }
  ],
  "annotations": {
    "list": [
      {
        "builtIn": 1,
        "datasource": {
          "type": "datasource",
          "uid": "grafana"
        },
        "enable": true,
        "hide": true,
        "iconColor": "rgba(0, 211, 255, 1)",
        "name": "Annotations & Alerts",
        "target": {
          "limit": 100,
          "matchAny": false,
          "tags": [],
          "type": "dashboard"
        },
        "type": "dashboard"
      }
    ]
  },
  "editable": true,
  "fiscalYearStartMonth": 0,
  "graphTooltip": 0,
  "id": null,
  "links": [
    {
      "asDropdown": false,
      "icon": "external link",
      "includeVars": true,
      "keepTime": true,
      "tags": [
        "promscale",
        "apm"
      ],
      "targetBlank": false,
      "title": "Menu",
      "tooltip": "",
      "type": "dashboards",
      "url": ""
    }
  ],
  "liveNow": false,
  "panels": [
    {
      "datasource": {
        "type": "postgres",
        "uid": "${DS_PROMSCALE-SQL}"
      },
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "thresholds"
          },
          "custom": {
            "align": "auto",
            "displayMode": "auto",
            "inspect": false
          },
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "red",
                "value": 80
              }
            ]
          }
        },
        "overrides": [
          {
            "matcher": {
              "id": "byName",
              "options": "Total exec time"
            },
            "properties": [
              {
                "id": "unit",
                "value": "ms"
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "Avg exec time"
            },
            "properties": [
              {
                "id": "unit",
                "value": "ms"
              },
              {
                "id": "decimals",
                "value": 2
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "Source"
            },
            "properties": [
              {
                "id": "links",
                "value": [
                  {
                    "title": "Show service overview",
                    "url": "/d/YWfN6wL7z/?var-service=${__value.raw}"
                  }
                ]
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "Target"
            },
            "properties": [
              {
                "id": "links",
                "value": [
                  {
                    "title": "Show service overview",
                    "url": "/d/YWfN6wL7z/?var-service=${__value.raw}"
                  }
                ]
              }
            ]
          }
        ]
      },
      "gridPos": {
        "h": 8,
        "w": 24,
        "x": 0,
        "y": 0
      },
      "id": 4,
      "options": {
        "footer": {
          "fields": "",
          "reducer": [
            "sum"
          ],
          "show": false
        },
        "showHeader": true
      },
      "pluginVersion": "8.5.2",
      "targets": [
        {
          "datasource": {
            "type": "postgres",
            "uid": "${DS_PROMSCALE-SQL}"
          },
          "format": "table",
          "group": [],
          "metricColumn": "none",
          "rawQuery": true,
          "rawSql": "SELECT\n    p.service_name as \"Source\",\n    k.service_name as \"Target\",\n    k.span_name as \"Operation\",\n    count(*) as \"Calls\",\n    sum(k.duration_ms) as \"Total exec time\",\n    avg(k.duration_ms) as \"Avg exec time\"\nFROM ps_trace.span p\nINNER JOIN ps_trace.span k\nON (p.trace_id = k.trace_id\nAND p.span_id = k.parent_span_id\nAND p.service_name != k.service_name)\nWHERE p.start_time >= NOW() - INTERVAL '10 minutes'\nAND k.start_time >= NOW() - INTERVAL '10 minutes'\nGROUP BY 1, 2, 3\nORDER BY 5 DESC",
          "refId": "A",
          "select": [
            [
              {
                "params": [
                  "span_duration_ms"
                ],
                "type": "column"
              }
            ]
          ],
          "table": "event",
          "timeColumn": "\"time\"",
          "timeColumnType": "timestamp",
          "where": [
            {
              "name": "$__timeFilter",
              "params": [],
              "type": "macro"
            }
          ]
        }
      ],
      "title": "Service Dependencies (last 10 minutes)",
      "type": "table"
    },
    {
      "datasource": {
        "type": "postgres",
        "uid": "${DS_PROMSCALE-SQL}"
      },
      "description": "This maps shows all services sending traces and the interactions between them.\nEach arrow represents a service calling a specific operation in another service. The legend in the arrows includes the requests per second for that interaction.  If you are downsampling your traces before sending them to Promscale, then the number of requests per second will not be accurate but you'll be able to see how it compares to other operations.",
      "gridPos": {
        "h": 19,
        "w": 24,
        "x": 0,
        "y": 8
      },
      "id": 2,
      "targets": [
        {
          "datasource": {
            "type": "postgres",
            "uid": "${DS_PROMSCALE-SQL}"
          },
          "format": "table",
          "group": [],
          "metricColumn": "none",
          "rawQuery": true,
          "rawSql": "SELECT \n   service_name as id,\n   service_name as title\nFROM ps_trace.span\nWHERE start_time >= NOW() - INTERVAL '10 minutes'\nGROUP BY service_name",
          "refId": "A",
          "select": [
            [
              {
                "params": [
                  "span_duration_ms"
                ],
                "type": "column"
              }
            ]
          ],
          "table": "event",
          "timeColumn": "\"time\"",
          "timeColumnType": "timestamp",
          "where": [
            {
              "name": "$__timeFilter",
              "params": [],
              "type": "macro"
            }
          ]
        },
        {
          "datasource": {
            "type": "postgres",
            "uid": "${DS_PROMSCALE-SQL}"
          },
          "format": "table",
          "group": [],
          "hide": false,
          "metricColumn": "none",
          "rawQuery": true,
          "rawSql": "SELECT\n    p.service_name || '->' || k.service_name || ':' || k.span_name as id,\n    p.service_name as source,\n    k.service_name as target,\n    k.span_name as \"mainStat\",\n    count(*) as \"secondaryStat\"\nFROM ps_trace.span p\nINNER JOIN ps_trace.span k\nON (p.trace_id = k.trace_id\nAND p.span_id = k.parent_span_id\nAND p.service_name != k.service_name)\nWHERE p.start_time >= NOW() - INTERVAL '10 minutes'\nAND k.start_time >= NOW() - INTERVAL '10 minutes'\nGROUP BY 1, 2, 3, 4",
          "refId": "B",
          "select": [
            [
              {
                "params": [
                  "span_duration_ms"
                ],
                "type": "column"
              }
            ]
          ],
          "table": "event",
          "timeColumn": "\"time\"",
          "timeColumnType": "timestamp",
          "where": [
            {
              "name": "$__timeFilter",
              "params": [],
              "type": "macro"
            }
          ]
        }
      ],
      "title": "Service Map (last 10 minutes)",
      "type": "nodeGraph"
    }
  ],
  "schemaVersion": 36,
  "style": "dark",
  "tags": [
    "promscale",
    "apm"
  ],
  "templating": {
    "list": []
  },
  "time": {
    "from": "now-1h",
    "to": "now"
  },
  "timepicker": {
    "hidden": true
  },
  "timezone": "",
  "title": "3 - APM Service Map",
  "uid": "K03UKvPnz",
  "version": 1,
  "weekStart": "",
  "gnetId": 16244,
  "description": "This map shows all services sending traces and the interactions between them. Each arrow represents a service calling a specific operation in another service. The legend in the arrows includes the requests per second for that interaction.  If you are downsampling your traces before sending them to Promscale, then the number of requests per second will not be accurate but you'll be able to see how it compares to other operations."
}