Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Browser UserAction Event #1941

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions docs/browser/events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<!--- Hugo front matter used to generate the website version of this page:
linkTitle: Events
--->

# Semantic conventions for browser events

**Status**: [Development][DocumentStatus]

This document defines semantic conventions for browser (web) instrumentations
that emit events.

## UserAction Event

<!-- semconv event.browser.user_action -->
<!-- NOTE: THIS TEXT IS AUTOGENERATED. DO NOT EDIT BY HAND. -->
<!-- see templates/registry/markdown/snippet.md.j2 -->
<!-- prettier-ignore-start -->
<!-- markdownlint-capture -->
<!-- markdownlint-disable -->

**Status:** ![Development](https://img.shields.io/badge/-development-blue)

The event name MUST be `browser.user_action`.

This event describes actions performed by the user such as click, scroll, zoom, resize, etc.

**Body fields:**

| Body Field | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
| `click_coordinates` | string | Click coordinates captured as a string in the format {x}X{y}. | `345X23` | `Recommended` | ![Development](https://img.shields.io/badge/-development-blue) |
| `element` | string | Target element tag name and it is obtained via event.target.tagName. | `button` | `Recommended` | ![Development](https://img.shields.io/badge/-development-blue) |
| `element_xpath` | string | Target element xpath | `//*[@id='testBtn']` | `Recommended` | ![Development](https://img.shields.io/badge/-development-blue) |
| `tags` | string | Grab data from data-otel-* attributes in tree. | `id` | `Recommended` | ![Development](https://img.shields.io/badge/-development-blue) |
| `user_action_type` | enum | Type of interaction. See enum [here](https://github.com/microsoft/ApplicationInsights-JS/blob/main/extensions/applicationinsights-clickanalytics-js/src/Enums.ts) for potential values we could add support for. | `cl` | `Required` | ![Development](https://img.shields.io/badge/-development-blue) |

`user_action_type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.

| Value | Description | Stability |
|---|---|---|
| `cl` | An element is left clicked by a user. | ![Development](https://img.shields.io/badge/-development-blue) |
| `cm` | An element is middle clicked by a user. | ![Development](https://img.shields.io/badge/-development-blue) |
| `cr` | An element is right clicked by a user. | ![Development](https://img.shields.io/badge/-development-blue) |
| `ke` | An element is entered via keyboard by a user. | ![Development](https://img.shields.io/badge/-development-blue) |
| `ks` | A space is entered via keyboard by a user. | ![Development](https://img.shields.io/badge/-development-blue) |
| `o` | User actions that are not listed above. | ![Development](https://img.shields.io/badge/-development-blue) |
| `r` | An element is resized by a user. | ![Development](https://img.shields.io/badge/-development-blue) |
| `s` | An element is scrolled by a user. | ![Development](https://img.shields.io/badge/-development-blue) |
| `z` | An element is zoomed by a user. | ![Development](https://img.shields.io/badge/-development-blue) |

<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- END AUTOGENERATED TEXT -->
<!-- endsemconv -->

[DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status
82 changes: 82 additions & 0 deletions model/browser/events.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
groups:
- id: event.browser.user_action
Copy link
Author

Choose a reason for hiding this comment

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

May use client?

stability: development
type: event
name: browser.user_action
Copy link
Contributor

@breedx-splk breedx-splk Mar 4, 2025

Choose a reason for hiding this comment

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

Do we think there's an opportunity to use another prefix/namespace other than browser? It seems like this is something that mobile (ios/android) could certainly also benefit from as well. If we can't make it broader to support multiple clients, then I fear we will encounter duplication later. I also undertand if the answer is "no, it doesn't make sense because browser already has all this stuff (eg. element xpath below, etc)"...but I think we should at least consider it.

Possible alternative namespaces: client.user_action, app.user_action, ux.action...

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe, but that is a larger discussion for the Client SIG. We can always deprecate this event in favor of any stable standard. But generally it would be "nice" to have to define a commonly used event once -- but there are some very browser centric definitions here at the moment.

brief: >
This event describes actions performed by the user such as click, scroll, zoom, resize, etc.
body:
Copy link
Contributor

Choose a reason for hiding this comment

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

I would like to see a comment here to clarify that this is temporary or that this will actually be an attribute. That way readers do not expect to find content in the actual body.

id: browser.user_action
requirement_level: required
stability: development
type: map
fields:
- id: element
Copy link
Member

Choose a reason for hiding this comment

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

let's try to follow attribute naming guidelines since we'll be moving these to (complex) attributes in the future

Suggested change
- id: element
- id: element.tag.name

Copy link
Contributor

Choose a reason for hiding this comment

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

@trask Sorry No!
These are NOT top-level attributes and do not (and should not) conform to the full attribute naming guidelines (ONLY top-level attributes should and MUST conform to that specification) -- NOT the contents of the body / value of a complex attribute.

If / when the body becomes a standard complex attribute then there will need to be a convention in place about how these event specific attributes are named, which will most likely need to include the actual event name as the prefix (browser.user_action.[payload/data] -- for a single complete attribute).

Then there is just the overhead of creating individual on-off fields (only used for a single event) and going through the approvals / discussions about each individual field and how it can / should be made generic. Vs having a single discussion about the "naming" of fields within a specific event. If / When the community decides that they want to reuse the same type of "thing" identified by the individual event specific name, then at that point for those few fields (like the already defined url.full) it makes sense to have the broader naming / namespace discussions and then the event specific "changes" to pass that value as a top-level attribute rather than in the single value body / payload complex attribute.

While I know there has been discussions about "allowing" complex types to be defined as individual fields but sent in a complete manner, this is would not scalable and would also mean that for every event specific field for every event the names would become something like browser.user_action.XXXX, so not whenever an event has to be constructed the these long attribute names have to be constructed (and destructed -- for transport). This WILL result in

  • larger code sizes (if these are included in the global semantic conventions and consumed) -- yes instrumentations could construct by thats another issue
  • larger install sizes (for servers) if these are now included in the global semantic conventions
  • More CPU used in constructing these events (to create the log record) and then even more to convert and send them
  • More memory usage in generating these events
  • More storage costs for these events (as browsers will generate billions/trillions of these events), a single user will generate hundreds of these events in a single session and large sites have 100's millions of daily users

Additional, part of the reason that the browser environment NEEDS to keep these in a single location is because

  • (already mentioned but) These are specific and unique to each event and should only be compared against other events with the same name it does not need to be elevated to a top-level attribute
  • These need to be kept as small as possible as this is specific for an environment that has extremely strict size, memory, network bandwidth constraints
  • If / when this moves from body to a single complex attribute whose value contains these, then again it doesn't need to have a full namespace.

The client Sig spent months defining the "common" set of values for the event payloads based on different companies (well before some of the attributes became stable and renamed (like the url.* discussions), so while moving "some" of the fields to top-level attributes, most of the fields should not.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not proposing a top-level element.* namespace, this would still be under the browser.user_action complex attribute in the future, e.g. browser.user_action.element.tag.name

Copy link
Member

Choose a reason for hiding this comment

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

I'm ok with keeping this as just element

Copy link
Member

@trask trask Mar 18, 2025

Choose a reason for hiding this comment

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

on further discussion in client SIG meeting, let's go with tag.name

(we can't have both .element and element.id)

Copy link
Contributor

Choose a reason for hiding this comment

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

@breedx-splk , based on us changing this from a browser focus to a generic user focus is element the correct description of the "thing" being tracked here?

I know for .NET there is no "Element" (so the tag name is not relevant as it's more "type" (button, text box)) but it does have an id for the GUI object...

Originally (years ago), we started out calling this target. So really looking for input on a generic name that would work for most languages / frameworks.

Copy link
Contributor

Choose a reason for hiding this comment

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

And to be a little clearer here, (if) element is fine for android as it's a common term for identifying this, then I'm fine to have this be called element (as previously agreed by the client Sig) -- especially as we don't have any .Net Client representation. We could just add additional documentation describing what we mean by the term element and call it done.

type: string
stability: development
brief: Target element tag name and it is obtained via event.target.tagName.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
brief: Target element tag name and it is obtained via event.target.tagName.
brief: Target element tag name and it is obtained via `event.target.tagName`.

requirement_level: recommended
examples: ["button"]
- id: element_xpath
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
- id: element_xpath
- id: element.xpath

Copy link
Contributor

Choose a reason for hiding this comment

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

Some of the documentation (if you care to read) around how we got to these names in the client SIG are located in the Archived section of the Client SIG meeting notes this inlcudes documents and spreadsheets used to get consensus on names to be used

If your objecting the the _ then I would propose using just xpath

Copy link
Member

Choose a reason for hiding this comment

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

just xpath works for me

type: string
stability: development
brief: Target element xpath
requirement_level: recommended
examples: ["//*[@id='testBtn']"]
- id: user_action_type
type: enum
Copy link
Author

Choose a reason for hiding this comment

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

need to confirm the user_action_type enum. Currently, I am using the definitions from https://github.com/microsoft/ApplicationInsights-JS/blob/main/extensions/applicationinsights-clickanalytics-js/src/Enums.ts

members:
- id: clickleft
value: "cl"
Copy link
Member

Choose a reason for hiding this comment

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

is cl an existing abbrevation defined somewhere (e.g. a browser spec)? thanks!

stability: development
brief: An element is left clicked by a user.
- id: clickright
value: "cr"
stability: development
brief: An element is right clicked by a user.
- id: clickmiddle
value: "cm"
stability: development
brief: An element is middle clicked by a user.
- id: scroll
value: "s"
stability: development
brief: An element is scrolled by a user.
- id: zoom
value: "z"
stability: development
brief: An element is zoomed by a user.
- id: resize
value: "r"
stability: development
brief: An element is resized by a user.
- id: keyboardenter
value: "ke"
stability: development
brief: An element is entered via keyboard by a user.
- id: keyboardspace
value: "ks"
stability: development
brief: A space is entered via keyboard by a user.
- id: other
value: "o"
stability: development
brief: User actions that are not listed above.
stability: development
brief: >
Type of interaction.
See enum [here](https://github.com/microsoft/ApplicationInsights-JS/blob/main/extensions/applicationinsights-clickanalytics-js/src/Enums.ts) for potential values we could add support for.
requirement_level: required
examples: ["cl"]
- id: click_coordinates
Copy link
Member

Choose a reason for hiding this comment

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

what do you think about

  • click.x
  • click.y

or is {x}Y{y} a browser spec thing? thanks

Copy link
Contributor

Choose a reason for hiding this comment

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

We had this discussion in the Client Sig when we came up with this name, it went through many iterations and we settled on a single field formatted in this manner so that backends (and users) can add any processing they want around this vs the overhead of populating, sending, storing and processing of individual fields.

Copy link
Contributor

Choose a reason for hiding this comment

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

For reference, the Android MotionEvent provides x and y as separate fields. https://developer.android.com/reference/android/view/MotionEvent

Copy link
Member

Choose a reason for hiding this comment

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

discussion in SIG meeting leaning towards 2-value number array

type: string
stability: development
brief: Click coordinates captured as a string in the format {x}X{y}.
requirement_level: recommended
examples: ["345X23"]
Comment on lines +71 to +76
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this specific enough? Should this also specify if the coordinates are relative to the element or the page or the window or ???

- id: tags
type: string
stability: development
brief: Grab data from data-otel-* attributes in tree.
requirement_level: recommended
examples: ["id"]
Loading