iOS API
- Instana iOS agent API
- Setup
- Current configuration
- Session identifier
- Automatic HTTP monitoring
- Manual HTTP monitoring
- Automatic and manual HTTP monitoring
- Views
- Identifying Users
- Metadata
- Excluding URLSession from monitoring
- Excluding URLs from monitoring
- Report custom events
- Enabled or disable collection
- Enable logging
- Redact URL Query parameters
- Capture HTTP header fields
Instana iOS agent API
The following section describes the usage of the Instana iOS agent. Instana's iOS agent can be used through the Instana
class methods that are explained here.
Setup
Initialize the Instana iOS agent early in didFinishLaunchingWithOptions
by calling the setup function. Do not start Instana delayed. Make sure to call the setup right after the app launch. You can enable or disable Instana delayed
by using the Instana.collectionEnabled
flag.
static func setup(key: String, reportingURL: URL, httpCaptureConfig: HTTPCaptureConfig = .automatic)
Parameters
Parameter | Description |
---|---|
key (String ) |
The Instana monitoring configuration key. |
reportingURL (URL ) |
The URL pointing to the Instana instance to which to the send monitoring data to. |
httpCaptureConfig (HTTPCaptureConfig , optional) |
Per default HTTP requests and responses are captured automatically. You can also disable automatic monitoring by using manual or use both modes together with automaticAndManual . To completely turn off http
session monitoring, you can pass none . |
collectionEnabled (Bool , optional) |
By default, the data collection is turned on with the setup. To set up Instana but ignore any data collection, you can set this property to false in the setup. This property is most useful for scenarios in which explicit
user consent is required before the agent can collect data. The default value is true . |
enableCrashReporting (Bool , optional) |
(technology preview) By default, the data collection is disabled in the setup. The data collection can be enabled later by using this property, which allows apps to start collecting Instana crash data. This property is most useful
for scenarios in which explicit user consent is required before the agent can collect crash data. The default value is false . |
Example
import InstanaAgent
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
Instana.setup(key: "<Your Instana Key>", reportingURL: URL(string: "<Your Instana instance URL>")!)
....
return true
}
The example uses the default automatic
HTTP capture configuration. To change, you can call:
Instana.setup(key: <Your Key>, reportingURL: <Your Instana URL>, httpCaptureConfig: .manual)
Current configuration
The Instana
class object has some properties to retrieve the current configuration setup:
Property | Description |
---|---|
key (String , optional) |
The Instana monitoring configuration key. |
reportingURL (URL , optional) |
The URL pointing to the Instana instance to which to the send monitoring data to. |
Example
let key = Instana.key
let url = Instana.reportingURL
Session identifier
Each Instana agent instance has an unique session identifier you could use for other purposes in your app.
Property | Description |
---|---|
sessionID (String , optional) |
The current session identifier. This session id will be created within the setup process. |
Example
let sessionID = Instana.sessionID
Automatic HTTP monitoring
By default HTTP sessions are captured automatically. The Instana iOS agent uses Foundation's NSURLProtocol
to monitor HTTP requests and responses. To observe all NSURLSession
automatically with NSURLProtocol
some method swizzling in the NSURLSession
is necessary. To opt out automatic HTTP session monitoring, you must capture every request and response manually.
Manual HTTP monitoring
To capture HTTP sessions manually, you must set up Instana by using the httpCaptureConfig: .manual
and use the corresponding functions that are described. You can capture HTTP requests and responses manually by using the URLRequest
or URL
.
Automatic and manual HTTP monitoring
To capture HTTP sessions automatically and manually you must set up Instana by using the httpCaptureConfig: .automaticAndManual
. You can use the automatic instrumentation or optionally capture HTTP requests or responses manually.
Start Capture (URLRequest)
This function starts the http capture for the URLRequest
and the optional view name. A HTTPMarker
object is returned which you need later to set the results of the HTTP response.
static func startCapture(_ request: URLRequest?, viewName: String? = nil) -> HTTPMarker
Parameters
Parameter | Description |
---|---|
request (URLRequest ) |
The URLRequest to capture. |
viewName (String , optional) |
Optional name of the visible view that is related to this request |
Returns: HTTP marker to set the results of the HTTP response (HTTP status code, sizes, error).
Start capture (URL)
This function starts the HTTP capture for the URL
, HTTP method, and the optional view name. A HTTPMarker
object is returned which you need later to set the results of the HTTP response.
static func startCapture(url: URL, method: String, viewName: String? = nil) -> HTTPMarker
Parameters
Parameter | Description |
---|---|
url (URL ) |
The URL to capture. |
method (String ) |
The HTTP method of the request. |
viewName (String , optional) |
Optional name of the visible view that is related to this request |
Returns: HTTP marker to set the results of the HTTP response (HTTP status code, sizes, error).
Set HTTP response size
Invoke this method on the HTTPMarker
when the response size is determined.
func set(responseSize: Instana.Types.HTTPSize)
Parameters
Parameter | Description |
---|---|
responseSize (HTTPSize ) |
The httpSize object that contains headerBytes , bodyBytes , bodyBytesAfterDecoding |
Note: Make sure that you don't call any methods on the HTTPMarker
after you called finish
or cancel
HTTP response size
You can create the HTTPMarker.Size
with the following initializer:
init(response: URLResponse, transactionMetrics: [URLSessionTaskTransactionMetrics]?)
Parameters
Parameter | Description |
---|---|
response (URLResponse ) |
The URLResponse object |
transactionMetrics ([URLSessionTaskTransactionMetrics] , optional) |
An optional array with URLSessionTaskTransactionMetrics |
You can also create the HTTPMarker.Size
object by passing the size values directly as parameter
HTTPMarker.Size(header: Instana.Types.Bytes, body: Instana.Types.Bytes, bodyAfterDecoding: Instana.Types.Bytes)
Finish Capture (URLResponse)
Call finish
on HTTPMarker
once the request is completed with the URLResponse
and an optional Error
func finish(response: URLResponse?, error: Error?)
Finish Capture (HTTPCaptureResult)
Alternatively you can use the HTTPCaptureResult
to finish the capture.
let size = HTTPMarker.Size(header: 123, body: 1024, bodyAfterDecoding: 2048)
let result = HTTPCaptureResult(statusCode: statusCode, backendTracingID: "Instana-backend-tracing-id", responseSize: size, error: error)
marker.finish(result: result)
Cancel capture
Invoke this method on the HTTPMarker
if the request is canceled before completion. The state is set to failed internally with an NSURLErrorCancelled
when you are calling cancel
.
func cancel()
Complete manual HTTP monitoring example (URLResponse)
let marker = Instana.startCapture(request, viewName: "User: Details")
URLSession.shared.dataTask(with: request) { data, response, error in
marker.finish(response: response, error: error)
}.resume()
You can also set the HTTP response size manually through the URLSessionDelegate
like the following example (before you are calling finish or cancel):
func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) {
guard let response = task.response else { return }
marker.set(responseSize: HTTPMarker.Size(response: response, transactionMetrics: metrics.transactionMetrics))
}
Complete manual HTTP monitoring example (URL)
let url = URL(string: "https://www.example.com/user/123/details")!
let marker = Instana.startCapture(url: url, method: "GET", viewName: "Home")
YourNetworkManager(url: url, method: "GET") { (statusCode, error) in
let size = HTTPMarker.Size(header: 123, body: 1024, bodyAfterDecoding: 2048) // optionally
let backendTracingID = "Instana-backend-tracing-id" // optionally
let result = HTTPCaptureResult(statusCode: statusCode, backendTracingID: backendTracingID, responseSize: size, error: error)
marker.finish(result: result)
}.resume()
Views
Instana can segment app metrics by logical views. To do so, it needs a hint what view the user is currently looking at. This view name can be set via the setView(name: String)
. The view name will be attached to all monitored beacons
until you call setView
again with another name. Generally speaking, we recommend not to use technical or generic names like the Class (i.e. WebViewController
) to define views. We recommend the usage of readable
names for views. For example product detail page
or payment selection
. This will result in fewer pages which will have a direct relation to actually existing code. We recommend to set the view name in viewDidAppear
.
Setting the view name will also enable Instana to track
page transitions in addition to page loads.
The view name gets updated automatically when your app changes the state (e.g. from active to inactive or background). The view name will be Inactive
when your app is in the inactive state (when receiving a SMS) and will be set
to Background
once your app leaves the foreground.
static func setView(name: String)
Parameters
Parameter | Description |
---|---|
name (String ) |
The name of the view. |
Example
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
Instana.setView(name: "User: Details")
}
To get the current view name, you can use the class variable viewName
. The value for view name might be Inactive
or Background
depending on your app state.
Property | Description |
---|---|
viewName (String , optional) |
The current view name set through setView(name:) . |
Example
let viewName = Instana.viewName
Identifying Users
User-specific information can optionally be sent with data transmitted to Instana. This information can then be used to unlock additional capabilities such as:
- calculate the number of users affected by errors,
- to filter data for specific users and
- to see which user initiated a view change or HTTP request.
By default, Instana will not associate any user-identifiable information to beacons. Please be aware of the respective data protection laws when choosing to do so. We generally recommend identification of users via a user ID. For Instana this
is a completely transparent String
that is only used to calculate certain metrics. userName
and userEmail
can also be used to have access to more filters and a more pleasant presentation of user information.
In cases in which you are handling anonymous users and thus don't have access to user IDs you could alternatively use session IDs. Session IDs are not as helpful as user IDs when filtering data but they are a good indicator to calculate affected/unique
user metrics. We recommend setting a user name such as Anonymous
to have a clear differentiation between authenticated and unauthenticated users. Session IDs can be sensitive data (depending on the framework/platform used).
Please consider hashing session IDs to avoid transmitting data to Instana that can grant access.
It is important to note that data already transmitted to Instana's server cannot be retroactively updated. For this reason it is important to call this API as soon as possible in the app launch process.
static func setUser(id: String, email: String?, name: String?)
Parameters
Parameter | Description |
---|---|
id (String ) |
An identifier for the user. |
email (String , optional) |
The user's email address. |
name (String , optional) |
The user's name. |
You can pass nil
for values you don't want to set.
Example
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Instana.setup(key: InstanaKey, reportingURL: InstanaURL)
Instana.setUser(id: someID, email: "email@example.com", name: "John")
return true
}
Alternatively, you can set the user properties individually.
User ID
Set the user ID
static func setUser(id: String)
Parameters
Parameter | Description |
---|---|
id (String ) |
An identifier for the user. |
User email address
Set the user email address
static func setUser(email: String)
Parameters
Parameter | Description |
---|---|
email (String ) |
User's email address. |
Username
Set user's name
static func setUser(name: String)
Parameters
Parameter | Description |
---|---|
name (String ) |
User's name. |
Metadata
Metadata information that is attached to the transmitted data. Consider using to track UI configuration values, settings, feature flags… any additional context that might be useful for analysis. You should set the metadata in the app launch process to assign the key or values to all transmitted data.
static func setMeta(value: String, key: String)
Parameters
Parameter | Description |
---|---|
value (String ) |
The value of the key-value pair you want to add as metadata. |
key (String ) |
The key of the key-value pair you want to add as metadata. |
Example
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Instana.setup(key: InstanaKey, reportingURL: InstanaURL)
Instana.setMeta(value: "ReactNative", key: "Platform")
Instana.setMeta(value: "DEBUG", key: "Environment")
return true
}
Excluding URLSession from monitoring
You can ignore a custom URLSession
from being monitored by the Instana iOS agent.
static func ignore(_ session: URLSession)
Parameters
Parameter | Description |
---|---|
session (URLSession ) |
URLSession to be ignored from monitoring. |
Example
let session = URLSession(configuration: .default)
Instana.ignore(session)
Excluding URLs from monitoring
You can ignore URLs to reject that match with the given regular expressions to prevent transmission to Instana. A good example for usage of this function would be to ignore all HTTP requests that contain any sensitive data like a password.
static func setIgnoreURLs(matching regex: [NSRegularExpression])
Parameters
Parameter | Description |
---|---|
regex ([NSRegularExpression] ) |
An array of NSRegularExpression objects matching the URLs you want to ignore. |
Example
let regex = try! NSRegularExpression(pattern: "/.*(&|\?)password=.*/i")
Instana.setIgnoreURLs(matching: [regex])
That examples ignore all URLs that contain password in the query.
Alternatively you can ignore full URLs like:
Instana.setIgnore(urls: [URL(string: "https://www.example.com")!])
Report custom events
Custom events enable reporting about nonstandard activities, important interactions, and custom timings to Instana. It can be especially helpful when analyzing uncaught errors (breadcrumbs) and to track more performance metrics.
static func reportEvent(name: String, timestamp: Instana.Types.Milliseconds? = nil, duration: Instana.Types.Milliseconds? = nil, backendTracingID: String? = nil, error: Error? = nil, meta: [String: String]? = nil, viewName: String? = Instana.viewName)
Parameters
Parameter | Description |
---|---|
name (String ) |
Defines what kind of event that happens in your app that results in the transmission of a custom beacon. |
timestamp (Int64 , optional) |
The timestamp in milliseconds when the event is started. If you don't provide a timestamp, we assume now as timestamp. In case you don't provide a timestamp, but set a duration, we calculate a timestamp by subtracting the duration from now. (timestamp = now - duration) |
duration (Int64 , optional) |
The duration in milliseconds of how long the event lasted. Default is zero |
backendTracingID (String , optional) |
Identifier to create a backend trace for this event. |
error (Error , optional) |
Error object to provide more context. |
meta ([String: String] , optional) |
Key - Value data, which can be used to send metadata to Instana just for this singular event |
viewName (String , optional) |
You can pass a String to group the request to a view. If you send explicitly nil, the viewName is ignored. Alternatively you can leave out the parameter viewName to use the current view name you did set in setView(name: String) ) |
Examples
Instana.reportEvent(name: "Event-Name")
Instana.reportEvent(name: "Event-Name", viewName: "User: Details")
Instana.reportEvent(name: "Event-Name", timestamp: 1590149955086, duration: 124842, backendTracingID: "some-id", error: NSError(domain: "Some", code: -1, userInfo: nil), meta: ["Key": "Value"], viewName: "User: Details")
Enabled or disable collection
You can enable or disable the data collection at any time during the runtime. It enables the delayed start of the data collection (for example after user consent).
Property | Description |
---|---|
collectionEnabled (Bool ) |
Flag to enable or disable data collection |
Example
Instana.collectionEnabled = true
Enable logging
The Instana iOS agent has a logging capability for debugging purposes. Just add the environment variable INSTANA_DEBUG_LOGLEVEL
in Xcode. As value you must pass the number for the log level: 0
= Debug information,
warnings and error, 1
= Warnings and errors, 2
=> Errors only
Redact URL Query parameters
Query parameters in collected URLs may contain sensitive data. Therefore, the Instana iOS agent supports the specification of regex patterns for query parameter keys whose values should be redacted. Any redacted value will be replaced with
<redacted>
. Redaction happens within the Instana agent, before reporting to the Instana server. Consequently, secrets will not reach the Instana servers for processing and will not be available for analysis in the UI or
retrieval by using Instana API.
By default, the Instana iOS agent is configured with a list of three regex patterns to automatically redact query parameter values for the keys: "password", "key" and "secret". Redaction will only be applied to automatically monitored requests and their associated logs. Manually monitored requests are not redacted.
static func redactHTTPQuery(matching regex: [NSRegularExpression])
Parameters
Parameter | Description |
---|---|
regex ([NSRegularExpression] ) |
An array of NSRegularExpression objects matching the keys for the values that you want to redact. |
Example
let regex = try! NSRegularExpression(pattern: #"pass(word|wort)"#)
Instana.redactHTTPQuery(matching: [regex])
This example redacts values for the HTTP parameter keys "password" or "passwort". The captured URL https://example.com/accounts/?password=123&passwort=459
will be collected and displayed as https://example.com/accounts/?password=<redacted>&passwort=<redacted>
.
Note: The Instana iOS agent does not support treating path parameters (/account/
Capture HTTP header fields
HTTP request and response headers can be captured by the iOS agent. You can use regular expressions to define the keys of the HTTP header fields that the iOS agent needs to capture.
public static func setCaptureHeaders(matching regex: [NSRegularExpression])
Parameters
Parameter | Description |
---|---|
regex ([NSRegularExpression] ) |
An array of NSRegularExpression objects to match the key of HTTP request/response headers that you want to capture. |
Example
let regex = try! NSRegularExpression(pattern: #"X-Key"#, options: [.caseInsensitive])
Instana.setCaptureHeaders(matching: [regex])
This example captures HTTP header fields with the key X-Key
or X-KEY
.