PHP
Send logs from PHP apps using cURL or Guzzle, with a PSR-3 compatible logger.
Quick start — cURL
No Composer packages needed:
php
<?php
define('LOGFLOW_API_KEY', getenv('LOGFLOW_API_KEY'));
function logflow(string $level, string $message, string $service = 'app', array $attributes = []): void
{
$ch = curl_init('https://api.getlogflow.com/v1/logs');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 3,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . LOGFLOW_API_KEY,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'level' => $level,
'message' => $message,
'service' => $service,
'attributes' => $attributes,
]),
]);
curl_exec($ch);
curl_close($ch);
}
logflow('info', 'Server started', 'api', ['php_version' => PHP_VERSION]);
logflow('error', 'DB connection failed', 'api', ['host' => 'db-1']);PSR-3 compatible logger
Implement Psr\Log\LoggerInterface for drop-in compatibility with Laravel, Symfony, and any PSR-3 aware package:
php
<?php
use PsrLogAbstractLogger;
use PsrLogLogLevel;
use Stringable;
class LogFlowLogger extends AbstractLogger
{
private const LEVEL_MAP = [
LogLevel::DEBUG => 'debug',
LogLevel::INFO => 'info',
LogLevel::NOTICE => 'info',
LogLevel::WARNING => 'warn',
LogLevel::ERROR => 'error',
LogLevel::CRITICAL => 'error',
LogLevel::ALERT => 'fatal',
LogLevel::EMERGENCY => 'fatal',
];
public function __construct(
private string $apiKey,
private string $service = 'app',
) {}
public function log($level, string|Stringable $message, array $context = []): void
{
$ch = curl_init('https://api.getlogflow.com/v1/logs');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 3,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $this->apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'level' => self::LEVEL_MAP[$level] ?? 'info',
'message' => (string) $message,
'service' => $this->service,
'attributes' => $context,
]),
]);
curl_exec($ch);
curl_close($ch);
}
}
// Usage
$logger = new LogFlowLogger(apiKey: getenv('LOGFLOW_API_KEY'), service: 'api');
$logger->info('User signed up', ['user_id' => 'u_123', 'plan' => 'growth']);
$logger->error('Payment failed', ['order_id' => 'ord_456', 'gateway' => 'stripe']);Laravel integration
Register LogFlow as a custom logging channel in config/logging.php:
php
// config/logging.php
'channels' => [
'logflow' => [
'driver' => 'custom',
'via' => AppLoggingLogFlowLogger::class,
],
'stack' => [
'driver' => 'stack',
'channels' => ['single', 'logflow'], // log to both file and LogFlow
],
],
// app/Logging/LogFlowLogger.php
namespace AppLogging;
class LogFlowLogger
{
public function __invoke(array $config): PsrLogLoggerInterface
{
return new LogFlowLogger(
apiKey: env('LOGFLOW_API_KEY'),
service: config('app.name'),
);
}
}💡
Set
LOG_CHANNEL=logflow in your .env to route all Laravel logs to LogFlow.Batch sending
php
<?php
function logflow_batch(array $logs): void
{
$ch = curl_init('https://api.getlogflow.com/v1/logs/batch');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . LOGFLOW_API_KEY,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['logs' => $logs]),
]);
curl_exec($ch);
curl_close($ch);
}
// Buffer logs during a request, flush at the end
$buffer = [];
$buffer[] = ['level' => 'info', 'message' => 'Request started', 'service' => 'api'];
$buffer[] = ['level' => 'info', 'message' => 'DB query ok', 'service' => 'api'];
logflow_batch($buffer);