@testdriverai/runner 7.9.6-test → 7.9.8-test

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/sandbox-agent.js +37 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testdriverai/runner",
3
- "version": "7.9.6-test",
3
+ "version": "7.9.8-test",
4
4
  "description": "TestDriver Runner - Ably-based remote automation agent with Node.js automation",
5
5
  "main": "index.js",
6
6
  "bin": {
package/sandbox-agent.js CHANGED
@@ -33,6 +33,7 @@
33
33
  */
34
34
  require('dotenv').config();
35
35
  const Sentry = require('@sentry/node');
36
+ const crypto = require('crypto');
36
37
  const fs = require('fs');
37
38
  const os = require('os');
38
39
  const path = require('path');
@@ -181,6 +182,7 @@ function log(msg) {
181
182
  // ─── Main ────────────────────────────────────────────────────────────────────
182
183
 
183
184
  async function main() {
185
+ let rootSpan = null;
184
186
  log('TestDriver Sandbox Agent starting...');
185
187
  log(`Runner version: ${getLocalVersion() || 'unknown'}`);
186
188
 
@@ -214,6 +216,38 @@ async function main() {
214
216
  if (config.sentryChannel || process.env.TD_CHANNEL) {
215
217
  Sentry.setTag('channel', config.sentryChannel || process.env.TD_CHANNEL);
216
218
  }
219
+
220
+ // Create a session-level root span for distributed tracing.
221
+ // Uses deterministic traceId = MD5(sessionId) so all components
222
+ // (SDK, API, Runner, Worker) share the same trace.
223
+ const sessionId = config.sessionId;
224
+ if (sessionId) {
225
+ const traceId = crypto.createHash('md5').update(sessionId).digest('hex');
226
+ const spanId = crypto.randomBytes(8).toString('hex');
227
+ const sentryTraceHeader = `${traceId}-${spanId}-1`;
228
+ const baggageHeader = `sentry-trace_id=${traceId},sentry-sampled=true`;
229
+
230
+ Sentry.continueTrace(
231
+ { sentryTrace: sentryTraceHeader, baggage: baggageHeader },
232
+ () => {
233
+ rootSpan = Sentry.startInactiveSpan({
234
+ name: 'runner.session',
235
+ op: 'session',
236
+ forceTransaction: true,
237
+ attributes: {
238
+ 'sandbox.id': config.sandboxId,
239
+ 'session.id': sessionId,
240
+ },
241
+ });
242
+ },
243
+ );
244
+
245
+ Sentry.setTag('session', sessionId);
246
+ Sentry.setTag('trace_id', traceId);
247
+ log(`Distributed tracing: session=${sessionId} traceId=${traceId}`);
248
+ }
249
+
250
+ Sentry.setTag('sandbox', config.sandboxId);
217
251
  log('Sentry initialized');
218
252
  }
219
253
  log(`Sandbox ID: ${config.sandboxId}`);
@@ -251,6 +285,9 @@ async function main() {
251
285
 
252
286
  const shutdown = async () => {
253
287
  log('Shutting down...');
288
+ if (rootSpan) {
289
+ try { rootSpan.end(); } catch (e) { /* ignore */ }
290
+ }
254
291
  await ablyService.close();
255
292
  automation.cleanup();
256
293
  await Sentry.close(2000);