self-hosted error monitor Open the panel

Search clusters

logs already indexed somewhere else open the screen

What it is for

Not every error needs an SDK. Plenty of shops already ship logs into Elasticsearch, OpenSearch or Loki, and the error is already indexed there. The cluster is the record of that place: the address, how to authenticate, and what to ask it.

What you record

  • URL of the cluster.
  • Authentication: none, basic, or token.
  • Index or index pattern to sweep.
  • The query: what separates an error from a normal log line. This is where level:error goes, or whatever your shop uses.
  • The field map: which document field becomes class, message, customer, version. Without it, meulog has no idea which piece of the JSON is what.

How the error arrives

By polling, not by push: a scheduled job asks the cluster every so often and brings back what is new. The pace is configured under Flows, and what it found shows up under Scheduled jobs.

What meulog decides for you

meulog keeps a marker of where it stopped and only asks for what came after. Restarting meulog does not reprocess the whole index, and a job that failed loses nothing: it picks up from that marker.

Test it first

The Test button runs the real query and shows what came back, without storing anything. It is the difference between finding your mapping mistake now and finding it tomorrow with a thousand wrong rows in the database.

The source that brings what worked

The same index that holds the failure holds the success. A second source, on the same cluster, with the error filter inverted and the Usage group format, brings back what worked — and it does not become an occurrence: it becomes a usage event.

Why this matters more than it looks

An error monitor cannot tell you whether the customer is working. Without the success signal, someone who did four thousand operations and failed forty is identical to someone who tried forty and failed all forty. With it, "how long since this customer could not get through" has an answer — and the alert worth having is the crossing: no success for an hour and failing right now.

What the source becomes is decided by the format, not the fetcher: the fetcher brings bytes and asks. A new format that produces something else is a file in app/plugins/format/ and nothing more.