Try it free

Custom events

  • Latest Dynatrace
  • How-to guide

Dynatrace allows you to send custom events to track user interactions, business metrics, and application-specific data. You can also enrich all events with additional context using event modifiers.

Event and session properties

Configure event and session properties

Before you can send event or session properties from your application, you must first define them in the Dynatrace web UI. Any properties that are not pre-configured will be discarded.

To define a new property

  1. In Experience Vitals Experience Vitals, select the frontend for which you want to add the property.
  2. Select the Settings tab, then choose Event and session properties.
  3. Select Add under either Defined event properties or Defined session properties, depending on the type of property you want to create.
  4. In the Field name box, enter a name for your property (for example, cart.total_value).
  5. Optional To make the field name case-insensitive, turn on Field name validation should be case-insensitive.
  6. From the Datatype list, select the appropriate data type for your property: string, boolean, or number.

Dynatrace automatically prefixes your field name with event_properties. or session_properties. based on the property type you selected. For example, a field name of cart.total_value will become event_properties.cart.total_value.

Send custom events

Use sendEvent() to report custom events with optional duration and event properties.

Basic usage

// Simple event
Dynatrace.sendEvent(DTXEventData())
// Event with duration (in milliseconds)
Dynatrace.sendEvent(DTXEventData().withDuration(150))
// Simple event
[Dynatrace sendEvent:[[DTXEventData alloc] init]];
// Event with duration (in milliseconds)
[Dynatrace sendEvent:[[[DTXEventData alloc] init] withDuration:@150]];

Add event properties

Add custom properties to provide context for your events. Property keys must be prefixed with event_properties..

Dynatrace.sendEvent(DTXEventData()
.withDuration(250)
.addEventProperty("event_properties.checkout_step", value: "payment_confirmed")
.addEventProperty("event_properties.cart_value", value: 149.99)
.addEventProperty("event_properties.item_count", value: 3))
[Dynatrace sendEvent:[[[[[[DTXEventData alloc] init]
withDuration:@250]
addEventProperty:@"event_properties.checkout_step" value:@"payment_confirmed"]
addEventProperty:@"event_properties.cart_value" value:@149.99]
addEventProperty:@"event_properties.item_count" value:@3]];

Property naming rules

For naming rules and limits, see Event and session properties.

Event modifiers

Event modifiers allow you to intercept and modify all events before they are sent to Dynatrace. Use them to add common properties, redact sensitive information, or filter events.

Add an event modifier

let subscriber = Dynatrace.addEventModifier { event in
// Add experiment tracking to all events
event.fields["event_properties.experiment_id"] = "checkout_flow_v2"
event.fields["event_properties.variant"] = "treatment_a"
return event
}
DTXModifyEventSubscriber *subscriber = [Dynatrace addEventModifier:^DTXModifyableEvent *(DTXModifyableEvent *event) {
// Add experiment tracking to all events
event.fields[@"event_properties.experiment_id"] = @"checkout_flow_v2";
event.fields[@"event_properties.variant"] = @"treatment_a";
return event;
}];

Filter events

Return nil to discard an event:

let subscriber = Dynatrace.addEventModifier { event in
// Filter out events from test users
if event.fields["event_properties.is_test_user"] as? Bool == true {
return nil // Discard this event
}
return event
}
DTXModifyEventSubscriber *subscriber = [Dynatrace addEventModifier:^DTXModifyableEvent *(DTXModifyableEvent *event) {
// Filter out events from test users
if ([event.fields[@"event_properties.is_test_user"] boolValue]) {
return nil; // Discard this event
}
return event;
}];

Redact sensitive data

let subscriber = Dynatrace.addEventModifier { event in
// Redact user IDs from URLs
if let url = event.fields["url.full"] as? String {
let redactedUrl = url.replacingOccurrences(
of: #"/users/\w+/"#,
with: "/users/{id}/",
options: .regularExpression
)
event.fields["url.full"] = redactedUrl
}
return event
}
DTXModifyEventSubscriber *subscriber = [Dynatrace addEventModifier:^DTXModifyableEvent *(DTXModifyableEvent *event) {
// Redact user IDs from URLs
NSString *url = event.fields[@"url.full"];
if (url) {
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"/users/\\w+/" options:0 error:nil];
NSString *redactedUrl = [regex stringByReplacingMatchesInString:url options:0 range:NSMakeRange(0, url.length) withTemplate:@"/users/{id}/"];
event.fields[@"url.full"] = redactedUrl;
}
return event;
}];

