Laravel Telescope: شاهد ما يحدث داخل تطبيقك
دليل عملي لتثبيت Laravel Telescope واستخدامه في تتبع Requests وQueries وJobs وExceptions وCache وEvents، مع إعداد آمن للبيئات المحلية والإنتاج.

Laravel Telescope: شاهد ما يحدث داخل تطبيقك
الـ API شغال ويرجع النتيجة المطلوبة… لكن إيش اللي صار فعلًا خلف الكواليس؟
كم Query تنفذت؟ ليش الـ request أخذ وقتًا طويلًا؟ هل الـ job وصل إلى الـ queue أو فشل؟ وهل البيانات جاءت من الـ cache أم من قاعدة البيانات؟
ممكن تبحث في ملفات الـ logs وتضيف dd() في أكثر من مكان، لكن كل أداة منها تعرض جزءًا صغيرًا من الصورة. هنا يجي دور Laravel Telescope.
Telescope أداة رسمية من Laravel تسجل ما يحدث داخل التطبيق وتعرضه في dashboard واحدة: Requests وQueries وJobs وExceptions وLogs وCache وEvents وMail وغيرها. فائدتها الأساسية ليست أنها تخبرك فقط أن هناك خطأ، بل تساعدك تربط الأحداث ببعضها وتفهم مسار التنفيذ كاملًا.
متى يفيدك Laravel Telescope؟
Telescope ممتاز أثناء التطوير وعند تشخيص مشكلة محددة، خصوصًا في هذه الحالات:
- endpoint يعمل لكن استجابته بطيئة.
- صفحة تنفذ عددًا غير منطقي من Queries أو تعاني من مشكلة N+1.
- Job لا يعمل كما توقعت أو يفشل داخل الـ queue.
- Exception تظهر أحيانًا وتحتاج stack trace وبيانات الطلب المرتبطة بها.
- Cache key لا يُقرأ أو لا يتم تحديثه في الوقت المتوقع.
- Event انطلق، لكنك غير متأكد من الـ listeners التي تعاملت معه.
- طلب HTTP خارجي إلى خدمة أخرى بطيء أو يرجع خطأ.
هو أداة debugging عميقة لكل عملية، وليس بديلًا كاملًا عن نظام monitoring وتنبيهات طويل المدى. في الإنتاج استخدمه بحذر وبسياسة تسجيل واضحة؛ لأن البيانات قد تكبر بسرعة وقد تحتوي تفاصيل حساسة.
تثبيت Laravel Telescope
للتثبيت العادي نفّذ:
composer require laravel/telescope
php artisan telescope:install
php artisan migrate
الأمر telescope:install ينشر ملف الإعدادات والـ migrations وينشئ TelescopeServiceProvider. بعد تشغيل الـ migrations افتح:
http://your-app.test/telescope
ستظهر لك لوحة Telescope، وأي request جديد داخل التطبيق سيبدأ بالظهور فيها.
تثبيته في البيئة المحلية فقط
إذا كان هدفك استخدام Telescope أثناء التطوير فقط، ثبّته كـ dev dependency:
composer require laravel/telescope --dev
php artisan telescope:install
php artisan migrate
لكن --dev وحدها لا تكفي. بعد التثبيت احذف تسجيل App\Providers\TelescopeServiceProvider من bootstrap/providers.php، ثم سجّل الـ providers فقط عندما تكون البيئة local داخل AppServiceProvider:
public function register(): void
{
if (
$this->app->environment('local') &&
class_exists(\Laravel\Telescope\TelescopeServiceProvider::class)
) {
$this->app->register(\Laravel\Telescope\TelescopeServiceProvider::class);
$this->app->register(TelescopeServiceProvider::class);
}
}
وأوقف auto-discovery للحزمة في composer.json:
{
"extra": {
"laravel": {
"dont-discover": [
"laravel/telescope"
]
}
}
}
بهذا لا يحاول production تحميل كلاس موجود فقط ضمن require-dev.
جولة سريعة داخل الـ dashboard
بعد فتح /telescope ستجد أقسامًا متعددة. لا تحتاج تتعلمها كلها من البداية؛ ابدأ بالقسم المرتبط بالمشكلة التي تبحث عنها.
Requests: افهم الطلب كاملًا
يعرض Request Watcher معلومات مثل:
- HTTP method والمسار والـ status code.
- مدة تنفيذ الطلب والذاكرة المستخدمة.
- headers وpayload وsession وresponse.
- المستخدم المرتبط بالطلب إن وجد.
- Queries وEvents وJobs وبقية entries التي حدثت ضمن نفس الطلب.
لو endpoint بطيء، افتح الـ request ثم راجع الـ Queries والـ HTTP calls المرتبطة به. غالبًا ستجد أن المشكلة ليست في الـ controller نفسه، بل في query تتكرر أو خدمة خارجية استغرقت وقتًا طويلًا.
Queries: اكتشف البطء وN+1
Query Watcher يسجل SQL والـ bindings ومدة التنفيذ. افتراضيًا يضع tag باسم slow على أي query تتجاوز 100ms، وتستطيع تغيير الحد في config/telescope.php:
use Laravel\Telescope\Watchers;
'watchers' => [
Watchers\QueryWatcher::class => [
'enabled' => env('TELESCOPE_QUERY_WATCHER', true),
'slow' => 50,
],
],
لا تنظر فقط إلى أبطأ query. راقب أيضًا عدد مرات التكرار. Query تستغرق 5ms لكنها تتكرر 200 مرة قد تكون أسوأ من query واحدة تستغرق 80ms.
مثال شائع:
$orders = Order::latest()->get();
foreach ($orders as $order) {
echo $order->customer->name;
}
لو علاقة customer لم تُحمّل مسبقًا، سترى query إضافية لكل order. ظهور النمط بوضوح داخل Telescope يقودك إلى استخدام eager loading:
$orders = Order::with('customer')->latest()->get();
بعد التعديل أعد الطلب وقارن عدد الـ Queries وزمن التنفيذ بدل الاعتماد على الإحساس.
Jobs: هل وصلت المهمة وهل فشلت؟
Job Watcher يعرض الـ jobs التي تم dispatch لها، الاتصال والـ queue المستخدمة، حالتها، وقت التنفيذ، والمحاولات. لو فشلت المهمة تستطيع الانتقال إلى الـ exception والـ stack trace المرتبطين بها.
انتبه إلى نقطة مهمة: إذا كنت تستخدم queue فعلية، يجب أن يكون الـ worker شغالًا حتى تُنفذ المهمة:
php artisan queue:work
ظهور job كـ pending لا يعني دائمًا أن الكود داخلها معطّل؛ أحيانًا المشكلة ببساطة أن worker متوقف أو يستمع إلى queue مختلفة.
Exceptions وLogs: من الخطأ إلى سببه
Exception Watcher يحتفظ برسالة الخطأ والـ stack trace ومكان حدوثه، ويربطه بالـ request أو job ذات الصلة. أما Log Watcher فيعرض رسائل الـ log المسجلة من التطبيق.
في الإصدارات الحالية يسجل Telescope افتراضيًا logs من مستوى error فأعلى. لو احتجت تفاصيل أكثر محليًا، غيّر المستوى:
Watchers\LogWatcher::class => [
'enabled' => env('TELESCOPE_LOG_WATCHER', true),
'level' => 'debug',
],
لا تترك مستوى debug يعمل بلا حاجة في بيئة مزدحمة؛ كمية البيانات ستزيد بسرعة.
Cache وEvents وHTTP Client
Cache Watcher يوضح هل حدث hit أو miss أو write أو forget للمفتاح. هذا مفيد عندما تتوقع بيانات مخزنة لكن التطبيق يستمر بالرجوع إلى قاعدة البيانات.
Event Watcher يعرض event والـ payload والـ listeners وبيانات الـ broadcast. أما HTTP Client Watcher فيعرض الطلبات الخارجية التي ينفذها Laravel HTTP client، ويساعدك تعرف هل البطء داخل تطبيقك أو في API خارجي.
تشغيل وإيقاف الـ Watchers
كل watcher يجمع نوعًا مختلفًا من البيانات، وتستطيع التحكم به من config/telescope.php:
'watchers' => [
Watchers\CacheWatcher::class => env('TELESCOPE_CACHE_WATCHER', true),
Watchers\EventWatcher::class => env('TELESCOPE_EVENT_WATCHER', true),
Watchers\JobWatcher::class => env('TELESCOPE_JOB_WATCHER', true),
Watchers\QueryWatcher::class => [
'enabled' => env('TELESCOPE_QUERY_WATCHER', true),
'slow' => 100,
],
],
لا توجد فائدة من تسجيل كل شيء دائمًا. إذا كان watcher لا يخدم احتياجك، عطّله لتقليل التخزين والـ overhead. ويمكنك إيقاف Telescope كاملًا من خلال:
TELESCOPE_ENABLED=false
لا تسجل البيانات الحساسة
Telescope قد يسجل headers وrequest payload وsession وresponse. لذلك راجع دالة hideSensitiveRequestDetails() داخل TelescopeServiceProvider وأضف الحقول الخاصة بمشروعك:
protected function hideSensitiveRequestDetails(): void
{
Telescope::hideRequestParameters([
'_token',
'password',
'password_confirmation',
'credit_card_number',
]);
Telescope::hideRequestHeaders([
'authorization',
'cookie',
'x-csrf-token',
'x-xsrf-token',
]);
}
الأسماء تعتمد على مشروعك. راجع login وpayments وwebhooks وأي endpoint يستقبل tokens أو معلومات شخصية قبل استخدام Telescope خارج جهازك.
استخدام Telescope في production بأمان
الأفضل غالبًا أن تبدأ به محليًا. لكن لو احتجته في production لتشخيص مشكلة، لا تفتح /telescope للجميع.
داخل TelescopeServiceProvider يوجد Gate باسم viewTelescope. اجعله يسمح فقط لمستخدمين محددين:
use App\Models\User;
use Illuminate\Support\Facades\Gate;
protected function gate(): void
{
Gate::define('viewTelescope', function (User $user) {
return in_array($user->email, [
'admin@example.com',
], true);
});
}
وتأكد أن APP_ENV=production مضبوط فعلًا. إعداد البيئة بشكل خاطئ قد يجعل Laravel يتعامل مع التطبيق كبيئة محلية ويسمح بوصول غير مقصود.
كذلك لا تسجل كل التفاصيل في production. الإعداد الافتراضي داخل الـ provider يسجل البيانات المهمة فقط خارج local، مثل exceptions وfailed jobs وscheduled tasks وslow queries والـ entries ذات monitored tags:
Telescope::filter(function (IncomingEntry $entry) {
if ($this->app->environment('local')) {
return true;
}
return $entry->isReportableException()
|| $entry->isFailedJob()
|| $entry->isScheduledTask()
|| $entry->isSlowQuery()
|| $entry->hasMonitoredTag();
});
عدّل الفلتر حسب احتياجك، لكن لا تجعل Telescope يجمع كل request في تطبيق مزدحم إلا إذا كنت تعرف تكلفة ذلك وحددت مدة قصيرة للتشخيص.
نظّف البيانات القديمة
Telescope يخزن بياناته في قاعدة البيانات، والجداول قد تكبر بسرعة. أضف أمر التنظيف إلى routes/console.php:
use Illuminate\Support\Facades\Schedule;
Schedule::command('telescope:prune --hours=48')->daily();
ثم تأكد أن Laravel Scheduler يعمل على السيرفر. من دون تشغيل الـ scheduler لن يتم تنفيذ أمر التنظيف حتى لو كتبته في الكود.
القيمة 48 تعني الاحتفاظ بآخر 48 ساعة. اختر مدة تناسب حجم التطبيق وسبب استخدامك لـ Telescope.
خطوات عملية لتشخيص request بطيء
لو عندك endpoint بطيء، جرّب هذا التسلسل:
- امسح أو تجاهل entries القديمة حتى تكون المقارنة واضحة.
- نفّذ request واحدًا بنفس المدخلات التي تسبب المشكلة.
- افتحه في قسم Requests وسجّل مدة التنفيذ.
- راجع Queries: العدد، المدة، التكرار، والـ slow tags.
- راجع HTTP Client لأي خدمة خارجية بطيئة.
- تحقق من Cache لمعرفة هل البيانات أصابت المفتاح أم حصل miss.
- راجع Jobs وEvents التي أطلقها الطلب.
- عدّل سببًا واحدًا، ثم أعد نفس request وقارن النتيجة.
هذه المقارنة أهم من مجرد فتح Telescope والنظر إلى الأرقام. الهدف أن تنتقل من "الـ API بطيء" إلى سبب محدد تستطيع قياسه وإصلاحه.
الخلاصة
Laravel Telescope يحول ما يحدث خلف الكواليس إلى معلومات تستطيع فحصها: request كامل، Queries ومدة كل واحدة، Jobs وحالتها، Exceptions، Cache، Events، وطلبات HTTP الخارجية.
ابدأ به محليًا، فعّل فقط الـ watchers التي تحتاجها، أخفِ البيانات الحساسة، وقارن قبل الإصلاح وبعده. وإذا استخدمته في production، قيّد الوصول وفلتر التسجيل ونظّف البيانات بشكل دوري.
للتفاصيل والخيارات الكاملة راجع توثيق Laravel Telescope الرسمي.