Analyst
They turn numbers into sentences. They get only the aggregates the panel already shows and give back what changed, in plain language. The summary becomes an event, so it arrives through the channels you already turned on.
Every morning at 7am, after the daily summary.
- Claude (Anthropic)
- OpenAI-compatible model (Groq, OpenRouter, vLLM, Azure...)
- Ollama (local model)
- OpenAI
Check
How meulog asks a URL whether it is up. The record is the watched URL -- the address, the rhythm, how many failures before it warns; what changes here is **the question**. A GET covers almost everything, and does not cover a web service that wants mutual TLS and answers 200 while standing still.
At the interval set on each watched URL.
Drawing
They draw what meulog stored. The `callstack` column is text, and what lands in it does not always look alike: a madExcept stack, a Ruby backtrace, a worker log with a timestamp on every line. Each one recognises its own by looking at the content -- there is nothing to configure.
When someone opens an occurrence.
- Callstack (Delphi)
- Execution log
- Callstack
- Structured value
Fetcher
meulog goes and fetches the error where it already is: a mailbox today, other sources later. Turning a fetcher on is saying where to look and how often.
At the interval set on the fetcher itself.
- HTTP API (any service returning JSON)
- Mailbox (IMAP)
- Grafana Loki
- Search cluster (OpenSearch, Elasticsearch)
Forge
They read code where it lives. The record is the repository -- the address, the token, the branch; what changes here is **the API**. Without one the analysis has no blame, no suggested owner and no snippet in the prompt, and it goes quiet rather than wrong.
When an analysis needs the lines around the one that broke.
- Azure DevOps
- GitHub
- GitLab
Format
They read what the fetcher brought in. The same e-mail can be a madExcept bug report, a plain-text alert or a JSON payload, and the format is what knows the difference. They do not turn on or off: each fetcher picks its own.
When a fetcher brings something in and it has to be understood.
- madExcept bug report
- Regular expression over the body
- JSON in the e-mail body
- Log group (cluster aggregation)
- Mapped JSON (you say where each field is)
- Alert e-mail (subject and body)
- Usage group (cluster aggregation)
Notifier
They tell whoever needs to know. Each one has its own channel and its own threshold, so you can send everything to one place and only the serious ones somewhere else.
When meulog detects a new error, a spike, a regression or a stalled job.
- Discord
- E-mail
- Google Chat
- PagerDuty
- Slack
- Microsoft Teams
- Telegram
- Webhook
Purge
What to delete, and when. Each policy has its own deadline, and zero turns it off: that is the value whoever operates reads as do not delete this.
Every night, at 4am.
- Evidence: .eml and attachments
- Run and cycle history
- Application log
- Whole occurrences
- URL checks and job heartbeats
- Usage history
- Performance windows
Receiver
The opposite of a fetcher: here the application reports and meulog only receives. These are the doors an SDK sends errors through.
The moment the application makes the call.
- CSP violation
- meulog heartbeat
- Application log
- madExcept upload
- meulog API
- OpenTelemetry (OTLP)
- OpenTelemetry (metrics)
- Performance measurement
- Sentry protocol
- Usage events
Renamer
They undo the renaming a minified build did. R8 -- which Flutter turns on for an Android release by default -- rewrites `com.acme.Pedido.gravar` as `a.b.c.d`, and the frame arrives like that: good for counting and unreadable. Worse, two builds rename differently, so the same bug splits into two groups the moment a new version ships.
On the way in, when an occurrence arrives with renamed frames.
Symbols
They read the symbol map of a native executable. Without one, the stack a native SDK sends is a list of addresses: good for counting volume and nothing else. With one, `ErpClient.exe+0x0004A1B0` becomes `uVendas.pas:412`. The format of the map belongs to the compiler, and each one recognises its own by looking at the file.
On the way in, when an occurrence arrives with addresses in the stack.
- Delphi map
- MSVC map (link.exe)
Tracker
They record the error outside meulog, somewhere people already work. It is the difference between hoping someone looks at the panel and the task showing up in the team's queue.
When the error passes the volume you set.
Vault
Where the backup goes besides the disk of this machine. A copy next to the database survives a table dropped by mistake and a bad migration; it does not survive the machine. Turning one on is saying where the second copy lives.
Right after the nightly backup is written.
- S3 bucket (Amazon, R2, Backblaze, MinIO)