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

> **Internal · agent reference.** Terse. Confirmed against `hiveops-module-log-collect` source 2026-07-01. Every key/string below is from code; nothing invented.

## Identity
- Module name (`AgentModule.getName()`): **`log-collect-path`**
- Maven artifact / jar: **`hiveops-module-log-collect`** → `hiveops-module-log-collect.jar` (own version `1.0.0`; parent `hiveops-agent-parent` `4.4.3`)
- Entry class: `com.hiveops.logcollect.LogCollectPathModule` (SPI: `META-INF/services/com.hiveops.core.module.AgentModule`)
- Uploader: `com.hiveops.logs.AgentLogUploader.uploadPath(...)` (from `hiveops-agent-journal`)
- Log package (`getLogPackage()`): `com.hiveops.logcollect`
- Fleet task kind it implements: **`LOG_COLLECT_PATH`**
- Dependencies: none (`getDependencies()` empty)

## Enable / disable
- Enabled when **`agent.endpoint`** OR **`incident.endpoint`** is non-blank. Both blank → `isEnabled` false, module never starts.
- Prefix selection: `agent.endpoint` set → prefix `agent`; else prefix `incident`.
- Disable explicitly: add `log-collect-path` to `modules.disabled` in `hiveops.properties`.

## Config property keys (read, not registered)
No `log-collect.*` keys exist. It reuses HTTP settings via `HttpClientHelper.loadSettingsFromProperties(props, prefix)`:

| Key | Notes |
|-----|-------|
| `agent.endpoint` / `incident.endpoint` | base URL; also the enable switch |
| `{prefix}.host` | host header |
| `{prefix}.sim` | routing hint |
| `{prefix}.to.connect` | default `10000` (ms) |
| `{prefix}.to.read` | default `10000` (ms) |
| `{prefix}.institution.key` | fallback → `agent.institution.key` → `incident.institution.key` |
| `agent.auth.token` | bearer, always this key regardless of prefix |

- Poll interval = **30s**, hardcoded constant `POLL_INTERVAL_SECONDS`. NOT configurable.

## Task-status strings it emits (`POST /api/agent/tasks/{tid}/status`)
- `RUNNING` — "Collecting logs from: <path>"
- `COMPLETED` — "Log collection uploaded successfully"
- `FAILED` — "No path specified in task configPatch" | `<exception message>`

It emits **no** journal/incident events, no `IAT_*` events. Status reports only.

## HTTP endpoints (base = `settings.getEndpoint()`)
| Call | Verb + path |
|------|-------------|
| Poll | `GET /api/agent/{country}/{atm}/task?kind=LOG_COLLECT_PATH` |
| Status | `POST /api/agent/tasks/{tid}/status` → `{status,message}` |
| Upload | `POST /api/agent/{country}/{atm}/log/upload?taskId={tid}` (multipart) |

- Multipart: boundary `----HiveOpsLogUploadBoundary`, part name `file`, filename `hiveops-logs.zip`, `Content-Type: application/zip`.

## Task input contract
- Target read from `task.configPatch.get("path")` only. Blank → `FAILED`.
- Accepts a directory (recursive, **all** files, any extension) or a single regular file.
- Windows paths OK: `\` is normalized to `/`.
- Unreadable files skipped (logged), rest still uploaded. Empty/missing path → `IOException` → `FAILED`.

## Fleet delivery (`INSTALL_MODULE`)
- Push jar `hiveops-module-log-collect.jar` via artifact (`task.paths[0]`) or url (`configPatch.url` + `filename`).
- Filename MUST end `.jar`. Agent writes to `modules/`, then **restarts the agent service** to load it (`ProcessInstallModule`).

## Gotchas
- Silent-ish poll failures: network/backend errors are `warn`-logged and retried next tick, not surfaced as task FAILED.
- Whole target tree is zipped to a temp file first — large dirs = large temp file + memory/disk pressure. Temp ZIP deleted in `finally`.
- `queryCurrentAtmPendingTask` returns `null` on HTTP 204 (nothing pending) — normal, not an error.
- `taskId` query param is required for the backend to create the trackable `AtmLogCollect` record; don't strip it.

## Do NOT
- Do NOT expect `log-collect.*` config keys — none exist; don't add one for poll interval without code.
- Do NOT assume it tails/watches logs continuously — it is poll-then-pull, task-driven only.
- Do NOT confuse with the built-in `LOG_COLLECT` command (`AgentLogUploader.uploadDirectory`, agent `logs/` only, `.log`/`.log.gz`). This module is `LOG_COLLECT_PATH` = arbitrary path, all files.
- Do NOT look for journal/incident events from this module — there are none.
- Do NOT rely on `configPatch` keys other than `path` (e.g. `url`/`filename` belong to `INSTALL_MODULE`, not this task).
