LinkMesh

Search docs, blog and changelog

ENDE

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
Components
batchmemory_limiterresourcedetectionotlphttp
Destination
OTLP/HTTP endpoint

OpenTelemetry Collector

OpenTelemetry Collector YAML
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:

Custom source body (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

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).