@@ -18,6 +18,7 @@ import {
1818 InstrumentationBase ,
1919 InstrumentationNodeModuleDefinition ,
2020 safeExecuteInTheMiddle ,
21+ InstrumentationNodeModuleFile ,
2122} from '@opentelemetry/instrumentation' ;
2223import {
2324 context ,
@@ -67,6 +68,12 @@ import {
6768 ATTR_DB_OPERATION_NAME ,
6869} from '@opentelemetry/semantic-conventions/incubating' ;
6970
71+ function extractModuleExports ( module : any ) {
72+ return module [ Symbol . toStringTag ] === 'Module'
73+ ? module . default // ESM
74+ : module ; // CommonJS
75+ }
76+
7077export class PgInstrumentation extends InstrumentationBase < PgInstrumentationConfig > {
7178 private _operationDuration ! : Histogram ;
7279 private _connectionsCount ! : UpDownCounter ;
@@ -125,45 +132,33 @@ export class PgInstrumentation extends InstrumentationBase<PgInstrumentationConf
125132 }
126133
127134 protected init ( ) {
128- const modulePG = new InstrumentationNodeModuleDefinition (
129- 'pg' ,
130- [ '>=8.0.3 <9' ] ,
131- ( module : any ) => {
132- const moduleExports : typeof pgTypes =
133- module [ Symbol . toStringTag ] === 'Module'
134- ? module . default // ESM
135- : module ; // CommonJS
136- if ( isWrapped ( moduleExports . Client . prototype . query ) ) {
137- this . _unwrap ( moduleExports . Client . prototype , 'query' ) ;
138- }
139-
140- if ( isWrapped ( moduleExports . Client . prototype . connect ) ) {
141- this . _unwrap ( moduleExports . Client . prototype , 'connect' ) ;
142- }
135+ const SUPPORTED_PG_VERSIONS = [ '>=8.0.3 <9' ] ;
143136
144- this . _wrap (
145- moduleExports . Client . prototype ,
146- 'query' ,
147- this . _getClientQueryPatch ( ) as any
148- ) ;
137+ const modulePgNativeClient = new InstrumentationNodeModuleFile (
138+ 'pg/lib/native/client.js' ,
139+ SUPPORTED_PG_VERSIONS ,
140+ this . _patchPgClient . bind ( this ) ,
141+ this . _unpatchPgClient . bind ( this )
142+ ) ;
149143
150- this . _wrap (
151- moduleExports . Client . prototype ,
152- 'connect' ,
153- this . _getClientConnectPatch ( ) as any
154- ) ;
144+ const modulePgClient = new InstrumentationNodeModuleFile (
145+ 'pg/lib/client.js' ,
146+ SUPPORTED_PG_VERSIONS ,
147+ this . _patchPgClient . bind ( this ) ,
148+ this . _unpatchPgClient . bind ( this )
149+ ) ;
155150
151+ const modulePG = new InstrumentationNodeModuleDefinition (
152+ 'pg' ,
153+ SUPPORTED_PG_VERSIONS ,
154+ ( module : any ) => {
155+ this . _patchPgClient ( module . Client ) ;
156156 return module ;
157157 } ,
158158 ( module : any ) => {
159- const moduleExports : typeof pgTypes =
160- module [ Symbol . toStringTag ] === 'Module'
161- ? module . default // ESM
162- : module ; // CommonJS
163- if ( isWrapped ( moduleExports . Client . prototype . query ) ) {
164- this . _unwrap ( moduleExports . Client . prototype , 'query' ) ;
165- }
166- }
159+ this . _unpatchPgClient ( module . Client ) ;
160+ return module ;
161+ } , [ modulePgClient , modulePgNativeClient ]
167162 ) ;
168163
169164 const modulePGPool = new InstrumentationNodeModuleDefinition (
@@ -190,6 +185,51 @@ export class PgInstrumentation extends InstrumentationBase<PgInstrumentationConf
190185 return [ modulePG , modulePGPool ] ;
191186 }
192187
188+ private _patchPgClient (
189+ module : any ,
190+ ) {
191+ const moduleExports = extractModuleExports ( module ) ;
192+
193+ if ( isWrapped ( moduleExports . prototype . query ) ) {
194+ this . _unwrap ( moduleExports . prototype , 'query' ) ;
195+ }
196+
197+ if ( isWrapped ( moduleExports . prototype . connect ) ) {
198+ this . _unwrap ( moduleExports . prototype , 'connect' ) ;
199+ }
200+
201+ this . _wrap (
202+ moduleExports . prototype ,
203+ 'query' ,
204+ this . _getClientQueryPatch ( ) as any
205+ ) ;
206+
207+ this . _wrap (
208+ moduleExports . prototype ,
209+ 'connect' ,
210+ this . _getClientConnectPatch ( ) as any
211+ ) ;
212+
213+ return module ;
214+ }
215+
216+ private _unpatchPgClient (
217+ module : any ,
218+ ) {
219+ const moduleExports = extractModuleExports ( module ) ;
220+
221+ if ( isWrapped ( moduleExports . prototype . query ) ) {
222+ this . _unwrap ( moduleExports . prototype , 'query' ) ;
223+ }
224+
225+ if ( isWrapped ( moduleExports . prototype . connect ) ) {
226+ this . _unwrap ( moduleExports . prototype , 'connect' ) ;
227+ }
228+
229+ return module ;
230+ }
231+
232+
193233 private _getClientConnectPatch ( ) {
194234 const plugin = this ;
195235 return ( original : PgClientConnect ) => {
@@ -272,12 +312,12 @@ export class PgInstrumentation extends InstrumentationBase<PgInstrumentationConf
272312 // to properly narrow arg0, but TS 4.3.5 does not.
273313 const queryConfig = firstArgIsString
274314 ? {
275- text : arg0 as string ,
276- values : Array . isArray ( args [ 1 ] ) ? args [ 1 ] : undefined ,
277- }
315+ text : arg0 as string ,
316+ values : Array . isArray ( args [ 1 ] ) ? args [ 1 ] : undefined ,
317+ }
278318 : firstArgIsQueryObjectWithText
279- ? ( arg0 as utils . ObjectWithText )
280- : undefined ;
319+ ? ( arg0 as utils . ObjectWithText )
320+ : undefined ;
281321
282322 const attributes : Attributes = {
283323 [ SEMATTRS_DB_SYSTEM ] : DBSYSTEMVALUES_POSTGRESQL ,
0 commit comments