云计算百科
云计算领域专业知识百科平台

语言服务器协议 `$/setTrace` 通知详解:服务端 Trace 级别的动态调整机制

  • 开发工具

【免费下载链接】language-server-protocol

Defines a common protocol for language servers.

项目地址:
https://gitcode.com/gh_mirrors/la/language-server-protocol

点击查看 免费下载

在语言服务器协议(LSP)的服务器生命周期消息中,$/setTrace 是客户端用于动态修改语言服务器 trace 设置的核心通知。本文以本仓库 3.18 版 setTrace 文档 为主干,结合 TraceValue 类型定义、配对的 $/logTrace 通知 与 机器可读元模型 源码,完整讲解该通知的报文结构、取值语义、生命周期时机以及实现要点。读完本文,你将掌握如何在客户端与服务端两侧正确实现 trace 级别的下发、接收与配套的执行轨迹上报。

$/setTrace 通知的定位与报文结构

$/setTrace 是一条 由客户端发送给服务器(client → server)的 notification(箭头 (:arrow_right:) 即表示消息方向为客户端指向服务器)。其协议意图在原文中定义得非常明确:

A notification that should be used by the client to modify the trace setting of the server.

即:该通知的唯一用途是让客户端修改服务器当前的 trace 设置。它与请求(request)不同,不需要服务器返回响应,属于单向的、尽力而为的通知类型。

method 与 params

根据 _includes/messages/3.18/setTrace.md 的规范定义:

  • method:'$/setTrace'($ 前缀表示这是协议框架级别的内建消息,而非某个语言特性专属请求)
  • params:SetTraceParams,其 TypeScript 定义如下:

interface SetTraceParams {
/**
* The new value that should be assigned to the trace setting.
*/
value: TraceValue;
}

参数结构非常精简,仅包含一个必填字段 value,用于承载将要赋值给服务器 trace 设置的新值。

典型 JSON 报文示例

基于上述结构,一个实际通过标准 LSP 消息帧传输的 $/setTrace 通知在 wire 格式上大致如下(JSON-RPC 外层信封按 2.0 约定):

{
"jsonrpc": "2.0",
"method": "$/setTrace",
"params": {
"value": "verbose"
}
}

其中 value 可以是下文介绍的三种 TraceValue 枚举值之一。

TraceValue:trace 级别的三档取值语义

TraceValue 是 SetTraceParams.value 的类型来源,定义于 _includes/types/traceValue.md:

export type TraceValue = 'off' | 'messages' | 'verbose';

其语义在本仓库文档中表述为:TraceValue 表示服务器通过 $/logTrace 通知系统性上报其执行轨迹时的详细程度(verbosity)级别。三个取值对应三级开关:

取值含义对 $/logTrace 行为的影响
'off' 关闭 trace 服务器不应发送任何 $/logTrace 通知
'messages' 仅上报消息级轨迹 发送 $/logTrace,但 LogTraceParams 中不应携带 verbose 字段
'verbose' 详细轨迹 发送 $/logTrace,且可携带 verbose 附加信息字段

该枚举在 元模型 metaModel.json 中的 TraceValue 定义 里被描述为三个字符串字面量值,官方说明分别为:

  • off:Turn tracing off(关闭追踪)
  • messages:Trace messages only(仅追踪消息)
  • verbose:Verbose message tracing(追踪详细消息)

三个取值的粒度自低到高,构成一个递增的"详细程度"阶梯,客户端可以在运行期按需上下调整。

与 $/logTrace 的配对联动:trace 的消费端

$/setTrace 负责"下发设置",真正"消费"该设置的是服务器 → 客户端方向的 $/logTrace 通知(_includes/messages/3.18/logTrace.md)。两条消息方向相反、语义互补,共同构成 LSP 的执行轨迹(trace)上报通道:

维度$/setTrace$/logTrace
方向 client → server server → client
作用 修改服务器 trace 设置 上报服务器执行轨迹
时机 生命周期内任意时刻(初始化后) 按当前 trace 级别决定是否发送

LogTraceParams 的结构如下:

interface LogTraceParams {
/**
* The message to be logged.
*/
message: string;
/**
* Additional information that can be computed if the `trace` configuration
* is set to `'verbose'`.
*/
verbose?: string;
}

