feat(logging): Implement database logging with app_log table

- Created migration to set up app_log table for storing application logs.
- Added AppLog entity and repository for ORM handling of logs.
- Developed DbLogger service to persist logs of level WARNING and above to the database while maintaining existing logging behavior.
- Implemented tests for admin log retrieval and DbLogger functionality to ensure proper logging behavior.
- Enhanced logging context sanitization for better error tracking.
This commit is contained in:
hamed
2026-06-29 20:01:03 +03:30
parent 830f7e8d0c
commit 803196108c
38 changed files with 3284 additions and 618 deletions
+50
View File
@@ -1078,3 +1078,53 @@ Reject a pending request. **Permission:** `ROLE_ADMIN`
تأیید/رد از طریق `POST /api/v1/settlement/{uuid}/approve|reject` (در `docs/api/settlement.md`).
**Errors:** `NOT_FOUND` (404) — درخواست یافت نشد.
---
## Application Logs
Persisted application logs (`warning` level and above). Written by the `DbLogger`
decorator over the `logger` service into the `app_log` table — every
`LoggerInterface::warning()/error()/critical()/...` call across the backend lands
here, while `info`/`debug` go to stderr only.
### GET `/api/v1/admin/logs`
List persisted logs with pagination and filters.
**Permission:** `ROLE_ADMIN`
### Query Parameters
| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `page` | integer | ❌ | Default: 1 |
| `limit` | integer | ❌ | Default: 25 (max 100) |
| `level` | string | ❌ | Exact PSR level: `warning`, `error`, `critical`, `alert`, `emergency` |
| `search` | string | ❌ | Substring match on the message |
| `from` | integer | ❌ | Unix timestamp lower bound (`created_at >=`) |
| `to` | integer | ❌ | Unix timestamp upper bound (`created_at <=`) |
Ordered by newest first (`id DESC`).
### Response `200`
```json
{
"success": true,
"data": [
{
"id": 4213,
"level": "error",
"message": "Unhandled exception: RuntimeException: boom @ /var/www/html/src/Foo.php:42 [path=/oauth/userinfo]",
"context": "{\"exception\":\"RuntimeException: boom @ /var/www/html/src/Foo.php:42\"}",
"channel": "app",
"path": "/oauth/userinfo",
"created_at": 1717000000
}
],
"meta": { "totalRecords": 137, "totalPages": 6, "currentPage": 1 }
}
```
Notes:
- `context` is a JSON string (or `null`); a `Throwable` in the context is stored as a compact `Class: message @ file:line` string, never the raw object.
- `created_at` is a Unix timestamp (integer).