{
  "leansignal_demand_export": "1.0",
  "exported_at": "2026-07-17T00:00:00Z",
  "source_tenant": "leansignal-catalog",
  "catalog": {
    "slug": "leansignal-agent-otel-demand-essential",
    "integration": "leansignal-agent",
    "variant": "essential",
    "title": "LeanSignal Agent — Essential",
    "category": "Infrastructure",
    "dashboards": 1,
    "panels": 4,
    "alerts": 3,
    "docs_url": "https://docs.leansignal.io/integrations/leansignal-agent/"
  },
  "demand": {
    "ref": "demand",
    "name": "LeanSignal Agent — Essential (OpenTelemetry)",
    "description": "Is the agent healthy and shipping data? Control-stream connectivity, ingest rate, export failures, and memory — the four signals that tell you an agent is doing its job.",
    "dashboards": [
      {
        "ref": "dash-leansignal-agent",
        "name": "LeanSignal Agent — Essential",
        "description": "The LeanSignal Agent's own telemetry — control-stream health, pipeline throughput, export failures, queue depth, and process memory (essential variant).",
        "data": {
          "display": {
            "name": "LeanSignal Agent — Essential"
          },
          "panels": {
            "connection_up": {
              "kind": "Panel",
              "spec": {
                "display": {
                  "name": "Control stream connected",
                  "description": "1 = connected to LeanSignal, 0 = down. Down means no demand updates, index sync, or edit-mode queries."
                },
                "plugin": {
                  "kind": "TimeSeriesChart",
                  "spec": {
                    "legend": {
                      "position": "bottom",
                      "mode": "table",
                      "values": [
                        "last-number",
                        "mean",
                        "max"
                      ]
                    },
                    "yAxis": {
                      "format": {
                        "unit": "decimal"
                      },
                      "min": 0,
                      "max": 1
                    }
                  }
                },
                "queries": [
                  {
                    "kind": "TimeSeriesQuery",
                    "spec": {
                      "plugin": {
                        "kind": "PrometheusTimeSeriesQuery",
                        "spec": {
                          "query": "min by (leansignal_agent_name) (leansignal_edgecontroller_connection_up{leansignal_agent_name=~\"$instance\"})",
                          "seriesNameFormat": "{{leansignal_agent_name}}"
                        }
                      }
                    }
                  }
                ]
              }
            },
            "ingest_rate": {
              "kind": "Panel",
              "spec": {
                "display": {
                  "name": "Accepted metric points",
                  "description": "Points entering the pipeline, per receiver."
                },
                "plugin": {
                  "kind": "TimeSeriesChart",
                  "spec": {
                    "legend": {
                      "position": "bottom",
                      "mode": "table",
                      "values": [
                        "last-number",
                        "mean",
                        "max"
                      ]
                    },
                    "yAxis": {
                      "format": {
                        "unit": "counts/sec"
                      },
                      "min": 0
                    }
                  }
                },
                "queries": [
                  {
                    "kind": "TimeSeriesQuery",
                    "spec": {
                      "plugin": {
                        "kind": "PrometheusTimeSeriesQuery",
                        "spec": {
                          "query": "sum by (leansignal_agent_name, receiver) (rate(otelcol_receiver_accepted_metric_points_total{leansignal_agent_name=~\"$instance\"}[5m]))",
                          "seriesNameFormat": "{{leansignal_agent_name}} · {{receiver}}"
                        }
                      }
                    }
                  }
                ]
              }
            },
            "export_failures": {
              "kind": "Panel",
              "spec": {
                "display": {
                  "name": "Failed metric points",
                  "description": "Points that failed to write out — sustained failures mean data loss."
                },
                "plugin": {
                  "kind": "TimeSeriesChart",
                  "spec": {
                    "legend": {
                      "position": "bottom",
                      "mode": "table",
                      "values": [
                        "last-number",
                        "mean",
                        "max"
                      ]
                    },
                    "yAxis": {
                      "format": {
                        "unit": "counts/sec"
                      },
                      "min": 0
                    }
                  }
                },
                "queries": [
                  {
                    "kind": "TimeSeriesQuery",
                    "spec": {
                      "plugin": {
                        "kind": "PrometheusTimeSeriesQuery",
                        "spec": {
                          "query": "sum by (leansignal_agent_name, exporter) (rate(otelcol_exporter_send_failed_metric_points_total{leansignal_agent_name=~\"$instance\"}[5m]))",
                          "seriesNameFormat": "{{leansignal_agent_name}} · {{exporter}}"
                        }
                      }
                    }
                  }
                ]
              }
            },
            "memory_rss": {
              "kind": "Panel",
              "spec": {
                "display": {
                  "name": "Agent memory (RSS)",
                  "description": "Resident memory of the agent process."
                },
                "plugin": {
                  "kind": "TimeSeriesChart",
                  "spec": {
                    "legend": {
                      "position": "bottom",
                      "mode": "table",
                      "values": [
                        "last-number",
                        "mean",
                        "max"
                      ]
                    },
                    "yAxis": {
                      "format": {
                        "unit": "bytes"
                      },
                      "min": 0
                    }
                  }
                },
                "queries": [
                  {
                    "kind": "TimeSeriesQuery",
                    "spec": {
                      "plugin": {
                        "kind": "PrometheusTimeSeriesQuery",
                        "spec": {
                          "query": "max by (leansignal_agent_name) (otelcol_process_memory_rss_bytes{leansignal_agent_name=~\"$instance\"})",
                          "seriesNameFormat": "{{leansignal_agent_name}}"
                        }
                      }
                    }
                  }
                ]
              }
            }
          },
          "layouts": [
            {
              "kind": "Grid",
              "spec": {
                "display": {
                  "title": "Control Plane",
                  "collapse": {
                    "open": true
                  }
                },
                "items": [
                  {
                    "x": 0,
                    "y": 0,
                    "width": 12,
                    "height": 8,
                    "content": {
                      "$ref": "#/spec/panels/connection_up"
                    }
                  }
                ]
              }
            },
            {
              "kind": "Grid",
              "spec": {
                "display": {
                  "title": "Throughput",
                  "collapse": {
                    "open": true
                  }
                },
                "items": [
                  {
                    "x": 0,
                    "y": 0,
                    "width": 12,
                    "height": 8,
                    "content": {
                      "$ref": "#/spec/panels/ingest_rate"
                    }
                  }
                ]
              }
            },
            {
              "kind": "Grid",
              "spec": {
                "display": {
                  "title": "Export Health",
                  "collapse": {
                    "open": true
                  }
                },
                "items": [
                  {
                    "x": 0,
                    "y": 0,
                    "width": 12,
                    "height": 8,
                    "content": {
                      "$ref": "#/spec/panels/export_failures"
                    }
                  }
                ]
              }
            },
            {
              "kind": "Grid",
              "spec": {
                "display": {
                  "title": "Process",
                  "collapse": {
                    "open": true
                  }
                },
                "items": [
                  {
                    "x": 0,
                    "y": 0,
                    "width": 12,
                    "height": 8,
                    "content": {
                      "$ref": "#/spec/panels/memory_rss"
                    }
                  }
                ]
              }
            }
          ],
          "variables": [
            {
              "kind": "ListVariable",
              "spec": {
                "name": "instance",
                "display": {
                  "name": "Instance"
                },
                "allowAllValue": true,
                "allowMultiple": true,
                "customAllValue": ".*",
                "defaultValue": ".*",
                "plugin": {
                  "kind": "PrometheusLabelValuesVariable",
                  "spec": {
                    "labelName": "leansignal_agent_name"
                  }
                }
              }
            }
          ],
          "duration": "1h",
          "refreshInterval": "30s",
          "datasources": {}
        }
      }
    ],
    "alert_rules": [
      {
        "ref": "alert-agent-disconnected",
        "name": "Agent control stream down",
        "description": null,
        "query": "min by (leansignal_agent_name) (leansignal_edgecontroller_connection_up)",
        "condition_op": "lt",
        "threshold": 1,
        "interval": "1m",
        "for": "5m",
        "severity": "critical",
        "message": "Agent {{labels.leansignal_agent_name}} has lost its control stream to LeanSignal — no demand updates, no index sync, no UI queries.",
        "notify_on_resolve": true,
        "paused": false,
        "channels": []
      },
      {
        "ref": "alert-export-failures",
        "name": "Agent export failures",
        "description": null,
        "query": "sum by (leansignal_agent_name, exporter) (rate(otelcol_exporter_send_failed_metric_points_total[5m]))",
        "condition_op": "gt",
        "threshold": 0,
        "interval": "1m",
        "for": "10m",
        "severity": "critical",
        "message": "Agent {{labels.leansignal_agent_name}} is failing to write to {{labels.exporter}} ({{value}} points/s) — data-loss risk.",
        "notify_on_resolve": true,
        "paused": false,
        "channels": []
      },
      {
        "ref": "alert-queue-near-capacity",
        "name": "Agent export queue near capacity",
        "description": null,
        "query": "max by (leansignal_agent_name, exporter) (otelcol_exporter_queue_size / otelcol_exporter_queue_capacity)",
        "condition_op": "gt",
        "threshold": 0.8,
        "interval": "1m",
        "for": "5m",
        "severity": "warning",
        "message": "Agent {{labels.leansignal_agent_name}} export queue for {{labels.exporter}} is {{value | percent:1}} full — the next step is dropped data.",
        "notify_on_resolve": true,
        "paused": false,
        "channels": []
      }
    ]
  }
}
