Dynatrace OpenKit API methods
Dynatrace OpenKit offers a number of API methods that enable you to integrate OpenKit into your application. The sections below describe how to use each of these OpenKit methods.
Obtain an OpenKit instance
To obtain a new OpenKit instance, use DynatraceOpenKitBuilder
.
1String applicationID = "application-id";2long deviceID = Util.getDeviceID();3String endpointURL = "https://tenantid.beaconurl.com/mbeacon";45OpenKit openKit = new DynatraceOpenKitBuilder(endpointURL, applicationID, deviceID).build();
endpointURL
is the Dynatrace endpoint that OpenKit communicates with. You can find the endpoint URL in your custom application settings. See Instrument your application using Dynatrace OpenKit for more information.applicationID
is the unique identifier of the application. You can find the application ID in your custom application settings. See Instrument your application using Dynatrace OpenKit for more information.deviceID
is a unique identifier, which can be used to uniquely identify a device.
In addition to the mandatory parameters described above, the builder provides additional methods to further customize OpenKit. These include device-specific information like the operating system, manufacturer, or model ID.
Method name | Description | Default value | Since version |
---|---|---|---|
withApplicationVersion | Sets the application version | OpenKit version | 1.0.1 |
withOperatingSystem | Sets the operating system name | OpenKit <OpenKit version> | 1.0.1 |
withManufacturer | Sets the manufacturer | Dynatrace | 1.0.1 |
withModelID | Sets the model ID | OpenKitDevice | 1.0.1 |
withBeaconCacheMaxRecordAge | Sets the maximum age of an entry in the beacon cache in milliseconds | 1 h 45 min | 1.0.1 |
withBeaconCacheLowerMemoryBoundary | Sets the lower memory boundary of the beacon cache in bytes | 80 MB | 1.0.1 |
withBeaconCacheUpperMemoryBoundary | Sets the upper memory boundary of the beacon cache in bytes | 100 MB | 1.0.1 |
withLogger | Sets a custom Logger replacing the currently set one | DefaultLogger | 1.0.1 |
withTrustManager | Sets a custom SSLTrustManager replacing the currently set one | SSLStrictTrustManager | 1.0.1 |
withDataCollectionLevel | Sets the data collection level | DataCollectionLevel.USER_BEHAVIOR | 1.1.0 |
withCrashReportingLevel | Sets the crash reporting level | CrashReportingLevel.OPT_IN_CRASHES | 1.1.0 |
withLogLevel | Sets the default log level when the built-in logger is used | LogLevel.WARN | 2.0.0 |
withHttpRequestInterceptor | Sets the Interceptor for requests to Dynatrace backends | NullHttpRequestInterceptor | 2.2.0 |
withHttpResponseInterceptor | Sets the Interceptor for responses received from Dynatrace backends | NullHttpResponseInterceptor | 2.2.0 |
SSL/TLS security
All OpenKit communication to the backend happens via HTTPS. By default, OpenKit expects valid server certificates. However, it is possible, if needed, to bypass certificate validation. You can configure a custom trust manager using the builder.
We do not recommend bypassing TLS/SSL server certificate validation, since this allows man-in-the-middle attacks.
1class MyCustomTrustManager implements SSLTrustManager {2 // implement interface methods3}45SSLTrustManager trustManager = new MyCustomTrustManager()67OpenKit openKit = new DynatraceOpenKitBuilder(endpointURL, applicationID, deviceID)8 .withTrustManager(trustManager)9 .build();
Enable verbose logging
By default, OpenKit uses a logger implementation that logs to stdout
. If the default logger is used, you can enable verbose logging via DynatraceOpenKitBuilder
. When the verbose mode is enabled, info and debug messages are logged.
You can also configure a custom logger. For details, see Dynatrace OpenKit logging.
Initialize OpenKit
When obtaining an OpenKit instance from the builder, the instance starts an automatic initialization phase. By default, initialization is performed asynchronously.
There might be situations when you need to ensure that initialization is completed before proceeding with the program logic, for example, in case of short-lived applications where a valid init and shutdown cannot be guaranteed. For such applications, OpenKit allows to wait for the initialization in two ways:
- With timeout: The calling threads waits a given amount of time for OpenKit to initialize. The method returns
false
in case the timeout expired or a shutdown was performed in the meantime andtrue
to indicate successful initialization. - Without timeout: The calling thread blocks until OpenKit is initialized. In case of misconfiguration this might block the calling thread indefinitely. The return value indicates whether the OpenKit instance has been initialized or a shutdown was performed meanwhile.
1// wait until the OpenKit instance is fully initialized2boolean success = openKit.waitForInitCompletion();34// wait up to 10 seconds for OpenKit to complete initialization5long timeoutInMilliseconds = 10 * 1000;6boolean success = openKit.waitForInitCompletion(timeoutInMilliseconds);
In addition, OpenKit enables you to verify whether or not it's been initialized.
1boolean isInitialized = openKit.isInitialized();2if (isInitialized) {3 System.out.println("OpenKit is initialized");4} else {5 System.out.println("OpenKit is not yet initialized");6}
Create a session
You can create a new session using the OpenKit instance obtained from the builder. When creating a new session, you can also provide an IP address.
If a valid IPv4 or IPv6 address is provided, it is assigned to the session.
If no IP address or an invalid IP address is provided, the IP address of the session is auto-detected and assigned on the server side.
1// create a session and pass an IP address2String clientIPAddress = "12.34.56.78";3Session sessionWithArgument = openKit.createSession(clientIPAddress);45// create a session and let the IP be assigned on the server side6// this overloaded method is available since OpenKit Java 1.4.07Session sessionWithoutArgument = openKit.createSession();
Tag specific users
You can tag the user assigned to a session. This enables you to search and filter specific user sessions and analyze individual user behavior over time in the backend. See User tagging for more details.
1session.identifyUser("jane.doe@example.com");
Finish a session
When a session is no longer needed, you should end it explicitly. Although all open sessions are automatically ended when OpenKit is shut down, it's highly recommended to manually end sessions that are no longer in use.
1session.end();2session = null; // not needed, just used to indicate that the session is no longer valid.
Report a crash
You can report unexpected application crashes on a session. The crash details are sent immediately after you've reported a crash.
1private static int div(int numerator, int denominator) {2 return numerator / denominator;3}45public static void divWithCrash() {6 int numerator = 5;7 int denominator = 0;8 try {9 System.out.println("Got: " + div(numerator, denominator));10 } catch (Exception e) {11 String errorName = e.getClass().getName();12 String reason = e.getMessage();13 String stackTrace = getStackTraceAsString(e); // get the stacktrace as string, similar as e.printStackTrace()14 // and now report the application crash via the session15 session.reportCrash(errorName, reason, stackTrace);16 }17}
Create custom and child actions
You can define and report custom actions. After you create a custom action, you can add a child action to it or enhance an action with additional information before finally closing it. You should create custom actions from a session and child actions from a custom action.
1String rootActionName = "rootActionName";2String childActionName = "childActionName";3// create a custom action for a session4RootAction rootAction = session.enterAction(rootActionName);5// create a child action for the custom action6Action childAction = rootAction.enterAction(childActionName);
The maximum duration of a user action in custom apps is 10 minutes. When a user action takes longer than this, such an action is discarded and not reported to Dynatrace.
There's no limit on the number of child actions attached to a custom action. However, note that you can have only one level of child actions—you can't create a child action for another child action (child actions can't have their own child actions). For an overview of a user action structure, see the illustration on the Real User Monitoring page.
Child actions are not displayed on the user session details page, but you can view them on the waterfall analysis page for a custom action to which these child actions are attached.
End an action
To record accurate timing information for actions, you should leave actions once they're finished.
1Action parentAction = action.leaveAction(); // returns the appropriate custom action2Action parent = parentAction.leaveAction(); // will always return null
Cancel an action
Canceling an action is similar to leaving an action, except that the action is discarded and is not sent to Dynatrace. Open child objects, like child actions and web request tracers, are discarded as well. Child objects that have been closed previously are sent to the backend and might be processed, depending on the event type.
1Action parentAction = action.cancelAction(); // returns the appropriate custom action2Action parent = parentAction.cancelAction(); // will always return null
Report an event
You can report named events on actions.
If you want to report standalone events with lots of additional information, see Report a business event.
1String eventName = "eventName";2action.reportEvent(eventName);34// also report on the RootAction5rootAction.reportEvent(eventName);
Report a value
The reportValue
method allows you to report key-value pairs of metadata that you can later view in the Dynatrace web UI and convert into user action and user session properties. The reported values must be part of a user action.
You can report values of the following data types:
32-bit integer
64-bit integer
Double
String
1// first report a 32-bit int value2String keyIntType = "intType";3int valueInt = 42;4action.reportValue(keyIntType, valueInt);56// then let's report a 64-bit long value7String keyLongType = "longType";8long valueLong = Long.MIN_VALUE;9action.reportValue(keyLongType, valueLong);1011// then let's report a double value12String keyDoubleType = "doubleType";13double valueDouble = 3.141592653589793;14action.reportValue(keyDoubleType, valueDouble);1516// and also a string value17String keyStringType = "stringType";18String valueString = "The quick brown fox jumps over the lazy dog";19action.reportValue(keyStringType, valueString);
To view the reported values in the Dynatrace web UI, go to the details of the user action that should contain that metadata and scroll down to the Reported values section.
To add action and session properties based on the reported values and then use these properties to create powerful queries, segmentations, and aggregations, see Define user action and user session properties for custom applications.
Report an error
You can report an error including its name (errorName
) and error code (errorCode
).
1String errorName = "Unknown Error";2int errorCode = 42;34action.reportError(errorName, errorCode);
You can also report the following additional information on the error:
- required
errorName
—The human-readable name of the error. - optional
causeName
—The cause leading to the reported error, for example, the exception's class name. - optional
causeDescription
—The description of the cause leading to the error, for example, the exception's description. - optional
stackTrace
orcauseStackTrace
—The stack trace of the cause leading to the error.
The code snippet below shows how to report errors with additional information.
1public void restrictedMethod() {2 if (!isUserAuthorized()) {3 // user is not authorized - report this as an error4 String errorName = "Authorization error";5 String causeName = "User not authorized";6 String causeDescription = "The current user is not authorized to call restrictedMethod.";7 String stackTrace = null; // no stack trace is reported89 action.reportError(errorName, causeName, causeDescription, stackTrace);1011 return;12 }1314 // ... further processing ...15}
OpenKit Java and OpenKit .NET offer a convenience API to directly report caught exceptions, as demonstrated in the example below.
1try {2 // call a method that is throwing an exception3 callMethodThrowingException();4} catch(Exception caughtException) {5 // report the caught exception as error via OpenKit6 String errorName = "Unknown Error";7 action.reportError(errorName, caughtException);8}
Report a business event
Dynatrace SaaS version 1.253+
With sendBizEvent
, you can report business events. These are standalone events, as Dynatrace sends them separately from user actions or user sessions.
For more information on business events, see Business Analytics.
1Map <String, JSONValue> attributes = new HashMap<String, JSONValue>();2attributes.put("event.name", JSONStringValue.fromString("Confirmed Booking"));3attributes.put("screen", JSONStringValue.fromString("booking-confirmation"));4attributes.put("product", JSONStringValue.fromString("Danube Anna Hotel"));5attributes.put("amount", JSONNumberValue.fromDouble(358.35));6attributes.put("currency", JSONStringValue.fromString("USD"));7attributes.put("reviewScore", JSONNumberValue.fromDouble(4.8));8attributes.put("arrivalDate", JSONStringValue.fromString("2022-11-05"));9attributes.put("departureDate", JSONStringValue.fromString("2022-11-15"));10attributes.put("journeyDuration", JSONNumberValue.fromLong(10));11attributes.put("adultTravelers", JSONNumberValue.fromLong(2));12attributes.put("childrenTravelers", JSONNumberValue.fromLong(0));1314session.sendBizEvent('com.easytravel.funnel.booking-finished', attributes);
Trace web requests
One of the most powerful OpenKit features is web request tracing. When the application starts a web request, for example, HTTP GET, a special tag can be attached to the header. This header allows Dynatrace to correlate actions with a server-side distributed trace. An example is shown below.
1// create URL and open URLConnection2URL url = new URL("http://www.my-backend.com/api/v3/users");3URLConnection urlConnection = url.openConnection();45// create the WebRequestTracer6WebRequestTracer webRequestTracer = action.traceWebRequest(urlConnection);7webRequestTracer.start();89// consume data10BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));11String inputLine;12while ((inputLine = in.readLine()) != null) {13 // TODO - do something useful with response14}15in.close();1617// stop web request tracing when done18webRequestTracer.stop(200); // would use the HTTP response code normally.1920// --------------------------------------------21// alternative solution not using URLConnection22// --------------------------------------------2324String url = "http://www.my-backend.com/api/v3/users";2526// create the WebRequestTracer27WebRequestTracer webRequestTracer = action.traceWebRequest(url);2829// this is the HTTP header name & value which needs to be added to the HTTP request.30String headerName = OpenKitConstants.WEBREQUEST_TAG_HEADER;31String headerValue = webRequestTracer.getTag();3233webRequestTracer.start();3435// perform the request here & do not forget to add the HTTP header3637webRequestTracer.setBytesSent(12345); // 12345 bytes sent38webRequestTracer.setBytesReceived(67890); // 67890 bytes received39webRequestTracer.stop(200); // 200 was the response code
Configure data privacy
You can dynamically adjust data privacy settings and build your custom applications in compliance with data protection laws and regulations. The privacy API methods allow you to dynamically change the data collection level and activate or deactivate crash reporting.
Data collection levels
The table below describes the available data collection levels and shows whether user tags and custom user actions, events, values, and errors are reported for a particular level.
Level | Description | User tags, custom events, and custom values | Custom user actions and errors |
---|---|---|---|
Off Monitoring data is not sent | No personal data is sent; all identifiers are randomized on every launch.1 | ||
Performance Only performance, automatically captured data is sent | No personal data is sent; all identifiers are randomized on every launch. | ||
User behavior Performance data and user data is sent | Personal data is sent; OneAgent recognizes and reports users who revisit in the future.2 |
A single Loading <App>
event is sent to track the number of users that opted out.
If you haven't configured user tagging and custom event or value reporting, the User behavior level works similarly to the Performance level.
Crash reporting levels
The following crash reporting levels are available.
Level name | Crash reporting | Use this level when… |
---|---|---|
Off |
| You don't need to collect crash reports. |
Opt out crashes |
| The user of your application has disallowed the collection of crash reports. |
Opt in crashes default |
| The user of your application has allowed the collection of crash reports. |
Set data collection and crash reporting levels
The code examples below show you how to work with the API:
1import com.dynatrace.openkit.DataCollectionLevel;2import com.dynatrace.openkit.CrashReportingLevel;34OpenKit openKit = new DynatraceOpenKitBuilder(endpointURL, applicationID, deviceID)5// set a data collection level (user allowed you to capture performance and personal data)6 .withDataCollectionLevel(DataCollectionLevel.USER_BEHAVIOR)7// allow crash reporting (user allowed you to collect information on crashes)8 .withCrashReportingLevel(CrashReportingLevel.OPT_IN_CRASHES)9 .build();
Possible values for the data collection level:
DataCollectionLevel.OFF
DataCollectionLevel.PERFORMANCE
DataCollectionLevel.USER_BEHAVIOR
Possible values for the crash reporting level:
CrashReportingLevel.OFF
CrashReportingLevel.OPT_OUT_CRASHES
CrashReportingLevel.OPT_IN_CRASHES
Terminate an OpenKit instance
When an OpenKit instance is no longer needed, for example, when the application using OpenKit is shut down, you can clear the obtained instance by invoking. A call to shutdown blocks the calling thread up to 10 seconds, while the OpenKit flushes data that hasn't been transmitted yet to the backend.
1openKit.shutdown();