Checking Elastic Stack health across Filebeat, Logstash, Elasticsearch, and Kibana confirms that events can move from a harvested log line to a searchable index while the UI is ready to read it. A stack sweep is useful after pipeline edits, restarts, certificate changes, and upgrades because one layer can answer locally while another layer is still blocked.
Use each component's own status surface for the part it owns. Elasticsearch reports shard allocation through _cluster/health, Logstash reports pipeline state and flow through its monitoring API, Filebeat reports publisher and output counters through its optional HTTP endpoint, and Kibana reports instance readiness through /api/status.
Local unsecured endpoints are shown for a validation stack. In production, use the real scheme, host, port, base path, CA trust, and credentials for each component. Keep Filebeat and Logstash monitoring endpoints on localhost or a trusted management network because they expose runtime, host, version, and pipeline metadata.
Related: How to monitor Elasticsearch cluster health
Related: How to check Logstash pipeline metrics
Related: How to enable the Filebeat HTTP endpoint
Related: How to check Kibana status
$ curl -sS --fail 'http://localhost:9200/_cluster/health?filter_path=cluster_name,status,number_of_nodes,active_primary_shards,active_shards,unassigned_primary_shards,unassigned_shards,number_of_pending_tasks,active_shards_percent_as_number&pretty'
{
"cluster_name" : "docker-cluster",
"status" : "yellow",
"number_of_nodes" : 1,
"active_primary_shards" : 42,
"active_shards" : 42,
"unassigned_shards" : 1,
"unassigned_primary_shards" : 0,
"number_of_pending_tasks" : 0,
"active_shards_percent_as_number" : 97.67441860465115
}
green means all shards are assigned. yellow with unassigned_primary_shards at 0 often means replica shards cannot be assigned, which is common in a single-node validation stack. red means at least one primary shard is unavailable.
$ curl -sS --fail 'http://localhost:9600/_health_report' | jq '{status, symptom, main_pipeline:.indicators.pipelines.indicators.main.details.status.state}'
{
"status": "green",
"symptom": "1 indicator is healthy (`pipelines`)",
"main_pipeline": "RUNNING"
}
Current Logstash releases use green, yellow, red, and unknown. The _health_report endpoint performs root-cause analysis for non-green states, so avoid tight polling loops against it.
$ curl -sS --fail 'http://localhost:9600/_node/stats/pipelines' | jq '.pipelines.main | {events:.events, flow:{input:.flow.input_throughput.last_1_minute, output:.flow.output_throughput.last_1_minute, backpressure:.flow.queue_backpressure.last_1_minute}, queue:{type:.queue.type, events_count:.queue.events_count}}'
{
"events": {
"duration_in_millis": 569,
"queue_push_duration_in_millis": 0,
"filtered": 1,
"out": 1,
"in": 1
},
"flow": {
"input": 0.0,
"output": 0.0,
"backpressure": 0.0
},
"queue": {
"type": "memory",
"events_count": 0
}
}
Use the active pipeline name instead of main when /_node/pipelines lists a different ID. events.in, events.filtered, and events.out should move together, and queue_backpressure near 0 means inputs are not spending time blocked on the queue.
$ curl -sS --fail 'http://localhost:5066/stats' | jq '{published:.libbeat.pipeline.events.published,acked:.libbeat.output.events.acked,retry:.libbeat.pipeline.events.retry,failed:.libbeat.output.events.failed,active:.libbeat.output.events.active,added:.filebeat.events.added,done:.filebeat.events.done,running_harvesters:.filebeat.harvester.running}'
{
"published": 1,
"acked": 1,
"retry": 0,
"failed": 0,
"active": 0,
"added": 1,
"done": 1,
"running_harvesters": 1
}
The Filebeat HTTP endpoint is disabled by default. Enable it only on localhost or a trusted management address before using port 5066.
$ curl -sS --fail 'http://localhost:5601/api/status' | jq '{overall:.status.overall, elasticsearch:.status.core.elasticsearch, savedObjects:.status.core.savedObjects}'
{
"overall": {
"level": "available",
"summary": "All services and plugins are available"
},
"elasticsearch": {
"level": "available",
"summary": "Elasticsearch is available",
"meta": {
"warningNodes": [],
"incompatibleNodes": []
}
},
"savedObjects": {
"level": "available",
"summary": "SavedObjects service has completed migrations and is available",
"meta": {
"migratedIndices": {
"migrated": 0,
"skipped": 0,
"patched": 8
}
}
}
}
Authenticated requests can return the detailed component breakdown. Unauthenticated requests on secured deployments may return only a redacted overall level.
$ curl -sS --fail 'http://localhost:9200/_cat/indices/filebeat-health-*?h=health,status,index,docs.count' yellow open filebeat-health-2026.06.18 1
Replace filebeat-health-* with the production data stream, index alias, or index pattern used by the Logstash output. A yellow health value here follows Elasticsearch shard allocation and can still appear when the latest document is searchable.
$ curl -sS --fail \
-H 'Content-Type: application/json' \
'http://localhost:9200/filebeat-health-*/_search?filter_path=hits.total,hits.hits._index,hits.hits._source.@timestamp,hits.hits._source.message&pretty' \
-d '{"size":1,"sort":[{"@timestamp":{"order":"desc"}}],"_source":["@timestamp","message"]}'
{
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"hits" : [
{
"_index" : "filebeat-health-2026.06.18",
"_source" : {
"@timestamp" : "2026-06-18T20:16:24.247Z",
"message" : "2026-06-19T04:18:00Z INFO sample application event delivered through Logstash"
}
}
]
}
}
The newest event should match a recent source that Filebeat is expected to harvest. If the latest event is stale, check Filebeat harvesters, Logstash output responses, and Elasticsearch rejected indexing errors before treating dashboards as current.