@agoric/telemetry 0.6.3-other-dev-1f26562.0 → 0.6.3-other-dev-3eb1a1d.0

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/CHANGELOG.md CHANGED
@@ -3,15 +3,6 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
- ### [0.6.3-u11.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/telemetry@0.6.2...@agoric/telemetry@0.6.3-u11.0) (2023-08-24)
7
-
8
-
9
- ### Features
10
-
11
- * **cosmic-swingset:** add JS upgrade plan handler stub ([7803d3d](https://github.com/Agoric/agoric-sdk/commit/7803d3de8e0cba681dfd27dacfc3577eed0bf2f8))
12
-
13
-
14
-
15
6
  ### [0.6.2](https://github.com/Agoric/agoric-sdk/compare/@agoric/telemetry@0.6.1...@agoric/telemetry@0.6.2) (2023-06-02)
16
7
 
17
8
  **Note:** Version bump only for package @agoric/telemetry
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/telemetry",
3
- "version": "0.6.3-other-dev-1f26562.0+1f26562",
3
+ "version": "0.6.3-other-dev-3eb1a1d.0+3eb1a1d",
4
4
  "description": "Agoric's telemetry implementation",
5
5
  "type": "module",
6
6
  "repository": "https://github.com/Agoric/agoric-sdk",
@@ -8,11 +8,11 @@
8
8
  "scripts": {
9
9
  "build": "exit 0",
10
10
  "test": "ava",
11
- "test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js",
11
+ "test:c8": "c8 --all $C8_OPTIONS ava",
12
12
  "test:xs": "exit 0",
13
13
  "lint-fix": "yarn lint:eslint --fix",
14
14
  "lint": "run-s --continue-on-error lint:*",
15
- "lint:types": "tsc -p jsconfig.json",
15
+ "lint:types": "tsc",
16
16
  "lint:eslint": "eslint ."
17
17
  },
18
18
  "bin": {
@@ -22,43 +22,51 @@
22
22
  "author": "Agoric",
23
23
  "license": "Apache-2.0",
24
24
  "dependencies": {
25
- "@agoric/assert": "0.6.1-other-dev-1f26562.0+1f26562",
26
- "@agoric/internal": "0.3.3-other-dev-1f26562.0+1f26562",
27
- "@agoric/store": "0.9.3-other-dev-1f26562.0+1f26562",
28
- "@endo/init": "0.5.56",
29
- "@endo/marshal": "0.8.5",
30
- "@endo/stream": "0.3.25",
25
+ "@agoric/internal": "0.3.3-other-dev-3eb1a1d.0+3eb1a1d",
26
+ "@agoric/store": "0.9.3-other-dev-3eb1a1d.0+3eb1a1d",
27
+ "@endo/errors": "^1.2.8",
28
+ "@endo/init": "^1.1.7",
29
+ "@endo/marshal": "^1.6.2",
30
+ "@endo/stream": "^1.2.8",
31
31
  "@opentelemetry/api": "~1.3.0",
32
+ "@opentelemetry/api-logs": "0.53.0",
33
+ "@opentelemetry/exporter-logs-otlp-http": "0.53.0",
32
34
  "@opentelemetry/exporter-prometheus": "~0.35.0",
33
35
  "@opentelemetry/exporter-trace-otlp-http": "~0.35.0",
34
36
  "@opentelemetry/resources": "~1.9.0",
37
+ "@opentelemetry/sdk-logs": "0.53.0",
35
38
  "@opentelemetry/sdk-metrics": "~1.9.0",
36
39
  "@opentelemetry/sdk-trace-base": "~1.9.0",
37
- "@opentelemetry/semantic-conventions": "~1.9.0",
40
+ "@opentelemetry/semantic-conventions": "~1.27.0",
38
41
  "anylogger": "^0.21.0",
39
- "better-sqlite3": "^8.2.0",
40
- "bufferfromfile": "agoric-labs/BufferFromFile#Agoric-built",
42
+ "better-sqlite3": "^9.1.1",
41
43
  "tmp": "^0.2.1"
42
44
  },
43
45
  "devDependencies": {
44
- "@endo/lockdown": "0.1.28",
45
- "@endo/ses-ava": "0.2.40",
46
- "ava": "^5.2.0",
47
- "c8": "^7.13.0",
46
+ "@endo/lockdown": "^1.0.13",
47
+ "@endo/ses-ava": "^1.2.8",
48
+ "ava": "^5.3.0",
49
+ "c8": "^10.1.2",
48
50
  "tmp": "^0.2.1"
49
51
  },
50
52
  "publishConfig": {
51
53
  "access": "public"
52
54
  },
53
55
  "engines": {
54
- "node": ">=14.15.0"
56
+ "node": "^18.12 || ^20.9"
55
57
  },
56
58
  "ava": {
57
59
  "files": [
58
- "test/**/test-*.js"
60
+ "test/**/*.test.*"
61
+ ],
62
+ "require": [
63
+ "@endo/init/debug.js"
59
64
  ],
60
65
  "timeout": "20m",
61
66
  "workerThreads": false
62
67
  },
63
- "gitHead": "1f265627270d514ab48943f86c668eb58a280552"
68
+ "typeCoverage": {
69
+ "atLeast": 88.87
70
+ },
71
+ "gitHead": "3eb1a1d2d75b2b4a94807cd3bf759bc9fc531f05"
64
72
  }
package/scripts/ingest.sh CHANGED
@@ -18,8 +18,8 @@ if [[ ! -s "$PROGRESS" ]]; then
18
18
  fi
19
19
  if [[ -n "$INGEST_START" ]]; then
20
20
  case "$1" in
21
- *.Z | *.gz) firstline=$(zcat "$1" | head -1) ;;
22
- *) firstline=$(head -1 "$1") ;;
21
+ *.Z | *.gz) firstline=$(zcat "$1" | head -1) ;;
22
+ *) firstline=$(head -1 "$1") ;;
23
23
  esac
