---
module: agent.log-collect
title: Log Collect Path — on-demand file/log pull from an arbitrary ATM path
tab: Internal
order: 20
audience: dev
---

> **Internal · ops/support view.** Confirmed against `hiveops-module-log-collect` source (`com.hiveops.logcollect.LogCollectPathModule`) 2026-07-01. Dev-facing; not customer material.

## What it does

The Log Collect Path module lets a fleet operator pull **any file or directory** off an ATM on demand — not just the agent's own logs. It implements the `LOG_COLLECT_PATH` fleet task kind:

1. The module polls the agent endpoint every **30 seconds** for a pending `LOG_COLLECT_PATH` task for this ATM.
2. When one arrives, it reads the target path from the task's `configPatch.path`.
3. It walks that path recursively, ZIPs every readable file, and uploads the bundle to the backend tagged with the task id so operators can download it (e.g. the **Other Logs** tab in device detail).
4. It reports task status back (`RUNNING` → `COMPLETED`, or `FAILED`).

It does **not** monitor anything continuously and it emits **no journal/incident events** — it is a task-driven, request/response file collector. There is no schedule, watch, or tail; the only trigger is an operator-created fleet task.

## What it monitors / why

Nothing passively. The "monitor" is a 30-second poll for pending tasks. Use cases:

- Grab a vendor log directory (dispenser, EPP, XFS logs) that the standard `LOG_COLLECT` command doesn't bundle.
- Pull a specific config/trace file from an arbitrary path during an investigation.
- Retrieve a single file (the module handles a regular-file target as well as a directory).

Contrast with the sibling built-in `LOG_COLLECT` command (in `AgentLogUploader.uploadDirectory`), which only bundles the agent's own `logs/` tree (`.log` / `.log.gz`). `LOG_COLLECT_PATH` collects **all files** under the requested path regardless of extension.

## Config properties it registers

The module registers **no dedicated `log-collect.*` properties**. It reuses the agent's existing HTTP client settings. It is **enabled** whenever either endpoint property is set:

| Property | Purpose | Default |
|----------|---------|---------|
| `agent.endpoint` | Agent-proxy base URL (preferred). If set, the module uses the `agent.*` settings prefix. | — |
| `incident.endpoint` | Legacy incident base URL. Used only if `agent.endpoint` is blank. | — |

Derived HTTP settings (loaded via the chosen `{prefix}` = `agent` or `incident`):

| Property | Purpose | Default |
|----------|---------|---------|
| `{prefix}.host` | Host header override | — |
| `{prefix}.sim` | Sim/routing hint | — |
| `{prefix}.to.connect` | Connect timeout (ms) | `10000` |
| `{prefix}.to.read` | Read timeout (ms) | `10000` |
| `{prefix}.institution.key` | Institution key; falls back to `agent.institution.key` then `incident.institution.key` | — |
| `agent.auth.token` | Bearer token — always read as `agent.auth.token` regardless of prefix | — |

The **30-second poll interval is a hardcoded constant** (`POLL_INTERVAL_SECONDS`), not a property — it cannot be tuned via config.

## How it's enabled / deployed to ATMs

The module ships as its own jar, `hiveops-module-log-collect.jar`, discovered at agent startup via the ServiceLoader SPI (`META-INF/services/com.hiveops.core.module.AgentModule`).

- **Standard build:** it's a `<module>` in the agent parent build; if the jar is on the classpath / in the agent `modules/` directory, it auto-registers.
- **Fleet delivery (`INSTALL_MODULE`):** push an `INSTALL_MODULE` task carrying `hiveops-module-log-collect.jar` (artifact or `configPatch.url`+`filename`). The agent drops it into `modules/` and **restarts the agent service** to load it (see `ProcessInstallModule`). Filename must end in `.jar`.
- **Disable:** add `log-collect-path` to `modules.disabled` in `hiveops.properties`, or unset both `agent.endpoint` and `incident.endpoint` (then `isEnabled` returns false).

## Common failure modes / what to check

| Symptom | Likely cause / check |
|---------|----------------------|
| Task stuck `FAILED` immediately, message "No path specified in task configPatch" | The task was created without `configPatch.path`. Recreate with a path. |
| `FAILED` "Path does not exist" / "No files found at path" | The path is wrong for that OS, or empty. Windows paths are accepted with `\` (the module normalizes `\`→`/`). |
| Task never picked up | Module disabled, agent offline, or neither `agent.endpoint`/`incident.endpoint` set → module didn't start. Check `logs/modules/…` for "LogCollectPathModule started". |
| Poll warns "transient network error" / "server error" | Endpoint unreachable or backend 4xx/5xx; poll retries on the next 30s tick — not fatal. |
| Upload returns non-2xx | Check the backend `/api/agent/{country}/{atm}/log/upload` route (served by agent-proxy) and the bearer token / institution key. |
| Huge/locked files | Unreadable files are skipped with a warning (`visitFileFailed`); the ZIP still uploads with the rest. Be mindful of very large target dirs — the whole tree is zipped to a temp file first. |
