Dynatrace Real User Monitoring (RUM) gives every page, view, user action, and error a name and groups events with the same name together. The defaults work for most frontends. When they don't match how you think about your application—for example, because every product page or every script file creates a group of its own—you can change the names. Use OpenPipeline to rename events without changing your frontend, or report names directly from your code for some event types.
This page explains how names and groups are created, describes the default naming, and shows how to customize names. It also covers what to check before you change a name and how to return to the default behavior.
The name of a page, view, user action, or error isn't only a label—it determines how events are grouped. Events with the same name form one group, and lists, trends, and alerts are calculated per group. You can use the name fields in custom alert conditions, and
Experience Vitals uses groups to show trends and detect anomalies.
Good names are:
Dynatrace names and groups the following user events. Each type has a boolean field that you can use in matching conditions and DQL queries:
characteristics.has_user_actioncharacteristics.has_errorcharacteristics.has_page_summarycharacteristics.has_view_summaryNames and groups are created in three steps:
Because the group is calculated from the name, you never set group IDs yourself. When you rename events, Dynatrace automatically moves them to the group of the new name.
| What | Field | Customize in OpenPipeline | Report using the API |
|---|---|---|---|
User action name |
| Yes | Yes, for user actions that you report through the API ( |
Error name |
| Yes | Yes, in mobile frontends ( |
Page name (web) |
| Yes | No |
View name |
| Yes | No |
Keep in mind:
page.name, a user action named Load /products/:id: keeps its name. Rename the user action as well if you want them to match.Knowing the default names helps you decide what to change and how to match events in your rules.
| Action type | Default name | Example |
|---|---|---|
Page load (web) |
|
|
Navigation (web: soft navigation, mobile: navigation) | interaction |
|
Interaction within a view | interaction |
|
App start (mobile) |
|
|
Reported through the API | The name that you report |
|
User actions that you report through the API have no automatic name. If you don't report a name, Dynatrace doesn't set one.
If the interaction, the UI element, or the view has no value, the name has an empty part, for example click on search:submit on or change on on /easytravel/journeys/:id:. You can fix these names with a rule.
For details about user actions, see User actions in web frontends and Concepts for mobile frontends.
| Error type | Default name | Example |
|---|---|---|
Failed request | Status code and URL without query string |
|
CSP violation | Blocked URI, with the page in parentheses if the URI has no host |
|
Exception, crash, ANR | Script location with line and column, otherwise the message or type |
|
Reported through the API | The name that you report |
|
Exceptions, crashes, and ANRs that don't contain enough information are grouped as ungrouped.
The default name of an error includes the script location. If your script file names or line numbers change with every deployment, you might get a new group for the same error after each release. See Group exceptions from many hosts and Group exceptions by message.
On web frontends, Dynatrace removes the scheme, host, query string, and fragment from the URL and converts the path to lowercase. It also replaces IDs with placeholders: :id: for numbers and hexadecimal IDs, and :uuid: for UUIDs.
| URL | Page name |
|---|---|
|
|
|
|
|
|
Dynatrace replaces dynamic IDs in the path with placeholders (:id:, :uuid:) for better grouping. Other parts of the path, such as product names or language codes, are kept as is, and each unique value creates its own group. To merge such pages, see Collapse pages with readable segments.
By default, the RUM JavaScript uses the URL path to determine page and view names. This is the path view name calculation mode. If your frontend uses a different mode, your view names can differ from these examples.
On mobile frontends, view names are the screen names defined in your app, such as MainActivity. Dynatrace doesn't change them.
For details about pages and views, see Pages, views, and navigations and Concepts for mobile frontends.
You can set names directly in your code for some event types. For details on the API methods, see Customize mobile frontend monitoring using the RUM APIs.
User actions. If you report user actions through the API, set the name with user_action.custom_name. This applies only to user actions that you report yourself. Dynatrace generates the names of other user actions (clicks, navigations, app starts), and you can change them in OpenPipeline.
Errors. Mobile frontends can set error.name for errors that they report. Web frontends can't set error.name—use OpenPipeline for web errors.
Reporting names in your code is a good fit when each team owns its own names; see Best practices.
Use OpenPipeline to change names without changing your frontend. This works for user action, error, page, and view names, including events from frontends that you can't update quickly.
To change names with OpenPipeline
Go to
Settings > Process and contextualize > OpenPipeline > User events and open or create a pipeline for your rules.
In the Processing stage, add a DQL processor. For details, see Processing stage in OpenPipeline.
Define the processor:
Group client errors of API v2.fieldsAdd user_action.name = "Checkout step".Route the events to your pipeline with a dynamic route. Use a matching condition that selects the events that your processors handle, for example isNotNull(characteristics.has_error) for rules that rename errors. For details, see Route data.
Save your changes.
Changes apply to events that arrive after you save the rule. Existing events keep their names.
Matching conditions support:
==, !=, >, >=, <, <=isNotNull(field) and isNull(field)matchesValue(field, "value"), where * matches any characters, for example matchesValue(view.name, "/checkout*")matchesPhrase(field, "phrase")and, or, and notMatching conditions don't support functions such as startsWith or contains. To select user actions or errors, use isNotNull(characteristics.has_user_action) or isNotNull(characteristics.has_error).
Each example shows the problem, the matching condition and processor definition of a DQL processor, and the result. To try an example, create a pipeline and a route as described in Use OpenPipeline. Replace the example values with your own.
Problem. Every step of your checkout creates its own user action, such as click on Next on /checkout/step1, and you want to analyze all checkout interactions together.
Matching condition:
isNotNull(characteristics.has_user_action) and user_action.type == "same_view" and matchesValue(view.name, "/checkout*")
Processor definition:
fieldsAdd user_action.name = "Interact with checkout"
Result. All interactions on checkout views share the name Interact with checkout and form one group. The rule gives the interactions a shared name; it doesn't merge them into a single user action or model the checkout as a sequence.
Problem. Your frontend runs on a separate host name for each tenant, such as https://tenant-a1.apps.com/main.js and https://tenant-b2.apps.com/main.js. The same exception gets a new group for each host name.
Matching condition:
error.type == "exception" and matchesValue(exception.file.full, "https://tenant-*") and matchesValue(exception.file.full, "*.apps.com/main.js")
Processor definition:
fieldsAdd error.name = "Exception https://tenant-*.apps.com/main.js"
Result. Exceptions from main.js on all tenant host names are one error group.
Problem. Your script file names include a hash that changes with every deployment, so the same exception gets a new group after each release.
Matching condition:
error.type == "exception" and isNotNull(exception.message)
Processor definition:
fieldsAdd error.name = exception.message
Result. Exceptions with the same message are one group, independent of the script file.
Use this only if your exception messages are stable. A message that contains IDs or timestamps creates a new group for each event.
Problem. Each failing URL of your API creates its own error group, such as 404: example.com/api/v2/users/… and 404: example.com/api/v2/orders/….
Matching condition:
isNotNull(characteristics.has_error) and error.type == "request" and http.response.status_code >= 400 and http.response.status_code < 500 and matchesValue(url.path, "/api/v2/*")
Processor definition:
fieldsAdd error.name = "API v2 client error"
Result. All 4xx responses from /api/v2/ are one error group.
A custom error name replaces the automatic grouping, so fatal and non-fatal errors with the same custom name are also one group. Apply a rule like this to errors of one kind.
Problem. You want to see on which continent a CSP violation happens, but all continents are in one group per page.
Matching condition:
error.type == "csp"
Processor definition:
fieldsAdd error.name = concat(csp.document_uri.path, " ", geo.continent.name)
Result. Error groups such as /easytravel/home Europe and /easytravel/home Asia. Each value that you add multiplies the number of groups, so add only values that have few distinct values.
Problem. Every product has its own page name, such as /products/blue-running-shoes, and you want to analyze product pages as one page. Because the user action that loads the page is named after the page, you need a second rule for it.
Rule 1: page name
Matching condition:
matchesValue(page.name, "/products/*")
Processor definition:
fieldsAdd page.name = "/products/:slug:"
Rule 2: user action name
Matching condition:
user_action.type == "hard_navigation" and matchesValue(user_action.name, "Load /products/*")
Processor definition:
fieldsAdd user_action.name = "Load /products/:slug:"
Result. Product pages form one page group, and the actions that load them form one user action group.
Problem. Your Android app reports technical class names as view names.
Matching condition:
view.name == "com.example.app.ui.checkout.CheckoutFragment"
Processor definition:
fieldsAdd view.name = "Checkout"
Result. The view appears as Checkout. User action names that were built from the old view name keep it, so add a rule for them if you want to rename them too.
Look at your current names before you change them, and again after you save a rule. Run the queries in
Notebooks.
Events are grouped by name. The queries below also break the results down by type (user_action.type, error.type) because the same name can occur for more than one type after you customize it. We recommend keeping the type in your analysis: it shows how a name is distributed across types and helps you spot rules that are too broad.
Use this query to see your current user action names and find groups that you might want to merge or rename.
fetch user.events, from: now() - 24h| filter characteristics.has_user_action//| filter frontend.name == "FRONTEND-NAME" // Optional: filter to a specific frontend| summarize count = count(), by: { user_action.name, user_action.type }| sort count desc| limit 50
Use this query to see your current error groups and identify groups that are too fine-grained or too broad.
fetch user.events, from: now() - 24h| filter characteristics.has_error//| filter frontend.name == "FRONTEND-NAME" // Optional: filter to a specific frontend| summarize count = count(), by: { error.name, error.type }| sort count desc| limit 50
Use this query to check whether your errors are grouped too finely. A high share of groups with only one event suggests that the default grouping creates too many groups.
fetch user.events, from: now() - 24h| filter characteristics.has_error//| filter frontend.name == "FRONTEND-NAME" // Optional: filter to a specific frontend| summarize count = count(), by: { error.name }| summarize total_groups = count(), single_event_groups = countIf(count == 1)
Use this query before you create a rule that groups exceptions by message. It compares the current number of groups with the number you would get.
fetch user.events, from: now() - 24h| filter characteristics.has_error and error.type == "exception"//| filter frontend.name == "FRONTEND-NAME" // Optional: filter to a specific frontend| summarize current_groups = countDistinct(error.name), groups_by_message = countDistinct(exception.message)
Use this query to see your current page names and find pages that create too many groups, such as pages with product names or IDs in the path.
fetch user.events, from: now() - 24h//| filter frontend.name == "FRONTEND-NAME" // Optional: filter to a specific frontend| filter isNotNull(page.name)| summarize events = count(), by: { page.name }| sort events desc| limit 100
Renaming changes how your data is grouped, which affects what you see and what you've set up on top of it.
Renaming events moves them to a new group. Alerts, trends, and baselines for the old group don't carry over. Review your setup after each change.
To reduce the impact
Experience Vitals after saving.If many teams build frontends in the same environment, maintaining all naming rules centrally in OpenPipeline gets difficult: each new frontend or frontend version can require new rules.
user_action.custom_name from the code that the team owns.<area> <action> <object>, such as checkout submit order. Don't include versions, build numbers, or wording that changes often.If a rule produces results that you don't want, remove it, and Dynatrace uses the default names again.
user_action.name, error.name, page.name, or view.name, and disable them to test the effect or delete them to remove the rules permanently.If you report names from your frontend, remove user_action.custom_name (or error.name in mobile frontends) from your code and release the frontend. User actions that you report through the API have no default name. Dynatrace doesn't name them until you report a name.
Returning to the default behavior is also a grouping change. Events that arrive after you remove the rule go back to the default groups, and the groups created by your rule stop receiving events. If events were in the default groups before you added the rule, new events continue there, and the history shows a gap for the period in which the rule was active. Existing events keep their names. See Before you change a name.
To verify the result, list the names of new events. Names that only your rule produced no longer appear, and new events follow the patterns in Default naming. A name can remain if another rule, your frontend, or the default naming also produces it. The following query lists the user action names of the last hour:
fetch user.events, from: now() - 1h| filter characteristics.has_user_action//| filter frontend.name == "FRONTEND-NAME" // Optional: filter to a specific frontend| summarize count = count(), by: { user_action.name, user_action.type }| sort count desc
For errors, group by error.name and error.has_custom_name, which is true for custom error names.
| Field | Description |
|---|---|
| Name of the user action. |
| Type of the user action, for example |
| Name that you report through the API for a user action. Dynatrace copies it to |
|
|
| Name of the error. |
| Type of the error: |
|
|
| Name of the page (web). |
| Name of the view. |
| Name of the view from which a navigation started. |