规范对二者联动关系的约束可以归纳为三条:

  • 'off' 静默:当 trace 为 'off' 时,服务器不得发送任何 $/logTrace 通知;
  • 'messages' 精简:当 trace 为 'messages' 时,服务器允许发送 $/logTrace,但不得携带可选的 verbose 字段;
  • 'verbose' 完整:仅在 'verbose' 级别下,verbose 附加字段才被允许计算并填充。
  • 此外,规范还对两种日志渠道做了明确分工:$/logTrace 用于系统性的轨迹上报(systematic trace reporting),而单次的调试消息应使用 window/logMessage 通知。这提示实现者在设计服务器日志时,应将"可结构化的轨迹流"与"面向用户的单条日志消息"区分对待,不要混用。

    trace 的初始值:InitializeParams.trace

    $/setTrace 处理的是运行期动态修改,而 trace 的初始值是在握手阶段由客户端通过 initialize 请求设置的。在 _specifications/lsp/3.18/general/initialize.md 的 InitializeParams 中:

    /**
    * The initial trace setting. If omitted trace is disabled ('off').
    */
    trace?: TraceValue;

    这里有两个关键点:

    • trace 是可选字段,类型同样是 TraceValue;
    • 若省略,则 trace 默认处于禁用状态,即 'off'。也就是说,服务器实现必须把"未收到任何 trace 配置"视为"不产生 trace 输出",而不是自行默认开启某个级别。

    从消息方向上看,InitializeParams.trace 与 $/setTrace 均由客户端发起,前者负责"初始状态",后者负责"后续变更",两者共同覆盖了 trace 设置在会话全生命周期的管理。

    在服务器生命周期中的位置与发送约束

    $/setTrace 属于 LSP 的 Server lifecycle(服务器生命周期)消息之一。在 _specifications/lsp/3.18/specification.md 中,生命周期章节按如下顺序编排:

  • initialize(请求,客户端 → 服务器,建立会话)
  • initialized(通知)
  • $/setTrace(通知)
  • $/logTrace(通知)
  • shutdown(请求)
  • exit(通知)
  • 规范同时规定:服务器在响应 initialize 请求并返回 InitializeResult 之前,不得向客户端发送任何请求或通知(初始化过程中的 window/showMessage、window/logMessage、telemetry/event 及 window/showMessageRequest 除外)。由此可以推断出对 $/setTrace 的实际约束:

    • 客户端在 initialize 完成握手、收到 InitializeResult 之后,才应开始发送 $/setTrace 通知;
    • 服务器端在处理 $/setTrace 时,应假设握手已完成的正常生命周期状态,直接更新内部 trace 状态即可。

    元模型中的机器可读表示

    除了人类可读的 Markdown 规范,本仓库还提供了同一份定义的机器可读版本,便于各语言 SDK 自动生成类型与分发层代码。

    通知条目定义

    在 metaModel.json 的 SetTraceNotification 条目 中:

    {
    "method": "$/setTrace",
    "typeName": "SetTraceNotification",
    "messageDirection": "clientToServer",
    "params": {
    "kind": "reference",
    "name": "SetTraceParams"
    }
    }

    messageDirection: "clientToServer" 与文档中的方向箭头 (:arrow_right:) 完全对应,可作为生成客户端 sendNotification('$/setTrace', params) 调用、以及服务器端通知分发处理器的依据。

    参数结构定义

    SetTraceParams 条目 表明其唯一属性 value 的类型是引用(reference)TraceValue:

    {
    "name": "SetTraceParams",
    "properties": [
    {
    "name": "value",
    "type": {
    "kind": "reference",
    "name": "TraceValue"
    }
    }
    ]
    }

    结合前文 TraceValue 的枚举定义,可以完整推演出元模型→类型系统→运行时校验的实现链路:生成的 SDK 可将 value 编译为联合类型 'off' | 'messages' | 'verbose',并在反序列化时对未知字符串报错。

    实现要点与实践建议

    综合规范文本与仓库元模型,两侧实现 $/setTrace 时可遵循以下要点:

    客户端侧(发送方):

    • 在 initialize 请求中携带 trace 字段设置初始级别(省略即视为 'off');
    • 用户或开发者修改 trace 选项时,发送 $/setTrace 通知,value 从 'off' / 'messages' / 'verbose' 三者中选取;
    • 该通知无需等待响应,属一次性、尽力投递的异步消息。

    服务器侧(接收方):

    • 在 initialize 时记录 params.trace 作为初始值,缺省按 'off' 处理;
    • 实现 $/setTrace 通知的分发处理器,收到后更新内部 trace 状态变量(从源码结构看,这一状态通常由服务器运行时持有并贯穿会话);
    • 在产生执行轨迹时,依据当前级别决定是否发送 $/logTrace:'off' 不发;'messages' 只发 message;'verbose' 额外填充 verbose 字段;
    • 将系统性轨迹走 $/logTrace,将单条调试信息走 window/logMessage,二者职责分离。

    调试排障场景:'verbose' 级别常用于定位协议交互的深层次问题(如请求参数、内部状态变化),'messages' 则适合日常开发时确认消息往来,'off' 用于正式运行环境下的性能与噪音控制。通过 $/setTrace 可在不重启服务器的前提下动态切换这三个级别,这也是它作为生命周期消息被设计出来的意义所在。

    小结

    $/setTrace 是 LSP 生命周期中一条轻量但关键的客户端 → 服务器通知,它以 SetTraceParams.value 承载三档 TraceValue('off'、'messages'、'verbose'),与服务器 → 客户端的 $/logTrace 通知配对构成完整的 trace 上报机制。其初始值由 InitializeParams.trace 约定(缺省 'off'),后续变更则完全由 $/setTrace 驱动。本仓库的 3.18 规范文档、setTrace 定义、logTrace 定义 与 元模型 JSON 三处相互印证,可作为各语言 LSP SDK 实现该通知的权威依据。

    赞

    分享

    • 开发工具

    【免费下载链接】language-server-protocol

    Defines a common protocol for language servers.

    项目地址:
    https://gitcode.com/gh_mirrors/la/language-server-protocol

    点击查看 免费下载

    上一篇:
    5个步骤快速上手SfMLearner:新手必读教程

    下一篇:
    基于 SPDK 的 Longhorn V2 数据引擎卷:架构设计与集群部署实战

    创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 语言服务器协议 `$/setTrace` 通知详解:服务端 Trace 级别的动态调整机制
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!