---
module: agent.win-app-events
title: Windows App Event Log Monitor — forwards Windows Application-log errors as HiveIQ incidents
tab: Internal
order: 20
audience: dev
---

> **Internal · ops/support view.** Confirmed against `hiveops-module-win-app-events` source (`com.hiveops.winevents`) 2026-07-01.

## What it monitors (and why)

`hiveops-module-win-app-events` (module name `win-app-events`, class `WinAppEventModule`) is a **passive poller** of the Windows **Application** event log. Every poll it shells out to `wevtutil` for new **Critical / Error / Warning** entries, applies filters, and forwards each survivor to the HiveIQ platform as a `WIN_APP_EVENT_ERROR` journal event (which lands in the incident pipeline like any other agent event).

The point: surface application-layer failures that never appear in the ATM's own `.jrn` journal — driver faults, .NET/service crashes, XFS middleware errors, disk/hardware warnings — so they become visible in HiveIQ without logging into the box.

- **Windows-only.** On Linux it logs `not Windows, module inactive` in `initialize()` and does nothing (silent no-op).
- Reads the **Application** channel only (not System/Security).
- Only levels **1 (Critical), 2 (Error), 3 (Warning)** are ever queried; level 4 (Information) and 0 are excluded by the `wevtutil` query itself.
- On the **first tick after start** the module *anchors* to the newest existing RecordID and only forwards events that arrive **after** that — no historical flood on install/restart.

## Config properties it registers

All read from `hiveops.properties` (main properties). Namespace is `winevt.*`. Defaults are the code defaults (second arg to `getProperty`), which do **not** always match the class Javadoc — trust this table.

| Key | Default (in code) | Meaning |
|---|---|---|
| `winevt.events.enabled` | **`false`** | Master on/off. Module stays inactive unless this is explicitly `true`. (The Javadoc says default true — the **code default is `false`**.) |
| `winevt.events.levels` | `3` | Max Windows level to capture: `1`=Critical only, `2`=Critical+Error, `3`=+Warning. |
| `winevt.events.sources` | `""` (all) | Comma-separated Provider names to include; exact case-insensitive match. Empty = all providers. |
| `winevt.events.poll.interval.sec` | `60` | Poll interval in seconds. |
| `winevt.events.batch.size` | `50` | Max events pulled per `wevtutil` call (`/c:`). |
| `winevt.pattern.WIN_APP_EVENT_ERROR` | `""` (catch-all) | Regex matched (`.find()`, case-insensitive) against `"<Provider> <EventID> <message>"`. Empty/absent = accept all. Invalid regex → logs a warning and falls back to catch-all. |
| `winevt.events.suspended` | `false` | Hot-reload-only pause switch: when `true` the poller keeps ticking but skips all work. Only read on reload (see below), not at startup. |

It also reuses the shared endpoint/auth keys (not its own): `agent.endpoint` (preferred) or `incident.endpoint` (fallback), and whatever `agent.*`/`incident.*` auth settings `HttpClientHelper` loads for that prefix.

### Hot reload (no restart)

`winevt.pattern.WIN_APP_EVENT_ERROR` and `winevt.events.suspended` are **hot-reloadable**. A `CONFIG_UPDATE` fleet task rewrites `hiveops.properties` on disk and then fires `PatternReloadRegistry.trigger()`, which re-reads the file and pushes the new pattern + suspended flag into the running poller. **Everything else** (`enabled`, `levels`, `sources`, `poll.interval.sec`, `batch.size`) is captured once in `initialize()` and only changes on an **agent restart**.

## How it's enabled / deployed to ATMs

- **Enable condition:** module self-activates only when `winevt.events.enabled=true` **and** an `agent.endpoint`/`incident.endpoint` is configured **and** the OS is Windows. Missing any of these → inactive, logged at INFO.
- **Shipped how:** part of the default **`atm`** module set in `deployment/build-dist.sh` — it ships in every standard ATM install/patch ZIP as a drop-in JAR `modules/hiveops-module-win-app-events.jar` (not baked into the fat JAR). It is **not** in the `srv` (server-monitor) set.
- **Turn on for a fleet:** push `winevt.events.enabled=true` (plus any `winevt.*` tuning) via a `CONFIG_UPDATE` fleet task.
- **Turn off:** set `winevt.events.enabled=false` (needs restart to take effect since `enabled` isn't hot-reloaded) **or** set `winevt.events.suspended=true` (immediate, hot-reload) **or** add `win-app-events` to `modules.disabled`.
- **Retrofit an ATM missing the JAR:** deliver an `INSTALL_MODULE` fleet task (drops the JAR into `modules/` and restarts the agent), or a full standard-set agent update.

## Common failure modes / what to check

| Symptom | Likely cause | What to check |
|---|---|---|
| No `WIN_APP_EVENT_ERROR` events ever arrive | `winevt.events.enabled` is at its default `false`, or module not on this ATM | Confirm `winevt.events.enabled=true` in `hiveops.properties`; confirm the JAR is in `modules/`; check the module log for `win-app-events initialized`. |
| Module log says `not Windows, module inactive` | Running on a Linux ATM | Expected — this module is Windows-only. |
| Started but silent | No new qualifying events since anchor, or everything filtered out | Log shows `anchored at RecordID N`, then `no new events` / `all N event(s) filtered`. Loosen `levels`/`sources`/pattern. |
| Historical errors never backfilled after enabling | By design — first tick anchors to newest RecordID; only new events forward | Not a bug. There is no historical replay. |
| Too noisy (flooding incidents) | `levels=3` (Warnings) + no source/pattern filter | Tighten `winevt.events.levels` to `2`, set `winevt.events.sources`, or set a `winevt.pattern.WIN_APP_EVENT_ERROR` regex. |
| Changed the pattern but old skipped events don't reappear | Bookmark always advances even when events are filtered out | Expected — filters apply going forward only; already-passed RecordIDs are not re-queried. |
| Pattern/suspend change didn't take effect | Only pattern + suspended hot-reload; the change wasn't a `CONFIG_UPDATE` (which fires the reload) | Push the change via `CONFIG_UPDATE`; for `levels`/`sources`/`interval`/`batch` you must restart the agent. |
| Garbled message text | `wevtutil` charset / code page mismatch on that box | The runner decodes with the JVM `file.encoding`; check the ATM's active code page if provider messages look corrupted. |
| Events fail to POST | Endpoint/auth wrong, or agent-proxy/incident down | Module logs `failed to send events`; each event is a POST to `/api/journal-events` — verify `agent.endpoint` and token. |
