datares / logger
Official PHP SDK for Datares Logger — structured log ingestion by Datares
Requires
- php: >=8.1
- ext-curl: *
- ext-json: *
Requires (Dev)
- phpunit/phpunit: ^10.5
This package is not auto-updated.
Last update: 2026-05-17 02:36:09 UTC
README
Official PHP SDK for Datares Logger — structured log ingestion by Datares.
Requirements: PHP 8.1+, ext-curl, ext-json
Installation
composer require datares/logger
Quick Start
use Datares\Logger\Logger;
$log = new Logger('dtr_live_...');
$log->info('User logged in', service: 'auth', meta: ['user_id' => 42]);
$log->error('Payment failed', service: 'billing', meta: ['order_id' => 99]);
$log->warning('Disk space low', service: 'storage', meta: ['free_gb' => 2]);
Logs are buffered automatically and flushed when the PHP process exits — no extra setup needed.
Log Levels
| Method | Level |
|---|---|
->debug() | debug |
->info() | info |
->warning() | warning |
->error() | error |
->critical() | critical |
All methods share the same signature:
$log->info(string $message, string $service = 'default', array $meta = []);
Configuration
Pass a Config object as the second argument to customize behavior:
use Datares\Logger\Config;
use Datares\Logger\Logger;
$log = new Logger('dtr_live_...', new Config(
baseUrl: 'https://api.datares.id', // API endpoint
timeout: 10, // cURL timeout in seconds
retries: 3, // retries on 5xx (exponential back-off)
batchSize: 100, // auto-flush when buffer reaches this
autoFlush: true, // flush on process shutdown
));
| Option | Default | Description |
|---|---|---|
baseUrl | https://api.datares.id | API base URL |
timeout | 10 | cURL timeout per request (seconds) |
retries | 3 | Max retries on server errors (1s → 2s → 4s back-off) |
batchSize | 100 | Flush buffer when it reaches this many entries |
autoFlush | true | Register shutdown handler to flush on exit |
Sending Logs
Buffered (default)
->info(), ->error(), etc. add to an internal buffer. The buffer flushes automatically when:
- It reaches
batchSizeentries, or - The PHP process exits (
autoFlush: true)
$log = new Logger('dtr_live_...');
$log->info('Request started', service: 'api');
$log->debug('Cache miss', service: 'cache', meta: ['key' => 'user:42']);
// ... more logs throughout your code ...
// Flush manually at any time:
$log->flush();
Immediate (guaranteed delivery)
->send() bypasses the buffer and sends immediately. It throws on failure, so use it when you need to know the log was received.
use Datares\Logger\LogEntry;
use Datares\Logger\Level;
// Single entry
$log->send(LogEntry::make(Level::Critical, 'Database connection lost', 'db'));
// Multiple entries
$log->send([
LogEntry::make(Level::Error, 'Order failed', 'checkout', meta: ['order_id' => 5]),
LogEntry::make(Level::Info, 'Retry queued', 'checkout', meta: ['order_id' => 5]),
]);
LogEntry factory
Use LogEntry::make() for full control, including a custom timestamp:
use Datares\Logger\LogEntry;
use Datares\Logger\Level;
$entry = LogEntry::make(
level: Level::Warning, // or plain string: 'warning'
message: 'High memory usage',
service: 'worker',
meta: ['usage_mb' => 512],
timestamp: new DateTimeImmutable(), // optional, defaults to server time
);
$log->log($entry); // add to buffer
// or
$log->send($entry); // send immediately
Error Handling
Buffered errors
When buffered logs fail to send (network error, server error), the error is passed to the error handler. The default handler writes to error_log. Override it:
$log->onError(function (\Datares\Logger\Exception\LoggerException $e): void {
// e.g. forward to Sentry, write to a fallback file, etc.
Sentry::captureException($e);
});
Immediate errors
->send() throws on failure. Catch specific exceptions for granular handling:
use Datares\Logger\Exception\AuthException;
use Datares\Logger\Exception\RateLimitException;
use Datares\Logger\Exception\ApiException;
use Datares\Logger\Exception\LoggerException;
try {
$log->send(LogEntry::make(Level::Error, 'Critical failure', 'payments'));
} catch (AuthException $e) {
// Invalid or revoked API key
} catch (RateLimitException $e) {
// Retry after $e->retryAfter seconds
sleep($e->retryAfter);
} catch (ApiException $e) {
// HTTP error with status code
echo $e->statusCode; // e.g. 422, 500
} catch (LoggerException $e) {
// Network error, JSON encode failure, etc.
}
| Exception | Cause |
|---|---|
AuthException | HTTP 401 / 403 — invalid or suspended API key |
RateLimitException | HTTP 429 — rate limit hit ($e->retryAfter) |
ApiException | HTTP 4xx/5xx — $e->statusCode has the code |
LoggerException | Network failure, payload too large, etc. |
API Limits
| Limit | Value |
|---|---|
| Max entries per request | 500 |
| Max payload size | 5 MB |
| Rate limit | 120 requests/min per key |
The SDK handles the 500-entry limit automatically by splitting large buffers into multiple requests. If a single serialized payload exceeds 5 MB, send() throws a LoggerException before making any HTTP call.
Laravel Integration
Add to AppServiceProvider::boot():
use Datares\Logger\Config;
use Datares\Logger\Logger;
$this->app->singleton(Logger::class, function () {
return new Logger(config('services.datares.key'), new Config(
batchSize: 50,
));
});
Then inject or resolve it anywhere:
public function store(Request $request, Logger $log): JsonResponse
{
$log->info('Order placed', service: 'checkout', meta: ['order_id' => $order->id]);
// ...
}
Running Tests
composer install
composer test
# With HTML coverage report (requires Xdebug or PCOV):
composer test:coverage