Requirements
Use OpenTelemetry Collector Contrib on Windows. The core collector does not include the Windows Event Log receiver. Download otelcol-contrib.exe from the OpenTelemetry Collector releases and run it from PowerShell.
On Windows you run the collector directly on the host - there is no Linux Docker /hostfs mount, so host metrics do not need a root_path.
API key injection
Telemtra authenticates every OTLP request with a single header, x-api-key. Create the key in the Telemtra app under workspace settings → API keys, then inject it into the exporter through an environment variable so the key is never hardcoded in the config file:
exporters:
otlp/telemtra:
endpoint: ingest.telemtra.io:443
headers:
x-api-key: ${env:TELEMTRA_API_KEY} Set the environment variable in the same PowerShell session before you start the collector:
$env:TELEMTRA_API_KEY = "tk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" The ${env:TELEMTRA_API_KEY} reference is resolved by the collector at startup. To run the key as a Windows Service, set TELEMTRA_API_KEY as a machine or service environment variable instead of a session variable.
Event logs config
Windows Event Logs are structured. The windowseventlog receiver reads a channel and preserves stable fields such as event ID, provider, computer, channel, and account names so they can be searched, grouped, and alerted on in Telemtra. Save this as windows-event-log.yaml:
receivers:
windowseventlog/application:
channel: application
start_at: end
processors:
transform:
error_mode: ignore
log_statements:
- context: log
statements:
# Core Windows Event attributes
- set(attributes["event.id"], body["event_id"]["id"]) where IsMap(body["event_id"])
- set(attributes["event.provider"], body["provider"]["name"]) where IsMap(body["provider"])
- set(attributes["event.channel"], body["channel"]) where body["channel"] != nil
- set(attributes["event.record_id"], body["record_id"]) where body["record_id"] != nil
- set(attributes["event.task"], body["task"]) where body["task"] != nil
- set(attributes["event.opcode"], body["opcode"]) where body["opcode"] != nil
- set(attributes["event.keywords"], body["keywords"]) where body["keywords"] != nil
# Flatten maps only; preserve other payload shapes before replacing body.
- merge_maps(attributes, body["event_data"], "upsert") where IsMap(body["event_data"])
- set(attributes["event.data"], body["event_data"]) where body["event_data"] != nil and not IsMap(body["event_data"])
- merge_maps(attributes, body["user_data"]["data"], "upsert") where IsMap(body["user_data"]) and IsMap(body["user_data"]["data"])
- set(attributes["event.user_data"], body["user_data"]) where body["user_data"] != nil
# Drop duplicate anonymous Windows EventData fields.
- delete_key(attributes, "param1") where attributes["param1"] != nil
# Severity normalization
- set(severity_text, "DEBUG") where body["level"] == "Verbose"
- set(severity_number, 5) where body["level"] == "Verbose"
- set(severity_text, "INFO") where body["level"] == "Information" or body["level"] == "Success Audit"
- set(severity_number, 9) where body["level"] == "Information" or body["level"] == "Success Audit"
- set(severity_text, "WARN") where body["level"] == "Warning" or body["level"] == "Failure Audit"
- set(severity_number, 13) where body["level"] == "Warning" or body["level"] == "Failure Audit"
- set(severity_text, "ERROR") where body["level"] == "Error"
- set(severity_number, 17) where body["level"] == "Error"
- set(severity_text, "FATAL") where body["level"] == "Critical"
- set(severity_number, 21) where body["level"] == "Critical"
# Replace giant object with actual message
- set(body, body["message"]) where body["message"] != nil
resource:
attributes:
- key: service.name
value: windows-event-viewer
action: upsert
- key: deployment.environment
value: production
action: upsert
batch:
send_batch_size: 1000
timeout: 10s
exporters:
otlp/telemtra:
endpoint: ingest.telemtra.io:443
headers:
x-api-key: ${env:TELEMTRA_API_KEY}
service:
pipelines:
logs:
receivers: [windowseventlog/application]
processors: [transform, resource, batch]
exporters: [otlp/telemtra] To collect more channels, add receivers like windowseventlog/security (channel: Security) and windowseventlog/system (channel: System) and list them in the logs pipeline alongside the application receiver. Once events are flowing, the Windows Event IDs reference covers which IDs in each channel are worth alerting on and which properties to filter.
Severity and fields
The windowseventlog receiver emits each event as a large structured JSON object in the log body. The transform processor above uses OTTL statements to turn that raw object into clean, searchable telemetry before it leaves the host. It does three things:
- Promotes core event fields to attributes. Event ID, provider, channel, record ID, task, opcode, and keywords are copied to stable
event.*attributes so they can be filtered, grouped, and used in alerts. Map-valuedevent_dataanduser_data.dataare flattened into attributes withmerge_maps. Otherevent_datashapes are preserved inevent.data, and the completeuser_datais preserved inevent.user_data, and the anonymousparam1duplicate is dropped. - Normalizes severity. Windows levels are mapped to OpenTelemetry severity so Telemtra colors and filters them correctly: Verbose → DEBUG, Information / Success Audit → INFO, Warning / Failure Audit → WARN, Error → ERROR, and Critical → FATAL. Each rule sets both
severity_textand the numericseverity_number. - Replaces the body with the rendered message. The final statement swaps the giant raw object for
body.message, so the log body in Telemtra reads as the human message while the structured detail lives in attributes.
Event payload types vary by Windows provider. A non-null value can be a string rather than a map; IsMap guards prevent merge_maps from failing on these events. Explicit error_mode: ignore logs unexpected transformation errors and continues processing. Apply these changes to the collector configuration on each Windows host and restart that collector; updating the ingest server alone does not change host configurations. Receiver retries cannot repair a deterministic type error.
Order matters: transform runs before resource and batch in the pipeline so it can read the raw event body before anything else touches it.
Host metrics config
Use the hostmetrics receiver for Windows CPU, memory, disk, filesystem, network, paging, and process metrics. The processes scraper emits metrics such as system.processes.count when supported on the host. Save this as windows-host-metrics.yaml:
receivers:
hostmetrics:
collection_interval: 30s
scrapers:
cpu:
memory:
disk:
filesystem:
metrics:
system.filesystem.utilization:
enabled: true
network:
paging:
processes:
processors:
memory_limiter:
check_interval: 1s
limit_mib: 512
resource/host:
attributes:
- key: service.name
value: windows-host
action: upsert
- key: host.name
value: THINKPAD
action: upsert
- key: deployment.environment
value: production
action: upsert
batch:
timeout: 1s
send_batch_size: 1024
exporters:
otlp/telemtra:
endpoint: ingest.telemtra.io:443
headers:
x-api-key: ${env:TELEMTRA_API_KEY}
service:
pipelines:
metrics:
receivers: [hostmetrics]
processors: [memory_limiter, resource/host, batch]
exporters: [otlp/telemtra] Replace host.name: THINKPAD with the machine name you use in operations, and set deployment.environment to the scope you want.
Run the collector
From PowerShell, set the API key, then start the collector with the config you want:
$env:TELEMTRA_API_KEY = "tk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
.\otelcol-contrib.exe --config .\windows-event-log.yaml If the collector fails because 127.0.0.1:8888 is already in use, another collector instance is running. Find and stop it:
Get-NetTCPConnection -LocalAddress 127.0.0.1 -LocalPort 8888 |
Select-Object LocalPort,OwningProcess
Stop-Process -Id <pid> Verify
Generate a test Application event from an Administrator PowerShell:
New-EventLog -LogName Application -Source TelemtraSmokeTest -ErrorAction SilentlyContinue
Write-EventLog -LogName Application -Source TelemtraSmokeTest -EventId 1001 -EntryType Information -Message "Telemtra Windows Event Viewer smoke test" In Telemtra, Logs should show service windows-event-viewer. Event records arrive as structured JSON bodies; the rendered message is in body.message. Host metrics appear under service windows-host for your machine.
Fields
service.namebecomes the service selector - use a stable value likewindows-event-viewerorwindows-host, not the machine name.host.namebecomes the host selector shared by logs, traces, metrics, alerts, and dashboards - this is where the machine identity belongs.deployment.environmentbecomes the environment selector.
Now that events are flowing, see which Event IDs to monitor and alert on. For Linux hosts, see Linux host observability. For OTLP transport details, see What is OTLP? New to Telemtra? The quickstart walks the minimum config for every supported stack. Create a workspace to get an API key.