Monitoring
Halaman ini menjelaskan sinyal apa yang diberikan PandaBear ketika application sudah berjalan, di mana sinyal tersebut muncul, dan bagian mana yang sengaja dibuat senyap. Package tidak menyediakan metrics endpoint, health route, atau audit log. Yang tersedia hanyalah tiga jenis log line, dua event, serta satu history table yang melakukan pruning sendiri. Gunakan dokumentasi ini saat menghubungkan PandaBear ke monitoring stack application, atau ketika sebuah kegagalan tidak menghasilkan sinyal yang Anda harapkan.
Contoh minimal yang berfungsi
Health check sederhana untuk dua hal yang paling sering tertinggal setelah deploy:
use Illuminate\Support\Facades\Route;
use PandaPanel\Cache\PanelManifest;
use PandaPanel\Core\PanelManager;
Route::get('/health/panel', function () {
return [
'manifest' => app(PanelManifest::class)->exists(),
'panels' => array_map(
static fn ($panel) => $panel->getId(),
app(PanelManager::class)->all(),
),
'resources' => count(app(PanelManager::class)->resources('admin')->all()),
];
});2
3
4
5
6
7
8
9
10
11
12
13
14
{"manifest":true,"panels":["admin","app"],"resources":1}Di production:
"manifest": falseberarti deploy tidak menjalankanpanel:cache;- jumlah
resourcesyang tiba-tiba turun biasanya berartipanel:cachedijalankan terhadap release/tree yang salah.
Log yang ditulis framework
PandaBear hanya menulis tiga jenis log line. Informasi lain biasanya disampaikan melalui UI kepada user.
Warning manifest stale — hanya development
[panel] The cached panel manifest is out of date: the classes under the
discovery paths have changed since `php artisan panel:cache` last ran. Until
you run `php artisan panel:clear`, anything added since then is invisible — no
route, no navigation entry, and no error to say so.2
3
4
Log ini menggunakan Log::warning dari PanelManifest::warnIfStale() dan hanya ditulis sekali per boot.
Ia tidak melakukan apa pun kecuali manifest tersedia dan environment adalah local, testing, atau debug mode aktif:
if (! app()->hasDebugModeEnabled() && ! app()->environment('local', 'testing')) {
return;
}2
3
Di production, manifest dianggap sebagai source of truth dan framework tidak seharusnya melakukan filesystem scan tambahan. Karena itu tidak ada warning stale manifest di production.
Konsekuensinya:
Deploy production yang lupa menjalankan
panel:cachedapat gagal secara senyap.
Itulah alasan validasi manifest sebaiknya ada pada deploy script atau health endpoint, bukan mengandalkan log alert.
Notice policy yang hilang — hanya development
[panel] UserResource is not in the navigation because User has no policy, so
viewAny() is denied by default. Create one with `php artisan make:policy
UserPolicy --model=User`, or say so on the resource by overriding canViewAny().
Panel::strictAuthorization() turns this into an exception everywhere the panel
asks, which is worth having in development.2
3
4
5
Log menggunakan Log::debug dari PandaPanel\Support\MissingPolicyNotice, maksimal sekali per model per process.
Notice ini juga hanya aktif di development karena Resource yang memang sengaja disembunyikan dari seluruh user adalah konfigurasi yang valid. Menghasilkan log pada setiap deploy untuk kondisi yang disengaja justru menambah noise.
API:
use PandaPanel\Support\MissingPolicyNotice;
MissingPolicyNotice::expectedPolicy(App\Models\User::class); // 'App\Policies\UserPolicy'
MissingPolicyNotice::forget(); // hanya untuk test2
3
4
Untuk development, Anda dapat membuat missing policy menjadi exception:
use PandaPanel\Core\Panel;
Panel::make('admin')->strictAuthorization();2
3
Warning integration gagal — seluruh environment
Log::warning('Panel integration failed.', [
'integration' => $integration->id,
'resource' => $integration->resource,
'trigger' => $integration->trigger->value,
'delivery' => $deliveryId,
'exception' => $exception->getMessage(),
]);2
3
4
5
6
7
Ini adalah satu-satunya log yang sengaja tetap ditulis di production.
Warning muncul jika outbound integration request melempar exception, misalnya:
- DNS failure;
- connection refused;
- TLS failure.
HTTP response non-2xx tidak dianggap exception. Kondisi tersebut disimpan di delivery history, tetapi tidak menghasilkan warning ini.
Exception ditangkap agar kegagalan integration tidak membatalkan record yang sedang disimpan. DNS failure bukan alasan agar domain record utama gagal dibuat.
Alert dapat dibuat berdasarkan message/context:
// Filter log channel atau Sentry berdasarkan message
'Panel integration failed.'2
Delivery history
Setiap delivery attempt menghasilkan satu row di:
panel_integration_deliveriesAPI:
use PandaPanel\Integrations\PanelIntegrationDelivery;
PanelIntegrationDelivery::enabled(); // static enabled(): bool
PanelIntegrationDelivery::prune(42); // static prune(int $integrationId): void
PanelIntegrationDelivery::BODY_LIMIT; // 20002
3
4
5
| Column | Isi |
|---|---|
integration_id | integration yang dijalankan |
trigger | case enum Trigger yang memicunya |
method, url | request yang dikirim |
delivery_id | ID per delivery; seluruh retry dari delivery yang sama menggunakan ID yang sama |
status | HTTP status, atau null jika request melempar exception |
duration_ms | durasi request |
error | exception message atau body non-2xx yang sudah dipotong |
request_body, response_body | body yang dipotong maksimal BODY_LIMIT |
attempted_at | waktu attempt |
Header tidak pernah disimpan. Header dapat mengandung API key/credential. Menyimpannya akan mengubah history table menjadi credential store yang tidak pernah dimaksudkan.
History melakukan pruning sendiri setelah setiap delivery. Tidak dibutuhkan scheduler.
| Batas | Config key | Default |
|---|---|---|
| Maksimum row per integration | integrations.history.keep_per_integration | 50 |
| Retention window | integrations.history.retention_days | 30 |
| Matikan history | integrations.history.enabled | true |
// config/panda-panel.php
'integrations' => [
'history' => [
'enabled' => true,
'keep_per_integration' => 50,
'retention_days' => 30, // 0 berarti hanya cap yang berlaku
],
],2
3
4
5
6
7
8
Hard cap memastikan ukuran table selalu dibatasi oleh:
keep_per_integration × jumlah integrationsbahkan pada application tanpa scheduler.
retention_days menjadi batas kedua bagi integration yang sangat jarang dipanggil agar row lama tidak tersimpan bertahun-tahun.
Event yang dapat didengarkan
Ada dua event. Keduanya ShouldBroadcast dan Dispatchable, sehingga listener application tetap dapat menerimanya walaupun broadcaster tidak tersedia.
use Illuminate\Support\Facades\Event;
use PandaPanel\Notifications\PanelNotificationSent;
Event::listen(PanelNotificationSent::class, function (PanelNotificationSent $event): void {
// $event->user Authenticatable
// $event->payload array<string, mixed>
});2
3
4
5
6
7
| Event | Constructor | Broadcast as |
|---|---|---|
PandaPanel\Notifications\PanelNotificationSent | (Authenticatable $user, array $payload) | panel.notification |
PandaPanel\Broadcasting\PanelNotification | (Authenticatable $user, string $message, string $type = 'info', ?string $url = null, ?string $urlLabel = null) | panel.notification |
Yang di-queue hanya proses broadcast websocket.
Notification::send() dispatch event melalui event(), sehingga listener biasa dijalankan synchronously pada request/job yang mengirim notification. Karena event menggunakan ShouldBroadcast, websocket delivery-nya yang masuk queue, bukan seluruh listener.
Artinya listener untuk metrics tetap berjalan meskipun queue worker tidak tersedia.
Tidak ada lifecycle event untuk:
- Panel boot;
- Resource registration;
- navigation build;
- setiap request.
Sinyal queue dan job
Job PandaBear adalah job Laravel biasa dan dapat dimonitor menggunakan tooling yang sudah digunakan application:
php artisan queue:failed
php artisan queue:monitor default:1002
| Job | $tries | Ketika final failure |
|---|---|---|
PandaPanel\Jobs\RunPanelExport | 3 | mengirim persistent notification ke owner dengan exception message |
PandaPanel\Jobs\RunPanelImport | 1 | menghapus upload kemudian mengirim notification dengan exception message |
PandaPanel\Jobs\SendPanelIntegration | 3 | tidak ada message user-facing; attempt tetap ada di delivery history |
Notification kegagalan yang dilihat satu user bukan pengganti monitoring operational. Untuk operator, monitor failed_jobs. Lihat Queues.
Apa yang dilihat user ketika request gagal
HTTP failure di dalam Panel diterjemahkan menjadi notification daripada blank screen.
Default:
| Status | Title | Body |
|---|---|---|
403 | Not allowed | You do not have permission to do that. |
404 | Not found | That record no longer exists. |
419 | Session expired | Refresh the page and try again. |
429 | Too many requests | Wait a moment and try again. |
500 | Something went wrong | The request could not be completed. |
503 | Temporarily unavailable | The application is down for maintenance. |
use PandaPanel\Core\Panel;
$panel->getErrorNotifications(); // array<int, array{title: string, body: string|null}|null>2
3
Custom error notification milik Panel di-merge di atas default framework. Override satu status tidak mewajibkan developer mendefinisikan seluruh status lain.
Ini adalah message untuk user, bukan log. Exception tetap diproses oleh exception handler application.
Membuat health check
Tiga pertanyaan murah yang layak dijawab probe:
use PandaPanel\Cache\PanelManifest;
use PandaPanel\Core\PanelManager;
use PandaPanel\Support\BroadcastSupport;
app(PanelManifest::class)->exists(); // apakah release ini memiliki Panel manifest
BroadcastSupport::isConfigured(); // apakah broadcaster tersedia
app(PanelManager::class)->get('admin')->getPath(); // apakah Panel ter-register2
3
4
5
6
7
Route cache:
use Illuminate\Support\Facades\Route;
Route::has('panel.admin.dashboard'); // apakah route cache berisi Panel ini2
3
Health endpoint sebaiknya diproteksi. Daftar Panel id dan jumlah Resource merupakan peta struktur application dan tidak perlu diekspos publik.
Hal yang sengaja tidak disediakan
| Tidak disediakan | Alasan |
|---|---|
| Metrics endpoint | queue depth, latency, dan error rate seharusnya berasal dari monitoring application yang sudah ada |
| Audit log generic | siapa mengubah apa adalah domain concern; generic audit log sering salah untuk schema yang berbeda |
| Warning production untuk stale manifest | membutuhkan filesystem stat terhadap discovery path; biaya tersebut sengaja tidak dibayar di production |
Output khusus di php artisan about | laporan plugin tersedia melalui panel:plugins |
| Penyimpanan integration headers | berpotensi menyimpan credential |
Informasi yang berguna saat membuat bug report
php artisan panel:plugins
php artisan panel:plugins --panel=admin2
Contoh:
+-------+---------+-----------+------------------+---------+----------+
| Panel | ID | Name | Package | Version | Requires |
+-------+---------+-----------+------------------+---------+----------+
| admin | audit | Audit Log | acme/panel-audit | 1.4.1 | ^0.1 |
+-------+---------+-----------+------------------+---------+----------+2
3
4
5
Satu Panel dapat mendapatkan Resource, Page, Widget, dan route dari beberapa plugin. Ketika behavior bermasalah, dua pertanyaan awal biasanya:
plugin mana?
versi berapa?2
Versi dibaca dari metadata Composer yang benar-benar ter-install, bukan version constant buatan plugin.
Hal yang perlu diperhatikan
- Production sengaja lebih senyap. Dua dari tiga jenis log hanya aktif di development. Resource yang hilang dari production dapat tidak menghasilkan log; health check adalah sinyalnya.
APP_DEBUG=truedi production mengaktifkan fingerprint/staleness check, sehingga filesystem harus melakukanstatterhadap file di discovery path pada setiap boot.- Integration warning hanya muncul untuk exception, bukan response 4xx/5xx. Webhook yang selalu mengembalikan 500 dicatat di delivery history tetapi tidak menulis warning tersebut.
- Delivery history dibatasi count terlebih dahulu. Menaikkan
retention_daystidak menambah row jika hard cap sudah memangkasnya. - Pada
PanelNotificationSent, hanya broadcast yang di-queue. Listener biasa untuk metrics dijalankan synchronously. - Unread notification count menangkap
QueryExceptiondan fallback ke0. Missingnotificationstable tidak membuat seluruh Panel 500; gejalanya adalah bell selalu kosong.
Lihat juga
- Production checklist, Queues, Broadcasting server
- Panel cache, Rollbacks
- Caching, Authorization
- Configuration reference — block
integrations, termasuk history bounds panel:plugins- Notifications, Database notifications