Skip to content

[logstash] Enable TSDB for metrics data streams#17401

Merged
AndersonQ merged 4 commits intoelastic:mainfrom
AndersonQ:16512-logstash-metrics-TSDB
Mar 12, 2026
Merged

[logstash] Enable TSDB for metrics data streams#17401
AndersonQ merged 4 commits intoelastic:mainfrom
AndersonQ:16512-logstash-metrics-TSDB

Conversation

@AndersonQ
Copy link
Copy Markdown
Member

@AndersonQ AndersonQ commented Feb 12, 2026

Proposed commit message

[logstash] Enable TSDB for metrics data streams

Enable TSDB for health_report and node_cel data streams in the Logstash 
integration and add metric_type annotations to pipeline and plugins.

`agent.id` is added as dimension to all data streams, so the events with errors
when fetching metrics can be indexed, having their TSDB ID from the 
`agent.id+timestamp`.

Annotate numeric fields with appropriate metric_type for the health_report,
node_cel, pipeline, plugins data streams.

Dimensions added:

- health_report:

| Field | Source | Pre-existing? |
|-------|--------|:---:|
| `service.hostname` | base-fields.yml | no |
| `service.id` | ecs.yml | no |
| `service.type` | ecs.yml | no |
| `service.version` | ecs.yml | no |
| `service.address` | ecs.yml | no |
| `service.name` | ecs.yml | no |
| `event.dataset` | ecs.yml | no |
| `event.module` | ecs.yml | no |
| `agent.id` | ecs.yml | no (new field) |
| `logstash.node.name` | fields.yml | no |
| `logstash.node.version` | fields.yml | no |
| `logstash.node.address` | fields.yml | no |
| `logstash.node.uuid` | fields.yml | no |
| `logstash.pipeline.id` | fields.yml | no |

- node_cel:

| Field | Source | Pre-existing? |
|-------|--------|:---:|
| `service.hostname` | base-fields.yml | no |
| `service.id` | ecs.yml | no |
| `service.type` | ecs.yml | no |
| `service.version` | ecs.yml | no |
| `service.address` | ecs.yml | no |
| `service.name` | ecs.yml | no |
| `event.dataset` | ecs.yml | no |
| `event.module` | ecs.yml | no |
| `agent.id` | ecs.yml | no (new field) |
| `input.type` | package-fields.yml | no |
| `cloud.account.id` | agent.yml | no |
| `cloud.availability_zone` | agent.yml | no |
| `cloud.instance.id` | agent.yml | no |
| `cloud.instance.name` | agent.yml | no |
| `cloud.machine.type` | agent.yml | no |
| `cloud.provider` | agent.yml | no |
| `cloud.region` | agent.yml | no |
| `cloud.project.id` | agent.yml | no |
| `cloud.image.id` | agent.yml | no |
| `host.architecture` | agent.yml | no |
| `host.domain` | agent.yml | no |
| `host.hostname` | agent.yml | no |
| `host.id` | agent.yml | no |
| `host.ip` | agent.yml | no |
| `host.mac` | agent.yml | no |
| `host.name` | agent.yml | no |
| `host.os.family` | agent.yml | no |
| `host.os.kernel` | agent.yml | no |
| `host.os.name` | agent.yml | no |
| `host.os.platform` | agent.yml | no |
| `host.os.version` | agent.yml | no |
| `host.type` | agent.yml | no |
| `host.os.build` | agent.yml | no |
| `host.os.codename` | agent.yml | no |
| `logstash.elasticsearch.cluster.id` | fields.yml | no |
| `logstash.node.stats.logstash.uuid` | fields.yml | no |
| `logstash.node.stats.logstash.version` | fields.yml | no |
| `logstash.node.stats.logstash.ephemeral_id` | fields.yml | **yes** |
| `logstash.node.stats.logstash.host` | fields.yml | no |
| `logstash.node.stats.logstash.http_address` | fields.yml | no |
| `logstash.node.stats.logstash.name` | fields.yml | no |
| `logstash.node.stats.pipelines.id` | fields.yml | no |
| `logstash.node.stats.pipelines.hash` | fields.yml | no |
| `logstash.node.stats.pipelines.ephemeral_id` | fields.yml | no |

- pipeline

| Field | Source | Pre-existing? |
|-------|--------|:---:|
| `service.hostname` | base-fields.yml | no |
| `service.id` | ecs.yml | no |
| `service.type` | ecs.yml | no |
| `service.version` | ecs.yml | no |
| `service.address` | ecs.yml | no |
| `service.name` | ecs.yml | no |
| `event.dataset` | ecs.yml | no |
| `event.module` | ecs.yml | no |
| `agent.id` | ecs.yml | no (new field) |
| `input.type` | package-fields.yml | no |
| `cloud.account.id` | agent.yml | no |
| `cloud.availability_zone` | agent.yml | no |
| `cloud.instance.id` | agent.yml | no |
| `cloud.instance.name` | agent.yml | no |
| `cloud.machine.type` | agent.yml | no |
| `cloud.provider` | agent.yml | no |
| `cloud.region` | agent.yml | no |
| `cloud.project.id` | agent.yml | no |
| `cloud.image.id` | agent.yml | no |
| `host.architecture` | agent.yml | no |
| `host.domain` | agent.yml | no |
| `host.hostname` | agent.yml | no |
| `host.id` | agent.yml | no |
| `host.ip` | agent.yml | no |
| `host.mac` | agent.yml | no |
| `host.name` | agent.yml | no |
| `host.os.family` | agent.yml | no |
| `host.os.kernel` | agent.yml | no |
| `host.os.name` | agent.yml | no |
| `host.os.platform` | agent.yml | no |
| `host.os.version` | agent.yml | no |
| `host.type` | agent.yml | no |
| `host.os.build` | agent.yml | no |
| `host.os.codename` | agent.yml | no |
| `logstash.pipeline.name` | fields.yml | **yes** |
| `logstash.pipeline.elasticsearch.cluster.id` | fields.yml | no |
| `logstash.pipeline.info.ephemeral_id` | fields.yml | **yes** |
| `logstash.pipeline.host.name` | fields.yml | no |
| `logstash.pipeline.host.address` | fields.yml | **yes** |
| `logstash.pipeline.total.flow.queues.type` | fields.yml | no |

- plugins

