Skip to content

feat(grouping): Add better support for native fingerprinting/grouping use-cases#102653

Closed
mujacica wants to merge 13 commits into
masterfrom
feat/native-grouping
Closed

feat(grouping): Add better support for native fingerprinting/grouping use-cases#102653
mujacica wants to merge 13 commits into
masterfrom
feat/native-grouping

Conversation

@mujacica

@mujacica mujacica commented Nov 4, 2025

Copy link
Copy Markdown
Contributor
  • Added support for fingerprinting based on the thread info
    thread.name:MainThread type:RuntimeError -> main-thread-error
    thread.crashed:true -> crashed-thread

  • Added support sibling matching for fingerprinting
    [ function:handler ] | function:process -> handler-process

  • Added support for thread info in client-side fingerprinting
    Sentry.setFingerprint(["{{ thread.name }}", "{{ transaction }}"]);
    sentry_sdk.set_fingerprint(["{{ thread.name }}", "database-error"])

@codecov

codecov Bot commented Nov 4, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.37748% with 10 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/sentry/grouping/fingerprinting/rules.py 86.84% 5 Missing ⚠️
src/sentry/grouping/fingerprinting/matchers.py 94.64% 3 Missing ⚠️
src/sentry/grouping/fingerprinting/parser.py 91.30% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##           master   #102653    +/-   ##
=========================================
  Coverage   80.41%    80.42%            
=========================================
  Files        9393      9394     +1     
  Lines      403390    403628   +238     
  Branches    25923     25923            
=========================================
+ Hits       324400    324613   +213     
- Misses      78550     78575    +25     
  Partials      440       440            

@lobsterkatie lobsterkatie left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks good!

My only question is if the tests would be better as snapshot tests, because then we'd be able to do versioned tests, the same way we do with enhancement rules. It would also allow you to get rid of some of the boilerplate in these tests. WDYT?

@mujacica mujacica force-pushed the feat/native-grouping branch from e4cdb9c to fe55639 Compare November 21, 2025 13:01
@mujacica mujacica marked this pull request as ready for review November 21, 2025 13:53
@mujacica mujacica requested a review from a team as a code owner November 21, 2025 13:53
Comment thread src/sentry/grouping/fingerprinting/matchers.py
Comment thread src/sentry/grouping/fingerprinting/matchers.py Outdated
Comment thread src/sentry/grouping/fingerprinting/matchers.py
@armenzg armenzg requested a review from lobsterkatie November 21, 2025 14:04
@getsantry

getsantry Bot commented Dec 13, 2025

Copy link
Copy Markdown
Contributor

This pull request has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you add the label WIP, I will leave it alone unless WIP is removed ... forever!


"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀

@cursor cursor Bot 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.

Bug: Thread matcher JSON round-trip fails on deserialization

The thread matchers cannot be properly deserialized from JSON after serialization. The _to_config_structure method serializes using the internal key (e.g., "thread_name"), but _from_config_structure passes this key directly to FingerprintMatcher.__init__, which expects the external key (e.g., "thread.name") to look up in MATCHERS. Since "thread_name" is not a key in MATCHERS (only a value), deserialization fails with InvalidFingerprintingConfig. This affects all new thread matchers (thread.id, thread.name, thread.state, thread.crashed, thread.current) and breaks any workflow that saves fingerprinting configs to JSON and loads them back, like to_json() followed by from_json().

src/sentry/grouping/fingerprinting/matchers.py#L140-L174

def _to_config_structure(self) -> list[str]:
key = self.key
if self.negated:
key = "!" + key
return [key, self.pattern]
@classmethod
def _from_config_structure(
cls, matcher: list[str]
) -> FingerprintMatcher | CallerMatcher | CalleeMatcher:
key, pattern = matcher
# Check for sibling matcher syntax
# CallerMatcher: [key]| or [!key]|
# CalleeMatcher: |[key] or |[!key]
if key.startswith("[") and key.endswith("]|"):
inner_key = key[1:-2] # Remove [ and ]|
negated = inner_key.startswith("!")
inner_key = inner_key.lstrip("!")
inner_matcher = cls(inner_key, pattern, negated)
return CallerMatcher(inner_matcher)
if key.startswith("|[") and key.endswith("]"):
inner_key = key[2:-1] # Remove |[ and ]
negated = inner_key.startswith("!")
inner_key = inner_key.lstrip("!")
inner_matcher = cls(inner_key, pattern, negated)
return CalleeMatcher(inner_matcher)
# Regular matcher
negated = key.startswith("!")
key = key.lstrip("!")
return cls(key, pattern, negated)

Fix in Cursor Fix in Web


@getsantry

getsantry Bot commented Jan 6, 2026

Copy link
Copy Markdown
Contributor

This pull request has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you add the label WIP, I will leave it alone unless WIP is removed ... forever!


"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀

@getsantry getsantry Bot closed this Jan 14, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Jan 29, 2026
@mujacica

Copy link
Copy Markdown
Contributor Author

Hey @lobsterkatie - any more info/insights for this one - I would like to slowly start integrating this. You mentioned snapshot testing as a potential improvement - I tried it out but without a lot of success. Is that blocking for the merge?

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

Labels

Scope: Backend Automatically applied to PRs that change backend components Stale

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants