@deepseek-ai/dsh-session-telemetry-otel 0.1.7-rc.2 → 0.2.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +16 -16
- package/README.md +18 -13
- package/README.zh.md +18 -13
- package/lib/index.js +46 -49
- package/lib/types/index.d.ts +19 -27
- package/package.json +24 -25
package/README.i18n.yaml
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
en: f8ea869792c8b207
|
|
10
10
|
zh: bc076172ce22ba9b
|
|
11
11
|
/deepseek-ai-dsh-session-telemetry-otel/summary:
|
|
12
|
-
en:
|
|
13
|
-
zh:
|
|
12
|
+
en: 828903209ef34983
|
|
13
|
+
zh: 8eac63f1e8df15d8
|
|
14
14
|
/deepseek-ai-dsh-session-telemetry-otel/table-of-contents:
|
|
15
15
|
en: d152484eb41ac6b4
|
|
16
16
|
zh: 09388d293f9be9cb
|
|
@@ -21,29 +21,29 @@
|
|
|
21
21
|
en: bc7e598148a7f8c3
|
|
22
22
|
zh: 0209c6aa258ec134
|
|
23
23
|
/deepseek-ai-dsh-session-telemetry-otel/use-this-package/minimal-configuration:
|
|
24
|
-
en:
|
|
25
|
-
zh:
|
|
24
|
+
en: 11845fd50dc0a494
|
|
25
|
+
zh: ee990bfca3621bd3
|
|
26
26
|
/deepseek-ai-dsh-session-telemetry-otel/use-this-package/what-leaves-the-machine:
|
|
27
|
-
en:
|
|
28
|
-
zh:
|
|
27
|
+
en: 2a5ddd227e400455
|
|
28
|
+
zh: 74b7bd9b9161b054
|
|
29
29
|
/deepseek-ai-dsh-session-telemetry-otel/use-this-package/failures-and-shutdown:
|
|
30
|
-
en:
|
|
31
|
-
zh:
|
|
30
|
+
en: a66831cb9de57e04
|
|
31
|
+
zh: 3ada28bb868e0932
|
|
32
32
|
/deepseek-ai-dsh-session-telemetry-otel/understand-the-implementation:
|
|
33
33
|
en: ee672a6a6f0fa02d
|
|
34
34
|
zh: c3bab8e6b60e768c
|
|
35
35
|
/deepseek-ai-dsh-session-telemetry-otel/understand-the-implementation/design-concept:
|
|
36
|
-
en:
|
|
37
|
-
zh:
|
|
36
|
+
en: 34f8a88224a1f6cf
|
|
37
|
+
zh: 40839dabaea39602
|
|
38
38
|
/deepseek-ai-dsh-session-telemetry-otel/understand-the-implementation/source-map:
|
|
39
39
|
en: 0b99d2e5c27213cd
|
|
40
40
|
zh: 3cbdaa7f6a45d81a
|
|
41
41
|
/deepseek-ai-dsh-session-telemetry-otel/understand-the-implementation/capture-wiring:
|
|
42
|
-
en:
|
|
43
|
-
zh:
|
|
42
|
+
en: 5c85eb0992eb5b2b
|
|
43
|
+
zh: a19cdd5814c0e2b9
|
|
44
44
|
/deepseek-ai-dsh-session-telemetry-otel/understand-the-implementation/field-mapping:
|
|
45
|
-
en:
|
|
46
|
-
zh:
|
|
45
|
+
en: a42e9e081fb93bee
|
|
46
|
+
zh: b8e817c2455278b9
|
|
47
47
|
/deepseek-ai-dsh-session-telemetry-otel/further-exploration:
|
|
48
48
|
en: 155b75490ec65d86
|
|
49
49
|
zh: 07d37d6e4ac90c89
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
en: e43087aea7af4c9e
|
|
58
58
|
zh: f8b529e2012b4c63
|
|
59
59
|
/deepseek-ai-dsh-session-telemetry-otel/known-limitations-and-deferred-work/dev-note:
|
|
60
|
-
en:
|
|
61
|
-
zh:
|
|
60
|
+
en: 0065df2648b09ac9
|
|
61
|
+
zh: b5bac41fc3aec70e
|
package/README.md
CHANGED
|
@@ -9,7 +9,9 @@ English | [中文](README.zh.md)
|
|
|
9
9
|
|
|
10
10
|
## Summary
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
The adapter injects `otel`; the [shared OTel plugin](../../telemetry/otel/README.md) creates its independent Session-log channel. Authorization, redaction, identity, scope version, configuration, and the shutdown deadline remain owned here.
|
|
13
|
+
|
|
14
|
+
`dsh-session-telemetry-otel` exports session records through the OTel JS SDK only after new explicit feedback, for all users and providers, including `deepseek-official`. `FEEDBACK_ONLY` releases the canonical prefix through that feedback, including context; later records wait for the next explicit feedback. `DISABLED` constructs no transport. Scheduled batching can finish an authorized upload without another user interaction or model call. Deployments own their redaction rules.
|
|
13
15
|
|
|
14
16
|
## Table of Contents
|
|
15
17
|
|
|
@@ -38,7 +40,7 @@ Programmatic TypeScript configuration uses the exported `SessionTelemetryMode` e
|
|
|
38
40
|
|
|
39
41
|
### Minimal configuration
|
|
40
42
|
|
|
41
|
-
Uploading modes require an exporter URL
|
|
43
|
+
Uploading modes require an exporter URL. Processor settings control the independent Session-log queue; routing headers are explicit `exporter.headers` values.
|
|
42
44
|
|
|
43
45
|
```yaml
|
|
44
46
|
- id: sessionTelemetry-otel
|
|
@@ -46,31 +48,34 @@ Uploading modes require an exporter URL and accept the SDK option blocks verbati
|
|
|
46
48
|
config:
|
|
47
49
|
mode: FEEDBACK_ONLY # optional; defaults to FEEDBACK_ONLY
|
|
48
50
|
shutdownTimeoutMillis: 3000 # optional; defaults to 3000
|
|
49
|
-
exporter: #
|
|
51
|
+
exporter: # explicit SDK transport settings
|
|
50
52
|
url: https://collector.example.com/v1/logs
|
|
51
53
|
headers:
|
|
52
54
|
authorization: !!js `Bearer ${process.env.OTLP_TOKEN}`
|
|
53
|
-
processor: {} # optional;
|
|
55
|
+
processor: {} # optional; byte/count batching and per-request watchdog
|
|
54
56
|
```
|
|
55
57
|
|
|
56
58
|
| Field | Default | Meaning |
|
|
57
59
|
|---|---|---|
|
|
58
60
|
| `mode` | `FEEDBACK_ONLY` | Sharing policy: `FEEDBACK_ONLY` or `DISABLED` |
|
|
59
61
|
| `exporter.url` | required in uploading modes | Full OTLP logs endpoint; must parse as `http(s)` |
|
|
60
|
-
| `exporter`, `processor` | — |
|
|
61
|
-
| `shutdownTimeoutMillis` | `3,000` | Outer deadline for
|
|
62
|
+
| `exporter`, `processor` | — | SDK transport plus byte/count batching; headers/TLS identity are not inherited from the environment. Agent factories own their returned agent settings, including keepAlive |
|
|
63
|
+
| `shutdownTimeoutMillis` | `3,000` | Outer deadline for all queued HTTP requests; remaining queued sends stop at expiry |
|
|
64
|
+
| `maxRequestBytes` | `4,000,000` | Maximum complete OTLP JSON request bytes before gzip; may only be lowered |
|
|
62
65
|
|
|
63
66
|
Direct `ctx.sessionTelemetry.emit()` calls are no-ops in every mode and cannot bypass feedback authorization. Inherited parent feedback does not authorize a child export: the child needs new feedback of its own. Its authorized prefix then includes inherited context.
|
|
64
67
|
|
|
65
|
-
Model requests, request headers, Session creation or adoption, restoration, and plugin mount or HMR do not authorize capture. Stored feedback alone triggers nothing.
|
|
68
|
+
Model requests, request headers, Session creation or adoption, restoration, and plugin mount or HMR do not authorize capture. Stored feedback alone triggers nothing. Scheduled flush and shutdown may finish batches authorized earlier, but never capture new records.
|
|
66
69
|
|
|
67
70
|
### What leaves the machine
|
|
68
71
|
|
|
69
|
-
|
|
72
|
+
Each Session event becomes one `eventName: "session-log"` record. `attributes.sessionId` is the collector Session identity; `attributes.content` encodes the complete event envelope with redacted `event.data`. JSON values are preserved, not the original JSONL bytes or key ordering. Legacy `session.id`, `event.seq`, and `event.type` metadata remain for existing consumers. Resources carry application and anonymous-user identity; scope carries the backend package name and version. The base profile uses `https://dsh-otel-collector.deepseeksvc.com/v1/logs`; `DSH_TELEMETRY_OTLP_URL` overrides it. No channel header is added implicitly.
|
|
73
|
+
|
|
74
|
+
The shared OTel channel measures each record once with the SDK OTLP JSON serializer, including its resource/scope envelope, then greedily packs requests using those conservative sizes. A single oversized event produces one rejection diagnostic without truncation. Session logs never mix with product analytics in a request. Capture handoff and shutdown are not collector acknowledgements.
|
|
70
75
|
|
|
71
76
|
### Failures and shutdown
|
|
72
77
|
|
|
73
|
-
|
|
78
|
+
Invalid byte limits, non-positive queue/timer values, `maxExportBatchSize > maxQueueSize`, invalid endpoints, and invalid shutdown deadlines fail at load. Processor defaults are 2,048 queued records, 512 records per request, a 1,000 ms scheduling delay, and a 30,000 ms request watchdog. Byte limits may split a count batch into multiple serial HTTP requests. Each request waits for SDK export-queue cleanup after its callback before the next starts. `exportTimeoutMillis` warns per request but never frees an unsettled transport slot; the SDK transport owns network timeout/retry. Shutdown drains these requests until `shutdownTimeoutMillis`; expiry discards the remaining queue and prevents further sends, while an active request may still settle. Large prefixes can therefore remain partially unsent at CLI exit.
|
|
74
79
|
|
|
75
80
|
-----
|
|
76
81
|
|
|
@@ -84,7 +89,7 @@ This section explains the backend's composition; the observable behavior is full
|
|
|
84
89
|
|
|
85
90
|
### Design concept
|
|
86
91
|
|
|
87
|
-
The backend
|
|
92
|
+
The backend owns feedback authorization, identity, and shutdown. The shared OTel service owns channel creation, byte/count scheduling, record construction, JSON transport, compression, and retries. Resource identity carries `service.name`/`service.version` from `APP_IDENTITY` and anonymous `user.id`; the scope retains this package’s name and version.
|
|
88
93
|
|
|
89
94
|
### Source map
|
|
90
95
|
|
|
@@ -94,11 +99,11 @@ The backend is a thin adapter over the OTel JS SDK: it owns feedback authorizati
|
|
|
94
99
|
|
|
95
100
|
### Capture wiring
|
|
96
101
|
|
|
97
|
-
The backend
|
|
102
|
+
The backend captures history on demand through new own feedback events or committed cold snapshots. Its private reporter serializes queued HTTP requests even after a watchdog fires; an outer shutdown deadline stops the remaining queue. It exposes no extra flush entry point.
|
|
98
103
|
|
|
99
104
|
### Field mapping
|
|
100
105
|
|
|
101
|
-
Each
|
|
106
|
+
Each capture record supplies a separately copied event envelope and redacted payload to `SessionLogReporter`; serialization retains optional surface metadata and the event sequence/time. Feedback authorizes the complete unhanded prefix, not only the feedback payload.
|
|
102
107
|
|
|
103
108
|
</details>
|
|
104
109
|
|
|
@@ -148,4 +153,4 @@ None.
|
|
|
148
153
|
|
|
149
154
|
</details>
|
|
150
155
|
|
|
151
|
-
**Runtime invariant:** No companion is published. Mode selection changes capture handoff, SDK setup, and local diagnostics without mutating session or service state an independent companion can compare.
|
|
156
|
+
**Runtime invariant:** No companion is published. Mode selection changes capture handoff, SDK setup, and local diagnostics without mutating session or service state an independent companion can compare. Collector delivery cannot be inferred from local queue state.
|
package/README.zh.md
CHANGED
|
@@ -9,7 +9,9 @@ kind: "package-reference"
|
|
|
9
9
|
|
|
10
10
|
## 概述
|
|
11
11
|
|
|
12
|
-
`
|
|
12
|
+
适配器注入 `otel`;[共享 OTel 插件](../../telemetry/otel/README.zh.md) 创建其独立 Session 日志通道。授权、脱敏、身份、scope 版本、配置和关闭期限仍由本包负责。
|
|
13
|
+
|
|
14
|
+
`dsh-session-telemetry-otel` 仅在新的显式反馈后通过 OTel JS SDK 导出会话记录,适用于所有用户和提供方,包括 `deepseek-official`。`FEEDBACK_ONLY` 释放截至该反馈的权威日志前缀,包含上下文;后续记录等待下一次显式反馈。`DISABLED` 不构造传输。定时批处理可完成已授权的上传,无需另一次用户交互或模型调用。部署方负责脱敏规则。
|
|
13
15
|
|
|
14
16
|
## 目录
|
|
15
17
|
|
|
@@ -38,7 +40,7 @@ kind: "package-reference"
|
|
|
38
40
|
|
|
39
41
|
### 最小配置
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
启用上传的模式必须提供 exporter URL。processor 设置控制独立的 Session 日志队列;路由头通过 `exporter.headers` 显式配置。
|
|
42
44
|
|
|
43
45
|
```yaml
|
|
44
46
|
- id: sessionTelemetry-otel
|
|
@@ -46,31 +48,34 @@ kind: "package-reference"
|
|
|
46
48
|
config:
|
|
47
49
|
mode: FEEDBACK_ONLY # optional; defaults to FEEDBACK_ONLY
|
|
48
50
|
shutdownTimeoutMillis: 3000 # optional; defaults to 3000
|
|
49
|
-
exporter: #
|
|
51
|
+
exporter: # explicit SDK transport settings
|
|
50
52
|
url: https://collector.example.com/v1/logs
|
|
51
53
|
headers:
|
|
52
54
|
authorization: !!js `Bearer ${process.env.OTLP_TOKEN}`
|
|
53
|
-
processor: {} # optional;
|
|
55
|
+
processor: {} # optional; byte/count batching and per-request watchdog
|
|
54
56
|
```
|
|
55
57
|
|
|
56
58
|
| 字段 | 默认值 | 含义 |
|
|
57
59
|
|---|---|---|
|
|
58
60
|
| `mode` | `FEEDBACK_ONLY` | 共享策略:`FEEDBACK_ONLY` 或 `DISABLED` |
|
|
59
61
|
| `exporter.url` | 上传模式必填 | 完整 OTLP 日志端点;必须能解析为 `http(s)` |
|
|
60
|
-
| `exporter
|
|
61
|
-
| `shutdownTimeoutMillis` | `3,000` |
|
|
62
|
+
| `exporter`, `processor` | — | SDK 传输及字节/条数聚合;不继承环境中的头部和 TLS 身份。agent 工厂负责返回实例的设置,包括 keepAlive |
|
|
63
|
+
| `shutdownTimeoutMillis` | `3,000` | 所有排队 HTTP 请求的外层期限;到期后停止剩余排队发送 |
|
|
64
|
+
| `maxRequestBytes` | `4,000,000` | gzip 前完整 OTLP JSON 请求的最大字节数;只能调低 |
|
|
62
65
|
|
|
63
66
|
直接调用 `ctx.sessionTelemetry.emit()` 在任何模式下都是空操作,不能绕过反馈授权。继承的父会话反馈不授权子会话导出:子会话需要新的自身反馈。授权后的前缀包含继承的上下文。
|
|
64
67
|
|
|
65
|
-
模型请求、请求头、Session 创建或接纳、恢复,以及插件挂载或 HMR
|
|
68
|
+
模型请求、请求头、Session 创建或接纳、恢复,以及插件挂载或 HMR(热模块替换)均不授权捕获。仅凭已存储的反馈不会触发任何操作。定时刷新和关闭可以完成先前已授权的批次,但绝不捕获新记录。
|
|
66
69
|
|
|
67
70
|
### 哪些数据会离开本机
|
|
68
71
|
|
|
69
|
-
|
|
72
|
+
每条 Session 事件对应一个 `eventName: "session-log"` 记录。`attributes.sessionId` 是 collector 使用的 Session 身份;`attributes.content` 编码完整事件 envelope 和脱敏后的 `event.data`。保留的是 JSON 值,不保证原 JSONL 字节或键顺序相同。为现有消费者保留 `session.id`、`event.seq` 和 `event.type` 元数据。Resource 携带应用和匿名用户身份;scope 携带后端包名和版本。基础配置使用 `https://dsh-otel-collector.deepseeksvc.com/v1/logs`,可用 `DSH_TELEMETRY_OTLP_URL` 覆盖。不隐式添加 channel 头。
|
|
73
|
+
|
|
74
|
+
共享 OTel 通道使用 SDK 的 OTLP JSON 序列化器对每条记录计量一次,包含其 resource/scope envelope,再按保守大小顺序组包。单条超限事件产生一次拒绝诊断且不截断。Session 日志不会与产品埋点混在一个请求中。捕获交接和关闭完成不代表 collector 确认。
|
|
70
75
|
|
|
71
76
|
### 失败与关闭
|
|
72
77
|
|
|
73
|
-
|
|
78
|
+
无效字节上限、非正队列/计时值、`maxExportBatchSize > maxQueueSize`、无效 endpoint 或关闭期限在加载时失败。processor 默认队列为 2,048 条、单请求最多 512 条、调度延迟 1,000 ms、请求监测期限 30,000 ms。字节上限可能将按条数划分的批次拆成多个串行 HTTP 请求。每个请求在回调后等待 SDK 导出队列清理完成,才启动下一个请求。`exportTimeoutMillis` 针对每个请求告警,但不会释放未结束的传输槽位;SDK transport 负责网络超时和重试。关闭时发送这些请求直到 `shutdownTimeoutMillis`,到期后丢弃剩余队列并禁止后续发送,在途请求仍可能结束。因此较大的授权前缀在 CLI 退出时可能只发送了一部分。
|
|
74
79
|
|
|
75
80
|
-----
|
|
76
81
|
|
|
@@ -84,7 +89,7 @@ kind: "package-reference"
|
|
|
84
89
|
|
|
85
90
|
### 设计理念
|
|
86
91
|
|
|
87
|
-
|
|
92
|
+
后端负责反馈授权、身份和关闭。共享 OTel 服务负责通道创建、字节和条数调度、记录构造、JSON 传输、压缩与重试。Resource 身份携带 `APP_IDENTITY` 中的 `service.name` / `service.version` 以及匿名 `user.id`;scope 保留本包的名称和版本。
|
|
88
93
|
|
|
89
94
|
### 源码地图
|
|
90
95
|
|
|
@@ -94,11 +99,11 @@ kind: "package-reference"
|
|
|
94
99
|
|
|
95
100
|
### 捕获接线
|
|
96
101
|
|
|
97
|
-
|
|
102
|
+
后端按需捕获历史,由新的自身反馈事件或已提交的冷会话快照触发。私有 reporter 串行发送排队 HTTP 请求,即使监测期限已触发也不会重叠;外层关闭期限停止剩余队列。不额外暴露 flush 入口。
|
|
98
103
|
|
|
99
104
|
### 字段映射
|
|
100
105
|
|
|
101
|
-
|
|
106
|
+
每条采集记录向 `SessionLogReporter` 提供单独复制的事件信封和脱敏后的载荷;序列化保留可选的呈现元数据及事件序号和时间。反馈授权整个尚未交接的前缀,而不只是反馈载荷。
|
|
102
107
|
|
|
103
108
|
</details>
|
|
104
109
|
|
|
@@ -148,4 +153,4 @@ kind: "package-reference"
|
|
|
148
153
|
|
|
149
154
|
</details>
|
|
150
155
|
|
|
151
|
-
**运行时不变式:** 不发布伴生入口。模式选择只改变 capture handoff、SDK setup 与本地 diagnostics,不改变可由独立 companion
|
|
156
|
+
**运行时不变式:** 不发布伴生入口。模式选择只改变 capture handoff、SDK setup 与本地 diagnostics,不改变可由独立 companion 对照的会话或服务状态。无法根据本地队列状态推断 collector 是否收到记录。
|
package/lib/index.js
CHANGED
|
@@ -4,25 +4,17 @@ import { Session } from "@deepseek-ai/dsh-session";
|
|
|
4
4
|
import { SessionTelemetryBackend, SessionTelemetryCoordinator } from "@deepseek-ai/dsh-session-telemetry";
|
|
5
5
|
import { APP_IDENTITY } from "@deepseek-ai/dsh-llm";
|
|
6
6
|
import { getOrCreateAnonymousUserId } from "@deepseek-ai/dsh-anonymous-user-id";
|
|
7
|
-
import { BatchLogRecordProcessor, LoggerProvider } from "@opentelemetry/sdk-logs";
|
|
8
|
-
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
|
|
9
7
|
import { SeverityNumber } from "@opentelemetry/api-logs";
|
|
10
|
-
import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
11
8
|
//#region lib/types/index.js
|
|
12
9
|
/**
|
|
13
10
|
* OpenTelemetry Service Provider for the DeepSeek Harness telemetry capability.
|
|
14
11
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* batching, retry, queueing, and loss policy use the SDK's documented behavior, configured
|
|
19
|
-
* verbatim through the `exporter`/`processor` passthroughs. This package owns
|
|
20
|
-
* capture mode and an outer shutdown deadline: the SDK's export timeout does
|
|
21
|
-
* not bound its preceding `forceFlush()` wait.
|
|
12
|
+
* Authorizes feedback-bounded capture and hands complete event strings to the
|
|
13
|
+
* Session-log reporter. This plugin owns resource identity and an outer
|
|
14
|
+
* shutdown deadline; the reporter owns byte-bounded SDK delivery.
|
|
22
15
|
*
|
|
23
16
|
* @module @deepseek-ai/dsh-session-telemetry-otel
|
|
24
17
|
*/
|
|
25
|
-
const { version } = createRequire(import.meta.url)("../package.json");
|
|
26
18
|
/** Session-sharing policy selected by {@link Config.mode}. */
|
|
27
19
|
var SessionTelemetryMode;
|
|
28
20
|
(function(SessionTelemetryMode) {
|
|
@@ -67,34 +59,25 @@ function sharingStatusFor(mode) {
|
|
|
67
59
|
}
|
|
68
60
|
/**
|
|
69
61
|
* Schemastery validator for {@link Config}; cordis runs it before the plugin
|
|
70
|
-
* starts.
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* silently drop every field this plugin did not repeat.
|
|
62
|
+
* starts. The constructor validates endpoint and shutdown requirements; the
|
|
63
|
+
* reporter validates Session byte and queue limits. SDK transport and
|
|
64
|
+
* processor settings retain their upstream types.
|
|
74
65
|
*/
|
|
75
66
|
const Config = z.object({
|
|
76
67
|
mode: z.union(Object.values(SessionTelemetryMode)).default(DEFAULT_TELEMETRY_MODE),
|
|
77
68
|
exporter: z.any(),
|
|
78
69
|
processor: z.any(),
|
|
79
|
-
shutdownTimeoutMillis: z.number()
|
|
70
|
+
shutdownTimeoutMillis: z.number(),
|
|
71
|
+
maxRequestBytes: z.number().step(1).min(1).max(4e6)
|
|
80
72
|
});
|
|
81
73
|
/** Default outer allowance for the SDK's complete shutdown sequence. */
|
|
82
74
|
const DEFAULT_SHUTDOWN_TIMEOUT_MILLIS = 3e3;
|
|
83
75
|
const MAX_TIMER_DELAY_MILLIS = 2147483647;
|
|
84
76
|
/** Severity mapping from the Service Definition's three-level vocabulary to OTel severity numbers. */
|
|
85
77
|
const SEVERITY = {
|
|
86
|
-
info:
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
},
|
|
90
|
-
warn: {
|
|
91
|
-
severityNumber: SeverityNumber.WARN,
|
|
92
|
-
severityText: "WARN"
|
|
93
|
-
},
|
|
94
|
-
error: {
|
|
95
|
-
severityNumber: SeverityNumber.ERROR,
|
|
96
|
-
severityText: "ERROR"
|
|
97
|
-
}
|
|
78
|
+
info: SeverityNumber.INFO,
|
|
79
|
+
warn: SeverityNumber.WARN,
|
|
80
|
+
error: SeverityNumber.ERROR
|
|
98
81
|
};
|
|
99
82
|
/**
|
|
100
83
|
* The backend plugin — the only entry a deployment loads. It always registers
|
|
@@ -103,7 +86,7 @@ const SEVERITY = {
|
|
|
103
86
|
* SDK state and listens only to warn when recorded feedback stays local.
|
|
104
87
|
*/
|
|
105
88
|
var OpenTelemetrySessionBackend = class extends SessionTelemetryBackend {
|
|
106
|
-
static inject = ["sessions"];
|
|
89
|
+
static inject = ["sessions", "otel"];
|
|
107
90
|
static Config = Config;
|
|
108
91
|
provider;
|
|
109
92
|
shutdownTimeoutMillis;
|
|
@@ -134,24 +117,40 @@ var OpenTelemetrySessionBackend = class extends SessionTelemetryBackend {
|
|
|
134
117
|
const shutdownTimeoutMillis = config.shutdownTimeoutMillis ?? 3e3;
|
|
135
118
|
if (!Number.isFinite(shutdownTimeoutMillis) || shutdownTimeoutMillis <= 0 || shutdownTimeoutMillis > MAX_TIMER_DELAY_MILLIS) throw new Error(`session-telemetry-otel: shutdownTimeoutMillis must be a positive finite number no greater than ${MAX_TIMER_DELAY_MILLIS}, got ${String(shutdownTimeoutMillis)}`);
|
|
136
119
|
this.shutdownTimeoutMillis = shutdownTimeoutMillis;
|
|
137
|
-
|
|
138
|
-
|
|
120
|
+
const { version } = createRequire(import.meta.url)("../package.json");
|
|
121
|
+
const reporter = ctx.otel.createSessionLogReporter({
|
|
122
|
+
scope: {
|
|
123
|
+
name: "@deepseek-ai/dsh-session-telemetry-otel",
|
|
124
|
+
version
|
|
125
|
+
},
|
|
126
|
+
exporter: {
|
|
127
|
+
...config.exporter,
|
|
128
|
+
url
|
|
129
|
+
},
|
|
130
|
+
...config.processor === void 0 ? {} : { processor: config.processor },
|
|
131
|
+
...config.maxRequestBytes === void 0 ? {} : { maxRequestBytes: config.maxRequestBytes },
|
|
132
|
+
resourceAttributes: {
|
|
139
133
|
"service.name": APP_IDENTITY.product,
|
|
140
134
|
"service.version": APP_IDENTITY.version,
|
|
141
135
|
"user.id": getOrCreateAnonymousUserId()
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
})]
|
|
136
|
+
},
|
|
137
|
+
onFailure: (message, error) => {
|
|
138
|
+
ctx.logger.warn(message, error);
|
|
139
|
+
}
|
|
147
140
|
});
|
|
148
|
-
|
|
141
|
+
this.provider = reporter;
|
|
149
142
|
const enqueue = (record) => {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
143
|
+
if (record.sourceEvent === void 0) {
|
|
144
|
+
ctx.logger.warn("Session log record withheld: redaction removed sourceEvent");
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
reporter.reportSessionLog({
|
|
148
|
+
sessionId: record.sourceEvent.sessionId,
|
|
149
|
+
event: {
|
|
150
|
+
...record.sourceEvent.envelope,
|
|
151
|
+
data: record.body
|
|
152
|
+
},
|
|
153
|
+
severityNumber: SEVERITY[record.severity],
|
|
155
154
|
attributes: record.attributes
|
|
156
155
|
});
|
|
157
156
|
};
|
|
@@ -185,13 +184,10 @@ var OpenTelemetrySessionBackend = class extends SessionTelemetryBackend {
|
|
|
185
184
|
*/
|
|
186
185
|
emit(_record) {}
|
|
187
186
|
/**
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
* observed after the deadline so a later rejection cannot become unhandled.
|
|
193
|
-
* `DISABLED` has no provider and resolves immediately.
|
|
194
|
-
* @returns resolves when the SDK pipeline quiesces or is disabled, or rejects at the configured deadline.
|
|
187
|
+
* Drain queued HTTP requests until the deployment deadline. The watchdog
|
|
188
|
+
* never releases an unsettled transport slot. At the outer deadline,
|
|
189
|
+
* queued records are abandoned and no further requests may start.
|
|
190
|
+
* @returns completion after transport shutdown, or rejection at the configured deadline.
|
|
195
191
|
*/
|
|
196
192
|
async shutdown() {
|
|
197
193
|
if (this.provider === void 0) return;
|
|
@@ -199,6 +195,7 @@ var OpenTelemetrySessionBackend = class extends SessionTelemetryBackend {
|
|
|
199
195
|
let timer;
|
|
200
196
|
const deadline = new Promise((_resolve, reject) => {
|
|
201
197
|
timer = setTimeout(() => {
|
|
198
|
+
this.provider?.stopPending();
|
|
202
199
|
reject(/* @__PURE__ */ new Error(`session-telemetry-otel: provider shutdown exceeded ${this.shutdownTimeoutMillis}ms`));
|
|
203
200
|
}, this.shutdownTimeoutMillis);
|
|
204
201
|
});
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OpenTelemetry Service Provider for the DeepSeek Harness telemetry capability.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* batching, retry, queueing, and loss policy use the SDK's documented behavior, configured
|
|
8
|
-
* verbatim through the `exporter`/`processor` passthroughs. This package owns
|
|
9
|
-
* capture mode and an outer shutdown deadline: the SDK's export timeout does
|
|
10
|
-
* not bound its preceding `forceFlush()` wait.
|
|
4
|
+
* Authorizes feedback-bounded capture and hands complete event strings to the
|
|
5
|
+
* Session-log reporter. This plugin owns resource identity and an outer
|
|
6
|
+
* shutdown deadline; the reporter owns byte-bounded SDK delivery.
|
|
11
7
|
*
|
|
12
8
|
* @module @deepseek-ai/dsh-session-telemetry-otel
|
|
13
9
|
*/
|
|
14
10
|
import z from '@deepseek-ai/schemastery';
|
|
15
11
|
import type { Context } from '@deepseek-ai/cordis';
|
|
16
12
|
import { SessionTelemetryBackend, type SessionTelemetryRecord, type SessionTelemetrySharingStatus } from '@deepseek-ai/dsh-session-telemetry';
|
|
17
|
-
import {
|
|
13
|
+
import type { BatchLogRecordProcessorOptions } from '@opentelemetry/sdk-logs';
|
|
18
14
|
import type { OTLPExporterNodeConfigBase } from '@opentelemetry/otlp-exporter-base';
|
|
19
15
|
/** Session-sharing policy selected by {@link Config.mode}. */
|
|
20
16
|
export declare enum SessionTelemetryMode {
|
|
@@ -24,37 +20,36 @@ export declare enum SessionTelemetryMode {
|
|
|
24
20
|
/** Default session-sharing policy for schema and direct construction. */
|
|
25
21
|
export declare const DEFAULT_TELEMETRY_MODE = SessionTelemetryMode.FEEDBACK_ONLY;
|
|
26
22
|
/**
|
|
27
|
-
* Plugin configuration:
|
|
28
|
-
* and
|
|
23
|
+
* Plugin configuration: sharing policy, SDK transport options, byte/count queue
|
|
24
|
+
* settings, and an overall shutdown bound. Uploading modes validate their endpoint
|
|
29
25
|
* and shutdown deadline at plugin load; `DISABLED` reads neither.
|
|
30
26
|
*/
|
|
31
27
|
export interface Config {
|
|
32
28
|
/** Defaults to `FEEDBACK_ONLY`: capture session history only when feedback is explicitly submitted. */
|
|
33
29
|
mode?: SessionTelemetryMode;
|
|
34
30
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* `compression`, `keepAlive`, …), owned and documented by the SDK. `url`
|
|
38
|
-
* is the one field this package requires and validates itself.
|
|
31
|
+
* Explicit SDK HTTP transport settings, including optional routing headers.
|
|
32
|
+
* Ambient credentials are not inherited. URL is required while uploading.
|
|
39
33
|
*/
|
|
40
34
|
exporter?: OTLPExporterNodeConfigBase & {
|
|
41
35
|
/** Full logs endpoint (e.g. `https://collector.example.com/v1/logs`). Required outside `DISABLED`; validated at load. */
|
|
42
36
|
url?: string;
|
|
43
37
|
};
|
|
44
38
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
39
|
+
* Count, queue, cadence, and per-request watchdog settings for the byte-bounded
|
|
40
|
+
* processor. A watchdog warning never releases an unsettled transport slot.
|
|
47
41
|
*/
|
|
48
42
|
processor?: Omit<BatchLogRecordProcessorOptions, 'exporter'>;
|
|
49
43
|
/** Maximum time spent awaiting the SDK provider's complete shutdown path. */
|
|
50
44
|
shutdownTimeoutMillis?: number;
|
|
45
|
+
/** Uncompressed OTLP request byte limit, at most 4,000,000. */
|
|
46
|
+
maxRequestBytes?: number;
|
|
51
47
|
}
|
|
52
48
|
/**
|
|
53
49
|
* Schemastery validator for {@link Config}; cordis runs it before the plugin
|
|
54
|
-
* starts.
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* silently drop every field this plugin did not repeat.
|
|
50
|
+
* starts. The constructor validates endpoint and shutdown requirements; the
|
|
51
|
+
* reporter validates Session byte and queue limits. SDK transport and
|
|
52
|
+
* processor settings retain their upstream types.
|
|
58
53
|
*/
|
|
59
54
|
export declare const Config: z<Config>;
|
|
60
55
|
/** Default outer allowance for the SDK's complete shutdown sequence. */
|
|
@@ -79,13 +74,10 @@ export declare class OpenTelemetrySessionBackend extends SessionTelemetryBackend
|
|
|
79
74
|
*/
|
|
80
75
|
emit(_record: SessionTelemetryRecord): void;
|
|
81
76
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* observed after the deadline so a later rejection cannot become unhandled.
|
|
87
|
-
* `DISABLED` has no provider and resolves immediately.
|
|
88
|
-
* @returns resolves when the SDK pipeline quiesces or is disabled, or rejects at the configured deadline.
|
|
77
|
+
* Drain queued HTTP requests until the deployment deadline. The watchdog
|
|
78
|
+
* never releases an unsettled transport slot. At the outer deadline,
|
|
79
|
+
* queued records are abandoned and no further requests may start.
|
|
80
|
+
* @returns completion after transport shutdown, or rejection at the configured deadline.
|
|
89
81
|
*/
|
|
90
82
|
shutdown(): Promise<void>;
|
|
91
83
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-session-telemetry-otel",
|
|
3
|
-
"description": "
|
|
4
|
-
"version": "0.
|
|
3
|
+
"description": "Feedback-authorized Session logs over byte-bounded OpenTelemetry HTTP requests",
|
|
4
|
+
"version": "0.2.0-rc.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -27,39 +27,38 @@
|
|
|
27
27
|
],
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@opentelemetry/api": "^1.9.1",
|
|
31
30
|
"@opentelemetry/api-logs": "^0.220.0",
|
|
32
|
-
"@opentelemetry/exporter-logs-otlp-http": "^0.220.0",
|
|
33
31
|
"@opentelemetry/otlp-exporter-base": "^0.220.0",
|
|
34
|
-
"@opentelemetry/resources": "^2.9.0",
|
|
35
32
|
"@opentelemetry/sdk-logs": "^0.220.0",
|
|
36
33
|
"@deepseek-ai/schemastery": "~3.18.4"
|
|
37
34
|
},
|
|
38
35
|
"peerDependencies": {
|
|
39
|
-
"@deepseek-ai/dsh-command-feedback": "0.
|
|
40
|
-
"@deepseek-ai/dsh-
|
|
41
|
-
"@deepseek-ai/dsh-
|
|
42
|
-
"@deepseek-ai/dsh-session": "0.
|
|
43
|
-
"@deepseek-ai/dsh-
|
|
44
|
-
"@deepseek-ai/dsh-
|
|
45
|
-
"@deepseek-ai/cordis": "~4.0.4"
|
|
36
|
+
"@deepseek-ai/dsh-command-feedback": "0.2.0-rc.2",
|
|
37
|
+
"@deepseek-ai/dsh-llm": "0.2.0-rc.2",
|
|
38
|
+
"@deepseek-ai/dsh-message-feedback": "0.2.0-rc.2",
|
|
39
|
+
"@deepseek-ai/dsh-session": "0.2.0-rc.2",
|
|
40
|
+
"@deepseek-ai/dsh-anonymous-user-id": "0.2.0-rc.2",
|
|
41
|
+
"@deepseek-ai/dsh-otel": "0.2.0-rc.2",
|
|
42
|
+
"@deepseek-ai/cordis": "~4.0.4",
|
|
43
|
+
"@deepseek-ai/dsh-session-telemetry": "0.2.0-rc.2"
|
|
46
44
|
},
|
|
47
45
|
"devDependencies": {
|
|
48
46
|
"@deepseek-ai/cordis-plugin-logger-console": "~1.0.4",
|
|
49
47
|
"@deepseek-ai/cordis-plugin-loader": "~1.0.5",
|
|
50
|
-
"@deepseek-ai/dsh-app-boot": "0.
|
|
51
|
-
"@deepseek-ai/dsh-bash-local": "0.
|
|
52
|
-
"@deepseek-ai/dsh-command-feedback": "0.
|
|
53
|
-
"@deepseek-ai/dsh-
|
|
54
|
-
"@deepseek-ai/dsh-
|
|
55
|
-
"@deepseek-ai/dsh-session": "0.
|
|
56
|
-
"@deepseek-ai/dsh-
|
|
57
|
-
"@deepseek-ai/dsh-session-checkpoint-policy": "0.
|
|
58
|
-
"@deepseek-ai/dsh-session-persistence-jsonl": "0.
|
|
59
|
-
"@deepseek-ai/dsh-session-telemetry": "0.
|
|
60
|
-
"@deepseek-ai/dsh-
|
|
48
|
+
"@deepseek-ai/dsh-app-boot": "0.2.0-rc.2",
|
|
49
|
+
"@deepseek-ai/dsh-bash-local": "0.2.0-rc.2",
|
|
50
|
+
"@deepseek-ai/dsh-command-feedback": "0.2.0-rc.2",
|
|
51
|
+
"@deepseek-ai/dsh-llm": "0.2.0-rc.2",
|
|
52
|
+
"@deepseek-ai/dsh-message-feedback": "0.2.0-rc.2",
|
|
53
|
+
"@deepseek-ai/dsh-session": "0.2.0-rc.2",
|
|
54
|
+
"@deepseek-ai/dsh-loader-smoke": "0.2.0-rc.2",
|
|
55
|
+
"@deepseek-ai/dsh-session-checkpoint-policy": "0.2.0-rc.2",
|
|
56
|
+
"@deepseek-ai/dsh-session-persistence-jsonl": "0.2.0-rc.2",
|
|
57
|
+
"@deepseek-ai/dsh-session-telemetry": "0.2.0-rc.2",
|
|
58
|
+
"@deepseek-ai/dsh-subprocess-local": "0.2.0-rc.2",
|
|
59
|
+
"@deepseek-ai/dsh-anonymous-user-id": "0.2.0-rc.2",
|
|
61
60
|
"@deepseek-ai/cordis": "~4.0.4",
|
|
62
|
-
"@deepseek-ai/dsh-http-proxy": "0.
|
|
63
|
-
"@deepseek-ai/dsh-
|
|
61
|
+
"@deepseek-ai/dsh-http-proxy": "0.2.0-rc.2",
|
|
62
|
+
"@deepseek-ai/dsh-otel": "0.2.0-rc.2"
|
|
64
63
|
}
|
|
65
64
|
}
|