| Field | Source | Pre-existing? |
|-------|--------|:---:|
| `service.hostname` | base-fields.yml | no |
| `service.id` | ecs.yml | no |
| `service.type` | ecs.yml | no |
| `service.version` | ecs.yml | no |
| `service.address` | ecs.yml | no |
| `service.name` | ecs.yml | no |
| `event.dataset` | ecs.yml | no |
| `event.module` | ecs.yml | no |
| `agent.id` | ecs.yml | no (new field) |
| `input.type` | package-fields.yml | no |
| `cloud.account.id` | agent.yml | no |
| `cloud.availability_zone` | agent.yml | no |
| `cloud.instance.id` | agent.yml | no |
| `cloud.instance.name` | agent.yml | no |
| `cloud.machine.type` | agent.yml | no |
| `cloud.provider` | agent.yml | no |
| `cloud.region` | agent.yml | no |
| `cloud.project.id` | agent.yml | no |
| `cloud.image.id` | agent.yml | no |
| `host.architecture` | agent.yml | no |
| `host.domain` | agent.yml | no |
| `host.hostname` | agent.yml | no |
| `host.id` | agent.yml | no |
| `host.ip` | agent.yml | no |
| `host.mac` | agent.yml | no |
| `host.name` | agent.yml | no |
| `host.os.family` | agent.yml | no |
| `host.os.kernel` | agent.yml | no |
| `host.os.name` | agent.yml | no |
| `host.os.platform` | agent.yml | no |
| `host.os.version` | agent.yml | no |
| `host.type` | agent.yml | no |
| `host.os.build` | agent.yml | no |
| `host.os.codename` | agent.yml | no |
| `logstash.pipeline.name` | fields.yml | no |
| `logstash.pipeline.id` | fields.yml | **yes** |
| `logstash.pipeline.elasticsearch.cluster.id` | fields.yml | no |
| `logstash.pipeline.host.name` | fields.yml | no |
| `logstash.pipeline.host.address` | fields.yml | no |
| `logstash.pipeline.plugin.type` | fields.yml | no |
| `logstash.pipeline.plugin.codec.name` | fields.yml | no |
| `logstash.pipeline.plugin.codec.id` | fields.yml | **yes** |
| `logstash.pipeline.plugin.input.name` | fields.yml | no |
| `logstash.pipeline.plugin.input.id` | fields.yml | **yes** |
| `logstash.pipeline.plugin.input.elasticsearch.cluster.id` | fields.yml | no |
| `logstash.pipeline.plugin.filter.name` | fields.yml | no |
| `logstash.pipeline.plugin.filter.id` | fields.yml | **yes** |
| `logstash.pipeline.plugin.filter.elasticsearch.cluster.id` | fields.yml | no |
| `logstash.pipeline.plugin.output.name` | fields.yml | no |
| `logstash.pipeline.plugin.output.id` | fields.yml | **yes** |
| `logstash.pipeline.plugin.output.elasticsearch.cluster.id` | fields.yml | no |


Assisted by Cursor
Data stream changes summary

1. health_report

Dimensions

Field Source Pre-existing?
service.hostname base-fields.yml no
service.id ecs.yml no
service.type ecs.yml no
service.version ecs.yml no
service.address ecs.yml no
service.name ecs.yml no
event.dataset ecs.yml no
event.module ecs.yml no
agent.id ecs.yml no (new field)
logstash.node.name fields.yml no
logstash.node.version fields.yml no
logstash.node.address fields.yml no
logstash.node.uuid fields.yml no
logstash.pipeline.id fields.yml no

Neither Dimension nor Metric

Field Type
@timestamp date (ecs)
process.pid long (ecs)
ecs.version keyword (ecs)
event.duration long (ecs)
error.message match_only_text (ecs)
logstash.node.symptom keyword
logstash.node.symptom.text match_only_text
logstash.node.status keyword
logstash.pipeline.status keyword
logstash.pipeline.state keyword
logstash.pipeline.symptom keyword
logstash.pipeline.symptom.text match_only_text
logstash.pipeline.diagnosis.id keyword
logstash.pipeline.diagnosis.cause keyword
logstash.pipeline.diagnosis.cause.text match_only_text
logstash.pipeline.diagnosis.action keyword
logstash.pipeline.diagnosis.action.text match_only_text
logstash.pipeline.diagnosis.help_url keyword
logstash.pipeline.diagnosis.help_url.text match_only_text
logstash.pipeline.impacts.id keyword
logstash.pipeline.impacts.description keyword
logstash.pipeline.impacts.description.text match_only_text
logstash.pipeline.impacts.impact_areas keyword

Metrics Added / Changed

All are newly added (no pre-existing metric_type in this data stream).

Field Type metric_type
logstash.pipeline.impacts.severity short gauge
logstash.pipeline.flow.worker_utilization.current float gauge
logstash.pipeline.flow.worker_utilization.last_1_hour float gauge
logstash.pipeline.flow.worker_utilization.last_5_minutes float gauge
logstash.pipeline.flow.worker_utilization.last_15_minutes float gauge
logstash.pipeline.flow.worker_utilization.lifetime float gauge
logstash.pipeline.flow.worker_utilization.last_1_minute float gauge
logstash.pipeline.flow.worker_utilization.last_24_hours float gauge

2. node_cel

Dimensions

Field Source Pre-existing?
service.hostname base-fields.yml no
service.id ecs.yml no
service.type ecs.yml no
service.version ecs.yml no
service.address ecs.yml no
service.name ecs.yml no
event.dataset ecs.yml no
event.module ecs.yml no
agent.id ecs.yml no (new field)
input.type package-fields.yml no
cloud.account.id agent.yml no
cloud.availability_zone agent.yml no
cloud.instance.id agent.yml no
cloud.instance.name agent.yml no
cloud.machine.type agent.yml no
cloud.provider agent.yml no
cloud.region agent.yml no
cloud.project.id agent.yml no
cloud.image.id agent.yml no
host.architecture agent.yml no
host.domain agent.yml no
host.hostname agent.yml no
host.id agent.yml no
host.ip agent.yml no
host.mac agent.yml no
host.name agent.yml no
host.os.family agent.yml no
host.os.kernel agent.yml no
host.os.name agent.yml no
host.os.platform agent.yml no
host.os.version agent.yml no
host.type agent.yml no
host.os.build agent.yml no
host.os.codename agent.yml no
logstash.elasticsearch.cluster.id fields.yml no
logstash.node.stats.logstash.uuid fields.yml no
logstash.node.stats.logstash.version fields.yml no
logstash.node.stats.logstash.ephemeral_id fields.yml yes
logstash.node.stats.logstash.host fields.yml no
logstash.node.stats.logstash.http_address fields.yml no
logstash.node.stats.logstash.name fields.yml no
logstash.node.stats.pipelines.id fields.yml no
logstash.node.stats.pipelines.hash fields.yml no
logstash.node.stats.pipelines.ephemeral_id fields.yml no

Neither Dimension nor Metric

