Mengimplementasi observabilitas untuk aplikasi NativePHP: crash reporting native iOS/Android, error tracking PHP via Sentry/Bugsnag, log shipping dari perangkat, release health metrics (crash-free rate), dan alerting untuk respons cepat terhadap issue production.

Setelah di episode 23 kita mengoptimalkan performa, pada episode ini kita pasang observabilitas pada aplikasi: crash reporting, error tracking, dan monitoring. Di production, kalian tidak bisa duduk di samping user untuk melihat apa yang terjadi — monitoring tools adalah "mata dan telinga" kalian di perangkat user.
NativePHP memiliki dua lapisan yang perlu dimonitor: native shell (Swift/Kotlin) dan PHP runtime (Laravel). Keduanya bisa crash atau error secara terpisah, jadi monitoring harus mencakup keduanya.
iOS menyediakan crash report bawaan, tapi lebih baik menggunakan SDK pihak ketiga untuk analysis yang lebih kaya:
import Sentry
@objc class AppDelegate: NSObject {
func applicationDidFinishLaunching() {
SentrySDK.start { options in
options.dsn = "https://YOUR_DSN@sentry.io/PROJECT_ID"
options.tracesSampleRate = 1.0
options.attachScreenshot = true
options.enableAppHangTracking = true
}
}
}import com.google.firebase.crashlytics.FirebaseCrashlytics
class NativePHPApplication : Application() {
override fun onCreate() {
super.onCreate()
FirebaseCrashlytics.getInstance().apply {
setCrashlyticsCollectionEnabled(true)
setCustomKey("php_version", "8.3")
setCustomKey("nativephp_version", "4.2.0")
}
}
}Sentry juga mendukung PHP — menangkap exception PHP dan mengirimkannya ke dashboard:
composer require sentry/sentry-laravel<?php
return [
'dsn' => env('SENTRY_DSN'),
'traces_sample_rate' => 1.0,
'environment' => env('APP_ENV', 'production'),
'release' => env('APP_VERSION', '1.0.0'),
'send_default_pii' => false,
];<?php
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Log;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
// Log semua error ke Sentry
if (app()->bound('sentry')) {
Log::error('Error message', [
'extra' => ['key' => 'value'],
]);
}
}
}<?php
use Sentry\Laravel\Integration;
try {
// Operasi yang mungkin gagal
$result = riskyOperation();
} catch (\Exception $e) {
Integration::captureException($e);
Log::error("Operation failed: {$e->getMessage()}");
}Log dari perangkat perlu dikirim ke server sentral untuk analysis:
<?php
return [
'channels' => [
'remote' => [
'driver' => 'monolog',
'handler' => \App\Logging\RemoteLogHandler::class,
'level' => 'info',
],
],
];<?php
namespace App\Logging;
use Monolog\Handler\AbstractProcessingHandler;
use Illuminate\Support\Facades\Http;
class RemoteLogHandler extends AbstractProcessingHandler
{
protected function write(array $record): void
{
Http::post('https://api.myapp.com/logs', [
'level' => $record['level'],
'message' => $record['message'],
'context' => $record['context'],
'device_id' => getDeviceId(),
'app_version' => config('app.version'),
'timestamp' => $record['time']->toIso8601String(),
]);
}
}Warning
Jangan kirim log terlalu sering atau di background saat device idle — ini menguras baterai. Batch log dan kirim saat online atau dalam interval minimal 5 menit.
Release health mengukur kualitas setiap versi aplikasi:
| Metric | Target | Deskripsi |
|---|---|---|
| Crash-free rate | > 99.5% | Persentase sesi tanpa crash |
| ANR-free rate | > 99.9% | Persentase sesi tanpa ANR |
| Error-free rate | > 99% | Persentase sesi tanpa error |
| User impact | < 0.1% | Persentase user terdampak |
<?php
use Illuminate\Support\Facades\Http;
Route::get('/api/release-health', function () {
return Http::get('https://sentry.io/api/0/organizations/{org}/releases/')
->json();
});Konfigurasi alert di Sentry Dashboard:
<?php
use Illuminate\Support\Facades\Http;
function sendAlert(string $title, string $message): void
{
Http::post(config('services.discord.webhook'), [
'content' => "**{$title}**\n{$message}",
]);
}
// Trigger saat error rate tinggi
sendAlert(
'NativePHP Error Spike',
"Error rate: 5.2% (threshold: 1%). Check Sentry dashboard."
);# Install
composer require sentry/sentry-laravel
# Publish config
php artisan vendor:publish --provider="Sentry\Laravel\ServiceProvider" --tag=config
# Set DSN di .env
echo "SENTRY_DSN=https://YOUR_DSN@sentry.io/PROJECT_ID" >> .env
# Test — trigger error
php artisan tinker
>>> throw new \Exception("Test error for Sentry");Cek Sentry Dashboard — error harus muncul dengan stack trace, breadcrumbs, dan context device.
Inti yang harus dibawa pulang:
Di episode 25 selanjutnya, kita akan membahas Capstone End-to-End — membangun aplikasi produksi lengkap (task manager/POS): login biometrik, data offline SQLite, push notification, sinkronisasi ke backend, UI SuperNative native, dan dirilis ke TestFlight + Play internal testing. Sampai jumpa di episode 25!