1. Go to this page and download the library: Download andydefer/laravel-jsonl library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
andydefer / laravel-jsonl example snippets
use AndyDefer\LaravelJsonl\JsonlService;
use AndyDefer\LaravelJsonl\Contexts\JsonlContext;
use AndyDefer\LaravelJsonl\Strategies\TemporalPathStrategy;
use AndyDefer\PhpServices\Services\FileSystemService;
$strategy = new TemporalPathStrategy('/var/logs');
$fileSystem = new FileSystemService();
$context = new JsonlContext();
$service = new JsonlService($strategy, $fileSystem, $context);
use AndyDefer\LaravelJsonl\Records\LogJsonlRecord;
use AndyDefer\PhpVo\ValueObjects\DateTimeVO;
use AndyDefer\DomainStructures\Structures\StrictDataObject;
$log = new LogJsonlRecord(
time: new DateTimeVO(), // Date/heure de l'événement
level: 'info', // Niveau (info, warning, error, debug)
type: 'user_login', // Type d'événement
payload: new StrictDataObject([ // Données métier
'user_id' => 123,
'ip' => '192.168.1.100',
]),
);
use AndyDefer\LaravelJsonl\Records\CacheJsonlRecord;
$cache = new CacheJsonlRecord(
key: 'user_profile_123', // Clé unique
value: json_encode(['name' => 'John']), // Valeur (JSON string)
expires_at: new DateTimeVO('+1 hour'), // Expiration (optionnel)
);
// Le service demande à la stratégie : "Où dois-je mettre ce log ?"
$filePath = $strategy->getFilePath($logRecord);
$strategy = new TemporalPathStrategy('/var/logs');
$log = new LogJsonlRecord(
time: new DateTimeVO('2026-01-15T14:35:00Z'),
// ...
);
$path = $strategy->getFilePath($log);
// Résultat: /var/logs/2026-01-15/14.jsonl
$strategy = new KeyBasedPathStrategy('/cache', hashLevels: 2);
$cache = new CacheJsonlRecord(key: 'user_123', ...);
$path = $strategy->getFilePath($cache);
// Résultat: /cache/e/1/user_123.jsonl
use AndyDefer\LaravelJsonl\Contracts\JsonlPathStrategyInterface;
/**
* Organisation par tenant (multi-entreprise)
* Structure: /{tenant_id}/{YYYY-MM-DD}/{HH}.jsonl
*/
class TenantBasedPathStrategy implements JsonlPathStrategyInterface
{
public function __construct(
private string $basePath,
private string $tenantId,
) {}
public function getFilePath(AbstractRecord $entity): string
{
if (!$entity instanceof LogJsonlRecord) {
throw new InvalidArgumentException('Expected LogJsonlRecord');
}
$date = $entity->time->format('Y-m-d');
$hour = $entity->time->format('H');
return implode(DIRECTORY_SEPARATOR, [
rtrim($this->basePath, DIRECTORY_SEPARATOR),
$this->tenantId,
$date,
$hour . '.jsonl',
]);
}
public function getFilesToScan(AbstractRecord $query): array
{
// Logique pour scanner tous les fichiers du tenant sur la plage demandée
// ...
}
public function getBaseDirectory(): string
{
return $this->basePath;
}
}
use AndyDefer\LaravelJsonl\JsonlService;
use AndyDefer\LaravelJsonl\Contexts\JsonlContext;
use AndyDefer\LaravelJsonl\Records\LogJsonlRecord;
use AndyDefer\LaravelJsonl\Strategies\TemporalPathStrategy;
use AndyDefer\PhpServices\Services\FileSystemService;
use AndyDefer\PhpVo\ValueObjects\DateTimeVO;
$strategy = new TemporalPathStrategy(storage_path('logs/structured'));
$fs = new FileSystemService();
$context = new JsonlContext();
$service = new JsonlService($strategy, $fs, $context);
$log = new LogJsonlRecord(
time: new DateTimeVO(),
level: 'info',
type: 'user_login',
payload: new StrictDataObject([
'user_id' => 123,
'username' => 'john_doe',
'ip' => '192.168.1.100',
]),
);
$service->write($log);
use AndyDefer\LaravelJsonl\Records\CacheJsonlRecord;
use AndyDefer\LaravelJsonl\Strategies\KeyBasedPathStrategy;
$strategy = new KeyBasedPathStrategy(storage_path('cache'), 2);
$service = new JsonlService($strategy, $fs, $context);
$cache = new CacheJsonlRecord(
key: 'user_123',
value: json_encode(['name' => 'John', 'email' => '[email protected]']),
expires_at: new DateTimeVO('+1 hour'),
);
$service->write($cache);
// Lire toutes les lignes
$lines = $service->readAll('/var/logs/2026-01-15/14.jsonl');
foreach ($lines as $line) {
echo $line['type'] . "\n";
}
// Lire ligne par ligne (streaming - économique en mémoire)
$service->readLineByLine('/var/logs/2026-01-15/14.jsonl', function ($line) {
echo $line['time'] . ': ' . $line['level'] . "\n";
});
// Lire uniquement la première ou dernière ligne
$first = $service->getFirstLine('/var/logs/2026-01-15/14.jsonl');
$last = $service->getLastLine('/var/logs/2026-01-15/14.jsonl');
// Trouver toutes les erreurs
$errors = $service->search('/var/logs/2026-01-15/14.jsonl', function ($line) {
return $line['level'] === 'error';
});
// Trouver les logs d'un utilisateur spécifique
$userLogs = $service->search('/var/logs/2026-01-15/14.jsonl', function ($line) {
return isset($line['payload']['user_id']) && $line['payload']['user_id'] === 123;
});
$logs = [
new LogJsonlRecord(/* ... */),
new LogJsonlRecord(/* ... */),
// ...
];
$service->writeBatch($logs); // Une seule opération I/O
// Pas de verrou (plus rapide mais pas sûr en concurrence)
$service->write($record, lock: false);
// Buffer de 100 lignes avant écriture automatique
$service->enableBuffer(100);
$service->enableBuffer(50);
for ($i = 0; $i < 100; $i++) {
$service->writeBuffered($log); // Stocké en mémoire
// Toutes les 50 écritures, flush automatique
}
$service->flushBuffer(); // Flush manuel des derniers
// Pour les logs
$query = new TemporalLogQueryRecord(
from: new DateTimeVO('2026-01-15T00:00:00Z'),
to: new DateTimeVO('2026-01-15T23:59:59Z'),
type: 'user_login', // Optionnel
level: 'info', // Optionnel
);
// Pour le cache
$query = new CacheKeyQueryRecord(key: 'user_123');
// ✅ BON - Données structurées
$payload = new StrictDataObject([
'event' => 'user_login',
'user_id' => 123,
'ip' => '192.168.1.100',
]);
// ❌ MAUVAIS - Texte non structuré
$payload = new StrictDataObject(['message' => 'User 123 logged in from 192.168.1.100']);
class UserActivityLogger
{
private JsonlService $service;
public function __construct()
{
$strategy = new TemporalPathStrategy(storage_path('logs/activities'));
$fs = new FileSystemService();
$context = new JsonlContext();
$this->service = new JsonlService($strategy, $fs, $context);
$this->service->enableBuffer(50);
}
public function logLogin(int $userId, string $ip, bool $success): void
{
$log = new LogJsonlRecord(
time: new DateTimeVO(),
level: $success ? 'info' : 'warning',
type: 'user_login',
payload: new StrictDataObject([
'user_id' => $userId,
'ip' => $ip,
'success' => $success,
'timestamp' => time(),
]),
);
$this->service->writeBuffered($log);
}
public function getFailedLogins(DateTimeVO $date): array
{
$query = new TemporalLogQueryRecord(
from: $date,
to: $date,
type: 'user_login',
level: 'warning',
);
$files = $this->service->getFilesToScan($query);
$failed = [];
foreach ($files as $file) {
$lines = $this->service->search($file, function ($line) {
return $line['payload']['success'] === false;
});
$failed = array_merge($failed, $lines);
}
return $failed;
}
public function __destruct()
{
$this->service->flushBuffer();
}
}
class PersistentCache
{
private JsonlService $service;
private int $ttl;
public function __construct(int $defaultTtlSeconds = 3600)
{
$strategy = new KeyBasedPathStrategy(storage_path('cache/persistent'), 2);
$fs = new FileSystemService();
$context = new JsonlContext();
$this->service = new JsonlService($strategy, $fs, $context);
$this->ttl = $defaultTtlSeconds;
}
public function set(string $key, mixed $value, ?int $ttl = null): void
{
$expiresAt = $ttl !== null
? new DateTimeVO("+{$ttl} seconds")
: ($this->ttl ? new DateTimeVO("+{$this->ttl} seconds") : null);
$cache = new CacheJsonlRecord(
key: $key,
value: json_encode($value),
expires_at: $expiresAt,
);
$this->service->write($cache);
}
public function get(string $key): mixed
{
$query = new CacheKeyQueryRecord(key: $key);
$files = $this->service->getFilesToScan($query);
if (empty($files) || !$this->service->fileExists($files[0])) {
return null;
}
$data = $this->service->readAll($files[0]);
if (empty($data)) {
return null;
}
$record = CacheJsonlRecord::fromArray($data[0]);
if ($this->service->isExpired($record)) {
unlink($files[0]);
return null;
}
return json_decode($record->value, true);
}
public function delete(string $key): void
{
$query = new CacheKeyQueryRecord(key: $key);
$files = $this->service->getFilesToScan($query);
if (!empty($files) && $this->service->fileExists($files[0])) {
unlink($files[0]);
}
}
public function clear(): void
{
$this->service->clear(storage_path('cache/persistent'));
}
public function cleanExpired(): int
{
return $this->service->cleanExpired(storage_path('cache/persistent'), function ($line) {
if (!isset($line['expires_at'])) {
return false;
}
$expiresAt = new DateTimeVO($line['expires_at']);
return $expiresAt->isBefore(new DateTimeVO());
});
}
}
// AppServiceProvider.php
use AndyDefer\LaravelJsonl\Contexts\JsonlContext;
use AndyDefer\LaravelJsonl\JsonlService;
use AndyDefer\LaravelJsonl\Strategies\TemporalPathStrategy;
use AndyDefer\LaravelJsonl\Strategies\KeyBasedPathStrategy;
use AndyDefer\PhpServices\Services\FileSystemService;
public function register(): void
{
// Contexte partagé
$this->app->singleton(JsonlContext::class);
// Service pour les logs
$this->app->singleton('jsonl.logs', function ($app) {
$strategy = new TemporalPathStrategy(storage_path('logs/structured'));
$fs = new FileSystemService();
$context = $app->make(JsonlContext::class);
return new JsonlService($strategy, $fs, $context);
});
// Service pour le cache
$this->app->singleton('jsonl.cache', function ($app) {
$strategy = new KeyBasedPathStrategy(storage_path('cache/jsonl'), 2);
$fs = new FileSystemService();
$context = $app->make(JsonlContext::class);
$service = new JsonlService($strategy, $fs, $context);
$service->enableBuffer(100);
return $service;
});
}
// Controller
class AnalyticsController extends Controller
{
public function track(Request $request)
{
$jsonl = app('jsonl.logs');
$log = new LogJsonlRecord(
time: new DateTimeVO(),
level: 'info',
type: 'page_view',
payload: new StrictDataObject([
'page' => $request->path(),
'user_id' => auth()->id(),
'user_agent' => $request->userAgent(),
]),
);
$jsonl->writeBuffered($log);
return response()->json(['status' => 'tracked']);
}
}
env
# Chemin de base pour les fichiers JSONL
JSONL_BASE_PATH=/custom/log/path
# Taille du buffer (null = désactivé)
JSONL_BUFFER_SIZE=100
# Permissions des dossiers (755, 775, 750, 700, etc.)
JSONL_DIRECTORY_PERMISSION=755
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.