Field Type
@timestamp date (ecs)
process.pid long (ecs)
ecs.version keyword (ecs)
event.duration long (ecs)
error.message match_only_text (ecs)
container.id keyword (ecs)
container.image.name keyword (ecs)
container.labels object (ecs)
container.name keyword (ecs)
host.containerized boolean
logstash.node.stats.timestamp date
logstash.node.stats.logstash.snapshot boolean
logstash.node.stats.logstash.status keyword
logstash.node.stats.logstash.pipelines keyword
logstash.node.stats.pipelines.queue.type keyword
logstash.node.stats.os.cgroup.cpuacct.control_group text
logstash.node.stats.os.cgroup.cpu.control_group text

Metrics Added / Changed

Changed (counter → gauge):

Field Type Old New
logstash.node.stats.jvm.threads.count long counter gauge
logstash.node.stats.jvm.threads.peak_count long counter gauge
logstash.node.stats.jvm.mem.heap_max_in_bytes long counter gauge
logstash.node.stats.queue.events_count long counter gauge

Newly added metric_type:

Field Type metric_type
logstash.node.stats.pipelines.reloads.failures long counter
logstash.node.stats.pipelines.reloads.successes long counter
logstash.node.stats.pipelines.queue.events_count long gauge
logstash.node.stats.pipelines.queue.queue_size_in_bytes long gauge
logstash.node.stats.pipelines.queue.max_queue_size_in_bytes long gauge
logstash.node.stats.pipelines.events.in long counter
logstash.node.stats.pipelines.events.out long counter
logstash.node.stats.pipelines.events.filtered long counter
logstash.node.stats.pipelines.events.duration_in_millis long counter
logstash.node.stats.pipelines.events.queue_push_duration_in_millis long counter

3. pipeline

Dimensions

Field Source Pre-existing?
service.hostname base-fields.yml no
service.id ecs.yml no
service.type ecs.yml no
service.version ecs.yml no
service.address ecs.yml no
service.name ecs.yml no
event.dataset ecs.yml no
event.module ecs.yml no
agent.id ecs.yml no (new field)
input.type package-fields.yml no
cloud.account.id agent.yml no
cloud.availability_zone agent.yml no
cloud.instance.id agent.yml no
cloud.instance.name agent.yml no
cloud.machine.type agent.yml no
cloud.provider agent.yml no
cloud.region agent.yml no
cloud.project.id agent.yml no
cloud.image.id agent.yml no
host.architecture agent.yml no
host.domain agent.yml no
host.hostname agent.yml no
host.id agent.yml no
host.ip agent.yml no
host.mac agent.yml no
host.name agent.yml no
host.os.family agent.yml no
host.os.kernel agent.yml no
host.os.name agent.yml no
host.os.platform agent.yml no
host.os.version agent.yml no
host.type agent.yml no
host.os.build agent.yml no
host.os.codename agent.yml no
logstash.pipeline.name fields.yml yes
logstash.pipeline.elasticsearch.cluster.id fields.yml no
logstash.pipeline.info.ephemeral_id fields.yml yes
logstash.pipeline.host.name fields.yml no
logstash.pipeline.host.address fields.yml yes
logstash.pipeline.total.flow.queues.type fields.yml no

Neither Dimension nor Metric

Field Type
@timestamp date (ecs)
process.pid long (ecs)
ecs.version keyword (ecs)
event.duration long (ecs)
error.message match_only_text (ecs)
container.id keyword (ecs)
container.image.name keyword (ecs)
container.labels object (ecs)
container.name keyword (ecs)
host.containerized boolean

Metrics Added / Changed

Changed (counter → gauge):

Field Type Old New
logstash.pipeline.total.flow.queues.events long counter gauge

Newly added metric_type:

Field Type metric_type
logstash.pipeline.info.batch_size long gauge
logstash.pipeline.info.batch_delay long gauge
logstash.pipeline.info.workers long gauge

4. plugins

Dimensions

Field Source Pre-existing?
service.hostname base-fields.yml no
service.id ecs.yml no
service.type ecs.yml no
service.version ecs.yml no
service.address ecs.yml no
service.name ecs.yml no
event.dataset ecs.yml no
event.module ecs.yml no
agent.id ecs.yml no (new field)
input.type package-fields.yml no
cloud.account.id agent.yml no
cloud.availability_zone agent.yml no
cloud.instance.id agent.yml no
cloud.instance.name agent.yml no
cloud.machine.type agent.yml no
cloud.provider agent.yml no
cloud.region agent.yml no
cloud.project.id agent.yml no
cloud.image.id agent.yml no
host.architecture agent.yml no
host.domain agent.yml no
host.hostname agent.yml no
host.id agent.yml no
host.ip agent.yml no
host.mac agent.yml no
host.name agent.yml no
host.os.family agent.yml no
host.os.kernel agent.yml no
host.os.name agent.yml no
host.os.platform agent.yml no
host.os.version agent.yml no
host.type agent.yml no
host.os.build agent.yml no
host.os.codename agent.yml no
logstash.pipeline.name fields.yml no
logstash.pipeline.id fields.yml yes
logstash.pipeline.elasticsearch.cluster.id fields.yml no
logstash.pipeline.host.name fields.yml no
logstash.pipeline.host.address fields.yml no
logstash.pipeline.plugin.type fields.yml no
logstash.pipeline.plugin.codec.name fields.yml no
logstash.pipeline.plugin.codec.id fields.yml yes
logstash.pipeline.plugin.input.name fields.yml no
logstash.pipeline.plugin.input.id fields.yml yes
logstash.pipeline.plugin.input.elasticsearch.cluster.id fields.yml no
logstash.pipeline.plugin.filter.name fields.yml no
logstash.pipeline.plugin.filter.id fields.yml yes
logstash.pipeline.plugin.filter.elasticsearch.cluster.id fields.yml no
logstash.pipeline.plugin.output.name fields.yml no
logstash.pipeline.plugin.output.id fields.yml yes
logstash.pipeline.plugin.output.elasticsearch.cluster.id fields.yml no

Neither Dimension nor Metric

Field Type
@timestamp date (ecs)
process.pid long (ecs)
ecs.version keyword (ecs)
event.duration long (ecs)
error.message match_only_text (ecs)
container.id keyword (ecs)
container.image.name keyword (ecs)
container.labels object (ecs)
container.name keyword (ecs)
host.containerized boolean
logstash.pipeline.plugin.input.source.column keyword
logstash.pipeline.plugin.input.source.id keyword
logstash.pipeline.plugin.input.source.line long
logstash.pipeline.plugin.input.source.protocol keyword
logstash.pipeline.plugin.filter.source.column keyword
logstash.pipeline.plugin.filter.source.id keyword
logstash.pipeline.plugin.filter.source.line long
logstash.pipeline.plugin.filter.source.protocol keyword
logstash.pipeline.plugin.output.source.column keyword
logstash.pipeline.plugin.output.source.id keyword
logstash.pipeline.plugin.output.source.line long
logstash.pipeline.plugin.output.source.protocol keyword

Metrics Added / Changed

Changed (counter → gauge):

