跳转到主要内容
基本的安装与配置请参考指南页面。本文介绍官方文档没有覆盖的、在本地开发中的实战模式。 Telescope 是只用于本地开发的工具。生产环境的监控请使用 Laravel PulseLaravel Nightwatch

有条理地发现 N+1 问题

下面介绍用 Telescope 排查 N+1 的实战流程。不是简单地“注意到同样的 SELECT 反复出现”,而是把修复后的确认也串成一条完整的工作流。
1

在 Requests 中找出慢请求

打开 /telescope,在 Requests 标签中锁定执行时间较长的请求。
2

在 Queries 中查看发生的 SQL

打开请求详情,会显示该请求期间执行的所有 SQL。如果看到形状相同的 SELECT 反复出现,那就是 N+1。
3

加上 Eager Loading 修复

在代码里加 with(),再次确认查询。查询数量大幅减少就说明修复完成。
// 会发生 N+1 的代码
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->user->name; // 每个 post 都追加一条查询
}

// 用 Eager Loading 解决
$posts = Post::with('user')->get();
不用往代码里加 dd() 或日志,这一整套流程都能在浏览器里完成。

用标签追踪特定请求

Telescope 有标签功能。用 Telescope::tag() 给条目打上任意标签,再在面板的过滤器里就能快速筛出带该标签的条目。 在只想追踪特定用户 ID、订单 ID 相关的处理时非常有效。
use Laravel\Telescope\IncomingEntry;
use Laravel\Telescope\Telescope;

// 覆盖 TelescopeServiceProvider 的 tags 方法
Telescope::tag(function (IncomingEntry $entry) {
    if ($entry->type === 'request') {
        return array_filter([
            'status:' . $entry->content['response_status'],
            auth()->check() ? 'user:' . auth()->id() : null,
        ]);
    }

    return [];
});
之后在 /telescope/requests 页面的 Search 里输入 user:42,就能只看用户 ID=42 的请求。

自动给模型打标签

TelescopeServiceProvidertags 方法中,可以给所有条目附加特定模型的 ID 标签。
// TelescopeServiceProvider
Telescope::tag(function (IncomingEntry $entry) {
    return $entry->tags();
});
只要给模型实现 HasTags 契约,该模型被记录时会自动带上标签。
use Laravel\Telescope\Contracts\EntriesRepository;

class Order extends Model implements \Laravel\Telescope\Contracts\HasTags
{
    public function telescopeTags(): array
    {
        return ['order:' . $this->id];
    }
}

用好 Dump watcher

dump() 时输出可能混进 HTML 响应,导致 API 调试变得困难。Telescope 的 Dump watcher 可以把 dump() 的输出从浏览器响应里剥离,记录到面板里。 用法很简单:在 /telescope 的 “Dump” 标签保持打开,然后调用 dump() 就行。
// 控制器
public function index()
{
    $users = User::with('posts')->get();
    dump($users->first()->toArray()); // 会显示在 Telescope 的 dump 标签
    return response()->json($users);
}
只有当页面处于打开状态时才会捕获,所以按需监视即可。它不像 dd() 会让程序停下来,连续多次请求也能持续调试。

与 Mailpit 配合让邮件调试更顺手

把 Mail watcher 和本地 SMTP 服务器 Mailpit 组合起来,邮件开发流程会舒服很多。
# .env
MAIL_MAILER=smtp
MAIL_HOST=127.0.0.1
MAIL_PORT=1025
Telescope 的 Mail 标签能预览已发送邮件的 HTML 和文本两种格式。在 Mailpit 中可以在浏览器里查看已收邮件,还能看附件和垃圾评分。
为了避免测试时把邮件误发到外部,本地一定要使用 Mailpit 或 Mailhog 这类本地 SMTP。

调试事件与监听器

事件驱动的实现往往难以调试。“事件到底触发没?”、“到底哪个监听器被调用了?”光看日志追这些非常麻烦。 Telescope 的 Events watcher 会把已经派发的事件和监听器都列出来。 如果监听器没被调用,可以在 Events 标签查看事件条目。
  • 事件已派发但没有显示监听器 → 监听器没注册(检查 EventServiceProvider)
  • 事件本身就没派发 → 检查 event() 的调用点
// 在本地代替测试的确认流程
event(new OrderShipped($order));
// → 在 /telescope/events 里看 OrderShipped 是否出现
// → 确认 SendShippingConfirmation 监听器有没有被调用

调试队列作业

异步处理只靠看日志很难定位原因。Telescope 的 Jobs watcher 会记录作业从 dispatch 到执行结果的全过程。 点击失败作业的条目,能看到堆栈跟踪和异常信息。除了 queue:failed 表以外,Telescope 也能查看,排查失败原因很快。
// 调试作业时用 sync 驱动同步执行更容易追踪
// .env
QUEUE_CONNECTION=sync
改成 sync 驱动后,作业会在请求内同步执行,Requests watcher 里也能看到作业的执行结果。

调试 HTTP 客户端

调试与外部 API 的通信时,HTTP Client Watcher 很有用。它会记录通过 Http:: 门面发起的请求及其响应。
$response = Http::get('https://api.example.com/users');
// → 在 /telescope/client-requests 里可以查看
响应内容、状态码、执行时间一目了然。不需要写 dd($response->json()),直接在面板里就能看。

总结

技巧效果
N+1 工作流不需要 dd() 就能有条理地发现并修复查询问题
打标签快速筛选特定用户 / 模型的记录
Dump watcher不污染 API 响应就能确认 dump 输出
Mailpit 集成让本地邮件开发更舒服
Events watcher直观确认事件/监听器的触发
Jobs + sync用同步执行来调试异步处理
HTTP 客户端记录并查看外部 API 通信

Laravel Telescope 指南

详细的安装和 watcher 配置请参考指南页面。

Laravel Nightwatch

生产环境的监控用 Nightwatch。
最后修改于 2026年7月13日