Debug Mode

Defined under the namespace Scandit.Datacapture.Core

The Scandit Data Capture SDK can record what it is doing while your application runs: the calls your code makes into the native SDK, how long each one took, mode and view lifecycle, listener registrations, and per-frame events. Use it to investigate an integration problem, and to attach evidence to a support ticket.

Everything described here stays on the device. See Privacy below.

Turning it on

Logging is off until you raise the level. Two settings control what is recorded, and they are checked independently:

  • LogLevel — the severity threshold. LogLevel.Debug is the level to start from.

  • LogCategory — a bit mask selecting which kinds of activity are recorded. The default is Bridge | Lifecycle | Listener, exported as DEFAULT_CATEGORIES.

ScanditLogger.setLevel(LogLevel.Debug);

Because the two are independent, raising the level alone never reveals a category that is masked out. Per-frame LogCategory.Events records are the case that catches people out: they are emitted at LogLevel.Debug, but LogCategory.Events is absent from the default mask, so switching to LogLevel.Trace shows nothing new. Opt the category in:

ScanditLogger.setCategories(DEFAULT_CATEGORIES | LogCategory.Events);

Reading the records

Records go to the platform console as they are produced, and into an in-memory ring buffer holding the most recent 1000 entries (ScanditLogger.setBufferSize() changes the capacity). Read the buffer with ScanditLogger.getRecentLogs(), or observe records live with ScanditLogger.subscribe():

const unsubscribe = ScanditLogger.subscribe(record => {
  console.log(ScanditLogger.format(record));
});

Each entry is a LogRecord. ScanditLogger.format() renders one as the same single-line string the SDK writes to the console.

What appears in a record

A record identifies the method or event it describes, where it came from, and how long it took, and it carries the arguments of the call under fields.

Those arguments pass through a fixed redaction floor first. Imagery, license keys, device identifiers and captured-document fields — barcode, MRZ, VIZ, NFC and verification results, names, dates of birth, document numbers — are replaced with [redacted], and parser payloads are redacted wholesale. Redaction is recursive and descends into JSON strings, so a key nested inside a serialized payload is caught too.

Add your own keys to the floor when your integration puts sensitive values somewhere the SDK cannot know about:

ScanditLogger.addRedactedArgKey('customerId');

The floor cannot be removed from — ScanditLogger.setAdditionalRedactedArgKeys() only extends it. To drop arguments altogether rather than redact them:

ScanditLogger.setLogBridgeArgs(false);

Error stack traces are a separate opt-in, off by default, because they can contain file paths from your own binary:

ScanditLogger.setLogErrorStacks(true);

Privacy

  • Records are held in memory in your application process and written to the platform console. Nothing is written to disk unless your application calls ScanditLogger.writeLogs(), which writes the buffer to the path you name — a relative path resolves under your application’s own storage — where it stays until you delete it.

  • Nothing is transmitted. The SDK does not upload log data to Scandit, and enabling debug mode does not start any reporting.

  • Call arguments are redacted against a built-in floor covering imagery, license keys, device identifiers and captured-document fields, and can be dropped entirely.

  • A LogRecordError.stack is omitted unless you enable it, because it can contain file paths from your own application binary. When kept it stays local and is never read or sent by the SDK.

The only way records leave the device is if you export them yourself.

Sending logs to Scandit

There is no upload built into the SDK. To attach logs to a support ticket, snapshot the buffer and hand the text to whatever sharing mechanism your application already uses — a share sheet, a file write, or your own crash-reporting backend:

ScanditLogger.setLevel(LogLevel.Debug);
ScanditLogger.setCategories(DEFAULT_CATEGORIES | LogCategory.Events);

// reproduce the problem, then:
const text = ScanditLogger.getRecentLogs()
  .map(record => ScanditLogger.format(record))
  .join('\n');

Reproduce the problem with logging already enabled, keep the run short so the buffer still holds the relevant records, and review the text before sending it. Tell us what you expected to happen and what happened instead — the records show what the SDK did, not what you meant.

Writing logs to a file

ScanditLogger.writeLogs() does the same assembly for you and writes the result to a file path you choose, so you don’t have to wire your own serialization:

ScanditLogger.setLevel(LogLevel.Debug);

// reproduce the problem, then:
const path = await ScanditLogger.writeLogs('scandit-debug-log.jsonl');

An app can only write inside its own storage, so pass a path under the app container on iOS (Documents, Library or the temporary directory), or under Context.getFilesDir() or Context.getExternalFilesDir() on Android; anywhere else needs the Storage Access Framework or MediaStore on Android 10 and later. A relative path, as above, is resolved against the app’s documents/files directory and works on both platforms. A file already at that path is replaced, so each export overwrites the previous one unless you vary the name.

The returned promise resolves with the absolute path written, and rejects if debug mode was never enabled, the buffer is empty, the SDK is not initialized yet, or the destination cannot be written; the rejection carries a message saying which, except on Cordova iOS, where only the error code reaches the caller. As with everything else on this page, nothing is uploaded automatically — the SDK writes the file and stops there. What happens next is up to you: attach it to a mail to support@scandit.com, show it in a share sheet, or send it through your own upload flow.