App Logs quickstart: Swift, Kotlin and mobile framework SDKs

See your application's own debug, info, warning and error events in Proxycept. Filter by category, app version, device installation or debug session, then use an explicit correlation ID to investigate a log alongside a captured API request.

Hosted App Logs requires a paid plan. It is separate from network capture: log upload needs no proxy configuration, VPN or CA certificate. It collects the messages your app explicitly logs, not another app's console or automatic crash reports. Self-hosted operators must enable ENABLE_APP_LOGS=1 before using this feature.

1. Create an application and an ingestion key

  1. Sign in and open App Logs under Understand.
  2. Choose an environment and Add application. Choose iOS, Android or Other as appropriate; cross-platform clients use the same ingestion API.
  3. Open Setup & keys, choose your SDK, and create a named ingestion key.
  4. Copy the key once. Configure it at runtime using your own trusted provisioning or secure-storage flow. It cannot be retrieved after that dialog closes.

You need an editor/admin role to create applications and keys. Viewers can read logs. Use the dedicated plog_ingest_… key, never your login JWT or personal read/write API token. Do not commit a key, paste it into a URL, or compile a permanent production key into your app. Keys expire after 30 days and can be rotated or revoked.

2. Install the SDK for your app

The public SDK repository contains source, examples and platform-specific setup instructions.

  • Swift/iOS: add https://github.com/MoathOthman/proxycept-samples.git in Xcode's Package Dependencies and link ProxyceptLogging. A revision or branch is currently required; no versioned Swift release is claimed. A local sdks/swift package also works.
  • Kotlin/Android: clone the repository, include sdks/kotlin as a Gradle source module, and add the Android INTERNET permission. It is not a Maven Central artifact.
  • React Native source preview: use the linked source revision, run npm ci --ignore-scripts and npm run build inside sdks/react-native, then install that local folder in your application. Install its CocoaPod and rebuild the native app. Expo Go is not supported.
  • Flutter source preview: use sdks/flutter from the linked revision as a local path dependency in pubspec.yaml. Follow its README for iOS/Android plugin setup. It is not on pub.dev.
  • Kotlin Multiplatform source preview: include the source Gradle module from the linked revision and consume its Android/JVM target or generated Apple framework. It is not a Maven artifact.

For a preview checkout, clone the public repository, fetch the linked revision, and check it out before adding the local dependency. The preview links deliberately pin a reviewed commit, so they do not depend on a temporary PR branch remaining available.

Compatibility is specific, not "any framework version": Swift 5.9+/iOS 15+; Kotlin Android API 21+; React Native 0.82.1/React 19.1.1 with iOS 15.1+/Android 24+; Flutter 3.47.9/Dart 3.13.7 with iOS 15+/Android 24+; KMP Kotlin 2.3.21 with Android 26+/iOS 14+. Check each README before integrating into a different toolchain. The framework integrations are source previews; minimum-OS and background-delivery coverage is narrower than the list of compile targets.

3. Configure the server and emit an event

Use https://proxycept.com for the hosted service, or your own server's reachable HTTPS origin, without /api, a query string or credentials. The SDK appends /api/logs/ingest. It must be reachable from the device, not just your browser.

Swift

import Foundation
import ProxyceptLogging

let folder = FileManager.default.urls(for: .applicationSupportDirectory,
    in: .userDomainMask)[0].appendingPathComponent("ProxyceptLogs")
let logger = try ProxyceptLogger(configuration: LoggingConfiguration(
    baseURL: URL(string: "https://proxycept.com")!,
    ingestToken: runtimeIngestionKey,
    appVersion: "1.0", build: "1", spoolDirectory: folder
))
logger.log(level: .info, category: "checkout", message: "Checkout tapped",
    attributes: ["screen": .string("checkout")])
await logger.flush()

Initialize the Swift client off the UI thread if startup filesystem work matters; retain it for the debug session and connect foreground/background lifecycle events as described in its README. Do not create a logger for each message.

Kotlin/Android

import com.proxycept.logging.Configuration
import com.proxycept.logging.Level
import com.proxycept.logging.ProxyceptLogger
import java.io.File

val logger = ProxyceptLogger(Configuration(
    baseUrl = "https://proxycept.com",
    ingestToken = runtimeIngestionKey,
    directory = File(context.noBackupFilesDir, "proxycept-logs-dev"),
    appVersion = "1.0", build = "1"
))
logger.log(Level.INFO, "checkout", "Checkout tapped", mapOf("screen" to "checkout"))
logger.flush()

Initialize/configure on an I/O worker. Retain the logger at application scope; Kotlin close() blocks on cleanup and must run off the UI thread. Each SDK README contains its complete lifecycle and delivery-statistics example.

For React Native use createLogger from @proxycept/react-native-logging after local/native installation. Flutter exposes createMobileLogger; KMP exposes ProxyceptLogger(Configuration(...)) with a private spool path. Their linked READMEs contain the exact initialization, logging and shutdown examples.

4. Find the event in the console

Keep Live enabled in App Logs, open the same environment and application, and look for Checkout tapped in category checkout. Use the severity, category, version and debug-session filters to narrow the view. The standalone console polls while visible and bounds displayed results; it is not a guarantee that every event will appear immediately or survive a terminated app.

A successful log call means admission to the SDK's bounded queue, not delivery. Check its delivery statistics for accepted, duplicate, queued, dropped and failed records. Flush schedules/attempts delivery according to that SDK's lifecycle and retry policy. Do not immediately destroy the client if you need an upload to finish.

5. Connect logs to an API capture (optional)

To correlate events, log a non-secret request ID and explicitly put the same ID in an HTTP header on a request to an endpoint your application controls. The default header is X-Proxycept-Correlation-ID; the app's configured correlation header must match. Swift and Kotlin provide opt-in request-tagging helpers in their READMEs. The framework previews accept an explicit correlationId; they do not automatically instrument your HTTP client or expose every native tagging helper.

The request must also pass through a running Proxycept capture profile to appear in Capture. Open its flow's App logs view to see correlated events. Without network capture you can still use the standalone App Logs console. Do not add headers to signed requests or third-party endpoints without checking their contract.

6. Troubleshoot the first upload

  • Feature disabled or upgrade required: hosted collection is paid-only; self-hosted operators also need ENABLE_APP_LOGS=1. Neither is fixed by a new key.
  • 401/403: use the application ingestion key, check expiry/revocation and the owning account's entitlement. Login and personal API tokens are not ingestion keys.
  • No event: clear filters, choose the correct application/environment, inspect SDK queue/delivery statistics, and keep the app in the foreground.
  • Connection error: physical-device 127.0.0.1 is the device itself. Use reachable HTTPS. For deliberate local Android tests use adb reverse and numeric 127.0.0.1; localhost and 10.0.2.2 are not SDK cleartext exceptions.
  • 413/422: keep attributes flat (string, finite number, boolean or null), use supported levels debug/info/warning/error, and respect the README's limits.
  • 429 or queued retries: wait for backoff/Retry-After. Do not recreate the client in a tight loop; inspect account and application collection budgets.
  • Native module missing: React Native and Flutter need native linking and a rebuilt application, not only a JavaScript/Dart reload.

Queues and server events expire after three days. Storage and collection quotas bound logging, and redaction is best effort. Choose messages and attributes that exclude credentials and personal information before you call the SDK.

Try Proxycept free

One hosted proxy endpoint for every device, emulator, and CI runner. Shared captures, no per-machine install.

Start free