Skip to content

2. Resource

Every request carries Resources that identify the app build and the device. A backend stores the Resource once per group, not once per record.

  • MUST set service.name to the bundle identifier (Apple) or application id (Android).
  • MUST set service.version to the user-facing version (CFBundleShortVersionString, versionName).
  • MUST set app.build_id to the value that matches the symbol files:
    • on Apple platforms, the main binary’s UUID (the dSYM UUID);
    • on Android, the build id of the R8 mapping, or the native library build id when the app has no mapping file.
  • Nothing in the app can read the Android build id at run time, so the build integration that uploads the mapping (for example a Gradle plugin) MUST also write the id into the app, as the manifest <meta-data> entry io.apsio.build_id, and the SDK reads it from there.
  • When that entry is absent, the SDK MUST set app.build_id to <package>@<versionName>+<versionCode> (for example com.example.shop@4.12.0+41200). No mapping file has that id, so a backend cannot deobfuscate the build’s stacks.
  • MUST set os.name (iOS, iPadOS or Android) and os.version. A backend compares os.name without regard to case.
  • SHOULD set os.build_id, device.manufacturer and device.model.identifier (for example iPhone17,1, SM-S928B).
  • MUST NOT set device.id, and MUST NOT derive any identifier from the vendor identifier (IDFV), the advertising identifier (IDFA) or the Android ID.
  • MAY set app.installation.id: a random identifier generated on the first launch, scoped to the app, and reset when the app is reinstalled. It MUST NOT be shared across apps.
  • An SDK that sets it MUST let the app turn it off at start. When it is off, a backend can count sessions but not users.

A session rotates while the process lives (section 3), but most OpenTelemetry SDKs fix their Resource at start-up. So:

  • MUST set session.id either on every log record and span, or on the Resource of the ResourceLogs or ResourceSpans group that contains them.
  • When both are present, the record wins. A backend MUST read session.id from the record first and fall back to the Resource.
  • The same rule applies to apsio.sampling.session.rate (section 9).
  • Metric points from MetricKit and other daily aggregates carry no session.id (section 7).

2.5 Attributes of a different app instance

Section titled “2.5 Attributes of a different app instance”

A record that describes another app instance (a crash or exit reported on the next launch, a session summary sent late) carries that instance’s identity as record attributes: app.build_id, service.version, os.name, os.version and session.id. A backend MUST let these record attributes override the Resource of the sending launch for that record.