Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(pg): fix instrumentation of ESM-imported pg #1701

Merged
merged 5 commits into from
Oct 17, 2023

Conversation

trentm
Copy link
Contributor

@trentm trentm commented Sep 27, 2023

The ESM imported top-level object is a Module Namespace Object per ECMA262 spec that is, apparently, incompatible with the 'PG' class object that 'pg' returns. The ".defaults" holds the equivalent of require('pg').

Fixes: #1693


This is a similar fix to #1694. See the discussion there on the use of module[Symbol.toStringTag] === 'Module' to sniff out ESM.

A dump of moduleExports before this change, when loading pg as ESM is as follows. This shows how the PG instance export is replaced with the [Module: null prototype] and how .default holds the top-level CommonJS exports.

[Module: null prototype] {
  default: PG {
    defaults: {
      host: 'localhost',
      user: 'trentm',
      database: undefined,
      password: null,
      connectionString: undefined,
      port: 5432,
      rows: 0,
      binary: false,
      max: 10,
      idleTimeoutMillis: 30000,
      client_encoding: '',
      ssl: false,
      application_name: undefined,
      fallback_application_name: undefined,
      options: undefined,
      parseInputDatesAsUTC: false,
      statement_timeout: false,
      idle_in_transaction_session_timeout: false,
      query_timeout: false,
      connect_timeout: 0,
      keepalives: 1,
      keepalives_idle: 0,
      parseInt8: [Setter]
    },
    Client: [class Client extends EventEmitter] {
      Query: [class Query extends EventEmitter]
    },
    Query: [class Query extends EventEmitter],
    Pool: [class BoundPool extends Pool],
    _pools: [],
    Connection: [class Connection extends EventEmitter],
    types: {
      getTypeParser: [Function: getTypeParser],
      setTypeParser: [Function: setTypeParser],
      arrayParser: [Object],
      builtins: [Object]
    },
    DatabaseError: [class DatabaseError extends Error]
  }
}

Checklist

  • Decide whether and how to add a test case for this. I could add a separate npm run test:esm. The downside of that is that the npm run test:local version of this will stop and start a Postgres instance once for CommonJS tests (*.test.js) and then once again for ESM tests (*.test.mjs).
  • Deal with TypeScript-related lint errors.

The ESM imported top-level object is a Module Namespace Object
per ECMA262 spec that is, apparently, incompatible with the
'PG' class object that 'pg' returns. The "<module>.defaults"
holds the equivalent of `require('pg')`.
@trentm trentm requested a review from a team September 27, 2023 15:43
@codecov
Copy link

codecov bot commented Sep 27, 2023

Codecov Report

Merging #1701 (7246328) into main (7b457cd) will decrease coverage by 0.05%.
The diff coverage is 44.44%.

@@            Coverage Diff             @@
##             main    #1701      +/-   ##
==========================================
- Coverage   91.67%   91.62%   -0.05%     
==========================================
  Files         139      139              
  Lines        7145     7151       +6     
  Branches     1440     1444       +4     
==========================================
+ Hits         6550     6552       +2     
- Misses        595      599       +4     
Files Coverage Δ
...elemetry-instrumentation-pg/src/instrumentation.ts 88.96% <44.44%> (-2.26%) ⬇️

@trentm
Copy link
Contributor Author

trentm commented Sep 27, 2023

  • Deal with TypeScript-related lint errors.

Oh, lint passes. There are a number of warnings from npm run lint, but I guess those are okay. Most of those warnings existed before my change.

@pichlermarc pichlermarc added bug Something isn't working priority:p1 Bugs which cause problems in end-user applications such as crashes, data inconsistencies pkg:instrumentation-pg labels Oct 11, 2023
@pichlermarc
Copy link
Member

pichlermarc commented Oct 12, 2023

Decide whether and how to add a test case for this. I could add a separate npm run test:esm. The downside of that is that the npm run test:local version of this will stop and start a Postgres instance once for CommonJS tests (.test.js) and then once again for ESM tests (.test.mjs).

I would consider this an acceptable trade-off for testing this. 👍
We could also add more scripts for local testing: test:local:cjs, test:local:esm that are both run by test:local - this way one can test both individually when working on the package. I think the important part would be to have the ESM tests run in the unit-testing and TAV workflows.

Edit: created #1731 to come up with a testing strategy for ESM - we'll need this going forward

Copy link
Member

@pichlermarc pichlermarc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking care of this! 🙂

@pichlermarc pichlermarc linked an issue Oct 17, 2023 that may be closed by this pull request
@pichlermarc pichlermarc merged commit 2502e18 into open-telemetry:main Oct 17, 2023
15 of 16 checks passed
@dyladan dyladan mentioned this pull request Oct 17, 2023
@trentm trentm deleted the tm-issue1693-pg-esm branch October 17, 2023 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working pkg:instrumentation-pg priority:p1 Bugs which cause problems in end-user applications such as crashes, data inconsistencies
Projects
None yet
Development

Successfully merging this pull request may close these issues.

pg: cannot instrument an ESM-imported pg pg instrumentation crashes when using ES module.
3 participants