{
  "repo": "tidbcloud/sli-reporter",
  "binary": "sli-reporter",
  "binary_path": "cmd/main.go",
  "dependencies": {
    "HTTP GET /metrics": {
      "infrastructure": {},
      "services": []
    },
    "HTTP GET /debug/pprof/*": {
      "infrastructure": {},
      "services": []
    },
    "BackgroundTask.ProbeTiDBClusters": {
      "infrastructure": {
        "kubernetes": {
          "conditions": ["Always"],
          "operations": [
            {
              "operation": "LIST TiDBCluster",
              "resource": "TidbCluster",
              "trigger": "List all TiDBCluster CRs from informer cache",
              "conditions": ["Always"],
              "implementation": "m.tcLister.List(labels.Everything())"
            },
            {
              "operation": "LIST TiDBGroup",
              "resource": "TiDBGroup",
              "trigger": "List all TiDBGroups using controller-runtime client",
              "conditions": ["Always"],
              "implementation": "m.cli.List(context.TODO(), &tidbGroupList, &client.ListOptions{Namespace: \"\"})"
            },
            {
              "operation": "LIST Service",
              "resource": "Service",
              "trigger": "List services for TiDB/TiProxy in namespace",
              "conditions": ["Dedicated mode"],
              "implementation": "m.kubeCli.CoreV1().Services(namespace).List(ctx, metav1.ListOptions{LabelSelector: \"app.kubernetes.io/used-by=end-user,...\"})"
            },
            {
              "operation": "LIST Service (TiDBGroup)",
              "resource": "Service",
              "trigger": "List services for each TiDBGroup by group label",
              "conditions": ["Next-gen mode"],
              "implementation": "m.kubeCli.CoreV1().Services(tidbGroup.Namespace).List(ctx, metav1.ListOptions{LabelSelector: LabelGroup=tidbGroup.Name})"
            },
            {
              "operation": "LIST Service (TiProxyGroup)",
              "resource": "Service",
              "trigger": "List services for TiProxyGroup by group label",
              "conditions": ["Next-gen mode", "TiProxy enabled"],
              "implementation": "m.kubeCli.CoreV1().Services(tiproxyGroup.Namespace).List(ctx, metav1.ListOptions{LabelSelector: LabelGroup=tiproxyGroup.Name})"
            },
            {
              "operation": "LIST TiProxyGroup",
              "resource": "TiProxyGroup",
              "trigger": "List TiProxyGroups for next-gen clusters",
              "conditions": ["Next-gen mode"],
              "implementation": "m.cli.List(ctx, &tiproxyGroupList, &client.ListOptions{LabelSelector: selector})"
            },
            {
              "operation": "GET Job",
              "resource": "Job",
              "trigger": "Check if TiDB initializer job is complete",
              "conditions": ["Dedicated mode", "precheck"],
              "implementation": "kubeCli.BatchV1().Jobs(namespace).Get(ctx, TiDBInitializerMemberName(ClusterPrefix), metav1.GetOptions{})"
            }
          ]
        }
      },
      "services": [
        {
          "name": "tidb",
          "target_interface": "MySQL Handshake Protocol",
          "operation_type": "tcp_connect",
          "conditions": ["TiDB service exists", "Cluster not in creating status", "TiDB not suspended"],
          "operations": [
            {
              "operation": "MySQL Protocol Handshake",
              "trigger": "Probe TiDB service availability via MySQL handshake",
              "conditions": ["Always when probing"],
              "implementation": "handshakeCli.TryConnect(ctx, addr)"
            }
          ]
        },
        {
          "name": "tiproxy",
          "target_interface": "MySQL Handshake Protocol",
          "operation_type": "tcp_connect",
          "conditions": ["TiProxy configured in TidbCluster", "TiProxy service exists"],
          "operations": [
            {
              "operation": "MySQL Protocol Handshake",
              "trigger": "Probe TiProxy service availability via MySQL handshake",
              "conditions": ["TiProxy enabled"],
              "implementation": "handshakeCli.TryConnect(ctx, addr)"
            }
          ]
        }
      ]
    },
    "BackgroundTask.SendMetricsToFirehose": {
      "infrastructure": {
        "aws_firehose": {
          "conditions": ["Dedicated mode"],
          "operations": [
            {
              "operation": "PutRecord",
              "trigger": "Send metrics data to AWS Firehose delivery stream",
              "conditions": ["Always"],
              "implementation": "s.deliveryStreamCli.PutRecord(context.Background(), &aws_firehose.PutRecordInput{...})"
            }
          ]
        },
        "aws_sts": {
          "conditions": ["AWS_DELIVERY_STREAM_ROLE_ARN is set"],
          "operations": [
            {
              "operation": "AssumeRole",
              "trigger": "Assume IAM role for Firehose access",
              "conditions": ["Role ARN provided"],
              "implementation": "stscreds.NewAssumeRoleProvider(stsCli, deliveryStreamRoleArn)"
            }
          ]
        }
      },
      "services": []
    }
  },
  "notes": [
    "sli-reporter is a service level indicator prober that checks TiDB cluster availability",
    "It runs in Kubernetes and uses in-cluster config to access K8s API",
    "Probing is done via MySQL protocol handshake (not full connection)",
    "Metrics are sent to AWS Firehose for billing/monitoring purposes",
    "Two modes: DEDICATED (default) uses TidbCluster CR, NEXT-GEN uses TiDBGroup/TiProxyGroup CRs",
    "pprof endpoints are for debugging only and have no external dependencies"
  ]
}
