现已发布!阅读关于 11 月新增功能和修复的内容。

引入日志点(Logpoints)和自动附加(auto-attach)功能

2018年7月12日 Kenneth Auchenberg, @auchenberg

在过去的几个月里,我们一直忙于改进 Visual Studio Code 中的调试体验。在这篇文章中,我将讨论我们如何思考调试、展示我们从用户那里听到的反馈,并解释我们为使 VS Code 中的调试更轻松、更简单而采取的步骤。

从 VS Code 诞生之初,我们就集成了调试体验,因为我们认为调试应该是您编写和编辑源代码的地方(即您的编辑器)不可或缺的一部分。

VS Code debugger

VS Code 的调试体验由一个通用的调试器 UI 提供支持,该 UI 通过调试适配器协议 (DAP) 与我们称之为调试适配器 (DA) 的特定类型 VS Code 扩展进行通信。DA 与真正的调试器通信,并在 DAP 与调试器运行时特定的调试协议或 API 之间进行转换。

这意味着 VS Code 的核心与特定的调试器完全解耦,并且这种架构允许 VS Code 调试任何东西,只要有可用的调试适配器,如下图所示


VS Code debugging architecture


观察和痛点

如今,有一大群满意的开发者经常使用 VS Code 进行调试,但是,作为我们使命的一部分,我们希望让调试更容易,并为更多的开发者所用。

为此,我们开始对话,以更好地了解 VS Code 中调试的痛点,并了解为什么有些开发者根本不使用我们的调试器。

以下是我们的观察结果

调试配置难以正确设置

VS Code 是一个带有通用调试器的通用编辑器,它不针对特定的堆栈或运行时进行专业化。因此,我们无法提供一个适用于所有人的有主见的默认调试配置。

这意味着 VS Code 要求您配置调试器设置,并指定如何使用正确的参数等来启动运行时。

我们认识到这可能很难正确设置,但我们看不到彻底消除所有人的调试配置的方法。然而,我们确实相信调试配置可以简化,并且可以根据上下文减少到最低限度。

稍后我会回到这个问题。

启动(launch)和附加(attach)配置之间的混淆

在 VS Code 中,我们有两个核心调试概念:启动(Launch)附加(Attach),它们处理两种不同的工作流和开发者群体。根据您的工作流,了解哪种类型的配置适合您的项目可能会令人困惑。

如果您来自浏览器开发者工具背景,您不习惯“从工具启动”的概念,因为您的浏览器实例已经打开。当您打开开发者工具时,您只是将开发者工具附加到您打开的浏览器标签页。另一方面,如果您来自 Java 背景,让您的编辑器为您启动 Java 进程,并且您的编辑器自动将其调试器附加到新启动的进程是很正常的。

解释启动附加之间区别的最佳方式是,将启动配置视为在 VS Code 附加到应用程序之前如何以调试模式启动应用程序的“食谱”,而附加配置则是如何将 VS Code 的调试器连接到已经运行的应用程序或进程的“食谱”。

启动配置的价值在于,通过创建可重复并与您的项目和团队共享的配置,它们提供了一种方法来减轻使用正确的调试参数启动应用程序的认知开销。

然而,当我们与开发者讨论他们如何启动应用程序时,我们看到了一个模式并做出了一个重要的观察

观察:许多使用 VS Code 的开发者非常喜欢集成终端(Integrated Terminal),并依赖命令行工具来启动他们的应用程序。对许多人来说,在终端中运行命令,然后从编辑器附加调试器是一种更自然的工作流。这类似于浏览器启动后打开开发者工具。

这个观察是关键,我们意识到许多用户不想要一个完整的“神奇”启动体验在他们的编辑器中。他们希望将编辑器作为编辑和调试源代码的地方,并使用终端来启动应用程序、运行构建脚本等。这也是为什么我们在 VS Code 中提供集成终端体验的原因之一,因为我们相信一个好的功能 UI 应该与终端共存并良好集成。

许多开发者不使用断点,因为他们在检查状态变化

在观察开发者如何调试他们的应用程序时,我们还看到了另一个有趣的模式:使用日志记录代替断点。

用于调试的日志记录并不是一个新概念,但观察结果很重要

观察:传统的调试工作流最关注于减慢执行速度以检查程序逻辑,而日志记录工作流通常涉及检查程序状态及其在应用程序正常执行期间如何变化。这里的基本观察是,这两种技术用于不同的调试目的。

这个观察结果对于 JavaScript 开发者尤其相关,他们主要处理管理状态的复杂性,这可能解释了为什么大多数 JavaScript 开发者仍然喜欢在源代码中添加 console.log 而不是使用脚本调试器。