24
24
  echo "$firstline" | jq --arg targetStart "$INGEST_START" \
25
25
  '{virtualTimeOffset: (($targetStart | fromdate) - .time), lastSlogTime: 0}' \
@@ -0,0 +1,42 @@
1
+ /* eslint-env node */
2
+
3
+ import { makeFsStreamWriter } from '@agoric/internal/src/node/fs-stream.js';
4
+ import { makeContextualSlogProcessor } from './context-aware-slog.js';
5
+ import { serializeSlogObj } from './serialize-slog-obj.js';
6
+
7
+ /**
8
+ * @param {import('./index.js').MakeSlogSenderOptions} options
9
+ */
10
+ export const makeSlogSender = async options => {
11
+ const { CHAIN_ID, CONTEXTUAL_SLOGFILE } = options.env || {};
12
+ if (!CONTEXTUAL_SLOGFILE)
13
+ return console.warn(
14
+ 'Ignoring invocation of slogger "context-aware-slog-file" without the presence of "CONTEXTUAL_SLOGFILE"',
15
+ );
16
+
17
+ const stream = await makeFsStreamWriter(CONTEXTUAL_SLOGFILE);
18
+
19
+ if (!stream)
20
+ return console.error(
21
+ `Couldn't create a write stream on file "${CONTEXTUAL_SLOGFILE}"`,
22
+ );
23
+
24
+ const contextualSlogProcessor = makeContextualSlogProcessor({
25
+ 'chain-id': CHAIN_ID,
26
+ });
27
+
28
+ /**
29
+ * @param {import('./context-aware-slog.js').Slog} slog
30
+ */
31
+ const slogSender = slog => {
32
+ const contextualizedSlog = contextualSlogProcessor(slog);
33
+
34
+ // eslint-disable-next-line prefer-template
35
+ stream.write(serializeSlogObj(contextualizedSlog) + '\n').catch(() => {});
36
+ };
37
+
38
+ return Object.assign(slogSender, {
39
+ forceFlush: () => stream.flush(),
40
+ shutdown: () => stream.close(),
41
+ });
42
+ };
@@ -0,0 +1,383 @@
1
+ /* eslint-env node */
2
+
3
+ /**
4
+ * @typedef {Partial<{
5
+ * 'block.height': Slog['blockHeight'];
6
+ * 'block.time': Slog['blockTime'];
7
+ * 'crank.deliveryNum': Slog['deliveryNum'];
8
+ * 'crank.num': Slog['crankNum'];
9
+ * 'crank.type': Slog['crankType'];
10
+ * 'crank.vatID': Slog['vatID'];
11
+ * init: boolean;
12
+ * replay: boolean;
13
+ * 'run.id': string;
14
+ * 'run.num': string | null;
15
+ * 'run.trigger.blockHeight': Slog['blockHeight'];
16
+ * 'run.trigger.msgIdx': number;
17
+ * 'run.trigger.sender': Slog['sender'];
18
+ * 'run.trigger.source': Slog['source'];
19
+ * 'run.trigger.bundleHash': Slog['endoZipBase64Sha512'];
20
+ * 'run.trigger.time': Slog['blockTime'];
21
+ * 'run.trigger.txHash': string;
22
+ * 'run.trigger.type': string;
23
+ * }>
24
+ * } Context
25
+ *
26
+ * @typedef {{
27
+ * 'crank.syscallNum'?: Slog['syscallNum'];
28
+ * 'process.uptime': Slog['monotime'];
29
+ * } & Context} LogAttributes
30
+ *
31
+ * @typedef {{
32
+ * blockHeight?: number;
33
+ * blockTime?: number;
34
+ * crankNum?: bigint;
35
+ * crankType?: string;
36
+ * deliveryNum?: bigint;
37
+ * inboundNum?: string;
38
+ * monotime: number;
39
+ * remainingBeans?: bigint;
40
+ * replay?: boolean;
41
+ * runNum?: number;
42
+ * sender?: string;
43
+ * source?: string;
44
+ * endoZipBase64Sha512?: string;
45
+ * syscallNum?: number;
46
+ * time: number;
47
+ * type: string;
48
+ * vatID?: string;
49
+ * }} Slog
50
+ */
51
+
52
+ const SLOG_TYPES = {
53
+ CLIST: 'clist',
54
+ CONSOLE: 'console',
55
+ COSMIC_SWINGSET: {
56
+ AFTER_COMMIT_STATS: 'cosmic-swingset-after-commit-stats',
57
+ BEGIN_BLOCK: 'cosmic-swingset-begin-block',
58
+ BOOTSTRAP_BLOCK: {
59
+ FINISH: 'cosmic-swingset-bootstrap-block-finish',
60
+ START: 'cosmic-swingset-bootstrap-block-start',
61
+ },
62
+ COMMIT: {
63
+ FINISH: 'cosmic-swingset-commit-finish',
64
+ START: 'cosmic-swingset-commit-start',
65
+ },
66
+ END_BLOCK: {
67
+ FINISH: 'cosmic-swingset-end-block-finish',
68
+ START: 'cosmic-swingset-end-block-start',
69
+ },
70
+ // eslint-disable-next-line no-restricted-syntax
71
+ RUN: {
72
+ FINISH: 'cosmic-swingset-run-finish',
73
+ START: 'cosmic-swingset-run-start',
74
+ },
75
+ },
76
+ COSMIC_SWINGSET_TRIGGERS: {
77
+ BRIDGE_INBOUND: 'cosmic-swingset-bridge-inbound',
78
+ DELIVER_INBOUND: 'cosmic-swingset-deliver-inbound',
79
+ TIMER_POLL: 'cosmic-swingset-timer-poll',
80
+ INSTALL_BUNDLE: 'cosmic-swingset-install-bundle',
81
+ },
82
+ CRANK: {
83
+ FINISH: 'crank-finish',
84
+ START: 'crank-start',
85
+ },
86
+ DELIVER: 'deliver',
87
+ DELIVER_RESULT: 'deliver-result',
88
+ KERNEL: {
89
+ INIT: {
90
+ FINISH: 'kernel-init-finish',
91
+ START: 'kernel-init-start',
92
+ },
93
+ },
94
+ REPLAY: {
95
+ FINISH: 'finish-replay',
96
+ START: 'start-replay',
97
+ },
98
+ SYSCALL: 'syscall',
99
+ SYSCALL_RESULT: 'syscall-result',
100
+ };
101
+
102
+ /**
103
+ * @template {Record<string, any>} [T={}]
104
+ * @param {T} [staticContext]
105
+ * @param {Partial<{ persistContext: (context: Context) => void; restoreContext: () => Context | null; }>} [persistenceUtils]
106
+ */
107
+ export const makeContextualSlogProcessor = (
108
+ staticContext,
109
+ persistenceUtils = {},
110
+ ) => {
111
+ /** @type Array<Context | null> */
112
+ let [
113
+ blockContext,
114
+ crankContext,
115
+ initContext,
116
+ lastPersistedTriggerContext,
117
+ replayContext,
118
+ triggerContext,
119
+ ] = [null, null, null, null, null, null];
120
+
121
+ /**
122
+ * @param {Context} context
123
+ */
124
+ const persistContext = context => {
125
+ lastPersistedTriggerContext = context;
126
+ return persistenceUtils?.persistContext?.(context);
127
+ };
128
+
129
+ const restoreContext = () => {
130
+ if (!lastPersistedTriggerContext)
131
+ lastPersistedTriggerContext =
132
+ persistenceUtils?.restoreContext?.() || null;
133
+ return lastPersistedTriggerContext;
134
+ };
135
+
136
+ /**
137
+ * @param {Slog} slog
138
+ * @returns {{ attributes: T & LogAttributes, body: Partial<Slog>; timestamp: Slog['time'] }}
139
+ */
140
+ const slogProcessor = ({ monotime, time: timestamp, ...body }) => {
141
+ const finalBody = { ...body };
142
+
143
+ /** @type {{'crank.syscallNum'?: Slog['syscallNum']}} */
144
+ const eventLogAttributes = {};
145
+
146
+ /**
147
+ * Add any before report operations here
148
+ * like setting context data
149
+ */
150
+ switch (body.type) {
151
+ case SLOG_TYPES.KERNEL.INIT.START: {
152
+ initContext = { init: true };
153
+ break;
154
+ }
155
+ case SLOG_TYPES.COSMIC_SWINGSET.BEGIN_BLOCK: {
156
+ blockContext = {
157
+ 'block.height': finalBody.blockHeight,
158
+ 'block.time': finalBody.blockTime,
159
+ };
160
+ break;
161
+ }
162
+ case SLOG_TYPES.COSMIC_SWINGSET.BOOTSTRAP_BLOCK.START: {
163
+ blockContext = {
164
+ 'block.height': finalBody.blockHeight || 0,
165
+ 'block.time': finalBody.blockTime,
166
+ };
167
+ break;
168
+ }
169
+ case SLOG_TYPES.COSMIC_SWINGSET.END_BLOCK.START:
170
+ case SLOG_TYPES.COSMIC_SWINGSET.END_BLOCK.FINISH:
171
+ case SLOG_TYPES.COSMIC_SWINGSET.BOOTSTRAP_BLOCK.FINISH:
172
+ case SLOG_TYPES.COSMIC_SWINGSET.COMMIT.START:
173
+ case SLOG_TYPES.COSMIC_SWINGSET.COMMIT.FINISH:
174
+ case SLOG_TYPES.COSMIC_SWINGSET.AFTER_COMMIT_STATS: {
175
+ assert(!!blockContext && !triggerContext);
176
+ break;
177
+ }
178
+ case SLOG_TYPES.COSMIC_SWINGSET_TRIGGERS.BRIDGE_INBOUND:
179
+ case SLOG_TYPES.COSMIC_SWINGSET_TRIGGERS.DELIVER_INBOUND: {
180
+ const [blockHeight, txHash, msgIdx] = (
181
+ finalBody.inboundNum || ''
182
+ ).split('-');
183
+ const [, triggerType] =
184
+ /cosmic-swingset-([^-]+)-inbound/.exec(body.type) || [];
185
+
186
+ triggerContext = {
187
+ 'run.num': undefined,
188
+ 'run.id': `${triggerType}-${finalBody.inboundNum}`,
189
+ 'run.trigger.type': triggerType,
190
+ 'run.trigger.source': finalBody.source,
191
+ 'run.trigger.sender': finalBody.sender,
192
+ 'run.trigger.blockHeight': Number(blockHeight),
193
+ 'run.trigger.txHash': txHash,
194
+ 'run.trigger.msgIdx': Number(msgIdx),
195
+ };
196
+ break;
197
+ }
198
+ case SLOG_TYPES.COSMIC_SWINGSET_TRIGGERS.INSTALL_BUNDLE: {
199
+ const [blockHeight, txHash, msgIdx] = (
200
+ finalBody.inboundNum || ''
201
+ ).split('-');
202
+
203
+ const triggerType = 'install-bundle';
204
+
205
+ triggerContext = {
206
+ 'run.num': undefined,
207
+ 'run.id': `${triggerType}-${finalBody.inboundNum}`,
208
+ 'run.trigger.type': triggerType,
209
+ 'run.trigger.bundleHash': finalBody.endoZipBase64Sha512,
210
+ 'run.trigger.blockHeight': Number(blockHeight),
211
+ 'run.trigger.txHash': txHash,
212
+ 'run.trigger.msgIdx': Number(msgIdx),
213
+ };
214
+
215
+ break;
216
+ }
217
+ case SLOG_TYPES.COSMIC_SWINGSET_TRIGGERS.TIMER_POLL: {
218
+ const triggerType = 'timer-poll';
219
+
220
+ triggerContext = {
221
+ 'run.num': undefined,
222
+ 'run.id': `${triggerType}-${finalBody.inboundNum}`,
223
+ 'run.trigger.type': triggerType,
224
+ 'run.trigger.time': finalBody.blockTime,
225
+ 'run.trigger.blockHeight': finalBody.blockHeight,
226
+ };
227
+
228
+ break;
229
+ }
230
+ // eslint-disable-next-line no-restricted-syntax
231
+ case SLOG_TYPES.COSMIC_SWINGSET.RUN.START: {
232
+ if (!finalBody.runNum) {
233
+ assert(!triggerContext);
234
+ triggerContext = restoreContext(); // Restore persisted context if any
235
+ } else if (!triggerContext) {
236
+ assert(!!blockContext);
237
+ // TODO: add explicit slog events of both timer poll and install bundle
238
+ // https://github.com/Agoric/agoric-sdk/issues/10332
239
+ triggerContext = {
240
+ 'run.num': undefined,
241
+ 'run.id': `unknown-${finalBody.blockHeight}-${finalBody.runNum}`,
242
+ 'run.trigger.type': 'unknown',
243
+ 'run.trigger.blockHeight': finalBody.blockHeight,
244
+ };
245
+ }
246
+
247
+ if (!triggerContext) triggerContext = {};
248
+ triggerContext['run.num'] = `${finalBody.runNum}`;
249
+
250
+ break;
251
+ }
252
+ case SLOG_TYPES.CRANK.START: {
253
+ crankContext = {
254
+ 'crank.num': finalBody.crankNum,
255
+ 'crank.type': finalBody.crankType,
256
+ };
257
+ break;
258
+ }
259
+ case SLOG_TYPES.CLIST: {
260
+ assert(!!crankContext);
261
+ crankContext['crank.vatID'] = finalBody.vatID;
262
+ break;
263
+ }
264
+ case SLOG_TYPES.REPLAY.START:
265
+ case SLOG_TYPES.REPLAY.FINISH: {
266
+ replayContext = { replay: true, 'crank.vatID': finalBody.vatID };
267
+ break;
268
+ }
269
+ case SLOG_TYPES.DELIVER: {
270
+ if (replayContext) {
271
+ assert(finalBody.replay);
272
+ replayContext = {
273
+ ...replayContext,
274
+ 'crank.vatID': finalBody.vatID,
275
+ 'crank.deliveryNum': finalBody.deliveryNum,
276
+ };
277
+ } else {
278
+ assert(!!crankContext && !finalBody.replay);
279
+ crankContext = {
280
+ ...crankContext,
281
+ 'crank.vatID': finalBody.vatID,
282
+ 'crank.deliveryNum': finalBody.deliveryNum,
283
+ };
284
+ }
285
+
286
+ delete finalBody.deliveryNum;
287
+ delete finalBody.replay;
288
+
289
+ break;
290
+ }
291
+ case SLOG_TYPES.DELIVER_RESULT: {
292
+ delete finalBody.deliveryNum;
293
+ delete finalBody.replay;
294
+
295
+ break;
296
+ }
297
+ case SLOG_TYPES.SYSCALL:
298
+ case SLOG_TYPES.SYSCALL_RESULT: {
299
+ eventLogAttributes['crank.syscallNum'] = finalBody.syscallNum;
300
+
301
+ delete finalBody.deliveryNum;
302
+ delete finalBody.replay;
303
+ delete finalBody.syscallNum;
304
+
305
+ break;
306
+ }
307
+ case SLOG_TYPES.CONSOLE: {
308
+ delete finalBody.crankNum;
309
+ delete finalBody.deliveryNum;
310
+
311
+ break;
312
+ }
313
+ default:
314
+ // All other log types are logged as is (using existing contexts) without
315
+ // any change to the slogs or any contributions to the contexts. This also
316
+ // means that any unexpected slog type will pass through. To fix that, add
317
+ // all remaining cases of expected slog types above with a simple break
318
+ // statement and log a warning here
319
+ break;
320
+ }
321
+
322
+ const logAttributes = {
323
+ ...staticContext,
324
+ 'process.uptime': monotime,
325
+ ...initContext, // Optional prelude
326
+ ...blockContext, // Block is the first level of execution nesting
327
+ ...triggerContext, // run and trigger info is nested next
328
+ ...crankContext, // Finally cranks are the last level of nesting
329
+ ...replayContext, // Replay is a substitute for crank context during vat page in
330
+ ...eventLogAttributes,
331
+ };
332
+
333
+ /**
334
+ * Add any after report operations here
335
+ * like resetting context data
336
+ */
337
+ switch (body.type) {
338
+ case SLOG_TYPES.KERNEL.INIT.FINISH: {
339
+ initContext = null;
340
+ break;
341
+ }
342
+ case SLOG_TYPES.COSMIC_SWINGSET.BOOTSTRAP_BLOCK.START: {
343
+ triggerContext = {
344
+ 'run.num': undefined,
345
+ 'run.id': `bootstrap-${finalBody.blockTime}`,
346
+ 'run.trigger.type': 'bootstrap',
347
+ 'run.trigger.time': finalBody.blockTime,
348
+ };
349
+ break;
350
+ }
351
+ case SLOG_TYPES.COSMIC_SWINGSET.AFTER_COMMIT_STATS:
352
+ case SLOG_TYPES.COSMIC_SWINGSET.BOOTSTRAP_BLOCK.FINISH: {
353
+ blockContext = null;
354
+ break;
355
+ }
356
+ // eslint-disable-next-line no-restricted-syntax
357
+ case SLOG_TYPES.COSMIC_SWINGSET.RUN.FINISH: {
358
+ assert(!!triggerContext);
359
+ persistContext(finalBody.remainingBeans ? {} : triggerContext);
360
+ triggerContext = null;
361
+ break;
362
+ }
363
+ case SLOG_TYPES.CRANK.FINISH: {
364
+ crankContext = null;
365
+ break;
366
+ }
367
+ case SLOG_TYPES.REPLAY.FINISH: {
368
+ replayContext = null;
369
+ break;
370
+ }
371
+ default:
372
+ break;
373
+ }
374
+
375
+ return {
376
+ attributes: /** @type {T & LogAttributes} */ (logAttributes),
377
+ body: finalBody,
378
+ timestamp,
379
+ };
380
+ };
381
+
382
+ return slogProcessor;
383
+ };