Custom Grouping Enhancements
If you use stack traces for grouping, the enhancements rules influence the data that feed into that algorithm. These rules can be configured on a per-project basis under Project Settings > General Settings > Grouping Settings.
Enhancements are rules written in a pretty straightforward way. Each line is a single enhancement rule. It's one or multiple match expressions followed by one or multiple actions to be executed when all expressions match. All rules are executed from top to bottom on all frames in the stack trace.
The syntax for grouping enhancements is similar to:
matcher-name:expression other-matcher:expression ... action1 action2 ...
The syntax follows the syntax from discover queries. If you want to negate
the match, you can prefix the expression with an exclamation mark (
The following is a practical example of how this looks:
These matchers are available; multiple matchers can be defined in a line:
Matches on the general platform family, which currently includes
other. Comma separate rules to apply them to multiple platforms.
This matches case insensitive with Unix glob behavior on a path in a stack trace.
The path separators are normalized to
/. As a special rule, if the filename is
relative, it still matches on
# match on all files under `project` with a `.c` extension stack.abs_path:**/project/**.c` +app # matches on vendor/foo without sub folders stack.abs_path:**/vendor/foo/*.c` -app # matches on `foo.c` as well as `foo/bar.c`. stack.abs_path:**/*.gen.c` -group
Module is similar to
path but matches on the
module. This is not used for Native,
sensitive, and normal globbing is available. Note that modules are not packages,
which can be confusing for native environments.
Matches on a function in a stack trace, and is case sensitive with normal globbing.
stack.function:myproject_* +app stack.function:malloc -group
Matches on a package in a stack trace. The package is the container that contains a function or module.
This is a
.dylib or similar. The same matching rules as for
path apply (For example, this is typically an absolute path).
Matches on the current state of the in-app flag of a stack trace frame.
means the frame is in app,
no means it's not.
There are two types of actions: flag setting and setting variables.
- flag: flags identify the action to be taken if all matchers match. A flag needs to be prefixed with
+to set it or
-to unset it. If this expression is prefixed with a
^, it applies to frames above the frame (toward the crash). If prefixed with
vit applies to frames below the frame (away from the crash). For instance,
-group ^-groupremoves the matching frame and all frames above it from the grouping.
app: marks or unmarks a frame in-app
group: adds or removes a frame from grouping
- variables: additionally variables can be set (
variable=value). Currently, there is just one:
max-frames: sets the total number of frames to be considered for grouping. The default is
0which means "all frames." If set to
3, only the top 3 frames are considered.
If a line is prefixed with a hash (
#), it's a comment and ignored.
stack.abs_path:**/node_modules/** -group stack.abs_path:**/app/utils/requestError.jsx -group stack.abs_path:**src/getsentry/src/getsentry/** +app family:native max-frames=3 stack.function:fetchSavedSearches v-group stack.abs_path:**/app/views/**.jsx stack.function:fetchData ^-group family:native stack.function:SpawnThread v-app -app family:native stack.function:_NSRaiseError ^-group -app family:native stack.function:std::* -app family:native stack.function:core::* -app
These recommendations will greatly improve your out of the box grouping experience.
For instance, the following marks as in-app all frames that are below a specific C++ namespace:
You can also achieve the same result by marking other frames "not in-app." However, if that's the case, you should ensure that first all frames are set to "in-app" to override the defaults:
app:no +app stack.function:std::* -app stack.function:boost::* -app
You need to force all frames to be in-app first because there might already have been some defaults set by the client SDK or earlier processing.
In many cases, you want to chop off the top or bottom of the stack trace. For instance, many code bases use a common function to generate an error. In this case, the error machinery will appear as part of the stack trace. For example, if you use Rust, you likely want to remove some frames that are related to panic handling:
stack.function:std::panicking::begin_panic ^-app -app ^-group stack.function:core::panicking::begin_panic ^-app -app ^-group
Here we tell the system that all frames from begin-panic to the crash location are not part of the application (including the panic frame itself). All frames above are also in all cases irrelevant for grouping.
Likewise, you can also chop off the base of a stack trace. This is particularly useful if you have different main loops that drive an application:
stack.function:myapp::LinuxMainLoop v-group -group stack.function:myapp::MacMainLoop v-group -group stack.function:myapp::WinMainLoop v-group -group
This isn't useful for all projects, but it can work well for large applications with many crashes. The default strategy is to consider most of the stack trace relevant for grouping. This means that every different stack trace that leads to a crashing function will cause a different group to be created. If you do not want that, you can alternatively force the groups to be much larger by limiting how many frames should be considered.
For instance, if any of the frames in the stack trace refer to a common external library, you could tell the system to only consider the top N frames, :
# always only consider the top 1 frame for all native events family:native max-frames=1 # if the bug is in proprietarymodule.so, only consider top 2 frames family:native stack.package:**/proprietarymodule.so max-frames=2 # these are functions we want to consider much more of the stack trace for family:native stack.function:KnownBadFunction1 max-frames=5 family:native stack.function:KnownBadFunction2 max-frames=5