Help us improve
Share bugs, ideas, or general feedback.
Queries OpenSearch Dashboards APIs via curl to discover workspaces, index patterns, datasets, saved objects, and configurations. Useful for observability setup and data source management.
npx claudepluginhub opensearch-project/observability-stack --plugin observabilityHow this skill is triggered — by the user, by Claude, or both
Slash command
/opensearch@observability:osd-configThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
| Variable | Default | Description |
Checks health of observability stack components including OpenSearch, Prometheus, and OTel Collector; verifies trace and log data ingestion; troubleshoots common issues with curl and bash commands.
Interact with Elasticsearch and Kibana via curl REST API for querying (Query DSL), indexing, CRUD, index management, mappings, aggregations, cluster health, ILM, ES|QL, dashboards, OpenTelemetry patterns, and troubleshooting.
Covers Grafana OSS dashboards, panels, data sources, template variables, alerting, provisioning, RBAC, and configuration. Useful when building dashboards, configuring Grafana, or writing PromQL/LogQL/TraceQL.
Share bugs, ideas, or general feedback.
| Variable | Default | Description |
|---|---|---|
OSD_ENDPOINT | http://localhost:5601 | OpenSearch Dashboards base URL |
OPENSEARCH_USER | admin | Username (same as OpenSearch) |
OPENSEARCH_PASSWORD | My_password_123!@# | Password (same as OpenSearch) |
Note: All OSD API calls require the osd-xsrf: true header.
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/workspaces/_list" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/workspaces/<WORKSPACE_ID>" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
-X POST "$OSD_ENDPOINT/api/workspaces/_associate" \
-H 'osd-xsrf: true' \
-H 'Content-Type: application/json' \
-d '{"workspaceId": "<WORKSPACE_ID>", "savedObjects": [{"type": "data-source", "id": "<DATASOURCE_ID>"}]}'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/opensearch-dashboards/settings" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=index-pattern&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/w/<WORKSPACE_ID>/api/saved_objects/_find?type=index-pattern&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/index-pattern/<INDEX_PATTERN_ID>" \
-H 'osd-xsrf: true'
Datasets are an evolution of index patterns that classify indices by signal type (logs, traces, metrics). Users define which indices are logs vs traces through the Dashboards UI. See Dataset Discovery documentation for details.
To discover datasets programmatically, query the saved objects API for index patterns with their signalType, displayName, and description fields:
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?fields=title&fields=type&fields=displayName&fields=signalType&fields=description&per_page=10000&type=index-pattern" \
-H 'osd-xsrf: true'
Index patterns created by the observability stack init script include schema mappings that identify their signal type (e.g., otelLogs for log indices, trace-specific time fields for trace indices). These mappings are visible in the index pattern's attributes.fields property.
The APM plugin stores correlations saved objects that define how traces, logs, and metrics are linked. Two correlation types are created by the init script:
trace-to-logs-* — Links a trace index pattern to a log index pattern for cross-signal navigationAPM-Config-* — Ties together the traces index, service map index, and Prometheus datasource for the APM UIcurl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=correlations&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/w/<WORKSPACE_ID>/api/saved_objects/_find?type=correlations&per_page=100" \
-H 'osd-xsrf: true'
The _find API requires a type parameter. To get a count without loading objects, use per_page=0:
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=index-pattern&per_page=0" \
-H 'osd-xsrf: true'
Common saved object types: index-pattern, query, dashboard, visualization, config, correlations, data-source, data-connection, explore.
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=correlations&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=data-source&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=data-connection&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=explore&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=query&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=dashboard&per_page=100" \
-H 'osd-xsrf: true'
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=visualization&per_page=100" \
-H 'osd-xsrf: true'
To discover existing Prometheus data connections, use the saved objects API (the data-connection type):
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OSD_ENDPOINT/api/saved_objects/_find?type=data-connection&per_page=100" \
-H 'osd-xsrf: true'
The init script creates Prometheus data connections via the direct query API:
curl -s -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
-X POST "$OSD_ENDPOINT/api/directquery/dataconnections" \
-H 'osd-xsrf: true' \
-H 'Content-Type: application/json' \
-d '{"name": "MyPrometheus", "connector": "prometheus", "allowedRoles": ["all_access"], "properties": {"prometheus.uri": "http://prometheus:9090", "prometheus.auth.type": "basicauth", "prometheus.auth.username": "", "prometheus.auth.password": ""}}'
When OSD is not available, query OpenSearch directly to discover indices and field mappings:
curl -sk -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OPENSEARCH_ENDPOINT/_cat/indices?format=json&v" | python3 -c "
import sys, json
for idx in json.load(sys.stdin):
name = idx['index']
if any(p in name for p in ['otel-', 'logs-otel-', 'apm-']):
print(f\"{name} docs={idx['docs.count']} size={idx['store.size']}\")"
curl -sk -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OPENSEARCH_ENDPOINT/otel-v1-apm-span-*/_mapping?pretty"
curl -sk -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OPENSEARCH_ENDPOINT/logs-otel-v1-*/_mapping?pretty"
curl -sk -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
"$OPENSEARCH_ENDPOINT/otel-v2-apm-service-map-*/_mapping?pretty"
curl -sk -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
-X POST "$OPENSEARCH_ENDPOINT/_plugins/_ppl" \
-H 'Content-Type: application/json' \
-d '{"query": "describe otel-v1-apm-span-000001"}'
curl -sk -u "$OPENSEARCH_USER:$OPENSEARCH_PASSWORD" \
-X POST "$OPENSEARCH_ENDPOINT/_plugins/_ppl" \
-H 'Content-Type: application/json' \
-d '{"query": "describe logs-otel-v1-000001"}'
When dynamic discovery is not possible, these are the default index patterns used by the observability stack:
| Signal | Index Pattern | Description |
|---|---|---|
| Traces | otel-v1-apm-span-* | Trace span data with serviceName, traceId, spanId |
| Logs | logs-otel-v1-* | Log entries with resource.attributes.service.name |
| Service Maps | otel-v2-apm-service-map-* | Service topology with sourceNode, targetNode |