hassanjrao/laravel-ai-log-search
Composer 安装命令:
composer require hassanjrao/laravel-ai-log-search
包简介
AI-assisted, natural-language log file search for Laravel. Streams huge log files without loading them into memory and turns plain-language questions into structured filters via Gemini or any OpenAI-compatible API.
README 文档
README
AI-assisted, natural-language search over your Laravel log files — built for very large logs (hundreds of MB) that normal log viewers choke on.
Ask in plain language:
"errors that happened today" · "entries mentioning PaymentJob after 2 pm" · "critical entries related to user 4521"
The AI turns your request into a structured filter (levels, keywords, date range) — it never reads your log file. A deterministic streaming scanner then applies that filter to the file:
- Flat memory — the file is read backwards in 64 KB chunks; a 2 GB log uses the same memory as a 2 KB one.
- Newest first — results stream from the end of the file.
- Bounded requests — each request stops at a match limit and a byte-scan budget (default 50 MB), returning a byte offset so "Load older" resumes exactly where it left off.
- Multi-line aware — stack traces and context lines are grouped with their entry.
- Redaction — emails, bearer tokens, obvious secrets, and long digit runs are masked before entries reach the browser.
- Works without AI — with
driver=none(the default) the prompt is used as a plain keyword search. No API key needed to try it.
The UI is a single self-contained page (vanilla JS, no build step, no frontend framework required).
Demo
Requirements
- PHP 7.2.5+ or 8.x
- Laravel 7 – 12
Installation
composer require hassanjrao/laravel-ai-log-search
The service provider is auto-discovered. Visit /ai-log-search (in the local environment it works immediately).
Authorization (required outside local)
Like Telescope, the page is open in the local environment only. Anywhere else you must define a viewAiLogSearch gate (e.g. in AuthServiceProvider::boot()):
use Illuminate\Support\Facades\Gate; Gate::define('viewAiLogSearch', function ($user) { return in_array($user->email, ['admin@example.com']); // or: return $user->hasPermissionTo('view-log-search'); });
Enable AI interpretation (optional)
Pick a driver in .env:
# Google Gemini AI_LOG_SEARCH_DRIVER=gemini AI_LOG_SEARCH_GEMINI_KEY=your-key AI_LOG_SEARCH_GEMINI_MODEL=gemini-2.5-flash # ...or any OpenAI-compatible API (OpenAI, Azure, Groq, Ollama, LM Studio, ...) AI_LOG_SEARCH_DRIVER=openai AI_LOG_SEARCH_OPENAI_KEY=your-key AI_LOG_SEARCH_OPENAI_MODEL=gpt-4o-mini AI_LOG_SEARCH_OPENAI_BASE_URL=https://api.openai.com/v1
If the AI call fails or returns garbage, the package silently falls back to searching the raw prompt as a keyword — the page keeps working.
Custom AI provider
Bind your own implementation of Hassanjrao\AiLogSearch\Contracts\AiClient in a service provider:
$this->app->bind(\Hassanjrao\AiLogSearch\Contracts\AiClient::class, MyAnthropicClient::class);
completeJson(string $instruction): ?array receives the interpretation prompt and must return the decoded JSON filter (or null).
Configuration
php artisan vendor:publish --tag=ai-log-search-config
Key options in config/ai-log-search.php:
| Option | Default | Description |
|---|---|---|
route_prefix |
ai-log-search |
URL prefix for the page and its API. |
middleware |
['web'] |
Middleware stack (the authorize middleware is always appended). |
log_dir |
storage/logs |
Directory scanned for *.log files. |
driver |
none |
gemini, openai, or none (keyword-only). |
limits.entries_per_page |
200 |
Max matching entries per request. |
limits.byte_budget |
50 MB |
Max bytes scanned per request. |
redact |
true |
Mask likely PII/secrets in returned entries. |
To customize the page itself:
php artisan vendor:publish --tag=ai-log-search-views
HTTP API
All endpoints live under the configured prefix and honor the same authorization.
| Method | Endpoint | Body | Returns |
|---|---|---|---|
GET |
/files |
— | {files: [{name, size, size_human, modified}]} |
POST |
/query |
{file, prompt} |
interpreted filter, explanation, plus the first result page |
POST |
/results |
{file, filter, offset} |
{entries, next_offset, eof, file_size, scanned_bytes} |
offset is the byte position returned as next_offset by the previous page (0 = start from the end of the file). filter shape:
{
"levels": ["ERROR", "CRITICAL"],
"keywords": ["PaymentJob"],
"date_from": "2026-07-14 00:00:00",
"date_to": null
}
Security notes
- File names from the client are reduced to their base name and resolved with
realpath()inside the configured log directory — path traversal is not possible, and only*.logfiles are served. - The AI provider receives only the user's prompt and the file's date — never log contents.
- Client-supplied filters are re-validated server-side (levels are whitelisted).
Testing
composer install vendor/bin/phpunit
License
MIT — see LICENSE.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-07-14