自动附加到 Node 进程

在反思一些开发者如何使用集成终端来启动他们的调试会话时,我们看到了一个独特的机会。通过利用我们在 VS Code 内部从您的编辑器和集成终端获得的上下文信息,我们可以检测您的上下文并推断您的调试意图,这可以为 Node.js 开发者提供更简单的调试体验。

因此,在 VS Code 的三月迭代中,我们发布了一个名为Node 自动附加(Auto Attach for Node)的新功能,它使 Node 调试器能够自动附加到从 VS Code 集成终端以调试模式启动的 Node.js 进程。

您可以通过在命令面板中运行 Debug: Toggle Auto Attach 命令来启用自动附加,激活后您也可以从状态栏切换自动附加。


Auto attach


此功能完全消除了任何调试配置,因为我们将任何以 node --inspect 启动的 Node.js 进程解释为调试意图。当与集成终端结合使用时,它是一种更简单的调试体验,允许开发者以自己的方式启动应用程序,同时消除了调试配置!🎉

NPM 脚本和调试

许多 Node.js 开发者依赖 npm 脚本来启动应用程序或开始调试会话,我们在这方面也有一些好消息:自动附加也适用于 npm 脚本。如果您运行 npm run debug 并且 "debug" 脚本是 "node --inspect" 或任何包含 --inspect 的其他命令,那么自动附加将检测到它并附加调试器 🎉

我们还认识到一些开发者希望以更直观的方式查找和运行他们的 npm 脚本,因此在 2018 年 4 月的迭代中,我们添加了一个新的 NPM 脚本资源管理器,允许您直接从 UI 浏览和运行您的 NPM 脚本。作为我们简化调试配置工作的一部分,我们还使得可以直接从资源管理器开始 Node.js 调试,而无需创建调试配置。

如果您有一个包含调试参数(如 --inspect)的 npm 脚本,我们将自动检测到这一点,并提供一个启动调试器的调试操作,如下图所示

NPM scripts

引入日志点(Logpoints)

基于日志记录是一种重要的调试技术的认识,我们看到了将状态检查添加到我们现有调试体验中的机会。在 VS Code 的三月迭代中,我们发布了我们称之为日志点(Logpoints)的调试功能的首次实现。

日志点是一种断点变体,它不会“中断”到调试器中,而是将消息记录到控制台。

Logpoints

日志点的概念并不新鲜,在过去几年中,我们在诸如 Visual StudioEdge DevToolsGDB 等工具中看到了这种概念的不同形式,名称包括 Tracepoints 和 Logpoints

为什么以及何时使用日志点?

日志点基于这样的观察:在许多情况下,您不想停止应用程序特定部分的执行,而是想检查状态在应用程序生命周期中如何变化。

日志点允许您在应用程序逻辑中“按需注入”日志记录语句,就像您在启动应用程序之前添加了日志记录语句一样。日志点是在执行时注入的,不会保留在源代码中,因此您无需提前计划,可以在需要时注入日志点。另一个好处是,您不必担心在调试完成后清理源代码。

对于 JavaScript 开发者来说,这意味着您不必再担心留下 console.logs –– 只需使用日志点!更好的是,您可以结合使用 console.log 和日志点。如果您在一个已经有 console.logs 的源代码块中插入一个日志点,您将在调试控制台中看到两种类型的日志记录语句。

云环境中的日志点

日志点在云环境中(或任何远程环境中)特别有用,因为它们使您无需重新部署应用程序即可将日志记录注入到远程环境中。同样重要的是,您不会使用日志点停止脚本执行,因此您的用户不会受到影响,这与在常规断点处停止正在运行的应用程序不同。

您可以在此处阅读有关如何在 Azure 上将日志点用于 Node.js 的更多信息

支持的语言

自 VS Code 中首次发布日志点以来,我们看到 VS Code 调试适配器的采用率不断增长,如今以下语言支持日志点

VS Code 中的日志点

如果您有兴趣在您的 VS Code 调试适配器中添加日志点支持,请查看协议中的这些更改。您也可以查看上述调试适配器,了解每个运行时如何选择实现日志点。

后续步骤

目前就这些,但我们还没有完成。根据用户反馈,在我们的七月迭代中,我们正在改进自动附加功能,以帮助提高可发现性(#53640)。

我们希望引入自动附加、NPM 脚本资源管理器和日志点能使使用 VS Code 进行调试变得更加容易。一如既往,我们渴望听到您的反馈,因此请通过 GitHubTwitter 上的 @code 联系我们。

代表 VS Code 团队:祝您编码愉快!

/Kenneth Auchenberg - @auchenberg on Twitter

© . This site is unofficial and not affiliated with Microsoft.