Skip to content

Python: Add various kinds of extractor telemetry - #22502

Open
tausbn wants to merge 3 commits into
mainfrom
tausbn/python-add-various-kinds-of-extractor-telemetry
Open

Python: Add various kinds of extractor telemetry#22502
tausbn wants to merge 3 commits into
mainfrom
tausbn/python-add-various-kinds-of-extractor-telemetry

Conversation

@tausbn

@tausbn tausbn commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Extends the extractor so as to emit the following kinds of telemetry:

  • Python runtime/analysis version. (The latter in particular will tell us the extent to which we still need to support older versions of Python.)
  • How many files were parsed with the old parser, and how many required the new parser. (Which will tell us whether we can get rid of the old parser.)
  • Which non-default extractor flags were used. (Which should inform us as to whether any of these flags can be safely removed or not.)

Each of the above extensions is in its own commit, so I recommend going commit-by-commit.

Here' `python_analysis_version` is the version of Python that we are
analysing the code as. In practice, all we care about is the major
version, but we might as well include the full thing (since it can be
overridden on the command line).

The `python_runtime_version` is the actual version of Python that ran
the extractor.
@tausbn tausbn added the no-change-note-required This PR does not need a change note label Sep 3, 2026
@github-actions github-actions Bot added the Python label Sep 3, 2026
@tausbn
tausbn force-pushed the tausbn/python-add-various-kinds-of-extractor-telemetry branch 2 times, most recently from bc3b4e1 to f728505 Compare September 3, 2026 15:21
Adds statistics on how many files were extracted using the old parser
and using the tree-sitter parser.

Because parsing is done in parallel across many workers, I opted not to
consolidate these statistics for the entire run. Instead, we emit the
statistics for each worker and then need to aggregate themselves after
the telemetry has been ingested. (In practice the number of workers is
~16 at most, so is unlikely to be an issue.)

In terms of implementation, I opted to simply extend the existing
`DiagnosticsWriter` object (instantiatied once per worker) with methods
for counting the number of parsed files, and then thread this object
through to `modules.py` where the magic happens.

Finally, this also required instantiating such an object in cases where
we call directly into the extractor for debugging purposes (e.g. dumping
the AST or CFG). Note that in these cases we do not actually print any
diagnostics, so it's harmless to create these objects.

As for tests, we add a new separate CLI integration test that checks the
behaviour against a database that contains two files -- one that can be
parsed with the old parser and one that requires the new one. The
existing diagnostics test is modified slightly so that it ignores these
statistics (as we cannot guarantee their exact form due to worker
nondeterminism).
Records any non-default extractor flags (without their arguments) as a
normalised string. This will enable us to determine which flags are
actually used (and which ones we might therefore get rid of).

When there are no flags other than the ones the autobuilder injects, we
simply report the string `"default"`. That way, there's no need to
remember exactly which flags are enabled by default during extraction.
@tausbn
tausbn force-pushed the tausbn/python-add-various-kinds-of-extractor-telemetry branch from f728505 to e3dff5e Compare September 3, 2026 20:31
@tausbn
tausbn marked this pull request as ready for review September 3, 2026 20:55
Copilot AI balanced review requested due to automatic review settings September 3, 2026 20:56
@tausbn
tausbn requested review from a team as code owners September 3, 2026 20:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

The telemetry paths are consistently integrated and covered by focused unit and integration tests.

Review tier: Balanced
Findings: None

What changed in this PR

Adds Python extractor telemetry for versions, parser usage, and non-default flags.

Changes:

  • Emits extractor and per-worker parser telemetry.
  • Records parser selection and command-line flags.
  • Adds unit and integration coverage.
File Description
python/​extractor/​tests/​test_diagnostics.py Tests telemetry generation and counters.
python/​extractor/​tests/​test_cmdline.py Tests flag recording.
python/​extractor/​semmle/​worker.py Writes and aggregates telemetry.
python/​extractor/​semmle/​util.py Bumps extractor version.
python/​extractor/​semmle/​python/​passes/​flow.py Supplies a diagnostics writer.
python/​extractor/​semmle/​python/​parser/​dump_ast.py Supplies a diagnostics writer.
python/​extractor/​semmle/​python/​modules.py Records parser usage.
python/​extractor/​semmle/​python/​finder.py Propagates the diagnostics writer.
python/​extractor/​semmle/​logging.py Defines telemetry messages.
python/​extractor/​semmle/​extractors/​py_extractor.py Passes telemetry state to modules.
python/​extractor/​semmle/​extractors/​module_printer.py Propagates the diagnostics writer.
python/​extractor/​semmle/​cmdline.py Records non-default flags.
python/​extractor/​cli-integration-test/​writing-diagnostics/​test_diagnostics_output.py Validates summary telemetry.
python/​extractor/​cli-integration-test/​writing-diagnostics/​diagnostics.expected Updates expected diagnostics.
python/​extractor/​cli-integration-test/​parser-telemetry/​test.sh Runs parser telemetry integration test.
python/​extractor/​cli-integration-test/​parser-telemetry/​test_parser_telemetry.py Validates aggregate parser counts.
python/​extractor/​cli-integration-test/​parser-telemetry/​repo_dir/​tree_sitter_parser.py Exercises Tree-sitter fallback.
python/​extractor/​cli-integration-test/​parser-telemetry/​repo_dir/​old_parser.py Exercises the old parser.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +167 to +169
"extractor_version": "7.1.10",
"python_analysis_version": "3.12",
"python_runtime_version": "3.12.3"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How robust is this going to be under extractor changes and runner updates? Would we need to update the test each time?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It is robust, because the skip_attributes=True argument to check_diagnostics automatically skips the object this field is on. Admittedly that also means we're not really testing these fields, but this .expected file was generated from an actual run, so at the very least it worked when the test was generated.

@jketema jketema Sep 4, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the clarification.

"id": "py/extractor/summary",
"name": "Python extractor telemetry"
},
"timestamp": "2026-09-01T13:41:33.056818Z",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm somewhat amazed that the test passes with this being present in the diagnostic output.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The check_diagnostics helper function automatically skips the timestamp field.

@jketema

jketema commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Question regarding the counting of the number of files parsed with the old and new parser: This happens per worker. How many workers are there normally? One per available core?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-change-note-required This PR does not need a change note Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants