diff --git a/metrics-collector/README.md b/metrics-collector/README.md index df8f49576..370f53c21 100644 --- a/metrics-collector/README.md +++ b/metrics-collector/README.md @@ -179,10 +179,20 @@ ibmcloud ce jobrun submit \ The metrics collector scrapes CPU/Memory metrics from your Code Engine applications, jobs, and builds. Metrics of all running instances are scraped every 30 seconds. -Once, metrics are ingested into an IBM Cloud Monitoring instance, the pre-populated dashboard "IBM Cloud Code Engine - Component Resource Overview" appears in Dashboard Manager. +Once, metrics are ingested into an IBM Cloud Monitoring instance, the pre-populated dashboard "Code Engine - Component Resource Overview" appears in Dashboard Manager. No manual dashboard upload is required. Allow a few minutes for the first data to arrive. ![](./images/monitoring-dashboard-library.png) +The dashboard provides the following panels. Use the `code_engine_project_name`, `component_type` and `component_name` scope filters to narrow them down. + +- **Components with Running Instances** / **Running Instances** - Number of components and instances currently running +- **Total Available CPUs** / **Total Used CPUs** / **Total CPU Utilization %** - Aggregated CPU capacity, usage and utilization +- **Total Available Memory** / **Total Used Memory** / **Total Memory Utilization %** - Aggregated memory capacity, usage and utilization +- **CPU Utilization % (by Component)** - CPU utilization per component +- **CPU Usage (per Instance)** - Raw CPU usage per instance +- **Memory Utilization % (by Component)** - Memory utilization per component +- **Memory Usage (per Instance)** - Raw memory usage per instance + #### Exposed Metrics The following Prometheus metrics are exposed as gauges: @@ -396,6 +406,12 @@ app:"codeengine" AND message.metric:"instance-resources" - **Missing `/etc/secrets/monitoring-apikey` file**: Ensure the secret is created and properly mounted - **Invalid API key**: Regenerate the monitoring API key and update the secret +**Dashboard Not Showing Data:** +- Verify the metrics collector is running with `METRICS_ENABLED=true` +- Check that metrics are being sent to IBM Cloud Monitoring +- Ensure the Prometheus remote write configuration is correct +- Wait a few minutes for data to appear (initial scrape interval) + **General Issues:** - **Missing or wrong `METRICS_REMOTE_WRITE_FQDN`**: Verify the endpoint matches your region's ingestion endpoint - **Prometheus agent fails to start**: Check the logs for configuration errors or network connectivity issues diff --git a/metrics-collector/setup/dashboard-code_engine_resource_consumption_metrics.json b/metrics-collector/setup/ibm-cloud-logs/dashboard-code_engine_resource_consumption_metrics.json similarity index 100% rename from metrics-collector/setup/dashboard-code_engine_resource_consumption_metrics.json rename to metrics-collector/setup/ibm-cloud-logs/dashboard-code_engine_resource_consumption_metrics.json diff --git a/metrics-collector/setup/ibm-cloud-monitoring/README.md b/metrics-collector/setup/ibm-cloud-monitoring/README.md deleted file mode 100644 index e58e9b94e..000000000 --- a/metrics-collector/setup/ibm-cloud-monitoring/README.md +++ /dev/null @@ -1,344 +0,0 @@ -# IBM Cloud Monitoring Dashboard Setup - -This directory contains tools and dashboards for IBM Cloud Monitoring (Sysdig) integration. - -## Files - -- **`monitoring-dashboard-manager.sh`**: Unified bash script for managing dashboards (recommended) -- **`code-engine-component-resource-overview.json`**: Dashboard configuration for Code Engine resource monitoring - -## Quick Start - -### Prerequisites - -1. **IBM Cloud CLI** installed and logged in -2. **jq** (JSON processor) installed -3. **curl** installed (usually pre-installed) -4. An IBM Cloud Monitoring (Sysdig) instance - -### Installation - -The bash script is ready to use. Make it executable if needed: - -```bash -chmod +x monitoring-dashboard-manager.sh -``` - -### Basic Usage - -```bash -# Show help -./monitoring-dashboard-manager.sh help - -# List all monitoring instances -./monitoring-dashboard-manager.sh list-instances - -# List dashboards in an instance -./monitoring-dashboard-manager.sh list-dashboards \ - --instance-id "YOUR_INSTANCE_ID" \ - --region us-south - -# Export a dashboard -./monitoring-dashboard-manager.sh export \ - --instance-id "YOUR_INSTANCE_ID" \ - --region us-south \ - --dashboard-id 12345 - -# Import/create a dashboard -./monitoring-dashboard-manager.sh import \ - --instance-id "YOUR_INSTANCE_ID" \ - --region us-south \ - --file code-engine-component-resource-overview.json -``` - -## Bash Script: monitoring-dashboard-manager.sh - -The unified bash script provides all dashboard management functionality using IBM Cloud CLI authentication. - -### Features - -- ✅ List monitoring instances (global and by region) -- ✅ List dashboards with name, ID, and last updated timestamp -- ✅ Export dashboards to JSON files -- ✅ Create new dashboards from JSON files -- ✅ Update existing dashboards -- ✅ Uses IBM Cloud CLI login context (no API key needed) -- ✅ Comprehensive error handling -- ✅ Table and JSON output formats -- ✅ Verbose mode for debugging - -### Authentication - -The script uses your current IBM Cloud CLI login session. Ensure you're logged in: - -```bash -ibmcloud login -``` - -The script automatically retrieves the IAM token using: -```bash -ibmcloud iam oauth-tokens --output JSON | jq -r '.iam_token' -``` - -### Commands - -#### List Monitoring Instances - -List all monitoring instances in your account: - -```bash -# List all instances -./monitoring-dashboard-manager.sh list-instances - -# List instances in a specific region -./monitoring-dashboard-manager.sh list-instances --region us-south - -# Output in JSON format -./monitoring-dashboard-manager.sh list-instances --format json -``` - -#### List Dashboards - -List all dashboards in a monitoring instance: - -```bash -./monitoring-dashboard-manager.sh list-dashboards \ - --instance-id "12345678-1234-1234-1234-123456789abc" \ - --region us-south - -# JSON format -./monitoring-dashboard-manager.sh list-dashboards \ - --instance-id "12345678-1234-1234-1234-123456789abc" \ - --region us-south \ - --format json -``` - -#### Export Dashboard - -Export a dashboard to a JSON file: - -```bash -# Export with auto-generated filename -./monitoring-dashboard-manager.sh export \ - --instance-id "12345678-1234-1234-1234-123456789abc" \ - --region us-south \ - --dashboard-id 12345 - -# Export with custom filename -./monitoring-dashboard-manager.sh export \ - --instance-id "12345678-1234-1234-1234-123456789abc" \ - --region us-south \ - --dashboard-id 12345 \ - --output my-dashboard.json -``` - -#### Import/Create Dashboard - -Import a dashboard from a JSON file: - -```bash -# Create new dashboard -./monitoring-dashboard-manager.sh import \ - --instance-id "12345678-1234-1234-1234-123456789abc" \ - --region us-south \ - --file code-engine-component-resource-overview.json - -# Update existing dashboard (by name) -./monitoring-dashboard-manager.sh import \ - --instance-id "12345678-1234-1234-1234-123456789abc" \ - --region us-south \ - --file code-engine-component-resource-overview.json \ - --update -``` - -### Environment Variables - -You can set default values using environment variables: - -```bash -export SYSDIG_INSTANCE_ID="12345678-1234-1234-1234-123456789abc" -export SYSDIG_REGION="us-south" - -# Now you can omit --instance-id and --region -./monitoring-dashboard-manager.sh list-dashboards -``` - -### Supported Regions - -- `us-south` - US South (Dallas) -- `us-east` - US East (Washington DC) -- `eu-de` - EU Central (Frankfurt) -- `eu-es` - EU Spain (Madrid) -- `eu-gb` - EU GB (London) -- `jp-tok` - Japan (Tokyo) -- `in-che` - India (Chennai) -- `jp-osa` - Japan (Osaka) -- `au-syd` - Australia (Sydney) -- `ca-tor` - Canada (Toronto) -- `br-sao` - Brazil (São Paulo) - -### Verbose Mode - -Enable verbose output for debugging: - -```bash -./monitoring-dashboard-manager.sh list-instances --verbose -``` - -## Dashboard: Code Engine Container Resource Overview - -The `code-engine-component-resource-overview.json` dashboard provides comprehensive monitoring of Code Engine resources. - -### Panels - -1. **CPU Usage vs Limit (per Pod)** - Compares live CPU usage to configured limits -2. **CPU Utilization % (per App)** - CPU percentage by component -3. **Memory Usage vs Limit (per Pod)** - Compares memory usage to limits -4. **Memory Utilization % (per App)** - Memory percentage by component -5. **CPU Utilization % (per Namespace)** - Namespace-level CPU monitoring -6. **Memory Utilization % (per Namespace)** - Namespace-level memory monitoring -7. **CPU Utilization % (per Revision/Parent)** - Revision-level CPU tracking -8. **Memory Utilization % (per Revision/Parent)** - Revision-level memory tracking -9. **Top Pods by CPU** - Top 10 CPU consumers -10. **Top Pods by Memory** - Top 10 memory consumers -11. **Cluster CPU Utilization (%)** - Global CPU percentage -12. **Cluster Memory Utilization (%)** - Global memory percentage - -### Required Metrics - -The dashboard uses the following Prometheus metrics: - -- `codeengine_container_cpu_usage_millicores` -- `codeengine_container_cpu_limit_millicores` -- `codeengine_container_memory_usage_bytes` -- `codeengine_container_memory_limit_bytes` - -These metrics are exposed by the Code Engine metrics collector when running with `METRICS_ENABLED=true`. - -## Getting Your IBM Cloud Credentials - -### IBM Cloud IAM API Key (for Python scripts) - -1. Log in to [IBM Cloud Console](https://cloud.ibm.com) -2. Go to **Manage** > **Access (IAM)** > **API keys** -3. Click **Create an IBM Cloud API key** -4. Give it a name and description -5. Copy and save the API key securely - -### Monitoring Instance ID - -1. Navigate to your IBM Cloud Monitoring instance -2. Click on **Overview** or **Settings** -3. Copy the **Instance ID** (GUID format: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`) - -### Region - -Note the region where your Monitoring instance is deployed (e.g., `us-south`, `eu-de`) - -## Complete Example Workflow - -```bash -# 1. Ensure you're logged in to IBM Cloud -ibmcloud login - -# 2. List your monitoring instances to find the instance ID -./monitoring-dashboard-manager.sh list-instances - -# Example output: -# NAME INSTANCE_ID REGION STATE -# my-monitoring-instance 12345678-1234-1234-1234-123456789abc us-south active - -# 3. Set environment variables for convenience -export SYSDIG_INSTANCE_ID="12345678-1234-1234-1234-123456789abc" -export SYSDIG_REGION="us-south" - -# 4. List existing dashboards -./monitoring-dashboard-manager.sh list-dashboards - -# 5. Import the Code Engine dashboard -./monitoring-dashboard-manager.sh import \ - --file code-engine-component-resource-overview.json - -# Output: -# → Loading dashboard configuration from: code-engine-component-resource-overview.json -# → Dashboard name: IBM Code Engine - Container Resource Overview -# → Checking if dashboard already exists... -# → Dashboard does not exist. Creating new dashboard... -# ✓ Dashboard 'IBM Code Engine - Container Resource Overview' created successfully! -# -# Dashboard ID: 12345 -# Dashboard URL: https://us-south.monitoring.cloud.ibm.com/#/dashboards/12345 - -# 6. Later, update the dashboard with changes -./monitoring-dashboard-manager.sh import \ - --file code-engine-component-resource-overview.json \ - --update - -# 7. Export a dashboard for backup -./monitoring-dashboard-manager.sh export --dashboard-id 12345 -``` - -## Troubleshooting - -### Authentication Errors - -**Error: "Not logged in to IBM Cloud CLI"** -- Solution: Run `ibmcloud login` to authenticate - -**Error: "Failed to obtain IAM token"** -- Solution: Ensure you're logged in and your session hasn't expired -- Try: `ibmcloud iam oauth-tokens` to verify token generation - -### Missing Tools - -**Error: "Missing required tools: jq"** -- macOS: `brew install jq` -- Ubuntu/Debian: `sudo apt-get install jq` -- RHEL/CentOS: `sudo yum install jq` - -**Error: "Missing required tools: ibmcloud"** -- Install IBM Cloud CLI: https://cloud.ibm.com/docs/cli?topic=cli-install-ibmcloud-cli - -### Dashboard Not Showing Data - -If the dashboard shows no data: -- Verify the metrics collector is running with `METRICS_ENABLED=true` -- Check that metrics are being sent to IBM Cloud Monitoring -- Ensure the Prometheus remote write configuration is correct -- Wait a few minutes for data to appear (initial scrape interval) - -### Import Errors - -**Error: "Dashboard configuration must include a 'name' field"** -- Ensure your JSON file has a `name` field at the top level - -**Error: "Dashboard 'X' already exists"** -- Use the `--update` flag to update the existing dashboard -- Or rename the dashboard in the JSON file - -### API Errors - -**Error: "API request failed (HTTP 403)"** -- Verify you have access to the monitoring instance -- Check that the instance ID is correct -- Ensure your IBM Cloud account has the necessary permissions - -**Error: "API request failed (HTTP 404)"** -- Verify the instance ID and region are correct -- Check that the dashboard ID exists (for export operations) - -## Additional Resources - -- [IBM Cloud Monitoring Documentation](https://cloud.ibm.com/docs/monitoring) -- [Sysdig Dashboard API](https://docs.sysdig.com/en/docs/developer-tools/sysdig-rest-api-conventions/) -- [PromQL Query Language](https://prometheus.io/docs/prometheus/latest/querying/basics/) -- [IBM Cloud CLI Documentation](https://cloud.ibm.com/docs/cli) - -## Contributing - -When making changes to the dashboard or scripts: - -1. Test thoroughly with a real IBM Cloud Monitoring instance -2. Update this README with any new features or changes -3. Ensure backward compatibility where possible -4. Document any breaking changes clearly diff --git a/metrics-collector/setup/ibm-cloud-monitoring/code-engine-component-resource-overview.json b/metrics-collector/setup/ibm-cloud-monitoring/code-engine-component-resource-overview.json deleted file mode 100644 index 3427e52ed..000000000 --- a/metrics-collector/setup/ibm-cloud-monitoring/code-engine-component-resource-overview.json +++ /dev/null @@ -1,1233 +0,0 @@ -{ - "name": "IBM Cloud Code Engine - Component Resource Overview", - "panels": [ - { - "id": 1, - "type": "text", - "name": "Dashboard Overview", - "description": "", - "nullValueDisplayText": null, - "links": null, - "markdownSource": "Monitor vCPU, and Memory usage across Code Engine components.\n\n**Use the scope filters above to narrow by:**\n- `component_type` (app, job, build)\n- `component_name` (specific app/job/build name)", - "transparentBackground": false, - "panelTitleVisible": true, - "textAutosized": false - }, - { - "id": 5, - "type": "advancedTimechart", - "name": "vCPU Utilization % (by Component)", - "description": "vCPU usage as percentage of limit, grouped by ibm_codeengine_component_name", - "nullValueDisplayText": null, - "links": null, - "advancedQueries": [ - { - "query": "(sum by (ibm_codeengine_project_name, ibm_codeengine_component_name) (ibm_codeengine_instance_cpu_usage_millicores{$__scope}) / sum by (ibm_codeengine_project_name, ibm_codeengine_component_name) (ibm_codeengine_instance_cpu_limit_millicores{$__scope})) * 100", - "enabled": true, - "displayInfo": { - "displayName": "project > component name", - "timeSeriesDisplayNameTemplate": "{{ibm_codeengine_project_name}} > {{ibm_codeengine_component_name}}", - "type": "lines" - }, - "format": { - "unit": "%", - "inputFormat": "0-100", - "displayFormat": "auto", - "decimals": 1, - "yAxis": "auto", - "nullValueDisplayMode": "connectSolid", - "minInterval": null - }, - "compareTo": { - "enabled": false, - "delta": 1, - "timeFormat": "day" - } - } - ], - "legendConfiguration": { - "enabled": true, - "position": "bottom", - "layout": "table", - "showCurrent": true, - "showMax": true, - "showMin": true, - "width": null, - "height": null - }, - "axesConfiguration": { - "bottom": { - "enabled": true - }, - "left": { - "enabled": true, - "displayName": null, - "unit": "%", - "displayFormat": "auto", - "decimals": null, - "minValue": 0, - "maxValue": null, - "minInputFormat": "0-100", - "maxInputFormat": "0-100", - "scale": "linear" - }, - "right": { - "enabled": false, - "displayName": null, - "unit": "%", - "displayFormat": "auto", - "decimals": null, - "minValue": 0, - "maxValue": null, - "minInputFormat": "0-100", - "maxInputFormat": "0-100", - "scale": "linear" - } - }, - "numberThresholds": { - "useDefaults": null, - "values": [ - { - "severity": "high", - "value": 80, - "inputFormat": "0-100", - "displayText": "" - }, - { - "severity": "ok", - "value": 0, - "inputFormat": "0-100", - "displayText": "" - } - ], - "base": { - "severity": "none", - "displayText": "" - } - } - }, - { - "id": 6, - "type": "advancedTimechart", - "name": "Memory Utilization % (by Component)", - "description": "Memory usage as percentage of limit, grouped by ibm_codeengine_component_name", - "nullValueDisplayText": null, - "links": null, - "advancedQueries": [ - { - "query": "(sum by (ibm_codeengine_project_name, ibm_codeengine_component_name) (ibm_codeengine_instance_memory_usage_bytes{$__scope}) / sum by (ibm_codeengine_project_name, ibm_codeengine_component_name) (ibm_codeengine_instance_memory_limit_bytes{$__scope})) * 100", - "enabled": true, - "displayInfo": { - "displayName": "project > component", - "timeSeriesDisplayNameTemplate": "{{ibm_codeengine_project_name}} > {{ibm_codeengine_component_name}}", - "type": "lines" - }, - "format": { - "unit": "%", - "inputFormat": "0-100", - "displayFormat": "auto", - "decimals": 1, - "yAxis": "auto", - "nullValueDisplayMode": "connectSolid", - "minInterval": null - }, - "compareTo": { - "enabled": false, - "delta": 1, - "timeFormat": "day" - } - } - ], - "legendConfiguration": { - "enabled": true, - "position": "bottom", - "layout": "table", - "showCurrent": true, - "showMax": true, - "showMin": true, - "width": null, - "height": null - }, - "axesConfiguration": { - "bottom": { - "enabled": true - }, - "left": { - "enabled": true, - "displayName": null, - "unit": "auto", - "displayFormat": "auto", - "decimals": null, - "minValue": 0, - "maxValue": null, - "minInputFormat": "0-100", - "maxInputFormat": "0-100", - "scale": "linear" - }, - "right": { - "enabled": true, - "displayName": null, - "unit": "auto", - "displayFormat": "auto", - "decimals": null, - "minValue": 0, - "maxValue": null, - "minInputFormat": "1", - "maxInputFormat": "1", - "scale": "linear" - } - }, - "numberThresholds": { - "useDefaults": null, - "values": [ - { - "severity": "high", - "value": 80, - "inputFormat": "0-100", - "displayText": "" - }, - { - "severity": "ok", - "value": 30, - "inputFormat": "0-100", - "displayText": "" - } - ], - "base": { - "severity": "none", - "displayText": "" - } - } - }, - { - "id": 8, - "type": "advancedNumber", - "name": "Total vCPU Utilization in %", - "description": "Overall vCPU utilization across all instances", - "nullValueDisplayText": null, - "links": null, - "advancedQueries": [ - { - "query": "(sum(ibm_codeengine_instance_cpu_usage_millicores{$__scope}) / sum(ibm_codeengine_instance_cpu_limit_millicores{$__scope})) * 100", - "enabled": true, - "displayInfo": { - "displayName": "CPU %", - "timeSeriesDisplayNameTemplate": null, - "type": "lines" - }, - "format": { - "unit": "%", - "inputFormat": "0-100", - "displayFormat": "auto", - "decimals": 1, - "yAxis": "auto", - "nullValueDisplayMode": "nullGap", - "minInterval": null - }, - "compareTo": { - "enabled": true, - "delta": 1, - "timeFormat": "hour" - } - } - ], - "numberThresholds": { - "useDefaults": null, - "values": [ - { - "severity": "medium", - "value": 90, - "inputFormat": "0-100", - "displayText": "" - }, - { - "severity": "ok", - "value": 30, - "inputFormat": "0-100", - "displayText": "" - }, - { - "severity": "none", - "value": 1, - "inputFormat": "0-100", - "displayText": "" - } - ], - "base": { - "severity": "none", - "displayText": "" - } - } - }, - { - "id": 9, - "type": "advancedNumber", - "name": "Total Memory Utilization in %", - "description": "Overall memory utilization across all instances", - "nullValueDisplayText": null, - "links": null, - "advancedQueries": [ - { - "query": "(sum(ibm_codeengine_instance_memory_usage_bytes{$__scope}) / sum(ibm_codeengine_instance_memory_limit_bytes{$__scope})) * 100", - "enabled": true, - "displayInfo": { - "displayName": "Memory %", - "timeSeriesDisplayNameTemplate": null, - "type": "lines" - }, - "format": { - "unit": "%", - "inputFormat": "0-100", - "displayFormat": "auto", - "decimals": 1, - "yAxis": "auto", - "nullValueDisplayMode": "nullGap", - "minInterval": null - }, - "compareTo": { - "enabled": true, - "delta": 1, - "timeFormat": "hour" - } - } - ], - "numberThresholds": { - "useDefaults": null, - "values": [ - { - "severity": "medium", - "value": 80, - "inputFormat": "0-100", - "displayText": "" - }, - { - "severity": "ok", - "value": 30, - "inputFormat": "0-100", - "displayText": "" - }, - { - "severity": "none", - "value": 1, - "inputFormat": "0-100", - "displayText": "" - } - ], - "base": { - "severity": "none", - "displayText": "" - } - } - }, - { - "id": 11, - "type": "advancedNumber", - "name": "Total Available vCPUs", - "description": "Overall number of available vCPUs across all instances", - "nullValueDisplayText": null, - "links": null, - "advancedQueries": [ - { - "query": "sum(ibm_codeengine_instance_cpu_limit_millicores{$__scope}) / 1000", - "enabled": true, - "displayInfo": { - "displayName": "CPU %", - "timeSeriesDisplayNameTemplate": null, - "type": "lines" - }, - "format": { - "unit": "number", - "inputFormat": "1", - "displayFormat": "auto", - "decimals": 1, - "yAxis": "auto", - "nullValueDisplayMode": "nullGap", - "minInterval": null - }, - "compareTo": { - "enabled": true, - "delta": 1, - "timeFormat": "hour" - } - } - ], - "numberThresholds": { - "useDefaults": null, - "values": [ - { - "severity": "info", - "value": 80, - "inputFormat": "1", - "displayText": "" - } - ], - "base": { - "severity": "none", - "displayText": "" - } - } - }, - { - "id": 12, - "type": "advancedNumber", - "name": "Total Available Memory", - "description": "Overall amount of available memory across all instances", - "nullValueDisplayText": null, - "links": null, - "advancedQueries": [ - { - "query": "sum(ibm_codeengine_instance_memory_limit_bytes{$__scope})", - "enabled": true, - "displayInfo": { - "displayName": "Memory %", - "timeSeriesDisplayNameTemplate": null, - "type": "lines" - }, - "format": { - "unit": "byte", - "inputFormat": "B", - "displayFormat": "auto", - "decimals": 1, - "yAxis": "auto", - "nullValueDisplayMode": "nullGap", - "minInterval": null - }, - "compareTo": { - "enabled": true, - "delta": 1, - "timeFormat": "hour" - } - } - ], - "numberThresholds": { - "useDefaults": null, - "values": [], - "base": { - "severity": "none", - "displayText": "" - } - } - }, - { - "id": 13, - "type": "advancedNumber", - "name": "Total Used vCPUs", - "description": "Actual number of vCPUs that are used across all instances", - "nullValueDisplayText": null, - "links": null, - "advancedQueries": [ - { - "query": "sum(ibm_codeengine_instance_cpu_usage_millicores{$__scope}) / 1000", - "enabled": true, - "displayInfo": { - "displayName": "CPU %", - "timeSeriesDisplayNameTemplate": null, - "type": "lines" - }, - "format": { - "unit": "number", - "inputFormat": "1", - "displayFormat": "auto", - "decimals": 1, - "yAxis": "auto", - "nullValueDisplayMode": "nullGap", - "minInterval": null - }, - "compareTo": { - "enabled": true, - "delta": 1, - "timeFormat": "hour" - } - } - ], - "numberThresholds": { - "useDefaults": null, - "values": [ - { - "severity": "info", - "value": 80, - "inputFormat": "1", - "displayText": "" - } - ], - "base": { - "severity": "none", - "displayText": "" - } - } - }, - { - "id": 14, - "type": "advancedNumber", - "name": "Total Used Memory", - "description": "Actual amount of memory used across all instances", - "nullValueDisplayText": null, - "links": null, - "advancedQueries": [ - { - "query": "sum(ibm_codeengine_instance_memory_usage_bytes{$__scope})", - "enabled": true, - "displayInfo": { - "displayName": "Memory %", - "timeSeriesDisplayNameTemplate": null, - "type": "lines" - }, - "format": { - "unit": "byte", - "inputFormat": "B", - "displayFormat": "auto", - "decimals": 1, - "yAxis": "auto", - "nullValueDisplayMode": "nullGap", - "minInterval": null - }, - "compareTo": { - "enabled": true, - "delta": 1, - "timeFormat": "hour" - } - } - ], - "numberThresholds": { - "useDefaults": null, - "values": [], - "base": { - "severity": "none", - "displayText": "" - } - } - }, - { - "id": 2, - "type": "advancedTimechart", - "name": "vCPU Usage (per Instance)", - "description": "Current vCPU usage per instance", - "nullValueDisplayText": null, - "links": null, - "advancedQueries": [ - { - "query": "ibm_codeengine_instance_cpu_usage_millicores{$__scope}", - "enabled": true, - "displayInfo": { - "displayName": "project > component name > instance ", - "timeSeriesDisplayNameTemplate": "{{ibm_codeengine_project_name}} > {{ibm_codeengine_component_name}} > {{ibm_codeengine_instance_name}} usage", - "type": "lines" - }, - "format": { - "unit": "number", - "inputFormat": "1", - "displayFormat": "auto", - "decimals": 0, - "yAxis": "auto", - "nullValueDisplayMode": "connectSolid", - "minInterval": null - }, - "compareTo": { - "enabled": false, - "delta": 1, - "timeFormat": "day" - } - } - ], - "legendConfiguration": { - "enabled": true, - "position": "bottom", - "layout": "table", - "showCurrent": true, - "showMax": true, - "showMin": true, - "width": null, - "height": null - }, - "axesConfiguration": { - "bottom": { - "enabled": true - }, - "left": { - "enabled": true, - "displayName": null, - "unit": "auto", - "displayFormat": "auto", - "decimals": null, - "minValue": 0, - "maxValue": null, - "minInputFormat": "0-100", - "maxInputFormat": "0-100", - "scale": "linear" - }, - "right": { - "enabled": true, - "displayName": null, - "unit": "auto", - "displayFormat": "auto", - "decimals": null, - "minValue": 0, - "maxValue": null, - "minInputFormat": "1", - "maxInputFormat": "1", - "scale": "linear" - } - }, - "numberThresholds": { - "useDefaults": null, - "values": [], - "base": { - "severity": "none", - "displayText": "" - } - } - }, - { - "id": 3, - "type": "advancedTimechart", - "name": "Memory Usage (per Instance)", - "description": "Current memory usage per instance", - "nullValueDisplayText": null, - "links": null, - "advancedQueries": [ - { - "query": "ibm_codeengine_instance_memory_usage_bytes{$__scope}", - "enabled": true, - "displayInfo": { - "displayName": "project > component name > instance", - "timeSeriesDisplayNameTemplate": "{{ibm_codeengine_project_name}} > {{ibm_codeengine_component_name}} > {{ibm_codeengine_instance_name}} usage", - "type": "lines" - }, - "format": { - "unit": "byte", - "inputFormat": "B", - "displayFormat": "auto", - "decimals": 0, - "yAxis": "auto", - "nullValueDisplayMode": "connectSolid", - "minInterval": null - }, - "compareTo": { - "enabled": false, - "delta": 1, - "timeFormat": "day" - } - } - ], - "legendConfiguration": { - "enabled": true, - "position": "bottom", - "layout": "table", - "showCurrent": true, - "showMax": true, - "showMin": true, - "width": null, - "height": null - }, - "axesConfiguration": { - "bottom": { - "enabled": true - }, - "left": { - "enabled": true, - "displayName": null, - "unit": "auto", - "displayFormat": "auto", - "decimals": null, - "minValue": 0, - "maxValue": null, - "minInputFormat": "B", - "maxInputFormat": "B", - "scale": "linear" - }, - "right": { - "enabled": false, - "displayName": null, - "unit": "auto", - "displayFormat": "auto", - "decimals": null, - "minValue": 0, - "maxValue": null, - "minInputFormat": "1", - "maxInputFormat": "1", - "scale": "linear" - } - }, - "numberThresholds": { - "useDefaults": null, - "values": [], - "base": { - "severity": "none", - "displayText": "" - } - } - }, - { - "id": 15, - "type": "advancedNumber", - "name": "Components with Running Instances", - "description": "Number of Code Engine components that do have running instances", - "nullValueDisplayText": null, - "links": null, - "advancedQueries": [ - { - "query": "count(count(\n ibm_codeengine_instance_cpu_limit_millicores{$__scope}\n)by (ibm_codeengine_project_name, ibm_codeengine_component_name))", - "enabled": true, - "displayInfo": { - "displayName": "CPU %", - "timeSeriesDisplayNameTemplate": null, - "type": "lines" - }, - "format": { - "unit": "number", - "inputFormat": "1", - "displayFormat": "auto", - "decimals": 0, - "yAxis": "auto", - "nullValueDisplayMode": "nullGap", - "minInterval": null - }, - "compareTo": { - "enabled": false, - "delta": 1, - "timeFormat": "hour" - } - } - ], - "numberThresholds": { - "useDefaults": null, - "values": [], - "base": { - "severity": "none", - "displayText": "" - } - } - }, - { - "id": 16, - "type": "advancedNumber", - "name": "Running Instances", - "description": "Number of running Code Engine instances", - "nullValueDisplayText": null, - "links": null, - "advancedQueries": [ - { - "query": "sum(count(\n ibm_codeengine_instance_cpu_limit_millicores{$__scope}\n)by (ibm_codeengine_component_name))", - "enabled": true, - "displayInfo": { - "displayName": "CPU %", - "timeSeriesDisplayNameTemplate": null, - "type": "lines" - }, - "format": { - "unit": "number", - "inputFormat": "1", - "displayFormat": "auto", - "decimals": 0, - "yAxis": "auto", - "nullValueDisplayMode": "nullGap", - "minInterval": null - }, - "compareTo": { - "enabled": true, - "delta": 1, - "timeFormat": "hour" - } - } - ], - "numberThresholds": { - "useDefaults": null, - "values": [ - { - "severity": "info", - "value": 80, - "inputFormat": "1", - "displayText": "" - } - ], - "base": { - "severity": "none", - "displayText": "" - } - } - }, - { - "id": 17, - "type": "section", - "name": "GENERAL OVERVIEW", - "description": null, - "nullValueDisplayText": null, - "links": null, - "panelIds": [ - 16, - 1, - 8, - 9, - 11, - 12, - 13, - 14, - 15 - ], - "basicQueries": [], - "advancedQueries": [] - }, - { - "id": 19, - "type": "section", - "name": "MEMORY USAGE", - "description": null, - "nullValueDisplayText": null, - "links": null, - "panelIds": [ - 3, - 6 - ], - "basicQueries": [], - "advancedQueries": [] - }, - { - "id": 18, - "type": "section", - "name": "CPU USAGE", - "description": null, - "nullValueDisplayText": null, - "links": null, - "panelIds": [ - 2, - 5 - ], - "basicQueries": [], - "advancedQueries": [] - } - ], - "scopeExpressionList": [ - { - "operand": "ibm_codeengine_project_name", - "operator": "in", - "displayName": "project_name", - "value": [], - "descriptor": { - "documentId": "ibm_codeengine_project_name", - "id": "ibm_codeengine_project_name", - "metricType": "tag", - "type": "string", - "scale": 0, - "name": "ibm_codeengine_project_name", - "description": "ibm_codeengine_project_name", - "namespaces": [ - "cloudProvider", - "host.container", - "ecs", - "host.fs", - "host.file", - "host", - "kubernetes", - "kubernetes.cluster", - "kubernetes.daemonSet", - "kubernetes.deployment", - "kubernetes.job", - "kubernetes.namespace", - "kubernetes.node", - "kubernetes.pod", - "kubernetes.replicaSet", - "kubernetes.service", - "kubernetes.statefulSet", - "kubernetes.resourcequota", - "kubernetes.hpa", - "link", - "mesos", - "host.net", - "host.process", - "prometheus", - "swarm", - "prombeacon" - ], - "scopes": [], - "timeAggregations": [ - "concat", - "distinct", - "count" - ], - "groupAggregations": [ - "concat", - "distinct", - "count" - ], - "aggregationForGroup": "none", - "hidden": false, - "experimental": false, - "deferred": false, - "identity": false, - "canMonitor": false, - "canGroupBy": false, - "canFilter": true, - "generatedFrom": "com.draios.model.metrics.custom.CustomMetric$Tag", - "publicId": "ibm_codeengine_project_name", - "heuristic": false, - "documentType": "metric", - "segment": false, - "documentTimestamp": 1774964935843 - }, - "operandPublicId": "ibm_codeengine_project_name", - "variable": true, - "isVariable": true - }, - { - "operand": "ibm_codeengine_component_type", - "operator": "in", - "displayName": "component_type", - "value": [], - "descriptor": { - "documentId": "ibm_codeengine_component_type", - "id": "ibm_codeengine_component_type", - "metricType": "tag", - "type": "string", - "scale": 0, - "name": "ibm_codeengine_component_type", - "description": "ibm_codeengine_component_type", - "namespaces": [ - "cloudProvider", - "host.container", - "ecs", - "host.fs", - "host.file", - "host", - "kubernetes", - "kubernetes.cluster", - "kubernetes.daemonSet", - "kubernetes.deployment", - "kubernetes.job", - "kubernetes.namespace", - "kubernetes.node", - "kubernetes.pod", - "kubernetes.replicaSet", - "kubernetes.service", - "kubernetes.statefulSet", - "kubernetes.resourcequota", - "kubernetes.hpa", - "link", - "mesos", - "host.net", - "host.process", - "prometheus", - "swarm", - "prombeacon" - ], - "scopes": [], - "timeAggregations": [ - "concat", - "distinct", - "count" - ], - "groupAggregations": [ - "concat", - "distinct", - "count" - ], - "aggregationForGroup": "none", - "hidden": false, - "experimental": false, - "deferred": false, - "identity": false, - "canMonitor": false, - "canGroupBy": false, - "canFilter": true, - "generatedFrom": "com.draios.model.metrics.custom.CustomMetric$Tag", - "publicId": "ibm_codeengine_component_type", - "heuristic": false, - "documentType": "metric", - "segment": false, - "documentTimestamp": 1774964935843 - }, - "operandPublicId": "ibm_codeengine_component_type", - "variable": true, - "isVariable": true - }, - { - "operand": "ibm_codeengine_component_name", - "operator": "in", - "displayName": "component_name", - "value": [], - "descriptor": { - "documentId": "ibm_codeengine_component_name", - "id": "ibm_codeengine_component_name", - "metricType": "tag", - "type": "string", - "scale": 0, - "name": "ibm_codeengine_component_name", - "description": "ibm_codeengine_component_name", - "namespaces": [ - "cloudProvider", - "host.container", - "ecs", - "host.fs", - "host.file", - "host", - "kubernetes", - "kubernetes.cluster", - "kubernetes.daemonSet", - "kubernetes.deployment", - "kubernetes.job", - "kubernetes.namespace", - "kubernetes.node", - "kubernetes.pod", - "kubernetes.replicaSet", - "kubernetes.service", - "kubernetes.statefulSet", - "kubernetes.resourcequota", - "kubernetes.hpa", - "link", - "mesos", - "host.net", - "host.process", - "prometheus", - "swarm", - "prombeacon" - ], - "scopes": [], - "timeAggregations": [ - "concat", - "distinct", - "count" - ], - "groupAggregations": [ - "concat", - "distinct", - "count" - ], - "aggregationForGroup": "none", - "hidden": false, - "experimental": false, - "deferred": false, - "identity": false, - "canMonitor": false, - "canGroupBy": false, - "canFilter": true, - "generatedFrom": "com.draios.model.metrics.custom.CustomMetric$Tag", - "publicId": "ibm_codeengine_component_name", - "heuristic": false, - "documentType": "metric", - "segment": false, - "documentTimestamp": 1774964935843 - }, - "operandPublicId": "ibm_codeengine_component_name", - "variable": true, - "isVariable": true - }, - { - "operand": "ibm_codeengine_instance_name", - "operator": "in", - "displayName": "instance", - "value": [], - "descriptor": { - "documentId": "ibm_codeengine_instance_name", - "id": "ibm_codeengine_instance_name", - "metricType": "tag", - "type": "string", - "scale": 0, - "name": "ibm_codeengine_instance_name", - "description": "ibm_codeengine_instance_name", - "namespaces": [ - "cloudProvider", - "host.container", - "ecs", - "host.fs", - "host.file", - "host", - "kubernetes", - "kubernetes.cluster", - "kubernetes.daemonSet", - "kubernetes.deployment", - "kubernetes.job", - "kubernetes.namespace", - "kubernetes.node", - "kubernetes.pod", - "kubernetes.replicaSet", - "kubernetes.service", - "kubernetes.statefulSet", - "kubernetes.resourcequota", - "kubernetes.hpa", - "link", - "mesos", - "host.net", - "host.process", - "prometheus", - "swarm", - "prombeacon" - ], - "scopes": [], - "timeAggregations": [ - "concat", - "distinct", - "count" - ], - "groupAggregations": [ - "concat", - "distinct", - "count" - ], - "aggregationForGroup": "none", - "hidden": false, - "experimental": false, - "deferred": false, - "identity": false, - "canMonitor": false, - "canGroupBy": false, - "canFilter": true, - "generatedFrom": "com.draios.model.metrics.custom.CustomMetric$Tag", - "publicId": "ibm_codeengine_instance_name", - "heuristic": false, - "documentType": "metric", - "segment": false, - "documentTimestamp": 1774964935843 - }, - "operandPublicId": "ibm_codeengine_instance_name", - "variable": true, - "isVariable": true - } - ], - "eventDisplaySettings": { - "enabled": true, - "queryParams": { - "severities": [], - "alertStatuses": [], - "categories": [], - "filter": "", - "teamScope": false - } - }, - "shared": true, - "public": false, - "description": "Overview of Code Engine instance resource usage: CPU/memory current vs limits, with filtering by component_type and component_name", - "layout": [ - { - "panelId": 17, - "x": 0, - "y": 0, - "w": 24, - "h": 1 - }, - { - "panelId": 1, - "x": 0, - "y": 1, - "w": 7, - "h": 4 - }, - { - "panelId": 8, - "x": 21, - "y": 1, - "w": 3, - "h": 2 - }, - { - "panelId": 9, - "x": 21, - "y": 3, - "w": 3, - "h": 2 - }, - { - "panelId": 11, - "x": 14, - "y": 1, - "w": 4, - "h": 2 - }, - { - "panelId": 12, - "x": 14, - "y": 3, - "w": 4, - "h": 2 - }, - { - "panelId": 13, - "x": 18, - "y": 1, - "w": 3, - "h": 2 - }, - { - "panelId": 14, - "x": 18, - "y": 3, - "w": 3, - "h": 2 - }, - { - "panelId": 15, - "x": 7, - "y": 1, - "w": 4, - "h": 4 - }, - { - "panelId": 16, - "x": 11, - "y": 1, - "w": 3, - "h": 4 - }, - { - "panelId": 18, - "x": 0, - "y": 5, - "w": 24, - "h": 1 - }, - { - "panelId": 5, - "x": 0, - "y": 6, - "w": 12, - "h": 6 - }, - { - "panelId": 2, - "x": 12, - "y": 6, - "w": 12, - "h": 6 - }, - { - "panelId": 19, - "x": 0, - "y": 12, - "w": 24, - "h": 1 - }, - { - "panelId": 6, - "x": 0, - "y": 13, - "w": 12, - "h": 5 - }, - { - "panelId": 3, - "x": 12, - "y": 13, - "w": 12, - "h": 5 - } - ], - "sharingSettings": [ - { - "role": "ROLE_RESOURCE_EDIT", - "member": { - "type": "USER_TEAMS", - "id": null, - "name": null, - "teamTheme": null - } - } - ], - "publicNotation": false, - "favorite": false, - "schema": 3, - "permissions": [ - "dashboards.edit", - "dashboards.sharing", - "dashboards.read", - "dashboards.transfer", - "dashboards.delete" - ] -} diff --git a/metrics-collector/setup/ibm-cloud-monitoring/monitoring-dashboard-manager.sh b/metrics-collector/setup/ibm-cloud-monitoring/monitoring-dashboard-manager.sh deleted file mode 100755 index e4b892dab..000000000 --- a/metrics-collector/setup/ibm-cloud-monitoring/monitoring-dashboard-manager.sh +++ /dev/null @@ -1,834 +0,0 @@ -#!/usr/bin/env bash - -# IBM Cloud Monitoring Dashboard Manager -# A unified tool for managing IBM Cloud Monitoring (Sysdig) dashboards -# -# This script provides functionality to: -# - List monitoring instances (global and by region) -# - List dashboards (name, id, last_updated) -# - Export dashboard by id into a file -# - Create/update dashboard from JSON file -# -# Authentication uses the current IBM Cloud CLI login context - -set -euo pipefail - -# Script metadata -readonly SCRIPT_VERSION="1.0.0" -readonly SCRIPT_NAME="$(basename "$0")" - -# Regional endpoints for IBM Cloud Monitoring -declare -A REGION_ENDPOINTS=( - ["us-south"]="https://us-south.monitoring.cloud.ibm.com" - ["us-east"]="https://us-east.monitoring.cloud.ibm.com" - ["eu-de"]="https://eu-de.monitoring.cloud.ibm.com" - ["eu-es"]="https://eu-es.monitoring.cloud.ibm.com" - ["eu-gb"]="https://eu-gb.monitoring.cloud.ibm.com" - ["jp-tok"]="https://jp-tok.monitoring.cloud.ibm.com" - ["in-che"]="https://in-che.monitoring.cloud.ibm.com" - ["au-syd"]="https://au-syd.monitoring.cloud.ibm.com" - ["jp-osa"]="https://jp-osa.monitoring.cloud.ibm.com" - ["ca-tor"]="https://ca-tor.monitoring.cloud.ibm.com" - ["br-sao"]="https://br-sao.monitoring.cloud.ibm.com" -) - -# IBM Cloud Resource Controller API -readonly RESOURCE_CONTROLLER_API="https://resource-controller.cloud.ibm.com/v2" - -# Default values -DEFAULT_OUTPUT_DIR="." -DEFAULT_FORMAT="table" - -# Global variables -IAM_TOKEN="" -VERBOSE=false - -# Color codes for output -readonly RED='\033[0;31m' -readonly GREEN='\033[0;32m' -readonly YELLOW='\033[1;33m' -readonly BLUE='\033[0;34m' -readonly NC='\033[0m' # No Color - -####################################### -# Print error message and exit -# Arguments: -# Error message -####################################### -error() { - echo -e "${RED}ERROR:${NC} $1" >&2 - exit 1 -} - -####################################### -# Print warning message -# Arguments: -# Warning message -####################################### -warn() { - echo -e "${YELLOW}WARNING:${NC} $1" >&2 -} - -####################################### -# Print info message -# Arguments: -# Info message -####################################### -info() { - echo -e "${BLUE}→${NC} $1" -} - -####################################### -# Print success message -# Arguments: -# Success message -####################################### -success() { - echo -e "${GREEN}✓${NC} $1" -} - -####################################### -# Print verbose message -# Arguments: -# Message -####################################### -verbose() { - if [[ "$VERBOSE" == true ]]; then - echo -e "${BLUE}[DEBUG]${NC} $1" >&2 - fi -} - -####################################### -# Check if required tools are installed -####################################### -check_prerequisites() { - local missing_tools=() - - # Check for required commands - for cmd in ibmcloud curl jq; do - if ! command -v "$cmd" &> /dev/null; then - missing_tools+=("$cmd") - fi - done - - if [[ ${#missing_tools[@]} -gt 0 ]]; then - error "Missing required tools: ${missing_tools[*]}\nPlease install them and try again." - fi - - verbose "All required tools are installed" -} - -####################################### -# Verify IBM Cloud CLI is logged in -####################################### -check_ibmcloud_login() { - verbose "Checking IBM Cloud CLI login status..." - - if ! ibmcloud account show &> /dev/null; then - error "Not logged in to IBM Cloud CLI. Please run 'ibmcloud login' first." - fi - - verbose "IBM Cloud CLI is logged in" -} - -####################################### -# Get IAM token from IBM Cloud CLI -# Returns: -# IAM token (Bearer token) -####################################### -get_iam_token() { - if [[ -n "$IAM_TOKEN" ]]; then - echo "$IAM_TOKEN" - return - fi - - verbose "Obtaining IAM token from IBM Cloud CLI..." - - local token - token=$(ibmcloud iam oauth-tokens --output JSON 2>/dev/null | jq -r '.iam_token' 2>/dev/null) - - if [[ -z "$token" || "$token" == "null" ]]; then - error "Failed to obtain IAM token. Please ensure you're logged in to IBM Cloud CLI." - fi - - if [[ ! "$token" =~ ^Bearer ]]; then - error "Invalid token format received from IBM Cloud CLI" - fi - - IAM_TOKEN="$token" - verbose "IAM token obtained successfully" - echo "$token" -} - -####################################### -# Get monitoring endpoint URL for region -# Arguments: -# Region name -# Returns: -# Endpoint URL -####################################### -get_region_endpoint() { - local region="$1" - - if [[ -z "${REGION_ENDPOINTS[$region]:-}" ]]; then - error "Unsupported region: $region\nSupported regions: ${!REGION_ENDPOINTS[*]}" - fi - - echo "${REGION_ENDPOINTS[$region]}" -} - -####################################### -# Make HTTP request with error handling -# Arguments: -# HTTP method -# URL -# Additional curl arguments (optional) -# Returns: -# Response body -####################################### -http_request() { - local method="$1" - local url="$2" - shift 2 - local curl_args=("$@") - - local response - local http_code - local temp_file - temp_file=$(mktemp) - - verbose "Making $method request to: $url" - - # Make request and capture both response and HTTP code - http_code=$(curl -s -w "%{http_code}" -o "$temp_file" \ - -X "$method" \ - "$url" \ - "${curl_args[@]}" \ - 2>/dev/null || echo "000") - - response=$(cat "$temp_file") - rm -f "$temp_file" - - verbose "HTTP response code: $http_code" - - # Check for HTTP errors - if [[ "$http_code" -ge 400 ]] || [[ "$http_code" == "000" ]]; then - local error_msg="API request failed (HTTP $http_code)" - if [[ -n "$response" ]]; then - local api_error - api_error=$(echo "$response" | jq -r '.message // .error // empty' 2>/dev/null || echo "") - if [[ -n "$api_error" ]]; then - error_msg="$error_msg: $api_error" - fi - fi - error "$error_msg" - fi - - echo "$response" -} - -####################################### -# List monitoring instances -# Arguments: -# Region filter (optional) -# Output format (table|json) -####################################### -list_monitoring_instances() { - local region_filter="${1:-}" - local format="${2:-table}" - - info "Fetching monitoring instances..." - - local token - token=$(get_iam_token) - - local response - response=$(http_request GET \ - "$RESOURCE_CONTROLLER_API/resource_instances?type=service_instance" \ - -H "Authorization: $token" \ - -H "Content-Type: application/json") - - # Filter for sysdig-monitor instances - local instances - instances=$(echo "$response" | jq -c '[.resources[] | select(.id | contains("sysdig-monitor"))]') - - # Apply region filter if specified - if [[ -n "$region_filter" ]]; then - instances=$(echo "$instances" | jq -c --arg region "$region_filter" '[.[] | select(.region_id == $region)]') - fi - - local count - count=$(echo "$instances" | jq 'length') - - if [[ "$count" -eq 0 ]]; then - warn "No monitoring instances found" - return - fi - - success "Found $count monitoring instance(s)" - echo - - if [[ "$format" == "json" ]]; then - echo "$instances" | jq '.' - else - # Table format - echo "$instances" | jq -r '["NAME", "INSTANCE_ID", "REGION", "STATE"], - (.[] | [.name, .guid, .region_id, .state]) | @tsv' | column -t -s $'\t' - fi -} - -####################################### -# List dashboards in a monitoring instance -# Arguments: -# Instance ID -# Region -# Output format (table|json) -####################################### -list_dashboards() { - local instance_id="$1" - local region="$2" - local format="${3:-table}" - - info "Fetching dashboards from instance $instance_id in region $region..." - - local token - token=$(get_iam_token) - - local endpoint - endpoint=$(get_region_endpoint "$region") - - local response - response=$(http_request GET \ - "$endpoint/api/v3/dashboards" \ - -H "Authorization: $token" \ - -H "IBMInstanceID: $instance_id" \ - -H "Content-Type: application/json") - - local dashboards - dashboards=$(echo "$response" | jq -c '.dashboards // []') - - local count - count=$(echo "$dashboards" | jq 'length') - - if [[ "$count" -eq 0 ]]; then - warn "No dashboards found in this instance" - return - fi - - success "Found $count dashboard(s)" - echo - - if [[ "$format" == "json" ]]; then - echo "$dashboards" | jq '.' - else - # Table format with ID, Name, and Last Updated - echo "$dashboards" | jq -r '["ID", "NAME", "LAST_UPDATED"], - (.[] | [.id, .name, (.modifiedOn | . / 1000 | strftime("%Y-%m-%dT%H:%M:%S %Z"))]) | @tsv' | column -t -s $'\t' - fi -} - -####################################### -# Find dashboard by name -# Arguments: -# Instance ID -# Region -# Dashboard name -# Returns: -# Dashboard ID or empty string -####################################### -find_dashboard_by_name() { - local instance_id="$1" - local region="$2" - local name="$3" - - verbose "Searching for dashboard: $name" - - local token - token=$(get_iam_token) - - local endpoint - endpoint=$(get_region_endpoint "$region") - - local response - response=$(http_request GET \ - "$endpoint/api/v3/dashboards" \ - -H "Authorization: $token" \ - -H "IBMInstanceID: $instance_id" \ - -H "Content-Type: application/json") - - local dashboard_id - dashboard_id=$(echo "$response" | jq -r --arg name "$name" '.dashboards[] | select(.name == $name) | .id') - - echo "$dashboard_id" -} - -####################################### -# Export dashboard to JSON file -# Arguments: -# Instance ID -# Region -# Dashboard ID -# Output file (optional) -####################################### -export_dashboard() { - local instance_id="$1" - local region="$2" - local dashboard_id="$3" - local output_file="${4:-}" - - info "Exporting dashboard $dashboard_id from instance $instance_id..." - - local token - token=$(get_iam_token) - - local endpoint - endpoint=$(get_region_endpoint "$region") - - local response - response=$(http_request GET \ - "$endpoint/api/v3/dashboards/$dashboard_id" \ - -H "Authorization: $token" \ - -H "IBMInstanceID: $instance_id" \ - -H "Content-Type: application/json") - - # Extract dashboard object - local dashboard - dashboard=$(echo "$response" | jq '.dashboard') - - if [[ "$dashboard" == "null" ]]; then - error "Dashboard not found or invalid response" - fi - - # Cleanse the dashboard - dashboard=$(echo "$dashboard" | jq 'del(.id)') - dashboard=$(echo "$dashboard" | jq 'del(.teamId)') - dashboard=$(echo "$dashboard" | jq 'del(.userId)') - dashboard=$(echo "$dashboard" | jq 'del(.createdOn)') - dashboard=$(echo "$dashboard" | jq 'del(.modifiedOn)') - dashboard=$(echo "$dashboard" | jq 'del(.lastAccessedOnByCurrentUser)') - dashboard=$(echo "$dashboard" | jq 'del(.username)') - dashboard=$(echo "$dashboard" | jq 'del(.publicToken)') - dashboard=$(echo "$dashboard" | jq 'del(.version)') - - # Generate output filename if not provided - if [[ -z "$output_file" ]]; then - local dashboard_name - dashboard_name=$(echo "$dashboard" | jq -r '.name // "dashboard"' | tr ' ' '_' | tr '[:upper:]' '[:lower:]') - local timestamp - timestamp=$(date -u +"%Y%m%d_%H%M%S") - output_file="${dashboard_name}_${timestamp}.json" - fi - - # Save to file with pretty printing - echo "$dashboard" | jq '.' > "$output_file" - - success "Dashboard exported successfully to: $output_file" - - # Show dashboard info - local name - name=$(echo "$dashboard" | jq -r '.name') - echo - echo "Dashboard: $name" - echo "ID: $dashboard_id" - echo "File: $output_file" -} - -####################################### -# Import or update dashboard from JSON file -# Arguments: -# Instance ID -# Region -# JSON file path -# Update mode (true|false) -####################################### -import_dashboard() { - local instance_id="$1" - local region="$2" - local file="$3" - local update_mode="${4:-false}" - - # Validate file exists - if [[ ! -f "$file" ]]; then - error "Dashboard file not found: $file" - fi - - info "Loading dashboard configuration from: $file" - - # Load and validate JSON - local dashboard_config - if ! dashboard_config=$(jq '.' "$file" 2>/dev/null); then - error "Invalid JSON in dashboard file: $file" - fi - - # Extract dashboard name - local dashboard_name - dashboard_name=$(echo "$dashboard_config" | jq -r '.name // empty') - - if [[ -z "$dashboard_name" ]]; then - error "Dashboard configuration must include a 'name' field" - fi - - info "Dashboard name: $dashboard_name" - - local token - token=$(get_iam_token) - - local endpoint - endpoint=$(get_region_endpoint "$region") - - # Check if dashboard already exists - info "Checking if dashboard already exists..." - local existing_id - existing_id=$(find_dashboard_by_name "$instance_id" "$region" "$dashboard_name") - - local response - local dashboard_id - local operation - - if [[ -n "$existing_id" ]]; then - if [[ "$update_mode" == "true" ]]; then - info "Dashboard exists (ID: $existing_id). Updating..." - operation="updated" - - # Update existing dashboard - response=$(http_request PUT \ - "$endpoint/api/v3/dashboards/$existing_id" \ - -H "Authorization: $token" \ - -H "IBMInstanceID: $instance_id" \ - -H "Content-Type: application/json" \ - -d "{\"dashboard\": $dashboard_config}") - - dashboard_id="$existing_id" - else - error "Dashboard '$dashboard_name' already exists (ID: $existing_id).\nUse --update flag to update the existing dashboard." - fi - else - info "Dashboard does not exist. Creating new dashboard..." - operation="created" - - # Create new dashboard - response=$(http_request POST \ - "$endpoint/api/v3/dashboards" \ - -H "Authorization: $token" \ - -H "IBMInstanceID: $instance_id" \ - -H "Content-Type: application/json" \ - -d "{\"dashboard\": $dashboard_config}") - - dashboard_id=$(echo "$response" | jq -r '.dashboard.id // empty') - - if [[ -z "$dashboard_id" ]]; then - error "Failed to create dashboard: No ID returned" - fi - fi - - success "Dashboard '$dashboard_name' $operation successfully!" - echo - echo "Dashboard ID: $dashboard_id" - echo "Dashboard URL: $endpoint/#/dashboards/$dashboard_id" -} - -####################################### -# Show usage information -####################################### -show_usage() { - cat << EOF -IBM Cloud Monitoring Dashboard Manager v${SCRIPT_VERSION} - -USAGE: - $SCRIPT_NAME [options] - -COMMANDS: - list-instances List monitoring instances - list-dashboards List dashboards in an instance - export Export a dashboard to JSON file - import Import/create a dashboard from JSON file - help Show this help message - -OPTIONS: - --instance-id ID Monitoring instance ID (GUID) - --region REGION IBM Cloud region - --dashboard-id ID Dashboard ID (for export) - --file FILE JSON file path (for import) - --output FILE Output file path (for export) - --format FORMAT Output format: table or json (default: table) - --update Update existing dashboard (for import) - --verbose Enable verbose output - --version Show version information - -EXAMPLES: - # List all monitoring instances - $SCRIPT_NAME list-instances - - # List instances in a specific region - $SCRIPT_NAME list-instances --region us-south - - # List instances in JSON format - $SCRIPT_NAME list-instances --format json - - # List dashboards in an instance - $SCRIPT_NAME list-dashboards \\ - --instance-id "12345678-1234-1234-1234-123456789abc" \\ - --region us-south - - # Export a dashboard - $SCRIPT_NAME export \\ - --instance-id "12345678-1234-1234-1234-123456789abc" \\ - --region us-south \\ - --dashboard-id 12345 - - # Export with custom output file - $SCRIPT_NAME export \\ - --instance-id "12345678-1234-1234-1234-123456789abc" \\ - --region us-south \\ - --dashboard-id 12345 \\ - --output my-dashboard.json - - # Import a new dashboard - $SCRIPT_NAME import \\ - --instance-id "12345678-1234-1234-1234-123456789abc" \\ - --region us-south \\ - --file dashboard.json - - # Update an existing dashboard - $SCRIPT_NAME import \\ - --instance-id "12345678-1234-1234-1234-123456789abc" \\ - --region us-south \\ - --file dashboard.json \\ - --update - -SUPPORTED REGIONS: - ${!REGION_ENDPOINTS[*]} - -ENVIRONMENT VARIABLES: - SYSDIG_INSTANCE_ID Default instance ID - SYSDIG_REGION Default region - SYSDIG_OUTPUT_DIR Default output directory for exports - -AUTHENTICATION: - This script uses the IBM Cloud CLI login context. Ensure you are logged in: - ibmcloud login - -For more information, see the documentation in the setup/ibm-cloud-monitoring directory. -EOF -} - -####################################### -# Show version information -####################################### -show_version() { - echo "IBM Cloud Monitoring Dashboard Manager v${SCRIPT_VERSION}" -} - -####################################### -# Parse command line arguments -####################################### -parse_args() { - local command="${1:-}" - - if [[ -z "$command" ]]; then - show_usage - exit 0 - fi - - shift - - # Parse command - case "$command" in - list-instances) - local region_filter="" - local format="$DEFAULT_FORMAT" - - while [[ $# -gt 0 ]]; do - case "$1" in - --region) - region_filter="$2" - shift 2 - ;; - --format) - format="$2" - shift 2 - ;; - --verbose) - VERBOSE=true - shift - ;; - *) - error "Unknown option: $1" - ;; - esac - done - - check_prerequisites - check_ibmcloud_login - list_monitoring_instances "$region_filter" "$format" - ;; - - list-dashboards) - local instance_id="${SYSDIG_INSTANCE_ID:-}" - local region="${SYSDIG_REGION:-}" - local format="$DEFAULT_FORMAT" - - while [[ $# -gt 0 ]]; do - case "$1" in - --instance-id) - instance_id="$2" - shift 2 - ;; - --region) - region="$2" - shift 2 - ;; - --format) - format="$2" - shift 2 - ;; - --verbose) - VERBOSE=true - shift - ;; - *) - error "Unknown option: $1" - ;; - esac - done - - if [[ -z "$instance_id" ]]; then - error "Instance ID is required. Use --instance-id or set SYSDIG_INSTANCE_ID environment variable." - fi - - if [[ -z "$region" ]]; then - error "Region is required. Use --region or set SYSDIG_REGION environment variable." - fi - - check_prerequisites - check_ibmcloud_login - list_dashboards "$instance_id" "$region" "$format" - ;; - - export) - local instance_id="${SYSDIG_INSTANCE_ID:-}" - local region="${SYSDIG_REGION:-}" - local dashboard_id="" - local output_file="" - - while [[ $# -gt 0 ]]; do - case "$1" in - --instance-id) - instance_id="$2" - shift 2 - ;; - --region) - region="$2" - shift 2 - ;; - --dashboard-id) - dashboard_id="$2" - shift 2 - ;; - --output) - output_file="$2" - shift 2 - ;; - --verbose) - VERBOSE=true - shift - ;; - *) - error "Unknown option: $1" - ;; - esac - done - - if [[ -z "$instance_id" ]]; then - error "Instance ID is required. Use --instance-id or set SYSDIG_INSTANCE_ID environment variable." - fi - - if [[ -z "$region" ]]; then - error "Region is required. Use --region or set SYSDIG_REGION environment variable." - fi - - if [[ -z "$dashboard_id" ]]; then - error "Dashboard ID is required. Use --dashboard-id." - fi - - check_prerequisites - check_ibmcloud_login - export_dashboard "$instance_id" "$region" "$dashboard_id" "$output_file" - ;; - - import) - local instance_id="${SYSDIG_INSTANCE_ID:-}" - local region="${SYSDIG_REGION:-}" - local file="" - local update_mode="false" - - while [[ $# -gt 0 ]]; do - case "$1" in - --instance-id) - instance_id="$2" - shift 2 - ;; - --region) - region="$2" - shift 2 - ;; - --file) - file="$2" - shift 2 - ;; - --update) - update_mode="true" - shift - ;; - --verbose) - VERBOSE=true - shift - ;; - *) - error "Unknown option: $1" - ;; - esac - done - - if [[ -z "$instance_id" ]]; then - error "Instance ID is required. Use --instance-id or set SYSDIG_INSTANCE_ID environment variable." - fi - - if [[ -z "$region" ]]; then - error "Region is required. Use --region or set SYSDIG_REGION environment variable." - fi - - if [[ -z "$file" ]]; then - error "File is required. Use --file." - fi - - check_prerequisites - check_ibmcloud_login - import_dashboard "$instance_id" "$region" "$file" "$update_mode" - ;; - - help|--help|-h) - show_usage - ;; - - version|--version|-v) - show_version - ;; - - *) - error "Unknown command: $command\nRun '$SCRIPT_NAME help' for usage information." - ;; - esac -} - -####################################### -# Main entry point -####################################### -main() { - parse_args "$@" -} - -# Run main function -main "$@" - -# Made with Bob