Remove event modifiers

// Store the subscriber when adding the modifier
let subscriber = Dynatrace.addEventModifier { event in
event.fields["event_properties.custom"] = "value"
return event
}
// Remove when no longer needed
Dynatrace.removeEventModifier(subscriber)
// Store the subscriber when adding the modifier
DTXModifyEventSubscriber *subscriber = [Dynatrace addEventModifier:^DTXModifyableEvent *(DTXModifyableEvent *event) {
event.fields[@"event_properties.custom"] = @"value";
return event;
}];
// Remove when no longer needed
[Dynatrace removeEventModifier:subscriber];

Modifier limitations

Event modifiers have restrictions on which fields can be modified to ensure data integrity.

Modifiable fields

The following fields can be modified or added:

  • event_properties.*—event properties.
  • session_properties.*—session properties (only on session property events).
  • url.full—complete request URL.
  • exception.stack_trace—exception stack traces.

All other fields are read-only and can't be modified. The original values are preserved.

Important considerations

  • Thread safety—modifiers may be called from any thread; ensure your code is thread-safe.
  • Performance—keep modifiers efficient; they run for every event.

Modifier examples

Add user context to all events

class UserContext {
static var userId: String?
static var userTier: String?
}
func setupEventEnrichment() {
_ = Dynatrace.addEventModifier { event in
if let userId = UserContext.userId {
event.fields["event_properties.user_id_hash"] = userId.hashValue
}
if let userTier = UserContext.userTier {
event.fields["event_properties.user_tier"] = userTier
}
return event
}
}
static NSString *userId = nil;
static NSString *userTier = nil;
- (void)setupEventEnrichment {
[Dynatrace addEventModifier:^DTXModifyableEvent *(DTXModifyableEvent *event) {
if (userId) {
event.fields[@"event_properties.user_id_hash"] = @(userId.hash);
}
if (userTier) {
event.fields[@"event_properties.user_tier"] = userTier;
}
return event;
}];
}

Add feature flags

func setupFeatureFlagTracking(featureFlags: [String: Bool]) {
_ = Dynatrace.addEventModifier { event in
for (key, value) in featureFlags {
event.fields["event_properties.ff_\(key)"] = value
}
return event
}
}
- (void)setupFeatureFlagTrackingWithFlags:(NSDictionary<NSString *, NSNumber *> *)featureFlags {
[Dynatrace addEventModifier:^DTXModifyableEvent *(DTXModifyableEvent *event) {
for (NSString *key in featureFlags) {
NSString *fieldKey = [NSString stringWithFormat:@"event_properties.ff_%@", key];
event.fields[fieldKey] = featureFlags[key];
}
return event;
}];
}

Conditional event enrichment

func setupConditionalEnrichment() {
_ = Dynatrace.addEventModifier { event in
// Only enrich HTTP events
if event.fields["http.request.method"] != nil {
event.fields["event_properties.api_client"] = "ios_app"
event.fields["event_properties.api_version"] = "v2"
}
// Only enrich error events
if event.fields["exception.type"] != nil {
event.fields["event_properties.error_context"] = "user_session"
}
return event
}
}
- (void)setupConditionalEnrichment {
[Dynatrace addEventModifier:^DTXModifyableEvent *(DTXModifyableEvent *event) {
// Only enrich HTTP events
if (event.fields[@"http.request.method"]) {
event.fields[@"event_properties.api_client"] = @"ios_app";
event.fields[@"event_properties.api_version"] = @"v2";
}
// Only enrich error events
if (event.fields[@"exception.type"]) {
event.fields[@"event_properties.error_context"] = @"user_session";
}
return event;
}];
}

Related topics

  • Web request performance—HTTP event modifiers.
  • Error and crash reporting—exception events.
  • Configuration—agent configuration.
Related tags
Digital Experience