Skip to main content

Network Instrumentation

Generates: Spans

Automatically instruments all URLSession HTTP traffic — no code changes required in your networking layer.

Configuration

URLSession instrumentation is enabled by default. To tune its behavior:

Pulse.shared.initialize(
endpointBaseUrl: "https://your-backend.com",
apiKey: "your-api-key",
instrumentations: { config in
config.urlSession { urlSession in
urlSession.enabled(true)

// Filter which requests are instrumented
urlSession.setShouldInstrument { request in
// Skip internal health-check calls
request.url?.path != "/health"
}

// Explicitly exclude your OTLP endpoint (auto-excluded by default)
urlSession.excludeOtlpEndpoints(baseUrl: "https://your-backend.com")
}
}
)

What Gets Tracked

  • HTTP method, URL, and host
  • HTTP status code
  • Request duration (from send to last byte received)
  • Network errors (timeout, no connection, SSL failure)
  • GraphQL operation name and type (when URL contains "graphql")

Generated Telemetry

Type: Span
Span Kind: Client
pulse.type: network.<status_code> — e.g. network.200, network.404, network.0 (for connection errors)

Attributes

AttributeDescriptionExampleAlways Present
http.methodHTTP verb"GET", "POST"✅ Yes
http.urlFull request URL"https://api.example.com/v1/users"✅ Yes
http.targetURL path"/v1/users"✅ Yes
net.peer.nameRequest host"api.example.com"✅ Yes
http.schemeProtocol scheme"https"✅ Yes
net.peer.portPort (if non-standard)8080⚠️ If present in URL
http.status_codeHTTP status200, 404, 500⚠️ If response received
http.request_body_sizeRequest body size in bytes1024⚠️ If body present
http.response_body_sizeResponse body size in bytes2048⚠️ If Content-Length header present
graphql.operation.nameGraphQL operation"GetUser"⚠️ If GraphQL
graphql.operation.typeGraphQL type"query", "mutation"⚠️ If GraphQL
session.idCurrent session"f40364c92b85ec0c19c35a65be42b97f"✅ Yes
screen.nameActive screen at request time"HomeViewController"⚠️ If available

All network spans include global resource attributes (device, OS, app). See Global Attributes.

Sample Payload: Successful Request

{
"name": "GET",
"kind": "CLIENT",
"status": "OK",
"attributes": {
"pulse.type": "network.200",
"http.method": "GET",
"http.url": "https://api.example.com/v1/users",
"http.target": "/v1/users",
"net.peer.name": "api.example.com",
"http.scheme": "https",
"http.status_code": 200,
"session.id": "f40364c92b85ec0c19c35a65be42b97f",
"screen.name": "HomeViewController"
}
}

Sample Payload: Failed Request

{
"name": "GET",
"kind": "CLIENT",
"status": "ERROR",
"attributes": {
"pulse.type": "network.0",
"http.method": "GET",
"http.url": "https://api.example.com/v1/feed",
"net.peer.name": "api.example.com",
"http.status_code": 0,
"session.id": "f40364c92b85ec0c19c35a65be42b97f"
}
}

GraphQL Support

GraphQL requests are automatically detected when the URL contains "graphql" (case-insensitive). The SDK reads the operation name and type from:

  1. The JSON request body (operationName, query fields)
  2. URL query parameters as a fallback

No additional configuration is needed.

Disabling Network Instrumentation

config.urlSession { $0.enabled(false) }

When disabled, no URLSession spans are created. Existing spans from other sources are unaffected.