Skip to content

Commit

Permalink
feat: (observability) trace Database.batchCreateSessions + SessionPoo…
Browse files Browse the repository at this point in the history
…l.createSessions

This change adds tracing for Database.batchCreateSessions
as well as SessionPool.createSessions which was raised
as a big need.
This change is a premise to finishing up tracing Transaction.

While here, also folded in the async/await fix to avoid day+ long
code review lag and then 3+ hours just to run tests per PR:
OpenTelemetry cannot work correctly for async/await if there isn't
a set AsyncHooksManager, but we should not burden our customers with
this type of specialist knowledge, their code should just work and
this change performs such a check. Later on we shall file a feature
request with the OpenTelemetry-JS API group to give us a hook to detect
if we've got a live asyncHooksManager instead of this mandatory
comparison to ROOT_CONTEXT each time.

Fixes #2146
Updates #2079
Spun out of PR #2122
Supersedes PR #2147
  • Loading branch information
odeke-em committed Oct 5, 2024
1 parent 5237e11 commit e600592
Show file tree
Hide file tree
Showing 7 changed files with 515 additions and 197 deletions.
109 changes: 109 additions & 0 deletions observability-test/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,115 @@ describe('Database', () => {
});
});

describe('batchCreateSessions', () => {
it('without error', done => {
const ARGS = [null, [{}]];
database.request = (config, callback) => {
callback(...ARGS);
};

database.batchCreateSessions(10, (err, sessions) => {
assert.ifError(err);
assert.ok(sessions);

traceExporter.forceFlush();
const spans = traceExporter.getFinishedSpans();

const actualSpanNames: string[] = [];
const actualEventNames: string[] = [];
spans.forEach(span => {
actualSpanNames.push(span.name);
span.events.forEach(event => {
actualEventNames.push(event.name);
});
});

const expectedSpanNames = ['CloudSpanner.Database.batchCreateSessions'];
assert.deepStrictEqual(
actualSpanNames,
expectedSpanNames,
`span names mismatch:\n\tGot: ${actualSpanNames}\n\tWant: ${expectedSpanNames}`
);

// Ensure that the span actually produced an error that was recorded.
const firstSpan = spans[0];
assert.strictEqual(
SpanStatusCode.UNSET,
firstSpan.status.code,
'Unexpected span status code'
);
assert.strictEqual(
undefined,
firstSpan.status.message,
'Mismatched span status message'
);

// We don't expect events.
const expectedEventNames = [];
assert.deepStrictEqual(
actualEventNames,
expectedEventNames,
`Unexpected events:\n\tGot: ${actualEventNames}\n\tWant: ${expectedEventNames}`
);

done();
});
});

it('with error', done => {
const ARGS = [new Error('batchCreateSessions.error'), null];
database.request = (config, callback) => {
callback(...ARGS);
};

database.batchCreateSessions(10, (err, sessions) => {
assert.ok(err);
assert.ok(!sessions);
traceExporter.forceFlush();
const spans = traceExporter.getFinishedSpans();

const actualSpanNames: string[] = [];
const actualEventNames: string[] = [];
spans.forEach(span => {
actualSpanNames.push(span.name);
span.events.forEach(event => {
actualEventNames.push(event.name);
});
});

const expectedSpanNames = ['CloudSpanner.Database.batchCreateSessions'];
assert.deepStrictEqual(
actualSpanNames,
expectedSpanNames,
`span names mismatch:\n\tGot: ${actualSpanNames}\n\tWant: ${expectedSpanNames}`
);

// Ensure that the span actually produced an error that was recorded.
const firstSpan = spans[0];
assert.strictEqual(
SpanStatusCode.ERROR,
firstSpan.status.code,
'Expected an ERROR span status'
);
assert.strictEqual(
'batchCreateSessions.error',
firstSpan.status.message,
'Mismatched span status message'
);

// We don't expect events.
const expectedEventNames = [];
assert.deepStrictEqual(
actualEventNames,
expectedEventNames,
`Unexpected events:\n\tGot: ${actualEventNames}\n\tWant: ${expectedEventNames}`
);

done();
});
});
});

describe('getSnapshot', () => {
let fakePool: FakeSessionPool;
let fakeSession: FakeSession;
Expand Down
Loading

0 comments on commit e600592

Please sign in to comment.