Skip to main content

Logs Collector

The Logs Collector module writes the SDK's own logs to disk and lets you send them to support. You open an upload session, which creates a ticket, share the ticket's code with a support agent, and attach the log files to it. It can also export the logs to a local ZIP file, with no ticket and no network.

info

This module is separate from the LogCallbackProtocol described in Setting up the SDK. That callback streams log events to your app. File logging keeps its own copy on disk, and the callback keeps working whether file logging is on or off.

Enabling File Logging​

File logging is off by default. Two settings enable it, and both must be set before the SdkManager is created. Later changes have no effect.

SettingDescription
setBasePath(path)A writable directory. Logs go to <path>/logs, the cache to <path>/cache_root unless setCacheFilePath already set one. Can be set only once; a second call throws
setLoggingConfig(config) or logging: YAMLTurns file logging on and sets its limits
try configuration.setBasePath(path: appSupportDirectory)
configuration.setLoggingConfig(config: LoggingConfig())
let manager = try SdkManager(configuration: configuration)

LoggingConfig​

Every field is optional and falls back to its default.

NameTypeDefaultDescription
prelogMaxMbUInt644Size cap of the in-memory buffer kept around startup, in MB
prelogMaxMinutesUInt6460How long the in-memory buffer is kept, in minutes
logfileMaxMbUInt64100Size cap of the log files on disk, in MB
logRetentionHoursUInt64168How long log files are kept on disk, in hours

Log files are encrypted on disk. The methods below decrypt them, so what reaches support or the ZIP file is plain JSON Lines.

danger

setDangerousYouAreResponsibleForUnencryptedPlaintextLogs(true) writes the logs unencrypted, into one file with no size cap and no retention. Logs contain user identifiers, tokens and network names. Use it for local debugging only, never in a production build. It has no YAML equivalent.

Getting the Module​

let logs = try manager.logsCollector()

All methods throw LoggingException. The async methods also have a blocking variant without the Async suffix.

create_session​

Creates a ticket and returns a LogUploadSession bound to it.

suspend fun createSessionAsync(): LogUploadSession

The ticket records the OS, OS version, app version, SDK version and device model. They come from the ClientDetails you already set, so you pass nothing extra.

No login is needed, so a user can upload logs after signing in has failed.

create_session_with_attributes​

Same as create_session, plus key/value pairs recorded on the ticket and shown to support staff. Use them for what the SDK cannot know, such as the network type or an app-side correlation id.

suspend fun createSessionWithAttributesAsync(
attributes: Map<String, String>
): LogUploadSession

The collector rejects the whole request if any pair breaks these rules:

RuleLimit
CountAt most 20 pairs per ticket
Key1–64 bytes of [a-z0-9_.-], starting with a lower-case letter
Value1–128 bytes, no control characters
Reserved keysos_name, os_version, app_version, sdk_version, device_model, and any key starting with kp_ or kp.
warning

Support staff can read these values, and they are kept as long as the ticket. Do not put personal data in them.

export_logs_to_zip​

Writes the current log files into a ZIP file, decrypted. Needs no ticket and no network.

suspend fun exportLogsToZipAsync(zipPath: String): UInt

zip_path must be an absolute path with no .. component. The archive is created if missing and appended to otherwise. A file already in the archive is skipped, so exporting again adds only the files written since. Returns the number of files added.

flush_logs​

Blocks until buffered log records are written to disk.

fun flushLogs(): Boolean

Call it from suspend and exit handlers, chiefly in an iOS Network Extension, so the last records survive the process being frozen or killed. Returns false when nothing was written to disk: file logging is off, or only the in-memory buffer is active.

LogUploadSession​

A session is bound to one ticket.

MethodReturnsDescription
code()StringThe ticket code. The only value the user reads out to support
uploadId()StringSecret upload token. Required for every attach call; do not show or share it
setAttributes(attributes)Map<String, String>Adds pairs to the ticket and returns all of its pairs
attachFile(filename, contentType, body)AttachFileResponseAttaches one file of your own to the ticket
uploadSdkLogs(progress)Array of AttachFileResponseAttaches every SDK log file, newest first

set_attributes​

Records a value that exists only after the ticket does, such as the helpdesk ticket id an agent creates once the user has read out the code. It keeps working for as long as the ticket exists.

Each key is write-once:

  • A new key is added.
  • A key sent again with the same value succeeds and changes nothing, so retrying after a lost response is safe.
  • A key sent again with a different value fails the whole call with HTTP 409, and none of the pairs are applied.

The rules and the warning of create_session_with_attributes apply. An empty map writes nothing and returns the current pairs.

attach_file​

Each call creates a new file on the ticket. Retrying after a failure uploads the file again rather than replacing it.

upload_sdk_logs​

Attaches each SDK log file, decrypted, in its own request. Returns one AttachFileResponse per uploaded file. A file that cannot be read or decrypted is skipped. A file cut short by a crash is sent up to the last readable record. Files already uploaded stay on the ticket if the upload stops early.

LogUploadProgressCallback​

interface LogUploadProgressCallback {
fun onProgress(current: UInt, total: UInt): Boolean
}

Called with current = 0 before the first upload, then once per file: (0, N), (1, N), …, (N, N). Skipped files are counted too, so current always reaches total. Return false, or throw, to stop after the current file.

AttachFileResponse​

NameTypeDescription
fileIdStringID of the file on the ticket
filenameStringName of the file
contentTypeStringMIME type. application/x-ndjson for SDK logs
sizeUInt64Size in bytes
statusStringUpload status reported by the collector
uploadStartedAtInt64Upload start, as a Unix timestamp
uploadFinishedAtInt64?Upload end, as a Unix timestamp, if finished

Example​

let session = try await manager.logsCollector()
.createSessionWithAttributesAsync(attributes: ["network_type": "wifi"])
showToUser(session.code())

try await session.uploadSdkLogsAsync(progress: ProgressBar())