Snippets · Sources
Collect Windows performance counters (CPU, memory, disk)
The windowsperfcounters receiver reads any performance counter Windows exposes and turns each into a metric you name: here processor time for the _Total instance, available memory, and free space for every logical disk. In our run on a GitLab SaaS Windows runner (interval shortened to 10 seconds for the test) the first collection already carried all three.
- Signals
- Metrics
- Category
- Collection
- Source
- Windows performance counters
- Destination
- OTLP/HTTP endpoint
OpenTelemetry Collector
receivers:
windowsperfcounters:
collection_interval: 30s
metrics:
processor.time:
description: Share of time the processors were busy.
unit: "%"
gauge: {}
memory.available:
description: Physical memory available to processes.
unit: MBy
gauge: {}
disk.free:
description: Share of free space on each volume.
unit: "%"
gauge: {}
perfcounters:
- object: Processor
instances: [_Total]
counters:
- name: "% Processor Time"
metric: processor.time
- object: Memory
counters:
- name: Available MBytes
metric: memory.available
- object: LogicalDisk
instances: ["*"]
counters:
- name: "% Free Space"
metric: disk.free
processors:
memory_limiter:
check_interval: 1s
limit_percentage: 80
spike_limit_percentage: 25
resourcedetection:
detectors: [system]
batch:
timeout: 5s
exporters:
otlphttp:
endpoint: https://your-backend:4318
service:
pipelines:
metrics:
receivers: [windowsperfcounters]
processors: [memory_limiter, resourcedetection, batch]
exporters: [otlphttp]
LinkMesh
LinkMesh has no built-in template for this job. Add it as a custom source in raw mode, with windowsperfcounters as the component type and this body - the same lines as under windowsperfcounters in the collector config:
collection_interval: 30s
metrics:
processor.time:
description: Share of time the processors were busy.
unit: "%"
gauge: {}
memory.available:
description: Physical memory available to processes.
unit: MBy
gauge: {}
disk.free:
description: Share of free space on each volume.
unit: "%"
gauge: {}
perfcounters:
- object: Processor
instances: [_Total]
counters:
- name: "% Processor Time"
metric: processor.time
- object: Memory
counters:
- name: Available MBytes
metric: memory.available
- object: LogicalDisk
instances: ["*"]
counters:
- name: "% Free Space"
metric: disk.free
How custom components are validated and rolled out: create a custom source.
Download config.yamlValidated on Windows with otelcol-contrib v0.161.0 on 2026-10-26
Complete config files, each checked with the collector's own validate command (otelcol-contrib v0.161.0). Replace https://your-backend:4318 with your own OTLP endpoint before you run it.
The gotcha
instances: ["*"] means every instance Windows has, not every drive you would name. On our runner LogicalDisk reported two instances, C: (23.6% free) and HarddiskVolume2 (65.6% free) - a partition without a drive letter. An alert on disk.free covers that partition too; list the drive letters when that is not what you want.
What it does not catch
No before/after table: the receiver exists only in the Windows build of the collector, and the behaviour harness runs on Linux. The figures above are from a measured run on a GitLab SaaS Windows runner; CI validates this config there on every change to it.
Manage this across a fleet
LinkMesh manages collector configuration across a fleet from one self-hosted control plane, so a change like this is made once rather than host by host. The first 25 Collectors are free after a no-card registration in the OpenSight Customer Portal (5 without one).
Related snippets
- Detect host and cloud resource attributesFill in host, environment and cloud resource attributes on the collector - without overwriting what the SDK already set.
- Prometheus counters to a delta-only backend (cumulativetodelta)Scrape Prometheus counters and convert them to the delta temporality Dynatrace requires - gauges untouched.
- Receive logs from Fluent Bit and Fluentd (forward)Take logs from existing Fluent Bit or Fluentd agents over the forward protocol, without replacing them first.
- Collect host metrics (CPU, memory, disk, network, processes)CPU, memory, disk, filesystem, network, load and per-process metrics from every host, without a separate node agent.