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
| Attribute | Description | Example | Always Present |
|---|---|---|---|
http.method | HTTP verb | "GET", "POST" | ✅ Yes |
http.url | Full request URL | "https://api.example.com/v1/users" | ✅ Yes |
http.target | URL path | "/v1/users" | ✅ Yes |
net.peer.name | Request host | "api.example.com" | ✅ Yes |
http.scheme | Protocol scheme | "https" | ✅ Yes |
net.peer.port | Port (if non-standard) | 8080 | ⚠️ If present in URL |
http.status_code | HTTP status | 200, 404, 500 | ⚠️ If response received |
http.request_body_size | Request body size in bytes | 1024 | ⚠️ If body present |
http.response_body_size | Response body size in bytes | 2048 | ⚠️ If Content-Length header present |
graphql.operation.name | GraphQL operation | "GetUser" | ⚠️ If GraphQL |
graphql.operation.type | GraphQL type | "query", "mutation" | ⚠️ If GraphQL |
session.id | Current session | "f40364c92b85ec0c19c35a65be42b97f" | ✅ Yes |
screen.name | Active 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:
- The JSON request body (
operationName,queryfields) - 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.