Skip to content
File integration · How-to Intermediate

Monitor a file-drop integration (hot folder) with OpenTelemetry

Turn each file that lands in a watched folder into a trace, and the folder's backlog into a metric — so a stuck or slow file-based integration shows up in Sluicio.

SLSluicio team 8 min read Updated Jun 2026

File drops are still everywhere in integration: an SFTP upload, an export written to a share, a partner dropping a nightly batch. They fail quietly — a file lands and just sits there. This guide makes a hot folder observable two ways: a trace per file so you can follow one document end-to-end, and a folder-depth metric so a growing backlog is impossible to miss.

  • A trace per file — best when you control the processor and want per-file timing, attributes (size, partner, type) and failures you can search.
  • Folder metrics — best when you can’t touch the code: just watch how many files are waiting and how old the oldest one is.

Wrap the per-file handler in a span. The attributes you set here become searchable fields in Sluicio, so add the ones you’d want to filter a failure by. (For SDK setup, see Instrument a service.)

FileProcessor.java
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
Tracer tracer = GlobalOpenTelemetry.getTracer("file-drop");
void processFile(Path file) throws IOException {
Span span = tracer.spanBuilder("file.process").startSpan();
try (var scope = span.makeCurrent()) {
span.setAttribute("file.name", file.getFileName().toString());
span.setAttribute("file.size", Files.size(file));
handle(file);
} catch (Exception e) {
span.recordException(e);
span.setStatus(StatusCode.ERROR); // shows as a failed message
throw e;
} finally {
span.end();
}
}

Each file becomes one trace. A failed file is a failed span you can find — and re-drive — from message search.

Option B — Folder metrics with the Collector

Section titled “Option B — Folder metrics with the Collector”

No code path: the Collector’s filestats receiver reports on the files matching a glob, so you get a live count (the backlog) and each file’s modification time (to find the oldest, stuck file).

otel-collector-config.yaml
receivers:
filestats:
include: '/data/inbound/*'
collection_interval: 60s
exporters:
otlphttp/sluicio:
endpoint: https://your-instance-name.sluicio.com
headers:
authorization: Bearer ${env:SLUICIO_INGEST_KEY}
service:
pipelines:
metrics:
receivers: [filestats]
exporters: [otlphttp/sluicio]
Terminal window
docker run --rm \
-v "$(pwd)/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml" \
-v /data/inbound:/data/inbound:ro \
-e SLUICIO_INGEST_KEY \
otel/opentelemetry-collector-contrib:latest
MetricWhat it tells you
file.countFolder depth — how many files are waiting.
file.mtimePer-file modification time — the oldest one is your stuck file.
file.sizeFile size — useful to spot a truncated or zero-byte drop.
  • Backlog buildingfile.count stays above your threshold for N minutes.
  • Stuck file — the oldest file’s age (now − min file.mtime) exceeds the batch window. This fires even when the count is low, which is exactly when a single wedged file would otherwise go unnoticed.