forked from open-telemetry/opentelemetry-js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: postgresql responseHook support (open-telemetry#528)
- Loading branch information
Showing
7 changed files
with
346 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,7 +24,11 @@ import { | |
trace, | ||
} from '@opentelemetry/api'; | ||
import { BasicTracerProvider } from '@opentelemetry/tracing'; | ||
import { PgInstrumentation } from '../src'; | ||
import { | ||
PgInstrumentation, | ||
PgInstrumentationConfig, | ||
PgResponseHookInformation, | ||
} from '../src'; | ||
import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; | ||
import * as testUtils from '@opentelemetry/test-utils'; | ||
import { | ||
|
@@ -95,6 +99,11 @@ const runCallbackTest = ( | |
}; | ||
|
||
describe('[email protected]', () => { | ||
function create(config: PgInstrumentationConfig = {}) { | ||
instrumentation.setConfig(config); | ||
instrumentation.enable(); | ||
} | ||
|
||
let pool: pgPool<pg.Client>; | ||
let contextManager: AsyncHooksContextManager; | ||
let instrumentation: PgInstrumentation; | ||
|
@@ -130,6 +139,7 @@ describe('[email protected]', () => { | |
if (testPostgresLocally) { | ||
testUtils.cleanUpDocker('postgres'); | ||
} | ||
|
||
pool.end(() => { | ||
done(); | ||
}); | ||
|
@@ -288,5 +298,154 @@ describe('[email protected]', () => { | |
assert.strictEqual(resNoPromise, undefined, 'No promise is returned'); | ||
}); | ||
}); | ||
|
||
describe('when specifying a responseHook configuration', () => { | ||
const dataAttributeName = 'pg_data'; | ||
const query = 'SELECT 0::text'; | ||
const events: TimedEvent[] = []; | ||
|
||
describe('AND valid responseHook', () => { | ||
const pgPoolattributes = { | ||
...DEFAULT_PGPOOL_ATTRIBUTES, | ||
}; | ||
const pgAttributes = { | ||
...DEFAULT_PG_ATTRIBUTES, | ||
[SemanticAttributes.DB_STATEMENT]: query, | ||
[dataAttributeName]: '{"rowCount":1}', | ||
}; | ||
|
||
beforeEach(async () => { | ||
const config: PgInstrumentationConfig = { | ||
enhancedDatabaseReporting: true, | ||
responseHook: ( | ||
span: Span, | ||
responseInfo: PgResponseHookInformation | ||
) => | ||
span.setAttribute( | ||
dataAttributeName, | ||
JSON.stringify({ rowCount: responseInfo?.data.rowCount }) | ||
), | ||
}; | ||
|
||
create(config); | ||
}); | ||
|
||
it('should attach response hook data to resulting spans for query with callback ', done => { | ||
const parentSpan = provider | ||
.getTracer('test-pg-pool') | ||
.startSpan('test span'); | ||
context.with(trace.setSpan(context.active(), parentSpan), () => { | ||
const resNoPromise = pool.query(query, (err, result) => { | ||
if (err) { | ||
return done(err); | ||
} | ||
runCallbackTest( | ||
parentSpan, | ||
pgPoolattributes, | ||
events, | ||
unsetStatus, | ||
2, | ||
0 | ||
); | ||
runCallbackTest( | ||
parentSpan, | ||
pgAttributes, | ||
events, | ||
unsetStatus, | ||
2, | ||
1 | ||
); | ||
done(); | ||
}); | ||
assert.strictEqual( | ||
resNoPromise, | ||
undefined, | ||
'No promise is returned' | ||
); | ||
}); | ||
}); | ||
|
||
it('should attach response hook data to resulting spans for query returning a Promise', async () => { | ||
const span = provider | ||
.getTracer('test-pg-pool') | ||
.startSpan('test span'); | ||
await context.with( | ||
trace.setSpan(context.active(), span), | ||
async () => { | ||
const result = await pool.query(query); | ||
runCallbackTest( | ||
span, | ||
pgPoolattributes, | ||
events, | ||
unsetStatus, | ||
2, | ||
0 | ||
); | ||
runCallbackTest(span, pgAttributes, events, unsetStatus, 2, 1); | ||
assert.ok(result, 'pool.query() returns a promise'); | ||
} | ||
); | ||
}); | ||
}); | ||
|
||
describe('AND invalid responseHook', () => { | ||
const pgPoolattributes = { | ||
...DEFAULT_PGPOOL_ATTRIBUTES, | ||
}; | ||
const pgAttributes = { | ||
...DEFAULT_PG_ATTRIBUTES, | ||
[SemanticAttributes.DB_STATEMENT]: query, | ||
}; | ||
|
||
beforeEach(async () => { | ||
create({ | ||
enhancedDatabaseReporting: true, | ||
responseHook: ( | ||
span: Span, | ||
responseInfo: PgResponseHookInformation | ||
) => { | ||
throw 'some kind of failure!'; | ||
}, | ||
}); | ||
}); | ||
|
||
it('should not do any harm when throwing an exception', done => { | ||
const parentSpan = provider | ||
.getTracer('test-pg-pool') | ||
.startSpan('test span'); | ||
context.with(trace.setSpan(context.active(), parentSpan), () => { | ||
const resNoPromise = pool.query(query, (err, result) => { | ||
if (err) { | ||
return done(err); | ||
} | ||
assert.ok(result); | ||
|
||
runCallbackTest( | ||
parentSpan, | ||
pgPoolattributes, | ||
events, | ||
unsetStatus, | ||
2, | ||
0 | ||
); | ||
runCallbackTest( | ||
parentSpan, | ||
pgAttributes, | ||
events, | ||
unsetStatus, | ||
2, | ||
1 | ||
); | ||
done(); | ||
}); | ||
assert.strictEqual( | ||
resNoPromise, | ||
undefined, | ||
'No promise is returned' | ||
); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.