risetechapps/monitoring-for-laravel
Composer 安装命令:
composer require risetechapps/monitoring-for-laravel
包简介
README 文档
README
Monitoring for Laravel é um pacote de monitoramento completo para aplicações Laravel, desenvolvido pela RiseTechApps. Ele captura automaticamente eventos da aplicação — requisições HTTP, exceções, jobs, comandos, notificações, e-mails, gates de autorização, eventos e muito mais — com suporte a múltiplos drivers de armazenamento.
Requisitos
- PHP
^8.3 - Laravel
^12.0 - Laravel Sanctum
^4.0
Instalação
Instale o pacote via Composer:
composer require risetechapps/monitoring-for-laravel
O pacote se registra automaticamente via auto-discovery do Laravel. O ServiceProvider e o alias Logs são configurados automaticamente.
Publicar a configuração
php artisan vendor:publish --tag=config --provider="RiseTechApps\Monitoring\MonitoringServiceProvider"
Isso criará o arquivo config/monitoring.php na sua aplicação.
Executar as migrações (drivers MySQL / PostgreSQL)
php artisan migrate
As migrações criam:
- A tabela
monitoringcom os campos padrão - Índices para otimização de consultas
- Campos de resolução de exceções (
resolved_at,resolved_by) — úteis para marcar exceções como "resolvidas"
Configuração
O arquivo config/monitoring.php centraliza todas as opções do pacote.
Opções principais
return [ // Habilita ou desabilita o monitoramento globalmente 'enabled' => env('MONITORING_ENABLED', true), // Driver de armazenamento: 'single' ou 'database' 'driver' => env('MONITORING_DRIVER', 'single'), // Quantidade de entradas acumuladas antes de persistir (buffer) 'buffer_size' => (int) env('MONITORING_BUFFER_SIZE', 5), 'watchers' => [ ... ], 'drivers' => [ ... ], ];
Variáveis de ambiente
| Variável | Padrão | Descrição |
|---|---|---|
MONITORING_ENABLED |
true |
Liga/desliga o monitoramento |
MONITORING_DRIVER |
single |
Driver de armazenamento |
Drivers de Armazenamento
O pacote suporta quatro drivers, configuráveis via MONITORING_DRIVER.
single — Arquivo de Log
Persiste os eventos em um arquivo local (storage/logs/monitoring.log). Ideal para desenvolvimento ou ambientes sem banco de dados.
MONITORING_DRIVER=single
mysql — MySQL
Armazena os eventos na tabela monitoring de uma conexão MySQL.
MONITORING_DRIVER=mysql DB_CONNECTION=mysql
// config/monitoring.php 'mysql' => [ 'connection' => env('DB_CONNECTION', 'mysql'), ],
pgsql — PostgreSQL
Idêntico ao driver MySQL, mas para conexões PostgreSQL.
MONITORING_DRIVER=pgsql DB_CONNECTION=pgsql
'pgsql' => [ 'connection' => env('DB_CONNECTION', 'pgsql'), ],
Watchers
Os watchers são os componentes responsáveis por interceptar e registrar cada categoria de evento. Todos podem ser habilitados/desabilitados individualmente no arquivo de configuração.
RequestWatcher — Requisições HTTP
Monitora todas as requisições HTTP recebidas pela aplicação.
Dados coletados: IP do cliente, URI, método HTTP, controller/action, middlewares, headers, payload, sessão, resposta, duração (ms) e uso de memória (MB).
Opções de filtro:
\RiseTechApps\Monitoring\Watchers\RequestWatcher::class => [ 'enabled' => true, 'options' => [ 'ignore_http_methods' => ['options'], // Ignora métodos HTTP específicos 'ignore_status_codes' => [404], // Ignora códigos de status HTTP 'ignore_paths' => ['telescope', 'horizon'], // Ignora paths específicos 'size_limit' => 64, // Limite de tamanho da resposta em KB ], ],
Segurança: Os campos
password,password_confirmation,authorizationephp-auth-pwsão automaticamente mascarados como********.
ExceptionWatcher — Exceções
Captura exceções registradas via Log::error(), Log::critical() e similares que passem uma instância de Throwable no contexto.
Dados coletados: classe da exceção, arquivo, linha, mensagem, contexto adicional, stack trace e preview de código (linhas ao redor da exceção).
Opções:
\RiseTechApps\Monitoring\Watchers\ExceptionWatcher::class => [ 'enabled' => true, 'options' => [ // Ignorar classes de exceção específicas 'ignore_exceptions' => [ \Illuminate\Validation\ValidationException::class, \Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class, ], // Ignorar exceções cujas mensagens contenham estes textos 'ignore_messages_containing' => ['password', 'sensitive_data'], // Ignorar exceções de arquivos que contenham estes caminhos 'ignore_files_containing' => ['/vendor/'], ], ],
EventWatcher — Eventos
Registra os eventos disparados na aplicação, excluindo eventos internos do framework por padrão.
Dados coletados: nome do evento, payload formatado, lista de listeners e indicação se o evento é broadcast.
Opções:
\RiseTechApps\Monitoring\Watchers\EventWatcher::class => [ 'enabled' => true, 'options' => [ 'ignore' => [ 'App\Events\MeuEventoInterno', ], ], ],
CommandWatcher — Artisan Commands
Monitora comandos Artisan executados.
Dados coletados: nome do comando, código de saída (exit_code), argumentos e opções.
Os comandos
schedule:run,schedule:finish,package:discover,horizon:*,migrate:*e outros comandos internos são ignorados automaticamente.
Opções:
\RiseTechApps\Monitoring\Watchers\CommandWatcher::class => [ 'enabled' => true, 'options' => [ 'ignore' => ['meu:comando-interno'], ], ],
ScheduleWatcher — Tarefas Agendadas
Registra a execução das tarefas agendadas do Laravel Scheduler.
Dados coletados: comando ou closure, descrição, expressão cron, timezone, usuário e saída do comando.
Opções:
\RiseTechApps\Monitoring\Watchers\ScheduleWatcher::class => [ 'enabled' => true, 'options' => [ // Ignorar comandos agendados específicos 'ignore_commands' => ['my:scheduled-command'], // Ignorar closures (tarefas agendadas como closures) 'ignore_closures' => false, ], ],
JobWatcher — Jobs de Fila
Monitora o ciclo de vida completo de jobs, incluindo pendente, processado e falho.
Dados coletados:
- Pendente: nome, conexão, fila, tentativas, timeout, payload,
batch_id - Processado: status, nome do job, tentativas, hostname
- Falho: status, nome do job, mensagem de exceção, trace, preview de código, hostname
Opções:
\RiseTechApps\Monitoring\Watchers\JobWatcher::class => [ 'enabled' => true, 'options' => [ // Ignorar namespaces de jobs 'ignore_namespaces' => [ 'App\Jobs\Internal\', ], // Ignorar jobs específicos 'ignore_jobs' => [ \App\Jobs\HeavyLoggingJob::class, ], ], ],
Jobs do próprio pacote, Telescope, Horizon e Pulse são ignorados automaticamente.
QueueWatcher — Worker de Fila
Detecta parada e retomada do worker de fila. Cria um arquivo storage/framework/queue_stopping ao parar e o remove ao retomar.
GateWatcher — Autorização
Monitora todas as verificações de autorização (Gates e Policies).
Dados coletados: ability verificada, resultado (allowed/denied), argumentos e arquivo/linha de origem da chamada.
Opções:
\RiseTechApps\Monitoring\Watchers\GateWatcher::class => [ 'enabled' => true, 'options' => [ 'ignore_abilities' => ['viewNova'], ], ],
NotificationWatcher — Notificações
Captura notificações enviadas pela aplicação.
Dados coletados: classe da notificação, se é queued, notifiable, canal, resposta e UUID da notificação.
Opções:
\RiseTechApps\Monitoring\Watchers\NotificationWatcher::class => [ 'enabled' => true, 'options' => [ // Ignorar classes de notificação específicas 'ignore_notifications' => [ \App\Notifications\TestNotification::class, ], // Ignorar canais específicos 'ignore_channels' => ['broadcast', 'slack'], // Ignorar notificações anônimas (AnonymousNotifiable) 'ignore_anonymous' => false, ], ],
MailWatcher — E-mails
Registra todos os e-mails enviados.
Dados coletados: classe mailable, se é queued, remetente, reply-to, destinatários (to, cc, bcc), assunto, corpo HTML e e-mail bruto.
Opções:
\RiseTechApps\Monitoring\Watchers\MailWatcher::class => [ 'enabled' => true, 'options' => [ // Ignorar classes Mailable específicas 'ignore_mailables' => [ \App\Mail\TestMail::class, ], // Ignorar e-mails cujo assunto contenha estes textos 'ignore_subjects_containing' => ['[Test]', '[Local]'], // Ignorar e-mails de remetentes específicos 'ignore_from_addresses' => ['noreply@example.com'], // Ignorar e-mails para destinatários específicos 'ignore_to_addresses' => ['test@example.com'], ], ],
ClientRequestWatcher — HTTP Client (Saída)
Monitora requisições HTTP feitas pela aplicação usando o Http:: facade do Laravel.
Dados coletados: método, URI, headers, payload, status da resposta, headers da resposta, corpo da resposta e duração (ms).
Requisições para os hosts da própria plataforma de monitoramento são ignoradas automaticamente para evitar loops.
Opções:
\RiseTechApps\Monitoring\Watchers\ClientRequestWatcher::class => [ 'enabled' => true, 'options' => [ 'ignore_hosts' => ['api.interna.com'], 'size_limit' => 64, ], ], --- ### QueryWatcher — Queries Lentas Monitora automaticamente queries SQL que excedem um tempo limite configurado. **Dados coletados:** SQL completo, bindings, tempo de execução, conexão utilizada, arquivo e linha de origem. **Opções:** ```php \RiseTechApps\Monitoring\Watchers\QueryWatcher::class => [ 'enabled' => true, 'options' => [ // Threshold em ms para considerar query lenta 'slow_query_threshold_ms' => 100, // Padrões de SQL que devem ser ignorados 'ignore_patterns' => ['information_schema', 'migrations', 'telescope'], // Logar bindings das queries 'log_bindings' => true, // Tamanho máximo do SQL antes de truncar 'max_sql_length' => 5000, ], ],
Exemplo de uso:
# Ver queries lentas GET /monitoring/type/query # Buscar queries específicas GET /monitoring/search?q=SELECT * FROM orders
CacheWatcher — Operações de Cache
Monitora hits, misses, escritas e deleções no cache da aplicação.
Dados coletados: operação (hit/miss/write/delete), key, store (redis/memcached/file), TTL (para writes).
Opções:
\RiseTechApps\Monitoring\Watchers\CacheWatcher::class => [ 'enabled' => true, 'options' => [ // Registrar cache hits 'track_hits' => true, // Registrar cache misses 'track_misses' => true, // Chaves de cache que devem ser ignoradas 'ignore_keys' => ['config', 'routes', 'telescope'], ], ],
Casos de uso:
- Identificar keys com baixo hit rate
- Detectar cache thrashing (misses excessivos)
- Analisar TTL efetivo das keys
---
## Loggly — Logger Estruturado
O `Loggly` é o componente de log manual do pacote, acessível via função helper global. Ele oferece uma API fluente para registrar logs ricos e estruturados.
### Helpers disponíveis
```php
loggly() // Info (padrão)
logglyInfo() // Nível INFO
logglyDebug() // Nível DEBUG
logglyWarning() // Nível WARNING
logglyNotice() // Nível NOTICE
logglyError() // Nível ERROR
logglyCritical() // Nível CRITICAL
logglyAlert() // Nível ALERT
logglyEmergency() // Nível EMERGENCY
logglyModel() // Nível MODEL
API fluente
loggly() ->level('error') // Define o nível ->performedOn($user) // Modelo ou string do contexto ->exception($exception) // Captura dados da exceção ->withProperties(['key' => 'value']) // Propriedades extras ->withContext(['request_id' => '123']) // Contexto adicional ->withTags(['pagamento', 'critico']) // Tags para categorização ->withRequest($request->all()) // Dados da requisição ->withResponse($response->json()) // Dados da resposta ->at(new DateTime()) // Timestamp personalizado ->encrypt() // Encripta a mensagem ->to('loggly') // Destino: 'loggly' ou 'file' ->log('Mensagem do log');
Exemplos de uso
Log simples:
logglyInfo()->log('Usuário autenticado com sucesso.');
Log de exceção com contexto:
try { // ... } catch (Exception $e) { logglyError() ->performedOn(PaymentService::class) ->exception($e) ->withProperties(['order_id' => $orderId]) ->log('Falha ao processar pagamento.'); }
Log de modelo:
logglyModel() ->performedOn($produto) ->withContext(['acao' => 'preco_atualizado']) ->log('Preço do produto foi alterado.');
Salvar em arquivo (sem enviar para o driver principal):
loggly()->to('file')->log('Debug local.');
Trait HasLoggly — Auditoria de Models
Adicione a trait HasLoggly a qualquer Model Eloquent para registrar automaticamente as operações de criação, atualização, exclusão e restauração.
use RiseTechApps\Monitoring\Traits\HasLoggly\HasLoggly; class Produto extends Model { use HasLoggly; }
Eventos monitorados
| Evento Eloquent | Ação registrada |
|---|---|
created |
Created record. |
updated |
Updated record. (com diff dos campos alterados) |
deleted |
Deleted record. ou Force deleted record. |
restored |
Restored record. (apenas com SoftDeletes) |
Dados coletados
- updated: classe do model, valores antigos, valores novos e um diff com
old/newpara cada campo alterado. - created/deleted/restored: classe do model e atributos atuais do model.
Se o Model usar
SoftDeletes, o eventorestoredé monitorado automaticamente.
Métricas Customizáveis
Além dos watchers automáticos, você pode registrar métricas de negócio personalizadas usando o helper monitoring().
Tipos de Métricas
Gauge (Valor Pontual)
Registra um valor em um momento específico. Ideal para contagens, estados ou níveis.
// Contagem de pedidos pendentes monitoring()->gauge('pedidos_pendentes', Pedido::where('status', 'pendente')->count()); // Valor em estoque de um produto monitoring()->gauge('estoque_produto', $produto->quantidade, ['produto_id' => $produto->id]); // Usuários ativos no momento monitoring()->gauge('usuarios_ativos', Cache::get('online_users', 0));
Counter (Contador)
Incrementa um contador. Ideal para eventos discretos.
// Checkout concluído monitoring()->increment('checkout_concluido'); // Incremento com valor personalizado monitoring()->increment('itens_vendidos', $quantidade); // Com tags adicionais monitoring()->increment('pagamentos', 1, ['metodo' => 'cartao']); monitoring()->increment('pagamentos', 1, ['metodo' => 'boleto']);
Histogram (Distribuição)
Registra valores em uma distribuição. Ideal para tempos e tamanhos.
// Tempo de processamento em milissegundos monitoring()->histogram('tempo_processamento', 250); // Tamanho da resposta da API monitoring()->histogram('tamanho_resposta_api', strlen($responseBody)); // Com tags para segmentação monitoring()->histogram('tempo_db', $queryTime, ['tabela' => 'pedidos']);
Timer (Medidor de Tempo)
Executa um código e automaticamente registra o tempo de execução.
// Medir tempo de uma operação $resultado = monitoring()->timer('processar_pedido', function() use ($pedido) { return $this->processarPedido($pedido); }); // Medir chamada de API externa $dados = monitoring()->timer('api_pagamento', function() use ($payload) { return Http::post('https://api.pagamento.com', $payload)->json(); }); // Com tags $relatorio = monitoring()->timer('gerar_relatorio', function() { return $this->gerarRelatorioVendas(); }, ['tipo' => 'vendas', 'periodo' => 'mensal']);
Dados Coletados
Cada métrica registra:
| Campo | Descrição |
|---|---|
metric_type |
Tipo: gauge, counter, histogram |
metric_name |
Nome da métrica (ex: checkout_concluido) |
value |
Valor numérico registrado |
tags |
Tags adicionais para segmentação |
created_at |
Timestamp do registro |
Exemplos de Uso na Prática
Controller de Checkout:
class CheckoutController extends Controller { public function processar(Request $request) { $resultado = monitoring()->timer('checkout_total', function() use ($request) { // Validação $dados = $request->validate([...]); // Processamento do pagamento $pagamento = monitoring()->timer('processar_pagamento', function() use ($dados) { return $this->pagamentoService->processar($dados); }, ['gateway' => $dados['gateway']]); // Criar pedido $pedido = Pedido::create([...]); // Atualizar estoque monitoring()->gauge('estoque_reduzido', $this->atualizarEstoque($pedido)); return $pedido; }); monitoring()->increment('pedidos_criados', 1, [ 'metodo_pagamento' => $resultado->metodo ]); return response()->json($resultado); } }
Job de Processamento:
class ProcessarImportacaoJob implements ShouldQueue { public function handle() { monitoring()->gauge('registros_a_processar', $this->totalRegistros); foreach ($this->registros as $registro) { $processado = monitoring()->timer('processar_registro', function() use ($registro) { return $this->processar($registro); }); if ($processado) { monitoring()->increment('registros_sucesso'); } else { monitoring()->increment('registros_falha'); } } monitoring()->gauge('registros_restantes', 0); } }
Comando Artisan:
class LimparCacheCommand extends Command { public function handle() { $chavesRemovidas = monitoring()->timer('limpar_cache', function() { return Cache::flush(); }); monitoring()->increment('cache_limpo', $chavesRemovidas); monitoring()->gauge('cache_tamanho', Cache::getMemoryUsage()); $this->info("Cache limpo: {$chavesRemovidas} chaves removidas."); } }
Consultando Métricas
As métricas são registradas com type = 'metric' e podem ser consultadas via API ou repositório:
use RiseTechApps\Monitoring\Entry\EntryType; // Todas as métricas $metricas = $monitoring->getEventsByTypes(EntryType::METRIC); // Filtrar por nome de métrica $checkouts = $metricas->filter(fn($m) => $m['content']['metric_name'] === 'checkout_concluido'); // Calcular estatísticas $totalCheckouts = $checkouts->sum('content.value'); $tempoMedio = $checkouts->where('content.metric_type', 'histogram')->avg('content.value');
Middleware monitoring.disable
Use o middleware para desabilitar o monitoramento em rotas específicas, como painéis administrativos ou endpoints de health check.
Registrando nas rotas
// routes/web.php ou routes/api.php Route::middleware('monitoring.disable')->group(function () { Route::get('/health', fn () => response()->json(['status' => 'ok'])); Route::get('/admin/dashboard', [AdminController::class, 'index']); });
Aplicando em um controller
public function __construct() { $this->middleware('monitoring.disable'); }
Controle Programático
Desabilitar o monitoramento
use RiseTechApps\Monitoring\Monitoring; Monitoring::disable();
Verificar se está habilitado
if (Monitoring::isEnabled()) { // ... }
Adicionar tags globais a todas as entradas
// Em um ServiceProvider Monitoring::tag(function ($entry) { return ['ambiente:' . app()->environment()]; });
Ocultar parâmetros sensíveis
// Em um ServiceProvider Monitoring::$hiddenRequestParameters = ['cartao_numero', 'cvv']; Monitoring::$hiddenResponseParameters = ['token_acesso', 'secret'];
Registrar rotas do pacote
Monitoring::routes();
Estrutura da Tabela (monitoring)
Quando usando os drivers mysql ou pgsql, os eventos são armazenados na tabela monitoring:
| Coluna | Tipo | Descrição |
|---|---|---|
id |
UUID (PK) | Identificador primário |
uuid |
UUID (unique) | Identificador único da entrada |
batch_id |
UUID | Agrupa entradas de uma mesma requisição/job |
type |
string(20) | Tipo da entrada (veja abaixo) |
content |
JSON | Dados específicos do evento |
tags |
JSON | Tags associadas à entrada |
user |
JSON | Dados do usuário autenticado |
device |
JSON | Dados do dispositivo/browser |
resolved_at |
timestamp (nullable) | Quando a exceção foi marcada como resolvida |
resolved_by |
string (nullable) | Identificador de quem resolveu (email/user_id) |
created_at |
timestamp | — |
updated_at |
timestamp | — |
Tipos de entrada (type)
| Constante | Valor | Descrição |
|---|---|---|
EntryType::REQUEST |
request |
Requisição HTTP recebida |
EntryType::EXCEPTION |
exception |
Exceção capturada |
EntryType::EVENT |
event |
Evento da aplicação |
EntryType::COMMAND |
command |
Comando Artisan |
EntryType::SCHEDULED_TASK |
schedule |
Tarefa agendada |
EntryType::JOB |
job |
Job de fila |
EntryType::GATE |
gate |
Verificação de autorização |
EntryType::NOTIFICATION |
notification |
Notificação enviada |
EntryType::MAIL |
mail |
E-mail enviado |
EntryType::CLIENT_REQUEST |
client_request |
Requisição HTTP de saída |
EntryType::LOG |
log |
Log manual via Loggly |
EntryType::MODEL |
model |
Operação em Model Eloquent |
EntryType::QUERY |
query |
Query no banco de dados |
EntryType::METRIC |
metric |
Métrica de negócio customizada |
Buffer de Entradas
O pacote utiliza um buffer em memória para otimizar a performance, evitando uma escrita no storage para cada evento individualmente.
- As entradas são acumuladas no buffer até atingir
buffer_size(padrão:5). - O buffer é descarregado automaticamente ao final de cada requisição HTTP (evento
RequestHandled). - Em ambientes de console (jobs, commands), o buffer é descarregado imediatamente após cada entrada.
Configure o tamanho do buffer:
MONITORING_BUFFER_SIZE=10
Consultando os Registros de Monitoramento
O pacote fornece um repositório com métodos padronizados para leitura dos eventos, disponíveis para os drivers dabase. O driver single (arquivo) não suporta leitura — seus métodos retornam coleções vazias.
Injetando o Repositório
Você pode injetar o MonitoringRepositoryInterface em qualquer controller, service ou job:
use RiseTechApps\Monitoring\Repository\Contracts\MonitoringRepositoryInterface; class MonitoringDashboardController extends Controller { public function __construct( protected MonitoringRepositoryInterface $monitoring ) {} }
Ou resolver diretamente via container:
$monitoring = app(MonitoringRepositoryInterface::class);
Métodos de Consulta
Todos os métodos retornam uma Illuminate\Support\Collection.
Todos os eventos
$events = $monitoring->getAllEvents(); // Retorna todos os registros ordenados por created_at DESC
Evento por ID
Retorna o evento específico e todos os eventos relacionados do mesmo batch_id no campo related_events.
$event = $monitoring->getEventById('uuid-ou-id-aqui'); // Estrutura de retorno: // [ // 'id' => '...', // 'uuid' => '...', // 'batch_id' => '...', // 'type' => 'request', // 'content' => [...], // 'tags' => [...], // 'user' => [...], // 'device' => [...], // 'created_at' => '...', // 'updated_at' => '...', // 'related_events' => [...], // outros eventos do mesmo batch // ]
Eventos por tipo
Filtra por um dos tipos definidos em EntryType. Retorna cada evento com seu related_events.
use RiseTechApps\Monitoring\Entry\EntryType; $requests = $monitoring->getEventsByTypes(EntryType::REQUEST); $exceptions = $monitoring->getEventsByTypes(EntryType::EXCEPTION); $jobs = $monitoring->getEventsByTypes(EntryType::JOB); $commands = $monitoring->getEventsByTypes(EntryType::COMMAND); $mails = $monitoring->getEventsByTypes(EntryType::MAIL); $logs = $monitoring->getEventsByTypes(EntryType::LOG); $models = $monitoring->getEventsByTypes(EntryType::MODEL); $gates = $monitoring->getEventsByTypes(EntryType::GATE); $events = $monitoring->getEventsByTypes(EntryType::EVENT); $schedules = $monitoring->getEventsByTypes(EntryType::SCHEDULED_TASK); $notifs = $monitoring->getEventsByTypes(EntryType::NOTIFICATION); $outbound = $monitoring->getEventsByTypes(EntryType::CLIENT_REQUEST);
Eventos por batch
Retorna todos os eventos que pertencem a um mesmo ciclo de requisição ou job, agrupados pelo batch_id.
$batchEvents = $monitoring->getByBatch('batch-uuid-aqui');
Lista de tipos disponíveis
$types = $monitoring->getEventsByTags(); // Retorna: ['command', 'event', 'exception', 'job', 'log', 'mail', // 'model', 'notification', 'query', 'request', // 'schedule', 'client_request', 'gate']
Consulta por Período
Filtra eventos pelos períodos pré-definidos:
$monitoring->getLast24Hours(); // Últimas 24 horas $monitoring->getLast7Days(); // Últimos 7 dias $monitoring->getLast15Days(); // Últimos 15 dias $monitoring->getLast30Days(); // Últimos 30 dias $monitoring->getLast60Days(); // Últimos 60 dias $monitoring->getLast90Days(); // Últimos 90 dias
Suporte por Driver
| Método | database |
single |
|---|---|---|
getAllEvents() |
✅ | ❌ |
getEventById() |
✅ | ❌ |
getEventsByTypes() |
✅ | ❌ |
getEventsByTags() |
✅ | ✅* |
getByBatch() |
✅ | ❌ |
getTimelineByTag() |
✅ | ❌ |
gauge() |
✅ | ✅ |
increment() |
✅ | ✅ |
histogram() |
✅ | ✅ |
timer() |
✅ | ✅ |
getLast24Hours() |
✅ | ❌ |
getLast7Days() |
✅ | ❌ |
getLast15Days() |
✅ | ❌ |
getLast30Days() |
✅ | ❌ |
getLast60Days() |
✅ | ❌ |
getLast90Days() |
✅ | ❌ |
resolveEvent() |
✅ | ❌ |
resolveExceptionType() |
✅ | ❌ |
unresolveEvent() |
✅ | ❌ |
getUnresolvedExceptions() |
✅ | ❌ |
*
getEventsByTags()no driversingleretorna apenas a lista de tipos disponíveis.
Rotas HTTP de Consulta
O pacote disponibiliza rotas prontas para expor os eventos via API. Registre-as no AppServiceProvider ou RouteServiceProvider:
use RiseTechApps\Monitoring\Monitoring; // Registro básico (usa middleware 'api' por padrão) Monitoring::routes();
Opções disponíveis:
Monitoring::routes([ 'middleware' => ['api', 'auth:sanctum'], // middlewares customizados 'authorize' => 'view-monitoring', // Gate/Policy de autorização 'rate_limit' => '60,1', // throttle: 60 req/min 'as' => 'monitoring.', // prefixo dos nomes das rotas ]);
Endpoints registrados:
| Método | URI | Nome | Descrição |
|---|---|---|---|
GET |
/monitoring |
monitoring.index |
Lista todos os eventos |
GET |
/monitoring/{id} |
monitoring.show |
Detalhe de um evento + relacionados |
GET |
/monitoring/type/{type} |
monitoring.type |
Filtra por tipo |
POST |
/monitoring/tags |
monitoring.tags |
Lista tipos disponíveis |
GET |
/monitoring/timeline/{tag}/{value} |
monitoring.timeline |
Timeline cronológico por tag |
Rotas de Health Check:
| Método | URI | Nome | Descrição |
|---|---|---|---|
GET |
/monitoring/health |
monitoring.health |
Verifica saúde da aplicação (DB, Cache, Queue, Storage) |
Rotas de Busca e Comparação:
| Método | URI | Nome | Descrição |
|---|---|---|---|
GET |
/monitoring/search |
monitoring.search |
Busca full-text nos eventos |
GET |
/monitoring/compare |
monitoring.compare |
Compara métricas entre dois períodos |
Rotas de Resolução de Exceções:
| Método | URI | Nome | Descrição |
|---|---|---|---|
GET |
/monitoring/exceptions/unresolved |
monitoring.exceptions.unresolved |
Lista exceções não resolvidas agrupadas por tipo |
POST |
/monitoring/resolve-exception |
monitoring.exceptions.resolve-type |
Marca todas as exceções de um tipo como resolvidas |
POST |
/monitoring/{id}/resolve |
monitoring.resolve |
Marca um evento específico como resolvido |
POST |
/monitoring/{id}/unresolve |
monitoring.unresolve |
Remove o status de resolvido de um evento |
As rotas do painel de monitoramento usam automaticamente o middleware
monitoring.disablepara não serem monitoradas.
Timeline por Tag
Visualize o fluxo completo de eventos relacionados a uma tag específica em ordem cronológica. Útil para rastrear o ciclo de vida de um pedido, usuário, ou qualquer entidade monitorada.
Endpoint
GET /monitoring/timeline/{tag}/{value}?period=24%20hours
Parâmetros:
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
tag |
string | Sim | Nome da tag (ex: pedido_id) |
value |
string | Sim | Valor da tag (ex: 123) |
period |
string | Não | Período de busca. Padrão: 24 hours. Opções: 1 hour, 6 hours, 12 hours, 24 hours, 7 days, 30 days, 90 days |
Exemplos de uso
Timeline de um pedido:
GET /monitoring/timeline/pedido_id/123?period=24%20hours
Timeline de um usuário específico:
GET /monitoring/timeline/user_id/550e8400-e29b-41d4-a716-446655440000?period=7%20days
Resposta
{
"tag": "pedido_id",
"value": "123",
"period": "24 hours",
"total_batches": 2,
"timeline": [
{
"batch_id": "abc-123-uuid",
"started_at": "2025-01-15 10:23:15",
"timeline": [
{
"id": "...",
"type": "request",
"type_label": "Requisição HTTP",
"icon": "🌐",
"content": { "method": "POST", "uri": "/api/pedidos", ... },
"tags": { "pedido_id": "123" },
"created_at": "2025-01-15 10:23:15"
},
{
"id": "...",
"type": "query",
"type_label": "Query SQL",
"icon": "🗄️",
"content": { "sql": "INSERT INTO pedidos...", "time_ms": 45 },
"tags": { "pedido_id": "123" },
"created_at": "2025-01-15 10:23:15"
},
{
"id": "...",
"type": "job",
"type_label": "Job",
"icon": "⚙️",
"content": { "displayName": "ProcessarPedidoJob", ... },
"tags": { "pedido_id": "123" },
"created_at": "2025-01-15 10:23:16"
},
{
"id": "...",
"type": "mail",
"type_label": "E-mail",
"icon": "📧",
"content": { "subject": "Pedido #123 recebido", ... },
"tags": { "pedido_id": "123" },
"created_at": "2025-01-15 10:23:18"
}
],
"duration_ms": 3000,
"event_count": 4
},
{
"batch_id": "def-456-uuid",
"started_at": "2025-01-15 14:45:22",
"timeline": [
{
"id": "...",
"type": "request",
"type_label": "Requisição HTTP",
"icon": "🌐",
"content": { "method": "PUT", "uri": "/api/pedidos/123", ... },
"tags": { "pedido_id": "123" },
"created_at": "2025-01-15 14:45:22"
},
{
"id": "...",
"type": "query",
"type_label": "Query SQL",
"icon": "🗄️",
"content": { "sql": "UPDATE pedidos...", "time_ms": 23 },
"tags": { "pedido_id": "123" },
"created_at": "2025-01-15 14:45:22"
}
],
"duration_ms": 800,
"event_count": 2
}
]
}
> **Nota:** Os eventos são agrupados por `batch_id` único. Se múltiplos eventos
> compartilharem o mesmo batch_id, você recebe apenas uma entrada na timeline
> contendo todos os eventos relacionados.
Uso programático
use RiseTechApps\Monitoring\Repository\Contracts\MonitoringRepositoryInterface; class PedidoController extends Controller { public function __construct( protected MonitoringRepositoryInterface $monitoring ) {} public function timeline(string $pedidoId) { // Busca todos os eventos relacionados ao pedido nas últimas 24h // Agrupados por batch_id único $timeline = $this->monitoring->getTimelineByTag('pedido_id', $pedidoId, '24 hours'); return response()->json([ 'pedido_id' => $pedidoId, 'total_operacoes' => $timeline->count(), 'operacoes' => $timeline->map(function ($batch) { return [ 'batch_id' => $batch['batch_id'], 'inicio' => $batch['started_at'], 'fim' => $batch['timeline']->last()['created_at'] ?? null, 'duracao_ms' => $batch['duration_ms'], 'eventos' => $batch['event_count'], 'passos' => $batch['timeline']->map(fn ($e) => [ 'hora' => $e['created_at'], 'tipo' => $e['type_label'], 'icone' => $e['icon'], ]), ]; }), ]); } }
Gerenciamento de Exceções Resolvidas
O pacote permite marcar exceções como "resolvidas", facilitando o acompanhamento de bugs e evitando poluição visual no dashboard.
Campos adicionais na resposta
Quando um evento é resolvido, os seguintes campos são adicionados à resposta:
[ 'id' => '...', 'uuid' => '...', 'type' => 'exception', 'content' => [...], // ... outros campos ... 'resolved_at' => '2025-01-15 14:30:00', // quando foi resolvido 'resolved_by' => 'user@example.com', // quem resolveu 'is_resolved' => true, // flag booleana ]
Listar exceções não resolvidas
GET /monitoring/exceptions/unresolved
Resposta:
[
{
"exception_class": "App\\Exceptions\\CustomException",
"count": 15,
"last_occurrence": "2025-01-15 10:23:00"
},
{
"exception_class": "Illuminate\\Validation\\ValidationException",
"count": 3,
"last_occurrence": "2025-01-15 09:45:00"
}
]
Marcar uma exceção como resolvida
POST /monitoring/{id}/resolve
Content-Type: application/json
{
"resolved_by": "user@example.com"
}
Marcar múltiplas exceções do mesmo tipo como resolvidas
POST /monitoring/resolve-exception
Content-Type: application/json
{
"exception_class": "App\\Exceptions\\CustomException",
"resolved_by": "user@example.com"
}
Resposta:
{
"message": "15 exceções marcadas como resolvidas.",
"exception_class": "App\\Exceptions\\CustomException",
"count": 15
}
Desfazer a resolução
POST /monitoring/{id}/unresolve
Uso programático
use RiseTechApps\Monitoring\Repository\Contracts\MonitoringRepositoryInterface; class ExceptionController extends Controller { public function __construct( protected MonitoringRepositoryInterface $monitoring ) {} // Marcar como resolvida public function resolve(string $id) { $success = $this->monitoring->resolveEvent( $id, auth()->user()?->email ); return $success ? response()->json(['message' => 'Resolvido!']) : response()->json(['message' => 'Não encontrado'], 404); } // Listar não resolvidas public function unresolved() { $exceptions = $this->monitoring->getUnresolvedExceptions(); return response()->json($exceptions); } }
Health Check
Endpoint para verificar a saúde da aplicação e suas dependências.
Endpoint
GET /monitoring/health
Resposta
{
"status": "healthy",
"checks": {
"database": { "status": "ok" },
"cache": { "status": "ok", "driver": "redis" },
"queue": { "status": "ok", "driver": "redis", "queue_size": 0 },
"storage": { "status": "ok", "disk": "local" }
},
"performance": {
"apdex_score": 0.94,
"throughput_per_minute": 245,
"error_rate_percent": 0.5
},
"timestamp": "2025-01-15T10:30:00Z"
}
Status possíveis
| Status | Significado |
|---|---|
healthy |
Todos os sistemas OK |
degraded |
Algum sistema com problemas leves |
unhealthy |
Falha crítica em algum sistema |
Uso em Load Balancers
# Health check para load balancer GET /monitoring/health # Retorna 200 se healthy/degraded # Retorna 503 se unhealthy
Sistema de Alertas
Configure notificações automáticas para eventos críticos via Slack, Discord ou Email.
Configuração
// config/monitoring.php 'alerts' => [ 'enabled' => env('MONITORING_ALERTS_ENABLED', true), // Webhooks 'slack_webhook' => env('MONITORING_SLACK_WEBHOOK'), 'discord_webhook' => env('MONITORING_DISCORD_WEBHOOK'), // Email 'email' => [ 'enabled' => true, 'to' => ['devops@empresa.com'], 'from' => 'monitoring@empresa.com', ], // Thresholds 'thresholds' => [ 'exceptions_per_minute' => 10, 'failed_jobs_per_hour' => 5, 'slow_request_ms' => 5000, 'slow_queries_per_minute' => 10, 'error_rate_percent' => 5.0, ], // Cooldown entre alertas (minutos) 'cooldown_minutes' => 5, ],
Variáveis de ambiente
MONITORING_ALERTS_ENABLED=true MONITORING_SLACK_WEBHOOK=https://hooks.slack.com/services/... MONITORING_DISCORD_WEBHOOK=https://discord.com/api/webhooks/... MONITORING_ALERTS_EMAIL_TO=devops@empresa.com,admin@empresa.com
Alertas Disparados
| Evento | Threshold | Mensagem |
|---|---|---|
| Exceção em produção | Qualquer | 🚨 Exceção: {class} - {message} |
| Requisição lenta | > 5000ms | ⏱️ Requisição lenta: {uri} - {duration}ms |
| Job falho | > 5/hora | 🔥 Job falhou: {job} |
| Query lenta | > 100ms | 🐢 Query lenta: {time}ms |
Cooldown
Para evitar spam, o mesmo tipo de alerta só é enviado a cada 5 minutos (configurável).
Relatórios Automáticos
Gere relatórios periódicos (diário, semanal, mensal) com métricas e estatísticas completas do sistema de monitoramento.
Configuração
// config/monitoring.php 'reports' => [ 'auto_schedule' => env('MONITORING_REPORTS_AUTO_SCHEDULE', false), 'timezone' => 'America/Sao_Paulo', 'daily' => [ 'enabled' => true, 'send_at' => '08:00', ], 'weekly' => [ 'enabled' => true, 'send_at' => '08:00', 'day' => 'monday', ], 'monthly' => [ 'enabled' => true, 'send_at' => '08:00', ], 'channels' => [ 'email' => [ 'enabled' => true, 'to' => ['devops@empresa.com'], 'from' => 'monitoring@empresa.com', ], 'slack' => ['enabled' => true], 'discord' => ['enabled' => true], ], ],
Variáveis de Ambiente
MONITORING_REPORTS_AUTO_SCHEDULE=true MONITORING_REPORT_EMAIL_TO=devops@empresa.com,admin@empresa.com MONITORING_REPORT_EMAIL_FROM=monitoring@empresa.com # Canais MONITORING_REPORT_EMAIL_ENABLED=true MONITORING_REPORT_SLACK_ENABLED=true MONITORING_REPORT_DISCORD_ENABLED=false
Comando Artisan
# Gerar relatório diário php artisan monitoring:report daily # Gerar e enviar automaticamente php artisan monitoring:report daily --send # Enviar para canais específicos php artisan monitoring:report weekly --send --channels=email,slack # Preview no console php artisan monitoring:report monthly --preview # Salvar HTML no storage php artisan monitoring:report daily --save
Conteúdo do Relatório
Cada relatório inclui:
1. Resumo Executivo
- Total de eventos
- Exceções, requisições, jobs
- Taxa de erro
- Tempo médio de resposta
2. Métricas de Performance
- Apdex Score
- Tempo mínimo, máximo e médio
- Queries lentas
3. Eventos por Tipo
- Distribuição percentual
- Gráficos de barras
4. Top Erros
- Exceções mais frequentes (não resolvidas)
- Contagem de ocorrências
5. Tendências
- Comparação com período anterior
- Indicadores de crescimento/queda
Agendamento Automático
Com MONITORING_REPORTS_AUTO_SCHEDULE=true:
| Relatório | Frequência | Horário |
|---|---|---|
| Diário | Todo dia | 08:00 |
| Semanal | Segundas-feiras | 08:00 |
| Mensal | Dia 1 de cada mês | 08:00 |
Relatórios Customizáveis (100% Autônomo)
O sistema de relatórios permite 100% de autonomia no envio. Você pode usar:
- Handlers Customizados - Substituir canais específicos ou todos
- Event Listener - Controle total via evento
ReportGenerated - Notificações Padrão - Email, Slack, Discord (funciona sem configuração extra)
Controle Total - Desabilitar Padrão
Para usar apenas suas notificações customizadas:
// Em um ServiceProvider use RiseTechApps\Monitoring\Services\Reporting\ReportService; public function boot(): void { // Desabilita notificações padrão ReportService::disableDefaultNotifications(); }
Handler Customizado para Relatórios
Implemente ReportHandlerInterface para criar seu próprio envio:
<?php namespace App\Monitoring\Handlers; use RiseTechApps\Monitoring\Contracts\ReportHandlerInterface; class MinhaNotificacaoEmail implements ReportHandlerInterface { public function send(array $report, string $html, array $config = []): bool { // Use sua própria lógica de envio return \Mail::send('minha-view-relatorio', [ 'relatorio' => $report, ], function ($message) use ($report, $config) { $message->to($config['to'] ?? 'admin@empresa.com') ->subject($report['period_label']); }); } public function isConfigured(array $config = []): bool { return !empty($config['to']); } public function getName(): string { return 'minha_notificacao_email'; } public function getSupportedChannels(): array { return ['email']; // Substitui só o email // return []; // Todos os canais // return ['email', 'slack']; // Email + Slack } }
Registre o handler:
use RiseTechApps\Monitoring\Services\Reporting\ReportService; use App\Monitoring\Handlers\MinhaNotificacaoEmail; public function boot(): void { // Substitui apenas o canal de email ReportService::registerHandler('meu_email', new MinhaNotificacaoEmail()); // Ou desabilita padrão e usa só o seu ReportService::disableDefaultNotifications(); }
Configure no config/monitoring.php:
'reports' => [ // ... outras configurações ... 'custom_handlers' => [ 'meu_email' => [ 'to' => 'admin@empresa.com', 'from' => 'monitoring@empresa.com', ], ], ],
Evento ReportGenerated
Ouça o evento para controle total:
<?php namespace App\Listeners; use RiseTechApps\Monitoring\Events\ReportGenerated; class EnviarMeuRelatorio { public function handle(ReportGenerated $event): void { // Acesso completo aos dados $period = $event->report['period']; // 'daily', 'weekly', 'monthly' $summary = $event->report['summary']; // Métricas $html = $event->html; // HTML renderizado $channels = $event->channels; // Canais solicitados // Envio customizado foreach ($channels as $channel) { match($channel) { 'email' => $this->enviarEmailCustom($event), 'slack' => $this->enviarSlackCustom($event), default => null, }; } // Suprime envio padrão (100% autônomo) $event->markAsHandled(); $event->suppressDefaultNotifications(); } }
Registre no EventServiceProvider:
protected $listen = [ \RiseTechApps\Monitoring\Events\ReportGenerated::class => [ \App\Listeners\EnviarMeuRelatorio::class, ], ];
Comparativo: Alertas vs Relatórios
| Recurso | Alertas (runtime) | Relatórios (periódicos) |
|---|---|---|
| Interface | AlertHandlerInterface |
ReportHandlerInterface |
| Evento | AlertTriggered |
ReportGenerated |
| Service | AlertService |
ReportService |
| Contexto | Evento individual (exceção, etc) | Dados agregados do período |
| Dados | IncomingEntry |
array $report + string $html |
| Canais | Email, Slack, Discord | Email, Slack, Discord |
Notificações Customizáveis (Alertas)
Além dos canais padrão (Slack, Discord, Email), você pode criar notificações customizadas usando Handlers ou ouvindo o evento AlertTriggered.
Método 1: Handler Customizado (Recomendado)
Crie uma classe implementando AlertHandlerInterface:
<?php namespace App\Monitoring\Handlers; use RiseTechApps\Monitoring\Contracts\AlertHandlerInterface; use RiseTechApps\Monitoring\Entry\IncomingEntry; class TelegramAlertHandler implements AlertHandlerInterface { public function send(string $type, IncomingEntry $entry, array $config = []): bool { $botToken = $config['bot_token'] ?? config('services.telegram.bot_token'); $chatId = $config['chat_id'] ?? config('services.telegram.chat_id'); $message = $this->formatMessage($type, $entry); $response = Http::post("https://api.telegram.org/bot{$botToken}/sendMessage", [ 'chat_id' => $chatId, 'text' => $message, 'parse_mode' => 'HTML', ]); return $response->successful(); } public function isConfigured(array $config = []): bool { return !empty($config['bot_token']) && !empty($config['chat_id']); } public function getName(): string { return 'telegram'; } private function formatMessage(string $type, IncomingEntry $entry): string { $content = $entry->content; return match ($type) { 'exception' => "<b>🚨 Exceção</b>\n" . "Classe: {$content['class']}\n" . "Mensagem: {$content['message']}", 'request' => "<b>⏱️ Requisição Lenta</b>\n" . "{$content['method']} {$content['uri']}\n" . "Duração: {$content['duration']}ms", default => "<b>Alerta:</b> {$type}", }; } }
Registre o handler em um ServiceProvider:
<?php namespace App\Providers; use App\Monitoring\Handlers\TelegramAlertHandler; use Illuminate\Support\ServiceProvider; use RiseTechApps\Monitoring\Services\Alerts\AlertService; class MonitoringServiceProvider extends ServiceProvider { public function boot(): void { // Registra o handler customizado AlertService::registerHandler('telegram', new TelegramAlertHandler()); } }
Configure o handler no config/monitoring.php:
'alerts' => [ 'enabled' => true, // ... configurações padrão ... // Handlers customizados 'custom_handlers' => [ 'telegram' => [ 'bot_token' => env('TELEGRAM_BOT_TOKEN'), 'chat_id' => env('TELEGRAM_CHAT_ID'), ], ], ],
Método 2: Event Listener
Ouça o evento AlertTriggered para executar ações customizadas:
<?php namespace App\Listeners; use RiseTechApps\Monitoring\Events\AlertTriggered; class SendPagerDutyNotification { public function handle(AlertTriggered $event): void { // Apenas para exceções críticas if ($event->type !== 'exception') { return; } $content = $event->entry->content; // Envia para PagerDuty Http::post(config('services.pagerduty.webhook'), [ 'routing_key' => config('services.pagerduty.key'), 'event_action' => 'trigger', 'payload' => [ 'summary' => $content['message'], 'severity' => 'critical', 'source' => $content['file'] ?? 'unknown', ], ]); // Marca como handled para pular notificações padrão (opcional) // $event->markAsHandled(); } }
Registre o listener no EventServiceProvider:
protected $listen = [ \RiseTechApps\Monitoring\Events\AlertTriggered::class => [ \App\Listeners\SendPagerDutyNotification::class, ], ];
Desabilitar Notificações Padrão
Para usar apenas notificações customizadas:
use RiseTechApps\Monitoring\Services\Alerts\AlertService; // Em um ServiceProvider::boot() AlertService::disableDefaultNotifications();
Para reabilitar:
AlertService::enableDefaultNotifications();
Ordem de Processamento
- Evento
AlertTriggeredé disparado → listeners podem processar - Se
$event->handled = true, notificações padrão são ignoradas - Handlers customizados são executados
- Notificações padrão (Slack/Discord/Email) são enviadas (se não desabilitadas)
Exemplo: Notificação para Múltiplos Canais
// Handler para Microsoft Teams class TeamsAlertHandler implements AlertHandlerInterface { public function send(string $type, IncomingEntry $entry, array $config = []): bool { $webhook = $config['webhook_url']; $card = [ '@type' => 'MessageCard', '@context' => 'https://schema.org/extensions', 'themeColor' => $this->getColorForType($type), 'summary' => "Alerta: {$type}", 'sections' => [ [ 'activityTitle' => "Alerta de Monitoramento: {$type}", 'facts' => $this->buildFacts($entry), ], ], ]; Http::post($webhook, $card); return true; } public function isConfigured(array $config = []): bool { return !empty($config['webhook_url']); } public function getName(): string { return 'teams'; } }
Performance Monitoring
Métricas avançadas de performance calculadas automaticamente.
Configuração
'performance' => [ 'track_memory_peaks' => true, 'track_db_connections' => true, 'track_cache_hits' => true, 'apdex' => [ 'threshold' => 500, // ms - satisfatório 'tolerable' => 2000, // ms - tolerável ], ],
Métricas Calculadas
Apdex Score
Mede satisfação do usuário (0.0 a 1.0):
1.0= Perfeito0.94-0.99= Excelente0.85-0.93= Bom0.70-0.84= Justo< 0.70= Ruim
Throughput
Requisições por minuto processadas.
Latência Percentil
| Métrica | Significado |
|---|---|
p50 (mediana) |
50% das requisições são mais rápidas que isso |
p95 |
95% das requisições são mais rápidas |
p99 |
99% das requisições são mais rápidas |
Exemplo de resposta
{
"apdex_score": 0.94,
"throughput_per_minute": 245,
"error_rate_percent": 0.5,
"latency": {
"p50": 120,
"p95": 450,
"p99": 890,
"avg": 180,
"min": 45,
"max": 1200
},
"memory": {
"peak_avg_mb": 64,
"peak_max_mb": 128
}
}
Filtros Avançados na API
Parâmetros de busca
# Filtrar por tipo e período GET /monitoring?type=exception&from=2025-01-01&to=2025-01-15 # Apenas exceções não resolvidas GET /monitoring?type=exception&unresolved=true # Ordenação personalizada GET /monitoring?sort=created_at&order=asc&per_page=25 # Busca full-text GET /monitoring/search?q=PaymentException # Busca por tipo específico GET /monitoring/search?q=TimeoutException&type=exception
Comparação de Períodos
GET /monitoring/compare?period1=last_7_days&period2=previous_7_days
Resposta:
{
"period1": {
"name": "last_7_days",
"data": { "total": 1250, "by_type": {...} }
},
"period2": {
"name": "previous_7_days",
"data": { "total": 980, "by_type": {...} }
},
"changes": {
"total_diff": 270,
"total_percent": 27.55
}
}
Política de Retenção Inteligente
Configure retenção diferenciada por tipo de dado.
Configuração
'retention' => [ 'days' => 90, // Padrão fallback // Políticas granulares 'granular' => [ 'exceptions' => 90, // Manter exceções por mais tempo 'requests' => 30, // Requisições por menos tempo 'jobs' => 60, 'queries' => 7, // Queries por pouco tempo 'cache' => 7, 'metrics' => 30, ], // Manter exceções não resolvidas além do prazo 'keep_unresolved' => true, ],
Comando de retenção
# Retenção padrão php artisan monitoring:retention # Com políticas granulares php artisan monitoring:retention --granular # Manter exceções não resolvidas php artisan monitoring:retention --keep-unresolved # Simular sem executar php artisan monitoring:retention --dry-run
Agendamento automático
// App/Console/Kernel.php protected function schedule(Schedule $schedule): void { $schedule->command('monitoring:retention --granular --force') ->dailyAt('02:00'); }
Exemplos de requisição:
# Todos os eventos GET /monitoring # Evento específico com relacionados GET /monitoring/018e4b2a-1234-7000-abcd-ef0123456789 # Filtrar por tipo GET /monitoring/type/exception GET /monitoring/type/request GET /monitoring/type/job # Listar tipos disponíveis POST /monitoring/tags
Exemplo Completo: Dashboard de Monitoramento
use RiseTechApps\Monitoring\Repository\Contracts\MonitoringRepositoryInterface; use RiseTechApps\Monitoring\Entry\EntryType; class MonitoringDashboardController extends Controller { public function __construct( protected MonitoringRepositoryInterface $monitoring ) {} public function index() { return response()->json([ 'resumo' => [ 'requisicoes' => $this->monitoring->getEventsByTypes(EntryType::REQUEST)->count(), 'excecoes' => $this->monitoring->getEventsByTypes(EntryType::EXCEPTION)->count(), 'jobs_falhos' => $this->monitoring->getEventsByTypes(EntryType::JOB) ->where('content.status', 'failed')->count(), ], 'ultimas_24h' => $this->monitoring->getLast24Hours(), 'ultimos_7d' => $this->monitoring->getLast7Days(), ]); } public function show(string $id) { return response()->json( $this->monitoring->getEventById($id) ); } public function byBatch(string $batchId) { // Útil para ver tudo que aconteceu em uma requisição específica: // request + events + jobs + gates disparados juntos return response()->json( $this->monitoring->getByBatch($batchId) ); } }
Diagnóstico e Troubleshooting
Testar Watchers (`monitoring:test-watchers)
Execute um diagnóstico completo para verificar se todos os watchers estão funcionando corretamente. O comando dispara eventos de teste e verifica se foram registrados no banco.
# Teste completo php artisan monitoring:test-watchers # Com detalhes php artisan monitoring:test-watchers --verbose # Aguardar mais tempo entre testes php artisan monitoring:test-watchers --wait=3 # Não limpar registros de teste (para debug) php artisan monitoring:test-watchers --no-cleanup
Testes executados
| Watcher | Evento de Teste | O que é verificado |
|---|---|---|
| Exception | Exception de teste | Captura de exceções |
| Query | SELECT simples | Monitoramento de queries |
| Cache | Write, Hit, Miss, Delete | Operações de cache |
| Log | Log::info() | Mensagens de log |
| Event | Evento de locale | Eventos disparados |
| Gate | Gate de teste | Autorizações |
| Mailable de teste | Envio de e-mail | |
| Notification | Notificação de teste | Notificações |
| HTTP Client | Request fake | Requisições HTTP |
Saída esperada
┌─────────────────────────────────────────────────┐
│ Monitoring — Teste de Watchers │
└─────────────────────────────────────────────────┘
✓ Monitoramento habilitado
Testando: Exception Watcher
✓ Evento disparado
Testando: Query Watcher
✓ Evento disparado
...
Verificando registros no banco...
✓ Exception Watcher: 1 registro(s) encontrado(s)
✓ Query Watcher: 1 registro(s) encontrado(s)
✓ Cache Watcher: 4 registro(s) encontrado(s)
...
─────────────────────────────────────────────────
RESUMO DOS TESTES
─────────────────────────────────────────────────
Total: 9 | Eventos disparados: 9 | Registros no DB: 8
┌─────────────────────────┬───────────────────┬────────────┐
│ Watcher │ Status │ Registros │
├─────────────────────────┼───────────────────┼────────────┤
│ Exception Watcher │ ✓ OK │ 1 │
│ Query Watcher │ ✓ OK │ 1 │
│ Cache Watcher │ ✓ OK │ 4 │
│ Log Watcher │ ✓ OK │ 1 │
│ ... │ ... │ ... │
└─────────────────────────┴───────────────────┴────────────┘
Possíveis problemas
"Monitoramento está DESABILITADO"
# Verifique a configuração cat .env | grep MONITORING_ENABLED # Ou habilite temporariamente php artisan tinker --execute="config(['monitoring.enabled' => true])"
Watcher não registra no banco
- Verifique se o watcher está habilitado em
config/monitoring.php - Confirme se o driver é
database(nãosingle) - Execute com
--wait=5para dar mais tempo ao buffer
"0 registros encontrados"
- Driver
singlegrava em arquivo, não no banco — isso é normal - Verifique
storage/logs/monitoring.logpara logs em arquivo
Canal de Log monitoring
O pacote registra automaticamente um canal de log chamado monitoring no Laravel. Você pode usá-lo diretamente com a facade Log:
use Illuminate\Support\Facades\Log; Log::channel('monitoring')->info('Mensagem de log.');
Os logs são gravados em storage/logs/monitoring.log.
Facade Logs
O pacote registra o alias Logs para a facade MonitoringFacade:
use Logs; // alias para MonitoringFacade Logs::disable(); Logs::isEnabled();
Changelog
Veja o CHANGELOG para o histórico completo de versões.
Contribuindo
Veja o CONTRIBUTING para detalhes sobre como contribuir com o projeto.
Licença
Este pacote é open-source, licenciado sob a MIT license.
Desenvolvido com ❤️ por RiseTechApps — apps@risetech.com.br
risetechapps/monitoring-for-laravel 适用场景与选型建议
risetechapps/monitoring-for-laravel 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 503 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 05 月 23 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「monitoring」 「laravel」 「logs」 「risetech」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 risetechapps/monitoring-for-laravel 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 risetechapps/monitoring-for-laravel 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 risetechapps/monitoring-for-laravel 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
The tenancy/tenancy logs mutations
A Symfony bundle for chameleon-system/sanitycheck
SoftWax Health Check Bundle for Symfony framework
1Pilot client for Symfony
Statsd (Object Oriented) client library for PHP
APM agent for laravel projects to monitor the application with elastic apm tools.
统计信息
- 总下载量: 503
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 23
- 依赖项目数: 3
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-05-23