Custom events

  • Latest Dynatrace
  • How-to guide

Dynatrace supports custom events to track user interactions, business metrics, and application-specific signals. Events can also be enriched before they are sent by applying event modifiers.

Send custom events

Custom events are reported using Dynatrace.sendEvent(...) with optional duration and event properties.

Consider basic usage

// Simple event
Dynatrace.sendEvent(new EventData());
// Event with duration (in milliseconds)
Dynatrace.sendEvent(new EventData().withDuration(150));

Add event properties

Custom properties provide context for reported events. Property keys must be prefixed with event_properties..

Dynatrace.sendEvent(new EventData()
.withDuration(250)
.addEventProperty("event_properties.checkout_step", "payment_confirmed")
.addEventProperty("event_properties.cart_value", 149.99)
.addEventProperty("event_properties.item_count", 3)
);

Follow property naming rules

  • Keys must be prefixed with event_properties..
  • Field names must contain only alphanumeric characters, underscores, and dots.
  • Each dot must be followed by an alphabetic character.
  • Each underscore must be followed by an alphabetic character or number.
  • Values must be primitive types (String, Int, Long, Double, Bool).

Valid examples:

  • event_properties.purchase_state.
  • event_properties.cart.total_value.
  • event_properties.step_1_status.

Event modifiers

Event modifiers intercept events before they are sent. They can be used to add common properties, redact sensitive information, or filter events.

On Android, modifiers operate on a JSONObject representation of the event.

Add an event modifier

EventModifier modifier = (JSONObject event) -> {
// Add build variant context to all events
event.put("event_properties.build_type", BuildConfig.BUILD_TYPE);
event.put("event_properties.flavor", BuildConfig.FLAVOR);
return event;
};
Dynatrace.addEventModifier(modifier);

Filter events

Returning null discards an event.

EventModifier modifier = (JSONObject event) -> {
// Events happening on the com.example.MainActivity activity will be dropped.
if ("com.example.MainActivity".equals(event.optString("view.detected_name"))) {
return null;
}
return event;
};
Dynatrace.addEventModifier(modifier);

Redact sensitive data

EventModifier modifier = (JSONObject event) -> {
// Redact user IDs from URLs
String url = event.optString("url.full", null);
if (url != null) {
String redactedUrl = Pattern.compile("/users/\\\\w+/")
.matcher(url)
.replaceAll("/users/{id}/");
event.put("url.full", redactedUrl);
}
return event;
};
Dynatrace.addEventModifier(modifier);

Remove event modifiers

// Store the modifier when adding it
EventModifier modifier = (JSONObject event) -> {
event.put("event_properties.custom", "value");
return event;
};
Dynatrace.addEventModifier(modifier);
// Remove when no longer needed
Dynatrace.removeEventModifier(modifier);

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.*—custom event properties.
  • 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.

Modifier example

Conditional event enrichment (example)

The following example shows how to enrich only specific event types. It adds context to HTTP events (for API segmentation) and to error events (for faster triage).

public void setupConditionalEnrichment(final String apiClientName) {
EventModifier modifier = (JSONObject event) -> {
// Add context only for HTTP events
if (event.optBoolean("characteristics.has_request")) {
event.put("event_properties.api_client", apiClientName);
event.put("event_properties.api_kind", "backend");
}
// Add context only for error events
if (event.optBoolean("characteristics.has_error")) {
event.put("event_properties.triage_owner", "mobile");
event.put("event_properties.triage_severity", "error");
}
return event;
};
Dynatrace.addEventModifier(modifier);
}

Important considerations

  • Execution order—modifiers run in the order they were added.
  • Returning null—discards the event; subsequent modifiers will not run.
  • Performance—keep modifiers efficient as they run for every event.
  • Primitive values—event properties can only contain primitive types.
  • Error handling—exceptions in modifiers are logged and do not block other modifiers.
  • Thread safety—modifiers may be called from any thread; ensure code is thread-safe.
Related tags
Digital Experience