viu / viu-laravel
Laravel SDK for Viu logging platform — Monolog Handler, Facade, HTTP/Kafka transport
Requires
- php: ^8.1
- guzzlehttp/guzzle: ^7.0
- illuminate/http: ^10.0|^11.0|^12.0
- illuminate/log: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
- monolog/monolog: ^3.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpunit/phpunit: ^10.5|^11.0
Suggests
- longlang/phpkafka: Required for Kafka transport mode (composer require longlang/phpkafka)
README
Laravel SDK para o sistema Viu de centralização de logs
✨ Quer ver logs? → Joga no Viu. Viu?
viu-laravel integra o sistema de logging nativo do Laravel com a plataforma Viu, oferecendo:
- Monolog Handler — integração nativa via
config/logging.php - Facade — acesso direto via
Viu::info(),Viu::error(), etc. - Middleware — propagação automática de Correlation ID
- HTTP Transport (recomendado) — via Guzzle com retry + circuit breaker
- Kafka Transport (alternativo) — envio direto ao tópico Kafka
🚀 Features
- ✅ Monolog Handler — plug-and-play com
Log::channel('viu') - ✅ Auto-discovery — zero configuração manual de providers
- ✅ Circuit Breaker — previne connection storms
- ✅ Retry automático — backoff exponencial em 429/5xx
- ✅ Smart Batching — envia em lote, flush automático no shutdown
- ✅ Correlation IDs — rastreamento de requisições ponta-a-ponta
- ✅ PHP 8.1+ / Laravel 10/11/12
- ✅ Kafka support — via
longlang/phpkafka(pure PHP, sem extensão C)
📦 Instalação
composer require viu/viu-laravel
O service provider é registrado automaticamente via auto-discovery do Laravel.
Opcional — Transport Kafka:
composer require longlang/phpkafka
⚙️ Configuração
1. Publicar o arquivo de configuração
php artisan vendor:publish --tag=viu-config
Isso cria config/viu.php no seu projeto.
2. Variáveis de ambiente (.env)
VIU_SERVICE_NAME=my-laravel-app VIU_ENVIRONMENT=production VIU_API_URL=https://api.viu.com VIU_API_KEY=viu_live_xxxxxxxxxxxxxxxxxxxxxxxx # Opcional VIU_LOG_LEVEL=debug VIU_BATCH_SIZE=100 VIU_HTTP_TIMEOUT=5 VIU_HTTP_MAX_RETRIES=3
🎯 Formas de uso
1. Canal Monolog (recomendado)
Adicione o canal viu em config/logging.php:
'channels' => [ // Canal dedicado 'viu' => [ 'driver' => 'viu', ], // Stack combinando logs locais + Viu 'stack' => [ 'driver' => 'stack', 'channels' => ['daily', 'viu'], ], ],
Uso em código:
use Illuminate\Support\Facades\Log; Log::channel('viu')->info('User logged in', ['user_id' => 123]); Log::channel('viu')->error('Payment failed', ['amount' => 99.90]); // Ou via stack (envia para 'daily' e 'viu' simultaneamente) Log::stack(['daily', 'viu'])->warning('Rate limit approaching');
Sobrescrever o nível mínimo por canal:
'viu' => [ 'driver' => 'viu', 'level' => 'warning', // ignora debug e info neste canal ],
2. Facade Viu
use Viu\ViuLaravel\Facades\Viu; Viu::info('User logged in', ['user_id' => 123]); Viu::warning('Rate limit approaching', ['remaining' => 10]); Viu::error('Payment failed', ['amount' => 99.90, 'currency' => 'BRL']); Viu::critical('Database unreachable', ['host' => 'db.prod']); // Com exception try { processPayment($order); } catch (\Throwable $e) { Viu::error('Payment processing failed', [ 'exception' => $e, 'order_id' => $order->id, 'amount' => $order->total, ]); }
3. Injeção de dependência
use Viu\ViuLaravel\ViuLogger; class OrderService { public function __construct( private readonly ViuLogger $logger, ) {} public function processOrder(Order $order): void { $this->logger->info('Processing order', ['order_id' => $order->id]); try { // ... } catch (\Throwable $e) { $this->logger->error('Order failed', [ 'exception' => $e, 'order_id' => $order->id, ]); } } }
🔗 Middleware — Correlation ID
O ViuCorrelationMiddleware propaga automaticamente o Correlation ID e Trace ID entre requisições,
garantindo rastreabilidade ponta-a-ponta nos logs.
Laravel 10 — app/Http/Kernel.php
protected $middlewareGroups = [ 'api' => [ \Viu\ViuLaravel\Middleware\ViuCorrelationMiddleware::class, // ... ], 'web' => [ \Viu\ViuLaravel\Middleware\ViuCorrelationMiddleware::class, // ... ], ];
Laravel 11/12 — bootstrap/app.php
use Viu\ViuLaravel\Middleware\ViuCorrelationMiddleware; ->withMiddleware(function (Middleware $middleware) { $middleware->appendToGroup('api', ViuCorrelationMiddleware::class); $middleware->appendToGroup('web', ViuCorrelationMiddleware::class); })
Comportamento
| Cenário | Comportamento |
|---|---|
Header X-Correlation-ID presente |
Usa o valor recebido |
| Header ausente | Gera um novo UUID v4 |
Header X-Trace-ID presente |
Usa como Trace ID |
X-Trace-ID ausente |
Usa o Correlation ID como Trace ID |
Headers adicionados na response:
X-Correlation-IDX-Trace-ID
🚀 Modo Kafka (alternativo)
Para ambientes de alta performance onde o envio direto ao Kafka é desejado:
composer require longlang/phpkafka
VIU_TRANSPORT_MODE=kafka VIU_KAFKA_BROKERS=kafka.example.com:9092 VIU_KAFKA_TOPIC=logs.my-tenant VIU_KAFKA_USERNAME=tenant_user VIU_KAFKA_PASSWORD=secure-password VIU_KAFKA_SASL_MECHANISM=SCRAM-SHA-256 VIU_KAFKA_SECURITY_PROTOCOL=SASL_SSL
O modo HTTP é recomendado para a maioria dos casos por sua simplicidade e segurança (não expõe Kafka diretamente).
📋 Configuração completa
// config/viu.php return [ 'service_name' => env('VIU_SERVICE_NAME', env('APP_NAME', 'laravel-app')), 'environment' => env('VIU_ENVIRONMENT', env('APP_ENV', 'production')), 'transport_mode' => env('VIU_TRANSPORT_MODE', 'http'), // 'http' | 'kafka' 'http' => [ 'api_url' => env('VIU_API_URL', ''), 'api_key' => env('VIU_API_KEY', ''), 'timeout' => (int) env('VIU_HTTP_TIMEOUT', 5), 'max_retries' => (int) env('VIU_HTTP_MAX_RETRIES', 3), ], 'kafka' => [ 'brokers' => env('VIU_KAFKA_BROKERS', 'localhost:9092'), 'topic' => env('VIU_KAFKA_TOPIC', 'logs.app.raw'), 'username' => env('VIU_KAFKA_USERNAME', ''), 'password' => env('VIU_KAFKA_PASSWORD', ''), 'sasl_mechanism' => env('VIU_KAFKA_SASL_MECHANISM', 'SCRAM-SHA-256'), 'security_protocol' => env('VIU_KAFKA_SECURITY_PROTOCOL', 'SASL_SSL'), ], 'batch_size' => (int) env('VIU_BATCH_SIZE', 100), 'level' => env('VIU_LOG_LEVEL', 'debug'), 'correlation_id_header' => env('VIU_CORRELATION_ID_HEADER', 'X-Correlation-ID'), ];
🧩 Payload enviado ao backend
{
"timestamp": "2026-03-13T15:04:05.000+00:00",
"level": "ERROR",
"message": "Payment failed",
"service": "my-laravel-app",
"environment": "production",
"source": "payments",
"correlation_id": "550e8400-e29b-41d4-a716-446655440000",
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"span_id": "a1b2c3d4e5f6g7h8",
"module": "payments",
"file": "",
"line": 0,
"context": {
"amount": 99.90,
"currency": "BRL",
"exception": {
"type": "RuntimeException",
"message": "Insufficient funds",
"code": 0,
"file": "/app/Services/PaymentService.php",
"line": 42,
"stacktrace": "..."
}
}
}
🧪 Flush manual (queue workers / jobs)
Em processos de longa duração (queue workers, Octane, etc.), chame flush() após cada job para garantir o envio dos logs pendentes:
// Em um Job public function handle(ViuLogger $logger): void { $logger->info('Job started', ['job' => static::class]); // ... $logger->info('Job completed'); $logger->flush(); // envia imediatamente }
Via Facade:
Viu::info('Job done'); Viu::flush();
🧪 Testes
composer install ./vendor/bin/phpunit
📄 Licença
MIT — veja LICENSE.