{"id":34585160,"url":"https://github.com/planetscale/planetscale-datadog","last_synced_at":"2026-05-27T17:32:32.131Z","repository":{"id":287969031,"uuid":"959527923","full_name":"planetscale/planetscale-datadog","owner":"planetscale","description":"Datadog Agent Integration for scraping PlanetScale Metrics","archived":false,"fork":false,"pushed_at":"2026-04-17T16:57:11.000Z","size":64,"stargazers_count":5,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-04-17T18:39:25.788Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/planetscale.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-02T23:45:10.000Z","updated_at":"2026-04-17T16:56:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"72bbc21f-618c-4656-8d0d-adb5eacc3135","html_url":"https://github.com/planetscale/planetscale-datadog","commit_stats":null,"previous_names":["planetscale/planetscale-datadog"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/planetscale/planetscale-datadog","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/planetscale%2Fplanetscale-datadog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/planetscale%2Fplanetscale-datadog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/planetscale%2Fplanetscale-datadog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/planetscale%2Fplanetscale-datadog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/planetscale","download_url":"https://codeload.github.com/planetscale/planetscale-datadog/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/planetscale%2Fplanetscale-datadog/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33577633,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-27T02:00:06.184Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-24T10:29:46.128Z","updated_at":"2026-05-27T17:32:32.126Z","avatar_url":"https://github.com/planetscale.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Datadog PlanetScale Custom Check\n\n## Overview\n\nThis Datadog Agent check integrates with the PlanetScale API to dynamically discover Prometheus scrape endpoints associated with database branches within a specified organization. It then utilizes the Agent's built-in OpenMetrics capabilities to collect metrics from these discovered endpoints.\n\nThis allows you to monitor metrics exposed by your PlanetScale database branches directly within Datadog.\n\n## Prerequisites\n\n*   **Datadog Agent:** Modern Release of Version 7 installed and running.\n*   **PlanetScale Account:** Access to the PlanetScale organization you wish to monitor.\n*   **PlanetScale Service Token:** A Service Token (ID and Secret) with `read_metrics_endpoints` permissions. Create one in your PlanetScale organization settings.\n\n## Installation\n\n1.  **Copy Check Files:**\n    *   Place `planetscale.py` into your Datadog Agent's `checks.d` directory.\n        *   Linux: `/etc/datadog-agent/checks.d/`\n        *   macOS: `/opt/datadog-agent/etc/checks.d/`\n        *   Windows: `C:\\ProgramData\\Datadog\\checks.d\\`\n        ```bash\n        # Linux (adjust path if necessary)\n        sudo -u dd-agent cp planetscale.py /etc/datadog-agent/checks.d/.\n\n        # MacOS (adjust path if necessary)\n        sudo -u dd-agent cp planetscale.py /opt/datadog-agent/etc/checks.d/.\n        ```\n\n2.  **Copy Configuration File:**\n    *   Copy the `conf.d/planetscale.yaml.example` file to your Agent's `conf.d` directory (e.g., `/etc/datadog-agent/conf.d/`) and rename it to `planetscale.yaml`.\n3.  **Install Dependencies:**\n    * Place the `requirements.txt` file somewhere accessible by your datadog-agent, such as `/etc/datadog-agent/planetscale.txt`\n    *   Install the required Python packages into the Datadog Agent's embedded Python environment. Open a terminal with appropriate permissions and run:\n        ```bash\n        # Linux/macOS (adjust path if necessary)\n        sudo -u dd-agent /opt/datadog-agent/embedded/bin/pip install -r /etc/datadog-agent/planetscale.txt\n\n        # Windows (adjust path if necessary, run as Administrator)\n        # \"C:\\Program Files\\Datadog\\Datadog Agent\\embedded\\python.exe\" -m pip install -r \"C:\\ProgramData\\Datadog\\planetscale.txt\"\n        ```\n4.  **Restart Datadog Agent:** Restart the Agent service to load the new check and configuration.\n\n## Configuration\n\nEdit the `conf.d/planetscale.yaml` file to configure the check:\n\n```yaml\ninstances:\n  - # Required: Your PlanetScale organization ID\n    planetscale_organization: '\u003cYOUR_PLANETSCALE_ORG_NAME\u003e'\n\n    # Required: Your PlanetScale Service Token ID\n    ps_service_token_id: '\u003cYOUR_PLANETSCALE_SERVICE_TOKEN_ID\u003e'\n\n    # Required: Your PlanetScale Service Token Secret\n    # Consider using Datadog secrets management for production:\n    # https://docs.datadoghq.com/agent/guide/secrets-management/\n    ps_service_token_secret: '\u003cYOUR_PLANETSCALE_SERVICE_TOKEN_SECRET\u003e'\n\n    # Required: Namespace for the metrics (prepended to metric names)\n    namespace: 'planetscale'\n\n    # Required: List of metrics to collect from discovered endpoints.\n    # Use simple names or mappings for renaming/type overrides.\n    metrics:\n      - planetscale_vtgate_queries_duration: vtgate_query_duration # Example: Rename metric\n\n      # Add other metrics exposed by the PlanetScale endpoints here\n      # Example with type override:\n      # - some_metric:\n      #     name: my_metric_gauge\n      #     type: gauge\n\n    # Optional: Set the collection interval (in seconds)\n    # Default is 15s. Set to 60s to match ~1 min metric updates from PlanetScale.\n    min_collection_interval: 60\n    send_distribution_buckets: true\n    collect_counters_with_distributions: true\n\n    # Optional: Maximum number of concurrent requests to make to PlanetScale endpoints\n    # Adjust based on your needs and available resources\n    max_concurrent_requests: 1\n\n    # Optional OpenMetricsBaseCheck settings (applied to discovered endpoints)\n    # tags:\n    #   - 'static_tag:value' # Additional static tags added to all metrics\n    # timeout: 5 # Override default timeout (10s) for scraping individual endpoints\n    # ssl_verify: true # Set to false to disable SSL verification (not recommended)\n    # prometheus_metrics_prefix: 'planetscale' # Optional prefix to remove from metric names\n```\n\nNote that Datadog strips some metric suffixes:\n\n\u003e Starting in Datadog Agent v7.32.0, in adherence to the OpenMetrics specification standard, counter names ending in _total must be specified without the _total suffix. For example, to collect promhttp_metric_handler_requests_total, specify the metric name promhttp_metric_handler_requests. This submits to Datadog the metric name appended with .count, promhttp_metric_handler_requests.count.\n\nFrom their [documentation](https://github.com/DataDog/integrations-core/blob/master/openmetrics/README.md). This means when configuring the agent to scrape `planetscale_mysql_bytes_received_total`, you want to configure Datadog for `planetscale_mysql_bytes_received`.\n\n**Key Configuration Options:**\n\n*   `planetscale_organization`: The ID of the PlanetScale organization to query.\n*   `ps_service_token_id`, `ps_service_token_secret`: Credentials for authenticating with the PlanetScale API.\n*   `namespace`: Prefix added to all collected metrics (e.g., `planetscale.cluster_size`).\n*   `metrics`: A list defining which metrics to collect from the discovered Prometheus endpoints. You can rename metrics or override their types here.\n*   `tags`: Optional static tags to add to all metrics collected by this instance. Discovered labels (like database and branch name) are automatically added as tags prefixed with `ps_`.\n*   `database_tags`: Optional mapping of database name to a list of extra tags, applied only to metrics from that database. Additive on top of `tags`. Each entry can specify one or more tags. Use this when databases in a single org need distinct tagging — for example, mixed environments in one org, per-team ownership, tiering, or compliance scope:\n\n    ```yaml\n    database_tags:\n      my-prod-db: ['env:prod', 'team:billing', 'tier:critical']\n      my-staging-db: ['env:staging']\n      shared-analytics-db: ['team:data', 'tier:standard', 'compliance:pci']\n    ```\n\n## Validation\n\n1.  **Check Agent Status:** Run the Datadog Agent status command (e.g., `sudo -u dd-agent -- datadog-agent check planetscale`) and look for configuration errors.\n2.  **Look for Metrics:** Search for metrics starting with `planetscale.` in your Datadog Metrics Explorer. Allow a few minutes for data to appear after restarting the Agent.\n3.  **Check Service Checks:** Look for the following service checks:\n    *   `planetscale.api.can_connect`: Reports the status of the connection to the PlanetScale API. Tags: `planetscale_org:\u003corg_id\u003e`.\n    *   `ps.openmetrics.health`: Reports the status of scraping individual discovered endpoints. Tags include discovered labels.\n\n## Troubleshooting\n\n*   **Configuration Errors:** Double-check `planetscale.yaml` for correct formatting, valid credentials, and organization ID. Check the Agent status report for specific errors.\n*   **API Connection Issues:** Verify the Service Token ID and Secret are correct and have the necessary permissions in PlanetScale. Check the `planetscale.api.can_connect` service check status. Ensure the Datadog Agent host has network connectivity to `api.planetscale.com`.\n*   **Scraping Errors:** Check the `planetscale.target.can_scrape` service check. Verify the discovered endpoints are accessible from the Agent host and are serving valid OpenMetrics/Prometheus data. Check Agent logs (`agent.log`, `collector.log`) for more detailed errors related to scraping.\n*   **Missing Metrics:** Ensure the metric names in your `planetscale.yaml` `metrics` list exactly match the names exposed by the PlanetScale endpoints (after any potential `prometheus_metrics_prefix` removal). Verify the `namespace` is correct.\n\n## Development\n\nUnit tests cover the check's config construction, tag merging, URL assembly, and API error handling. To run them:\n\n```bash\npython3 -m venv .venv\n.venv/bin/pip install -r tests/requirements.txt\n.venv/bin/pytest\n```\n\nThe tests patch `create_scraper` so no Datadog Agent runtime or PlanetScale API credentials are required.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplanetscale%2Fplanetscale-datadog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplanetscale%2Fplanetscale-datadog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplanetscale%2Fplanetscale-datadog/lists"}