Skip to content

Application logs

Beyond exceptions, the SDK can forward your application's log messages to Quiet Guard. This is opt-in and adds at most one HTTP call per request.

Enabling

Log forwarding is off by default. Turn it on and pick a minimum level:

dotenv
MONITOR_LOGS_ENABLED=true
MONITOR_LOG_LEVEL=warning
MONITOR_LOGS_MAX_BATCH=200

The log hook only activates when all of the following hold: the SDK is enabled (MONITOR_ENABLED=true), logs are enabled (MONITOR_LOGS_ENABLED=true), the project key is set (MONITOR_KEY) and the current environment is in the allowlist (MONITOR_ENVIRONMENTS). Otherwise the listener is never registered and there is zero overhead. From version 0.3.1, an empty MONITOR_URL does not turn logs off: it means the hosted service, and that is where they go. To turn them off, use MONITOR_LOGS_ENABLED=false.

How it works

The SDK listens to Laravel's MessageLogged event. Each message at or above the configured level is buffered in memory during the request and flushed once, as a single batch, to the server's /api/v1/logs endpoint.

Flushing happens when the work unit ends:

  • on app termination for HTTP requests and console commands;
  • after each queued job (JobProcessed and JobFailed), because long-running queue workers never terminate between jobs.

If the buffer reaches MONITOR_LOGS_MAX_BATCH entries (default 200) mid-request, it is flushed early so nothing is silently dropped.

MONITOR_LOGS_MAX_BATCH is clamped to 500, the largest batch the server accepts. A higher value used to be taken by the client and refused by the server on every flush, so nothing was ever forwarded and nothing said so.

Levels

The minimum level is a standard PSR-3 level. Anything at or above it (by severity) is captured:

debug < info < notice < warning < error < critical < alert < emergency

With the default MONITOR_LOG_LEVEL=warning, warning, error, critical, alert and emergency entries are forwarded; debug, info and notice are ignored. An unrecognised level value fails safe (it captures less, not more).

What is captured, and what is not

Each forwarded entry carries: level, message, scrubbed context, environment, release and logged_at (ISO 8601).

Two kinds of entries are deliberately skipped:

  • Log entries that carry an exception (a context['exception']): these are already handled by the exception pipeline, so forwarding them as logs too would duplicate them.
  • The SDK's own internal failure logs: marked with an internal flag so a transport error can never feed itself back into the log buffer (no feedback loop).

Context values are passed through the same scrubber as exceptions, and non-scalar context values are normalised into a JSON-serialisable form before sending.

One line never costs you the batch

The server validates every entry of a batch and refuses the whole batch when one of them is malformed, so a single bad line used to take the two hundred that travelled with it. Two guards apply as each entry is buffered:

  • a message longer than 8192 characters is cut, with … [truncated] marking the cut, on characters rather than bytes;
  • an empty message, which the server requires to be present, is replaced with (empty log message) rather than sinking its batch.

Sending in the background

When MONITOR_QUEUE is set, the batch is dispatched as a SendLogsToMonitor queued job (2 attempts) rather than sent inline. See Configuration.

Like exception payloads, a batch is masked before it is queued, so a log context carrying an address or a card number never sits in clear in your jobs or failed_jobs tables. A job whose send failed throws, so its second attempt really happens.

Plan note

Application logs are a paid server-side feature and count toward your event quota. If your plan does not include logs, the server will reject the batch. That never affects your application, and it is no longer invisible: the refusal is written to your own log as a warning naming the status, the address and what the server said. See the server documentation.

You are reading the Laravel SDK v1.0 documentation.