logging module to its own directory on a shared Archil disk. From your
laptop, you search every instance’s logs at once with disk.grep and compute per-instance error
counts with serverless execution and jq.
There’s no log shipper, agent, or index to run. The application writes ordinary files, and the search runs next to the data.
Prerequisites
Export your Archil API key and a region that offers sandboxes (aws-us-east-1, aws-us-west-2, or aws-eu-west-1), then
install the SDK for the language you’ll orchestrate from.
npx tsx <name>.ts and Python
scripts with python <name>.py.
Write the service
The service below stands in for your application: it handles a stream of fake requests and logs one JSON line per request, with timeouts on/checkout logged as errors. Logging is plain logging with two additions:
- A formatter that turns each record into one line of JSON, so the logs are easy to grep and to parse.
- A
RotatingFileHandler, which renamesapp.logtoapp.log.1when it reaches 1 MB and keeps five old files.
/mnt/archil/logs/<instance>/. Pass the instance name in explicitly rather than using the hostname,
because every sandbox reports the same hostname.
app.py
Start three instances
Create the disk and three sandboxes that mount it in conditional mode. Conditional mode sends writes straight to the server instead of taking an exclusive lock on the disk, so all three instances can write at the same time, and every write is visible to other clients as soon as it lands. Writes in conditional mode are slower than on an exclusive mount, which doesn’t matter for appending log lines. Each sandbox runs the service as a supervised service, which restarts it if it crashes and starts it again when the sandbox reboots.app-3 gets a higher error rate, so there’s something to find.
Search every instance at once
disk.grep takes an extended regular expression and a directory on the disk. Archil lists the files under that directory and
fans the search out across parallel workers that run next to the data, so you don’t download anything. This search finds
every error line, in current and rotated files, across all three instances:
stoppedReason is completed when every file was scanned. A search stops early, and returns a sample of the matches,
when it reaches maxResults (1,000 by default) or maxDurationSeconds (30 by default). There are more than 1,000 errors
here, so the search raises maxResults to 10,000.
Search results are current. Python’s file handler flushes after every record, and conditional mode sends each write to the
server, so a line is searchable as soon as the service logs it, without closing or rotating the file. If you use a logger that buffers output in memory, lines become searchable when it flushes.
Count errors per instance
For questions that need more than matching lines, run a command next to the data withdisk.exec. The serverless runtime
includes jq, and the disk is mounted at /mnt/archil, which is also the working directory. This command lists app-3’s
log files, then parses every log line from every instance and counts lines and errors per instance:
app.log.1 file is the rotated log. Because the glob logs/*/app.log* matches rotated files too, the counts cover
everything the instances have logged since they started (up to the five rotated files each one keeps). Serverless commands
mount the disk in shared mode, so they read the logs while the instances keep writing.
Clean up
Stop and delete the three sandboxes, then delete the disk and the logs on it.Next steps
- Search files — concurrency and limits for
disk.grep - Serverless execution — run commands across several disks, read-only or pinned to a subdirectory
- Sharing disks — how exclusive, shared, and conditional mounts behave
- Analytics with DuckDB — query Parquet data on an Archil disk with SQL