Dynatrace OpenKit API methods
Dynatrace OpenKit offers a number of API methods that enable you to integrate OpenKit into your application for monitoring. Read below how you can use each of these OpenKit methods.
To obtain a new OpenKit instance, use DynatraceOpenKitBuilder
.
String applicationID = "application-id";
long deviceID = Util.getDeviceID();
String endpointURL = "https://tenantid.beaconurl.com/mbeacon";
OpenKit openKit = new DynatraceOpenKitBuilder(endpointURL, applicationID, deviceID).build();
string applicationID = "application-id";
long deviceID = Util.GetDeviceID();
string endpointURL = "https://tenantid.beaconurl.com/mbeacon";
IOpenKit openKit = new DynatraceOpenKitBuilder(endpointURL, applicationID, deviceID).Build();
const char* applicationID = "application-id";
int64_t deviceID = Util::GetDeviceID();
const char* endpointURL = "https://tenantid.beaconurl.com/mbeacon";
std::shared_pointer<openkit::IOpenKit> openKit =
openkit::DynatraceOpenKitBuilder(endpointURL, applicationID, deviceID).build();
const char* applicationID = "application-id";
int64_t deviceID = GetDeviceID();
const char* endpointURL = "https://tenantid.beaconurl.com/mbeacon";
struct OpenKitConfigurationHandle* configurationHandle = createOpenKitConfiguration(endpointURL, applicationID, deviceID);
struct OpenKitHandle* openKitHandle = createDynatraceOpenKit(configurationHandle);
destroyOpenKitConfiguration(configurationHandle);
endpointURL
denotes the Dynatrace endpoint that OpenKit communicates with. The endpoint URL can be found in the settings page of the custom application. More information can be found here.applicationID
is the unique identifier of the application. The application's id can be found in the settings page of the custom application. More information can be found here.deviceID
is a unique identifier, which can be used to uniquely identify a device.
Optional Configuration
In addition to the mandatory parameters described above, the builder provides additional methods to further customize OpenKit. These include device specific information like operating system, manufacturer, or model id.
Method name | Description | Default value | Since Version | Remarks |
---|---|---|---|---|
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 | |
enableVerbose |
enables extended log output for OpenKit if the default logger is used | false |
1.0.1 | deprecated since version 2.0.0, use withLogLevel instead |
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 if the builtin logger is used | LogLevel.WARN |
2.0.0 |
Method name | Description | Default value | Since Version | Remarks |
---|---|---|---|---|
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 | |
EnableVerbose |
enables extended log output for OpenKit if the default logger is used | false |
1.0.1 | deprecated since version 2.0.0, use WithLogLevel instead |
WithLogger |
sets a custom ILogger replacing the currently set one |
DefaultLogger |
1.0.1 | |
WithTrustManager |
sets a custom ISSLTrustManager 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 if the builtin logger is used | LogLevel.WARN |
2.0.0 |
Method name | Description | Default value | Since Version |
---|---|---|---|
withApplicationVersion |
sets the application version | OpenKit version | 1.0.0 |
withOperatingSystem |
sets the operating system name | OpenKit <OpenKit version> |
1.0.0 |
withManufacturer |
sets the manufacturer | Dynatrace |
1.0.0 |
withModelID |
sets the model id | OpenKitDevice |
1.0.0 |
withBeaconCacheMaxRecordAge |
sets the maximum age of an entry in the beacon cache in milliseconds | 1 h 45 min | 1.0.0 |
withBeaconCacheLowerMemoryBoundary |
sets the lower memory boundary of the beacon cache in bytes | 80 MB | 1.0.0 |
withBeaconCacheUpperMemoryBoundary |
sets the upper memory boundary of the beacon cache in bytes | 100 MB | 1.0.0 |
enableVerbose |
enables extended log output for OpenKit if the default logger is used | false |
1.0.0 |
withLogger |
sets a custom ILogger replacing the currently set one |
DefaultLogger |
1.0.0 |
withTrustManager |
sets a custom ISSLTrustManager replacing the currently set one |
SSLStrictTrustManager |
1.0.0 |
withDataCollectionLevel |
sets the data collection level | DataCollectionLevel::USER_BEHAVIOR |
1.0.0 |
withCrashReportingLevel |
sets the crash reporting level | CrashReportingLevel::OPT_IN_CRASHES |
1.0.0 |
Method name | Description | Default value | Since Version |
---|---|---|---|
useApplicationVersionForConfiguration |
sets the application version | OpenKit version | 1.0.0 |
useOperatingSystemForConfiguration |
sets the operating system name | OpenKit <OpenKit version> |
1.0.0 |
useManufacturerForConfiguration |
sets the manufacturer | Dynatrace |
1.0.0 |
useModelIDForConfiguration |
sets the model id | OpenKitDevice |
1.0.0 |
useBeaconCacheBehaviorForConfiguration |
sets caching behavior for the beacon cache | 1 h 45 min retention, 80 MB lower memory boundary, 100 MB upper memory boundary | 1.0.0 |
useLoggerForConfiguration |
sets a custom ILogger replacing the currently set one |
A default logger, logging to stdout, is used as fallback | 1.0.0 |
useTrustModeForConfiguration |
sets a custom ISSLTrustManager replacing the currently set one |
STRICT_TRUST |
1.0.0 |
useDataCollectionLevelForConfiguration |
sets the data collection level | DATA_COLLECTION_LEVEL_USER_BEHAVIOR |
1.0.0 |
useCrashReportingLevelForConfiguration |
sets the crash reporting level | CRASH_REPORTING_LEVEL_OPT_IN_CRASHES |
1.0.0 |
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. A custom trust manager can be configured using the builder.
Note: We do NOT recommend bypassing TLS/SSL server certificate validation, since this allows man-in-the-middle attacks.
class MyCustomTrustManager implements SSLTrustManager {
// implement interface methods
}
SSLTrustManager trustManager = new MyCustomTrustManager()
OpenKit openKit = new DynatraceOpenKitBuilder(endpointURL, applicationID, deviceID)
.withTrustManager(trustManager)
.build();
class MyCustomTrustManager : ISSLTrustManager
{
// implement interface methods
}
ISSLTrustManager trustManager = new MyCustomTrustManager()
OpenKit openKit = new DynatraceOpenKitBuilder(endpointURL, applicationID, deviceID)
.WithTrustManager(trustManager)
.Build();
class MyCustomTrustManager : public openkit::ISSLTrustManager
{
// implement interface methods
};
std::shared_ptr<openkit::ISSLTrustManager> trustManager = std::make_shared<MyCustomTrustManager>()
OpenKit openKit = new DynatraceOpenKitBuilder(endpointURL, applicationID, deviceID)
.withTrustManager(trustManager)
.build();
void applySslOptions(CURL* curl)
{
// set CURL options accordingly
}
struct TrustManagerHandle* trustManager = createCustomTrustManager(&applySslOptions);
// create OpenKit configuration and assign custom trust manager
struct OpenKitConfigurationHandle* configurationHandle = createOpenKitConfiguration(endpointURL, applicationID, deviceID);
useTrustModeForConfiguration(configurationHandle, CUSTOM_TRUST, trustManager);
// create OpenKit instance
struct OpenKitHandle* openKitHandle = createDynatraceOpenKit(configurationHandle);
By default, OpenKit uses a logger implementation that logs to stdout. If the default logger is used, verbose logging can be enabled using DynatraceOpenKitBuilder
. By enabling verbose mode, info and debug messages are logged. It is also possible to configure a custom logger. See logging for OpenKit for details
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 a developer wants 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 cases 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.
// wait until the OpenKit instance is fully initialized
boolean success = openKit.waitForInitCompletion();
// wait up to 10 seconds for OpenKit to complete initialization
long timeoutInMilliseconds = 10 * 1000;
boolean success = openKit.waitForInitCompletion(timeoutInMilliseconds);
// wait until the OpenKit instance is fully initialized
bool success = openKit.WaitForInitCompletion();
// wait up to 10 seconds for OpenKit to complete initialization
int timeoutInMilliseconds = 10 * 1000;
bool success = openKit.WaitForInitCompletion(timeoutInMilliseconds);
// wait until the OpenKit instance is fully initialized
bool success = openKit->waitForInitCompletion();
// wait up to 10 seconds for OpenKit to complete initialization
int64_t timeoutInMilliseconds = 10 * 1000;
bool success = openKit->waitForInitCompletion(timeoutInMilliseconds);
// wait until the OpenKit instance is fully initialized
bool success = waitForInitCompletion(openKit);
// wait up to 10 seconds for OpenKit to complete initialization
int64_t timeoutInMilliseconds = 10 * 1000;
bool success = waitForInitCompletionWithTimeout(openKit, timeoutInMilliseconds);
In addition, OpenKit enables you to verify whether or not it's been initialized.
boolean isInitialized = openKit.isInitialized();
if (isInitialized) {
System.out.println("OpenKit is initialized");
} else {
System.out.println("OpenKit is not yet initialized");
}
bool isInitialized = openKit.IsInitialized;
if (isInitialized)
{
Console.WriteLine("OpenKit is initialized");
}
else
{
Console.WriteLine("OpenKit is not yet initialized");
}
bool isInitialized = openKit->isInitialized();
if (isInitialized)
{
std::cout << "OpenKit is initialized" << std::endl;
}
else
{
std::cout << "OpenKit is not yet initialized" << std::endl;
}
bool isInitialized = isInitialized(openKit);
if (isInitialized)
{
printf("OpenKit is initialized\n");
}
else
{
printf("OpenKit is not yet initialized\n");
}
New sessions can be created using the OpenKit instance obtained from the builder. When creating a new session an optional IP address can be provided.
- If a valid IPv4 or IPv6 address is provided it will be assigned to the session.
- If no IP address or an invalid IP address is provided, the IP address of the session will be auto-detected and assigned on the server side.
This example shows how to create sessions.
// create a session and pass an IP address
String clientIPAddress = "12.34.56.78";
Session sessionWithArgument = openKit.createSession(clientIPAddress);
// create a session and let the IP be assigned on the server side
// this overloaded method is available since OpenKit Java 1.4.0
Session sessionWithoutArgument = openKit.createSession();
// create a session and pass an IP address
string clientIPAddress = "12.34.56.78";
ISession sessionWithArgument = openKit.CreateSession(clientIPAddress);
// create a session and let the IP be assigned on the server side
// this overloaded method is available since OpenKit .NET 1.4.0
ISession sessionWithoutArgument = openKit.CreateSession();
// create a session and pass an IP address
const char* clientIPAddress = "12.34.56.78";
std::shared_ptr<openkit::ISession> sessionWithArgument = openKit->createSession(clientIPAddress);
// create a session and let the IP be assigned on the server side
// this overloaded method is available since OpenKit Native 1.1.0
std::shared_ptr<openkit::ISession> sessionWithoutArgument = openKit->createSession();
// create a session and pass an IP address
const char* clientIPAddress = "12.34.56.78";
SessionHandle* sessionWithArgument = createSession(openKit, clientIPAddress);
// create a session and let the IP be assigned on the server side
// this function is available since OpenKit Native 1.1.0
SessionHandle* sessionWithoutArgument = createSessionWithAutoIpDetermination(openKit);
The user assigned to a session can be identified. This enables you to search and filter specific user sessions and analyze individual user behavior over time in the backend.
session.identifyUser("jane.doe@example.com");
session.IdentifyUser("jane.doe@example.com");
session->identifyUser("jane.doe@example.com");
identifyUser(session, "jane.doe@example.com");
When a session is no longer needed, it should be ended explicitly. Although all open sessions are automatically ended when OpenKit is shut down, it's highly recommended to manually end sessions, which are no longer in use.
session.end();
session = null; // not needed, just used to indicate that the session is no longer valid.
session.End();
session = null; // not needed, just used to indicate that the session is no longer valid.
session->end();
session = nullptr; // not needed, just used to indicate that the session is no longer valid.
endSession(session);
session = NULL; // good pratice, as the allocated memory is freed in endSession
Unexpected application crashes can be reported on a session. The example below shows how an exception might be reported.
private static int div(int numerator, int denominator) {
return numerator / denominator;
}
public static void divWithCrash() {
int numerator = 5;
int denominator = 0;
try {
System.out.println("Got: " + div(numerator, denominator));
} catch (Exception e) {
String errorName = e.getClass().getName();
String reason = e.getMessage();
String stackTrace = getStackTraceAsString(e); // get the stacktrace as string, similar as e.printStackTrace()
// and now report the application crash via the session
session.reportCrash(errorName, reason, stackTrace);
}
}
private static int Div(int numerator, int denominator)
{
return numerator / denominator;
}
public static void DivWithCrash()
{
int numerator = 5;
int denominator = 0;
try
{
Console.WriteLine("Got: " + Div(numerator, denominator));
}
catch (Exception e)
{
string errorName = e.GetType().ToString();
string reason = e.Message;
string stackTrace = e.StackTrace;
// and now report the application crash via the session
session.ReportCrash(errorName, reason, stackTrace);
}
}
static int32_t div(int32_t numerator, int32_t denominator)
{
if (denominator == 0)
{
throw std::logic_error("Division by zero");
}
return numerator / denominator;
}
static void divWithCrash()
{
int32_t numerator = 5;
int32_t denominator = 0;
try
{
int32_t result = div(numerator, denominator);
std::cout << "Got: " << result << std::endl;
}
catch (std::logic_error& e)
{
const char* errorName = "std::logic_error"; // if RTTI is enabled, typeid could be used
const char* reason = e.what();
const char* stackTrace = nullptr; // use a valid const char* if a stack trace can be generated
// and now report the application crash via the session
session->reportCrash(errorName, reason, stackTrace);
}
}
const char* errorName = "application crash";
const char* reason = "some reason indicator";
const char* stackTrace = NULL; // use a valid const char* if a stack trace can be generated
// and now report the application crash via the session
reportCrash(session, errorName, reason, stackTrace);
Root actions and actions are hierarchically named events, where a root action represents the first level of the hierarchy. A root action can have child actions and is created from a session. Child actions are created from a root action.
String rootActionName = "rootActionName";
String childActionName = "childActionName";
// create a root action for a session
RootAction rootAction = session.enterAction(rootActionName);
// create a child action for the root action
Action childAction = rootAction.enterAction(childActionName);
string rootActionName = "rootActionName";
string childActionName = "childActionName";
// create a root action for a session
IRootAction rootAction = session.EnterAction(rootActionName);
// create a child action for the root action
IAction childAction = rootAction.EnterAction(childActionName);
const char* rootActionName = "rootActionName";
const char* childActionName = "childActionName";
// create a root action for a session
std::shared_ptr<openkit::IRootAction> rootAction = session->enterAction(rootActionName);
// create a child action for the root action
std::shared_ptr<openkit::IAction> childAction = rootAction->enterAction(childActionName);
const char* rootActionName = "rootActionName";
const char* childActionName = "childActionName";
// create a root action for a session
RootActionHandle* rootAction = enterRootAction(session, rootActionName);
// create a child action for the root action
ActionHandle* childAction = enterAction(rootAction, childActionName);
To record accurate timing information for actions, actions must be "left" once they're finished. The return value of the leave
method will always return the parent action. For root actions null
is returned.
Action parentAction = action.leave(); // returns the root action
Action parent = parentAction.leave(); // will always return null
IAction parentAction = action.Leave(); // returns the appropriate RootAction
IAction parent = parentAction.Leave(); // will always return null
std::shared_ptr<openkit::IAction> parentAction = action->leave(); // returns the appropriate RootAction
std::shared_ptr<openkit::IAction> parent = parentAction->leave(); // will always return nullptr
leaveAction(action); // return type is void
leaveRootAction(rootAction); // return type is void
Named events can be reported on actions.
String eventName = "eventName";
action.reportEvent(eventName);
// also report on the RootAction
rootAction.reportEvent(eventName);
string eventName = "eventName";
action.ReportEvent(eventName);
// also report on the RootAction
rootAction.ReportEvent(eventName);
const char* eventName = "eventName";
action->reportEvent(eventName);
// also report on the RootAction
rootAction->reportEvent(eventName);
const char* eventName = "eventName";
reportEventOnAction(action, eventName);
// also report on the RootAction
reportEventOnRootAction(rootAction, eventName);
Key-value pairs can be reported for actions, as shown in the example below. Overloaded methods exist for the following value types:
- Integer
- Double
- String
// first report an int value
String keyIntType = "intType";
int valueInt = 42;
action.reportValue(keyIntType, valueInt);
// then let's report a double value
String keyDoubleType = "doubleType";
double valueDouble = 3.141592653589793;
action.reportValue(keyDoubleType, valueDouble);
// and also a string value
String keyStringType = "stringType";
String valueString = "The quick brown fox jumps over the lazy dog";
action.reportValue(keyStringType, valueString);
// first report an int value
string keyIntType = "intType";
int valueInt = 42;
action.ReportValue(keyIntType, valueInt);
// then let's report a double value
string keyDoubleType = "doubleType";
double valueDouble = 3.141592653589793;
action.ReportValue(keyDoubleType, valueDouble);
// and also a string value
string keyStringType = "stringType";
string valueString = "The quick brown fox jumps over the lazy dog";
action.ReportValue(keyStringType, valueString);
// first report a 32-bit integer value
const char* keyIntType = "intType";
int32_t valueInt = 42;
action->reportValue(keyIntType, valueInt);
// then let's report a double value
const char* keyDoubleType = "doubleType";
double valueDouble = 3.141592653589793;
action->reportValue(keyDoubleType, valueDouble);
// and also a string value
const char* keyStringType = "stringType";
const char* valueString = "The quick brown fox jumps over the lazy dog";
action->reportValue(keyStringType, valueString);
// first report a 32-bit integer value
const char* keyIntType = "intType";
int32_t valueInt = 42;
reportIntValueOnAction(action, keyIntType, valueInt);
// then let's report a double value
const char* keyDoubleType = "doubleType";
double valueDouble = 3.141592653589793;
reportDoubleValueOnAction(action, keyDoubleType, valueDouble);
// and also a string value
const char* keyStringType = "stringType";
const char* valueString = "The quick brown fox jumps over the lazy dog";
reportStringValueOnAction(action, keyStringType, valueString);
An action also has the possibility to report an error with a given name, code, and reason. The code fragment below shows how this can be done.
String errorName = "Unknown Error";
int errorCode = 42;
String reason = "Not sure what's going on here";
action.reportError(errorName, errorCode, reason);
string errorName = "Unknown Error";
int errorCode = 42;
string reason = "Not sure what's going on here";
action.ReportError(errorName, errorCode, reason);
const char* errorName = "Unknown Error";
int32_t errorCode = 42;
const char* reason = "Not sure what's going on here";
action->reportError(errorName, errorCode, reason);
const char* errorName = "Unknown Error";
int32_t errorCode = 42;
const char* reason = "Not sure what's going on here";
// report error on child action
reportErrorOnAction(action, errorName, errorCode, reason);
// report error on root action
reportErrorOnRootAction(rootAction, errorName, errorCode, reason);
One of the most powerful OpenKit features is web request tracing. When the application starts a web request (e.g. HTTP GET), a special tag can be attached to the header. This header allows Dynatrace to correlate actions with a server-side PurePath. An example is shown below.
// create URL and open URLConnection
URL url = new URL("http://www.my-backend.com/api/v3/users");
URLConnection urlConnection = url.openConnection();
// create the WebRequestTracer
WebRequestTracer webRequestTracer = action.traceWebRequest(urlConnection);
webRequestTracer.start();
// consume data
BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
// TODO - do something useful with response
}
in.close();
// stop web request tracing when done
webRequestTracer.setResponseCode(200); // would use the HTTP response code normally.
webRequestTracer.stop();
// --------------------------------------------
// alternative solution not using URLConnection
// --------------------------------------------
String url = "http://www.my-backend.com/api/v3/users";
// create the WebRequestTracer
WebRequestTracer webRequestTracer = action.traceWebRequest(url);
// this is the HTTP header name & value which needs to be added to the HTTP request.
String headerName = OpenKitConstants.WEBREQUEST_TAG_HEADER;
String headerValue = webRequestTracer.getTag();
webRequestTracer.start();
// perform the request here & do not forget to add the HTTP header
webRequestTracer.setBytesSent(12345); // 12345 bytes sent
webRequestTracer.setBytesReceived(67890); // 67890 bytes received
webRequestTracer.setResponseCode(200); // 200 was the response code
webRequestTracer.stop();
// Note: Since OpenKit .NET version 2.0.0
// webRequestTracer.Stop(200);
// can be used to set the response code and stop tracing.
string url = "http://www.my-backend.com/api/v3/users";
// create the WebRequestTracer
IWebRequestTracer webRequestTracer = action.TraceWebRequest(url);
// this is the HTTP header name & value which needs to be added to the HTTP request.
string headerName = OpenKitConstants.WEBREQUEST_TAG_HEADER;
string headerValue = webRequestTracer.Tag;
// perform the request here & do not forget to add the HTTP header
using (HttpClient httpClient = new HttpClient()) {
// start timing
webRequestTracer.Start();
// set the tag
httpClient.DefaultRequestHeaders.Add(headerName, headerValue);
// ... perform the request and process the response ...
// set metadata
webRequestTracer.SetBytesSent(12345); // 12345 bytes sent
webRequestTracer.SetBytesReceived(67890); // 67890 bytes received
webRequestTracer.SetResponseCode(200); // 200 was the response code
// stop timing
webRequestTracer.Stop();
// Note: Since OpenKit .NET version 2.0.0
// webRequestTracer.Stop(200);
// can be used to set the response code and stop tracing.
}
const char* url = "http://www.my-backend.com/api/v3/users";
// create the WebRequestTracer
std::shared_ptr<openkit::IWebRequestTracer> webRequestTracer = action->traceWebRequest(url);
// this is the HTTP header name & value which needs to be added to the HTTP request.
const char* headerName = openkit::WEBREQUEST_TAG_HEADER;
const char* headerValue = webRequestTracer->getTag();
// start timing
webRequestTracer->start();
// set the tag on httpRequest
// Note: how to set this, depends on the HTTP client library in use
httpRequest.addHeader(headerName, headerValue);
// ... perform the request and process the response ...
// set metadata
webRequestTracer->setBytesSent(12345); // 12345 bytes sent
webRequestTracer->setBytesReceived(67890); // 67890 bytes received
webRequestTracer->setResponseCode(200); // 200 was the response code
// stop timing
webRequestTracer->stop();
const char* url = "http://www.my-backend.com/api/v3/users";
// create the WebRequestTracer on child action
WebRequestTracerHandle* webRequestTracer = traceWebRequestOnRootAction(rootAction, url);
// Alterantively web requests can be created on a child action like below
// WebRequestTracerHandle* webRequestTracer = traceWebRequestOnAction(action, url);
// this is the HTTP header name & value which needs to be added to the HTTP request.
const char* headerName = WEBREQUEST_TAG_HEADER;
const char* headerValue = getTag(webRequestTracer);
// start timing
startWebRequest(webRequestTracer)
// set the tag on httpRequest
// Note: how to set this, depends on the HTTP client library in use
addCustomHeaderToWebRequest(httpRequest, headerName, headerValue);
// ... perform the request and process the response ...
// set metadata
setBytesSent(webRequestTracer, 12345); // 12345 bytes sent
setBytesReceived(webRequestTracer, 67890); // 67890 bytes received
setResponseCode(webRequestTracer, 200); // 200 was the response code
// stop timing
stopWebRequest(webRequestTracer);
// After calling stopWebRequest the allocated memory is freed and therefore
// webRequestTracer is no longer valid.
webRequestTracer = NULL;
When an OpenKit instance is no longer needed (for example, when the application using OpenKit is shut down), the obtained instance can be cleared by invoking. A call to shutdown blocks the calling thread up to 10 seconds, while the OpenKit flushes data which hasn't been transmitted yet to the backend.
openKit.shutdown();
openKit.Shutdown();
openKit->shutdown();
shutdownOpenKit(openKit);
See also a complete example of how to use Dynatrace OpenKit API to send monitoring data to Dynatrace.