@cnpinsight/cnpclawinsights 2.0.0 → 2.0.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.md +216 -68
- package/dist/cli.mjs +206 -0
- package/dist/index.js +5 -4
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
`@cnpinsight/cnpclawinsights` 是一个 OpenClaw 插件,用于把 OpenClaw 产生的 trace、log、metrics 指标通过 OTLP HTTP/Protobuf 导出到 `otel-collector`。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
插件默认按 `plugins.entries.cnpclawinsights` 这个插件条目启用。
|
|
6
|
+
|
|
7
|
+
最简配置只需要开启插件条目;如果你需要自定义 endpoint、日志导出、headers 等,再补 `config`。
|
|
6
8
|
|
|
7
9
|
## 安装
|
|
8
10
|
|
|
@@ -18,17 +20,80 @@ openclaw plugins install @cnpinsight/cnpclawinsights
|
|
|
18
20
|
openclaw plugins install @cnpinsight/cnpclawinsights@2.0.0
|
|
19
21
|
```
|
|
20
22
|
|
|
23
|
+
## 安装器
|
|
24
|
+
|
|
25
|
+
如果你不想手动编辑 `openclaw.json`,可以使用安装器命令自动写入插件配置。
|
|
26
|
+
|
|
27
|
+
最简单的方式:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm exec -y --package=@cnpinsight/cnpclawinsights -- \
|
|
31
|
+
cnpclawinsights-install \
|
|
32
|
+
--non-interactive
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
这会自动把配置写入默认的 `~/.openclaw/openclaw.json`,并生成:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"plugins": {
|
|
40
|
+
"entries": {
|
|
41
|
+
"cnpclawinsights": {
|
|
42
|
+
"enabled": true,
|
|
43
|
+
"config": {
|
|
44
|
+
"otel": {
|
|
45
|
+
"endpoint": "http://127.0.0.1:4318"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
指定 endpoint 并开启 logs:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npm exec -y --package=@cnpinsight/cnpclawinsights -- \
|
|
58
|
+
cnpclawinsights-install \
|
|
59
|
+
--non-interactive \
|
|
60
|
+
--endpoint http://127.0.0.1:4318 \
|
|
61
|
+
--logs
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
指定 service name 和 header:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npm exec -y --package=@cnpinsight/cnpclawinsights -- \
|
|
68
|
+
cnpclawinsights-install \
|
|
69
|
+
--non-interactive \
|
|
70
|
+
--service-name openclaw \
|
|
71
|
+
--header Authorization="Bearer <token>"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
安装器支持的主要参数:
|
|
75
|
+
|
|
76
|
+
- `--config-path <path>`:指定 `openclaw.json` 路径
|
|
77
|
+
- `--endpoint <url>`:设置 OTLP endpoint
|
|
78
|
+
- `--service-name <name>`:设置 OTel service name
|
|
79
|
+
- `--logs` / `--no-logs`:开启或关闭 logs 导出
|
|
80
|
+
- `--traces` / `--no-traces`:开启或关闭 traces 导出
|
|
81
|
+
- `--metrics` / `--no-metrics`:开启或关闭 metrics 导出
|
|
82
|
+
- `--sample-rate <0..1>`:设置 trace 采样率
|
|
83
|
+
- `--flush-interval-ms <ms>`:设置导出刷新间隔
|
|
84
|
+
- `--header <k=v>`:追加请求头,可重复传入
|
|
85
|
+
|
|
21
86
|
## 最小配置
|
|
22
87
|
|
|
23
88
|
在 `openclaw.json` 中添加:
|
|
24
89
|
|
|
25
90
|
```json
|
|
26
91
|
{
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
92
|
+
"plugins": {
|
|
93
|
+
"entries": {
|
|
94
|
+
"cnpclawinsights": {
|
|
95
|
+
"enabled": true
|
|
96
|
+
}
|
|
32
97
|
}
|
|
33
98
|
}
|
|
34
99
|
}
|
|
@@ -36,37 +101,65 @@ openclaw plugins install @cnpinsight/cnpclawinsights@2.0.0
|
|
|
36
101
|
|
|
37
102
|
这个最小配置下:
|
|
38
103
|
|
|
104
|
+
- 默认 OTLP endpoint 是 `http://127.0.0.1:4318`
|
|
39
105
|
- `traces` 默认开启
|
|
40
106
|
- `metrics` 默认开启
|
|
41
107
|
- `logs` 默认关闭
|
|
42
108
|
- OTLP 协议默认使用 `http/protobuf`
|
|
43
109
|
|
|
110
|
+
## 自定义配置
|
|
111
|
+
|
|
112
|
+
如果你需要覆盖默认行为,可以继续加 `config`:
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"plugins": {
|
|
117
|
+
"entries": {
|
|
118
|
+
"cnpclawinsights": {
|
|
119
|
+
"enabled": true,
|
|
120
|
+
"config": {
|
|
121
|
+
"otel": {
|
|
122
|
+
"endpoint": "http://127.0.0.1:4318",
|
|
123
|
+
"logs": true
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
44
132
|
## 完整配置示例
|
|
45
133
|
|
|
46
134
|
```json
|
|
47
135
|
{
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
"enabled": true,
|
|
52
|
-
"protocol": "http/protobuf",
|
|
53
|
-
"endpoint": "http://127.0.0.1:4318",
|
|
54
|
-
"traces": true,
|
|
55
|
-
"metrics": true,
|
|
56
|
-
"logs": true,
|
|
57
|
-
"serviceName": "openclaw",
|
|
58
|
-
"sampleRate": 1,
|
|
59
|
-
"flushIntervalMs": 5000,
|
|
60
|
-
"headers": {
|
|
61
|
-
"Authorization": "Bearer <token>"
|
|
62
|
-
},
|
|
63
|
-
"captureContent": {
|
|
136
|
+
"plugins": {
|
|
137
|
+
"entries": {
|
|
138
|
+
"cnpclawinsights": {
|
|
64
139
|
"enabled": true,
|
|
65
|
-
"
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
140
|
+
"config": {
|
|
141
|
+
"otel": {
|
|
142
|
+
"protocol": "http/protobuf",
|
|
143
|
+
"endpoint": "http://127.0.0.1:4318",
|
|
144
|
+
"traces": true,
|
|
145
|
+
"metrics": true,
|
|
146
|
+
"logs": true,
|
|
147
|
+
"serviceName": "openclaw",
|
|
148
|
+
"sampleRate": 1,
|
|
149
|
+
"flushIntervalMs": 5000,
|
|
150
|
+
"headers": {
|
|
151
|
+
"Authorization": "Bearer <token>"
|
|
152
|
+
},
|
|
153
|
+
"captureContent": {
|
|
154
|
+
"enabled": true,
|
|
155
|
+
"inputMessages": true,
|
|
156
|
+
"outputMessages": true,
|
|
157
|
+
"toolInputs": false,
|
|
158
|
+
"toolOutputs": false,
|
|
159
|
+
"systemPrompt": false
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
70
163
|
}
|
|
71
164
|
}
|
|
72
165
|
}
|
|
@@ -77,14 +170,19 @@ openclaw plugins install @cnpinsight/cnpclawinsights@2.0.0
|
|
|
77
170
|
|
|
78
171
|
```json
|
|
79
172
|
{
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
173
|
+
"plugins": {
|
|
174
|
+
"entries": {
|
|
175
|
+
"cnpclawinsights": {
|
|
176
|
+
"enabled": true,
|
|
177
|
+
"config": {
|
|
178
|
+
"otel": {
|
|
179
|
+
"tracesEndpoint": "http://127.0.0.1:4318/v1/traces",
|
|
180
|
+
"metricsEndpoint": "http://127.0.0.1:4318/v1/metrics",
|
|
181
|
+
"logsEndpoint": "http://127.0.0.1:4318/v1/logs",
|
|
182
|
+
"logs": true
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
88
186
|
}
|
|
89
187
|
}
|
|
90
188
|
}
|
|
@@ -92,85 +190,93 @@ openclaw plugins install @cnpinsight/cnpclawinsights@2.0.0
|
|
|
92
190
|
|
|
93
191
|
## 配置说明
|
|
94
192
|
|
|
95
|
-
`cnpclawinsights.enabled`
|
|
193
|
+
`plugins.entries.cnpclawinsights.enabled`
|
|
96
194
|
|
|
97
|
-
-
|
|
195
|
+
- 是否启用这个插件条目
|
|
98
196
|
- 必须为 `true`
|
|
99
197
|
|
|
100
|
-
`cnpclawinsights.
|
|
198
|
+
`plugins.entries.cnpclawinsights.config.enabled`
|
|
101
199
|
|
|
102
|
-
-
|
|
103
|
-
-
|
|
200
|
+
- 可选的插件内部总开关
|
|
201
|
+
- 不写时默认按启用处理
|
|
202
|
+
- 只有显式写成 `false` 才会关闭
|
|
203
|
+
|
|
204
|
+
`plugins.entries.cnpclawinsights.config.otel.enabled`
|
|
104
205
|
|
|
105
|
-
|
|
206
|
+
- 可选的 OTel 导出开关
|
|
207
|
+
- 不写时默认按启用处理
|
|
208
|
+
- 只有显式写成 `false` 才会关闭
|
|
209
|
+
|
|
210
|
+
`plugins.entries.cnpclawinsights.config.otel.protocol`
|
|
106
211
|
|
|
107
212
|
- 目前只支持 `http/protobuf`
|
|
108
213
|
- 不配置时默认也是 `http/protobuf`
|
|
109
214
|
|
|
110
|
-
`cnpclawinsights.otel.endpoint`
|
|
215
|
+
`plugins.entries.cnpclawinsights.config.otel.endpoint`
|
|
111
216
|
|
|
112
217
|
- 通用 OTLP endpoint
|
|
113
218
|
- 例如 `http://127.0.0.1:4318`
|
|
219
|
+
- 不配置时默认值是 `http://127.0.0.1:4318`
|
|
114
220
|
- 如果不带 `/v1/traces`、`/v1/metrics`、`/v1/logs`,插件会自动补全对应路径
|
|
115
221
|
|
|
116
|
-
`cnpclawinsights.otel.traces`
|
|
222
|
+
`plugins.entries.cnpclawinsights.config.otel.traces`
|
|
117
223
|
|
|
118
224
|
- 是否导出 traces
|
|
119
225
|
- 默认 `true`
|
|
120
226
|
|
|
121
|
-
`cnpclawinsights.otel.metrics`
|
|
227
|
+
`plugins.entries.cnpclawinsights.config.otel.metrics`
|
|
122
228
|
|
|
123
229
|
- 是否导出 metrics
|
|
124
230
|
- 默认 `true`
|
|
125
231
|
|
|
126
|
-
`cnpclawinsights.otel.logs`
|
|
232
|
+
`plugins.entries.cnpclawinsights.config.otel.logs`
|
|
127
233
|
|
|
128
234
|
- 是否导出 logs
|
|
129
235
|
- 默认 `false`
|
|
130
236
|
|
|
131
|
-
`cnpclawinsights.otel.tracesEndpoint`
|
|
237
|
+
`plugins.entries.cnpclawinsights.config.otel.tracesEndpoint`
|
|
132
238
|
|
|
133
239
|
- 单独指定 traces 导出地址
|
|
134
240
|
- 优先级高于 `endpoint`
|
|
135
241
|
|
|
136
|
-
`cnpclawinsights.otel.metricsEndpoint`
|
|
242
|
+
`plugins.entries.cnpclawinsights.config.otel.metricsEndpoint`
|
|
137
243
|
|
|
138
244
|
- 单独指定 metrics 导出地址
|
|
139
245
|
- 优先级高于 `endpoint`
|
|
140
246
|
|
|
141
|
-
`cnpclawinsights.otel.logsEndpoint`
|
|
247
|
+
`plugins.entries.cnpclawinsights.config.otel.logsEndpoint`
|
|
142
248
|
|
|
143
249
|
- 单独指定 logs 导出地址
|
|
144
250
|
- 优先级高于 `endpoint`
|
|
145
251
|
|
|
146
|
-
`cnpclawinsights.otel.serviceName`
|
|
252
|
+
`plugins.entries.cnpclawinsights.config.otel.serviceName`
|
|
147
253
|
|
|
148
254
|
- OpenTelemetry service name
|
|
149
255
|
- 不配置时优先读取环境变量 `OTEL_SERVICE_NAME`
|
|
150
256
|
- 如果环境变量也没有,默认值是 `openclaw`
|
|
151
257
|
|
|
152
|
-
`cnpclawinsights.otel.sampleRate`
|
|
258
|
+
`plugins.entries.cnpclawinsights.config.otel.sampleRate`
|
|
153
259
|
|
|
154
260
|
- trace 采样率
|
|
155
261
|
- 取值范围 `0` 到 `1`
|
|
156
262
|
|
|
157
|
-
`cnpclawinsights.otel.flushIntervalMs`
|
|
263
|
+
`plugins.entries.cnpclawinsights.config.otel.flushIntervalMs`
|
|
158
264
|
|
|
159
265
|
- metrics 周期导出间隔
|
|
160
266
|
- 也用于 logs 批量刷新间隔
|
|
161
267
|
- 最小值为 `1000`
|
|
162
268
|
|
|
163
|
-
`cnpclawinsights.otel.headers`
|
|
269
|
+
`plugins.entries.cnpclawinsights.config.otel.headers`
|
|
164
270
|
|
|
165
271
|
- OTLP 请求头
|
|
166
272
|
- 适合传认证信息
|
|
167
273
|
|
|
168
|
-
`cnpclawinsights.otel.captureContent`
|
|
274
|
+
`plugins.entries.cnpclawinsights.config.otel.captureContent`
|
|
169
275
|
|
|
170
276
|
- 控制是否导出消息内容
|
|
171
277
|
- 默认不采集正文内容
|
|
172
278
|
|
|
173
|
-
`cnpclawinsights.otel.captureContent = true`
|
|
279
|
+
`plugins.entries.cnpclawinsights.config.otel.captureContent = true`
|
|
174
280
|
|
|
175
281
|
- 开启后会采集:
|
|
176
282
|
- `inputMessages`
|
|
@@ -179,7 +285,7 @@ openclaw plugins install @cnpinsight/cnpclawinsights@2.0.0
|
|
|
179
285
|
- `toolOutputs`
|
|
180
286
|
- `systemPrompt` 仍默认不采集
|
|
181
287
|
|
|
182
|
-
`cnpclawinsights.otel.captureContent = { ... }`
|
|
288
|
+
`plugins.entries.cnpclawinsights.config.otel.captureContent = { ... }`
|
|
183
289
|
|
|
184
290
|
- 可以按字段精细控制:
|
|
185
291
|
- `enabled`
|
|
@@ -191,7 +297,15 @@ openclaw plugins install @cnpinsight/cnpclawinsights@2.0.0
|
|
|
191
297
|
|
|
192
298
|
## 环境变量回退
|
|
193
299
|
|
|
194
|
-
如果部分配置未写入 `
|
|
300
|
+
如果部分配置未写入 `plugins.entries.cnpclawinsights.config`,插件会按下面的优先级取值:
|
|
301
|
+
|
|
302
|
+
1. `config.otel` 里的显式配置
|
|
303
|
+
2. 对应的标准 OTel 环境变量
|
|
304
|
+
3. 插件内置默认值
|
|
305
|
+
|
|
306
|
+
其中 endpoint 的内置默认值是 `http://127.0.0.1:4318`。
|
|
307
|
+
|
|
308
|
+
相关环境变量包括:
|
|
195
309
|
|
|
196
310
|
- `OTEL_EXPORTER_OTLP_PROTOCOL`
|
|
197
311
|
- `OTEL_EXPORTER_OTLP_ENDPOINT`
|
|
@@ -218,29 +332,63 @@ openclaw plugins install @cnpinsight/cnpclawinsights@2.0.0
|
|
|
218
332
|
|
|
219
333
|
```json
|
|
220
334
|
{
|
|
221
|
-
"
|
|
222
|
-
"
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
335
|
+
"plugins": {
|
|
336
|
+
"entries": {
|
|
337
|
+
"cnpclawinsights": {
|
|
338
|
+
"enabled": true,
|
|
339
|
+
"config": {
|
|
340
|
+
"otel": {
|
|
341
|
+
"endpoint": "http://127.0.0.1:4318",
|
|
342
|
+
"logs": true
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
227
346
|
}
|
|
228
347
|
}
|
|
229
348
|
}
|
|
230
349
|
```
|
|
231
350
|
|
|
232
|
-
### 3.
|
|
351
|
+
### 3. 为什么只写了 `enabled: true` 也能工作
|
|
233
352
|
|
|
234
|
-
|
|
353
|
+
插件现在支持最简模式:
|
|
235
354
|
|
|
236
355
|
```json
|
|
237
356
|
{
|
|
238
|
-
"
|
|
239
|
-
"
|
|
240
|
-
|
|
241
|
-
|
|
357
|
+
"plugins": {
|
|
358
|
+
"entries": {
|
|
359
|
+
"cnpclawinsights": {
|
|
360
|
+
"enabled": true
|
|
361
|
+
}
|
|
242
362
|
}
|
|
243
363
|
}
|
|
244
364
|
}
|
|
245
365
|
```
|
|
246
366
|
|
|
367
|
+
这时会默认:
|
|
368
|
+
|
|
369
|
+
- 使用 `http/protobuf`
|
|
370
|
+
- 发往 `http://127.0.0.1:4318`
|
|
371
|
+
- 开启 traces 和 metrics
|
|
372
|
+
- 关闭 logs
|
|
373
|
+
|
|
374
|
+
### 4. 为什么配置了但没有导出
|
|
375
|
+
|
|
376
|
+
如果你显式写了下面任意一个值为 `false`,插件就不会导出:
|
|
377
|
+
|
|
378
|
+
```json
|
|
379
|
+
{
|
|
380
|
+
"plugins": {
|
|
381
|
+
"entries": {
|
|
382
|
+
"cnpclawinsights": {
|
|
383
|
+
"enabled": true,
|
|
384
|
+
"config": {
|
|
385
|
+
"enabled": false,
|
|
386
|
+
"otel": {
|
|
387
|
+
"enabled": false
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
```
|
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
|
|
7
|
+
const PLUGIN_ID = "cnpclawinsights";
|
|
8
|
+
const LEGACY_PLUGIN_ID = "cnpclawinsight";
|
|
9
|
+
const DEFAULT_CONFIG_PATH = path.join(os.homedir(), ".openclaw", "openclaw.json");
|
|
10
|
+
const DEFAULT_ENDPOINT = "http://127.0.0.1:4318";
|
|
11
|
+
|
|
12
|
+
function printHelp() {
|
|
13
|
+
console.log(`Usage:
|
|
14
|
+
cnpclawinsights-install [options]
|
|
15
|
+
|
|
16
|
+
Options:
|
|
17
|
+
--config-path <path> Path to openclaw.json
|
|
18
|
+
--endpoint <url> OTLP endpoint, default: ${DEFAULT_ENDPOINT}
|
|
19
|
+
--service-name <name> OpenTelemetry service name
|
|
20
|
+
--logs Enable logs export
|
|
21
|
+
--no-logs Disable logs export
|
|
22
|
+
--traces Enable traces export
|
|
23
|
+
--no-traces Disable traces export
|
|
24
|
+
--metrics Enable metrics export
|
|
25
|
+
--no-metrics Disable metrics export
|
|
26
|
+
--sample-rate <0..1> Trace sampling rate
|
|
27
|
+
--flush-interval-ms <ms> Export flush interval
|
|
28
|
+
--header <k=v> Add OTLP header, repeatable
|
|
29
|
+
--non-interactive Run without prompts
|
|
30
|
+
--help Show this help
|
|
31
|
+
`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function fail(message) {
|
|
35
|
+
console.error(`cnpclawinsights-install: ${message}`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function parseArgs(argv) {
|
|
40
|
+
const options = {
|
|
41
|
+
configPath: DEFAULT_CONFIG_PATH,
|
|
42
|
+
endpoint: DEFAULT_ENDPOINT,
|
|
43
|
+
headers: {}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
47
|
+
const arg = argv[i];
|
|
48
|
+
switch (arg) {
|
|
49
|
+
case "--config-path":
|
|
50
|
+
options.configPath = argv[++i];
|
|
51
|
+
break;
|
|
52
|
+
case "--endpoint":
|
|
53
|
+
options.endpoint = argv[++i];
|
|
54
|
+
break;
|
|
55
|
+
case "--service-name":
|
|
56
|
+
options.serviceName = argv[++i];
|
|
57
|
+
break;
|
|
58
|
+
case "--logs":
|
|
59
|
+
options.logs = true;
|
|
60
|
+
break;
|
|
61
|
+
case "--no-logs":
|
|
62
|
+
options.logs = false;
|
|
63
|
+
break;
|
|
64
|
+
case "--traces":
|
|
65
|
+
options.traces = true;
|
|
66
|
+
break;
|
|
67
|
+
case "--no-traces":
|
|
68
|
+
options.traces = false;
|
|
69
|
+
break;
|
|
70
|
+
case "--metrics":
|
|
71
|
+
options.metrics = true;
|
|
72
|
+
break;
|
|
73
|
+
case "--no-metrics":
|
|
74
|
+
options.metrics = false;
|
|
75
|
+
break;
|
|
76
|
+
case "--sample-rate":
|
|
77
|
+
options.sampleRate = Number(argv[++i]);
|
|
78
|
+
break;
|
|
79
|
+
case "--flush-interval-ms":
|
|
80
|
+
options.flushIntervalMs = Number(argv[++i]);
|
|
81
|
+
break;
|
|
82
|
+
case "--header": {
|
|
83
|
+
const raw = argv[++i];
|
|
84
|
+
const eqIndex = raw.indexOf("=");
|
|
85
|
+
if (eqIndex <= 0) fail(`invalid --header value: ${raw}`);
|
|
86
|
+
const key = raw.slice(0, eqIndex).trim();
|
|
87
|
+
const value = raw.slice(eqIndex + 1).trim();
|
|
88
|
+
if (!key || !value) fail(`invalid --header value: ${raw}`);
|
|
89
|
+
options.headers[key] = value;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case "--non-interactive":
|
|
93
|
+
options.nonInteractive = true;
|
|
94
|
+
break;
|
|
95
|
+
case "--help":
|
|
96
|
+
case "-h":
|
|
97
|
+
options.help = true;
|
|
98
|
+
break;
|
|
99
|
+
default:
|
|
100
|
+
fail(`unknown argument: ${arg}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return options;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function ensureParentDir(filePath) {
|
|
108
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function readConfig(configPath) {
|
|
112
|
+
if (!fs.existsSync(configPath)) {
|
|
113
|
+
return {};
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
return JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
117
|
+
} catch (error) {
|
|
118
|
+
fail(`failed to parse config file ${configPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function normalizePluginEntry(entries) {
|
|
123
|
+
const pluralEntry = entries[PLUGIN_ID];
|
|
124
|
+
if (pluralEntry && typeof pluralEntry === "object") {
|
|
125
|
+
return pluralEntry;
|
|
126
|
+
}
|
|
127
|
+
const legacyEntry = entries[LEGACY_PLUGIN_ID];
|
|
128
|
+
if (legacyEntry && typeof legacyEntry === "object") {
|
|
129
|
+
delete entries[LEGACY_PLUGIN_ID];
|
|
130
|
+
entries[PLUGIN_ID] = legacyEntry;
|
|
131
|
+
return legacyEntry;
|
|
132
|
+
}
|
|
133
|
+
const entry = {};
|
|
134
|
+
entries[PLUGIN_ID] = entry;
|
|
135
|
+
return entry;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function buildPluginConfig(options) {
|
|
139
|
+
const otel = {
|
|
140
|
+
endpoint: options.endpoint
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
if (options.logs !== undefined) otel.logs = options.logs;
|
|
144
|
+
if (options.traces !== undefined) otel.traces = options.traces;
|
|
145
|
+
if (options.metrics !== undefined) otel.metrics = options.metrics;
|
|
146
|
+
if (options.serviceName) otel.serviceName = options.serviceName;
|
|
147
|
+
if (options.sampleRate !== undefined) otel.sampleRate = options.sampleRate;
|
|
148
|
+
if (options.flushIntervalMs !== undefined) otel.flushIntervalMs = options.flushIntervalMs;
|
|
149
|
+
if (Object.keys(options.headers).length > 0) otel.headers = options.headers;
|
|
150
|
+
|
|
151
|
+
return { otel };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function writeConfig(configPath, config) {
|
|
155
|
+
ensureParentDir(configPath);
|
|
156
|
+
fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf8");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function main() {
|
|
160
|
+
const options = parseArgs(process.argv.slice(2));
|
|
161
|
+
if (options.help) {
|
|
162
|
+
printHelp();
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (options.sampleRate !== undefined && (!Number.isFinite(options.sampleRate) || options.sampleRate < 0 || options.sampleRate > 1)) {
|
|
167
|
+
fail("--sample-rate must be a number between 0 and 1");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (options.flushIntervalMs !== undefined && (!Number.isInteger(options.flushIntervalMs) || options.flushIntervalMs < 1000)) {
|
|
171
|
+
fail("--flush-interval-ms must be an integer >= 1000");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const config = readConfig(options.configPath);
|
|
175
|
+
if (!config.plugins || typeof config.plugins !== "object" || Array.isArray(config.plugins)) {
|
|
176
|
+
config.plugins = {};
|
|
177
|
+
}
|
|
178
|
+
if (!config.plugins.entries || typeof config.plugins.entries !== "object" || Array.isArray(config.plugins.entries)) {
|
|
179
|
+
config.plugins.entries = {};
|
|
180
|
+
}
|
|
181
|
+
const entry = normalizePluginEntry(config.plugins.entries);
|
|
182
|
+
entry.enabled = true;
|
|
183
|
+
entry.config = {
|
|
184
|
+
...(entry.config && typeof entry.config === "object" && !Array.isArray(entry.config) ? entry.config : {}),
|
|
185
|
+
...buildPluginConfig(options)
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
if (!Array.isArray(config.plugins.allow)) {
|
|
189
|
+
config.plugins.allow = [];
|
|
190
|
+
}
|
|
191
|
+
if (!config.plugins.allow.includes(PLUGIN_ID)) {
|
|
192
|
+
config.plugins.allow.push(PLUGIN_ID);
|
|
193
|
+
}
|
|
194
|
+
config.plugins.allow = config.plugins.allow.filter((value, index, values) => value !== LEGACY_PLUGIN_ID || values.indexOf(PLUGIN_ID) === -1);
|
|
195
|
+
|
|
196
|
+
writeConfig(options.configPath, config);
|
|
197
|
+
|
|
198
|
+
console.log(`Updated ${options.configPath}`);
|
|
199
|
+
console.log(`Configured plugins.entries.${PLUGIN_ID}.enabled = true`);
|
|
200
|
+
console.log(`Configured plugins.entries.${PLUGIN_ID}.config.otel.endpoint = ${options.endpoint}`);
|
|
201
|
+
if (options.logs !== undefined) {
|
|
202
|
+
console.log(`Configured plugins.entries.${PLUGIN_ID}.config.otel.logs = ${String(options.logs)}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
main();
|
package/dist/index.js
CHANGED
|
@@ -44,6 +44,7 @@ const OTEL_EXPORTER_OTLP_ENDPOINT_ENV = "OTEL_EXPORTER_OTLP_ENDPOINT";
|
|
|
44
44
|
const OTEL_EXPORTER_OTLP_TRACES_ENDPOINT_ENV = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT";
|
|
45
45
|
const OTEL_EXPORTER_OTLP_METRICS_ENDPOINT_ENV = "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT";
|
|
46
46
|
const OTEL_EXPORTER_OTLP_LOGS_ENDPOINT_ENV = "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT";
|
|
47
|
+
const DEFAULT_OTLP_HTTP_ENDPOINT = "http://127.0.0.1:4318";
|
|
47
48
|
const OTEL_SEMCONV_STABILITY_OPT_IN_ENV = "OTEL_SEMCONV_STABILITY_OPT_IN";
|
|
48
49
|
const GEN_AI_LATEST_EXPERIMENTAL_OPT_IN = "gen_ai_latest_experimental";
|
|
49
50
|
const GEN_AI_TOKEN_USAGE_BUCKETS = [
|
|
@@ -354,9 +355,9 @@ function createDiagnosticsOtelService() {
|
|
|
354
355
|
id: "cnpclawinsights",
|
|
355
356
|
async start(ctx) {
|
|
356
357
|
await stopStarted();
|
|
357
|
-
const cfg = ctx.config.
|
|
358
|
-
const otel = cfg?.otel;
|
|
359
|
-
if (
|
|
358
|
+
const cfg = ctx.config?.cnpclawinsights ?? ctx.config ?? {};
|
|
359
|
+
const otel = cfg?.otel ?? {};
|
|
360
|
+
if (cfg?.enabled === false || otel.enabled === false) return;
|
|
360
361
|
const emitExporterEvent = (event) => {
|
|
361
362
|
try {
|
|
362
363
|
ctx.internalDiagnostics?.emit({
|
|
@@ -390,7 +391,7 @@ function createDiagnosticsOtelService() {
|
|
|
390
391
|
ctx.logger.warn(`cnpclawinsights: unsupported protocol ${protocol}`);
|
|
391
392
|
return;
|
|
392
393
|
}
|
|
393
|
-
const endpoint = normalizeEndpoint(otel.endpoint ?? process.env[OTEL_EXPORTER_OTLP_ENDPOINT_ENV]);
|
|
394
|
+
const endpoint = normalizeEndpoint(otel.endpoint ?? process.env[OTEL_EXPORTER_OTLP_ENDPOINT_ENV] ?? DEFAULT_OTLP_HTTP_ENDPOINT);
|
|
394
395
|
const headers = otel.headers ?? void 0;
|
|
395
396
|
const serviceName = otel.serviceName?.trim() || process.env.OTEL_SERVICE_NAME || DEFAULT_SERVICE_NAME;
|
|
396
397
|
const sampleRate = resolveSampleRate(otel.sampleRate);
|
package/package.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cnpinsight/cnpclawinsights",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "OpenClaw insights OpenTelemetry exporter",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/openclaw/openclaw"
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
|
+
"bin": {
|
|
11
|
+
"cnpclawinsights-install": "dist/cli.mjs"
|
|
12
|
+
},
|
|
10
13
|
"dependencies": {
|
|
11
14
|
"@opentelemetry/api": "1.9.1",
|
|
12
15
|
"@opentelemetry/api-logs": "0.218.0",
|