Field Type Old New
logstash.pipeline.plugin.input.metrics.beats.peak_connections long counter gauge
logstash.pipeline.plugin.input.metrics.beats.current_connections long counter gauge

No newly added metric_type fields in this data stream.

Open questions

Original question

As the data streams are migrated to TSDB they do not support metrics which documents
containing the error when fetching a metric as those would not have the necessary
dimensions. When testing, I started the agent before logstash was ready, getting
a few errors, which when testing the migration with https://github.com/elastic/TSDB-migration-test-kit
could not be migrated.

If we want to keep this behaviour, we'd need to add more dimensions to allow
those events to be ingested.

On my tests, the error events were present on health_report and on node_cel
data streams.

Here is an example of the error documents:

{"error": {"type": "illegal_argument_exception", "reason": "Error extracting routing: source didn't contain any routing fields"}, "status": 400, "document": {"cloud": {"availability_zone": "us-central1-f", "instance": {"name": "anderson-logstash", "id": "8077647130981829769"}, "provider": "gcp", "service": {"name": "GCE"}, "machine": {"type": "e2-standard-4"}, "project": {"id": "elastic-observability"}, "region": "us-central1", "account": {"id": "elastic-observability"}}, "input": {"type": "cel"}, "agent": {"name": "anderson-logstash", "id": "27ad10fc-cef3-424a-879c-23721c867517", "type": "filebeat", "ephemeral_id": "c2cfc104-c50f-4906-af6e-7ddcf911012a", "version": "8.17.10"}, "@timestamp": "2026-02-12T11:32:41.562Z", "ecs": {"version": "8.0.0"}, "data_stream": {"namespace": "default", "type": "metrics", "dataset": "logstash.node"}, "elastic_agent": {"id": "27ad10fc-cef3-424a-879c-23721c867517", "version": "8.17.10", "snapshot": false}, "host": {"hostname": "anderson-logstash", "os": {"kernel": "6.1.0-43-cloud-amd64", "codename": "bookworm", "name": "Debian GNU/Linux", "type": "linux", "family": "debian", "version": "12 (bookworm)", "platform": "debian"}, "containerized": false, "ip": ["10.128.0.72", "fe80::4001:aff:fe80:48"], "name": "anderson-logstash", "id": "370ef8b742434f90a470fd961035344e", "mac": ["42-01-0A-80-00-48"], "architecture": "x86_64"}, "error": {"message": "failed eval: ERROR: <input>:7:7: Get \"http://localhost:9600/_node/stats?graph=true&vertices=true\": dial tcp [::1]:9600: connect: connection refused\n |       ? {\n | ......^"}, "event": {"agent_id_status": "verified", "ingested": "2026-02-12T11:32:50Z", "dataset": "logstash.node"}}}

One option could be to have the agent.id as dimension, that way the error events
could be indexed, having their TSDB ID from the agent.id+timestamp, what seems
ok. However, it means additional mappings and dimensions for this corner case.

I checked and the errors are still logged and appear on the agent dashboards
which show errors, like the "concerning agents". So, the errors aren't lost,
nevertheless, it's still a breaking change if anyone would rely on documents with
the error key to know something is wrong.

Talking to the team we agreed there is no issue adding the agent.id as
dimension to all data streams, so the events with errors when fetching metrics
can be indexed, having their TSDB ID from the agent.id+timestamp. See above
for details.

Also, I confirmed with the ES team that "redundant" dimensions, dimensions that
do not "create new IDs" have a negligible impact.
Here it's create a new "metric series", but only one for agent to allow the
errors to be ingested and keep the backwards compatibility, which seems a good
trade-off.

Checklist

  • [ ] I have reviewed tips for building integrations and this pull request is aligned with them.
  • I have verified that all data streams collect metrics or logs.
  • [ ] I have added an entry to my package's changelog.yml file.
  • [ ] I have verified that Kibana version constraints are current according to guidelines.
  • [ ] I have verified that any added dashboard complies with Kibana's Dashboard good practices

How to test this PR locally

I used a modified version
of the TSDB migration test kit
to test the migration of the data streams to TSDB. It reindex the source index
to the destination index. This approach fails if there are documents that cannot
be ingested into the TSDB. For example the "error" events I mentioned above.
Thus, I modified it to scan the source index and use the bulk API to index the
documents, saving the failed and duplicated documents into 2 different files.

You may try both versions of the test kit.

click to show instructions
  • set up an elastic stack version 8.17.10 (8.17 is the lowest version supported)

Agent + Logstash output setup

Let's setup 2 nodes. All paths are relative to the Logstash directory

logstash: node 1:

agent.conf:

input {
  elastic_agent {
    port => 5044
    enrich => none
    ssl_enabled => false
  }
}

output {
  elasticsearch {
    cloud_id => "cloudID"
    data_stream => true
    ssl_enabled => true
    user => "elastic"
    password => "changeme"
  }
}

config/logstash.yml:

node.name: logstash-node-1

log.level: debug 
log.format.json.fix_duplicate_message_fields: true

path.logs: /tmp/logstash-node-1/logs
cd logstasn-node-1
./bin/logstash -f agent.conf

logstash: node 2:

agent.conf:

input {
  elastic_agent {
    port => 5045
    enrich => none
    ssl_enabled => false
  }
}

output {
  elasticsearch {
    cloud_id => "cloudID"
    data_stream => true
    ssl_enabled => true
    user => "elastic"
    password => "changeme"
  }
}

config/logstash.yml:

node.name: logstash-node-2
api.http.port: 9601

log.level: debug 
log.format.json.fix_duplicate_message_fields: true

path.logs: /tmp/logstash-node-2/logs
cd logstasn-node-2
./bin/logstash -f agent.conf

Elastic Agent

  • create a agent policy
  • add a logstash output with hosts: ["localhost:5044", "localhost:5045"]
  • set the output as the integrations output
  • generate some logs: flog -t log -o /tmp/agent/in/log.ndjson -w -f json -l -p 1048576 -d 500ms
  • setup a filestream input to collect the generated logs
  • install the agent with --namespace logstash-output

Elastic Agent with Logstash integration

  • create an agent policy
  • add 2 logstash integrations, each to monitor a node:
    • integration 1:
      • Metrics Metrics (Elastic Agent) -> Logstash URL: http://localhost:9600
      • Logs paths: /tmp/logstash-node-1/logs/logstash-plain*.log
      • Slowlogs paths: /tmp/logstash-node-1/logs/logstash-slowlog-plain*.log
      • Metrics (Stack Monitoring) -> Hosts http://localhost:9600
    • integration 1:
      • Metrics Metrics (Elastic Agent) -> Logstash URL: http://localhost:9601
      • Logs paths: /tmp/logstash-node-2/logs/logstash-plain*.log
      • Slowlogs paths: /tmp/logstash-node-2/logs/logstash-slowlog-plain*.log
      • Metrics (Stack Monitoring) -> Hosts http://localhost:9601
    • install the agent with --namespace monitoring

Verify

  • verify the agent-logstash-output is sending data, check there are logs from
    path /tmp/agent/in/log.ndjson
  • verify the agent-monitoring is collecting data. Check the logstash dashboards.
    I recomend to let it run for a good while, so there will be a good amount of data
    https://github.com/elastic/TSDB-migration-test-kit can use when testing the TSDB
    migration.
  • build and install the integration from this PR: elastic-package build -v && elastic-package install -v
  • run TSDB-migration-test-kit for each one of the changed data streams
  • check the dashboards are working fine with the old and new data

Check failures are ingested as metrics

tl;dr: the cel input produces an event with error.message if it fails to fetch
data. The only dimension present on this event is agent.id. Given it has at
least one dimension, present, the event should be ingested.

  • Go to the logstash node 2 and stop it, so the agent cannot fetch data from it
  • observe the agent logs, you should see errors like:
{
  "log.level": "warn",
  "message": "Failed to index 4 events in last 10s: events were dropped! Look at the event log to view the event and cause.",
  "log.logger": "elasticsearch"
}
  • go to the "Logstash Stack Monitoring Metrics" data view in discover
  • filter by your error.message exists: error.message : *
  • ensure you see connection errors like: error making http request: Get "http://localhost:9601/": dial tcp 127.0.0.1:9601: connect: connection refused

Related issues

@AndersonQ AndersonQ self-assigned this Feb 12, 2026
@AndersonQ AndersonQ added Integration:logstash Logstash Team:Elastic-Agent-Data-Plane Agent Data Plane team [elastic/elastic-agent-data-plane] labels Feb 12, 2026
@AndersonQ AndersonQ force-pushed the 16512-logstash-metrics-TSDB branch from 1b1af21 to 6cbf6df Compare February 12, 2026 16:53
@AndersonQ AndersonQ changed the title WIP: [logstash] Enable TSDB for metrics data streams [logstash] Enable TSDB for metrics data streams Feb 13, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 16, 2026

Vale Linting Results

Summary: 4 warnings, 2 suggestions found

