feat: Add APPMAP_DISPLAY_LABELED_PARAMS to capture params for labeled functions#384
feat: Add APPMAP_DISPLAY_LABELED_PARAMS to capture params for labeled functions#384dividedmind merged 2 commits intomasterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new configuration knob to selectively capture parameter/return-value details (via repr() and schema) for labeled functions even when global parameter capture is disabled, improving visibility for semantically important calls without enabling full parameter capture everywhere.
Changes:
- Introduces
APPMAP_DISPLAY_LABELED_PARAMS(defaulttrue) and threads it through initialization andEnv. - Propagates “has labels” metadata through instrumentation so event value rendering can decide whether to display details.
- Adds tests and test fixtures validating labeled vs unlabeled behavior under different env settings.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
appmap/__init__.py |
Initializes _APPMAP_DISPLAY_LABELED_PARAMS from APPMAP_DISPLAY_LABELED_PARAMS (default true) when AppMap is enabled. |
_appmap/env.py |
Adds display_labeled_params to Env for runtime checks. |
_appmap/event.py |
Adds _should_display(has_labels) gating and plumbs has_labels into parameter/return value description logic. |
_appmap/instrument.py |
Detects whether the function has labels and forwards has_labels into param/return event creation. |
_appmap/test/conftest.py |
Ensures tests initialize _APPMAP_DISPLAY_LABELED_PARAMS for deterministic behavior. |
_appmap/test/test_events.py |
Adds coverage for labeled/unlabeled param/return display behavior under env combinations. |
_appmap/test/data/example_class.py |
Adds a labeled method that takes a parameter for exercising the new behavior in tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
dividedmind
left a comment
There was a problem hiding this comment.
I like this change, however in my opinion there's a better UX than adding another envar: APPMAP_DISPLAY_PARAMS could be true to force all parameters being captured, false to none, and unset (or, maybe, set to auto or labeled? in any case, the default) to only capture on the labeled functions. WDYT? Having two variables can be confusing — it's unclear what their interaction is.
6471e4d to
1e60a85
Compare
@kgilpin , I went ahead and implemented this change, can you take a look if it looks okay? Note when merging the commits should be squashed and a new unified commit message written. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| _display_params = os.environ.get("APPMAP_DISPLAY_PARAMS", "labeled") | ||
| os.environ.setdefault("_APPMAP_DISPLAY_PARAMS", _display_params) |
There was a problem hiding this comment.
PR title/description mention a new env var APPMAP_DISPLAY_LABELED_PARAMS, but the implementation here instead changes the default and accepted values of APPMAP_DISPLAY_PARAMS (e.g. defaulting to "labeled"). There are no references to APPMAP_DISPLAY_LABELED_PARAMS in the repo, so either the new env var needs to be implemented as described, or the PR metadata/docs should be updated to match the actual behavior and configuration surface.
There was a problem hiding this comment.
This shall be resolved in the final commit message. I'm reluctant to change the description and title of this collaborative PR to not distort the history.
| display_params = self._env.get("_APPMAP_DISPLAY_PARAMS", "labeled").lower() | ||
| if display_params == "true": | ||
| self._display_params = True | ||
| self._display_labeled_params = True | ||
| elif display_params == "false": | ||
| self._display_params = False | ||
| self._display_labeled_params = False | ||
| else: # "labeled" or "auto" or anything else defaults to labeled | ||
| self._display_params = False | ||
| self._display_labeled_params = True |
There was a problem hiding this comment.
The parsing logic treats any value other than "true"/"false" as "labeled" (including typos). That makes it easy to accidentally enable labeled parameter capture when the intent was to disable it. Consider validating against an explicit allowlist (e.g., true/false/labeled), and for invalid values log a warning and fall back to the safest behavior (typically fully disabled).
There was a problem hiding this comment.
In principle you're right, but I'm not very concerned about it. The other variables aren't defensive like this and I don't think we should make this one any different.
1e60a85 to
404a74d
Compare
I would have been fine with it either way so I'm ok with this. It makes it tricky to add another case - but we don't have plans for another case anyway. |
LGTM. You're actually the reviewer so I can't Approve the PR (I opened it). 🛳️ Thanks for contributing to this PR! |
404a74d to
a32893d
Compare
Introduces a new mode to APPMAP_DISPLAY_PARAMS, which now can be: - 'true': capture argument values for all functions, - 'false': disable all argument value capture, - 'labeled' (new, default): capture only for labeled functions. The labeled default provides useful argument visibility for semantically important functions (such as HTTP, crypto, etc.) without the performance cost of global capture. The capture policy is evaluated once per function at instrumentation time and cached on the `_InstrumentedFn` tuple, eliminating per-call environment lookups from the hot path. Co-Authored-By: kgilpin <kgilpin@gmail.com>
a32893d to
b324b48
Compare
Adds a new env var
APPMAP_DISPLAY_LABELED_PARAMS (default: true)that enablesstrandrepr()-based parameter and return value capture for functions that have labels, even whenAPPMAP_DISPLAY_PARAMSis off. This provides useful parameter visibility for semantically important functions (HTTP, crypto, serialization, etc.) without the performance cost of capturing all parameters globally.