Search by

minhyung / monolog-openobserve

lostland

Monolog handler for OpenObserve

Package info

github.com/overworks/monolog-openobserve

pkg:composer/minhyung/monolog-openobserve

Statistics

Installs: 2 289

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

0.4.0 2026-10-13 01:38 UTC

This package is auto-updated.

Last update: 2026-10-13 01:41:32 UTC


README

CI Latest Version PHP Version Total Downloads License

Monolog handler for OpenObserve

Requirements

  • PHP 8.3 or later
  • the curl extension
  • Monolog 3

Installation

composer require minhyung/monolog-openobserve

Usage

use Minhyung\Monolog\OpenObserveHandler;
use Monolog\Logger;

$handler = new OpenObserveHandler(
	host: 'http://localhost:5080',
	organizationId: 'default',
	streamName: 'monolog',
	token: 'your-ingest-token',
);

$logger = new Logger('app');
$logger->pushHandler($handler);

$logger->info('Hello OpenObserve!', ['foo' => 'bar']);

The token is the value after Basic in OpenObserve's ingestion Authorization header. Pass it without that prefix. The handler sends it unchanged, without base64-encoding it again.

Builder and username/password authentication

Use the builder to authenticate with a username and password:

$handler = OpenObserveHandler::builder('http://localhost:5080', 'default', 'monolog')
    ->withCredentials('admin@yourdomain.com', 'yourpassword')
    ->withLevel(\Monolog\Level::Info)
    ->withTimeout(5.0)
    ->build();

Tokens are also supported by the builder:

$handler = OpenObserveHandler::builder('http://localhost:5080', 'default', 'monolog')
    ->withToken('your-ingest-token')
    ->withIgnoreFailure(true)
    ->build();

The builder is mutable: each with...() call returns the same builder, and the last withToken() or withCredentials() call determines authentication. Each build() creates an independent handler. Authentication must be configured before building, otherwise build() throws LogicException. Empty tokens and tokens containing CR or LF cause InvalidArgumentException at construction or build time.

All constructor options have matching builder methods: withIgnoreFailure(), withLevel(), withBubble(), withFallbackLogger(), withConnectTimeout(), and withTimeout(). Defaults are identical to the constructor: failures throw, level is Debug, bubbling is enabled, there is no fallback logger, and connection and request timeouts are 2 and 5 seconds.

Migration: The constructor's former username and password arguments have been replaced by a single token argument. Replace existing credentials-based constructor calls with OpenObserveHandler::builder($host, $organizationId, $streamName)->withCredentials($username, $password)->build(), transferring optional arguments to their matching builder methods.

Handling failures

By default the handler throws when OpenObserve cannot be reached or rejects the request, including on an authentication failure such as 401 or when an HTTP success response reports rejected records in status[].failed. Set ignoreFailure: true to swallow those errors so that a logging problem never breaks the application:

$handler = new OpenObserveHandler(
	host: 'http://localhost:5080',
	organizationId: 'default',
	streamName: 'monolog',
	token: 'your-ingest-token',
	ignoreFailure: true,
);

Swallowed failures disappear silently. To keep a record of them, pass a fallbackLogger — any PSR-3 logger — and every ignored failure is reported to it at error level, with the original exception under the exception context key:

use Monolog\Handler\ErrorLogHandler;

$handler = new OpenObserveHandler(
	host: 'http://localhost:5080',
	organizationId: 'default',
	streamName: 'monolog',
	token: 'your-ingest-token',
	ignoreFailure: true,
	fallbackLogger: new Logger('openobserve', [new ErrorLogHandler()]),
);

The fallback logger must not write back to this handler, as that would recurse. It is only consulted while ignoreFailure is on; when the handler rethrows, the caller already sees the exception.

Timeouts

Because a stalled or unreachable OpenObserve would otherwise block the application on every log call, the request is bounded by two timeouts: 2 seconds to connect and 5 seconds for the whole request. Adjust them — or set the request timeout to 0 to disable it — via the connectTimeout and timeout arguments:

$handler = new OpenObserveHandler(
	host: 'http://localhost:5080',
	organizationId: 'default',
	streamName: 'monolog',
	token: 'your-ingest-token',
	connectTimeout: 2.0,
	timeout: 5.0,
);

Each log or batch is sent once, without automatic retries, so retries do not multiply the configured timeout. A timeout does not guarantee that the server has not already ingested the records; retrying may create duplicates.