⚠️ Warnings (4)
File Line Rule Message
packages/logstash/docs/README.md 33 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'and so on' instead of 'etc'.
packages/logstash/docs/README.md 38 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'for example' instead of 'e.g'.
packages/logstash/docs/README.md 40 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'for example' instead of 'e.g'.
packages/logstash/docs/README.md 75 Elastic.DontUse Don't use 'Note that'.
💡 Suggestions (2)
File Line Rule Message
packages/logstash/docs/README.md 36 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/logstash/docs/README.md 75 Elastic.WordChoice Consider using 'refer to (if it's a document), view (if it's a UI element)' instead of 'see', unless the term is in the UI.

The Vale linter checks documentation changes against the Elastic Docs style guide.

To use Vale locally or report issues, refer to Elastic style guide for Vale.

@elastic-vault-github-plugin-prod
Copy link
Copy Markdown

elastic-vault-github-plugin-prod Bot commented Feb 16, 2026

🚀 Benchmarks report

To see the full report comment with /test benchmark fullreport

@andrewkroh andrewkroh added the documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. label Feb 16, 2026
@AndersonQ AndersonQ force-pushed the 16512-logstash-metrics-TSDB branch from 48bd9ea to 7d21447 Compare February 19, 2026 11:37
Comment on lines +25 to +27
- name: agent.id
external: ecs
dimension: true
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agent.id is added so the data stream can accept the events produced by the Cel input or metricbeat when an error occurs. On error they produce an event without the metric metadata and dimensions, causing it to be rejected. The metadata guaranteed to be there is agent.id. Even though it isn't really a metric, those documents are allowed for backwards compatibility.

@AndersonQ AndersonQ force-pushed the 16512-logstash-metrics-TSDB branch from 7d21447 to d8af58b Compare February 19, 2026 16:24
@AndersonQ AndersonQ marked this pull request as ready for review February 19, 2026 16:24
@AndersonQ AndersonQ requested a review from a team as a code owner February 19, 2026 16:24
@elasticmachine
Copy link
Copy Markdown

Pinging @elastic/elastic-agent-data-plane (Team:Elastic-Agent-Data-Plane)

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enables Time Series Data Stream (TSDB) mode for the Logstash integration's health_report and node_cel data streams, and corrects metric type annotations across multiple data streams. The changes allow error events to be properly ingested in TSDB mode by adding agent.id as a dimension across all affected data streams, ensuring backward compatibility.

Changes:

  • Enabled TSDB mode for health_report and node_cel data streams
  • Added dimension annotations to support TSDB routing (agent.id, node names, pipeline identifiers, host names)
  • Corrected metric_type from counter to gauge for point-in-time measurements (thread counts, heap max, queue depths, connection counts)
  • Added metric_type annotations to previously unannotated numeric fields

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/logstash/manifest.yml Version bump from 2.8.0 to 2.9.0
packages/logstash/docs/README.md Updated documentation tables to include agent.id field and Metric Type column for all affected data streams
packages/logstash/data_stream/health_report/manifest.yml Enabled TSDB mode by adding index_mode: "time_series"
packages/logstash/data_stream/health_report/fields/fields.yml Added dimensions (node.name, node.uuid, pipeline.id) and metric_type annotations for worker utilization and severity fields
packages/logstash/data_stream/health_report/fields/ecs.yml Added agent.id as dimension
packages/logstash/data_stream/node_cel/manifest.yml Enabled TSDB mode by adding index_mode: "time_series"
packages/logstash/data_stream/node_cel/fields/fields.yml Added dimension (logstash.name), corrected metric_types (counter→gauge), and added metric_type annotations for pipeline events and queue fields
packages/logstash/data_stream/node_cel/fields/ecs.yml Added agent.id as dimension
packages/logstash/data_stream/pipeline/fields/fields.yml Added dimension (host.name), added metric_type annotations for info fields, corrected queues.events from counter to gauge
packages/logstash/data_stream/pipeline/fields/ecs.yml Added agent.id as dimension
packages/logstash/data_stream/plugins/fields/fields.yml Added dimension (host.name), corrected beats connection metrics from counter to gauge
packages/logstash/data_stream/plugins/fields/ecs.yml Added agent.id as dimension
packages/logstash/changelog.yml Added version 2.9.0 entry documenting TSDB enablement and metric_type fixes

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Enable TSDB for health_report and node_cel data streams in the Logstash
integration and add metric_type annotations to pipeline and plugins.
Dimensions added:

- health_report:
  service.hostname
  logstash.node.name
  logstash.node.uuid
  logstash.pipeline.id
  logstash.node.version
  logstash.node.address
  logstash.pipeline.diagnosis.id
  logstash.pipeline.diagnosis.help_url
  logstash.pipeline.impacts.id
  logstash.pipeline.impacts.impact_areas

- node_cel:
  input.type
  cloud.image.id
  host.os.build
  host.os.codename
  service.hostname
  logstash.node.stats.logstash.name
  logstash.node.stats.logstash.uuid
  logstash.node.stats.logstash.version
  logstash.node.stats.logstash.host
  logstash.node.stats.logstash.http_address
  logstash.elasticsearch.cluster.id

- pipeline:
  input.type
  cloud.image.id
  host.os.build
  host.os.codename
  service.hostname
  logstash.pipeline.host.name,
  logstash.pipeline.elasticsearch.cluster.id,
  logstash.pipeline.total.queues.type

- plugins:
  input.type
  cloud.image.id
  host.os.build
  host.os.codename
  service.hostname
  logstash.pipeline.host.name
  logstash.pipeline.name,
  logstash.pipeline.host.address
  logstash.pipeline.plugin.type
  logstash.pipeline.plugin.codec.name
  logstash.pipeline.plugin.input.name
  logstash.pipeline.plugin.filter.name
  logstash.pipeline.plugin.output.name

Add agent.id as a dimension so the data streams can accept events produced
by the Cel input or Metricbeat on error. Error events lack metric metadata
and dimensions, causing them to be rejected. Since agent.id is guaranteed
to be present, it serves as a fallback dimension. Although not strictly a
metric, these documents are allowed for backwards compatibility.

Annotate numeric fields with appropriate metric_type for the health_report,
node_cel, pipeline, plugins data streams.
metric_type corrections (counter → gauge):
- node_cel: jvm.threads.count, jvm.threads.peak_count,
  jvm.mem.heap_max_in_bytes, queue.events_count
- pipeline: logstash.pipeline.queues.events
- plugins: beats.peak_connections, beats.current_connections

Assisted by Cursor
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +60 to +63
dimension: true
- name: mac
external: ecs
dimension: true
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

host.ip and host.mac are marked as dimension: true, but these ECS fields are commonly multi-valued arrays. Time series dimension fields must be single-valued; if a host reports multiple IPs/MACs, TSDB ingestion can be rejected. Consider removing dimension: true from these fields (and keep stable identifiers like host.id, host.name, host.hostname as dimensions).

Suggested change
dimension: true
- name: mac
external: ecs
dimension: true
- name: mac
external: ecs

Copilot uses AI. Check for mistakes.
Comment on lines 3 to +17
- name: service.id
external: ecs
dimension: true
- name: service.type
external: ecs
dimension: true
- name: service.version
external: ecs
dimension: true
- name: service.address
external: ecs
dimension: true
- name: service.name
external: ecs
dimension: true
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This data stream already uses index_mode: "time_series", and this change adds many more dimension: true fields (service/event/agent + cloud/host + pipeline/plugin identifiers). The manifest currently doesn't set index_template.settings.index.mapping.dimension_fields.limit, so once the dimension count exceeds the default (16) indexing/template creation can fail. Please update packages/logstash/data_stream/plugins/manifest.yml to set an appropriate dimension_fields.limit (or reduce the dimension set).

Copilot uses AI. Check for mistakes.
Comment on lines +60 to +63
dimension: true
- name: mac
external: ecs
dimension: true
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

host.ip and host.mac are marked as dimension: true, but these ECS fields are commonly multi-valued arrays. Time series dimension fields must be single-valued; if a host reports multiple IPs/MACs, TSDB ingestion can be rejected. Consider removing dimension: true from these fields (and keep stable identifiers like host.id, host.name, host.hostname as dimensions).

Suggested change
dimension: true
- name: mac
external: ecs
dimension: true
- name: mac
external: ecs

Copilot uses AI. Check for mistakes.
Comment thread packages/logstash/data_stream/node_cel/manifest.yml
Comment on lines +60 to +63
dimension: true
- name: mac
external: ecs
dimension: true
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

host.ip and host.mac are marked as dimension: true, but these ECS fields are commonly multi-valued arrays. Time series dimension fields must be single-valued; if an agent reports multiple IPs/MACs (common on dual-stack hosts), TSDB ingestion can be rejected. Consider removing dimension: true from these fields (and rely on stable identifiers like host.id, host.name, host.hostname) or otherwise ensure a single value is indexed.

Suggested change
dimension: true
- name: mac
external: ecs
dimension: true
- name: mac
external: ecs

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +14
dimension: true
- name: service.address
external: ecs
dimension: true
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This data stream already uses index_mode: "time_series", and this change adds many more dimension: true fields (ECS service/event/agent + cloud/host + logstash pipeline fields). The manifest currently doesn't set index_template.settings.index.mapping.dimension_fields.limit, so once the dimension count exceeds the default (16) indexing/template creation can fail. Please update packages/logstash/data_stream/pipeline/manifest.yml to set an appropriate dimension_fields.limit (or reduce the dimension set).

Suggested change
dimension: true
- name: service.address
external: ecs
dimension: true
- name: service.address
external: ecs

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

@mashhurs mashhurs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still on it this (setting up the stack and testing) but to move forward, I have left some questions.
Also, I wonder how integration upgrade experience would be (sorry not much experience with entire process):

  • before upgrade, index isn't with tsds mode. How does it affect after upgrade? Will integration create new index with mapping mode changed?
  • on the dashboards, will older metrics be available?
  • how does field metric_type change impact?
  • can you also please check if package conditions need to change? -

Thank you for the great work.

Comment thread packages/logstash/data_stream/node_cel/fields/fields.yml
external: ecs
- name: service.id
external: ecs
dimension: true
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to add as much as possible more fields to the dimension? I was thinking if it will be meaningful to include node.uuid + pipeline.id granularity (one series for {node vs pipeline}) if it makes sense. Also, AFAIK, there is also limitation (16 fields by default?) for the TSDB dimension if need to change the mapping, but you better know than me...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to add as much as possible more fields to the dimension?

I was talking to the ES storage engine team, ideally a TSDB has only dimension and metrics. The data we append to each event has more than that, so to try to achieve it, I added the dimensions that seems to be redundant, which will not create a new time series (tsid). Thus, minimising the number of non-metric non-dimension fields. I'll ping you on slack the discussion with the ES team.

Also, AFAIK, there is also limitation (16 fields by default?)

The dimension limit is pretty high now, 32768, see docs (look for index.mapping.dimension_fields.limit ). Which is the same for the 8.17 stach, see here

I was thinking if it will be meaningful to include node.uuid + pipeline.id granularity (one series for {node vs pipeline})

On this data stream or on all of them? I can add it

@AndersonQ
Copy link
Copy Markdown
Member Author

AndersonQ commented Mar 5, 2026

Hi, let me try to answer your questions

  • before upgrade, index isn't with tsds mode. How does it affect after upgrade? Will integration create new index with mapping mode changed?

Yes, the index is rolled over and the new backing index is a TSDB

  • on the dashboards, will older metrics be available?

Yes, I haven't observed any issue. But please, double check that. On my tests not visualisation/charts had data since the beginning (before the migration). But as far as
I'm concerned, it all should work.

The only thing I could imagine having an impact is for any metric that had its type fixed, if there were anything that needed the old type. However, given the old type was wrong, anything depending on the old type should be wrong as well.

  • how does field metric_type change impact?

It's what tells ES what type of metric it is so ES can store it in the best way possible. It's what I know from the docs.

I'll look into it

external: ecs
- name: service.id
external: ecs
dimension: true
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to add as much as possible more fields to the dimension?

I was talking to the ES storage engine team, ideally a TSDB has only dimension and metrics. The data we append to each event has more than that, so to try to achieve it, I added the dimensions that seems to be redundant, which will not create a new time series (tsid). Thus, minimising the number of non-metric non-dimension fields. I'll ping you on slack the discussion with the ES team.

Also, AFAIK, there is also limitation (16 fields by default?)

The dimension limit is pretty high now, 32768, see docs (look for index.mapping.dimension_fields.limit ). Which is the same for the 8.17 stach, see here

I was thinking if it will be meaningful to include node.uuid + pipeline.id granularity (one series for {node vs pipeline})

On this data stream or on all of them? I can add it

Comment thread packages/logstash/data_stream/node_cel/fields/fields.yml
Comment on lines +54 to 56
dimension: true
- name: id
external: ecs
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mashhurs, do you think host.id is stable enough? Some tsdb here use ephemeral_id as dimension, so it seems to me host.id would change as much as ephemeral_id. At the end the question is do you think the host.id can change and it'd still be the same host?

Comment thread packages/logstash/data_stream/node_cel/manifest.yml
Comment on lines +11 to +14
dimension: true
- name: service.address
external: ecs
dimension: true
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

@mashhurs mashhurs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AndersonQ, first of all thank you for clarifications. I don't have concerns after reading the slack thread with storage-engine team you clarified dimensions.

  • One thing left if you please check the conditions - it doesn't seem we need to change but for the safety if we need to Kibana 8.18+.
  • I have done couple of tests, including upgrade and fresh set up etc...
    One scenario didn't work (tested twice, maybe I did something wrong) which is when upgrading with policies (screenshot below). I of course updated elastic-agent with the new policy including generated API key. Can you please check it?
Image

@AndersonQ
Copy link
Copy Markdown
Member Author

@AndersonQ, first of all thank you for clarifications. I don't have concerns after reading the slack thread with storage-engine team you clarified dimensions.

  • One thing left if you please check the conditions - it doesn't seem we need to change but for the safety if we need to Kibana 8.18+.
  • I have done couple of tests, including upgrade and fresh set up etc...
    One scenario didn't work (tested twice, maybe I did something wrong) which is when upgrading with policies (screenshot below). I of course updated elastic-agent with the new policy including generated API key. Can you please check it?
Image

Hi @mashhurs,

What exactly didn't work? What steps did you follow to produce the error? what was the error you got?

@mashhurs
Copy link
Copy Markdown
Contributor

mashhurs commented Mar 6, 2026

Hi @mashhurs,

What exactly didn't work? What steps did you follow to produce the error? what was the error you got?

I spinned up the stack (with elastic-package) where LS integration 2.8.0 was provide. I installed the integration, added standalone agent (elastic-agent-9.1.2-darwin-aarch64, sudo ./elastic-agent run -e --develop) and pushed data to ES. I confirmed metrics around ~20min. Then pulled your PR, build the package (run elastic-package build && elastic-package install in the package path). Upgrade to 2.9.0 was available. I upgraded by enabling "Upgrade integration policies". Then under the installed integration, copied the policy (from Fleet -> Agent policies -> created-ls-policy -> Actions -> View policy) and updated in standalone elastic-agent.yaml. Since this didn't work, I recreated policy through adding agent, again created API key and updated elastic-agent.yaml. I did wait for around 20mins but data didn't arrive. I was getting warning message in elastic-agent console saying "N inflight events...." (I will re-test and capture if you need, my console was cleared).
Note that, same test I did without enabling "Upgrade integration policies" and I didn't face issue. Upgrade was smooth, index was rolled out, updated index mapping was clearly showing TSDB...

@AndersonQ
Copy link
Copy Markdown
Member Author

Since this didn't work, I recreated policy through adding agent, again created API key and updated elastic-agent.yaml. I did wait for around 20mins but data didn't arrive. I was getting warning message in elastic-agent console saying "N inflight events...." (I will re-test and capture if you need, my console was cleared).

Hum... I'd need the agent logs at least, ideally an agent diagnostics. I confess I'm not sure if it's possible to get a diagnostic of an agent that isn't installed.

Let me know when you have the doagnostics/logs

@mashhurs
Copy link
Copy Markdown
Contributor

Let me know when you have the doagnostics/logs

It looks like something is weird with upgrade process. This time I faced the same issue without enabling "Upgrade Integration policies". It happened once.

Step by step explanation if I did something wrong:

  • spinned the stack with elastic-package stack up
  • logged in Kibana and installed LS integration, setup standalone agent and used the policy. Confirmed data on dashboards.
  • pulled your change and did elastic-package build in the packages/logstash
  • then restarted the stack (elastic-package stack down && elastic-package stack up)
  • logged back to the Kibana and confirm upgrade to option is available
  • I hit the upgrade button (this time didn't enable the "Upgrade Integration policies") and you can see in the below screenshot the version is now 2.9.0
image
  • however, if I click the Logstash, I again see the "Upgrade" option. If I click the "Upgrade" button, the success/alert message says "ready to upgrade...." which is very confusing. At this stage I went to dashboard and confirmed no data was flowing.
image image
  • following logs were in the elastic-agent logs:
{"log.level":"info","@timestamp":"2026-03-09T17:59:14.889-0700","message":"process repeated request","component":{"binary":"filebeat","dataset":"elastic_agent.filebeat","id":"cel-default","type":"cel"},"log":{"source":"cel-default"},"log.logger":"input.cel","log.origin":{"file.line":243,"file.name":"cel/input.go","function":"github.com/elastic/beats/v7/x-pack/filebeat/input/cel.input.run.func1"},"service.name":"filebeat","id":"cel-logstash.health_report-c2b7a34a-bd72-4cff-9055-3c82933a6987","input_source":"http://localhost:9600/_health_report","input_url":"http://localhost:9600/_health_report","ecs.version":"1.6.0","ecs.version":"1.6.0"}
{"log.level":"info","@timestamp":"2026-03-09T17:59:14.889-0700","message":"process repeated request","component":{"binary":"filebeat","dataset":"elastic_agent.filebeat","id":"cel-default","type":"cel"},"log":{"source":"cel-default"},"id":"cel-logstash.plugins-c2b7a34a-bd72-4cff-9055-3c82933a6987","log.logger":"input.cel","service.name":"filebeat","input_source":"http://localhost:9600/_node","input_url":"http://localhost:9600/_node","ecs.version":"1.6.0","log.origin":{"file.line":243,"file.name":"cel/input.go","function":"github.com/elastic/beats/v7/x-pack/filebeat/input/cel.input.run.func1"},"ecs.version":"1.6.0"}
{"log.level":"info","@timestamp":"2026-03-09T17:59:14.889-0700","message":"process repeated request","component":{"binary":"filebeat","dataset":"elastic_agent.filebeat","id":"cel-default","type":"cel"},"log":{"source":"cel-default"},"log.logger":"input.cel","log.origin":{"file.line":243,"file.name":"cel/input.go","function":"github.com/elastic/beats/v7/x-pack/filebeat/input/cel.input.run.func1"},"service.name":"filebeat","input_url":"http://localhost:9600/_node/stats?graph=true&vertices=true","ecs.version":"1.6.0","id":"cel-logstash.node-c2b7a34a-bd72-4cff-9055-3c82933a6987","input_source":"http://localhost:9600/_node/stats?graph=true&vertices=true","ecs.version":"1.6.0"}
{"log.level":"info","@timestamp":"2026-03-09T17:59:14.890-0700","message":"process repeated request","component":{"binary":"filebeat","dataset":"elastic_agent.filebeat","id":"cel-default","type":"cel"},"log":{"source":"cel-default"},"log.logger":"input.cel","id":"cel-logstash.pipeline-c2b7a34a-bd72-4cff-9055-3c82933a6987","input_source":"http://localhost:9600/_node","input_url":"http://localhost:9600/_node","log.origin":{"file.line":243,"file.name":"cel/input.go","function":"github.com/elastic/beats/v7/x-pack/filebeat/input/cel.input.run.func1"},"service.name":"filebeat","ecs.version":"1.6.0","ecs.version":"1.6.0"}

{"log.level":"info","@timestamp":"2026-03-09T17:59:14.890-0700","message":"process repeated request","component":{"binary":"filebeat","dataset":"elastic_agent.filebeat","id":"cel-default","type":"cel"},"log":{"source":"cel-default"},"log.logger":"input.cel","id":"cel-logstash.pipeline-c2b7a34a-bd72-4cff-9055-3c82933a6987","input_source":"http://localhost:9600/_node","input_url":"http://localhost:9600/_node","log.origin":{"file.line":243,"file.name":"cel/input.go","function":"github.com/elastic/beats/v7/x-pack/filebeat/input/cel.input.run.func1"},"service.name":"filebeat","ecs.version":"1.6.0","ecs.version":"1.6.0"}
{"log.level":"info","@timestamp":"2026-03-09T17:59:41.907-0700","message":"Non-zero metrics in the last 30s","component":{"binary":"filebeat","dataset":"elastic_agent.filebeat","id":"cel-default","type":"cel"},"log":{"source":"cel-default"},"log.logger":"monitoring","log.origin":{"file.line":192,"file.name":"log/log.go","function":"github.com/elastic/beats/v7/libbeat/monitoring/report/log.(*reporter).logSnapshot"},"service.name":"filebeat","monitoring":{"ecs.version":"1.6.0","metrics":{"beat":{"cpu":{"system":{"ticks":4},"total":{"ticks":15,"time":{"ms":1},"value":15},"user":{"ticks":11,"time":{"ms":1}}},"info":{"ephemeral_id":"206b0fa1-6c25-473b-88b2-0d02fce74af1","uptime":{"ms":510051},"version":"9.1.2"},"memstats":{"gc_next":84872018,"memory_alloc":48048960,"memory_total":199990736,"rss":206684160},"runtime":{"goroutines":62}},"filebeat":{"events":{"active":0,"added":10,"done":10},"harvester":{"open_files":0,"running":0}},"libbeat":{"config":{"module":{"running":4}},"output":{"events":{"acked":10,"active":0,"batches":1,"total":10},"read":{"bytes":411},"write":{"bytes":4301,"latency":{"histogram":{"count":17,"max":324,"mean":50.76470588235294,"median":6,"min":5,"p75":10,"p95":324,"p99":324,"p999":324,"stddev":98.0663217430307}}}},"pipeline":{"clients":4,"events":{"active":0,"published":10,"total":10},"queue":{"acked":10,"added":{"bytes":19972,"events":10},"consumed":{"bytes":19972,"events":10},"filled":{"bytes":0,"events":0,"pct":0},"max_bytes":0,"max_events":4100,"removed":{"bytes":19972,"events":10}}}},"registrar":{"states":{"current":0}},"system":{"load":{"1":4.0151,"15":3.3496,"5":3.9189,"norm":{"1":0.3346,"15":0.2791,"5":0.3266}}}}},"ecs.version":"1.6.0"}

After saving the integration (from the last screenshot), I do see the data again displayed on the dashboard.
I feel (based on the issue behavior), it doesn't seem related to your change unless there were some errors when upgrading. But I do see index was rolled over, mapping changed. Not sure where to dig and not consistent (cleaned docker images, and did couple of tests didn't face again) behavior.

@AndersonQ
Copy link
Copy Markdown
Member Author

Step by step explanation if I did something wrong:

I don't think there is anything wrong, but I never tried like that. I do as I described on "How to test this PR", which is basically: install and enroll the agent, build install the integration, upgrade the integration, check everything. And also the TSDB migration test kit, but my modified version.

From the logs, I don't see any error or issue. If the data eventually appears in the dashboards, that means the data is there.

I think the issue might be related to the integration upgrade process or just timing between it showing it's updated and all the index rollover. But I'm guessing here.

From what I observed, just installing the new version of the integration is enough to update the indexes, even if you don't upgrade it on a specific policy.

@mashhurs
Copy link
Copy Markdown
Contributor

@AndersonQ please rebase your PR 🙏 This one got merged first - #17009

@elasticmachine
Copy link
Copy Markdown

💚 Build Succeeded

History

cc @AndersonQ

@AndersonQ AndersonQ merged commit ca36b0a into elastic:main Mar 12, 2026
10 checks passed
@elastic-vault-github-plugin-prod
Copy link
Copy Markdown

Package logstash - 2.10.0 containing this change is available at https://epr.elastic.co/package/logstash/2.10.0/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. Integration:logstash Logstash Team:Elastic-Agent-Data-Plane Agent Data Plane team [elastic/elastic-agent-data-plane]

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Logstash integration] Migrate datas treams to TSDB.

5 participants